From d558f50d8b379b20f18a7b3da85a02161a941241 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 18 Jul 2024 10:04:48 +1000 Subject: [PATCH 001/124] 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 Signed-off-by: gconnect --- 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 1bc0e55567f..953d1859e8e 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 62cee8a615424ed4466fdd55986a0613a56c9142 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Thu, 18 Jul 2024 10:28:29 +1000 Subject: [PATCH 002/124] [minor] Remove redundant info from plugin summary (#7339) Signed-off-by: Gabriel-Trintinalia Signed-off-by: gconnect --- .../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 6aa64ac5106..ddf69402921 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 List getPluginsSummaryLog() { 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 1ea78e7f3a5..58c241509ee 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 952f1fb074d..1d7acf3a3ee 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 @@ default String getVersion() { Optional.ofNullable(pluginPackage.getImplementationVersion()) .filter(version -> !version.isBlank()) .orElse(""); - return implTitle + "/v" + implVersion; + return implTitle + "/" + implVersion; } } From 3327ceeb9081aa103852d9a8f5053fb47b456383 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 18 Jul 2024 11:29:17 +1000 Subject: [PATCH 003/124] 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 Signed-off-by: gconnect --- 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 4444f7acf72..eed35a03a94 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 @@ private void waitForServiceToStop(final String serviceName, final SynchronousShu 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 11a1500e4e7..37025feca7e 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 void onBlockAdded(final BlockAddedEvent event) { 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 857ec0b079d..75b370c1cd0 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 @@ Optional rollMutableStateToBlockHash( } 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 8cc907d6866..755283b0809 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 @@ private int compareDuplicateConnections(final PeerConnection a, final PeerConnec } } // 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 dcb66696662..1e2f3eb6abb 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 @@ private CompletableFuture timeout( 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 void stop() { 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 c65a1c6b0cd..ce639a7a9a0 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 void processMessage(final Capability cap, final Message message) { 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 void processMessage(final Capability cap, final Message message) { 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 a7386d7f78e..292fb0b0079 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 UpnpNatManager() { 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 ba986089a41e34d402f7d7c9f9476a775af534de Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Thu, 18 Jul 2024 14:09:41 +1000 Subject: [PATCH 004/124] Update release checklist (#7329) Signed-off-by: Simon Dudley Signed-off-by: gconnect --- .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 f484b7a5902..9840a3fa497 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 e85dd37ac76f22062cd6856098db73180d71cb1f Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 19 Jul 2024 03:21:08 +1000 Subject: [PATCH 005/124] Add metrics for trie log pruner (#7352) --------- Signed-off-by: Simon Dudley Signed-off-by: gconnect --- 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 5fb35c2e0b0..7710f8e7b95 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 8f26909a512..20f3ca8ef61 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 @@ private TrieLogPruner createTrieLogPruner( 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 6f347be0334..cea5c1a327d 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.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 TrieLogPruner( 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 TrieLogPruner( 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 @@ private int preloadQueue() { // 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 synchronized void addToPruneQueue(final long blockNumber, final Hash bloc .addArgument(blockHash) .log(); trieLogBlocksAndForksByDescendingBlockNumber.put(blockNumber, blockHash); + addedToPruneQueueCounter.inc(); } public synchronized int pruneFromQueue() { @@ -155,6 +175,7 @@ public synchronized int pruneFromQueue() { }); 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 bca954a4935..621e73711ab 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.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 void initialize_preloads_queue_and_prunes_orphaned_blocks() { // 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 void trieLogs_pruned_in_reverse_order_within_pruning_window() { // 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 void skip_pruning_when_finalized_block_required_but_not_present() { 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 void onTrieLogAdded_should_prune() { // 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 void onTrieLogAdded_should_prune() { 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 @@ private TrieLogPruner setupPrunerAndFinalizedBlock( 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 5cdc82cadbc78b1fc63884d8537de3843d47271e Mon Sep 17 00:00:00 2001 From: Karim Taam Date: Fri, 19 Jul 2024 18:11:30 +0200 Subject: [PATCH 006/124] 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 Signed-off-by: gconnect --- 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 7710f8e7b95..9c6cb373ba8 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 7216d9ebd66..198c26fe2a8 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 BesuControllerBuilder getControllerBuilder() { .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 69cf819cb4b..fc92a7e5dd9 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 static class Unstable { "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 static DataStorageOptions create() { * @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 static DataStorageOptions fromConfig(final DataStorageConfiguration domai domainObject.getUnstable().getBonsaiFullFlatDbEnabled(); dataStorageOptions.unstableOptions.bonsaiCodeUsingCodeHashEnabled = domainObject.getUnstable().getBonsaiCodeStoredByCodeHashEnabled(); + dataStorageOptions.unstableOptions.isParallelTxProcessingEnabled = + domainObject.getUnstable().isParallelTxProcessingEnabled(); return dataStorageOptions; } @@ -214,6 +232,7 @@ public DataStorageConfiguration toDomainObject() { 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 20f3ca8ef61..ddb75fcdedc 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 BesuControllerBuilder randomPeerPriority(final Boolean randomPeerPriority 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 c1274240694..b4ada605498 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 @@ protected ProtocolSchedule createProtocolSchedule() { 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 f6693322029..0d0f8d2fd87 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 BesuControllerBuilder isRevertReasonEnabled(final boolean isRevertReasonE 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 473549e0bd7..b8d4d2645e0 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 @@ protected ProtocolSchedule createProtocolSchedule() { 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 27570483c12..e0fbed608ab 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 @@ protected ProtocolSchedule createProtocolSchedule() { 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 cdd46ea5b98..f5fc75959e1 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 @@ protected ProtocolSchedule createProtocolSchedule() { 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 795136ded5d..ab2dbce3f13 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 @@ protected ProtocolSchedule createProtocolSchedule() { 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 cdf5413fff2..d7b701b4c5d 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 BesuControllerBuilder isRevertReasonEnabled(final boolean isRevertReasonE 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 fe5077acc6a..28d4c77036f 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.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 @@ private static MilestoneStreamingTransitionProtocolSchedule createSchedule( 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 c92a3a5bda4..8a6a5781198 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 void initMocks() throws Exception { 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 91013ab97c9..cd197556386 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.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 static ProtocolSchedule create( 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 static ProtocolSchedule create( isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager) + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem) .createProtocolSchedule(); } @@ -124,6 +132,9 @@ public static ProtocolSchedule create( * @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 static ProtocolSchedule create( 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 static ProtocolSchedule create( 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 35f959e45bd..5cbdbb6d06e 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.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 void protocolSpecsAreCreatedAtBlockDefinedInJson() { 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 void parametersAlignWithMainnetWithAdjustments() { 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 void zeroEpochLengthThrowsException() { 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 void negativeEpochLengthThrowsException() { 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 void shouldValidateBaseFeeMarketTransition() { 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 485b2aff79d..ec10630df9c 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 @@ void setup() { 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 bb69aaff483..9502d00a192 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 void setup() { 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 da81ce80b7c..311bf30faef 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.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 @@ protected 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 BftProtocolSchedule createProtocolSchedule( 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 BftProtocolSchedule createProtocolSchedule( 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 4e3cab78e7f..02689d52af1 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.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 @@ private BftProtocolSchedule createProtocolSchedule( 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 9b05bd7a365..e23664fd8d3 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.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 @@ protected BlockHeaderValidator.Builder createBlockHeaderRuleset( 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 55a2f3551a1..2d620c56321 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 @@ private static ControllerAndState createControllerAndFinalState( 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 5cad697c537..0789f2e8981 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.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 @@ protected IbftProtocolScheduleBuilder() {} * @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 static BftProtocolSchedule create( 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 static BftProtocolSchedule create( bftExtraDataCodec, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -78,6 +86,9 @@ public static BftProtocolSchedule create( * @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 static BftProtocolSchedule create( 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 static BftProtocolSchedule create( 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 611399fd55b..e5551ff3f31 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.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 @@ private BftProtocolSchedule createProtocolSchedule( 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 25c5c1d10b8..1b86896f36f 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 BlockHeaderValidator.Builder createBlockHeaderRuleset( 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 68e0ee5efe5..b388b80a3f1 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.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 void setup() { 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 ff92319ae39..abbc3b130aa 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.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 static ProtocolSchedule create( * @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 static ProtocolSchedule create( 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 static ProtocolSchedule create( 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 faab15dac4a..8600344cefe 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.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 TransitionProtocolSchedule( * 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 b1f7414e453..0d4aede3a14 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.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 void protocolSpecsAreCreatedAtBlockDefinedInJson() { 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 void mergeSpecificModificationsAreUnappliedForShanghai() { 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 void mergeSpecificModificationsAreUnappliedForCancun_whenShanghaiNotConfi 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 void mergeSpecificModificationsAreUnappliedForAllMainnetForksAfterParis() 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 void parametersAlignWithMainnetWithAdjustments() { 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 54099f868cb..dcfe5f98e34 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.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 @@ default ProtocolSchedule getMergeProtocolSchedule() { 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 5cf74f9458c..3467dce9fb2 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 @@ private static ControllerAndState createControllerAndFinalState( 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 58a50efa261..44c7ddfba8c 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.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 static BftProtocolSchedule create( 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 static BftProtocolSchedule create( bftExtraDataCodec, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -82,6 +90,9 @@ public static BftProtocolSchedule create( * @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 static BftProtocolSchedule create( 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 static BftProtocolSchedule create( bftExtraDataCodec, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } /** @@ -111,6 +126,9 @@ public static BftProtocolSchedule create( * @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 static ProtocolSchedule create( 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 static ProtocolSchedule create( 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 07b3be34b44..020d6e0e5ae 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.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 @@ private BftProtocolSchedule createProtocolSchedule( 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 0aa1f7843bc..71ea4131a3b 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.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 @@ BftContext.class, validators, new QbftExtraDataCodec()), 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 63449d74b50..ad4fe7ddb15 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 Blake2bfMessageDigest() { 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 Blake2bfMessageDigest() { * *

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 static class Blake2bfDigest implements Digest { // 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 static class Blake2bfDigest implements Digest { 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 bd00dc7dae1..390d7d41438 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 @@ 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 @@ */ 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 void throwsIfEmptyBufferUpdatedLargeByteArray() { .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 a8bf7c9afd1..8404453cf18 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 boolean equals(final Object o) { @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 2a62331d336..3e261abf6d7 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.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 BlockchainImporter(final URL blocksUrl, final String genesisJson) throws 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 af5228dc06e..80626ef2fc6 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 void initServerAndClient() throws Exception { 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 6ae5d37a0fc..0fb55fdf344 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 static void initServerAndClient() throws Exception { 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 f8c9dbc18fb..a2a856333ea 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 static void initServerAndClient() throws Exception { 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 2f62e490beb..1d3a3a087a7 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 void initServer() throws Exception { 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 2ff0833bc69..684f843d2fb 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 @@ public void beforeEach() { 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 e650f9d490b..b6d7fa67f81 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 void initServer() throws Exception { 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 5fa137e312c..75927c45130 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 void before() throws URISyntaxException { 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 2444d9db7de..946d4ab09d3 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 @@ private AbstractBlockCreator createBlockCreator(final ProtocolSpecAdapters proto 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 d70589ae832..c6ee454241a 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 void emptyPendingTransactionsResultsInEmptyVettingResult() { 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 62063845342..416e5fd2349 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.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 @@ protected ProtocolSchedule createProtocolSchedule() { 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 e9bfcfb762a..a59841d4f4f 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.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 @@ protected ProtocolSchedule createProtocolSchedule() { 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 2cd5bc5e9e2..7e3c01200ce 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 @@ void createMainnetBlock1() throws IOException { PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - miningParameters, - new BadBlockManager()) + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule()) .build(); @@ -158,8 +160,10 @@ void createMainnetBlock1_fixedDifficulty1() { PrivacyParameters.DEFAULT, false, EvmConfiguration.DEFAULT, - miningParameters, - new BadBlockManager()) + MiningParameters.MINING_DISABLED, + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule()) .build(); @@ -209,8 +213,10 @@ void rewardBeneficiary_zeroReward_skipZeroRewardsFalse() { 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 @@ void rewardBeneficiary_zeroReward_skipZeroRewardsTrue() { 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 b7f8395d92f..b86b2b0de22 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.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 static ProtocolSchedule create( 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 static ProtocolSchedule create( isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager) + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem) .createProtocolSchedule(); } @@ -52,27 +57,35 @@ public static ProtocolSchedule create( 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 8ecfa453d9f..480a1d8d7ab 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.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 BlockProcessingResult processBlock( 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 BlockProcessingResult processBlock( 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 BlockProcessingResult processBlock( 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 @@ abstract boolean rewardCoinbase( 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 aec844894f7..47c1747dc95 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.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 @@ private 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 static ProtocolSpecBuilder tangerineWhistleDefinition( } 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 static ProtocolSpecBuilder dieHardDefinition( 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 static ProtocolSpecBuilder gothamDefinition( 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 static ProtocolSpecBuilder atlantisDefinition( 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 static ProtocolSpecBuilder aghartaDefinition( 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 static ProtocolSpecBuilder phoenixDefinition( 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 static ProtocolSpecBuilder thanosDefinition( 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 static ProtocolSpecBuilder magnetoDefinition( 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 static ProtocolSpecBuilder mystiqueDefinition( 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 static ProtocolSpecBuilder spiralDefinition( 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 794f96cfb39..88b6a5ae1be 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.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 static ProtocolSchedule fromConfig( 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 static ProtocolSchedule fromConfig( isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } return new ProtocolScheduleBuilder( config, @@ -66,7 +73,9 @@ public static ProtocolSchedule fromConfig( isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager) + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem) .createProtocolSchedule(); } @@ -79,6 +88,7 @@ public static ProtocolSchedule fromConfig( * @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 static ProtocolSchedule fromConfig( 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 static ProtocolSchedule fromConfig( * @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 static ProtocolSchedule fromConfig( * 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 aa9bae6c7e3..55bfb363baa 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 @@ 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 ProtocolSpecBuilder pragueEOFDefinition(final GenesisConfigOptions genesi */ 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 ProtocolSpecBuilder futureEipsDefinition(final GenesisConfigOptions genes 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 6f09df923eb..36d8257ffb9 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.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.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 static ProtocolSpecBuilder frontierDefinition(final EvmConfiguration evmC .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 static BlockValidatorBuilder blockValidatorBuilder() { 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 static ProtocolSpecBuilder homesteadDefinition(final EvmConfiguration evm } 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 static ProtocolSpecBuilder daoRecoveryInitDefinition( 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 static ProtocolSpecBuilder spuriousDragonDefinition( 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 static ProtocolSpecBuilder byzantiumDefinition( 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 static ProtocolSpecBuilder constantinopleDefinition( 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 static ProtocolSpecBuilder petersburgDefinition( 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 static ProtocolSpecBuilder istanbulDefinition( 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 @@ static ProtocolSpecBuilder muirGlacierDefinition( 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 @@ static ProtocolSpecBuilder londonDefinition( 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 @@ static ProtocolSpecBuilder londonDefinition( 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 @@ static ProtocolSpecBuilder arrowGlacierDefinition( 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 @@ static ProtocolSpecBuilder grayGlacierDefinition( 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 @@ static ProtocolSpecBuilder parisDefinition( 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 @@ static ProtocolSpecBuilder shanghaiDefinition( 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 @@ static ProtocolSpecBuilder cancunDefinition( 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 @@ static ProtocolSpecBuilder cancunDefinition( } 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 @@ static ProtocolSpecBuilder cancunEOFDefinition( 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 @@ static ProtocolSpecBuilder pragueDefinition( 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 @@ static ProtocolSpecBuilder pragueEOFDefinition( 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 @@ static ProtocolSpecBuilder futureEipsDefinition( 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 @@ static ProtocolSpecBuilder experimentalEipsDefinition( 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 9ad1db7d896..5fa2b119f1c 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 TransactionProcessingResult processTransaction( 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 TransactionProcessingResult processTransaction( 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 649442f88c1..1cb3a5cb3c5 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.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 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 ProtocolScheduleBuilder( isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } public ProtocolScheduleBuilder( @@ -73,7 +80,9 @@ public 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 ProtocolScheduleBuilder( isRevertReasonEnabled, evmConfiguration, miningParameters, - badBlockManager); + badBlockManager, + isParallelTxProcessingEnabled, + metricsSystem); } private ProtocolScheduleBuilder( @@ -93,7 +104,9 @@ private 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 @@ private ProtocolScheduleBuilder( this.defaultChainId = defaultChainId; this.miningParameters = miningParameters; this.badBlockManager = badBlockManager; + this.isParallelTxProcessingEnabled = isParallelTxProcessingEnabled; + this.metricsSystem = metricsSystem; } public ProtocolSchedule createProtocolSchedule() { @@ -121,7 +136,9 @@ private void initSchedule( config.getEcip1017EraRounds(), evmConfiguration.overrides( config.getContractSizeLimit(), OptionalInt.empty(), config.getEvmStackSize()), - miningParameters); + miningParameters, + isParallelTxProcessingEnabled, + metricsSystem); validateForkOrdering(); @@ -203,7 +220,8 @@ private void initSchedule( 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 cd886b6c847..0d792b7870c 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 00000000000..d1f0d9c5127 --- /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 00000000000..c6beaa2f40e --- /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 00000000000..30305ce00b5 --- /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 00000000000..4120c0edb1e --- /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 00000000000..8f58e697fee --- /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 ad838aa528d..b62805c1fda 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 BonsaiWorldState( 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 b5bae0aed9b..0799ed3db27 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 DiffBasedWorldStateUpdateAccumulator( this.evmConfiguration = evmConfiguration; } - protected void cloneFromUpdater(final DiffBasedWorldStateUpdateAccumulator source) { + public void cloneFromUpdater(final DiffBasedWorldStateUpdateAccumulator source) { accountsToUpdate.putAll(source.getAccountsToUpdate()); codeToUpdate.putAll(source.codeToUpdate); storageToClear.addAll(source.storageToClear); @@ -100,6 +100,120 @@ protected void cloneFromUpdater(final 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 @@ protected Consumer getStoragePreloader() { return storagePreloader; } - protected EvmConfiguration getEvmConfiguration() { + public EvmConfiguration getEvmConfiguration() { return evmConfiguration; } @@ -234,6 +348,7 @@ public void revert() { @Override public void commit() { this.isAccumulatorStateChanged = true; + for (final Address deletedAddress : getDeletedAccounts()) { final DiffBasedValue accountValue = accountsToUpdate.computeIfAbsent( @@ -305,7 +420,6 @@ public void commit() { final ACCOUNT updatedAccount; final DiffBasedValue updatedAccountValue = accountsToUpdate.get(updatedAddress); - final Map> pendingStorageUpdates = storageToUpdate.computeIfAbsent( updatedAddress, @@ -359,12 +473,6 @@ public void commit() { pendingStorageUpdates.clear(); } - // This is especially to avoid unnecessary computation for withdrawals and - // self-destruct beneficiaries - if (updatedAccount.getUpdatedStorage().isEmpty()) { - return; - } - // parallel stream here may cause database corruption updatedAccount .getUpdatedStorage() 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 646e67d2da5..615b5bad6eb 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 @@ -85,6 +85,8 @@ interface Unstable { boolean DEFAULT_BONSAI_FULL_FLAT_DB_ENABLED = true; boolean DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED = true; + boolean DEFAULT_PARALLEL_TRX_ENABLED = false; + DataStorageConfiguration.Unstable DEFAULT = ImmutableDataStorageConfiguration.Unstable.builder().build(); @@ -100,5 +102,10 @@ default boolean getBonsaiFullFlatDbEnabled() { default boolean getBonsaiCodeStoredByCodeHashEnabled() { return DEFAULT_BONSAI_CODE_USING_CODE_HASH_ENABLED; } + + @Value.Default + default boolean isParallelTxProcessingEnabled() { + return DEFAULT_PARALLEL_TRX_ENABLED; + } } } diff --git a/ethereum/core/src/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 60b40c5f24b..551f593e825 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 @@ -142,7 +142,9 @@ private static ProtocolSchedule mainnetProtocolScheduleProvider( genesisConfigFile.getConfigOptions(), EvmConfiguration.DEFAULT, MiningParameters.newDefault(), - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); } private static ProtocolContext mainnetProtocolContextProvider( 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 5aa00d0ed64..91ab41b636d 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 @@ -146,7 +146,9 @@ public ExecutionContextTestFixture build() { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()) + new BadBlockManager(), + false, + new NoOpMetricsSystem()) .createProtocolSchedule(); } if (blockchainKeyValueStorage == null) { diff --git a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ProtocolScheduleFixture.java b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ProtocolScheduleFixture.java index a4c6556ea34..e94c6b49fd0 100644 --- a/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ProtocolScheduleFixture.java +++ b/ethereum/core/src/test-support/java/org/hyperledger/besu/ethereum/core/ProtocolScheduleFixture.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.mainnet.MainnetProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.io.IOException; @@ -39,7 +40,9 @@ public class ProtocolScheduleFixture { false, EvmConfiguration.DEFAULT, MiningParameters.newDefault(), - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); private static GenesisConfigOptions getMainnetConfigOptions() { // this method avoids reading all the alloc accounts when all we want is the "config" section diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java index d2d1fed8b73..d3a261803fb 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/BlockImportExceptionHandlingTest.java @@ -41,6 +41,7 @@ import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; import org.hyperledger.besu.ethereum.mainnet.blockhash.FrontierBlockHashProcessor; +import org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket; import org.hyperledger.besu.ethereum.mainnet.requests.RequestsValidatorCoordinator; import org.hyperledger.besu.ethereum.storage.StorageProvider; import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.BonsaiWorldStateProvider; @@ -50,6 +51,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.evm.gascalculator.GasCalculator; import org.hyperledger.besu.evm.internal.EvmConfiguration; import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.hyperledger.besu.plugin.services.exception.StorageException; @@ -80,6 +82,8 @@ class BlockImportExceptionHandlingTest { private final BlockBodyValidator blockBodyValidator = mock(BlockBodyValidator.class); private final ProtocolContext protocolContext = mock(ProtocolContext.class); private final ProtocolSpec protocolSpec = mock(ProtocolSpec.class); + private final GasCalculator gasCalculator = mock(GasCalculator.class); + private final FeeMarket feeMarket = mock(FeeMarket.class); protected final MutableBlockchain blockchain = mock(MutableBlockchain.class); private final StorageProvider storageProvider = new InMemoryKeyValueStorageProvider(); @@ -116,6 +120,8 @@ public void setup() { when(protocolSpec.getRequestsValidatorCoordinator()) .thenReturn(RequestsValidatorCoordinator.empty()); when(protocolSpec.getBlockHashProcessor()).thenReturn(new FrontierBlockHashProcessor()); + when(protocolSpec.getGasCalculator()).thenReturn(gasCalculator); + when(protocolSpec.getFeeMarket()).thenReturn(feeMarket); mainnetBlockValidator = new MainnetBlockValidator( blockHeaderValidator, blockBodyValidator, blockProcessor, badBlockManager); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java index adaf4c476b2..7969ab6824a 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/difficulty/fixed/FixedProtocolScheduleTest.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.junit.jupiter.api.Test; @@ -36,7 +37,9 @@ public void reportedDifficultyForAllBlocksIsAFixedValue() { GenesisConfigFile.fromResource("/dev.json").getConfigOptions(), EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); final BlockHeaderTestFixture headerBuilder = new BlockHeaderTestFixture(); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolScheduleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolScheduleTest.java index 9e4522912d7..2d5dd2cee34 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolScheduleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/DefaultProtocolScheduleTest.java @@ -25,6 +25,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; import java.util.Optional; @@ -61,7 +62,9 @@ public void setup() { isRevertReasonEnabled, evmConfiguration, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); } @Test diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolScheduleTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolScheduleTest.java index fa8cda5cffc..c63a9b5ccbd 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolScheduleTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/MainnetProtocolScheduleTest.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.ProtocolScheduleFixture; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; @@ -73,7 +74,9 @@ public void shouldOnlyUseFrontierWhenEmptyJsonConfigIsUsed() { GenesisConfigFile.fromConfig("{}").getConfigOptions(), EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); Assertions.assertThat(sched.getByBlockHeader(blockHeader(1L)).getName()).isEqualTo("Frontier"); Assertions.assertThat(sched.getByBlockHeader(blockHeader(Long.MAX_VALUE)).getName()) .isEqualTo("Frontier"); @@ -88,7 +91,9 @@ public void createFromConfigWithSettings() { GenesisConfigFile.fromConfig(json).getConfigOptions(), EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); Assertions.assertThat(sched.getByBlockHeader(blockHeader(1)).getName()).isEqualTo("Frontier"); Assertions.assertThat(sched.getByBlockHeader(blockHeader(2)).getName()).isEqualTo("Homestead"); Assertions.assertThat(sched.getByBlockHeader(blockHeader(3)).getName()) @@ -120,7 +125,9 @@ public void outOfOrderConstantinoplesFail() { GenesisConfigFile.fromConfig(json).getConfigOptions(), EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager())); + new BadBlockManager(), + false, + new NoOpMetricsSystem())); } private BlockHeader blockHeader(final long number) { 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 c7be26039e3..0e1011de761 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 @@ -29,6 +29,7 @@ import org.hyperledger.besu.ethereum.core.MiningParameters; import org.hyperledger.besu.ethereum.core.PrivacyParameters; import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; import java.math.BigInteger; import java.util.OptionalLong; @@ -61,7 +62,9 @@ public void setup() { false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); } @Test @@ -216,7 +219,9 @@ private MilestoneStreamingProtocolSchedule createScheduleModifiedAt(final int bl false, EvmConfiguration.DEFAULT, MiningParameters.MINING_DISABLED, - new BadBlockManager()); + new BadBlockManager(), + false, + new NoOpMetricsSystem()); return new MilestoneStreamingProtocolSchedule( (DefaultProtocolSchedule) builder.createProtocolSchedule()); diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessorTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessorTest.java new file mode 100644 index 00000000000..bba91843568 --- /dev/null +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/parallelization/ParallelizedConcurrentTransactionProcessorTest.java @@ -0,0 +1,213 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.ethereum.mainnet.parallelization; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Hash; +import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.BlockHeader; +import org.hyperledger.besu.ethereum.core.InMemoryKeyValueStorageProvider; +import org.hyperledger.besu.ethereum.core.Transaction; +import org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor; +import org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams; +import org.hyperledger.besu.ethereum.mainnet.ValidationResult; +import org.hyperledger.besu.ethereum.privacy.storage.PrivateMetadataUpdater; +import org.hyperledger.besu.ethereum.processing.TransactionProcessingResult; +import org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.NoOpBonsaiCachedWorldStorageManager; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.cache.NoopBonsaiCachedMerkleTrieLoader; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.storage.BonsaiWorldStateKeyValueStorage; +import org.hyperledger.besu.ethereum.trie.diffbased.bonsai.worldview.BonsaiWorldState; +import org.hyperledger.besu.ethereum.trie.diffbased.common.trielog.NoOpTrieLogManager; +import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.DiffBasedWorldStateConfig; +import org.hyperledger.besu.ethereum.trie.diffbased.common.worldview.accumulator.DiffBasedWorldStateUpdateAccumulator; +import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; +import org.hyperledger.besu.evm.internal.EvmConfiguration; +import org.hyperledger.besu.evm.operation.BlockHashOperation; +import org.hyperledger.besu.evm.tracing.OperationTracer; +import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; + +import java.util.Collections; +import java.util.Optional; + +import org.apache.tuweni.bytes.Bytes; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class ParallelizedConcurrentTransactionProcessorTest { + + @Mock private MainnetTransactionProcessor transactionProcessor; + @Mock private BlockHeader blockHeader; + @Mock private Transaction transaction; + @Mock private PrivateMetadataUpdater privateMetadataUpdater; + @Mock private TransactionCollisionDetector transactionCollisionDetector; + + private BonsaiWorldState worldState; + + private ParallelizedConcurrentTransactionProcessor processor; + + @BeforeEach + void setUp() { + processor = + new ParallelizedConcurrentTransactionProcessor( + transactionProcessor, transactionCollisionDetector); + final BonsaiWorldStateKeyValueStorage bonsaiWorldStateKeyValueStorage = + new BonsaiWorldStateKeyValueStorage( + new InMemoryKeyValueStorageProvider(), + new NoOpMetricsSystem(), + DataStorageConfiguration.DEFAULT_BONSAI_CONFIG); + worldState = + new BonsaiWorldState( + bonsaiWorldStateKeyValueStorage, + new NoopBonsaiCachedMerkleTrieLoader(), + new NoOpBonsaiCachedWorldStorageManager(bonsaiWorldStateKeyValueStorage), + new NoOpTrieLogManager(), + EvmConfiguration.DEFAULT, + new DiffBasedWorldStateConfig()); + when(transactionCollisionDetector.hasCollision(any(), any(), any(), any())).thenReturn(false); + } + + @Test + void testRunTransaction() { + Address miningBeneficiary = Address.fromHexString("0x1"); + Wei blobGasPrice = Wei.ZERO; + + Mockito.when( + transactionProcessor.processTransaction( + any(), any(), any(), any(), any(), any(), anyBoolean(), any(), any(), any())) + .thenReturn( + TransactionProcessingResult.successful( + Collections.emptyList(), 0, 0, Bytes.EMPTY, ValidationResult.valid())); + + processor.runTransaction( + worldState, + blockHeader, + 0, + transaction, + miningBeneficiary, + (blockNumber) -> Hash.EMPTY, + blobGasPrice, + privateMetadataUpdater); + + verify(transactionProcessor, times(1)) + .processTransaction( + any(DiffBasedWorldStateUpdateAccumulator.class), + eq(blockHeader), + eq(transaction), + eq(miningBeneficiary), + any(OperationTracer.class), + any(BlockHashOperation.BlockHashLookup.class), + eq(true), + eq(TransactionValidationParams.processingBlock()), + eq(privateMetadataUpdater), + eq(blobGasPrice)); + + assertTrue( + processor + .applyParallelizedTransactionResult( + worldState, miningBeneficiary, transaction, 0, Optional.empty(), Optional.empty()) + .isPresent(), + "Expected the transaction context to be stored"); + } + + @Test + void testRunTransactionWithFailure() { + Address miningBeneficiary = Address.fromHexString("0x1"); + Wei blobGasPrice = Wei.ZERO; + + when(transactionProcessor.processTransaction( + any(), any(), any(), any(), any(), any(), anyBoolean(), any(), any(), any())) + .thenReturn( + TransactionProcessingResult.failed( + 0, + 0, + ValidationResult.invalid( + TransactionInvalidReason.BLOB_GAS_PRICE_BELOW_CURRENT_BLOB_BASE_FEE), + Optional.of(Bytes.EMPTY))); + + processor.runTransaction( + worldState, + blockHeader, + 0, + transaction, + miningBeneficiary, + (blockNumber) -> Hash.EMPTY, + blobGasPrice, + privateMetadataUpdater); + + Optional 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 00000000000..0cd1bad3c57 --- /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 845b859ef73..388a112699a 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 ac3b8f2fc62..b11afeb4c56 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.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 void setup() { 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 2b9105ed46d..72f089a53eb 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.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 void blockHeadersRoundTrip() throws IOException { 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 4bad73ebb64..5f7baaff418 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 9afba66ad3a..cfc9f9dc123 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.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 ecb72881ed4..6dc69ea274e 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.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 5fb47a557ac..a5d2cf61045 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.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 23eb9d02bf6..cd780c2dc99 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 @@ protected static ExecutionContextTestFixture createExecutionContextTestFixtureBa 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 8e9bda89c05..c679183b0ff 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 TestNode( 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 ef8d0701782..5742637c3e8 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 @@ private void setupScheduleWith(final StubGenesisConfigOptions config) { 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 db70ccf41f0..4f10650273a 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.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 @@ ProtocolSchedule provideProtocolSchedule( } 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 @@ private static Supplier createSchedule(final GenesisConfigOpti 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 11db6b8eeee..3c073136acd 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 8ac419f7a68..5dfb12f1d61 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.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 @@ private static ProtocolSchedule createSchedule(final GenesisConfigOptions option 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 6377b1ae3ba..00733de1f8e 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 @@ 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.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 static Stream getTestParametersForConfig() throws IOException 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 fd39ef7f44c..32d4e0bab10 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 @@ private boolean buildContext( 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 34e28bbb32f..f139386118a 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 @@ 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 @@ default void tracePrepareTransaction(final WorldView worldView, final Transactio */ 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 d419a6ac7c5..4151320177b 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 64e18a70b712a1003d778c90c3841498b9aaa7da Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 22 Jul 2024 09:22:33 +1000 Subject: [PATCH 007/124] 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 Signed-off-by: gconnect --- .../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 9df006722e9..9a4c83e9625 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 @@ /** * 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 1048f6238a2..4645abdfcf9 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 ReferenceTestBlockHeader( @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 ReferenceTestBlockHeader( 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 9748d2aa030..a36d3804323 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 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 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 3d7ad162a0e78704fb7f1dc1771947fc05b1732d 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 008/124] Fix NPE for legacy ForkId with no forks (#7349) Fix NPE for legacy ForkId with no forks Signed-off-by: stefan.pingel@consensys.net Signed-off-by: gconnect --- .../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 859fb918a4d..407e5149d67 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 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 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 84c24bc9a25..df97386e9f0 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.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 static Stream data() { 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 void assertBackwardCompatibilityWorks( 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 325fd41c812..bc9196e6d50 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 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 List getForkAndHashList() { } 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 static ForkId readFrom(final RLPInput in) { } 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 93a80be2fd2..3a3331b568f 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.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.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 void transactionMessagesGoToTheCorrectExecutor() { } @Test - public void forkIdForChainHeadMayBeNull() { + public void forkIdForChainHeadLegacyNoForksNotEmpty() { final EthScheduler ethScheduler = mock(EthScheduler.class); try (final EthProtocolManager ethManager = EthProtocolManagerTestUtil.create( @@ -1149,7 +1151,13 @@ public void forkIdForChainHeadMayBeNull() { 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 e3ed95edf3bb7c9d64298dd53e70d2f54de70a09 Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Tue, 23 Jul 2024 10:25:07 +0100 Subject: [PATCH 009/124] 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> Signed-off-by: gconnect --- 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 9c6cb373ba8..d0e62bc5ef6 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 7ed627cfc17..dfd09165b7d 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 RunnerBuilder allowedSubnets(final List allowedSubnets) { 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 Runner build() { 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 Runner build() { 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 198c26fe2a8..2607f6e5953 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 @@ void setBannedNodeIds(final List values) { } } + // 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 @@ private Runner synchronize( .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 efeff412d62..c892ffe7fe6 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 void bootnodesUrlCliArgTakesPrecedenceOverGenesisFile() throws IOExceptio 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 8a6a5781198..c77ced5c6fe 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 void initMocks() throws Exception { 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 3243b056135..8ae2105efd6 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 a5e03bd5990..27ea5c16453 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 86bb079a298..3f59abf2fdf 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 DiscoveryConfiguration setBootnodes(final List bootnodes) { 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 d1f17b5304e..7efc50750fb 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 @@ private PeerDiscoveryController createController(final DiscoveryPeer localNode) .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 5d0fee18453..11b5216a82b 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 @@ private 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 @@ private 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 @@ RecursivePeerRefreshState getRecursivePeerRefreshState() { */ 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 static class Builder { 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 PeerDiscoveryController build() { metricsSystem, Optional.of(cachedEnrRequests), filterOnEnrForkId, - rlpxAgent); + rlpxAgent, + includeBootnodesOnPeerRefresh); } private void validate() { @@ -953,5 +968,10 @@ public Builder rlpxAgent(final RlpxAgent rlpxAgent) { this.rlpxAgent = rlpxAgent; return this; } + + public Builder includeBootnodesOnPeerRefresh(final boolean includeBootnodesOnPeerRefresh) { + this.includeBootnodesOnPeerRefresh = includeBootnodesOnPeerRefresh; + return this; + } } } From 4b31e6ec708697b5451578f64b2321d255df311d Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Wed, 24 Jul 2024 14:51:25 +1000 Subject: [PATCH 010/124] Disable limit trie logs for trie log subcommand (#7366) This avoids executing TrieLogPruner.preload Signed-off-by: Simon Dudley Signed-off-by: gconnect --- 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 d0e62bc5ef6..8b999bca71e 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 2607f6e5953..1eaab20bd27 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 @@ private MiningParameters getMiningParameters() { 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 de42616822f..e054bfb615b 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.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 void run() { } 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 00000000000..66536070a7b --- /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 d5f036492662151edaa3c3c58888bd698ad580be Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Wed, 24 Jul 2024 08:36:38 -0600 Subject: [PATCH 011/124] 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 Signed-off-by: gconnect --- .../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 2d9be8d3129..06ef2da2536 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 static void registerFrontierOperations( 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 static void registerConstantinopleOperations( 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 @@ private static void registerEOFOperations( 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 37a92ffc6ef..2f1c1391826 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 OperationResult execute(final MessageFrame frame, final EVM evm) { 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 953ddfb04d2..c08331b0065 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 OperationResult execute(final MessageFrame frame, final EVM evm) { 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 95e5acc6ff1..1779175f152 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 OperationResult execute(final MessageFrame frame, final EVM evm) { 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 ac816137af3..13f04849887 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.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 cebffeb9105..9692c27625d 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.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 d19e94e0a62..3ce7e3c207a 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 fe662893e1e..9d7fa85d416 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.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 969039266d8..acae6249c4d 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 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 3cea9300e11..b8a254bbe40 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 73a4abd34ab..51e2863a69b 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.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 4fa5a0fdd74..c10d8f3d6c8 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.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 83d7f09e5a9..af5922aa074 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.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 86a0f8cce10..d5d1212dfba 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 946dd0b52eb..c43893a5435 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.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 00000000000..b45824a92b4 --- /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 a7ca5eefe67..97461cdbcdb 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.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 @@ void shouldZeroOutLeftMostBitsToGetAddress() { 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 00000000000..8c324692234 --- /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 d83e9f3ddc5..e1881892d53 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.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 76f267ec538..90f2d300887 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.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 52a7211050c..4611faa0f87 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.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 3c466422ed3..7b9fab338e0 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.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 f2cf9506837..b4865df5d23 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 29753129209..6bf5a8afd21 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 25a2682e87d..28340920a07 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.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 3309fccce81..d7440b07961 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.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 31042257759..7ca5eb04caa 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.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 672628140cf..f2a0947086b 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.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 9ffc422d609..d5094494a3c 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 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 3993d9f81e7..6f3c7fd21f6 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.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 86182e47e39..c7d7cad00dc 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 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 7842174e90d..d3a3db754b0 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.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 b567cb6302f..a4d0b8f3104 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 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 659c50d35ce..5acc7466a2e 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 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 c73a4544f9f..c7c3470825a 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.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 260b8f6fedb4b62aa505d67baf75cff9f2c21695 Mon Sep 17 00:00:00 2001 From: gconnect Date: Sun, 4 Aug 2024 22:39:40 +0100 Subject: [PATCH 012/124] add option for ephemery testnet Signed-off-by: gconnect --- .../besu/cli/config/NetworkName.java | 3 + config/src/main/resources/ephemery.json | 911 ++++++++++++++++++ 2 files changed, 914 insertions(+) create mode 100644 config/src/main/resources/ephemery.json diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java index f864068bb4e..ae432021950 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java @@ -31,6 +31,9 @@ public enum NetworkName { /** LUKSO mainnet network name. */ LUKSO("/lukso.json", BigInteger.valueOf(42)), + /** EPHEMERY network name. */ + EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135)), + /** Dev network name. */ DEV("/dev.json", BigInteger.valueOf(2018), false), /** Future EIPs network name. */ diff --git a/config/src/main/resources/ephemery.json b/config/src/main/resources/ephemery.json new file mode 100644 index 00000000000..fec3d5463b8 --- /dev/null +++ b/config/src/main/resources/ephemery.json @@ -0,0 +1,911 @@ +{ + "config": { + "chainId": 39438135, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "preMergeForkBlock": 0, + "terminalTotalDifficulty": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "depositContractAddress": "0x4242424242424242424242424242424242424242", + "ethash": {} + }, + "alloc": { + "0x0000000000000000000000000000000000000000": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000001": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000002": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000003": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000004": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000005": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000006": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000007": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000008": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000009": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000000f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000010": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000011": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000012": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000013": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000014": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000015": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000016": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000017": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000018": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000019": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000001f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000020": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000021": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000022": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000023": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000024": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000025": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000026": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000027": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000028": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000029": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000002f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000030": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000031": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000032": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000033": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000034": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000035": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000036": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000037": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000038": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000039": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000003f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000040": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000041": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000042": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000043": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000044": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000045": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000046": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000047": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000048": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000049": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000004f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000050": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000051": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000052": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000053": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000054": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000055": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000056": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000057": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000058": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000059": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000005f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000060": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000061": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000062": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000063": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000064": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000065": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000066": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000067": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000068": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000069": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000006f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000070": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000071": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000072": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000073": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000074": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000075": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000076": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000077": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000078": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000079": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000007f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000080": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000081": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000082": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000083": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000084": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000085": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000086": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000087": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000088": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000089": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000008f": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000090": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000091": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000092": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000093": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000094": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000095": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000096": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000097": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000098": { + "balance": "1" + }, + "0x0000000000000000000000000000000000000099": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009a": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009b": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009c": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009d": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009e": { + "balance": "1" + }, + "0x000000000000000000000000000000000000009f": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000a9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000aa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ab": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ac": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ad": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ae": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000af": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000b9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ba": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000be": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000bf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000c9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ca": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ce": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000cf": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000d9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000da": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000db": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000dd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000de": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000df": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000e9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ea": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000eb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ec": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ed": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ee": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ef": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f0": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f1": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f2": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f3": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f4": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f5": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f6": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f7": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f8": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000f9": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fa": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fb": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fc": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fd": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000fe": { + "balance": "1" + }, + "0x00000000000000000000000000000000000000ff": { + "balance": "1" + }, + "0x4242424242424242424242424242424242424242": { + "balance": "0", + "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + } + }, + "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02": { + "balance": "0", + "nonce": "1", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500" + }, + "0xa2A6d93439144FFE4D27c9E088dCD8b783946263": { + "balance": "1000000000000000000000000" + }, + "0xBc11295936Aa79d594139de1B2e12629414F3BDB": { + "balance": "1000000000000000000000000" + }, + "0x7cF5b79bfe291A67AB02b393E456cCc4c266F753": { + "balance": "1000000000000000000000000" + }, + "0xaaec86394441f915bce3e6ab399977e9906f3b69": { + "balance": "1000000000000000000000000" + }, + "0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8": { + "balance": "1000000000000000000000000" + }, + "0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8": { + "balance": "1000000000000000000000000" + }, + "0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e": { + "balance": "1000000000000000000000000" + }, + "0xe2e2659028143784d557bcec6ff3a0721048880a": { + "balance": "1000000000000000000000000" + }, + "0xd9a5179f091d85051d3c982785efd1455cec8699": { + "balance": "1000000000000000000000000" + }, + "0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf": { + "balance": "1000000000000000000000000" + }, + "0x0000006916a87b82333f4245046623b23794c65c": { + "balance": "10000000000000000000000000" + }, + "0xb21c33de1fab3fa15499c62b59fe0cc3250020d1": { + "balance": "100000000000000000000000000" + }, + "0x10F5d45854e038071485AC9e402308cF80D2d2fE": { + "balance": "100000000000000000000000000" + }, + "0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E": { + "balance": "100000000000000000000000000" + }, + "0x799D329e5f583419167cD722962485926E338F4a": { + "balance": "1000000000000000000" + }, + "0x4c2ae482593505f0163cdefc073e81c63cda4107": { + "balance": "1000000000000000000000000" + }, + "0xa8e8f14732658e4b51e8711931053a8a69baf2b1": { + "balance": "1000000000000000000000000" + }, + "0xe0a2bd4258d2768837baa26a28fe71dc079f84c7": { + "balance": "100000000000000000000000000" + }, + "0x1eA692E68a7765dE26FC03A6D74EE5B56A7e2b4d": { + "balance": "100000000000000000000000000" + }, + "0x57c3dfd40A86628B67721115d7A03C9F341d7718": { + "balance": "100000000000000000000000000" + }, + "0xc90E920F4DCfd4954230edCaB168D0C5B9561e03": { + "balance": "1000000000000000000000000000" + }, + "0x6Cc9397c3B38739daCbfaA68EaD5F5D77Ba5F455": { + "balance": "10000000000000000000000000" + }, + "0x992775d32fd0ec76b95C5E76CeEA92ED5a4bE1F9": { + "balance": "10000000000000000000000000" + } + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "baseFeePerGas": "0x3B9ACA00", + "difficulty": "0x01", + "extraData": "", + "gasLimit": "0x1c9c380", + "nonce": "0x1234", + "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "1720119600" +} From 05da951dc5150b66f3536fe6a7e16352e6415f4b Mon Sep 17 00:00:00 2001 From: gconnect Date: Sun, 4 Aug 2024 22:53:37 +0100 Subject: [PATCH 013/124] add ephemery bootnodes to the ephemery.json genesis file Signed-off-by: gconnect --- config/src/main/resources/ephemery.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/config/src/main/resources/ephemery.json b/config/src/main/resources/ephemery.json index fec3d5463b8..5924633d196 100644 --- a/config/src/main/resources/ephemery.json +++ b/config/src/main/resources/ephemery.json @@ -16,7 +16,13 @@ "shanghaiTime": 0, "cancunTime": 0, "depositContractAddress": "0x4242424242424242424242424242424242424242", - "ethash": {} + "ethash": {}, + "discovery": { + "bootnodes": [ + "enode://50a54ecbd2175497640bcf46a25bbe9bb4fae51d7cc2a29ef4947a7ee17496cf39a699b7fe6b703ed0feb9dbaae7e44fc3827fcb7435ca9ac6de4daa4d983b3d@137.74.203.240:30303", + "enode://0f2c301a9a3f9fa2ccfa362b79552c052905d8c2982f707f46cd29ece5a9e1c14ecd06f4ac951b228f059a43c6284a1a14fce709e8976cac93b50345218bf2e9@135.181.140.168:30343" + ] + } }, "alloc": { "0x0000000000000000000000000000000000000000": { From dd3ab095cd47fe094beeae972b04ddf3047eafb9 Mon Sep 17 00:00:00 2001 From: gconnect Date: Sun, 4 Aug 2024 23:47:40 +0100 Subject: [PATCH 014/124] Add test for ephemery Signed-off-by: gconnect --- .../hyperledger/besu/cli/BesuCommandTest.java | 27 +++++++++++++++---- .../cli/NetworkDeprecationMessageTest.java | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) 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 c892ffe7fe6..35be94e7ed1 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -17,15 +17,16 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.is; +import static org.hyperledger.besu.cli.config.NetworkName.MAINNET; +import static org.hyperledger.besu.cli.config.NetworkName.FUTURE_EIPS; import static org.hyperledger.besu.cli.config.NetworkName.CLASSIC; -import static org.hyperledger.besu.cli.config.NetworkName.DEV; import static org.hyperledger.besu.cli.config.NetworkName.EXPERIMENTAL_EIPS; -import static org.hyperledger.besu.cli.config.NetworkName.FUTURE_EIPS; -import static org.hyperledger.besu.cli.config.NetworkName.HOLESKY; -import static org.hyperledger.besu.cli.config.NetworkName.LUKSO; -import static org.hyperledger.besu.cli.config.NetworkName.MAINNET; import static org.hyperledger.besu.cli.config.NetworkName.MORDOR; import static org.hyperledger.besu.cli.config.NetworkName.SEPOLIA; +import static org.hyperledger.besu.cli.config.NetworkName.HOLESKY; +import static org.hyperledger.besu.cli.config.NetworkName.LUKSO; +import static org.hyperledger.besu.cli.config.NetworkName.DEV; +import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ENGINE; import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_BOOTSTRAP_NODES; import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_DISCOVERY_URL; @@ -1786,6 +1787,22 @@ public void luksoValuesAreUsed() { assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } + @Test + public void ephemeryValuesAreUsed() { + parseCommand("--network", "ephemery"); + + final ArgumentCaptor networkArg = + ArgumentCaptor.forClass(EthNetworkConfig.class); + + verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any()); + verify(mockControllerBuilder).build(); + + assertThat(networkArg.getValue()).isEqualTo(EthNetworkConfig.getNetworkConfig(EPHEMERY)); + + assertThat(commandOutput.toString(UTF_8)).isEmpty(); + assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); + } + @Test public void classicValuesAreUsed() { parseCommand("--network", "classic"); 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 87be2a699e3..e56e3744f0b 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java @@ -40,7 +40,7 @@ void shouldGenerateDeprecationMessageForDeprecatedNetworks(final NetworkName net @EnumSource( value = NetworkName.class, names = { - "MAINNET", "SEPOLIA", "DEV", "CLASSIC", "MORDOR", "HOLESKY", "LUKSO", + "MAINNET", "SEPOLIA", "DEV", "CLASSIC", "MORDOR", "HOLESKY", "LUKSO", "EPHEMERY" }) void shouldThrowErrorForNonDeprecatedNetworks(final NetworkName network) { assertThatThrownBy(() -> NetworkDeprecationMessage.generate(network)) From 4d678a41bdcb157333da2577a12aa55f3b01a9b8 Mon Sep 17 00:00:00 2001 From: gconnect Date: Mon, 5 Aug 2024 01:26:29 +0100 Subject: [PATCH 015/124] Format code with sportlessApply Signed-off-by: gconnect --- .../org/hyperledger/besu/cli/BesuCommandTest.java | 14 +++++++------- .../besu/cli/NetworkDeprecationMessageTest.java | 4 +--- 2 files changed, 8 insertions(+), 10 deletions(-) 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 35be94e7ed1..cd829b1561b 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -17,16 +17,16 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.is; -import static org.hyperledger.besu.cli.config.NetworkName.MAINNET; -import static org.hyperledger.besu.cli.config.NetworkName.FUTURE_EIPS; import static org.hyperledger.besu.cli.config.NetworkName.CLASSIC; +import static org.hyperledger.besu.cli.config.NetworkName.DEV; +import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; import static org.hyperledger.besu.cli.config.NetworkName.EXPERIMENTAL_EIPS; -import static org.hyperledger.besu.cli.config.NetworkName.MORDOR; -import static org.hyperledger.besu.cli.config.NetworkName.SEPOLIA; +import static org.hyperledger.besu.cli.config.NetworkName.FUTURE_EIPS; import static org.hyperledger.besu.cli.config.NetworkName.HOLESKY; import static org.hyperledger.besu.cli.config.NetworkName.LUKSO; -import static org.hyperledger.besu.cli.config.NetworkName.DEV; -import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; +import static org.hyperledger.besu.cli.config.NetworkName.MAINNET; +import static org.hyperledger.besu.cli.config.NetworkName.MORDOR; +import static org.hyperledger.besu.cli.config.NetworkName.SEPOLIA; import static org.hyperledger.besu.ethereum.api.jsonrpc.RpcApis.ENGINE; import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_BOOTSTRAP_NODES; import static org.hyperledger.besu.ethereum.p2p.config.DefaultDiscoveryConfiguration.MAINNET_DISCOVERY_URL; @@ -1792,7 +1792,7 @@ public void ephemeryValuesAreUsed() { parseCommand("--network", "ephemery"); final ArgumentCaptor networkArg = - ArgumentCaptor.forClass(EthNetworkConfig.class); + ArgumentCaptor.forClass(EthNetworkConfig.class); verify(mockControllerBuilderFactory).fromEthNetworkConfig(networkArg.capture(), any()); verify(mockControllerBuilder).build(); 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 e56e3744f0b..649560d1119 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/NetworkDeprecationMessageTest.java @@ -39,9 +39,7 @@ void shouldGenerateDeprecationMessageForDeprecatedNetworks(final NetworkName net @ParameterizedTest @EnumSource( value = NetworkName.class, - names = { - "MAINNET", "SEPOLIA", "DEV", "CLASSIC", "MORDOR", "HOLESKY", "LUKSO", "EPHEMERY" - }) + names = {"MAINNET", "SEPOLIA", "DEV", "CLASSIC", "MORDOR", "HOLESKY", "LUKSO", "EPHEMERY"}) void shouldThrowErrorForNonDeprecatedNetworks(final NetworkName network) { assertThatThrownBy(() -> NetworkDeprecationMessage.generate(network)) .isInstanceOf(AssertionError.class); From 9e875eca17c3d132fbdb207f485aadb1b6f27bfa Mon Sep 17 00:00:00 2001 From: gconnect Date: Mon, 19 Aug 2024 02:04:58 +0100 Subject: [PATCH 016/124] Add setNetworkId method and generateEphemeryGenesis Signed-off-by: gconnect --- .../org/hyperledger/besu/cli/BesuCommand.java | 49 + .../besu/cli/config/NetworkName.java | 10 +- config/src/main/resources/ephemery.json | 1256 ++++++++--------- 3 files changed, 686 insertions(+), 629 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 1eaab20bd27..b832028456d 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -19,6 +19,7 @@ import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.hyperledger.besu.cli.DefaultCommandValues.getDefaultBesuDataPath; +import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; import static org.hyperledger.besu.cli.config.NetworkName.MAINNET; import static org.hyperledger.besu.cli.util.CommandLineUtils.DEPENDENCY_WARNING_MSG; import static org.hyperledger.besu.cli.util.CommandLineUtils.isOptionSet; @@ -31,6 +32,8 @@ 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 com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; @@ -215,6 +218,8 @@ import java.net.UnknownHostException; import java.nio.file.Path; import java.time.Clock; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1159,6 +1164,9 @@ public void run() { if (network != null && network.isDeprecated()) { logger.warn(NetworkDeprecationMessage.generate(network)); } + if (network == EPHEMERY) { + generateEphemeryGenesisFile(); + } try { configureLogging(true); @@ -1728,6 +1736,47 @@ private GenesisConfigOptions readGenesisConfigOptions() { } } + /** + * generateEphemeryGenesisFile checks if a genesis update is available + * and updates the ephemery.json file + */ + private void generateEphemeryGenesisFile() { + if(EPHEMERY.getGenesisFile() != null){ + + GenesisConfigFile configFile = GenesisConfigFile.fromResource( + Optional.ofNullable(network).orElse(EPHEMERY).getGenesisFile()); + GenesisConfigOptions configOptions = readGenesisConfigOptions(); + final int PERIOD = 28; + long timestamp = configFile.getTimestamp(); + Optional chainId = configOptions.getChainId(); + + long periodInSeconds = (PERIOD * 24 * 60 * 60); + long currentTimestamp = Instant.now().getEpochSecond(); + long periodsSinceGenesis = ChronoUnit.DAYS.between(Instant.ofEpochSecond(timestamp), Instant.now()) / PERIOD; + long newGenesisTimestamp = timestamp + (periodsSinceGenesis * periodInSeconds); + BigInteger newChainId = chainId.orElseThrow(() -> new IllegalStateException("ChainId not present")) + .add(BigInteger.valueOf(periodsSinceGenesis)); + + EPHEMERY.setNetworkId(newChainId); + + if (currentTimestamp > (timestamp + periodInSeconds)) { + Path ephemeryGenesisfilePath = Path.of(EPHEMERY.getGenesisFile()); + try { + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode rootNode = (ObjectNode) objectMapper.readTree(ephemeryGenesisfilePath.toFile()); + + ObjectNode configNode = (ObjectNode) rootNode.path("config"); + configNode.put("chainId", newChainId.toString()); + rootNode.put("timestamp", String.valueOf(newGenesisTimestamp)); + + objectMapper.writerWithDefaultPrettyPrinter().writeValue(ephemeryGenesisfilePath.toFile(), rootNode); + } catch (IOException e) { + throw new ParameterException(this.commandLine, "Unable to update ephemery genesis file. " + e.getMessage(), e); + } + } + } + } + private void issueOptionWarnings() { // Check that P2P options are able to work diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java index ae432021950..d76559d4c9b 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java @@ -46,7 +46,7 @@ public enum NetworkName { MORDOR("/mordor.json", BigInteger.valueOf(7)); private final String genesisFile; - private final BigInteger networkId; + private BigInteger networkId; private final boolean canSnapSync; private final String deprecationDate; @@ -80,6 +80,14 @@ public BigInteger getNetworkId() { return networkId; } + /** + * Sets network id. + */ + public void setNetworkId(final BigInteger networkId) { + this.networkId = networkId; + } + + /** * Can SNAP sync boolean. * diff --git a/config/src/main/resources/ephemery.json b/config/src/main/resources/ephemery.json index 5924633d196..3024b4c7a3f 100644 --- a/config/src/main/resources/ephemery.json +++ b/config/src/main/resources/ephemery.json @@ -1,917 +1,917 @@ { - "config": { - "chainId": 39438135, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "preMergeForkBlock": 0, - "terminalTotalDifficulty": 0, - "shanghaiTime": 0, - "cancunTime": 0, - "depositContractAddress": "0x4242424242424242424242424242424242424242", - "ethash": {}, - "discovery": { - "bootnodes": [ + "config" : { + "chainId" : "39438135", + "homesteadBlock" : 0, + "eip150Block" : 0, + "eip155Block" : 0, + "eip158Block" : 0, + "byzantiumBlock" : 0, + "constantinopleBlock" : 0, + "petersburgBlock" : 0, + "istanbulBlock" : 0, + "berlinBlock" : 0, + "londonBlock" : 0, + "preMergeForkBlock" : 0, + "terminalTotalDifficulty" : 0, + "shanghaiTime" : 0, + "cancunTime" : 0, + "depositContractAddress" : "0x4242424242424242424242424242424242424242", + "ethash" : { }, + "discovery" : { + "bootnodes" : [ "enode://50a54ecbd2175497640bcf46a25bbe9bb4fae51d7cc2a29ef4947a7ee17496cf39a699b7fe6b703ed0feb9dbaae7e44fc3827fcb7435ca9ac6de4daa4d983b3d@137.74.203.240:30303", "enode://0f2c301a9a3f9fa2ccfa362b79552c052905d8c2982f707f46cd29ece5a9e1c14ecd06f4ac951b228f059a43c6284a1a14fce709e8976cac93b50345218bf2e9@135.181.140.168:30343" ] } }, - "alloc": { - "0x0000000000000000000000000000000000000000": { - "balance": "1" + "alloc" : { + "0x0000000000000000000000000000000000000000" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000001": { - "balance": "1" + "0x0000000000000000000000000000000000000001" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000002": { - "balance": "1" + "0x0000000000000000000000000000000000000002" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000003": { - "balance": "1" + "0x0000000000000000000000000000000000000003" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000004": { - "balance": "1" + "0x0000000000000000000000000000000000000004" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000005": { - "balance": "1" + "0x0000000000000000000000000000000000000005" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000006": { - "balance": "1" + "0x0000000000000000000000000000000000000006" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000007": { - "balance": "1" + "0x0000000000000000000000000000000000000007" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000008": { - "balance": "1" + "0x0000000000000000000000000000000000000008" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000009": { - "balance": "1" + "0x0000000000000000000000000000000000000009" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000000a": { - "balance": "1" + "0x000000000000000000000000000000000000000a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000000b": { - "balance": "1" + "0x000000000000000000000000000000000000000b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000000c": { - "balance": "1" + "0x000000000000000000000000000000000000000c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000000d": { - "balance": "1" + "0x000000000000000000000000000000000000000d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000000e": { - "balance": "1" + "0x000000000000000000000000000000000000000e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000000f": { - "balance": "1" + "0x000000000000000000000000000000000000000f" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000010": { - "balance": "1" + "0x0000000000000000000000000000000000000010" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000011": { - "balance": "1" + "0x0000000000000000000000000000000000000011" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000012": { - "balance": "1" + "0x0000000000000000000000000000000000000012" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000013": { - "balance": "1" + "0x0000000000000000000000000000000000000013" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000014": { - "balance": "1" + "0x0000000000000000000000000000000000000014" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000015": { - "balance": "1" + "0x0000000000000000000000000000000000000015" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000016": { - "balance": "1" + "0x0000000000000000000000000000000000000016" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000017": { - "balance": "1" + "0x0000000000000000000000000000000000000017" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000018": { - "balance": "1" + "0x0000000000000000000000000000000000000018" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000019": { - "balance": "1" + "0x0000000000000000000000000000000000000019" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000001a": { - "balance": "1" + "0x000000000000000000000000000000000000001a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000001b": { - "balance": "1" + "0x000000000000000000000000000000000000001b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000001c": { - "balance": "1" + "0x000000000000000000000000000000000000001c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000001d": { - "balance": "1" + "0x000000000000000000000000000000000000001d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000001e": { - "balance": "1" + "0x000000000000000000000000000000000000001e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000001f": { - "balance": "1" + "0x000000000000000000000000000000000000001f" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000020": { - "balance": "1" + "0x0000000000000000000000000000000000000020" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000021": { - "balance": "1" + "0x0000000000000000000000000000000000000021" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000022": { - "balance": "1" + "0x0000000000000000000000000000000000000022" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000023": { - "balance": "1" + "0x0000000000000000000000000000000000000023" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000024": { - "balance": "1" + "0x0000000000000000000000000000000000000024" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000025": { - "balance": "1" + "0x0000000000000000000000000000000000000025" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000026": { - "balance": "1" + "0x0000000000000000000000000000000000000026" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000027": { - "balance": "1" + "0x0000000000000000000000000000000000000027" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000028": { - "balance": "1" + "0x0000000000000000000000000000000000000028" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000029": { - "balance": "1" + "0x0000000000000000000000000000000000000029" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000002a": { - "balance": "1" + "0x000000000000000000000000000000000000002a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000002b": { - "balance": "1" + "0x000000000000000000000000000000000000002b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000002c": { - "balance": "1" + "0x000000000000000000000000000000000000002c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000002d": { - "balance": "1" + "0x000000000000000000000000000000000000002d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000002e": { - "balance": "1" + "0x000000000000000000000000000000000000002e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000002f": { - "balance": "1" + "0x000000000000000000000000000000000000002f" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000030": { - "balance": "1" + "0x0000000000000000000000000000000000000030" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000031": { - "balance": "1" + "0x0000000000000000000000000000000000000031" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000032": { - "balance": "1" + "0x0000000000000000000000000000000000000032" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000033": { - "balance": "1" + "0x0000000000000000000000000000000000000033" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000034": { - "balance": "1" + "0x0000000000000000000000000000000000000034" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000035": { - "balance": "1" + "0x0000000000000000000000000000000000000035" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000036": { - "balance": "1" + "0x0000000000000000000000000000000000000036" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000037": { - "balance": "1" + "0x0000000000000000000000000000000000000037" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000038": { - "balance": "1" + "0x0000000000000000000000000000000000000038" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000039": { - "balance": "1" + "0x0000000000000000000000000000000000000039" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000003a": { - "balance": "1" + "0x000000000000000000000000000000000000003a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000003b": { - "balance": "1" + "0x000000000000000000000000000000000000003b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000003c": { - "balance": "1" + "0x000000000000000000000000000000000000003c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000003d": { - "balance": "1" + "0x000000000000000000000000000000000000003d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000003e": { - "balance": "1" + "0x000000000000000000000000000000000000003e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000003f": { - "balance": "1" + "0x000000000000000000000000000000000000003f" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000040": { - "balance": "1" + "0x0000000000000000000000000000000000000040" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000041": { - "balance": "1" + "0x0000000000000000000000000000000000000041" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000042": { - "balance": "1" + "0x0000000000000000000000000000000000000042" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000043": { - "balance": "1" + "0x0000000000000000000000000000000000000043" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000044": { - "balance": "1" + "0x0000000000000000000000000000000000000044" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000045": { - "balance": "1" + "0x0000000000000000000000000000000000000045" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000046": { - "balance": "1" + "0x0000000000000000000000000000000000000046" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000047": { - "balance": "1" + "0x0000000000000000000000000000000000000047" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000048": { - "balance": "1" + "0x0000000000000000000000000000000000000048" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000049": { - "balance": "1" + "0x0000000000000000000000000000000000000049" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000004a": { - "balance": "1" + "0x000000000000000000000000000000000000004a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000004b": { - "balance": "1" + "0x000000000000000000000000000000000000004b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000004c": { - "balance": "1" + "0x000000000000000000000000000000000000004c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000004d": { - "balance": "1" + "0x000000000000000000000000000000000000004d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000004e": { - "balance": "1" + "0x000000000000000000000000000000000000004e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000004f": { - "balance": "1" + "0x000000000000000000000000000000000000004f" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000050": { - "balance": "1" + "0x0000000000000000000000000000000000000050" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000051": { - "balance": "1" + "0x0000000000000000000000000000000000000051" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000052": { - "balance": "1" + "0x0000000000000000000000000000000000000052" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000053": { - "balance": "1" + "0x0000000000000000000000000000000000000053" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000054": { - "balance": "1" + "0x0000000000000000000000000000000000000054" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000055": { - "balance": "1" + "0x0000000000000000000000000000000000000055" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000056": { - "balance": "1" + "0x0000000000000000000000000000000000000056" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000057": { - "balance": "1" + "0x0000000000000000000000000000000000000057" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000058": { - "balance": "1" + "0x0000000000000000000000000000000000000058" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000059": { - "balance": "1" + "0x0000000000000000000000000000000000000059" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000005a": { - "balance": "1" + "0x000000000000000000000000000000000000005a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000005b": { - "balance": "1" + "0x000000000000000000000000000000000000005b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000005c": { - "balance": "1" + "0x000000000000000000000000000000000000005c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000005d": { - "balance": "1" + "0x000000000000000000000000000000000000005d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000005e": { - "balance": "1" + "0x000000000000000000000000000000000000005e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000005f": { - "balance": "1" + "0x000000000000000000000000000000000000005f" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000060": { - "balance": "1" + "0x0000000000000000000000000000000000000060" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000061": { - "balance": "1" + "0x0000000000000000000000000000000000000061" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000062": { - "balance": "1" + "0x0000000000000000000000000000000000000062" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000063": { - "balance": "1" + "0x0000000000000000000000000000000000000063" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000064": { - "balance": "1" + "0x0000000000000000000000000000000000000064" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000065": { - "balance": "1" + "0x0000000000000000000000000000000000000065" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000066": { - "balance": "1" + "0x0000000000000000000000000000000000000066" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000067": { - "balance": "1" + "0x0000000000000000000000000000000000000067" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000068": { - "balance": "1" + "0x0000000000000000000000000000000000000068" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000069": { - "balance": "1" + "0x0000000000000000000000000000000000000069" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000006a": { - "balance": "1" + "0x000000000000000000000000000000000000006a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000006b": { - "balance": "1" + "0x000000000000000000000000000000000000006b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000006c": { - "balance": "1" + "0x000000000000000000000000000000000000006c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000006d": { - "balance": "1" + "0x000000000000000000000000000000000000006d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000006e": { - "balance": "1" + "0x000000000000000000000000000000000000006e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000006f": { - "balance": "1" + "0x000000000000000000000000000000000000006f" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000070": { - "balance": "1" + "0x0000000000000000000000000000000000000070" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000071": { - "balance": "1" + "0x0000000000000000000000000000000000000071" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000072": { - "balance": "1" + "0x0000000000000000000000000000000000000072" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000073": { - "balance": "1" + "0x0000000000000000000000000000000000000073" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000074": { - "balance": "1" + "0x0000000000000000000000000000000000000074" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000075": { - "balance": "1" + "0x0000000000000000000000000000000000000075" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000076": { - "balance": "1" + "0x0000000000000000000000000000000000000076" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000077": { - "balance": "1" + "0x0000000000000000000000000000000000000077" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000078": { - "balance": "1" + "0x0000000000000000000000000000000000000078" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000079": { - "balance": "1" + "0x0000000000000000000000000000000000000079" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000007a": { - "balance": "1" + "0x000000000000000000000000000000000000007a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000007b": { - "balance": "1" + "0x000000000000000000000000000000000000007b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000007c": { - "balance": "1" + "0x000000000000000000000000000000000000007c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000007d": { - "balance": "1" + "0x000000000000000000000000000000000000007d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000007e": { - "balance": "1" + "0x000000000000000000000000000000000000007e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000007f": { - "balance": "1" + "0x000000000000000000000000000000000000007f" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000080": { - "balance": "1" + "0x0000000000000000000000000000000000000080" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000081": { - "balance": "1" + "0x0000000000000000000000000000000000000081" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000082": { - "balance": "1" + "0x0000000000000000000000000000000000000082" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000083": { - "balance": "1" + "0x0000000000000000000000000000000000000083" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000084": { - "balance": "1" + "0x0000000000000000000000000000000000000084" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000085": { - "balance": "1" + "0x0000000000000000000000000000000000000085" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000086": { - "balance": "1" + "0x0000000000000000000000000000000000000086" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000087": { - "balance": "1" + "0x0000000000000000000000000000000000000087" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000088": { - "balance": "1" + "0x0000000000000000000000000000000000000088" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000089": { - "balance": "1" + "0x0000000000000000000000000000000000000089" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000008a": { - "balance": "1" + "0x000000000000000000000000000000000000008a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000008b": { - "balance": "1" + "0x000000000000000000000000000000000000008b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000008c": { - "balance": "1" + "0x000000000000000000000000000000000000008c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000008d": { - "balance": "1" + "0x000000000000000000000000000000000000008d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000008e": { - "balance": "1" + "0x000000000000000000000000000000000000008e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000008f": { - "balance": "1" + "0x000000000000000000000000000000000000008f" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000090": { - "balance": "1" + "0x0000000000000000000000000000000000000090" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000091": { - "balance": "1" + "0x0000000000000000000000000000000000000091" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000092": { - "balance": "1" + "0x0000000000000000000000000000000000000092" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000093": { - "balance": "1" + "0x0000000000000000000000000000000000000093" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000094": { - "balance": "1" + "0x0000000000000000000000000000000000000094" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000095": { - "balance": "1" + "0x0000000000000000000000000000000000000095" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000096": { - "balance": "1" + "0x0000000000000000000000000000000000000096" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000097": { - "balance": "1" + "0x0000000000000000000000000000000000000097" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000098": { - "balance": "1" + "0x0000000000000000000000000000000000000098" : { + "balance" : "1" }, - "0x0000000000000000000000000000000000000099": { - "balance": "1" + "0x0000000000000000000000000000000000000099" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000009a": { - "balance": "1" + "0x000000000000000000000000000000000000009a" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000009b": { - "balance": "1" + "0x000000000000000000000000000000000000009b" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000009c": { - "balance": "1" + "0x000000000000000000000000000000000000009c" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000009d": { - "balance": "1" + "0x000000000000000000000000000000000000009d" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000009e": { - "balance": "1" + "0x000000000000000000000000000000000000009e" : { + "balance" : "1" }, - "0x000000000000000000000000000000000000009f": { - "balance": "1" + "0x000000000000000000000000000000000000009f" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a0": { - "balance": "1" + "0x00000000000000000000000000000000000000a0" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a1": { - "balance": "1" + "0x00000000000000000000000000000000000000a1" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a2": { - "balance": "1" + "0x00000000000000000000000000000000000000a2" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a3": { - "balance": "1" + "0x00000000000000000000000000000000000000a3" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a4": { - "balance": "1" + "0x00000000000000000000000000000000000000a4" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a5": { - "balance": "1" + "0x00000000000000000000000000000000000000a5" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a6": { - "balance": "1" + "0x00000000000000000000000000000000000000a6" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a7": { - "balance": "1" + "0x00000000000000000000000000000000000000a7" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a8": { - "balance": "1" + "0x00000000000000000000000000000000000000a8" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000a9": { - "balance": "1" + "0x00000000000000000000000000000000000000a9" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000aa": { - "balance": "1" + "0x00000000000000000000000000000000000000aa" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ab": { - "balance": "1" + "0x00000000000000000000000000000000000000ab" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ac": { - "balance": "1" + "0x00000000000000000000000000000000000000ac" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ad": { - "balance": "1" + "0x00000000000000000000000000000000000000ad" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ae": { - "balance": "1" + "0x00000000000000000000000000000000000000ae" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000af": { - "balance": "1" + "0x00000000000000000000000000000000000000af" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b0": { - "balance": "1" + "0x00000000000000000000000000000000000000b0" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b1": { - "balance": "1" + "0x00000000000000000000000000000000000000b1" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b2": { - "balance": "1" + "0x00000000000000000000000000000000000000b2" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b3": { - "balance": "1" + "0x00000000000000000000000000000000000000b3" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b4": { - "balance": "1" + "0x00000000000000000000000000000000000000b4" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b5": { - "balance": "1" + "0x00000000000000000000000000000000000000b5" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b6": { - "balance": "1" + "0x00000000000000000000000000000000000000b6" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b7": { - "balance": "1" + "0x00000000000000000000000000000000000000b7" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b8": { - "balance": "1" + "0x00000000000000000000000000000000000000b8" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000b9": { - "balance": "1" + "0x00000000000000000000000000000000000000b9" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ba": { - "balance": "1" + "0x00000000000000000000000000000000000000ba" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000bb": { - "balance": "1" + "0x00000000000000000000000000000000000000bb" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000bc": { - "balance": "1" + "0x00000000000000000000000000000000000000bc" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000bd": { - "balance": "1" + "0x00000000000000000000000000000000000000bd" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000be": { - "balance": "1" + "0x00000000000000000000000000000000000000be" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000bf": { - "balance": "1" + "0x00000000000000000000000000000000000000bf" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c0": { - "balance": "1" + "0x00000000000000000000000000000000000000c0" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c1": { - "balance": "1" + "0x00000000000000000000000000000000000000c1" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c2": { - "balance": "1" + "0x00000000000000000000000000000000000000c2" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c3": { - "balance": "1" + "0x00000000000000000000000000000000000000c3" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c4": { - "balance": "1" + "0x00000000000000000000000000000000000000c4" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c5": { - "balance": "1" + "0x00000000000000000000000000000000000000c5" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c6": { - "balance": "1" + "0x00000000000000000000000000000000000000c6" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c7": { - "balance": "1" + "0x00000000000000000000000000000000000000c7" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c8": { - "balance": "1" + "0x00000000000000000000000000000000000000c8" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000c9": { - "balance": "1" + "0x00000000000000000000000000000000000000c9" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ca": { - "balance": "1" + "0x00000000000000000000000000000000000000ca" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000cb": { - "balance": "1" + "0x00000000000000000000000000000000000000cb" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000cc": { - "balance": "1" + "0x00000000000000000000000000000000000000cc" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000cd": { - "balance": "1" + "0x00000000000000000000000000000000000000cd" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ce": { - "balance": "1" + "0x00000000000000000000000000000000000000ce" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000cf": { - "balance": "1" + "0x00000000000000000000000000000000000000cf" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d0": { - "balance": "1" + "0x00000000000000000000000000000000000000d0" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d1": { - "balance": "1" + "0x00000000000000000000000000000000000000d1" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d2": { - "balance": "1" + "0x00000000000000000000000000000000000000d2" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d3": { - "balance": "1" + "0x00000000000000000000000000000000000000d3" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d4": { - "balance": "1" + "0x00000000000000000000000000000000000000d4" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d5": { - "balance": "1" + "0x00000000000000000000000000000000000000d5" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d6": { - "balance": "1" + "0x00000000000000000000000000000000000000d6" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d7": { - "balance": "1" + "0x00000000000000000000000000000000000000d7" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d8": { - "balance": "1" + "0x00000000000000000000000000000000000000d8" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000d9": { - "balance": "1" + "0x00000000000000000000000000000000000000d9" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000da": { - "balance": "1" + "0x00000000000000000000000000000000000000da" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000db": { - "balance": "1" + "0x00000000000000000000000000000000000000db" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000dc": { - "balance": "1" + "0x00000000000000000000000000000000000000dc" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000dd": { - "balance": "1" + "0x00000000000000000000000000000000000000dd" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000de": { - "balance": "1" + "0x00000000000000000000000000000000000000de" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000df": { - "balance": "1" + "0x00000000000000000000000000000000000000df" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e0": { - "balance": "1" + "0x00000000000000000000000000000000000000e0" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e1": { - "balance": "1" + "0x00000000000000000000000000000000000000e1" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e2": { - "balance": "1" + "0x00000000000000000000000000000000000000e2" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e3": { - "balance": "1" + "0x00000000000000000000000000000000000000e3" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e4": { - "balance": "1" + "0x00000000000000000000000000000000000000e4" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e5": { - "balance": "1" + "0x00000000000000000000000000000000000000e5" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e6": { - "balance": "1" + "0x00000000000000000000000000000000000000e6" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e7": { - "balance": "1" + "0x00000000000000000000000000000000000000e7" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e8": { - "balance": "1" + "0x00000000000000000000000000000000000000e8" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000e9": { - "balance": "1" + "0x00000000000000000000000000000000000000e9" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ea": { - "balance": "1" + "0x00000000000000000000000000000000000000ea" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000eb": { - "balance": "1" + "0x00000000000000000000000000000000000000eb" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ec": { - "balance": "1" + "0x00000000000000000000000000000000000000ec" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ed": { - "balance": "1" + "0x00000000000000000000000000000000000000ed" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ee": { - "balance": "1" + "0x00000000000000000000000000000000000000ee" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ef": { - "balance": "1" + "0x00000000000000000000000000000000000000ef" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f0": { - "balance": "1" + "0x00000000000000000000000000000000000000f0" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f1": { - "balance": "1" + "0x00000000000000000000000000000000000000f1" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f2": { - "balance": "1" + "0x00000000000000000000000000000000000000f2" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f3": { - "balance": "1" + "0x00000000000000000000000000000000000000f3" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f4": { - "balance": "1" + "0x00000000000000000000000000000000000000f4" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f5": { - "balance": "1" + "0x00000000000000000000000000000000000000f5" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f6": { - "balance": "1" + "0x00000000000000000000000000000000000000f6" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f7": { - "balance": "1" + "0x00000000000000000000000000000000000000f7" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f8": { - "balance": "1" + "0x00000000000000000000000000000000000000f8" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000f9": { - "balance": "1" + "0x00000000000000000000000000000000000000f9" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000fa": { - "balance": "1" + "0x00000000000000000000000000000000000000fa" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000fb": { - "balance": "1" + "0x00000000000000000000000000000000000000fb" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000fc": { - "balance": "1" + "0x00000000000000000000000000000000000000fc" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000fd": { - "balance": "1" + "0x00000000000000000000000000000000000000fd" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000fe": { - "balance": "1" + "0x00000000000000000000000000000000000000fe" : { + "balance" : "1" }, - "0x00000000000000000000000000000000000000ff": { - "balance": "1" + "0x00000000000000000000000000000000000000ff" : { + "balance" : "1" }, - "0x4242424242424242424242424242424242424242": { - "balance": "0", - "code": "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000022": "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", - "0x0000000000000000000000000000000000000000000000000000000000000023": "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x0000000000000000000000000000000000000000000000000000000000000024": "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", - "0x0000000000000000000000000000000000000000000000000000000000000025": "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", - "0x0000000000000000000000000000000000000000000000000000000000000026": "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", - "0x0000000000000000000000000000000000000000000000000000000000000027": "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", - "0x0000000000000000000000000000000000000000000000000000000000000028": "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", - "0x0000000000000000000000000000000000000000000000000000000000000029": "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", - "0x000000000000000000000000000000000000000000000000000000000000002a": "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", - "0x000000000000000000000000000000000000000000000000000000000000002b": "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", - "0x000000000000000000000000000000000000000000000000000000000000002c": "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", - "0x000000000000000000000000000000000000000000000000000000000000002d": "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", - "0x000000000000000000000000000000000000000000000000000000000000002e": "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", - "0x000000000000000000000000000000000000000000000000000000000000002f": "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", - "0x0000000000000000000000000000000000000000000000000000000000000030": "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", - "0x0000000000000000000000000000000000000000000000000000000000000031": "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", - "0x0000000000000000000000000000000000000000000000000000000000000032": "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", - "0x0000000000000000000000000000000000000000000000000000000000000033": "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", - "0x0000000000000000000000000000000000000000000000000000000000000034": "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", - "0x0000000000000000000000000000000000000000000000000000000000000035": "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", - "0x0000000000000000000000000000000000000000000000000000000000000036": "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", - "0x0000000000000000000000000000000000000000000000000000000000000037": "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", - "0x0000000000000000000000000000000000000000000000000000000000000038": "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", - "0x0000000000000000000000000000000000000000000000000000000000000039": "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", - "0x000000000000000000000000000000000000000000000000000000000000003a": "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", - "0x000000000000000000000000000000000000000000000000000000000000003b": "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", - "0x000000000000000000000000000000000000000000000000000000000000003c": "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", - "0x000000000000000000000000000000000000000000000000000000000000003d": "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", - "0x000000000000000000000000000000000000000000000000000000000000003e": "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", - "0x000000000000000000000000000000000000000000000000000000000000003f": "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", - "0x0000000000000000000000000000000000000000000000000000000000000040": "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + "0x4242424242424242424242424242424242424242" : { + "balance" : "0", + "code" : "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", + "storage" : { + "0x0000000000000000000000000000000000000000000000000000000000000022" : "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x0000000000000000000000000000000000000000000000000000000000000023" : "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x0000000000000000000000000000000000000000000000000000000000000024" : "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x0000000000000000000000000000000000000000000000000000000000000025" : "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x0000000000000000000000000000000000000000000000000000000000000026" : "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x0000000000000000000000000000000000000000000000000000000000000027" : "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x0000000000000000000000000000000000000000000000000000000000000028" : "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x0000000000000000000000000000000000000000000000000000000000000029" : "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x000000000000000000000000000000000000000000000000000000000000002a" : "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x000000000000000000000000000000000000000000000000000000000000002b" : "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x000000000000000000000000000000000000000000000000000000000000002c" : "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x000000000000000000000000000000000000000000000000000000000000002d" : "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x000000000000000000000000000000000000000000000000000000000000002e" : "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x000000000000000000000000000000000000000000000000000000000000002f" : "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x0000000000000000000000000000000000000000000000000000000000000030" : "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x0000000000000000000000000000000000000000000000000000000000000031" : "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x0000000000000000000000000000000000000000000000000000000000000032" : "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x0000000000000000000000000000000000000000000000000000000000000033" : "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x0000000000000000000000000000000000000000000000000000000000000034" : "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x0000000000000000000000000000000000000000000000000000000000000035" : "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x0000000000000000000000000000000000000000000000000000000000000036" : "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x0000000000000000000000000000000000000000000000000000000000000037" : "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x0000000000000000000000000000000000000000000000000000000000000038" : "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x0000000000000000000000000000000000000000000000000000000000000039" : "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x000000000000000000000000000000000000000000000000000000000000003a" : "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x000000000000000000000000000000000000000000000000000000000000003b" : "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x000000000000000000000000000000000000000000000000000000000000003c" : "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x000000000000000000000000000000000000000000000000000000000000003d" : "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x000000000000000000000000000000000000000000000000000000000000003e" : "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x000000000000000000000000000000000000000000000000000000000000003f" : "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x0000000000000000000000000000000000000000000000000000000000000040" : "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" } }, - "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02": { - "balance": "0", - "nonce": "1", - "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500" + "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" : { + "balance" : "0", + "nonce" : "1", + "code" : "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500" }, - "0xa2A6d93439144FFE4D27c9E088dCD8b783946263": { - "balance": "1000000000000000000000000" + "0xa2A6d93439144FFE4D27c9E088dCD8b783946263" : { + "balance" : "1000000000000000000000000" }, - "0xBc11295936Aa79d594139de1B2e12629414F3BDB": { - "balance": "1000000000000000000000000" + "0xBc11295936Aa79d594139de1B2e12629414F3BDB" : { + "balance" : "1000000000000000000000000" }, - "0x7cF5b79bfe291A67AB02b393E456cCc4c266F753": { - "balance": "1000000000000000000000000" + "0x7cF5b79bfe291A67AB02b393E456cCc4c266F753" : { + "balance" : "1000000000000000000000000" }, - "0xaaec86394441f915bce3e6ab399977e9906f3b69": { - "balance": "1000000000000000000000000" + "0xaaec86394441f915bce3e6ab399977e9906f3b69" : { + "balance" : "1000000000000000000000000" }, - "0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8": { - "balance": "1000000000000000000000000" + "0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8" : { + "balance" : "1000000000000000000000000" }, - "0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8": { - "balance": "1000000000000000000000000" + "0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8" : { + "balance" : "1000000000000000000000000" }, - "0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e": { - "balance": "1000000000000000000000000" + "0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e" : { + "balance" : "1000000000000000000000000" }, - "0xe2e2659028143784d557bcec6ff3a0721048880a": { - "balance": "1000000000000000000000000" + "0xe2e2659028143784d557bcec6ff3a0721048880a" : { + "balance" : "1000000000000000000000000" }, - "0xd9a5179f091d85051d3c982785efd1455cec8699": { - "balance": "1000000000000000000000000" + "0xd9a5179f091d85051d3c982785efd1455cec8699" : { + "balance" : "1000000000000000000000000" }, - "0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf": { - "balance": "1000000000000000000000000" + "0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf" : { + "balance" : "1000000000000000000000000" }, - "0x0000006916a87b82333f4245046623b23794c65c": { - "balance": "10000000000000000000000000" + "0x0000006916a87b82333f4245046623b23794c65c" : { + "balance" : "10000000000000000000000000" }, - "0xb21c33de1fab3fa15499c62b59fe0cc3250020d1": { - "balance": "100000000000000000000000000" + "0xb21c33de1fab3fa15499c62b59fe0cc3250020d1" : { + "balance" : "100000000000000000000000000" }, - "0x10F5d45854e038071485AC9e402308cF80D2d2fE": { - "balance": "100000000000000000000000000" + "0x10F5d45854e038071485AC9e402308cF80D2d2fE" : { + "balance" : "100000000000000000000000000" }, - "0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E": { - "balance": "100000000000000000000000000" + "0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E" : { + "balance" : "100000000000000000000000000" }, - "0x799D329e5f583419167cD722962485926E338F4a": { - "balance": "1000000000000000000" + "0x799D329e5f583419167cD722962485926E338F4a" : { + "balance" : "1000000000000000000" }, - "0x4c2ae482593505f0163cdefc073e81c63cda4107": { - "balance": "1000000000000000000000000" + "0x4c2ae482593505f0163cdefc073e81c63cda4107" : { + "balance" : "1000000000000000000000000" }, - "0xa8e8f14732658e4b51e8711931053a8a69baf2b1": { - "balance": "1000000000000000000000000" + "0xa8e8f14732658e4b51e8711931053a8a69baf2b1" : { + "balance" : "1000000000000000000000000" }, - "0xe0a2bd4258d2768837baa26a28fe71dc079f84c7": { - "balance": "100000000000000000000000000" + "0xe0a2bd4258d2768837baa26a28fe71dc079f84c7" : { + "balance" : "100000000000000000000000000" }, - "0x1eA692E68a7765dE26FC03A6D74EE5B56A7e2b4d": { - "balance": "100000000000000000000000000" + "0x1eA692E68a7765dE26FC03A6D74EE5B56A7e2b4d" : { + "balance" : "100000000000000000000000000" }, - "0x57c3dfd40A86628B67721115d7A03C9F341d7718": { - "balance": "100000000000000000000000000" + "0x57c3dfd40A86628B67721115d7A03C9F341d7718" : { + "balance" : "100000000000000000000000000" }, - "0xc90E920F4DCfd4954230edCaB168D0C5B9561e03": { - "balance": "1000000000000000000000000000" + "0xc90E920F4DCfd4954230edCaB168D0C5B9561e03" : { + "balance" : "1000000000000000000000000000" }, - "0x6Cc9397c3B38739daCbfaA68EaD5F5D77Ba5F455": { - "balance": "10000000000000000000000000" + "0x6Cc9397c3B38739daCbfaA68EaD5F5D77Ba5F455" : { + "balance" : "10000000000000000000000000" }, - "0x992775d32fd0ec76b95C5E76CeEA92ED5a4bE1F9": { - "balance": "10000000000000000000000000" + "0x992775d32fd0ec76b95C5E76CeEA92ED5a4bE1F9" : { + "balance" : "10000000000000000000000000" } }, - "coinbase": "0x0000000000000000000000000000000000000000", - "baseFeePerGas": "0x3B9ACA00", - "difficulty": "0x01", - "extraData": "", - "gasLimit": "0x1c9c380", - "nonce": "0x1234", - "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "1720119600" -} + "coinbase" : "0x0000000000000000000000000000000000000000", + "baseFeePerGas" : "0x3B9ACA00", + "difficulty" : "0x01", + "extraData" : "", + "gasLimit" : "0x1c9c380", + "nonce" : "0x1234", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "1720119600" +} \ No newline at end of file From 6130d9c637e567965cd02c8999abf0d3a7e6b824 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Thu, 25 Jul 2024 23:53:53 +0200 Subject: [PATCH 017/124] 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 Signed-off-by: gconnect --- .../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 c106b7aff16..ed028767d6a 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 @@ private TransactionSelectionResult handleTransactionNotSelected( 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 @@ private TransactionSelectionResult handleTransactionNotSelected( 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 85d97bdf460..9eed2bff09e 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 @@ private TransactionSelectionResult transactionSelectionResultForInvalidResult( * @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 c6ee454241a..adcc3ee1e27 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.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 void invalidTransactionsAreSkippedButBlockStillFills() { 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 void invalidTransactionsAreSkippedButBlockStillFills() { .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 void shouldDiscardTransactionsThatFailValidation() { 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 void shouldDiscardTransactionsThatFailValidation() { .containsOnly( entry( invalidTransaction, - TransactionSelectionResult.invalid( - TransactionInvalidReason.UPFRONT_COST_EXCEEDS_BALANCE.name()))); + TransactionSelectionResult.invalid(TransactionInvalidReason.NONCE_TOO_LOW.name()))); } @Test @@ -948,7 +946,7 @@ public void subsetOfPendingTransactionsIncludedWhenTxSelectionMaxTimeIsOver( @ParameterizedTest @MethodSource("subsetOfPendingTransactionsIncludedWhenTxSelectionMaxTimeIsOver") - public void pendingTransactionsThatTakesTooLongToEvaluateIsDroppedFromThePool( + public void pendingTransactionsThatTakesTooLongToEvaluateIsPenalized( final boolean isPoa, final boolean preProcessingTooLate, final boolean processingTooLate, @@ -961,7 +959,7 @@ public void pendingTransactionsThatTakesTooLongToEvaluateIsDroppedFromThePool( postProcessingTooLate, 900, TX_EVALUATION_TOO_LONG, - true); + false); } private void internalBlockSelectionTimeoutSimulation( @@ -1085,7 +1083,7 @@ public void subsetOfInvalidPendingTransactionsIncludedWhenTxSelectionMaxTimeIsOv 500, BLOCK_SELECTION_TIMEOUT, false, - UPFRONT_COST_EXCEEDS_BALANCE); + NONCE_TOO_LOW); } @ParameterizedTest @@ -1102,9 +1100,9 @@ public void invalidPendingTransactionsThatTakesTooLongToEvaluateIsDroppedFromThe 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 @@ protected MiningParameters createMiningParameters( 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 boolean stop() { 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 6ce8f47a7aa..bd98bee5adc 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 int memorySize() { 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 String toString() { + isReceivedFromLocalSource() + ", hasPriority=" + hasPriority() + + ", score=" + + score + '}'; } @@ -267,6 +285,8 @@ public String toTraceLog() { + isReceivedFromLocalSource() + ", hasPriority=" + hasPriority() + + ", score=" + + score + ", " + transaction.toTraceLog() + "}"; @@ -282,13 +302,13 @@ public Local(final Transaction transaction) { 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 Priority(final Transaction transaction, final long addedAt) { 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 Remote(final Transaction transaction) { 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 Priority(final Transaction transaction, final long addedAt) { 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 812e7de9f4e..90e9628e5c4 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 TransactionPoolMetrics(final MetricsSystem metricsSystem) { "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 void incrementRejected( .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 7a65b3febca..470e7f5b7b7 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.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 @@ protected void internalRemove( 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 List getBySender() { .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 5997fe6c189..b4f6e927c0d 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 @@ final void promoteTransactions() { } } + @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 8140cd5d7a2..b3dec34b772 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 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 BaseFeePrioritizedTransactions( @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 @@ protected String internalLogStats() { 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 @@ protected String internalLogStats() { + 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 0f5d9a6d15d..f383f178c2c 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 TransactionAddedResult add(final PendingTransaction pendingTransaction, f @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 97bd3a88ee4..504a453fa88 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 GasPricePrioritizedTransactions( @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 @@ protected boolean promotionFilter(final PendingTransaction pendingTransaction) { } @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 9444885ebe4..5297f080215 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 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 synchronized List getPriorityTransactions() { @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 1f9fc0ab8d6..0f52e1c5c3e 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 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 @@ protected void internalRemove( } } + @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 String internalLogStats() { 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 String internalLogStats() { + 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 52f598ba71a..aef318e6df9 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 @@ protected void internalRemove( } } + @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 d3c22aeef10..531add0af7b 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 fbc9da9fe57..ff274ce4ea4 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 c5c2bdcf976..84ac759a798 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 @@ void maxPrioritizedByType(final Scenario scenario) { 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 @@ static Stream providerMaxPrioritizedByType() { .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 Scenario expectedDroppedForSenders() { 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 Scenario removeForSender(final Sender sender, final long... nonce) { 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 58c241509ee..81e66a06a04 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 b59fb269670..66b1c1f2d65 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 @@ protected interface Status { */ 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 @@ protected interface Status { 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 boolean stop() { 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 boolean discard() { 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 boolean discard() { 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 c378dc915b2c6a032421f27672adf2693414e432 Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Fri, 26 Jul 2024 03:50:05 +0530 Subject: [PATCH 018/124] 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 Signed-off-by: gconnect --- .../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 064a093e840..40f36f18f1c 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 @@ private void traceTestSpecs(final String test, final List 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 Hash getExpectedLogsHash() { 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 affc6e46010..394cb9a2695 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 @@ private Map> generate( .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 f948a5b24e3..18d574adc15 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 static Collection generateTestParametersForConfig(final String[ 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 4c4b60a0f6ebc37230b8d9fdd2b7101e8a991090 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Thu, 25 Jul 2024 15:41:45 -0700 Subject: [PATCH 019/124] bump execution-spec-tests, account for new name for main stable artifact (#7380) Signed-off-by: garyschulte Signed-off-by: gconnect --- 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 3c073136acd..426c1084db6 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 7cdf7ce0803..950e0ee8661 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1385,9 +1385,9 @@ - - - + + + From edace71fb71e0918d62b3aea2f446fe7ca70ebb1 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 26 Jul 2024 09:16:49 +1000 Subject: [PATCH 020/124] 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 Signed-off-by: gconnect --- 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 8b999bca71e..c5754da1c96 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 b832028456d..dac00e06c35 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -142,6 +142,7 @@ 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; @@ -1595,7 +1596,7 @@ private void validateTransactionPoolOptions() { } private void validateDataStorageOptions() { - dataStorageOptions.validate(commandLine, syncMode); + dataStorageOptions.validate(commandLine); } private void validateRequiredOptions() { @@ -2304,6 +2305,32 @@ public DataStorageConfiguration getDataStorageConfiguration() { 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 fc92a7e5dd9..a0403c39420 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 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 static DataStorageOptions create() { * 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 cd829b1561b..53ffacfb28e 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -66,6 +66,7 @@ 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; @@ -1304,13 +1305,34 @@ public void bonsaiLimitTrieLogsEnabledByDefault() { } @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 5ab2757f888..2086381825f 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 void bonsaiTrieLogsEnabled_explicitlySetToFalse() { "--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 3a742f9cc0995b1db954d17ee51a7f0d04b9ae2a Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Fri, 26 Jul 2024 01:10:23 +0100 Subject: [PATCH 021/124] 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> Signed-off-by: gconnect --- 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 c5754da1c96..813cf6804b8 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 dfd09165b7d..d0c434fc819 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 Runner build() { 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 5c82a3f1b6b3a3b29c1c4a8c319bca913f837d6d Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Fri, 26 Jul 2024 12:17:08 +1000 Subject: [PATCH 022/124] 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 Signed-off-by: gconnect --- 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 813cf6804b8..4d3f9eb4012 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 cea5c1a327d..98bc4246ebe 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 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 @@ 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 TrieLogPruner( 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 @@ private int preloadQueue() { 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 615b5bad6eb..8d767f442aa 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 5521cb82fb3402d010acbc9114d346f1617f76f8 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 29 Jul 2024 08:58:03 +1000 Subject: [PATCH 023/124] Snap server GetTrieNodes to return empty bytes when trienode doesn't exist (#7305) Signed-off-by: Jason Frame Signed-off-by: gconnect --- .../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 d6bfe900d9c..cb92941e5b6 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 @@ MessageData constructGetTrieNodesResponse(final MessageData message) { 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 @@ MessageData constructGetTrieNodesResponse(final MessageData message) { // 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 @@ MessageData constructGetTrieNodesResponse(final MessageData message) { 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 2103af41242..e252fe0335d 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 void assertStorageTriePathRequest() { 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 void assertStorageTrieLimitRequest() { 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 a98457edf76d46cf45c9d016d11470d68f450d8f Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Mon, 29 Jul 2024 09:36:17 +1000 Subject: [PATCH 024/124] Rotate changelog for 24.7.1 (#7385) Signed-off-by: Simon Dudley Signed-off-by: gconnect --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d3f9eb4012..04e0f76e4a8 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 4545cbae9d2c93e01d3bfe0115a3111bdbcd4154 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 29 Jul 2024 16:19:11 +1000 Subject: [PATCH 025/124] 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 Signed-off-by: gconnect --- 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 04e0f76e4a8..072a84c2ba4 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 849b121186e..d6323ee9bfb 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 @@ default boolean isConsensusMigration() { */ 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 b418a678518..67114b29bf3 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 boolean isFixedBaseFee() { 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 Map asMap() { 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 24f33310299..efe56a086d0 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 List getForkBlockTimestamps() { 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 ed313ad6cfc..219ea4fcf8a 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 @@ void asMapIncludesFixedBaseFee() { 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 36d8257ffb9..a96ca58fddb 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 @@ 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 @@ static ProtocolSpecBuilder pragueDefinition( 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 @@ static ProtocolSpecBuilder pragueDefinition( // 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 d855544edee..6e61a0343c3 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 static RequestsValidatorCoordinator pragueRequestsValidator( } 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 b230a6d6103..d4021c9a104 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 @@ 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 cffadfd6369596773bd0f0078eb2b031a64bbf63 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Mon, 29 Jul 2024 13:42:05 +0200 Subject: [PATCH 026/124] Move `JsonRpcResponseType` to `RpcResponseType` in the plugin API module (#7392) Signed-off-by: Fabio Di Fabio Signed-off-by: gconnect --- .../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 f5810520fc7..038f97e1e74 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.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 void discardEmpty() { 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 void discardAuth() { 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 void discardDrop() { 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 void discardIsolation() { 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 efbc78542c5..7e7d7bf7704 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.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 void testAuth() { 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 void testAuthWithAddressZeroResultsInError() { 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 void testDrop() { 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 void testDropWithAddressZeroResultsInError() { 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 void testRepeatAuth() { 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 void testRepeatDrop() { 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 void testChangeToAuth() { 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 void testChangeToDrop() { 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 d285ef3816d..5b488987169 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.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 void debugTraceTransactionSuccessTest() { 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 5a839d8ad07..72d6c5b6152 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.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 void executeRpcRequestBatch( 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 d2a2cb37428..70c78e9ab3e 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.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 @@ private void handleJsonObjectResponse( 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 c40c8f8c1f6..369e425b6fe 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.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 JsonRpcResponse process( 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 3dffff4956a..4cfd7a1df37 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 JsonRpcError getError() { @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 b7391a867b8..92a63174ac9 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 3b308ff9d7e..6817d2cfbbd 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 @@ default String getVersion() { 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 82b1b8835b7..e26e2cf972e 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 Object getResult() { @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 f59b49a30bd..cdf7661678b 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 JsonRpcError getError() { @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 41214d9021a..b980c750d5c 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.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 Future start() { .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 d88f6cba8e5..da7baa5084c 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.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 void handle( 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 1c1cbaf6f78..b12cdbe22fd 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.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.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 void exceptionWhenBoolParamInvalid() { @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 void errorWhenAskingFinalizedButFinalizedIsNotPresent() { @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 void successWhenAskingSafe() { 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 4cb4c81cc9e..6936f2833d4 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.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.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 @@ private JsonRpcResponse resp( 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 @@ private void assertInvalidForkchoiceState(final JsonRpcResponse resp) { 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 10da8a4486f..9b3e94330eb 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.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.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 @@ protected ExecutionEngineJsonRpcMethod.EngineStatus getExpectedInvalidBlockHashS } 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 @@ protected EnginePayloadStatusResult fromSuccessResp(final JsonRpcResponse resp) } 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 e3a3268aa62..4ccd9318a25 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.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 @@ private JsonRpcResponse resp(final List capabilitiesParam) { @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 d3104670de8..f1575f81ab4 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.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.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 @@ private JsonRpcResponse resp(final EngineExchangeTransitionConfigurationParamete } 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 42f2a5df0be..8a99fa94392 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.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.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 @@ private JsonRpcResponse resp(final Hash[] hashes) { } 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 @@ private EngineGetPayloadBodiesResultV1 fromSuccessResp(final JsonRpcResponse res } 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 60fb2ed1f80..6bc89ba6791 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.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.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 @@ private JsonRpcResponse resp(final String startBlockNumber, final String range) } 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 @@ private EngineGetPayloadBodiesResultV1 fromSuccessResp(final JsonRpcResponse res } 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 8803540392c..d7979dccc83 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.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 void delegatesWhenHasValidToken() { 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 void failsWhenHasNoToken() { 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 void failsWhenTokenDoesNotHavePrivacyPublicKey() { 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 7c2b6162665..a7a4f6f5906 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.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 void shouldReturnErrorIfInvalidGroupId() { 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 void shouldReturnErrorIfPrivacyGroupDoesNotExist() { .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 7e61830ce67..a9b9376dc37 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 void setVersion(final Object version) { } @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 ab7b90735b5..52a875a4cbd 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.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.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 void rpcMethodsCreatedWhenPrivacyIsNotEnabledAreDisabled() { 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 76496235386..b156f2294df 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 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 void testMissingParent() { "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 void testBadBlock() { "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 void testGoodBlock() { "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 void testReimportExistingBlock() { 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 81e66a06a04..0d593b1105f 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 9d5be9c4306..b02b45c8577 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 f434809dadca4e6be5362a68a573319c7de94f62 Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Mon, 29 Jul 2024 17:45:15 +0200 Subject: [PATCH 027/124] 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 Signed-off-by: gconnect --- .../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 f1b2558a977..b134b1f5c02 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 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 @@ void setUp() throws IOException { 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 void shouldTransferAllEthOfAuthorizerToSponsor() throws IOException { 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 f79e2c98e3a..c40eca0f742 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 AuthorityProcessor(final Optional maybeChainId) { } public void addContractToAuthority( - final WorldUpdater worldUpdater, + final WorldUpdater worldState, final AuthorizedCodeService authorizedCodeService, final Transaction transaction) { @@ -60,7 +60,7 @@ public void addContractToAuthority( } 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 void addContractToAuthority( } 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 5fa2b119f1c..cb9cd24e23d 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 TransactionProcessingResult processTransaction( } final Address senderAddress = transaction.getSender(); - final MutableAccount sender = worldState.getOrCreateSenderAccount(senderAddress); validationResult = @@ -318,6 +317,19 @@ public TransactionProcessingResult processTransaction( 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 TransactionProcessingResult processTransaction( 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 TransactionProcessingResult processTransaction( 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 c933eeafd40b88be7d8b32a7ca8f06054bfced5f Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Tue, 30 Jul 2024 16:51:06 +1000 Subject: [PATCH 028/124] Refactor TrieLogPruner preload timeout to be more testable (#7393) Also update logging Signed-off-by: Simon Dudley Signed-off-by: gconnect --- .../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 98bc4246ebe..02ff553fe11 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 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 TrieLogPruner( } 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 @@ private void preloadQueue( 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 @@ private void preloadQueue( } }); - 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 621e73711ab..5f985b1f89c 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.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.Test; import org.mockito.InOrder; import org.mockito.Mockito; +import org.mockito.internal.stubbing.answers.AnswersWithDelay; public class TrieLogPrunerTest { @@ -82,6 +80,53 @@ public void initialize_preloads_queue_and_prunes_orphaned_blocks() { 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 2d817358ee9d327edb32ee33613fa90d0479a5f6 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 30 Jul 2024 08:51:47 -0600 Subject: [PATCH 029/124] 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 Signed-off-by: gconnect --- .../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 401308715af..1249e475b43 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.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 @@ private 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 static EOFLayout parseEOF(final Bytes container) { 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 static EOFLayout parseEOF(final Bytes container) { * @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 static EOFLayout parseEOF(final Bytes container, final boolean strictSize } if (codeSectionCount > 1024) { return invalidLayout( - container, + step.container, version, "Too many code sections - 0x" + Integer.toHexString(codeSectionCount)); } @@ -209,7 +280,7 @@ public static EOFLayout parseEOF(final Bytes container, final boolean strictSize 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 static EOFLayout parseEOF(final Bytes container, final boolean strictSize 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 static EOFLayout parseEOF(final Bytes container, final boolean strictSize 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 static EOFLayout parseEOF(final Bytes container, final boolean strictSize 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 static EOFLayout parseEOF(final Bytes container, final boolean strictSize 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 static EOFLayout parseEOF(final Bytes container, final boolean strictSize 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 static EOFLayout parseEOF(final Bytes container, final boolean strictSize 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 static EOFLayout parseEOF(final Bytes container, final boolean strictSize 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 509323ec83ec0692e906ad416af1e309dc5d1eb6 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 30 Jul 2024 09:40:13 -0600 Subject: [PATCH 030/124] 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 Signed-off-by: gconnect --- .../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 e16d4014f0b..3bc2d41d02c 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.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 @@ * 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 String considerCode(final String hexCode) { 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 24cd858ba7b..9ec5e431da6 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 static Object[][] b11rTests() { 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 @@ private static Object[] pathToParams(final String subDir, final File file) { @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 00000000000..c119235cdc1 --- /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 00000000000..79658155591 --- /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 7d60967079528eee3209d073719de8bb302b1734 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Wed, 31 Jul 2024 09:27:37 +1000 Subject: [PATCH 031/124] 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 Signed-off-by: gconnect --- .../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 369e425b6fe..eba3827bfaf 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 JsonRpcResponse process( 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 65fe455bd5c..ea28ca7c4a2 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 5353439e0b0..7dcda5939c8 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 6e10b7a2316..a8b5fb7dc8a 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 T required(final Object[] params, final int index, final Class par * @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 Optional optional( 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 Optional> optionalList( } 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 1b1ee48c0af..309fe498627 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 0d593b1105f..c7203e2f883 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 b8d6791ecec..efba770701f 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 @@ */ 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 f9c65c34b5ddc353439b0ae94fd4b431604fdc00 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Wed, 31 Jul 2024 16:03:01 +1000 Subject: [PATCH 032/124] 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 Signed-off-by: gconnect --- .../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 21898c79ede..407edcd8fe4 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 @@ 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 String getName() { @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 aefd69141d5..bd0176dbd3f 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 @@ 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 String getName() { @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 0892cc5c647..a37db420a14 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 void whenEmptyParamOnRequestShouldThrowInvalidJsonRpcException() { 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 0dd4fb73d46..d07beb934f2 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 void whenEmptyParamOnRequestShouldThrowInvalidJsonRpcException() { 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 a70ac9e4b3a..2e8218752e6 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 void whenEmptyParamOnRequestShouldThrowInvalidJsonRpcException() { 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 934329052dc..582ef1d32ac 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 void whenEmptyParamOnRequestShouldThrowInvalidJsonRpcException() { 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 bfc462e99deeb17f5f5c7548a06acec161e5faa7 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 31 Jul 2024 16:28:57 +1000 Subject: [PATCH 033/124] removed permissioning methods referencing whitelist (#7401) * removed whitelist permissioning methods * removed actual RPC methods Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Signed-off-by: gconnect --- 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 072a84c2ba4..498b3c1edd6 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 37d530634a8..00000000000 --- 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 c75a86e28ca..00000000000 --- 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 97281ae707a..00000000000 --- 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 850872d3fd3..00000000000 --- 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 f72984f03b5..00000000000 --- 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 a0b4de534cf..00000000000 --- 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 3a3b6cfb003..96fce83eab6 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 @@ 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 @@ protected String getApiGroup() { @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 a37db420a14..4a3300d16cd 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 @@ @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 void getNameShouldReturnExpectedName() { } @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 void whenAccountsAreAddedToWhitelistShouldReturnSuccess() { 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 void whenAccountIsInvalidShouldReturnInvalidAccountErrorResponse() { 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 void whenAccountExistsShouldReturnExistingEntryErrorResponse() { 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 void whenEmptyListOnRequestShouldReturnEmptyEntryErrorResponse() { 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 d07beb934f2..00000000000 --- 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 237094b90c8..00000000000 --- 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 024349d8b23..00000000000 --- 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 9981cb27e74..00000000000 --- 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 582ef1d32ac..00000000000 --- 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 45630a25ad1..00000000000 --- 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 a8f06f52650..7484730a308 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 @@ 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 void allowlistMethodsPresent() { 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 4b0fe96ed2815430d6f6efc4666f83a03524ceda Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Wed, 31 Jul 2024 21:56:13 +1000 Subject: [PATCH 034/124] 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 Signed-off-by: gconnect --- .../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 4ca5cb0685f..47fe7738b9d 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 @@ 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 String getName() { 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 1065078f9670dfd4b23691eb205ccb6fde6f30f8 Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Wed, 31 Jul 2024 16:15:59 +0100 Subject: [PATCH 035/124] Update deps for CVEs (#7412) Signed-off-by: Matthew Whitehead Signed-off-by: gconnect --- 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 950e0ee8661..c7f3039dffb 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 6d176ba7e3a..9ad95a20748 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 9e3e25806a5ee0f271253055b5b84a66ea7898c0 Mon Sep 17 00:00:00 2001 From: Usman Saleem Date: Thu, 1 Aug 2024 01:39:44 +1000 Subject: [PATCH 036/124] 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 Signed-off-by: gconnect --- 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 498b3c1edd6..c5d782ba257 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 c31175cee8f..19a45d218ad 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 00000000000..a61b80ab8e4 --- /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 00000000000..dd620844b13 --- /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 d9e5dbb9ef7..1f014ee0610 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.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 Optional getFinalizedBlock() { 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 c7203e2f883..cc4b3237b52 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 69a2e6a8220..84a573aadc3 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 0a52e35a4a486d5c088301bce2bd98c1305e93c2 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 31 Jul 2024 18:46:16 +0200 Subject: [PATCH 037/124] In process RPC service (#7395) Signed-off-by: Fabio Di Fabio Signed-off-by: gconnect --- 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 c5d782ba257..0db9e9df3f5 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 5f30941f232..1ae27d62614 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.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 BesuNode( 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 BesuNode( 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 @@ JsonRpcIpcConfiguration jsonRpcIpcConfiguration() { 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 0448d324e64..459fe49efb3 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.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 void startNode(final BesuNode node) { .transactionPoolValidatorService(transactionPoolValidatorServiceImpl) .build(); + final InProcessRpcConfiguration inProcessRpcConfiguration = node.inProcessRpcConfiguration(); + final int maxPeers = 25; builder @@ -297,7 +300,8 @@ public void startNode(final BesuNode node) { .besuPluginContext(besuPluginContext) .autoLogBloomCaching(false) .storageProvider(storageProvider) - .rpcEndpointService(rpcEndpointServiceImpl); + .rpcEndpointService(rpcEndpointServiceImpl) + .inProcessRpcConfiguration(inProcessRpcConfiguration); node.engineRpcConfiguration().ifPresent(runnerBuilder::engineJsonRpcConfiguration); besuPluginContext.beforeExternalServices(); @@ -313,6 +317,9 @@ public void startNode(final BesuNode node) { 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 7bffe9d7750..c77a6c8ac7b 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 @@ 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 JsonRpcIpcConfiguration getJsonRpcIpcConfiguration() { 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 86fb8ab5caf..d8b5e0f9040 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.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 BesuNodeConfigurationBuilder jsonRpcIpcConfiguration( 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 BesuNodeConfiguration build() { 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 1ea29388bd5..ed4a28422dd 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 @@ 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.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 BesuNode create(final BesuNodeConfiguration config) throws IOException { config.getEngineRpcConfiguration(), config.getWebSocketConfiguration(), config.getJsonRpcIpcConfiguration(), + config.getInProcessRpcConfiguration(), config.getMetricsConfiguration(), config.getPermissioningConfiguration(), config.getApiConfiguration(), @@ -330,12 +334,20 @@ public BesuNode createArchiveNodeWithRpcDisabled(final String name) throws IOExc } 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 BesuNode createCliqueNodeWithExtraCliOptionsAndRpcApis( .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 219d15d1adf..c2e82c0f835 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.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 JsonRpcConfiguration createJsonRpcWithRpcApiEnabledConfig(final String... 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 32a5a0fbf4a..520cd7d5741 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 PrivacyNode( 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 00000000000..991e9f7bc4e --- /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 26be9d3a968..5c8b5ef6c10 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 @@ 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 @@ Request minerStop() { 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 e5cacd4e7a6..a8d24515a98 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 MinerStartTransaction minerStart() { 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 00000000000..3ebced0df91 --- /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 00000000000..4dbf8fd5d18 --- /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 eed35a03a94..609dab117ff 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.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.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 Optional getMetricsPort() { } } + /** + * 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 d0c434fc819..e34c0115fea 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.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 RunnerBuilder webSocketConfiguration(final WebSocketConfiguration webSock 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 Runner build() { 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 Runner build() { 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 dac00e06c35..73a15701be7 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -66,6 +66,7 @@ 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; @@ -110,6 +111,7 @@ 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; @@ -665,6 +667,10 @@ static class EngineRPCOptionGroup { @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(); @@ -931,6 +937,7 @@ static class MetricsOptionGroup { private GraphQLConfiguration graphQLConfiguration; private WebSocketConfiguration webSocketConfiguration; private JsonRpcIpcConfiguration jsonRpcIpcConfiguration; + private InProcessRpcConfiguration inProcessRpcConfiguration; private ApiConfiguration apiConfiguration; private MetricsConfiguration metricsConfiguration; private Optional permissioningConfiguration; @@ -1361,6 +1368,7 @@ private Runner buildRunner() { engineJsonRpcConfiguration, webSocketConfiguration, jsonRpcIpcConfiguration, + inProcessRpcConfiguration, apiConfiguration, metricsConfiguration, permissioningConfiguration, @@ -1378,6 +1386,7 @@ private void startPlugins(final Runner runner) { besuController.getProtocolContext().getWorldStateArchive(), besuController.getProtocolSchedule(), apiConfiguration.getGasCap())); + rpcEndpointServiceImpl.init(runner.getInProcessRpcMethods()); besuPluginContext.addService( BesuEvents.class, @@ -1859,6 +1868,7 @@ private void configure() throws Exception { 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 @@ -2370,6 +2380,7 @@ private Runner synchronize( final JsonRpcConfiguration engineJsonRpcConfiguration, final WebSocketConfiguration webSocketConfiguration, final JsonRpcIpcConfiguration jsonRpcIpcConfiguration, + final InProcessRpcConfiguration inProcessRpcConfiguration, final ApiConfiguration apiConfiguration, final MetricsConfiguration metricsConfiguration, final Optional permissioningConfiguration, @@ -2402,6 +2413,7 @@ private Runner synchronize( .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 00000000000..9adeb37db7d --- /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 f31323b91b8..dcfe29146e7 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 @@ 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 void registerRPCEndpoint( 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 c1770640801..c7180b958c1 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.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 void enodeUrlShouldHaveAdvertisedHostWhenDiscoveryDisabled() { .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 void movingAcrossProtocolSpecsUpdatesNodeRecord() { .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 void whenEngineApiAddedListensOnDefaultPort() { .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 void whenEngineApiAddedWebSocketReadyOnSamePort() { .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 void whenEngineApiAddedEthSubscribeAvailable() { .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 void noEngineApiNoServiceForMethods() { .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 e10d5475818..5b2a56078f5 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.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 @@ private void syncFromGenesis(final SyncMode mode, final GenesisConfigFile genesi .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 c77ced5c6fe..f6fa2e47984 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 void initMocks() throws Exception { 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 00000000000..e59d06a21fb --- /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 6817d2cfbbd..5fb82187b69 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 cc4b3237b52..e49297ab7b3 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 a1b69a7c7fe..512d9877c78 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 c360f35edc1..eab35b4b043 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 00000000000..7096a8a4227 --- /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 00000000000..3fafbb1d108 --- /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 a5d41934a6a224fac663e35f3009653c9a6224b3 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Thu, 1 Aug 2024 14:11:51 +1000 Subject: [PATCH 038/124] Add comments to make deprecated trie log pruning option names clear (#7416) Signed-off-by: Simon Dudley Signed-off-by: gconnect --- .../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 a0403c39420..6f5c037c0d3 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 57a391fd2fe0490e719e5b4aa7eb0c0913d6ea17 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 039/124] fix(doc): tiny typo (#7388) Signed-off-by: Francois Bojarski Co-authored-by: Sally MacFarlane Signed-off-by: gconnect --- .../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 762030bf3b5..68ded6793e4 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 OperationResult execute(final MessageFrame frame, final EVM evm) { 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 da6c6c0944fdf0e58bf52d525d2a7ae4188abdf8 Mon Sep 17 00:00:00 2001 From: Gaurav Ahuja Date: Thu, 1 Aug 2024 10:43:30 +0530 Subject: [PATCH 040/124] Make GeneralStateTestCaseEipSpec constructor public for use in linea-tracer/arithmetization (#7411) Signed-off-by: Gaurav Ahuja Signed-off-by: gconnect --- .../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 ddf6ac2eb1c..9d9b2785516 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 18452159c479646b740f4d7d0cf6f4bec857face Mon Sep 17 00:00:00 2001 From: ahamlat Date: Thu, 1 Aug 2024 17:00:16 +0200 Subject: [PATCH 041/124] 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 Signed-off-by: gconnect --- .../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 91ab41b636d..511b94d3ae5 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.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 @@ private 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 @@ private 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 static class Builder { 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 Builder protocolSchedule(final ProtocolSchedule protocolSchedule) { 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 ExecutionContextTestFixture build() { 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 00000000000..c9e43327d96 --- /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 00000000000..496ae672025 --- /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 00000000000..72fbc561ec7 --- /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 75d8aea21c0f508caa2b73543d27fd96ec9836ac Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Thu, 1 Aug 2024 19:36:45 +0200 Subject: [PATCH 042/124] 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 Signed-off-by: gconnect --- .../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 08b7a067a19..ee80bc2d777 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 Bytes execute() { }) .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 2428da2dc2a..b6baf9dd012 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 PrecompileContractResult computePrecompile( 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 5a50490f6b4a9b970d4fcc403652b3c6876ed07b Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 2 Aug 2024 13:05:33 +1000 Subject: [PATCH 043/124] 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 Signed-off-by: gconnect --- .../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 4fb3af6cd46..467164e8c02 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.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 String getName() { 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 0e278dee953..f2b81d56e3e 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.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 String getName() { 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 038f97e1e74..80220a3f04a 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 void discardWithoutAddress() { 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 2fdc60c1298..7e6c0010888 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.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 String getName() { 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 fe89961410e..a29187b5138 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.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 String getName() { 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 da0a35ab2fe..7a25ab67b85 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 void returnsCorrectMethodName() { 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 d667bb173b4..d0df723d54f 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 void returnsCorrectMethodName() { 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 void exceptionWhenNoAuthSupplied() { 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 7e9a3b973fd..98856caaa61 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.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 String getName() { @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 160ca144d69..9eefbb8d13a 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.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 String getName() { @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 0716fd42d20..c8ce4195695 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 void returnsCorrectMethodName() { 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 fa3f89036eb..62f7dc61691 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 void returnsCorrectMethodName() { 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 void exceptionWhenNoAuthSupplied() { 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 3d823886484..db6481b46aa 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 JsonRpcResponse process( 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 f4a56f05eb5..8fafd5ec3da 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 0ea50b41aca..72110852b76 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 8b658d27530..449de64261a 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( @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 2417b422fa2..9002b6d89ce 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( @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 96602e23a97..67a07924080 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 e2741233f61..efec2ee1d6f 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( @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 053588e89a4..a03d90ea293 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( @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 @@ protected Object pendingResult(final JsonRpcRequestContext request) { @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 eda085d77c4..d6676a60740 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 c09e21dc2a2..8f0e8290842 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 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 String getName() { 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 b7cafd8cabe..56318da37eb 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 @@ 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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { 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 3ec2d87b6aa..cd107b2e713 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 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 31cac2b8b3d..c796d35d5f4 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 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 0275626addd..e6cf056989d 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 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 String getName() { 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 2106b86744d..344ee39d80f 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 @@ void errorWhenNoAddressAccountSupplied() { 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 a50a9576b08..20abf9e9c1d 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 void shouldFailWhenMissingAddress() { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessage("Missing required json rpc parameter at index 0"); + .hasMessage("Invalid address parameter (index 0)"); } @Test From a2da625b7fafee49e14f4f9c41be84d7cd6af046 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Thu, 1 Aug 2024 22:32:32 -0600 Subject: [PATCH 044/124] EOF validation updates (#7419) * Ensure forward calls stack height range is preserved. * add subcontainer and top container size checks Signed-off-by: Danno Ferrin Signed-off-by: gconnect --- .../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 465f2c48951..2e1656b13d4 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 void run() { 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 00000000000..27833a1bb93 --- /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 3c85bd1eb22..f968bbf36aa 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 @@ String validateStack( "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 1249e475b43..39723f7fd37 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 @@ String subcontainerIndex() { * 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 static EOFLayout parseEOF(final Bytes container, final boolean strictSize + " - " + 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 f32a3f48668..08cbbedf75c 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.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 @@ static Stream stackUnderflow() { "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 145adfb2dd9..006fe1632b9 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 static Collection subContainers() { 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 73cec314a812947a12d2f61f6d76ecac586c03d8 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 2 Aug 2024 15:50:49 +1000 Subject: [PATCH 045/124] 5098: Update already merged RpcErrorTypes to include index in exception message (#7420) Signed-off-by: Matilda Clerke Signed-off-by: gconnect --- .../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 47fe7738b9d..32ed9c56118 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 407edcd8fe4..f3407ba10d6 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 bd0176dbd3f..a39acd5e9cd 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 4a3300d16cd..a87a6487fb5 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 void whenEmptyParamOnRequestShouldThrowInvalidJsonRpcException() { 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 2e8218752e6..af3fc2ee6ad 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 void whenEmptyParamOnRequestShouldThrowInvalidJsonRpcException() { 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 5656b084f75aa1634be74b0e02f888d747c9a2ad Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 2 Aug 2024 16:17:18 +1000 Subject: [PATCH 046/124] 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 Signed-off-by: gconnect --- .../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 f2b81d56e3e..6e198a84fe2 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 eba3827bfaf..822c6ac895b 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 JsonRpcResponse process( 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 JsonRpcResponse process( 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 309fe498627..d46dc900c57 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 b11d633e626e5e03122468b28c107abcda4494de Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 2 Aug 2024 18:04:40 +1000 Subject: [PATCH 047/124] 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 Signed-off-by: gconnect --- .../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 543c965c804..68adb2ab69c 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 @@ protected ValidationResult validateBlobs( // 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 @@ protected ValidationResult validateBlobs( 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 42048e35e391048686382d50c3feae3687bc3f4a Mon Sep 17 00:00:00 2001 From: Justin Florentine Date: Fri, 2 Aug 2024 13:01:58 -0400 Subject: [PATCH 048/124] 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 Signed-off-by: gconnect --- .../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 a2ffc9b36da..0913fd227f3 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 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 void verify(final Node node) { 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 459fe49efb3..7e8d435c721 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 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.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.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 void startNode(final BesuNode node) { 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 void startNode(final BesuNode node) { .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 void startNode(final BesuNode node) { .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 void startNode(final BesuNode node) { .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 void startConsoleCapture() { 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 520cd7d5741..d54bf908726 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 @@ private PrivacyStorageProvider createKeyValueStorageProvider( 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 8fbd0d3d625..39cc5ad26fc 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 void setUp() throws Exception { 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 286ca7a30fc..7eef4a216c2 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 ddb75fcdedc..6bb3fb117c1 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 BesuController build() { 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 1f014ee0610..f10ebcce474 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.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 eda202f6d4d..e43bf1c054e 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.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 dcfe29146e7..5d7df73b2ef 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.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 c3905c304bc..5605fe49b5f 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.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 6629da690e8..dd5d822ccc3 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.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 1e1f94fb324..46af0a6ea54 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.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 8595a3c030b..c7049c9aa0a 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.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 54cce205a36..8ec00e81703 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.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 00000000000..a246d18d2ff --- /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 ceb0be40fe6..6298b70a953 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.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.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.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.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 void setUp() throws IOException { .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 void privacyGroupHeadIsTracked() { // 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 void reorgToChainAtEqualHeight() { // 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 void reorgToChainAtEqualHeight() { 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 void reorgToLongerChain() { } @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 @@ private BlockDataGenerator.BlockOptions getBlockOptions( .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 dc5b7003c84..4d488ced3bc 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 @@ 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.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 @@ private PrecompiledContract getPrecompile( 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 5b2a56078f5..5fefc7ef224 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.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 @@ private BesuController getController( .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 05057f15c83..bbc7dea1abb 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 @@ 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 @@ private static BesuController createController(final @TempDir Path dataDir) thro .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 73015afd005..7b1a4bc7d2c 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 @@ 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 @@ protected BesuController createController(final GenesisConfigFile genesisConfigF .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 e37b8a5fd08..7d4fabb2225 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 @@ 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 void blockImport() throws IOException { .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 void blockImportRejectsBadPow() throws IOException { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) + .besuComponent(mock(BesuComponent.class)) .build(); assertThatThrownBy( @@ -140,6 +144,7 @@ public void blockImportCanSkipPow() throws IOException { .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 00000000000..20f9c1bf497 --- /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 00000000000..ae82b8b9288 --- /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 00000000000..743b4ee8de9 --- /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 00000000000..e7807e3d759 --- /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 00000000000..0b8fcf744ff --- /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 00000000000..13cafe1ab45 --- /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 731fd2ac568..c7caf62ec2a 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.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 void setup() throws JsonProcessingException { .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 82f98ba8266..aa79b944a11 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.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 void setup() throws JsonProcessingException { .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 0e4948ddd5c..c788f417103 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.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 @@ MergeBesuControllerBuilder visitWithMockConfigs(final MergeBesuControllerBuilder .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 e1d158f3fce..e087edd4312 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 Builder ipAddress(final String ip) { 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 Builder ipAddress(final String ip, final EnodeDnsConfiguration enodeDnsCo 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 a2ac648ae6012505ec6a85006d6eaf8ccfe31ecf Mon Sep 17 00:00:00 2001 From: leeli Date: Mon, 5 Aug 2024 12:20:30 +0200 Subject: [PATCH 049/124] redirect the path in readme (#7422) Signed-off-by: Lee Co-authored-by: daniellehrner Signed-off-by: gconnect --- .../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 40dc739ed5d..c6a92e2cff9 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 a9eef5a3dc7f244e479e4e0405400e758246d3f9 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 6 Aug 2024 01:23:01 -0600 Subject: [PATCH 050/124] 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 Signed-off-by: gconnect --- .../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 3bc2d41d02c..962fc2804b7 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.IntStream; import org.apache.tuweni.bytes.Bytes; +import org.web3j.utils.Strings; import picocli.CommandLine; import picocli.CommandLine.ParentCommand; @@ -107,7 +108,10 @@ public void run() { } } 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 void run() { 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 String considerCode(final String hexCode) { 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 String considerCode(final String hexCode) { 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 String considerCode(final String hexCode) { .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 c119235cdc1..5ecd5511a50 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 4dba98b1840d5dfd52c262a485703a62c44c7dd4 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 6 Aug 2024 18:37:29 -0600 Subject: [PATCH 051/124] 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 Signed-off-by: gconnect --- 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 0db9e9df3f5..bae9c5b77c8 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 9d7b48d3cb1..b16407be293 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 dec0555640c..12632070281 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 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 898f1dd4b6a..989c6e0b7fe 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.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 void run() { 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 00000000000..58402eeaa48 --- /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 00000000000..ff9bf415e60 --- /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 00000000000..b88134778ec --- /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 a5d29cbde25225ae2edfaa3fcf1c2235403131dd Mon Sep 17 00:00:00 2001 From: Lucas Saldanha Date: Fri, 9 Aug 2024 09:41:07 +1200 Subject: [PATCH 052/124] Restore previous behaviour for preMergeBesuControllerBuilder (#7431) Signed-off-by: gconnect --- CHANGELOG.md | 1 + .../besu/controller/TransitionBesuControllerBuilder.java | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bae9c5b77c8..6a97946652d 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 d7b701b4c5d..251ffba1c24 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.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 @@ protected MiningCoordinator createMiningCoordinator( transitionProtocolSchedule.getPreMergeSchedule(), protocolContext, transactionPool, - MiningParameters.MINING_DISABLED, + ImmutableMiningParameters.builder() + .from(miningParameters) + .mutableInitValues( + ImmutableMiningParameters.MutableInitValues.builder() + .isMiningEnabled(false) + .build()) + .build(), syncState, ethProtocolManager), mergeBesuControllerBuilder.createTransitionMiningCoordinator( From 485f0687b5bc492071b8bb345490b3ef421ca896 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 053/124] chore: fix some typos (#7438) Signed-off-by: MASDXI Signed-off-by: gconnect --- .../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 251ffba1c24..ee2611d9c87 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 BesuControllerBuilder dataStorageConfiguration( 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 53b3541a5b0..d7a7b1ce66c 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.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 f1a022fa7c2..e011329c071 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 void applyGenesisToPrivateWorldState( 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 8dc536c7bf6..5368a7fd749 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 ee80bc2d777..a0461980432 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 EvmSpecVersion getEVMVersion() { } /** - * 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 0cf6bc4f765..f8af2bdddbd 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.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 e2dd7861c9723d6ff8ab5fd839c2f44174fb1a34 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 12 Aug 2024 10:46:29 +1000 Subject: [PATCH 054/124] 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 Signed-off-by: gconnect --- .../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 68adb2ab69c..c548507710d 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 @@ protected ValidationResult validateBlobs( 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 08a6b6b3d0a..640d8dc6036 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 @@ protected ValidationResult validateParameters( 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 8f7a32899ee..1ca232b7737 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 @@ protected ValidationResult validateParameters( 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 93060821f80..8b073a95552 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 @@ protected ValidationResult validateParameters( 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 412dc6f8927..afee556eda2 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 @@ 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 void shouldValidateBlobGasUsedCorrectly() { 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 c19bb8fbcbd..82025888176 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 void shouldValidateBlobGasUsedCorrectly() { 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 52d77a6f04194bc3817a9f6bb7ededf68c7cd5f9 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 12 Aug 2024 14:16:53 +1000 Subject: [PATCH 055/124] 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 Signed-off-by: gconnect --- .../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 9f7b2d9f9d5..813c296098c 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 5e36ca2070c..7992f0918c4 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 @@ 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 IbftGetValidatorsByBlockNumber( @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 804ecc6b5a0..7a64a7ab22a 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.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 QbftGetValidatorsByBlockNumber( @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 a7c3aa254ea..9f76609fd79 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 void missingTagParameterBlockHashes() { 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 void missingTagParameterBlockTransactions() { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasMessageContaining("Invalid json rpc parameter at index 0"); + .hasMessageContaining("Invalid block parameter"); } /** @@ -437,7 +437,6 @@ public void missingHashesOrTransactionParameter() { assertThat(thrown) .isInstanceOf(InvalidJsonRpcParameters.class) - .hasNoCause() .hasMessage("Missing required json rpc parameter at index 1"); } @@ -453,8 +452,7 @@ public void missingAllParameters() { 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 e55a8c4785c..6dbf9f586fe 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 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 String getName() { @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 4fd98cd4fed..a5965211757 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 @@ 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 @@ protected AbstractTraceByBlock( @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 fd197110b68..437f7f5821a 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 @@ 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 String getName() { @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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 8fafd5ec3da..550a25982d2 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 String getName() { @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 32ed9c56118..c891bde56a9 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 String getName() { @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 cec275e5a62..28d886bd81e 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 @@ 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 String getName() { @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 05ef0eb53db..e2f2c89e1aa 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 @@ 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 String getName() { @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 7965480c6fb..cddba5086e8 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 @@ 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 String getName() { @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 7d26eaca25e..a3b423675fd 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.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 String getName() { @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 72110852b76..9f0f2f0b1e3 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 String getName() { @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 3a1dee65608..44cbf153dee 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 32d0e02f90c..dce3ab1ebf1 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 @@ 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 String getName() { @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 0243398833e..9de8108e679 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 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 @@ protected TraceOptions getTraceOptions(final JsonRpcRequestContext requestContex @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 c645bab453f..a08b17dfc63 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.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 String getName() { @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 6bea493d312..26e414acda9 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.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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 449de64261a..e863626c967 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 String getName() { @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 c1bdcc37dd2..19ad9a51ad2 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 @@ 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 String getName() { @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 54a37332860..d9592db8c11 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 @@ 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 String getName() { @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 b6819c7510d..2a068a61740 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 @@ 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 String getName() { @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 9002b6d89ce..8a9881a0125 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 String getName() { @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 83ca008890d..c2df7126864 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 @@ 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 String getName() { @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 67a07924080..a20cd62f290 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 String getName() { @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 efec2ee1d6f..7b84365b561 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 String getName() { @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 ab08127ca79..6a419d35c54 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 @@ 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 String getName() { @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 a03d90ea293..a9916099eac 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 String getName() { @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 2687982b8e3..d2ac0b26af8 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 @@ 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 String getName() { @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 5fbfc80a988..e79c0b60b7d 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 cd78d837dfa..5ec46e08cc4 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 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 String getName() { @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 3e3b0c9343c..8dabd29a3ee 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 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 String getName() { @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 058fbd47960..50e580cd86d 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 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 String getName() { @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 31469530b09..8fe48474a83 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 String getName() { @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 6ccc9630f96..b6ea645dc3e 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.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 String getName() { @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 56318da37eb..0010b8e0525 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 String getName() { @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 7c3157d2231..96b9b9f7793 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 void getBlockByNumberForInvalidBlockParameter() throws Exception { // 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 b12cdbe22fd..e2837593800 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 void exceptionWhenNoBoolSupplied() { 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 5e8ad1455d8..545b43a6e70 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 void returnsCorrectMethodName() { 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 ca65fcf42ab..9295e64da91 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 void exceptionWhenNoNumberSuppliedTest() { 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 void exceptionWhenNumberParamInvalidTest() { 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 344ee39d80f..3cf24df3d45 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 @@ void errorWhenNoBlockNumberSupplied() { 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 59b20d58466..06c7408a84a 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 void shouldReturnErrorWhenMissingBlockNumberParam() { 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 562e0f33265..70a9be13f5c 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 d6a714eb49b..f00531954c3 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 fa6fab63065..7e56b0a5669 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 e84f3045a33..0f07f4a3bbe 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 91f6a6af8f7..4dca011466b 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 655ff6013ae..8fc9c2d805a 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 7e40d417e76..1a56a83a607 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 a5e1e004af8..9e715fca1da 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 5a65b4d17c5..929a0f3f358 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 257380fdac1..4fb69d437c9 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 ba169f79dea..095ebd2a910 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 3ab3afb25ea..e8fecda1030 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 99af70906a3..9ad533c0c68 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 8ba25d9c33b..c88d01904db 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 52651090e96..f98c40c0d2c 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 0ad4a0d3cb4..c25d81a1abb 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 75437d4db8a..75ca3aed1aa 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 b67f6eb872a..42967740d90 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 0652b92cdbf..516dc2f55f1 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 @@ 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 String getName() { @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 062a51bc7f50f7d62a87781bf3a2b26c5f945939 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 12 Aug 2024 14:54:07 +1000 Subject: [PATCH 056/124] 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 Signed-off-by: gconnect --- .../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 26e414acda9..92d42f22784 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 String getName() { 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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 5fdd1657f67..88431dd89bd 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 @@ 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { 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 a0821abf2de..0ed7e133822 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 void blockCountBounds() { 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 3060b326bb8..7907cee3f78 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 @@ 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 String getName() { @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 e65a87e7f4311f5e342da4dcc7c8db54f49355b0 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 12 Aug 2024 15:39:35 +1000 Subject: [PATCH 057/124] 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 Signed-off-by: gconnect --- .../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 8dd7ac5c23a..c683b9d4855 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 ee5dc0f023c..3699ccf6eed 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 void failsWhenNoParam() { 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 a14eb49e876..3c3346cd436 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 4726e81bd33..e991f7f355d 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 8110bf6c2c4..be6ecfa82e6 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 @@ protected Object handleParamTypes(final JsonRpcRequestContext requestContext) { 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 25c59e47636..7587e40c75a 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.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 String getName() { @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 306f4c449ed..601eabeab14 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 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 String getName() { @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 c1caaef2b9e..b1216885f1a 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 @@ 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 String getName() { @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 04cad96291e..d5f1bba01c9 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 a9654555953..e1fbd790868 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 @@ 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 String getName() { @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 0e868d89870..8e3d55f1eab 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.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 String getName() { @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 311da6b45f4..93ae857a695 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 c8efa19f309..9a5a3b225ba 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 @@ 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 String getName() { @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 b5644502464..0e6b62d320f 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { 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 96b9b9f7793..05284af6b87 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 void getBlockByHashWithMissingHashParameter() throws Exception { 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 void getBlockByHashWithInvalidHashParameterWithOddLength() throws Excepti 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 void getBlockByHashWithInvalidHashParameterThatIsTooShort() throws Except 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 void getBlockByHashWithAllParametersMissing() throws Exception { 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 void getBlockByHashWithNoParameters() throws Exception { 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 1747030ba60..28043b2e092 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 void exceptionWhenNoBoolSupplied() { 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 08737d0546c..9d93dde85ae 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 void exceptionWhenNoHashSuppliedTest() { 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 void exceptionWhenHashParamInvalidTest() { 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 07f8364615c..fff08f81fbd 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 void shouldReturnErrorWhenMissingBlockHashParam() { 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 void shouldReturnErrorWhenInvalidBlockHashParam() { 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 e05ba50cc6e..07a35abf6d9 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 03fc632fa467209761efc1ebfdcdce47c513d9db Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Mon, 12 Aug 2024 11:38:59 +0200 Subject: [PATCH 058/124] 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 Signed-off-by: gconnect --- 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 6a97946652d..e7921fac5f3 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 8600344cefe..f24e11bd8b7 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.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 String listMilestones() { 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 ec65ebe7a9e..eec79e9a7cd 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.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.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 @@ 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 AbstractEngineForkchoiceUpdated( 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 747c63c162f..1dedf2919a3 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.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 String getName() { @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 b5aebf4f5d7..414d4625b2a 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.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 @@ 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 EngineForkchoiceUpdatedV3( 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 @@ protected ValidationResult validateParameter( @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 @@ protected Optional isPayloadAttributesValid( 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 ade62077df0..1732585f163 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.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 @@ public class EngineGetPayloadV2 extends AbstractEngineGetPayload { - private final Optional cancun; + private final Optional cancunMilestone; public EngineGetPayloadV2( final Vertx vertx, @@ -49,7 +50,7 @@ public EngineGetPayloadV2( mergeMiningCoordinator, blockResultFactory, engineCallListener); - this.cancun = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun")); + cancunMilestone = schedule.milestoneFor(CANCUN); } @Override @@ -67,20 +68,10 @@ protected JsonRpcResponse createResponse( @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 742a240aa02..555afb50b91 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.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 @@ public class EngineGetPayloadV3 extends AbstractEngineGetPayload { - private final Optional cancun; + private final Optional cancunMilestone; public EngineGetPayloadV3( final Vertx vertx, @@ -49,7 +50,7 @@ public EngineGetPayloadV3( mergeMiningCoordinator, blockResultFactory, engineCallListener); - this.cancun = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Cancun")); + cancunMilestone = schedule.milestoneFor(CANCUN); } @Override @@ -67,17 +68,6 @@ protected JsonRpcResponse createResponse( @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 c5a713beea2..f67a2743eac 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.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 @@ public class EngineGetPayloadV4 extends AbstractEngineGetPayload { - private final Optional prague; + private final Optional pragueMilestone; public EngineGetPayloadV4( final Vertx vertx, @@ -49,7 +50,7 @@ public EngineGetPayloadV4( mergeMiningCoordinator, blockResultFactory, engineCallListener); - this.prague = schedule.hardforkFor(s -> s.fork().name().equalsIgnoreCase("Prague")); + pragueMilestone = schedule.milestoneFor(PRAGUE); } @Override @@ -67,17 +68,6 @@ protected JsonRpcResponse createResponse( @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 640d8dc6036..ba7624a493e 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 io.vertx.core.Vertx; public class EngineNewPayloadV2 extends AbstractEngineNewPayload { + private final Optional cancunMilestone; public EngineNewPayloadV2( final Vertx vertx, @@ -42,6 +45,7 @@ public EngineNewPayloadV2( final EthPeers ethPeers, final EngineCallListener engineCallListener) { super(vertx, protocolSchedule, protocolContext, mergeCoordinator, ethPeers, engineCallListener); + cancunMilestone = protocolSchedule.milestoneFor(CANCUN); } @Override @@ -74,4 +78,13 @@ protected ValidationResult validateBlobs( 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 1ca232b7737..c6bfb638c87 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.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 @@ public class EngineNewPayloadV3 extends AbstractEngineNewPayload { - private final Optional cancun; + private final Optional cancunMilestone; public EngineNewPayloadV3( final Vertx vertx, @@ -42,7 +43,7 @@ public EngineNewPayloadV3( 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 @@ protected ValidationResult validateParameters( @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 8b073a95552..09354fa1bac 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.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 @@ public class EngineNewPayloadV4 extends AbstractEngineNewPayload { - private final Optional prague; + private final Optional pragueMilestone; public EngineNewPayloadV4( final Vertx vertx, @@ -42,7 +43,7 @@ public EngineNewPayloadV4( 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 @@ protected ValidationResult validateParameters( @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 00000000000..0059f3d61b1 --- /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 6936f2833d4..d2fb3c37411 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.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 AbstractEngineForkchoiceUpdatedTest(final MethodFactory methodFactory) { 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 AbstractEngineForkchoiceUpdatedTest(final MethodFactory methodFactory) { 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 void before() { 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 void shouldReturnValidWithoutFinalizedWithPayload() { var payloadParams = new EnginePayloadAttributesParameter( - String.valueOf(System.currentTimeMillis()), + String.valueOf(defaultPayloadTimestamp()), Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), Address.ECREC.toString(), null, @@ -426,7 +429,7 @@ public void shouldIgnoreUpdateToOldHeadAndNotPreparePayload() { var payloadParams = new EnginePayloadAttributesParameter( - String.valueOf(System.currentTimeMillis()), + String.valueOf(defaultPayloadTimestamp()), Bytes32.fromHexStringLenient("0xDEADBEEF").toHexString(), Address.ECREC.toString(), null, @@ -488,7 +491,7 @@ public void shouldReturnInvalidIfWithdrawalsIsNotNull_WhenWithdrawalsProhibited( 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 void shouldReturnValidIfWithdrawalsIsNull_WhenWithdrawalsProhibited() { 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 void shouldReturnInvalidIfWithdrawalsIsNull_WhenWithdrawalsAllowed() { 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 void shouldReturnValidIfWithdrawalsIsNotNull_WhenWithdrawalsAllowed() { 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 void shouldReturnValidIfProtocolScheduleIsEmpty() { 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 void shouldReturnValidIfProtocolScheduleIsEmpty() { 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 @@ protected RpcErrorType expectedInvalidPayloadError() { return RpcErrorType.INVALID_PARAMS; } - private JsonRpcResponse resp( + protected JsonRpcResponse resp( final EngineForkchoiceUpdatedParameter forkchoiceParam, final Optional payloadParam) { return method.response( @@ -772,4 +775,8 @@ private void assertInvalidForkchoiceState( 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 9da345dbcdc..bfe23e07e77 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 boolean matches(final Predicate value) { @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 550e1380d27..7ae80313a1d 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 void shouldReturnExpectedMethodName() { 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 5f42f02c82b..5c455222f17 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 void shouldReturnExecutionPayloadWithoutWithdrawals_PreShanghaiBlock() { 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 afee556eda2..4d53d83cf8b 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.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 void shouldReturnInvalidIfWithdrawalsIsNull_WhenWithdrawalsAllowed() { 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 82025888176..72f0108a692 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 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 @@ private Transaction createTransactionWithBlobs() { .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 e868abf2aed..d6d3cc0a559 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 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 void putTimestampMilestone(final long timestamp, final ProtocolSpec proto 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 Optional hardforkFor( .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 00000000000..6c764a42094 --- /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 e07b2835e9f..88448a8b549 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.ProcessableBlockHeader; import java.math.BigInteger; +import java.util.Map; import java.util.Optional; import java.util.function.Predicate; @@ -46,11 +47,19 @@ default ProtocolSpec getForNextBlockHeader( 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 1cb3a5cb3c5..fb8abbe1b65 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.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 @@ private void initSchedule( 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 @@ private void initSchedule( 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 @@ private long validateForkOrder( 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 @@ private NavigableMap buildMilestoneMap( 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 @@ private Optional createMilestone( 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 @@ private void addProtocolSpec( } 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 0e1011de761..a1f3d647979 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 @@ 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.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 @@ void createProtocolScheduleInOrder() { .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 ccbfcf97b7141355c58c7f348c9e627d344818f7 Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Mon, 12 Aug 2024 20:23:20 +0000 Subject: [PATCH 059/124] Move creator address warmup from targetContractAddress generation method to createe frame (#7415) Signed-off-by: Luis Pinto Signed-off-by: gconnect --- .../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 cf776192299..fe44664d856 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 MessageFrame build() { 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 16ea218f9c6..901f7ff9de2 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 @@ protected int getPcIncrement() { * @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 @@ private void fail(final MessageFrame frame) { 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 a044cd138fa..1fe3ef6469d 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 long cost(final MessageFrame frame, final Supplier unused) { } @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 fc260024530..a82288fff71 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 long cost(final MessageFrame frame, final Supplier unused) { } @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 0fb1e34a745..11d361e54c0 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 long cost(final MessageFrame frame, final Supplier codeSupplier) { } @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 3c99bd71ffc..d066b4e9abf 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 @@ public long cost(final MessageFrame frame, final Supplier unused) { } @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 51e2863a69b..a08fd2916fd 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 @@ void shouldCalculateAddress( 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 048779919ea50621d1623fdddbba2de342f0a94e Mon Sep 17 00:00:00 2001 From: daniellehrner Date: Mon, 12 Aug 2024 23:28:06 +0200 Subject: [PATCH 060/124] 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 Signed-off-by: gconnect --- 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 e7921fac5f3..616ac3d1dc8 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 c40eca0f742..1d25d2d34fc 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.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 AuthorityProcessor(final Optional maybeChainId) { } 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 void addContractToAuthority( } 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 void addContractToAuthority( 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 void addContractToAuthority( 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 cb9cd24e23d..b008a8d5f60 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.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 TransactionProcessingResult processTransaction( 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 TransactionProcessingResult processTransaction( } 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 TransactionProcessingResult processTransaction( return TransactionProcessingResult.invalid(validationResult); } - operationTracer.tracePrepareTransaction(worldState, transaction); + operationTracer.tracePrepareTransaction(evmWorldUpdater, transaction); final Set
addressList = new BytesTrieSet<>(Address.SIZE); @@ -324,10 +323,8 @@ public TransactionProcessingResult processTransaction( 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 TransactionProcessingResult processTransaction( 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 TransactionProcessingResult processTransaction( .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 TransactionProcessingResult processTransaction( 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 TransactionProcessingResult processTransaction( 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 TransactionProcessingResult processTransaction( 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 TransactionProcessingResult processTransaction( } } catch (final MerkleTrieException re) { operationTracer.traceEndTransaction( - worldState.updater(), + evmWorldUpdater.updater(), transaction, false, Bytes.EMPTY, @@ -590,7 +584,7 @@ public TransactionProcessingResult processTransaction( 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 b4e8e285617..fc20db7f813 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.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 WorldUpdater updater() { 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 0799ed3db27..c28bb731b5b 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 MutableAccount createAccount(final Address address, final long nonce, fin accountsToUpdate.put(address, diffBasedValue); } else if (diffBasedValue.getUpdated() != null) { if (diffBasedValue.getUpdated().isEmpty()) { - return authorizedCodeService.processMutableAccount( - this, track(new UpdateTrackingAccount<>(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 MutableAccount createAccount(final Address address, final long nonce, fin Hash.EMPTY, true); diffBasedValue.setUpdated(newAccount); - return authorizedCodeService.processMutableAccount( - this, track(new UpdateTrackingAccount<>(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 c64ca3744fd..f52e788babf 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.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 SimpleWorld() { */ public SimpleWorld(final SimpleWorld parent) { this.parent = parent; - this.authorizedCodeService = new AuthorizedCodeService(); } @Override @@ -60,11 +56,11 @@ public WorldUpdater updater() { @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 MutableAccount createAccount(final Address address, final long nonce, fin } 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 MutableAccount getAccount(final Address address) { 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 void commit() { 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 fe44664d856..16551876d24 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.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 enum Type { // Global data fields. private final WorldUpdater worldUpdater; - private final AuthorizedCodeService authorizedCodeService; // Metadata fields. private final Type type; @@ -272,8 +270,7 @@ private 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 @@ private MessageFrame( this.completer = completer; this.contextVariables = contextVariables; this.revertReason = revertReason; - this.authorizedCodeService = authorizedCodeService; this.undoMark = txValues.transientStorage().mark(); } @@ -427,15 +423,6 @@ public Bytes getReturnData() { 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 static class Builder { 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 Builder versionedHashes(final Optional> versionedHash 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 MessageFrame build() { boolean newStatic; TxValues newTxValues; - if (authorizedCodeService == null) { - authorizedCodeService = new AuthorizedCodeService(); - } - if (parentMessageFrame == null) { newTxValues = new TxValues( @@ -1721,8 +1692,6 @@ public MessageFrame build() { parentMessageFrame.warmUpAddress(contract); } - updater.setAuthorizedCodeService(authorizedCodeService); - MessageFrame messageFrame = new MessageFrame( type, @@ -1739,8 +1708,7 @@ public MessageFrame build() { 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 68ded6793e4..12cb06eaa61 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 OperationResult execute(final MessageFrame frame, final EVM evm) { .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 901f7ff9de2..3bc712341ba 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 @@ private void spawnChildMessage(final MessageFrame parent, final Code code, final .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 e19b6cd8a29..43d7e343ff1 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 OperationResult execute(final MessageFrame frame, final EVM evm) { .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 00cd67ddb81..9623eaf89ed 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 Account get(final Address address) { // We may have updated it already, so check that first. final MutableAccount existing = updatedAccounts.get(address); if (existing != null) { - return authorizedCodeService.processAccount(this, existing, address); + return existing; } if (deletedAccounts.contains(address)) { return null; } - return authorizedCodeService.processAccount(this, getForMutation(address), address); + return getForMutation(address); } @Override @@ -112,7 +108,7 @@ public MutableAccount getAccount(final Address address) { // We may have updated it already, so check that first. final MutableAccount existing = updatedAccounts.get(address); if (existing != null) { - return authorizedCodeService.processMutableAccount(this, existing, address); + return existing; } if (deletedAccounts.contains(address)) { return null; @@ -121,10 +117,9 @@ public MutableAccount getAccount(final Address address) { // Otherwise, get it from our wrapped view and create a new update tracker. final A origin = getForMutation(address); if (origin == null) { - return authorizedCodeService.processMutableAccount(this, null, address); + return null; } else { - return authorizedCodeService.processMutableAccount( - this, track(new UpdateTrackingAccount<>(origin)), address); + return track(new UpdateTrackingAccount<>(origin)); } } @@ -170,11 +165,6 @@ public Optional parentUpdater() { } } - @Override - public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { - this.authorizedCodeService = authorizedCodeService; - } - /** * The accounts modified in this updater. * 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 new file mode 100644 index 00000000000..bac21e73fc8 --- /dev/null +++ b/evm/src/main/java/org/hyperledger/besu/evm/worldstate/EVMWorldUpdater.java @@ -0,0 +1,127 @@ +/* + * 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.datatypes.Wei; +import org.hyperledger.besu.evm.account.Account; +import org.hyperledger.besu.evm.account.MutableAccount; +import org.hyperledger.besu.evm.frame.MessageFrame; + +import java.util.Collection; +import java.util.Optional; + +/** + * The EVM world updater. This class is a wrapper around a WorldUpdater that provides an + * AuthorizedCodeService to manage the authorized code for accounts. + */ +public class EVMWorldUpdater implements WorldUpdater { + private final WorldUpdater rootWorldUpdater; + private final AuthorizedCodeService authorizedCodeService; + + /** + * Instantiates a new EVM world updater. + * + * @param rootWorldUpdater the root world updater + */ + public EVMWorldUpdater(final WorldUpdater rootWorldUpdater) { + this(rootWorldUpdater, new AuthorizedCodeService()); + } + + private EVMWorldUpdater( + final WorldUpdater rootWorldUpdater, final AuthorizedCodeService authorizedCodeService) { + this.rootWorldUpdater = rootWorldUpdater; + this.authorizedCodeService = authorizedCodeService; + } + + /** + * Authorized code service. + * + * @return the authorized code service + */ + public AuthorizedCodeService authorizedCodeService() { + return authorizedCodeService; + } + + @Override + public MutableAccount createAccount(final Address address, final long nonce, final Wei balance) { + return authorizedCodeService.processMutableAccount( + this, rootWorldUpdater.createAccount(address, nonce, balance), address); + } + + @Override + public MutableAccount getAccount(final Address address) { + return authorizedCodeService.processMutableAccount( + this, rootWorldUpdater.getAccount(address), address); + } + + @Override + public MutableAccount getOrCreate(final Address address) { + return authorizedCodeService.processMutableAccount( + this, rootWorldUpdater.getOrCreate(address), address); + } + + @Override + public MutableAccount getOrCreateSenderAccount(final Address address) { + return authorizedCodeService.processMutableAccount( + this, rootWorldUpdater.getOrCreateSenderAccount(address), address); + } + + @Override + public MutableAccount getSenderAccount(final MessageFrame frame) { + return authorizedCodeService.processMutableAccount( + this, rootWorldUpdater.getSenderAccount(frame), frame.getSenderAddress()); + } + + @Override + public void deleteAccount(final Address address) { + rootWorldUpdater.deleteAccount(address); + } + + @Override + public Collection 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 2497ed348d7..9987a5be752 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 JournaledUpdater(final WorldUpdater world, final EvmConfiguration evmConf "WorldUpdater must be a JournaledWorldUpdater or an AbstractWorldUpdater"); } undoMark = accounts.mark(); - this.authorizedCodeService = new AuthorizedCodeService(); } /** @@ -128,18 +126,12 @@ public void markTransactionBoundary() { 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 MutableAccount getAccount(final Address address) { // 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 MutableAccount getAccount(final Address address) { // 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 void deleteAccount(final Address address) { 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 5144176e799..4cbda732798 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 @@ default void clearAccountsThatAreEmpty() { 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 479376a8fe3..e1e9c4c3ad3 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.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 ToyWorld() { public ToyWorld(final ToyWorld parent) { this.parent = parent; - this.authorizedCodeService = new AuthorizedCodeService(); } @Override @@ -52,11 +49,11 @@ public WorldUpdater updater() { @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 MutableAccount createAccount( 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 MutableAccount getAccount(final Address address) { parentAccount.getCode()); } } else { - return authorizedCodeService.processMutableAccount(this, null, address); + return null; } } @@ -131,9 +128,4 @@ public void commit() { public Optional parentUpdater() { return Optional.empty(); } - - @Override - public void setAuthorizedCodeService(final AuthorizedCodeService authorizedCodeService) { - this.authorizedCodeService = authorizedCodeService; - } } From 57275ce7992ccd9e5a89ada194b01eb1268e17e2 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 13 Aug 2024 14:19:43 +1000 Subject: [PATCH 061/124] 5098: Disable txpoolForcePriceBumpToZeroWhenZeroBaseFeeMarket test and add comment explaining why (#7452) Signed-off-by: Matilda Clerke Signed-off-by: gconnect --- .../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 a5ca07484a0..8389ab5bae8 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.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 void txpoolSaveFileAbsolutePathOutsideDataPath() throws IOException { } @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 c4a87cf6e7a8b6cbc0e72157153ab8408e64e702 Mon Sep 17 00:00:00 2001 From: Nischal Sharma Date: Tue, 13 Aug 2024 10:22:53 +0530 Subject: [PATCH 062/124] 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 Signed-off-by: gconnect --- 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 616ac3d1dc8..1629002cbd7 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 3763e40bb7c..d168108c975 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.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 PrivGetLogsTransaction privGetLogs( 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 00000000000..b971c4afde7 --- /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 056598a9d56..7c01c02c48e 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 static class GetPrivacyPrecompileAddressResponse 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 Request privGetLogs( "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 00000000000..9cac6d8bf59 --- /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 4174fdf8313..2c883337d34 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 00000000000..01398868624 --- /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 00000000000..b1802b07eb7 --- /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 00000000000..de5c11940b5 --- /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 00000000000..4deebed2617 --- /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 00000000000..c58af8fc3fc --- /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 00000000000..c79feead167 --- /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 00000000000..45e41d068b6 --- /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 00000000000..805e1c5ca37 --- /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 00000000000..3f78ffe592f --- /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 03bafbe859f..de7ae2c6f0e 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 Builder balance(final String balance) { 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 ad39330fa53..a253c6e323f 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 @@ private static List calculateSelfDescructAddress( .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 0f6df40d143..8ae62741b94 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.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 @@ protected Map create( 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 @@ protected Map create( 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 604bad0c9bc..9768ead9dc5 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.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 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 249b2e7077e..b9024db9984 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 c108d27626f..42672ddbf06 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 Bytes getPayload() { 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 af32e76513c..255f80b5871 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 List getPrivateTransactionMetadataList( .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 e49297ab7b3..fe7308993b8 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 4ab171ecae9..fe918bf8f17 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 33dd5e76f16d4e3f0c34f355a14b27055ba1b105 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 13 Aug 2024 15:38:20 +1000 Subject: [PATCH 063/124] 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 Signed-off-by: gconnect --- .../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 89c48fb978b..310b3b1017d 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 void returnsCorrectMethodName() { 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 3566684ab14..7ef368fb762 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.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 @@ protected 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 bb6d44aca60..4eb8fbe12bd 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 void returnsCorrectMethodName() { 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 d070ba47cc3..153a4ef55bc 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 void returnsCorrectMethodName() { 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 be6ecfa82e6..ba3bcd69c63 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 @@ protected Object handleParamTypes(final JsonRpcRequestContext requestContext) { 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 01cfb02a1e8..94430c526f8 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 @@ 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 String getName() { @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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 757ac2756bb..7336faff0e6 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 @@ 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 String getName() { @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 92d42f22784..e2056ac94b5 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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 c4356ce1c2b..60f38fb7ace 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .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 93ae857a695..9269bf965c0 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 @@ private BlockResult blockResult(final JsonRpcRequestContext requestContext) { 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 d2ac0b26af8..a6c5e6d89df 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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { @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 88431dd89bd..ec5d5bf6045 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 String getName() { 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { .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 fbe27b42fb9..c58556114c7 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 void requestBlockRangeInvalidTest() { 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 0ed7e133822..a04cb06c67a 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 void cantGetBlockHigherThanChainHead() { 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 fff08f81fbd..6b968380c67 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 void shouldReturnErrorWhenMissingIndexParam() { 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 void shouldReturnErrorWhenInvalidIndexParam() { 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 06c7408a84a..746f63be75c 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 void shouldReturnErrorWhenMissingIndexParam() { 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 146756fc552..2a59465e88f 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 6a336a96667..e2011bb4d05 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 de1c3ccb57b..f0cf31f79dd 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 67892401ce3..1f46003c8f6 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 a2bc59ecc23..d5adb36a243 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 String getName() { @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 2ad191777ef4c76068b379765810f92c68df4e62 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 13 Aug 2024 16:51:48 +1000 Subject: [PATCH 064/124] 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 Signed-off-by: gconnect --- .../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 b2df8c0676b..891d837df3c 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 @@ 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 c548507710d..8d7a12f2541 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 8fe48474a83..0418fc24746 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 @@ private JsonRpcError errorResponse( } 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 3527c02ad5b..ae35506298f 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.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 String getName() { 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 9be3122c1e4..771c287ac3b 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 String getDescription() { 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 void returnsCorrectExceptionMissingParam() { 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 bf4cb06350a..80c21e6a1b2 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 309e96df249..e304f0cbbd6 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 f11fe90633d02ed10b37da5d975206b5290ffb3d Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 13 Aug 2024 17:49:32 +1000 Subject: [PATCH 065/124] 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 Signed-off-by: gconnect --- .../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 b1d137bb6b7..b06cd572934 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 8d7a12f2541..246a2777c8a 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 fdb94df9d67..67b86575336 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.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 String getName() { 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 83310ead028..a978e5c0c1d 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 void shouldReturnErrorOnOddLengthParam() { 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 void shouldReturnErrorOnNonHexParam() { 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 void shouldReturnErrorOnNoPrefixParam() { 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 void shouldReturnErrorOnNoPrefixNonHexParam() { 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 0aab456d35185931165c8449d9d4b5729224eae1 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 13 Aug 2024 12:21:49 -0600 Subject: [PATCH 066/124] 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 Signed-off-by: gconnect --- .../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 73a15701be7..f055ae1db9e 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1511,7 +1511,7 @@ public static Optional getColorEnabled() { private void configureNativeLibs() { if (unstableNativeLibraryOptions.getNativeAltbn128() - && AbstractAltBnPrecompiledContract.isNative()) { + && AbstractAltBnPrecompiledContract.maybeEnableNative()) { logger.info("Using the native implementation of alt bn128"); } else { AbstractAltBnPrecompiledContract.disableNative(); @@ -1527,7 +1527,7 @@ private void configureNativeLibs() { } 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 27495cd97c5..b10e654626f 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 Optional recoverPublicKeyFromSignature( 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 ad4fe7ddb15..d458a4c43d5 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 Blake2bfMessageDigest clone() throws CloneNotSupportedException { /** * 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 static class Blake2bfDigest implements Digest, 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 Blake2bfDigest clone() throws CloneNotSupportedException { 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 8d7ba7924f3..2ec0470e547 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 void disableNative() { * * @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 384723a239d..812d7762199 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 boolean isNative() { 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 408b1d423a9..db9565d18d0 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 7112d362947..22bd5c76512 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 static String suiteName() { } @Test - public void recoverPublicKeyFromSignature() { + void recoverPublicKeyFromSignature() { final SECPPrivateKey privateKey = secp256R1.createPrivateKey( new BigInteger("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", 16)); @@ -139,20 +139,20 @@ public void recoverPublicKeyFromSignature() { 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 void signatureGenerationVerificationAndPubKeyRecovery() { } @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 af78f975b77..5b7b470a8a7 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.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 @@ Bytes validPointBytes() { 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 @@ void compute_invalidPointsOutsideSubgroupG2() { @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 381e64c0153..742edc85486 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 @@ 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 @@ static Arguments[] parameters() { @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 ac248b947b5..7d2c52efca9 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 @@ static Arguments[] parameters() { @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 ac4fd9041a1..61e0f63cfb5 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 @@ static Arguments[] parameters() { @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 15c85c75a7ec3541299e9d56afe1b5762ef03ce7 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Wed, 14 Aug 2024 09:28:30 +1000 Subject: [PATCH 067/124] Snap sync server StorageRange message limit to apply limit hash as post check (#7399) Signed-off-by: Jason Frame Signed-off-by: gconnect --- .../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 84441ca05fb..50adf7b34fe 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 NavigableMap streamFlatAccounts( } 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 NavigableMap streamFlatStorages( 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 299d441350e..ad631b8da91 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 NavigableMap streamAccountFlatDatabase( 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 NavigableMap streamStorageFlatDatabase( .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 @@ private static Stream> accountsToPairStream( .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 cb92941e5b6..c1b855f2d6f 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 @@ MessageData constructGetAccountRangeResponse(final MessageData message) { .map( storage -> { LOGGER.trace("obtained worldstate in {}", stopWatch); - StatefulPredicate shouldContinuePredicate = - new StatefulPredicate( + ResponseSizePredicate responseSizePredicate = + new ResponseSizePredicate( "account", stopWatch, maxResponseBytes, @@ -248,9 +248,13 @@ MessageData constructGetAccountRangeResponse(final MessageData message) { 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 @@ MessageData constructGetStorageRangeResponse(final MessageData message) { 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 @@ MessageData constructGetStorageRangeResponse(final MessageData message) { 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 @@ MessageData constructGetStorageRangeResponse(final MessageData message) { // 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 @@ MessageData constructGetStorageRangeResponse(final MessageData message) { } } - if (!statefulPredicate.shouldGetMore()) { + if (!predicate.shouldGetMore()) { break; } } @@ -462,7 +469,7 @@ MessageData constructGetBytecodesResponse(final MessageData message) { 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 @@ MessageData constructGetTrieNodesResponse(final MessageData message) { 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 @@ && sumListBytes(trieNodes) + trieNode.size() > maxResponseBytes) { } } - 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 @@ static class StatefulPredicate implements Predicate> { 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 @@ public boolean test(final Pair pair) { 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 e252fe0335d..a41da1ef6b8 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 void assertAccountLimitRangeResponse() { 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 void assertPartialStorageForSingleAccountEmptyRange() { .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 void assertLastEmptyPartialStorageForSingleAccount() { @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 void assertStorageLimitRangeResponse() { 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 void assertStorageTriePathRequest_accountNotPresent() { 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 @@ static SnapTestAccount createTestAccount(final String hexAddr) { 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 @@ static SnapTestAccount createTestContractAccount( 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 f58d870ed3f90157bca3b553274180d02094a5ac Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Tue, 13 Aug 2024 18:00:04 -0600 Subject: [PATCH 068/124] 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 Signed-off-by: gconnect --- .../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 962fc2804b7..6c8b9d5ad3f 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.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 CodeValidateSubCommand() { 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 String considerCode(final String hexCode) { 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 989c6e0b7fe..06ee9676200 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.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 @@ void setBytes(final String optionValue) { 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 @@ void setBytes(final String optionValue) { 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 void run() { } 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 void run() { 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 void run() { .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 void run() { } } } - - 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 820b11442e9..01238e2b286 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 @@ EvmConfiguration provideEvmConfiguration() { } /** 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 1283ec039fc..6eae387a647 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 @@ static GenesisFileModule createGenesisModule(final File genesisFile) throws IOEx 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 4f10650273a..e36668f47c1 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 @@ ProtocolSchedule provideProtocolSchedule( } } - 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 @@ ProtocolSchedule provideProtocolSchedule( 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 @@ public static Map> createSchedules() { 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 7ffca7e466a..78dc43c02e1 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 6ea64e18cf6..9355c472837 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 f23565c64be..127d60fc60f 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 79ca8e5bf35..02f9395981d 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 b0699f1b3cd..1fa459916b6 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 00000000000..061d8f0940c --- /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 ff9bf415e60..c9553c92091 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 875ceb81b12..4798d5da706 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 8a7a5500580..1c2a9c8064a 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 43d7e343ff1..e44c0e7f9c7 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 OperationResult execute(final MessageFrame frame, final EVM evm) { 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 4ea5bc1b7f7..2a71fb70cd1 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 void tracePreExecution(final MessageFrame messageFrame) { 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 void tracePostExecution( 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 b361a8291b12425307c79c94085c2616e9d49056 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Tue, 13 Aug 2024 17:22:40 -0700 Subject: [PATCH 069/124] Bump besu-native dependency (#7456) * bump besu-native ahead of next release Signed-off-by: garyschulte Signed-off-by: gconnect --- 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 1629002cbd7..0d30381a921 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 c7f3039dffb..46029c87c87 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 9ad95a20748..57f2acae37d 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 f6b769c7552244568c6ac4a1d69d4211ee499608 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Wed, 14 Aug 2024 14:34:45 +1000 Subject: [PATCH 070/124] 5098 branch 15 update remaining invalid engine params (#7443) Signed-off-by: Matilda Clerke Signed-off-by: gconnect --- .../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 822c6ac895b..f1a799cf638 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 JsonRpcResponse process( 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 eec79e9a7cd..f958b584447 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 246a2777c8a..5d0d379d810 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.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 AbstractEngineNewPayload( 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 26f8e99edd7..e55cfb1506e 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.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 String getName() { @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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 d46dc900c57..d16c258879c 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 60955bd34acc62aa65cdbac71d638ff9bd010573 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 071/124] 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 Signed-off-by: gconnect --- .../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 f055ae1db9e..1cdc76ff5b7 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -380,7 +380,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 d9882382769..fbed68de0cd 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 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 53ffacfb28e..58f7cb096dd 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -2520,4 +2520,16 @@ public void genesisStateHashCacheEnabledShouldWork() throws IOException { 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 babf188423153e56b2137c226dab6dbd023419aa Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Wed, 14 Aug 2024 16:54:13 +0000 Subject: [PATCH 072/124] 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 Signed-off-by: gconnect --- 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 0d30381a921..8a162840153 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 1963bba8a5c..e3ce69d74ab 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 @@ private void executePrecompile( 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 c3f04c07c58..d17744c8580 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 073/124] isolates MetricsOptionGroup for future reusability, minor renaming (#7464) * isolates MetricsOptionGroup for future reusability, minor renaming --------- Signed-off-by: Justin Florentine Signed-off-by: gconnect --- .../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 1cdc76ff5b7..92ee3d16ea5 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -26,10 +26,6 @@ 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 com.fasterxml.jackson.databind.ObjectMapper; @@ -57,6 +53,7 @@ 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; @@ -319,7 +316,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; @@ -751,81 +748,6 @@ static class PrivacyOptionGroup { @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", @@ -967,7 +889,7 @@ static class MetricsOptionGroup { * @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 */ @@ -977,7 +899,7 @@ public BesuCommand( final Function jsonBlockImporterFactory, final Function rlpBlockExporterFactory, final RunnerBuilder runnerBuilder, - final BesuController.Builder controllerBuilderFactory, + final BesuController.Builder controllerBuilder, final BesuPluginContextImpl besuPluginContext, final Map environment) { this( @@ -986,7 +908,7 @@ public BesuCommand( jsonBlockImporterFactory, rlpBlockExporterFactory, runnerBuilder, - controllerBuilderFactory, + controllerBuilder, besuPluginContext, environment, new StorageServiceImpl(), @@ -1008,7 +930,7 @@ public BesuCommand( * @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 @@ -1028,7 +950,7 @@ protected BesuCommand( 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, @@ -1046,7 +968,7 @@ protected BesuCommand( this.rlpBlockExporterFactory = rlpBlockExporterFactory; this.jsonBlockImporterFactory = jsonBlockImporterFactory; this.runnerBuilder = runnerBuilder; - this.controllerBuilderFactory = controllerBuilderFactory; + this.controllerBuilder = controllerBuilder; this.besuPluginContext = besuPluginContext; this.environment = environment; this.storageService = storageService; @@ -1960,7 +1882,7 @@ public BesuControllerBuilder getControllerBuilder() { .withMiningParameters(miningParametersSupplier.get()) .withJsonRpcHttpOptions(jsonRpcHttpOptions); final KeyValueStorageProvider storageProvider = keyValueStorageProvider(keyValueStorageName); - return controllerBuilderFactory + return controllerBuilder .fromEthNetworkConfig(updateNetworkConfig(network), getDefaultSyncModeIfNotSet()) .synchronizerConfiguration(buildSyncConfig()) .ethProtocolConfiguration(unstableEthProtocolOptions.toDomainObject()) @@ -2036,7 +1958,7 @@ private void checkPrivacyTlsOptionsDependencies() { * @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 " @@ -2047,14 +1969,14 @@ public MetricsConfiguration metricsConfiguration() { 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", @@ -2063,23 +1985,23 @@ public MetricsConfiguration metricsConfiguration() { 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(); } @@ -2711,7 +2633,9 @@ private List getEffectivePorts() { 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 00000000000..add2bf16553 --- /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 fa259d8af29709e2550068724bf861287f4ad5f4 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Thu, 15 Aug 2024 08:23:11 +1000 Subject: [PATCH 074/124] remove vestigial whitelist methods (#7449) * remove vestigial whitelist methods * rename param and method Signed-off-by: Sally MacFarlane --------- Signed-off-by: Sally MacFarlane Signed-off-by: gconnect --- .../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 2c883337d34..63fa5b3ce55 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 d9c2ba0e806..b8ba4397459 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 @@ 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 @@ private static LocalPermissioningConfiguration loadNodePermissioning( 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 @@ private static LocalPermissioningConfiguration loadAccountPermissioning( 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 @@ private static LocalPermissioningConfiguration loadAccountPermissioning( } /** - * 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 c4e965513a4..8f2059f935f 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 9c1cfd9e474..00000000000 --- 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 e3d20f590153efa7fd45898149c8a6bd792630ae Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Thu, 15 Aug 2024 15:39:30 +1000 Subject: [PATCH 075/124] 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 Signed-off-by: gconnect --- .../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 7ad3c9286b9..4f50ad180d7 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 5d0d379d810..05881215169 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 @@ protected ValidationResult validateBlobs( 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 ba7624a493e..fa15891750f 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 @@ protected ValidationResult validateParameters( } 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 c6bfb638c87..b946df40bd5 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 @@ protected ValidationResult validateParameters( 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 09354fa1bac..b87eceed5d3 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 @@ protected ValidationResult validateParameters( 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 9659f5a776e..2aec3b6f955 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 @@ 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 String getName() { @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 876376fab15..862b694f4f8 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 @@ 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 String getName() { @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 4d53d83cf8b..4e68cca76cb 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 void shouldValidateExcessBlobGasCorrectly() { 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 72f0108a692..d8cf86758f8 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 void shouldValidateExcessBlobGasCorrectly() { 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 d4346a0991d407321fb2bab4342e5d93d6a5080a Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Thu, 15 Aug 2024 20:31:06 +1000 Subject: [PATCH 076/124] 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 Signed-off-by: gconnect --- .../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 fa9031efe53..0773651b615 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 @@ 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 String getName() { @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 2e928c3b548..b66b7963e1c 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 @@ 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 String getName() { @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 60f38fb7ace..c9645d53e0a 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 String getName() { @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 e2e4576d433..7578b43a2ed 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 @@ 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 String getName() { @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 ede4f105d01..b51dc1f4fd3 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 @@ 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 String getName() { @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 1b04ee1d52c..a3d6b2561f7 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 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 String getName() { @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 f82d30684af..5b9bc581dbe 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .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 1bfe0e09aea..dd2684e8271 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.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 List filters() throws IllegalArgumentException { 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 @@ private Optional getFilter(final String key, final Map m .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 57b13cc423e..7b9a8d1478f 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 @@ 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 String getName() { @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 c687d66a1ab..0e564772c05 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 @@ 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 String getName() { @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 1683c9511c3..738c0b19cf8 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 @@ 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 String getName() { @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 5e89386cda9..abb6411b00c 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 @@ 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 String getName() { @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 830e7e7e934..f9a080c72f4 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 @@ 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 String getName() { @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 JsonRpcResponse response(final JsonRpcRequestContext request) { } 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 b3e76fead87..d9099e697dc 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 @@ private SubscribeRequest parseNewBlockHeadersRequest( } 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 PrivateSubscribeRequest mapPrivateSubscribeRequest( 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 7bf8e1a9dde..584702d7464 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 void shouldThrowExceptionWhenNoParamsSupplied() { 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 void shouldThrowExceptionWhenInvalidParamsSupplied() { 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 ee9723c6672..c7b4ae85071 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 void shouldReturnErrorWhenMissingParams() { 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 void shouldReturnErrorWhenMissingFilterId() { 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 5af104335d3..93cb216011b 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 void shouldReturnErrorWhenMissingParams() { 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 edaf60d765a..c6ae2dc1017 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 void filterWithInvalidParameters() { 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 ad44c690433..b3c7b45d076 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 void shouldReturnErrorWhenExtraDataNotHex() { 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 void shouldReturnErrorWhenExtraDataTooLong() { 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 5d4d381c1ef..cf89a4bbcad 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 void filterIdIsRequired() { 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 1bd983ffd74..1c5be875722 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 void filterIdIsRequired() { 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 09eb8b00895..d06b47ee103 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 void filterParameterIsRequired() { 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 void filterWithInvalidParameters() { 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 f9e9795f1cd..696e3333cad 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 void filterParameterIsRequired() { 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 void filterWithInvalidParameters() { 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 a0e28aab163..9a60d60d725 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 void filterIdIsRequired() { 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 d71b47421eb..80bb9b05dcc 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 void mapRequestToLogsWithInvalidTopicInFilter() { .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 void mapRequestToLogsWithInvalidSecondParam() { .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 5a3dcb038a3..c2c23fdfec3 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 be517fc357c..52d5bd7966b 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 2795655948916f35de25fbac1fc7513dcaa04926 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 16 Aug 2024 09:51:29 +1000 Subject: [PATCH 077/124] 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 Signed-off-by: gconnect --- .../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 9f76609fd79..966cda12008 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 void missingHashesOrTransactionParameter() { 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 678eae61b74..8944b0d84c1 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 45381303319..3cfd524c148 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 String getName() { @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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 9f0f2f0b1e3..f6f16013318 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 d5f1bba01c9..09b1c2f9523 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 @@ private BlockResult transactionHash(final Hash hash) { } 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 19ad9a51ad2..5e0bc9c7ab4 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 @@ private BlockResult transactionHash(final long blockNumber) { } 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 c2e792b23f0..9db7edcc804 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 @@ 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 String getName() { @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 891d837df3c..7d7bd013bea 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 static JsonCallParameter validateAndGetCallParams(final JsonRpcRequestCon && (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 d16c258879c..cb19d2e7a35 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 05284af6b87..7be6b7499ef 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 void getBlockByHashWithMissingBooleanParameter() throws Exception { 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 void getBlockByHashWithInvalidBooleanParameter() throws Exception { 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 120f380cd7a..cf7e3337fd9 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 void requestHasNullArrayParameter() { 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 void requestHasInvalidStringLogLevelParameter() { 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 void requestHasInvalidLogFilterParameter() { 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 28043b2e092..0fc8969c938 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 void exceptionWhenNoHashSupplied() { 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 void exceptionWhenHashParamInvalid() { 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 e2837593800..bc6ec997f34 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 void exceptionWhenNoNumberSupplied() { 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 void exceptionWhenNumberParamInvalid() { 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 275724aa965..7f928fbddad 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 @@ default void handleHashrateSubmit( 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 b9bcd4a3bb23d2081e185b42634d5ab9cd61d524 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 078/124] 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 Signed-off-by: gconnect --- 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 8a162840153..183ca24e550 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 e5176c55b2f..2a48201dcc9 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 String getRemoteAddress() { 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 c420990d65b..1bc2283acc3 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 @@ static PeerResult fromEthPeer(final EthPeer peer) { .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 876e795468f..63f71c435fd 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 6d7981757cf00eaf56b2c8de16ca0c1e0cb13093 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Fri, 16 Aug 2024 11:37:10 +1000 Subject: [PATCH 079/124] 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 Signed-off-by: gconnect --- .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 9840a3fa497..721c26edbdd 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 cea30955c3bcd127ad58ade00517ac3f17bbb458 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 16 Aug 2024 11:59:57 +1000 Subject: [PATCH 080/124] 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 Signed-off-by: gconnect --- .../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 db7fe131054..06b495624ef 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 @@ 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 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 c891bde56a9..fc787031dac 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 370643f203a..cebb2e7a006 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 @@ 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 String getName() { 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 05881215169..369d7a387a4 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 b946df40bd5..0277d6990e9 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 @@ protected ValidationResult validateParameters( 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 b87eceed5d3..a767c723455 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 @@ protected ValidationResult validateParameters( 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 c72e5c95c73..59c18b80dbb 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 f3dd52f906a..9c217b0c23c 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 a5cb18a2dff..fb56b573075 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 void shouldReturnFalseWhenParameterIsInvalid() { 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 cc69c1e7c49..7e564ac4259 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 void shouldReturnInvalidParamsWhenParameterIsInvalid() { 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 void shouldReturnInvalidParamsWhenParameterIsMissing() { 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 d3408dc4c94..308d15f6f11 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 @@ 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 void handle( 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 def362000b0f19f91011b88a0e18a26078dec23c Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 16 Aug 2024 12:59:03 +1000 Subject: [PATCH 081/124] 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 Signed-off-by: gconnect --- .../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 4f50ad180d7..f1c134ed915 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 @@ protected AdminModifyPeer( 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 2c854239e7b..8221de1f3f1 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 String getName() { 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 e79c0b60b7d..70b232faab2 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 String getName() { 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 34e9276c829..f895008e232 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 8dabd29a3ee..5b14019b070 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 @@ protected Object resultByBlockNumber( 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 f6289e2ce2d..2837e93e136 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 String getName() { 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 ad34d92b490..a69414900f7 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 @@ protected Object resultByBlockNumber( 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 c1d224e1f14..67e90d55b5a 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 b06cd572934..b70ad760519 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 901eda782c3..a6f94ac00e0 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.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 AbstractEngineGetPayload( 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 cd107b2e713..8fa43b79e37 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 String getName() { 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 c796d35d5f4..b51f0fc36fe 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 String getName() { 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 897029afcd2..5c92a43e57f 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 void invalidParamsShouldReturnInvalidParams() throws Exception { 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 void unhandledExceptionShouldReturnInternalErrorResponse() throws Excepti 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 25a0899c8c4..f3dcb1c8f51 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 void requestIsMissingParameter() { 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 void requestHasNullObjectParameter() { 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 void requestHasNullArrayParameter() { 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 void requestRefusesListOfNodes() { 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 3bbe50684b9..2ba7c335239 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 void requestIsMissingParameter() { 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 void requestHasNullObjectParameter() { 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 void requestHasNullArrayParameter() { 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 void requestRefusesListOfNodes() { 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 b376ef1ef84..48350ff9d0b 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 @@ void shouldReturnErrorResponseIfMissingRequiredParameter() { 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 16cbbe3649a..35abfa66ce8 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 void requestIsMissingParameter() { 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 void requestHasNullObjectParameter() { 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 void requestHasNullArrayParameter() { 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 1eef04fb93a..9cc6947b260 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 void shouldReturnsErrorIfInvalidPredicate() { 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 void shouldReturnsErrorIfInvalidNumberOfPredicate() { 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 void shouldReturnsErrorIfInvalidPredicateUsedForFromField() { 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 void shouldReturnsErrorIfInvalidPredicateUsedForToField() { 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 a978e5c0c1d..d690a1a614e 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 void shouldReturnErrorOnExtraParam() { "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 void shouldReturnErrorOnNoParam() { 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 03756bd7bb6..424c31ebf02 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 7791942380f..a0a7fea74bb 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 082d8a52c46476cf57927ef1a3ae34d9230392ce Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Thu, 15 Aug 2024 22:02:26 -0600 Subject: [PATCH 082/124] 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 Signed-off-by: gconnect --- .../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 f24e11bd8b7..e733cc800ec 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.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 00000000000..73eaddb7cad --- /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 f958b584447..df169560f59 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 414d4625b2a..c06b119328f 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 1732585f163..ce9cdcbbb3f 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 555afb50b91..f0b026ef450 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 f67a2743eac..ba42aec2ed1 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 fa15891750f..acb177c3e03 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 0277d6990e9..393687743e9 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 a767c723455..2465cdd8137 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 0059f3d61b1..57b8f549c95 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 d2fb3c37411..5496224e257 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 @@ 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 bfe23e07e77..46fe7d3b6ce 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 d6d3cc0a559..4c67466b9b0 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 @@ 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 6c764a42094..00000000000 --- 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 88448a8b549..f97d8f27eae 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 fb8abbe1b65..beac906be55 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 a1f3d647979..ad261abf472 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 @@ 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 5dfb12f1d61..d6c5afdc4a8 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 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 static ReferenceTestProtocolSchedules create() { } 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 @@ private ReferenceTestProtocolSchedules(final Map sched } 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 5368a7fd749..7d4344c6bcf 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 @@ /** 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 int getMaxInitcodeSize() { * @return name of the fork */ public String getName() { - return name; + return initialHardfork.name(); } /** @@ -174,7 +158,7 @@ public String getName() { * @return description */ public String getDescription() { - return description; + return initialHardfork.description(); } /** Maybe warn version. */ @@ -184,7 +168,7 @@ public void maybeWarnVersion() { 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 static EvmSpecVersion fromName(final String name) { */ public static EvmSpecVersion mostRecent() { return Stream.of(EvmSpecVersion.values()) - .filter(v -> v.specFinalized) + .filter(v -> v.initialHardfork.finalized()) .max(Comparator.naturalOrder()) .orElseThrow(); } From f797b0df11671d2f7924eee4bc8186b0f6337a57 Mon Sep 17 00:00:00 2001 From: Gabriel-Trintinalia Date: Fri, 16 Aug 2024 15:09:31 +1000 Subject: [PATCH 083/124] CLI option for disabling auto-registration of external plugins (#7470) Signed-off-by: Gabriel-Trintinalia Signed-off-by: gconnect --- .../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 7e8d435c721..001406cb781 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 BesuPluginContextImpl providePluginContext( 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 c266eaf66a1..7e277041776 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 @@ void setup() { @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 void registrationErrorsHandledSmoothly() { 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 void startErrorsHandledSmoothly() { 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 void stopErrorsHandledSmoothly() { 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 void stopErrorsHandledSmoothly() { @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 void lifecycleExceptions() throws Throwable { @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 @@ void shouldThrowExceptionIfExplicitlySpecifiedPluginNotFound() { 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 92ee3d16ea5..1d1839145cd 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1130,7 +1130,7 @@ public void run() { runner.startExternalServices(); startPlugins(runner); - validatePluginOptions(); + validatePrivacyPluginOptions(); setReleaseMetrics(); preSynchronization(); @@ -1355,7 +1355,7 @@ private void startPlugins(final Runner runner) { 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 @@ -1499,6 +1499,7 @@ private void validateOptions() { validateGraphQlOptions(); validateApiOptions(); validateConsensusSyncCompatibilityOptions(); + validatePluginOptions(); p2pTLSConfigOptions.checkP2PTLSOptionsDependencies(logger, commandLine); } @@ -1519,6 +1520,10 @@ private void validateConsensusSyncCompatibilityOptions() { } } + 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 84055db663c..ba05f455246 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 88f88c06d4d..47df831c577 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 @@ /** 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 PluginsConfigurationOptions() {} @Override public PluginConfiguration toDomainObject() { - return new PluginConfiguration(plugins); + return new PluginConfiguration.Builder() + .externalPluginsEnabled(externalPluginsEnabled) + .requestedPlugins(plugins) + .build(); + } + + /** + * Validate that there are no inconsistencies in the specified options. + * + * @param commandLine the full commandLine to check all the options specified by the user + */ + public void validate(final CommandLine commandLine) { + String errorMessage = + String.format( + "%s option can only be used when %s is true", + DEFAULT_PLUGINS_OPTION_NAME, DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME); + CommandLineUtils.failIfOptionDoesntMeetRequirement( + commandLine, errorMessage, externalPluginsEnabled, List.of(DEFAULT_PLUGINS_OPTION_NAME)); } @Override @@ -61,6 +88,13 @@ public static PluginConfiguration fromCommandLine(final CommandLine commandLine) CommandLineUtils.getOptionValueOrDefault( commandLine, DEFAULT_PLUGINS_OPTION_NAME, new PluginInfoConverter()); - return new PluginConfiguration(plugins); + boolean externalPluginsEnabled = + CommandLineUtils.getOptionValueOrDefault( + commandLine, DEFAULT_PLUGINS_EXTERNAL_ENABLED_OPTION_NAME, Boolean::parseBoolean); + + return new PluginConfiguration.Builder() + .requestedPlugins(plugins) + .externalPluginsEnabled(externalPluginsEnabled) + .build(); } } 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 ddf69402921..c89733f9354 100644 --- a/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java +++ b/besu/src/main/java/org/hyperledger/besu/services/BesuPluginContextImpl.java @@ -132,20 +132,25 @@ public void registerPlugins(final PluginConfiguration config) { "Besu plugins have already been registered. Cannot register additional plugins."); state = Lifecycle.REGISTERING; - detectedPlugins = detectPlugins(config); - if (!config.getRequestedPlugins().isEmpty()) { - // 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); + 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 @@ private void registerPlugins(final List pluginsToRegister) { 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 00000000000..1adfb585e9d --- /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 27ea5c16453..b489df9fa29 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 dbc742fb2fe..ebc99f647af 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 Path getPluginsDir() { 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 b4a420c477f20959b8f7f4f99f620dddbd6f9077 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Fri, 16 Aug 2024 15:46:56 +1000 Subject: [PATCH 084/124] 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 Signed-off-by: gconnect --- .../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 e2056ac94b5..01a08022790 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 JsonRpcResponse response(final JsonRpcRequestContext request) { "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 a20cd62f290..7c2f67b724f 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 7b84365b561..34ed62b6329 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 @@ protected String resultByBlockHash(final JsonRpcRequestContext request, final Ha 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 9db7edcc804..c0763e77f6d 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 cebb2e7a006..9474fec7bad 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 0431898c78e..624d9bebddc 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 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 7b9a8d1478f..bbd7189ffa3 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 String getName() { @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 0e564772c05..4436c33b502 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 String getName() { @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 738c0b19cf8..c1e122578ab 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 String getName() { @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 0418fc24746..e09d5966cf5 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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { 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 b6ea645dc3e..9ee5d57b3b4 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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { @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 @@ protected Object resultByBlockNumber( } } 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 db0c11ea5af..5c6f929c5c2 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 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 String getName() { 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 0010b8e0525..5d9498f3bd4 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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { @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 8fa43b79e37..7bdba8824a2 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 abb6411b00c..d0c75da33fb 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 String getName() { @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 b51f0fc36fe..2cbcc655359 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 f9a080c72f4..e73b0c141c6 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 String getName() { @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 d9099e697dc..7235a81987a 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 SubscribeRequest mapSubscribeRequest(final JsonRpcRequestContext jsonRpcR 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 SubscribeRequest mapSubscribeRequest(final JsonRpcRequestContext jsonRpcR } 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 UnsubscribeRequest mapUnsubscribeRequest(final JsonRpcRequestContext json 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 PrivateSubscribeRequest mapPrivateSubscribeRequest( 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 PrivateUnsubscribeRequest mapPrivateUnsubscribeRequest( 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 7be6b7499ef..dcfd198d6e1 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 void ethGetStorageAtInvalidParameterStorageIndex() throws Exception { 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 3cf24df3d45..06a4b9d0e7c 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 @@ void errorWhenNoStorageKeysSupplied() { 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 0919ea48e92..cc5169d75d5 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 void shouldThrowCorrectExceptionWhenNoPrivacyGroupSpecified() { 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 a7a4f6f5906..c730be1db85 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 void shouldThrowInvalidJsonRpcParametersExceptionWhenNoPrivacyGroup() { 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 cf89a4bbcad..3b9f5c81314 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 void privacyGroupIdIsRequired() { 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 1c5be875722..c055988271f 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 void privacyGroupIdIsRequired() { 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 d06b47ee103..9426f214786 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 void privacyGroupIdIsRequired() { 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 696e3333cad..855da64b011 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 void privacyGroupIdIsRequired() { 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 9a60d60d725..74935692e8d 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 void privacyGroupIdIsRequired() { 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 void filterIdIsRequired() { 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 80bb9b05dcc..f560dfaa089 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 void mapRequestToUnsubscribeRequestMissingSubscriptionIdFails() { .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 void mapRequestToNewHeadsWithInvalidSecondParamFails() { .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 void mapAbsentSubscriptionTypeRequestFails() { .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 7f928fbddad..3f13a568803 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 @@ default void handleHashrateSubmit( 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 56d3df2cb41bafcddcd501b7b2b003ee77deedf3 Mon Sep 17 00:00:00 2001 From: Karim Taam Date: Fri, 16 Aug 2024 13:58:24 +0100 Subject: [PATCH 085/124] Implement getNearest methods (#7258) Signed-off-by: Karim Taam Signed-off-by: gconnect --- 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 fe7308993b8..4440a4f0691 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 df8a8c48941..4f734c7c977 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 dfc1c8a1ac5..72976a9d84b 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 Optional get(final SegmentIdentifier segment, final byte[] key) } @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 Optional getNearestTo( } } + @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 647dc7019f7..0bf107ddb0e 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 Optional get(final SegmentIdentifier segment, final byte[] key) } @Override - public Optional getNearestTo( + public Optional getNearestBefore( final SegmentIdentifier segmentIdentifier, final Bytes key) throws StorageException { try (final RocksIterator rocksIterator = @@ -366,6 +366,19 @@ public Optional getNearestTo( } } + @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 00000000000..54cd03215fc --- /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 00000000000..ff9dd00dd8a --- /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 36bb5c52d8d..de9abcaf298 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.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 Optional get(final SegmentIdentifier segmentId, final byte[] key) } @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 beabb04d84f..a7cedca362b 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.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 Optional get(final SegmentIdentifier segmentIdentifier, final byt } @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 f96cc90157a..00000000000 --- 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 55a10ffa8d1..00000000000 --- 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 00000000000..b6f536f8b6c --- /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 dba0ae2a366..00000000000 --- 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 ba6c2105cfb616cc879bf81069493461cb8b8c9f Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Fri, 16 Aug 2024 22:06:53 +0200 Subject: [PATCH 086/124] Correctly release txpool save and restore lock in case of exceptions (#7473) Signed-off-by: Fabio Di Fabio Signed-off-by: gconnect --- 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 183ca24e550..84641ea16e1 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 c069a771eb2..6bb2029960a 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 @@ private CompletableFuture serializeAndDedupOperation( 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 2c54bdc2e60be77c54093b43315db3043ff27762 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Fri, 16 Aug 2024 17:03:07 -0700 Subject: [PATCH 087/124] Bump changelog ahead of 24.8.0 (#7476) * bump changelog Signed-off-by: garyschulte Signed-off-by: gconnect --- CHANGELOG.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84641ea16e1..9173e46fd5e 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 7e23edab5e9d5385ef018da10ddaa63ca0a746e3 Mon Sep 17 00:00:00 2001 From: gconnect Date: Mon, 19 Aug 2024 05:09:10 +0100 Subject: [PATCH 088/124] Add testGenerateEphemeryGenesisFile Signed-off-by: gconnect --- .../hyperledger/besu/cli/BesuCommandTest.java | 49 +- .../besu/cli/CommandTestAbstract.java | 6 +- temp-ephemery.json | 917 ++++++++++++++++++ 3 files changed, 968 insertions(+), 4 deletions(-) create mode 100644 temp-ephemery.json 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 58f7cb096dd..3c47e076e4f 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -16,6 +16,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.contentOf; import static org.hamcrest.Matchers.is; import static org.hyperledger.besu.cli.config.NetworkName.CLASSIC; import static org.hyperledger.besu.cli.config.NetworkName.DEV; @@ -38,10 +39,9 @@ import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNotNull; -import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.config.GenesisConfigFile; @@ -72,6 +72,7 @@ import org.hyperledger.besu.util.number.PositiveNumber; import org.hyperledger.besu.util.platform.PlatformDetector; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.math.BigInteger; @@ -79,7 +80,10 @@ import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -1825,6 +1829,45 @@ public void ephemeryValuesAreUsed() { assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } + @Test + public void testGenerateEphemeryGenesisFileSuccess() throws IOException { + parseCommand("--network", "ephemery"); + // Set up the mock genesis file path + Path tempJsonFile = Files.createTempFile("temp-ephemery", ".json"); + + // Set up the initial genesis string + String initialGenesisInput = "{\n" + + " \"config\": {\n" + + " \"chainId\": 39438135\n" + + " },\n" + + " \"timestamp\": \"1720119600\"\n" + + "}"; + Files.write(tempJsonFile, initialGenesisInput.getBytes(UTF_8)); + + // Mock the return value of the genesis file path + when(EPHEMERY.getGenesisFile()).thenReturn(tempJsonFile.toString()); + long mockTimestamp = Instant.now().getEpochSecond() - 60 * 60 * 24 * 30 * 3; // 3 periods ago + when(mockGenesisConfigFile.getTimestamp()).thenReturn(mockTimestamp); + + BigInteger mockChainId = BigInteger.valueOf(39438135); + when(mockGenesisConfigOptions.getChainId()).thenReturn(Optional.of(mockChainId)); + + // Calculate the expected new values + long periodInSeconds = 28 * 24 * 60 * 60; // 28 days in seconds + long periodsSinceGenesis = ChronoUnit.DAYS.between(Instant.ofEpochSecond(mockTimestamp), Instant.now()) / 28; + long expectedTimestamp = mockTimestamp + periodsSinceGenesis * periodInSeconds; + BigInteger expectedChainId = mockChainId.add(BigInteger.valueOf(periodsSinceGenesis)); + + ObjectNode mockRootNode = mock(ObjectNode.class); + ObjectNode mockConfigNode = mock(ObjectNode.class); + when(mockObjectMapper.readTree(any(File.class))).thenReturn(mockRootNode); + when(mockRootNode.path("config")).thenReturn(mockConfigNode); + + verify(mockConfigNode).put(eq("chainId"), expectedChainId); + verify(mockRootNode).put(eq("timestamp"), expectedTimestamp); + verify(mockObjectMapper).writerWithDefaultPrettyPrinter(); + } + @Test public void classicValuesAreUsed() { parseCommand("--network", "classic"); 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 f6fa2e47984..437b5874860 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.fasterxml.jackson.databind.ObjectMapper; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; import org.hyperledger.besu.chainexport.RlpBlockExporter; @@ -44,6 +45,7 @@ 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.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; @@ -224,7 +226,9 @@ public abstract class CommandTestAbstract { @Mock protected TransactionPool mockTransactionPool; @Mock protected PrivacyPluginServiceImpl privacyPluginService; @Mock protected StorageProvider storageProvider; - + @Mock protected GenesisConfigOptions mockGenesisConfigOptions; + @Mock protected GenesisConfigFile mockGenesisConfigFile; + @Mock protected ObjectMapper mockObjectMapper; @SuppressWarnings("PrivateStaticFinalLoggers") // @Mocks are inited by JUnit @Mock protected Logger mockLogger; diff --git a/temp-ephemery.json b/temp-ephemery.json new file mode 100644 index 00000000000..3024b4c7a3f --- /dev/null +++ b/temp-ephemery.json @@ -0,0 +1,917 @@ +{ + "config" : { + "chainId" : "39438135", + "homesteadBlock" : 0, + "eip150Block" : 0, + "eip155Block" : 0, + "eip158Block" : 0, + "byzantiumBlock" : 0, + "constantinopleBlock" : 0, + "petersburgBlock" : 0, + "istanbulBlock" : 0, + "berlinBlock" : 0, + "londonBlock" : 0, + "preMergeForkBlock" : 0, + "terminalTotalDifficulty" : 0, + "shanghaiTime" : 0, + "cancunTime" : 0, + "depositContractAddress" : "0x4242424242424242424242424242424242424242", + "ethash" : { }, + "discovery" : { + "bootnodes" : [ + "enode://50a54ecbd2175497640bcf46a25bbe9bb4fae51d7cc2a29ef4947a7ee17496cf39a699b7fe6b703ed0feb9dbaae7e44fc3827fcb7435ca9ac6de4daa4d983b3d@137.74.203.240:30303", + "enode://0f2c301a9a3f9fa2ccfa362b79552c052905d8c2982f707f46cd29ece5a9e1c14ecd06f4ac951b228f059a43c6284a1a14fce709e8976cac93b50345218bf2e9@135.181.140.168:30343" + ] + } + }, + "alloc" : { + "0x0000000000000000000000000000000000000000" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000001" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000002" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000003" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000004" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000005" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000006" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000007" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000008" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000009" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000000a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000000b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000000c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000000d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000000e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000000f" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000010" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000011" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000012" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000013" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000014" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000015" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000016" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000017" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000018" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000019" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000001a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000001b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000001c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000001d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000001e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000001f" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000020" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000021" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000022" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000023" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000024" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000025" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000026" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000027" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000028" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000029" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000002a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000002b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000002c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000002d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000002e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000002f" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000030" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000031" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000032" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000033" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000034" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000035" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000036" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000037" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000038" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000039" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000003a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000003b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000003c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000003d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000003e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000003f" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000040" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000041" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000042" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000043" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000044" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000045" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000046" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000047" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000048" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000049" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000004a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000004b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000004c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000004d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000004e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000004f" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000050" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000051" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000052" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000053" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000054" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000055" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000056" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000057" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000058" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000059" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000005a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000005b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000005c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000005d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000005e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000005f" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000060" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000061" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000062" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000063" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000064" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000065" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000066" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000067" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000068" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000069" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000006a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000006b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000006c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000006d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000006e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000006f" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000070" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000071" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000072" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000073" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000074" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000075" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000076" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000077" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000078" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000079" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000007a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000007b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000007c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000007d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000007e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000007f" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000080" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000081" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000082" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000083" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000084" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000085" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000086" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000087" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000088" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000089" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000008a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000008b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000008c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000008d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000008e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000008f" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000090" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000091" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000092" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000093" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000094" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000095" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000096" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000097" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000098" : { + "balance" : "1" + }, + "0x0000000000000000000000000000000000000099" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000009a" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000009b" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000009c" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000009d" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000009e" : { + "balance" : "1" + }, + "0x000000000000000000000000000000000000009f" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a0" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a1" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a2" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a3" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a4" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a5" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a6" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a7" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a8" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000a9" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000aa" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ab" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ac" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ad" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ae" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000af" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b0" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b1" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b2" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b3" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b4" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b5" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b6" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b7" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b8" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000b9" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ba" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000bb" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000bc" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000bd" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000be" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000bf" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c0" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c1" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c2" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c3" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c4" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c5" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c6" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c7" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c8" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000c9" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ca" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000cb" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000cc" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000cd" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ce" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000cf" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d0" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d1" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d2" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d3" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d4" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d5" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d6" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d7" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d8" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000d9" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000da" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000db" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000dc" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000dd" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000de" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000df" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e0" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e1" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e2" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e3" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e4" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e5" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e6" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e7" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e8" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000e9" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ea" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000eb" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ec" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ed" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ee" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ef" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f0" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f1" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f2" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f3" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f4" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f5" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f6" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f7" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f8" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000f9" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000fa" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000fb" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000fc" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000fd" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000fe" : { + "balance" : "1" + }, + "0x00000000000000000000000000000000000000ff" : { + "balance" : "1" + }, + "0x4242424242424242424242424242424242424242" : { + "balance" : "0", + "code" : "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", + "storage" : { + "0x0000000000000000000000000000000000000000000000000000000000000022" : "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", + "0x0000000000000000000000000000000000000000000000000000000000000023" : "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0x0000000000000000000000000000000000000000000000000000000000000024" : "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", + "0x0000000000000000000000000000000000000000000000000000000000000025" : "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", + "0x0000000000000000000000000000000000000000000000000000000000000026" : "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", + "0x0000000000000000000000000000000000000000000000000000000000000027" : "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", + "0x0000000000000000000000000000000000000000000000000000000000000028" : "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", + "0x0000000000000000000000000000000000000000000000000000000000000029" : "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", + "0x000000000000000000000000000000000000000000000000000000000000002a" : "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", + "0x000000000000000000000000000000000000000000000000000000000000002b" : "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x000000000000000000000000000000000000000000000000000000000000002c" : "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0x000000000000000000000000000000000000000000000000000000000000002d" : "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", + "0x000000000000000000000000000000000000000000000000000000000000002e" : "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", + "0x000000000000000000000000000000000000000000000000000000000000002f" : "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", + "0x0000000000000000000000000000000000000000000000000000000000000030" : "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", + "0x0000000000000000000000000000000000000000000000000000000000000031" : "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", + "0x0000000000000000000000000000000000000000000000000000000000000032" : "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", + "0x0000000000000000000000000000000000000000000000000000000000000033" : "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", + "0x0000000000000000000000000000000000000000000000000000000000000034" : "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", + "0x0000000000000000000000000000000000000000000000000000000000000035" : "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", + "0x0000000000000000000000000000000000000000000000000000000000000036" : "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", + "0x0000000000000000000000000000000000000000000000000000000000000037" : "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", + "0x0000000000000000000000000000000000000000000000000000000000000038" : "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", + "0x0000000000000000000000000000000000000000000000000000000000000039" : "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", + "0x000000000000000000000000000000000000000000000000000000000000003a" : "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", + "0x000000000000000000000000000000000000000000000000000000000000003b" : "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", + "0x000000000000000000000000000000000000000000000000000000000000003c" : "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", + "0x000000000000000000000000000000000000000000000000000000000000003d" : "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", + "0x000000000000000000000000000000000000000000000000000000000000003e" : "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", + "0x000000000000000000000000000000000000000000000000000000000000003f" : "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", + "0x0000000000000000000000000000000000000000000000000000000000000040" : "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" + } + }, + "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" : { + "balance" : "0", + "nonce" : "1", + "code" : "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500" + }, + "0xa2A6d93439144FFE4D27c9E088dCD8b783946263" : { + "balance" : "1000000000000000000000000" + }, + "0xBc11295936Aa79d594139de1B2e12629414F3BDB" : { + "balance" : "1000000000000000000000000" + }, + "0x7cF5b79bfe291A67AB02b393E456cCc4c266F753" : { + "balance" : "1000000000000000000000000" + }, + "0xaaec86394441f915bce3e6ab399977e9906f3b69" : { + "balance" : "1000000000000000000000000" + }, + "0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8" : { + "balance" : "1000000000000000000000000" + }, + "0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8" : { + "balance" : "1000000000000000000000000" + }, + "0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e" : { + "balance" : "1000000000000000000000000" + }, + "0xe2e2659028143784d557bcec6ff3a0721048880a" : { + "balance" : "1000000000000000000000000" + }, + "0xd9a5179f091d85051d3c982785efd1455cec8699" : { + "balance" : "1000000000000000000000000" + }, + "0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf" : { + "balance" : "1000000000000000000000000" + }, + "0x0000006916a87b82333f4245046623b23794c65c" : { + "balance" : "10000000000000000000000000" + }, + "0xb21c33de1fab3fa15499c62b59fe0cc3250020d1" : { + "balance" : "100000000000000000000000000" + }, + "0x10F5d45854e038071485AC9e402308cF80D2d2fE" : { + "balance" : "100000000000000000000000000" + }, + "0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E" : { + "balance" : "100000000000000000000000000" + }, + "0x799D329e5f583419167cD722962485926E338F4a" : { + "balance" : "1000000000000000000" + }, + "0x4c2ae482593505f0163cdefc073e81c63cda4107" : { + "balance" : "1000000000000000000000000" + }, + "0xa8e8f14732658e4b51e8711931053a8a69baf2b1" : { + "balance" : "1000000000000000000000000" + }, + "0xe0a2bd4258d2768837baa26a28fe71dc079f84c7" : { + "balance" : "100000000000000000000000000" + }, + "0x1eA692E68a7765dE26FC03A6D74EE5B56A7e2b4d" : { + "balance" : "100000000000000000000000000" + }, + "0x57c3dfd40A86628B67721115d7A03C9F341d7718" : { + "balance" : "100000000000000000000000000" + }, + "0xc90E920F4DCfd4954230edCaB168D0C5B9561e03" : { + "balance" : "1000000000000000000000000000" + }, + "0x6Cc9397c3B38739daCbfaA68EaD5F5D77Ba5F455" : { + "balance" : "10000000000000000000000000" + }, + "0x992775d32fd0ec76b95C5E76CeEA92ED5a4bE1F9" : { + "balance" : "10000000000000000000000000" + } + }, + "coinbase" : "0x0000000000000000000000000000000000000000", + "baseFeePerGas" : "0x3B9ACA00", + "difficulty" : "0x01", + "extraData" : "", + "gasLimit" : "0x1c9c380", + "nonce" : "0x1234", + "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp" : "1720119600" +} \ No newline at end of file From fce7eefc621acadfac2400f28c71e989e4fd3887 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 19 Aug 2024 11:35:58 +1000 Subject: [PATCH 089/124] 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 Signed-off-by: gconnect --- .../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 a29187b5138..9364422c578 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 d0df723d54f..dfa6f7b6e59 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 void exceptionWhenNoParamsSupplied() { 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 void exceptionWhenNoAddressSupplied() { 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 9eefbb8d13a..aa3a8b267e5 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 62f7dc61691..1f5b1466d97 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 void exceptionWhenNoParamsSupplied() { 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 void exceptionWhenNoAddressSupplied() { 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 550a25982d2..602f3de3e0c 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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( @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 @@ protected Object resultByBlockHash( 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 ab1230ca961..d6ede25b27e 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 @@ 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 String getName() { @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 7587e40c75a..2d0c4cac4e2 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 601eabeab14..5fba2911bdd 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 f6f16013318..5aabff4b574 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 44cbf153dee..2d668c7f229 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 b1216885f1a..da795439cf3 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 dce3ab1ebf1..eb90edabb95 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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { 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 9de8108e679..ad46d981ac8 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 String getName() { @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 8ce0052b8b8..8ec14dc4ad5 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 @@ 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 String getName() { @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 44fb91689d0..9c7cf5e7a85 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 @@ 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 String getName() { @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 6a419d35c54..a5383f6680d 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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { @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 8221de1f3f1..90e7a6a1edc 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 78c5f3b6504..a437cd86dc2 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 @@ 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 String getName() { @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 70b232faab2..272014d3bc4 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 c50525cef82..9882257143c 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 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 @@ protected TraceOptions getTraceOptions(final JsonRpcRequestContext requestContex 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 5b14019b070..2cbeb8ee7f8 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 @@ protected Object resultByBlockNumber( } 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 2837e93e136..a1460c5aa24 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 a69414900f7..a7205698752 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 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 50e580cd86d..a8b3bbc46de 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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { @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 55d1c0569d9..b79b9620e8d 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 @@ 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 String getName() { @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 67e90d55b5a..8dc38135c60 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 df169560f59..7df76973ac9 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 369d7a387a4..02ccf5d2311 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.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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 @@ protected ValidationResult validateBlobs( 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 393687743e9..7d13ecc02c4 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 @@ protected ValidationResult validateParameters( 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 2465cdd8137..904ec08e5c2 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 @@ protected ValidationResult validateParameters( 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 1c530c14cf6..f1b949ad639 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 80ba8bf6736..1b8e3a19d2d 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 @@ 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 @@ private void validateTraceTypes(final List traceTypesInput) .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 7ca3e943993..12c496b639d 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.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 String getName() { 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 62a087dade7..39003358ede 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 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 String getName() { @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 7bdba8824a2..31bfc52c804 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 d260647c843..0629b2d55d4 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.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 String getName() { 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 f9bc4241048..a1844841f00 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.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 String getName() { @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 7ea2de0c016..bf9d49d4e9c 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 static Transaction decodeRawTransaction(final String rawTransaction) 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 d7840241d5a..7876693b4cc 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 @@ void testInvalidParamsResponseEmptyList() { 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 @@ void testInvalidParamsResponseNegative() { 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 @@ void testInvalidParamsResponseTooHigh() { 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 5496224e257..cdca20cb00e 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 @@ protected EngineUpdateForkchoiceResult assertSuccessWithPayloadForForkchoiceResu } 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 d38d3994415..6993be3d7ae 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 @@ protected String getMethodName() { @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 7ae80313a1d..c3558ef3292 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 @@ protected String getMethodName() { @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 f31ac5e986f..df9d9247c35 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 void failsWithInvalidValue() { 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 4d209b847ba..b44100ba6c3 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 void requestIsMissingParameter() { 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 void requestHasNullObjectParameter() { 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 void requestHasNullArrayParameter() { 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 7f804359ab5..aac1138b583 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 97240170b07..b6c8becdb2e 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 6d12441ac7e..5984be529b7 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 64f1cdef765..f3c8fca4e56 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 977ea64f158..f4e3dea7753 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 2263de69d16..0abcb4da7e9 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 47f13b7287c..eb1bfbd30b1 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 a0790c9fcdb..e4fd7bcff27 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 @@ 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 String getName() { @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 eeae7faa18b..d9cfafbaeab 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 String getName() { @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 2867ae9b913366ed59d48675309c03256264f5c4 Mon Sep 17 00:00:00 2001 From: gconnect Date: Mon, 19 Aug 2024 05:45:21 +0100 Subject: [PATCH 090/124] Update comments on testGenerateEphemeryGenesisFile Signed-off-by: gconnect --- .../test/java/org/hyperledger/besu/cli/BesuCommandTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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 3c47e076e4f..b1b603b12b2 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -1832,10 +1832,9 @@ public void ephemeryValuesAreUsed() { @Test public void testGenerateEphemeryGenesisFileSuccess() throws IOException { parseCommand("--network", "ephemery"); - // Set up the mock genesis file path + Path tempJsonFile = Files.createTempFile("temp-ephemery", ".json"); - // Set up the initial genesis string String initialGenesisInput = "{\n" + " \"config\": {\n" + " \"chainId\": 39438135\n" + @@ -1844,7 +1843,6 @@ public void testGenerateEphemeryGenesisFileSuccess() throws IOException { "}"; Files.write(tempJsonFile, initialGenesisInput.getBytes(UTF_8)); - // Mock the return value of the genesis file path when(EPHEMERY.getGenesisFile()).thenReturn(tempJsonFile.toString()); long mockTimestamp = Instant.now().getEpochSecond() - 60 * 60 * 24 * 30 * 3; // 3 periods ago when(mockGenesisConfigFile.getTimestamp()).thenReturn(mockTimestamp); @@ -1852,7 +1850,7 @@ public void testGenerateEphemeryGenesisFileSuccess() throws IOException { BigInteger mockChainId = BigInteger.valueOf(39438135); when(mockGenesisConfigOptions.getChainId()).thenReturn(Optional.of(mockChainId)); - // Calculate the expected new values + // This calculates the expected new values long periodInSeconds = 28 * 24 * 60 * 60; // 28 days in seconds long periodsSinceGenesis = ChronoUnit.DAYS.between(Instant.ofEpochSecond(mockTimestamp), Instant.now()) / 28; long expectedTimestamp = mockTimestamp + periodsSinceGenesis * periodInSeconds; From 53c6298bf0505f8da44284869faffcb74a1ffc37 Mon Sep 17 00:00:00 2001 From: gconnect Date: Fri, 23 Aug 2024 05:47:22 +0100 Subject: [PATCH 091/124] Create standalone EphemeryGenerateGenesisFile and Test file Signed-off-by: gconnect --- .../org/hyperledger/besu/cli/BesuCommand.java | 55 +- .../besu/cli/config/NetworkName.java | 4 +- .../util/GenerateEphemeryGenesisFile.java | 99 ++ .../hyperledger/besu/cli/BesuCommandTest.java | 89 +- .../besu/cli/CommandTestAbstract.java | 6 +- .../util/GenerateEphemeryGenesisFileTest.java | 215 ++++ config/src/main/resources/ephemery.json | 5 +- gradle.properties | 2 +- temp-ephemery.json | 917 ------------------ 9 files changed, 359 insertions(+), 1033 deletions(-) create mode 100644 besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java create mode 100644 besu/src/test/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFileTest.java delete mode 100644 temp-ephemery.json 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 1d1839145cd..77f0dcf1a3f 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -28,8 +28,6 @@ import static org.hyperledger.besu.ethereum.api.jsonrpc.authentication.EngineAuthService.EPHEMERAL_JWT_FILE; import static org.hyperledger.besu.nat.kubernetes.KubernetesNatManager.DEFAULT_BESU_SERVICE_NAME_FILTER; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; @@ -199,6 +197,7 @@ import org.hyperledger.besu.services.TransactionSelectionServiceImpl; import org.hyperledger.besu.services.TransactionSimulationServiceImpl; import org.hyperledger.besu.services.kvstore.InMemoryStoragePlugin; +import org.hyperledger.besu.util.GenerateEphemeryGenesisFile; import org.hyperledger.besu.util.InvalidConfigurationException; import org.hyperledger.besu.util.LogConfigurator; import org.hyperledger.besu.util.NetworkUtility; @@ -218,8 +217,6 @@ import java.net.UnknownHostException; import java.nio.file.Path; import java.time.Clock; -import java.time.Instant; -import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1096,7 +1093,14 @@ public void run() { logger.warn(NetworkDeprecationMessage.generate(network)); } if (network == EPHEMERY) { - generateEphemeryGenesisFile(); + GenerateEphemeryGenesisFile generateEphemeryGenesisFile = + new GenerateEphemeryGenesisFile( + network, readGenesisConfigFile(), readGenesisConfigOptions()); + try { + generateEphemeryGenesisFile.generate(); + } catch (IOException e) { + throw new RuntimeException(e); + } } try { configureLogging(true); @@ -1674,47 +1678,6 @@ private GenesisConfigOptions readGenesisConfigOptions() { } } - /** - * generateEphemeryGenesisFile checks if a genesis update is available - * and updates the ephemery.json file - */ - private void generateEphemeryGenesisFile() { - if(EPHEMERY.getGenesisFile() != null){ - - GenesisConfigFile configFile = GenesisConfigFile.fromResource( - Optional.ofNullable(network).orElse(EPHEMERY).getGenesisFile()); - GenesisConfigOptions configOptions = readGenesisConfigOptions(); - final int PERIOD = 28; - long timestamp = configFile.getTimestamp(); - Optional chainId = configOptions.getChainId(); - - long periodInSeconds = (PERIOD * 24 * 60 * 60); - long currentTimestamp = Instant.now().getEpochSecond(); - long periodsSinceGenesis = ChronoUnit.DAYS.between(Instant.ofEpochSecond(timestamp), Instant.now()) / PERIOD; - long newGenesisTimestamp = timestamp + (periodsSinceGenesis * periodInSeconds); - BigInteger newChainId = chainId.orElseThrow(() -> new IllegalStateException("ChainId not present")) - .add(BigInteger.valueOf(periodsSinceGenesis)); - - EPHEMERY.setNetworkId(newChainId); - - if (currentTimestamp > (timestamp + periodInSeconds)) { - Path ephemeryGenesisfilePath = Path.of(EPHEMERY.getGenesisFile()); - try { - ObjectMapper objectMapper = new ObjectMapper(); - ObjectNode rootNode = (ObjectNode) objectMapper.readTree(ephemeryGenesisfilePath.toFile()); - - ObjectNode configNode = (ObjectNode) rootNode.path("config"); - configNode.put("chainId", newChainId.toString()); - rootNode.put("timestamp", String.valueOf(newGenesisTimestamp)); - - objectMapper.writerWithDefaultPrettyPrinter().writeValue(ephemeryGenesisfilePath.toFile(), rootNode); - } catch (IOException e) { - throw new ParameterException(this.commandLine, "Unable to update ephemery genesis file. " + e.getMessage(), e); - } - } - } - } - private void issueOptionWarnings() { // Check that P2P options are able to work diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java index d76559d4c9b..dc464054707 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java @@ -81,13 +81,13 @@ public BigInteger getNetworkId() { } /** - * Sets network id. + * Sets network id. This method is called only by the Ephemery network. It is required to update + * the networkid. */ public void setNetworkId(final BigInteger networkId) { this.networkId = networkId; } - /** * Can SNAP sync boolean. * diff --git a/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java b/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java new file mode 100644 index 00000000000..59e5a8e971d --- /dev/null +++ b/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java @@ -0,0 +1,99 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.util; + +import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; + +import org.hyperledger.besu.cli.config.NetworkName; +import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfigOptions; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.Path; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Optional; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * The Generate Ephemery Genesis File. Checks for update based on the set period and update the + * Ephemery genesis file + */ +public class GenerateEphemeryGenesisFile { + private final NetworkName network; + private final GenesisConfigFile genesisConfigFile; + private final GenesisConfigOptions genesisConfigOptions; + + /** + * Instantiates a new Generate Ephemery genesis file. + * + * @param network the Network + * @param genesisConfigFile the Genesis Config File + * @param genesisConfigOptions the Genesis Config Options + */ + public GenerateEphemeryGenesisFile( + final NetworkName network, + final GenesisConfigFile genesisConfigFile, + final GenesisConfigOptions genesisConfigOptions) { + this.genesisConfigFile = genesisConfigFile; + this.network = network; + this.genesisConfigOptions = genesisConfigOptions; + } + + public void generate() throws IOException { + if (Optional.ofNullable(network).orElse(EPHEMERY).getGenesisFile() != null + || genesisConfigFile.getConfigOptions() != null + || genesisConfigFile.getTimestamp() != 0) { + + final int PERIOD = 28; + long genesisTimestamp = genesisConfigFile.getTimestamp(); + Optional genesisChainId = genesisConfigOptions.getChainId(); + + long periodInSeconds = (PERIOD * 24 * 60 * 60); + long currentTimestamp = Instant.now().getEpochSecond(); + long periodsSinceGenesis = + ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) / PERIOD; + long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * periodInSeconds); + BigInteger updatedChainId = + genesisChainId + .orElseThrow(() -> new IllegalStateException("ChainId not present")) + .add(BigInteger.valueOf(periodsSinceGenesis)); + + EPHEMERY.setNetworkId(updatedChainId); + + if (currentTimestamp > (genesisTimestamp + periodInSeconds)) { + Path ephemeryGenesisfilePath = Path.of(EPHEMERY.getGenesisFile()); + try { + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode rootNode = + (ObjectNode) objectMapper.readTree(ephemeryGenesisfilePath.toFile()); + + ObjectNode configNode = (ObjectNode) rootNode.path("config"); + configNode.put("chainId", updatedChainId.toString()); + rootNode.put("timestamp", String.valueOf(updatedTimestamp)); + + objectMapper + .writerWithDefaultPrettyPrinter() + .writeValue(ephemeryGenesisfilePath.toFile(), rootNode); + } catch (IOException e) { + throw new IOException("Unable to update ephemery genesis file. " + e); + } + } + } + } +} 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 b1b603b12b2..33e74be18b0 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -16,7 +16,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.contentOf; import static org.hamcrest.Matchers.is; import static org.hyperledger.besu.cli.config.NetworkName.CLASSIC; import static org.hyperledger.besu.cli.config.NetworkName.DEV; @@ -39,9 +38,10 @@ import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNotNull; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.atLeast; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; -import com.fasterxml.jackson.databind.node.ObjectNode; import org.hyperledger.besu.BesuInfo; import org.hyperledger.besu.cli.config.EthNetworkConfig; import org.hyperledger.besu.config.GenesisConfigFile; @@ -72,7 +72,6 @@ import org.hyperledger.besu.util.number.PositiveNumber; import org.hyperledger.besu.util.platform.PlatformDetector; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.math.BigInteger; @@ -80,10 +79,7 @@ import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.nio.file.Path; -import java.time.Instant; -import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -290,8 +286,9 @@ public void callingWithConfigOptionButInvalidContentTomlFileShouldDisplayHelp() parseCommand("--config-file", tempConfigFile.toString()); final String expectedOutputStart = - "Invalid TOML configuration: org.apache.tuweni.toml.TomlParseError: Unexpected '.', expected a-z, A-Z, 0-9, ', \", a table key, " - + "a newline, or end-of-input (line 1, column 1)"; + "Invalid TOML configuration: org.apache.tuweni.toml.TomlParseError: Unexpected '.'," + + " expected a-z, A-Z, 0-9, ', \", a table key, a newline, or end-of-input (line 1," + + " column 1)"; assertThat(commandErrorOutput.toString(UTF_8)).startsWith(expectedOutputStart); assertThat(commandOutput.toString(UTF_8)).isEmpty(); } @@ -318,8 +315,9 @@ public void callingWithConfigOptionButInvalidValueTomlFileShouldDisplayHelp() th parseCommand("--config-file", tempConfigFile.toString()); final String expectedOutputStart = - "Invalid TOML configuration: org.apache.tuweni.toml.TomlParseError: Unexpected '=', expected ', \", ''', \"\"\", a number, " - + "a boolean, a date/time, an array, or a table (line 1, column 8)"; + "Invalid TOML configuration: org.apache.tuweni.toml.TomlParseError: Unexpected '='," + + " expected ', \", ''', \"\"\", a number, a boolean, a date/time, an array, or a table" + + " (line 1, column 8)"; assertThat(commandErrorOutput.toString(UTF_8)).startsWith(expectedOutputStart); assertThat(commandOutput.toString(UTF_8)).isEmpty(); } @@ -1135,7 +1133,8 @@ public void syncMode_invalid() { 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] (case-insensitive) but was 'bogus'"); + "Invalid value for option '--sync-mode': expected one of [FULL, FAST, SNAP, CHECKPOINT]" + + " (case-insensitive) but was 'bogus'"); } @Test @@ -1291,7 +1290,9 @@ public void ethStatsContactOptionCannotBeUsedWithoutEthStatsServerProvided() { assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)) .contains( - "The `--ethstats-contact` requires ethstats server URL to be provided. Either remove --ethstats-contact or provide a URL (via --ethstats=nodename:secret@host:port)"); + "The `--ethstats-contact` requires ethstats server URL to be provided. Either remove" + + " --ethstats-contact or provide a URL (via" + + " --ethstats=nodename:secret@host:port)"); } @Test @@ -1321,7 +1322,8 @@ public void bonsaiLimitTrieLogsDisabledWhenFullSyncEnabled() { assertThat(dataStorageConfiguration.getBonsaiLimitTrieLogsEnabled()).isFalse(); verify(mockLogger) .warn( - "Forcing {}, since it cannot be enabled with --sync-mode={} and --data-storage-format={}.", + "Forcing {}, since it cannot be enabled with --sync-mode={} and" + + " --data-storage-format={}.", "--bonsai-limit-trie-logs-enabled=false", SyncMode.FULL, DataStorageFormat.BONSAI); @@ -1336,7 +1338,9 @@ public void parsesInvalidWhenFullSyncAndBonsaiLimitTrieLogsExplicitlyTrue() { assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)) .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"); + "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 @@ -1401,7 +1405,8 @@ public void dnsUpdateEnabledOptionCannotBeUsedWithoutDnsEnabled() { assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)) .contains( - "The `--Xdns-update-enabled` requires dns to be enabled. Either remove --Xdns-update-enabled or specify dns is enabled (--Xdns-enabled)"); + "The `--Xdns-update-enabled` requires dns to be enabled. Either remove" + + " --Xdns-update-enabled or specify dns is enabled (--Xdns-enabled)"); } @Test @@ -1829,43 +1834,6 @@ public void ephemeryValuesAreUsed() { assertThat(commandErrorOutput.toString(UTF_8)).isEmpty(); } - @Test - public void testGenerateEphemeryGenesisFileSuccess() throws IOException { - parseCommand("--network", "ephemery"); - - Path tempJsonFile = Files.createTempFile("temp-ephemery", ".json"); - - String initialGenesisInput = "{\n" + - " \"config\": {\n" + - " \"chainId\": 39438135\n" + - " },\n" + - " \"timestamp\": \"1720119600\"\n" + - "}"; - Files.write(tempJsonFile, initialGenesisInput.getBytes(UTF_8)); - - when(EPHEMERY.getGenesisFile()).thenReturn(tempJsonFile.toString()); - long mockTimestamp = Instant.now().getEpochSecond() - 60 * 60 * 24 * 30 * 3; // 3 periods ago - when(mockGenesisConfigFile.getTimestamp()).thenReturn(mockTimestamp); - - BigInteger mockChainId = BigInteger.valueOf(39438135); - when(mockGenesisConfigOptions.getChainId()).thenReturn(Optional.of(mockChainId)); - - // This calculates the expected new values - long periodInSeconds = 28 * 24 * 60 * 60; // 28 days in seconds - long periodsSinceGenesis = ChronoUnit.DAYS.between(Instant.ofEpochSecond(mockTimestamp), Instant.now()) / 28; - long expectedTimestamp = mockTimestamp + periodsSinceGenesis * periodInSeconds; - BigInteger expectedChainId = mockChainId.add(BigInteger.valueOf(periodsSinceGenesis)); - - ObjectNode mockRootNode = mock(ObjectNode.class); - ObjectNode mockConfigNode = mock(ObjectNode.class); - when(mockObjectMapper.readTree(any(File.class))).thenReturn(mockRootNode); - when(mockRootNode.path("config")).thenReturn(mockConfigNode); - - verify(mockConfigNode).put(eq("chainId"), expectedChainId); - verify(mockRootNode).put(eq("timestamp"), expectedTimestamp); - verify(mockObjectMapper).writerWithDefaultPrettyPrinter(); - } - @Test public void classicValuesAreUsed() { parseCommand("--network", "classic"); @@ -2236,7 +2204,8 @@ public void assertThatCheckPortClashRejectsAsExpectedForEngineApi() throws Excep assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)) .contains( - "Port number '8545' has been specified multiple times. Please review the supplied configuration."); + "Port number '8545' has been specified multiple times. Please review the supplied" + + " configuration."); } @Test @@ -2341,7 +2310,8 @@ public void logsWarningWhenFailToLoadJemalloc() { verify(mockLogger) .warn( eq( - "BESU_USING_JEMALLOC is present but we failed to load jemalloc library to get the version"), + "BESU_USING_JEMALLOC is present but we failed to load jemalloc library to get the" + + " version"), any(Throwable.class)); } @@ -2387,7 +2357,8 @@ public void checkpointPostMergeShouldFailWhenGenesisUsesCheckpointFromPreMerge() assertThat(commandOutput.toString(UTF_8)).isEmpty(); assertThat(commandErrorOutput.toString(UTF_8)) .contains( - "PoS checkpoint sync requires a block with total difficulty greater or equal than the TTD"); + "PoS checkpoint sync requires a block with total difficulty greater or equal than the" + + " TTD"); } @Test @@ -2521,7 +2492,8 @@ public void snapsyncForHealingFeaturesShouldFailWhenHealingIsNotEnabled() { "100"); assertThat(commandErrorOutput.toString(UTF_8)) .contains( - "--Xsnapsync-synchronizer-flat option can only be used when --Xbonsai-full-flat-db-enabled is true"); + "--Xsnapsync-synchronizer-flat option can only be used when" + + " --Xbonsai-full-flat-db-enabled is true"); parseCommand( "--Xbonsai-full-flat-db-enabled", @@ -2530,7 +2502,8 @@ public void snapsyncForHealingFeaturesShouldFailWhenHealingIsNotEnabled() { "100"); assertThat(commandErrorOutput.toString(UTF_8)) .contains( - "--Xsnapsync-synchronizer-flat option can only be used when --Xbonsai-full-flat-db-enabled is true"); + "--Xsnapsync-synchronizer-flat option can only be used when" + + " --Xbonsai-full-flat-db-enabled is true"); } @Test 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 437b5874860..f6fa2e47984 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/CommandTestAbstract.java @@ -29,7 +29,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.fasterxml.jackson.databind.ObjectMapper; import org.hyperledger.besu.Runner; import org.hyperledger.besu.RunnerBuilder; import org.hyperledger.besu.chainexport.RlpBlockExporter; @@ -45,7 +44,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.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; import org.hyperledger.besu.controller.BesuController; import org.hyperledger.besu.controller.BesuControllerBuilder; @@ -226,9 +224,7 @@ public abstract class CommandTestAbstract { @Mock protected TransactionPool mockTransactionPool; @Mock protected PrivacyPluginServiceImpl privacyPluginService; @Mock protected StorageProvider storageProvider; - @Mock protected GenesisConfigOptions mockGenesisConfigOptions; - @Mock protected GenesisConfigFile mockGenesisConfigFile; - @Mock protected ObjectMapper mockObjectMapper; + @SuppressWarnings("PrivateStaticFinalLoggers") // @Mocks are inited by JUnit @Mock protected Logger mockLogger; diff --git a/besu/src/test/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFileTest.java b/besu/src/test/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFileTest.java new file mode 100644 index 00000000000..f621d302567 --- /dev/null +++ b/besu/src/test/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFileTest.java @@ -0,0 +1,215 @@ +/* + * Copyright contributors to Hyperledger Besu. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package org.hyperledger.besu.util; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.hyperledger.besu.cli.config.NetworkName; +import org.hyperledger.besu.config.GenesisConfigFile; +import org.hyperledger.besu.config.GenesisConfigOptions; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import io.vertx.core.json.JsonObject; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class GenerateEphemeryGenesisFileTest { + private static ObjectMapper objectMapper; + private static Path tempJsonFile; + private GenesisConfigFile genesisConfigFile; + private GenesisConfigOptions genesisConfigOptions; + private NetworkName network; + GenerateEphemeryGenesisFile generateEphemeryGenesisFile; + private static final int GENESIS_CONFIG_TEST_CHAINID = 39438135; + private static final long GENESIS_TEST_TIMESTAMP = 1609459200; + private static final long CURRENT_TIMESTAMP = 1512041200; + private static final long CURRENT_TIMESTAMP_HIGHER = 1622041200; + private static final long PERIOD_IN_SECONDS = 28 * 24 * 60 * 60; + private static final long PERIOD_SINCE_GENESIS = 3; + + private static final JsonObject VALID_GENESIS_JSON = + (new JsonObject()) + .put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID)) + .put("timestamp", GENESIS_TEST_TIMESTAMP); + + private static final JsonObject INVALID_GENESIS_VALID_JSON = new JsonObject(); + private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_CHAINID = + (new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP); + + private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP = + new JsonObject() + .put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID)); + + @BeforeEach + void setUp() throws IOException { + objectMapper = new ObjectMapper(); + network = mock(NetworkName.class); + genesisConfigFile = mock(GenesisConfigFile.class); + genesisConfigOptions = mock(GenesisConfigOptions.class); + generateEphemeryGenesisFile = + new GenerateEphemeryGenesisFile(network, genesisConfigFile, genesisConfigOptions); + tempJsonFile = Files.createTempFile("temp-ephemery", ".json"); + } + + @Test + public void testGenerateWhenChainIdIsAbsent() throws IOException { + Map node = + createGenesisFile(tempJsonFile, INVALID_GENESIS_JSON_WITHOUT_CHAINID); + ObjectNode configNode = node.get("configNode"); + assertThat(configNode.has("chainId")).isFalse(); + assertThat(configNode.get("chainId")).isNull(); + Files.delete(tempJsonFile); + } + + @Test + public void testGenerateWhenTimestampIsAbsent() throws IOException { + Map node = + createGenesisFile(tempJsonFile, INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP); + ObjectNode rootNode = node.get("rootNode"); + assertThat(rootNode.has("timestamp")).isFalse(); + assertThat(rootNode.get("timestamp")).isNull(); + Files.delete(tempJsonFile); + } + + @Test + public void testGenerateWhenGenesisJsonIsInvalid() throws IOException { + Map node = createGenesisFile(tempJsonFile, INVALID_GENESIS_VALID_JSON); + ObjectNode rootNode = node.get("rootNode"); + ObjectNode configNode = node.get("configNode"); + assertThat(rootNode.has("timestamp")).isFalse(); + assertThat(configNode.has("chainId")).isFalse(); + assertThat(rootNode.get("timestamp")).isNull(); + assertThat(configNode.get("chainId")).isNull(); + Files.delete(tempJsonFile); + } + + @Test + public void testGenerateWhenGenesisJsonIsValid() throws IOException { + Map node = createGenesisFile(tempJsonFile, VALID_GENESIS_JSON); + ObjectNode rootNode = node.get("rootNode"); + ObjectNode configNode = node.get("configNode"); + assertThat(rootNode.has("timestamp")).isTrue(); + assertThat(configNode.has("chainId")).isTrue(); + assertThat(rootNode.get("timestamp")).isNotNull(); + assertThat(configNode.get("chainId")).isNotNull(); + Files.delete(tempJsonFile); + } + + @Test + public void testGenerateNotYetDueForUpdate() throws IOException { + Map node = createGenesisFile(tempJsonFile, VALID_GENESIS_JSON); + ObjectNode rootNode = node.get("rootNode"); + assertThat(CURRENT_TIMESTAMP) + .isLessThan(rootNode.get("timestamp").asLong() + PERIOD_IN_SECONDS); + objectMapper.writerWithDefaultPrettyPrinter().writeValue(tempJsonFile.toFile(), rootNode); + Files.delete(tempJsonFile); + } + + @Test + public void testGenerateWhenSuccessful() throws IOException { + Map node = createGenesisFile(tempJsonFile, VALID_GENESIS_JSON); + ObjectNode rootNode = node.get("rootNode"); + ObjectNode configNode = node.get("configNode"); + + BigInteger expectedChainId = + BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID) + .add(BigInteger.valueOf(PERIOD_SINCE_GENESIS)); + + long expectedGenesisTimestamp = + GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); + EPHEMERY.setNetworkId(expectedChainId); + + configNode.put("chainId", expectedChainId); + rootNode.put("timestamp", String.valueOf(expectedGenesisTimestamp)); + + objectMapper.writerWithDefaultPrettyPrinter().writeValue(tempJsonFile.toFile(), rootNode); + + assertThat(CURRENT_TIMESTAMP_HIGHER) + .isGreaterThan(rootNode.get("timestamp").asLong() + PERIOD_IN_SECONDS); + assertThat(tempJsonFile).exists(); + assertThat(rootNode.get("timestamp").asLong()).isEqualTo(expectedGenesisTimestamp); + assertThat(configNode.get("chainId").toString()).isEqualTo(expectedChainId.toString()); + Files.delete(tempJsonFile); + } + + @Test + public void testGenerateWhenGenesisFilePathIsNull() throws IOException { + final Path tempJsonFile = Path.of("invalid-path"); + assertThat(tempJsonFile).doesNotExist(); + } + + @Test + public void testGenerateWhenChainIdAndTimestampIsPresent() throws IOException { + when(genesisConfigFile.getTimestamp()).thenReturn(GENESIS_TEST_TIMESTAMP); + when(genesisConfigOptions.getChainId()) + .thenReturn(Optional.of(BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID))); + generateEphemeryGenesisFile.generate(); + verify(network).getGenesisFile(); + verify(genesisConfigFile).getTimestamp(); + verify(genesisConfigOptions).getChainId(); + } + + @Test + public void testGenerateThrowIOException() throws IOException { + GenerateEphemeryGenesisFile spyGenerateEphemeryGenesisFile = spy(generateEphemeryGenesisFile); + + doThrow(new IOException("Unable to update ephemery genesis file.")) + .when(spyGenerateEphemeryGenesisFile) + .generate(); + + assertThatThrownBy(spyGenerateEphemeryGenesisFile::generate) + .isInstanceOf(IOException.class) + .hasMessage("Unable to update ephemery genesis file."); + verify(spyGenerateEphemeryGenesisFile).generate(); + } + + public Map createGenesisFile( + final Path tempJsonFile, final JsonObject genesisData) throws IOException { + Files.write(tempJsonFile, genesisData.encodePrettily().getBytes(UTF_8)); + + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode rootNode = (ObjectNode) objectMapper.readTree(tempJsonFile.toFile()); + + ObjectNode configNode = + rootNode.has("config") + ? (ObjectNode) rootNode.path("config") + : objectMapper.createObjectNode(); + Map nodes = new HashMap<>(); + nodes.put("rootNode", rootNode); + nodes.put("configNode", configNode); + + return nodes; + } +} diff --git a/config/src/main/resources/ephemery.json b/config/src/main/resources/ephemery.json index 3024b4c7a3f..7fda79626b7 100644 --- a/config/src/main/resources/ephemery.json +++ b/config/src/main/resources/ephemery.json @@ -18,10 +18,7 @@ "depositContractAddress" : "0x4242424242424242424242424242424242424242", "ethash" : { }, "discovery" : { - "bootnodes" : [ - "enode://50a54ecbd2175497640bcf46a25bbe9bb4fae51d7cc2a29ef4947a7ee17496cf39a699b7fe6b703ed0feb9dbaae7e44fc3827fcb7435ca9ac6de4daa4d983b3d@137.74.203.240:30303", - "enode://0f2c301a9a3f9fa2ccfa362b79552c052905d8c2982f707f46cd29ece5a9e1c14ecd06f4ac951b228f059a43c6284a1a14fce709e8976cac93b50345218bf2e9@135.181.140.168:30343" - ] + "bootnodes" : [ "enode://50a54ecbd2175497640bcf46a25bbe9bb4fae51d7cc2a29ef4947a7ee17496cf39a699b7fe6b703ed0feb9dbaae7e44fc3827fcb7435ca9ac6de4daa4d983b3d@137.74.203.240:30303", "enode://0f2c301a9a3f9fa2ccfa362b79552c052905d8c2982f707f46cd29ece5a9e1c14ecd06f4ac951b228f059a43c6284a1a14fce709e8976cac93b50345218bf2e9@135.181.140.168:30343" ] } }, "alloc" : { diff --git a/gradle.properties b/gradle.properties index 93f56e01379..b707e599df2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,4 @@ org.gradle.jvmargs=-Xmx4g \ --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \ --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED # Could be moved to sonar properties after https://sonarsource.atlassian.net/browse/SONARGRADL-134 -systemProp.sonar.gradle.skipCompile=true \ No newline at end of file +systemProp.sonar.gradle.skipCompile=true diff --git a/temp-ephemery.json b/temp-ephemery.json deleted file mode 100644 index 3024b4c7a3f..00000000000 --- a/temp-ephemery.json +++ /dev/null @@ -1,917 +0,0 @@ -{ - "config" : { - "chainId" : "39438135", - "homesteadBlock" : 0, - "eip150Block" : 0, - "eip155Block" : 0, - "eip158Block" : 0, - "byzantiumBlock" : 0, - "constantinopleBlock" : 0, - "petersburgBlock" : 0, - "istanbulBlock" : 0, - "berlinBlock" : 0, - "londonBlock" : 0, - "preMergeForkBlock" : 0, - "terminalTotalDifficulty" : 0, - "shanghaiTime" : 0, - "cancunTime" : 0, - "depositContractAddress" : "0x4242424242424242424242424242424242424242", - "ethash" : { }, - "discovery" : { - "bootnodes" : [ - "enode://50a54ecbd2175497640bcf46a25bbe9bb4fae51d7cc2a29ef4947a7ee17496cf39a699b7fe6b703ed0feb9dbaae7e44fc3827fcb7435ca9ac6de4daa4d983b3d@137.74.203.240:30303", - "enode://0f2c301a9a3f9fa2ccfa362b79552c052905d8c2982f707f46cd29ece5a9e1c14ecd06f4ac951b228f059a43c6284a1a14fce709e8976cac93b50345218bf2e9@135.181.140.168:30343" - ] - } - }, - "alloc" : { - "0x0000000000000000000000000000000000000000" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000001" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000002" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000003" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000004" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000005" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000006" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000007" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000008" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000009" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000000a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000000b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000000c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000000d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000000e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000000f" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000010" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000011" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000012" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000013" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000014" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000015" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000016" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000017" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000018" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000019" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000001a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000001b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000001c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000001d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000001e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000001f" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000020" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000021" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000022" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000023" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000024" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000025" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000026" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000027" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000028" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000029" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000002a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000002b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000002c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000002d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000002e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000002f" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000030" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000031" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000032" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000033" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000034" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000035" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000036" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000037" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000038" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000039" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000003a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000003b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000003c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000003d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000003e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000003f" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000040" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000041" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000042" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000043" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000044" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000045" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000046" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000047" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000048" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000049" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000004a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000004b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000004c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000004d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000004e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000004f" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000050" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000051" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000052" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000053" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000054" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000055" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000056" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000057" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000058" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000059" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000005a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000005b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000005c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000005d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000005e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000005f" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000060" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000061" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000062" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000063" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000064" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000065" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000066" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000067" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000068" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000069" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000006a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000006b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000006c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000006d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000006e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000006f" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000070" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000071" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000072" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000073" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000074" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000075" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000076" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000077" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000078" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000079" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000007a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000007b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000007c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000007d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000007e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000007f" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000080" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000081" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000082" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000083" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000084" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000085" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000086" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000087" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000088" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000089" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000008a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000008b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000008c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000008d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000008e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000008f" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000090" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000091" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000092" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000093" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000094" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000095" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000096" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000097" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000098" : { - "balance" : "1" - }, - "0x0000000000000000000000000000000000000099" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000009a" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000009b" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000009c" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000009d" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000009e" : { - "balance" : "1" - }, - "0x000000000000000000000000000000000000009f" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a0" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a1" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a2" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a3" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a4" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a5" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a6" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a7" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a8" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000a9" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000aa" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ab" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ac" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ad" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ae" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000af" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b0" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b1" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b2" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b3" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b4" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b5" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b6" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b7" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b8" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000b9" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ba" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000bb" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000bc" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000bd" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000be" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000bf" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c0" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c1" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c2" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c3" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c4" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c5" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c6" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c7" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c8" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000c9" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ca" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000cb" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000cc" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000cd" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ce" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000cf" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d0" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d1" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d2" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d3" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d4" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d5" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d6" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d7" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d8" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000d9" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000da" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000db" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000dc" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000dd" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000de" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000df" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e0" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e1" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e2" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e3" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e4" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e5" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e6" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e7" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e8" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000e9" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ea" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000eb" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ec" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ed" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ee" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ef" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f0" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f1" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f2" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f3" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f4" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f5" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f6" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f7" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f8" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000f9" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000fa" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000fb" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000fc" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000fd" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000fe" : { - "balance" : "1" - }, - "0x00000000000000000000000000000000000000ff" : { - "balance" : "1" - }, - "0x4242424242424242424242424242424242424242" : { - "balance" : "0", - "code" : "0x60806040526004361061003f5760003560e01c806301ffc9a71461004457806322895118146100a4578063621fd130146101ba578063c5f2892f14610244575b600080fd5b34801561005057600080fd5b506100906004803603602081101561006757600080fd5b50357fffffffff000000000000000000000000000000000000000000000000000000001661026b565b604080519115158252519081900360200190f35b6101b8600480360360808110156100ba57600080fd5b8101906020810181356401000000008111156100d557600080fd5b8201836020820111156100e757600080fd5b8035906020019184600183028401116401000000008311171561010957600080fd5b91939092909160208101903564010000000081111561012757600080fd5b82018360208201111561013957600080fd5b8035906020019184600183028401116401000000008311171561015b57600080fd5b91939092909160208101903564010000000081111561017957600080fd5b82018360208201111561018b57600080fd5b803590602001918460018302840111640100000000831117156101ad57600080fd5b919350915035610304565b005b3480156101c657600080fd5b506101cf6110b5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102095781810151838201526020016101f1565b50505050905090810190601f1680156102365780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025057600080fd5b506102596110c7565b60408051918252519081900360200190f35b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a70000000000000000000000000000000000000000000000000000000014806102fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f8564090700000000000000000000000000000000000000000000000000000000145b92915050565b6030861461035d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118056026913960400191505060405180910390fd5b602084146103b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603681526020018061179c6036913960400191505060405180910390fd5b6060821461040f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806118786029913960400191505060405180910390fd5b670de0b6b3a7640000341015610470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806118526026913960400191505060405180910390fd5b633b9aca003406156104cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260338152602001806117d26033913960400191505060405180910390fd5b633b9aca00340467ffffffffffffffff811115610535576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061182b6027913960400191505060405180910390fd5b6060610540826114ba565b90507f649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c589898989858a8a6105756020546114ba565b6040805160a0808252810189905290819060208201908201606083016080840160c085018e8e80828437600083820152601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690910187810386528c815260200190508c8c808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690920188810386528c5181528c51602091820193918e019250908190849084905b83811015610648578181015183820152602001610630565b50505050905090810190601f1680156106755780820380516001836020036101000a031916815260200191505b5086810383528881526020018989808284376000838201819052601f9091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169092018881038452895181528951602091820193918b019250908190849084905b838110156106ef5781810151838201526020016106d7565b50505050905090810190601f16801561071c5780820380516001836020036101000a031916815260200191505b509d505050505050505050505050505060405180910390a1600060028a8a600060801b604051602001808484808284377fffffffffffffffffffffffffffffffff0000000000000000000000000000000090941691909301908152604080517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0818403018152601090920190819052815191955093508392506020850191508083835b602083106107fc57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016107bf565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610859573d6000803e3d6000fd5b5050506040513d602081101561086e57600080fd5b5051905060006002806108846040848a8c6116fe565b6040516020018083838082843780830192505050925050506040516020818303038152906040526040518082805190602001908083835b602083106108f857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016108bb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610955573d6000803e3d6000fd5b5050506040513d602081101561096a57600080fd5b5051600261097b896040818d6116fe565b60405160009060200180848480828437919091019283525050604080518083038152602092830191829052805190945090925082918401908083835b602083106109f457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016109b7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610a51573d6000803e3d6000fd5b5050506040513d6020811015610a6657600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610ada57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a9d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610b37573d6000803e3d6000fd5b5050506040513d6020811015610b4c57600080fd5b50516040805160208101858152929350600092600292839287928f928f92018383808284378083019250505093505050506040516020818303038152906040526040518082805190602001908083835b60208310610bd957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610b9c565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610c36573d6000803e3d6000fd5b5050506040513d6020811015610c4b57600080fd5b50516040518651600291889160009188916020918201918291908601908083835b60208310610ca957805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610c6c565b6001836020036101000a0380198251168184511680821785525050505050509050018367ffffffffffffffff191667ffffffffffffffff1916815260180182815260200193505050506040516020818303038152906040526040518082805190602001908083835b60208310610d4e57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610d11565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610dab573d6000803e3d6000fd5b5050506040513d6020811015610dc057600080fd5b5051604080516020818101949094528082019290925280518083038201815260609092019081905281519192909182918401908083835b60208310610e3457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610df7565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015610e91573d6000803e3d6000fd5b5050506040513d6020811015610ea657600080fd5b50519050858114610f02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260548152602001806117486054913960600191505060405180910390fd5b60205463ffffffff11610f60576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806117276021913960400191505060405180910390fd5b602080546001019081905560005b60208110156110a9578160011660011415610fa0578260008260208110610f9157fe5b0155506110ac95505050505050565b600260008260208110610faf57fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061102557805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610fe8565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa158015611082573d6000803e3d6000fd5b5050506040513d602081101561109757600080fd5b50519250600282049150600101610f6e565b50fe5b50505050505050565b60606110c26020546114ba565b905090565b6020546000908190815b60208110156112f05781600116600114156111e6576002600082602081106110f557fe5b01548460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061116b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161112e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156111c8573d6000803e3d6000fd5b5050506040513d60208110156111dd57600080fd5b505192506112e2565b600283602183602081106111f657fe5b015460405160200180838152602001828152602001925050506040516020818303038152906040526040518082805190602001908083835b6020831061126b57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161122e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa1580156112c8573d6000803e3d6000fd5b5050506040513d60208110156112dd57600080fd5b505192505b6002820491506001016110d1565b506002826112ff6020546114ba565b600060401b6040516020018084815260200183805190602001908083835b6020831061135a57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161131d565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790527fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000095909516920191825250604080518083037ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8018152601890920190819052815191955093508392850191508083835b6020831061143f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101611402565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930194509192505080830381855afa15801561149c573d6000803e3d6000fd5b5050506040513d60208110156114b157600080fd5b50519250505090565b60408051600880825281830190925260609160208201818036833701905050905060c082901b8060071a60f81b826000815181106114f457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060061a60f81b8260018151811061153757fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060051a60f81b8260028151811061157a57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060041a60f81b826003815181106115bd57fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060031a60f81b8260048151811061160057fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060021a60f81b8260058151811061164357fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060011a60f81b8260068151811061168657fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508060001a60f81b826007815181106116c957fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050919050565b6000808585111561170d578182fd5b83861115611719578182fd5b505082019391909203915056fe4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c6c4465706f736974436f6e74726163743a207265636f6e7374727563746564204465706f7369744461746120646f6573206e6f74206d6174636820737570706c696564206465706f7369745f646174615f726f6f744465706f736974436f6e74726163743a20696e76616c6964207769746864726177616c5f63726564656e7469616c73206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c7565206e6f74206d756c7469706c65206f6620677765694465706f736974436f6e74726163743a20696e76616c6964207075626b6579206c656e6774684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f20686967684465706f736974436f6e74726163743a206465706f7369742076616c756520746f6f206c6f774465706f736974436f6e74726163743a20696e76616c6964207369676e6174757265206c656e677468a2646970667358221220dceca8706b29e917dacf25fceef95acac8d90d765ac926663ce4096195952b6164736f6c634300060b0033", - "storage" : { - "0x0000000000000000000000000000000000000000000000000000000000000022" : "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", - "0x0000000000000000000000000000000000000000000000000000000000000023" : "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0x0000000000000000000000000000000000000000000000000000000000000024" : "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", - "0x0000000000000000000000000000000000000000000000000000000000000025" : "0x536d98837f2dd165a55d5eeae91485954472d56f246df256bf3cae19352a123c", - "0x0000000000000000000000000000000000000000000000000000000000000026" : "0x9efde052aa15429fae05bad4d0b1d7c64da64d03d7a1854a588c2cb8430c0d30", - "0x0000000000000000000000000000000000000000000000000000000000000027" : "0xd88ddfeed400a8755596b21942c1497e114c302e6118290f91e6772976041fa1", - "0x0000000000000000000000000000000000000000000000000000000000000028" : "0x87eb0ddba57e35f6d286673802a4af5975e22506c7cf4c64bb6be5ee11527f2c", - "0x0000000000000000000000000000000000000000000000000000000000000029" : "0x26846476fd5fc54a5d43385167c95144f2643f533cc85bb9d16b782f8d7db193", - "0x000000000000000000000000000000000000000000000000000000000000002a" : "0x506d86582d252405b840018792cad2bf1259f1ef5aa5f887e13cb2f0094f51e1", - "0x000000000000000000000000000000000000000000000000000000000000002b" : "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", - "0x000000000000000000000000000000000000000000000000000000000000002c" : "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", - "0x000000000000000000000000000000000000000000000000000000000000002d" : "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f", - "0x000000000000000000000000000000000000000000000000000000000000002e" : "0xdf6af5f5bbdb6be9ef8aa618e4bf8073960867171e29676f8b284dea6a08a85e", - "0x000000000000000000000000000000000000000000000000000000000000002f" : "0xb58d900f5e182e3c50ef74969ea16c7726c549757cc23523c369587da7293784", - "0x0000000000000000000000000000000000000000000000000000000000000030" : "0xd49a7502ffcfb0340b1d7885688500ca308161a7f96b62df9d083b71fcc8f2bb", - "0x0000000000000000000000000000000000000000000000000000000000000031" : "0x8fe6b1689256c0d385f42f5bbe2027a22c1996e110ba97c171d3e5948de92beb", - "0x0000000000000000000000000000000000000000000000000000000000000032" : "0x8d0d63c39ebade8509e0ae3c9c3876fb5fa112be18f905ecacfecb92057603ab", - "0x0000000000000000000000000000000000000000000000000000000000000033" : "0x95eec8b2e541cad4e91de38385f2e046619f54496c2382cb6cacd5b98c26f5a4", - "0x0000000000000000000000000000000000000000000000000000000000000034" : "0xf893e908917775b62bff23294dbbe3a1cd8e6cc1c35b4801887b646a6f81f17f", - "0x0000000000000000000000000000000000000000000000000000000000000035" : "0xcddba7b592e3133393c16194fac7431abf2f5485ed711db282183c819e08ebaa", - "0x0000000000000000000000000000000000000000000000000000000000000036" : "0x8a8d7fe3af8caa085a7639a832001457dfb9128a8061142ad0335629ff23ff9c", - "0x0000000000000000000000000000000000000000000000000000000000000037" : "0xfeb3c337d7a51a6fbf00b9e34c52e1c9195c969bd4e7a0bfd51d5c5bed9c1167", - "0x0000000000000000000000000000000000000000000000000000000000000038" : "0xe71f0aa83cc32edfbefa9f4d3e0174ca85182eec9f3a09f6a6c0df6377a510d7", - "0x0000000000000000000000000000000000000000000000000000000000000039" : "0x31206fa80a50bb6abe29085058f16212212a60eec8f049fecb92d8c8e0a84bc0", - "0x000000000000000000000000000000000000000000000000000000000000003a" : "0x21352bfecbeddde993839f614c3dac0a3ee37543f9b412b16199dc158e23b544", - "0x000000000000000000000000000000000000000000000000000000000000003b" : "0x619e312724bb6d7c3153ed9de791d764a366b389af13c58bf8a8d90481a46765", - "0x000000000000000000000000000000000000000000000000000000000000003c" : "0x7cdd2986268250628d0c10e385c58c6191e6fbe05191bcc04f133f2cea72c1c4", - "0x000000000000000000000000000000000000000000000000000000000000003d" : "0x848930bd7ba8cac54661072113fb278869e07bb8587f91392933374d017bcbe1", - "0x000000000000000000000000000000000000000000000000000000000000003e" : "0x8869ff2c22b28cc10510d9853292803328be4fb0e80495e8bb8d271f5b889636", - "0x000000000000000000000000000000000000000000000000000000000000003f" : "0xb5fe28e79f1b850f8658246ce9b6a1e7b49fc06db7143e8fe0b4f2b0c5523a5c", - "0x0000000000000000000000000000000000000000000000000000000000000040" : "0x985e929f70af28d0bdd1a90a808f977f597c7c778c489e98d3bd8910d31ac0f7" - } - }, - "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02" : { - "balance" : "0", - "nonce" : "1", - "code" : "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500" - }, - "0xa2A6d93439144FFE4D27c9E088dCD8b783946263" : { - "balance" : "1000000000000000000000000" - }, - "0xBc11295936Aa79d594139de1B2e12629414F3BDB" : { - "balance" : "1000000000000000000000000" - }, - "0x7cF5b79bfe291A67AB02b393E456cCc4c266F753" : { - "balance" : "1000000000000000000000000" - }, - "0xaaec86394441f915bce3e6ab399977e9906f3b69" : { - "balance" : "1000000000000000000000000" - }, - "0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8" : { - "balance" : "1000000000000000000000000" - }, - "0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8" : { - "balance" : "1000000000000000000000000" - }, - "0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e" : { - "balance" : "1000000000000000000000000" - }, - "0xe2e2659028143784d557bcec6ff3a0721048880a" : { - "balance" : "1000000000000000000000000" - }, - "0xd9a5179f091d85051d3c982785efd1455cec8699" : { - "balance" : "1000000000000000000000000" - }, - "0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf" : { - "balance" : "1000000000000000000000000" - }, - "0x0000006916a87b82333f4245046623b23794c65c" : { - "balance" : "10000000000000000000000000" - }, - "0xb21c33de1fab3fa15499c62b59fe0cc3250020d1" : { - "balance" : "100000000000000000000000000" - }, - "0x10F5d45854e038071485AC9e402308cF80D2d2fE" : { - "balance" : "100000000000000000000000000" - }, - "0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E" : { - "balance" : "100000000000000000000000000" - }, - "0x799D329e5f583419167cD722962485926E338F4a" : { - "balance" : "1000000000000000000" - }, - "0x4c2ae482593505f0163cdefc073e81c63cda4107" : { - "balance" : "1000000000000000000000000" - }, - "0xa8e8f14732658e4b51e8711931053a8a69baf2b1" : { - "balance" : "1000000000000000000000000" - }, - "0xe0a2bd4258d2768837baa26a28fe71dc079f84c7" : { - "balance" : "100000000000000000000000000" - }, - "0x1eA692E68a7765dE26FC03A6D74EE5B56A7e2b4d" : { - "balance" : "100000000000000000000000000" - }, - "0x57c3dfd40A86628B67721115d7A03C9F341d7718" : { - "balance" : "100000000000000000000000000" - }, - "0xc90E920F4DCfd4954230edCaB168D0C5B9561e03" : { - "balance" : "1000000000000000000000000000" - }, - "0x6Cc9397c3B38739daCbfaA68EaD5F5D77Ba5F455" : { - "balance" : "10000000000000000000000000" - }, - "0x992775d32fd0ec76b95C5E76CeEA92ED5a4bE1F9" : { - "balance" : "10000000000000000000000000" - } - }, - "coinbase" : "0x0000000000000000000000000000000000000000", - "baseFeePerGas" : "0x3B9ACA00", - "difficulty" : "0x01", - "extraData" : "", - "gasLimit" : "0x1c9c380", - "nonce" : "0x1234", - "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp" : "1720119600" -} \ No newline at end of file From 7b7819e92b98aedfdeef7eef767cd2b38218d0a0 Mon Sep 17 00:00:00 2001 From: gconnect Date: Fri, 23 Aug 2024 06:13:52 +0100 Subject: [PATCH 092/124] Update EphemeryGenerateGenesisFile, generate method Signed-off-by: gconnect --- .../besu/util/GenerateEphemeryGenesisFile.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java b/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java index 59e5a8e971d..d6b2b62959b 100644 --- a/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java +++ b/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java @@ -56,9 +56,9 @@ public GenerateEphemeryGenesisFile( } public void generate() throws IOException { - if (Optional.ofNullable(network).orElse(EPHEMERY).getGenesisFile() != null - || genesisConfigFile.getConfigOptions() != null - || genesisConfigFile.getTimestamp() != 0) { + if (EPHEMERY.getGenesisFile() != null + || genesisConfigOptions != null + || genesisConfigFile != null) { final int PERIOD = 28; long genesisTimestamp = genesisConfigFile.getTimestamp(); @@ -77,6 +77,9 @@ public void generate() throws IOException { EPHEMERY.setNetworkId(updatedChainId); if (currentTimestamp > (genesisTimestamp + periodInSeconds)) { + + GenesisConfigFile.fromResource( + Optional.ofNullable(network).orElse(EPHEMERY).getGenesisFile()); Path ephemeryGenesisfilePath = Path.of(EPHEMERY.getGenesisFile()); try { ObjectMapper objectMapper = new ObjectMapper(); From e8e5dc5442fda197cb7bd1171abe110cc6e10fa9 Mon Sep 17 00:00:00 2001 From: Jason Frame Date: Mon, 19 Aug 2024 15:09:38 +1000 Subject: [PATCH 093/124] Change default for receipt compaction to be enabled (#7450) Signed-off-by: Jason Frame Signed-off-by: gconnect --- 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 9173e46fd5e..8945cdd1ee5 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 6f5c037c0d3..3d53a595ec8 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 2086381825f..29fa3d66071 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 void bonsaiCodeUsingCodeHashEnabledCanBeDisabled() { "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 void receiptCompactionCanBeDisabled() { 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 8d767f442aa..320e38733d4 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 909a2c5e90e..6debcc046e5 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 @@ private Optional handleVersionUpgrade( // 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 @@ private Optional handleVersionUpgrade( "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 8e1a4fa5213..d53c9e57fde 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 @@ private Optional handleVersionUpgrade( // 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 @@ private Optional handleVersionUpgrade( "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 658bb24a0f8..ad3557636d2 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 46dbb9e7403..a72db7c322b 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 static DatabaseMetadata defaultForNewDb(final BesuConfiguration besuConfi * @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 87ff357e16d..ca5988dc75f 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 5dd485cb7af..17a3fb874a4 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 void shouldDetectVersion1MetadataIfPresent() throws Exception { 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 void shouldCreateCorrectMetadataFileForLatestVersion() throws Exception { // 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 void shouldUpdateCorrectMetadataFileForLatestVersion( 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 void shouldUpdateCorrectMetadataFileForLatestVersion( 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 void shouldUpdateCorrectMetadataFileForLatestVersionWithReceiptCompaction 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 a86c5ba807b..7148f601cbd 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 void shouldCreateCorrectMetadataFileForLatestVersionForNewDb( // 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 void shouldCreateCorrectMetadataFileForLatestVersionForNewDbWithReceiptCo 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 void shouldFailIfDbExistsAndNoMetadataFileFound() throws Exception { } @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 void shouldDetectCorrectMetadataV1() throws Exception { 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 void shouldDetectCorrectMetadataV2AndSetSegmentationFieldDuringCreation() () -> 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 void shouldCreateDBCorrectlyIfSymlink() throws Exception { // 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 79f6eda8316febe35d185259489943844209e97d Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Mon, 19 Aug 2024 15:50:57 +1000 Subject: [PATCH 094/124] 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 Signed-off-by: gconnect --- .../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 966cda12008..3798cbe507c 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 void missingHashesOrTransactionParameter() { 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 f1a799cf638..ec0e6aef64a 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 JsonRpcResponse process( 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 da795439cf3..4c1d3bfc2a6 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .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 ad46d981ac8..d309f8dfdd8 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 @@ protected TraceOptions getTraceOptions(final JsonRpcRequestContext requestContex .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 09b1c2f9523..875daea7f13 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 @@ private boolean isCompleteTransactions(final JsonRpcRequestContext requestContex 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 5e0bc9c7ab4..8e0954144d8 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 @@ private boolean isCompleteTransactions(final JsonRpcRequestContext request) { 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 a1460c5aa24..b346637ec25 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 cb19d2e7a35..009fca38fc0 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 dcfd198d6e1..bb5cb68a2ae 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 void getBlockByHashWithMissingBooleanParameter() throws Exception { 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 void getBlockByHashWithInvalidBooleanParameter() throws Exception { 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 0fc8969c938..e79fff04f7f 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 void exceptionWhenNoHashSupplied() { 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 void exceptionWhenHashParamInvalid() { 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 bc6ec997f34..254d0fbe9e8 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 void exceptionWhenNoNumberSupplied() { 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 void exceptionWhenNumberParamInvalid() { 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 badfd2d7dc4d48ac3f6372450d761fc2ad2433c7 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Mon, 19 Aug 2024 15:20:47 +0200 Subject: [PATCH 095/124] 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 Signed-off-by: gconnect --- 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 8945cdd1ee5..1ad5678b086 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 16b683ed712..6e0f0e3e35c 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.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 Optional getAndMapWorldState( } 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 54e17cb21cb..5d6aba76942 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 @@ 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.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 void shouldReturnMinValueWhenNoTransactionsExist() { 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 void shouldReturnBaseFeeAsMinValueOnGenesis() { 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 void shouldReturnMedianWhenTransactionsExist() { 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 void shortChainQueriesAllBlocks() { 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 void ethGasPriceAtGenesis( 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 @@ private void mockBlockchain( 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 3c76ba69f5c..49b6fea33e1 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 @@ default boolean contains(final Hash blockHash) { */ 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 04eaaa6a353..5849f3e676c 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 BlockHeader getChainHeadHeader() { @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 Optional getBlockBody(final Hash blockHeaderHash) { .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 5e31464ee61..c5905967fc2 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 Optional getBlockBody(final Hash blockHeaderHash) { 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 3773c8d1f05..8f03a01caa7 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 Optional getBlockBody(final Hash blockHeaderHash) { 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 bfe5e75df0f2ad76ed0aaf55c73e928901773edb Mon Sep 17 00:00:00 2001 From: garyschulte Date: Mon, 19 Aug 2024 15:46:15 -0700 Subject: [PATCH 096/124] preprocess release name for release workflow (#7486) Signed-off-by: garyschulte Signed-off-by: gconnect --- .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 2aff0bb48e5..c7436653578 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 454d04f189323eca66e34a2580acd0d2e13e02c7 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Tue, 20 Aug 2024 01:50:26 +0200 Subject: [PATCH 097/124] 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 Signed-off-by: gconnect --- 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 1ad5678b086..f04fcfb345f 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 a3dd13bd1b5..f8bf6d50c5c 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 ed028767d6a..3d56c1fc07b 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 @@ private TransactionEvaluationContext createTransactionEvaluationContext( .getTransactionPriceCalculator() .price( pendingTransaction.getTransaction(), - blockSelectionContext.processableBlockHeader().getBaseFee()); + blockSelectionContext.pendingBlockHeader().getBaseFee()); return new TransactionEvaluationContext( + blockSelectionContext.pendingBlockHeader(), pendingTransaction, Stopwatch.createStarted(), transactionGasPriceInBlock, @@ -330,10 +331,10 @@ private TransactionSelectionResult evaluatePostProcessing( 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 0a17812b0f9..7fce600a1a6 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 @@ 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 Transaction getTransaction() { 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 793f3e93842..2877c4ce139 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 @@ private boolean transactionTooLargeForBlock( final TransactionSelectionResults transactionSelectionResults) { return transaction.getGasLimit() - > context.processableBlockHeader().getGasLimit() + > context.pendingBlockHeader().getGasLimit() - transactionSelectionResults.getCumulativeGasUsed(); } @@ -104,7 +104,7 @@ private boolean transactionTooLargeForBlock( */ 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 @@ private boolean blockOccupancyAboveThreshold( * @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 fc32a5c08ca..5783c7e5007 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 @@ private boolean isPriorityFeePriceBelowMinimum(final PendingTransaction pendingT 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 8122dc3088c..6f81f4df2c6 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 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 void initialize() { 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 @@ private TransactionEvaluationContext mockTransactionEvaluationContext( 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 f52a5dfb462..123faf2d18a 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 @@ void notBlobTransactionsAreSelectedWithoutAnyCheck() { 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 @@ void firstBlobTransactionIsSelected() { 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 @@ void returnsBlobsFullWhenMaxNumberOfBlobsAlreadyPresent() { 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 @@ void returnsTooLargeForRemainingBlobGas() { 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 4440a4f0691..af8da71a7f1 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 93eae92dc7b..8938ef881b4 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 @@ 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 @@ */ public interface TransactionEvaluationContext { + /** + * Gets the pending block header + * + * @return the pending block header + */ + ProcessableBlockHeader getPendingBlockHeader(); + /** * Gets the pending transaction. * From c305ec2036e1328067a8e017de57477bf081d067 Mon Sep 17 00:00:00 2001 From: gringsam Date: Mon, 19 Aug 2024 20:33:19 -0400 Subject: [PATCH 098/124] fix wiki (#7480) Signed-off-by: Snazzy Co-authored-by: Sally MacFarlane Signed-off-by: gconnect --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb4a656b0e4..c2d6c57d25a 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 23d9933eaf030bcfe398ff0331d91e4a0852bbdd Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Mon, 19 Aug 2024 18:31:50 -0700 Subject: [PATCH 099/124] 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 Signed-off-by: gconnect --- .../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 5b9bc2cdfe0..bec68a3cc39 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.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 @@ private void traceTestSpecs(final String test, final BlockchainReferenceTestCase .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 6c8b9d5ad3f..4c041198646 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 CodeValidateSubCommand() { 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 bfa873e61cf..94f8b2cd492 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 void run() { 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 2e1656b13d4..aeff4a96b59 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 void run() { 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 40f36f18f1c..f6e05b5a498 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.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 @@ private void traceTestSpecs(final String test, 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 bf17f2f96ec..9aa04bd0ffe 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 @@ 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 a15bcb24189..8621b5d08af 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 static Collection generateTestParametersForConfig(final String[ @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 static void executeTest( .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 1d9ce8eefaa..aabc6740870 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.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 static void executeTest(final BlockchainReferenceTestCaseSpec spec) { .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 18d574adc15..42934b612d0 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.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 @@ private static MainnetTransactionProcessor transactionProcessor(final String nam } 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 d9e52403d78..a08efec2b6b 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 f968bbf36aa..0192c6f5787 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 CodeV1Validation(final int maxContainerSize) { @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 String validate(final EOFLayout layout) { 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 @@ String validateCode( 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 @@ String validateCode( 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 @@ String validateCode( 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 @@ String validateCode( 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 @@ String validateCode( 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 @@ String validateCode( 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 @@ String validateCode( 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 @@ String validateCode( 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 @@ String validateCode( // 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 @@ String validateCode( } 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 @@ String validateStack( 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 @@ String validateStack( } 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 @@ String validateStack( 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 @@ String validateStack( } 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 @@ String validateStack( } 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 @@ String validateStack( } 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 @@ String validateStack( 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 @@ String validateStack( "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 @@ String validateStack( } 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 @@ String validateStack( 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 39723f7fd37..d5abb05f868 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 void prettyPrint( 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 void prettyPrint( 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 e1f1e767d21..6f60ab7865b 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 @@ void invalidComboEOFCreateStop() { # 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 @@ void invalidComboEOFCretateReturn() { # 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 @@ void invalidReturncontractReturncontract() { # 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 08cbbedf75c..9b7edf80b40 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 @@ private static Stream rjumptableValidImmediateArguments() { @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 @@ private static Stream invalidCodeArguments() { @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 @@ private static Stream pushTruncatedImmediateArguments() { @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 @@ void testRjumpiTruncatedImmediate(final String code) { "6001e2030000000100" }) void testRjumpvTruncatedImmediate(final String code) { - assertValidation("Truncated jump table", code); + assertValidation("truncated_instruction", code); } @ParameterizedTest @@ -264,7 +264,7 @@ void testRjumpvTruncatedImmediate(final String code) { "6001e200fff900" }) void testRjumpsOutOfBounds(final String code) { - assertValidation("Relative jump destination out of bounds", code); + assertValidation("invalid_rjump_destination", code); } @ParameterizedTest @@ -317,7 +317,7 @@ void testRjumpsOutOfBounds(final String code) { "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 @@ private static Stream rjumpsIntoImmediateExtraArguments() { @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 @@ void validateStackAnalysis( 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 @@ static Stream stackImmediateBytes() { 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 @@ static Stream stackRJumpForward() { 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 @@ static Stream stackRJumpBackward() { 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 @@ static Stream stackRJumpBackward() { "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 @@ static Stream stackRJumpI() { 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 @@ static Stream stackCallF() { 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 @@ static Stream stackUnreachable() { 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 @@ static Stream stackHeight() { 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 @@ static Stream invalidInstructions() { 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 185e23bc735908a765cac9dcad78b4e98d037c85 Mon Sep 17 00:00:00 2001 From: Matilda-Clerke Date: Tue, 20 Aug 2024 14:54:00 +1000 Subject: [PATCH 100/124] 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 Signed-off-by: gconnect --- .../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 813c296098c..057fb30ee5e 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.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 @@ private Optional determineBlockHeader(final JsonRpcRequestContext r 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 c683b9d4855..908ff9f4123 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.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 @@ private Optional determineBlockHeader(final JsonRpcRequestContext r 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 467164e8c02..da3214b1ef0 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 6e198a84fe2..26ab19c9882 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 7ef368fb762..e3785976af9 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 7e6c0010888..89534689379 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 3c3346cd436..dfefe22c53f 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.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 @@ private Object blockResult(final JsonRpcRequestContext request) { 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 7992f0918c4..a878ebc66e7 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.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 IbftGetValidatorsByBlockNumber( 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 9364422c578..f010633e63f 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 98856caaa61..66e9cf60143 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 e991f7f355d..75000bde5d3 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.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 @@ private Object blockResult(final JsonRpcRequestContext request) { 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 7a64a7ab22a..b33490f0c22 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.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 QbftGetValidatorsByBlockNumber( 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 aa3a8b267e5..e6ad3ff6a89 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 6dbf9f586fe..ab53e415dd5 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.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 String getName() { 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 06b495624ef..a7c1e15e01d 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 @@ 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 int hashCode() { 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 b489259eb82..cc96384005b 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 Optional getUser() { 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 a5965211757..36991796b51 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 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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { 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 3cfd524c148..6081f8f3404 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 437f7f5821a..cad60660c33 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 94430c526f8..c7b67b28270 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 7336faff0e6..650a9f74eb4 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 f1c134ed915..5b70668c322 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 602f3de3e0c..318d8a0b8de 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 @@ protected Object resultByBlockHash( 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 @@ protected Object resultByBlockHash( 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 fc787031dac..852972f4d82 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 83553dc8745..d78f9fb6be9 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 28d886bd81e..c9097583e36 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.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 String getName() { 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 e2f2c89e1aa..8e4f9ce6ead 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.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 String getName() { 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 cddba5086e8..1c634c3c730 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 d6ede25b27e..2b1e756d22a 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 a3b423675fd..7958f8e7595 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.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 String getName() { 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 2d0c4cac4e2..b49c94fd6a0 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 5fba2911bdd..b3bb32370ee 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 5aabff4b574..1fde6610ef8 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 2d668c7f229..edfb816bb9d 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 @@ 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 String getName() { @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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .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 4c1d3bfc2a6..d98e8abd8df 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .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 eb90edabb95..99c96c99be9 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.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 String getName() { 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 @@ protected Object resultByBlockNumber( .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 d309f8dfdd8..e808e79ddc3 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.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 @@ protected TraceOptions getTraceOptions(final JsonRpcRequestContext requestContex .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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { 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 8ec14dc4ad5..1e85e6530a4 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .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 a08b17dfc63..0e0318f9c2b 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 01a08022790..b95746dad98 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.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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 e863626c967..cb1d879a05f 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 @@ protected String resultByBlockHash(final JsonRpcRequestContext request, final Ha 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 875daea7f13..f5b633253ad 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.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 @@ private BlockResult blockResult(final JsonRpcRequestContext request) { 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 @@ private BlockResult transactionHash(final Hash hash) { 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 8e0954144d8..0a26a24ee38 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.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 String getName() { 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 @@ private BlockResult transactionHash(final long blockNumber) { 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 d9592db8c11..a113e4ee8e8 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 e1fbd790868..fc7c3cc70c2 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 2a068a61740..95bd7cc5070 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.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 String getName() { 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 8a9881a0125..0c9194b0b34 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 @@ protected String resultByBlockHash(final JsonRpcRequestContext request, final Ha 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 0773651b615..b3fa7565d63 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 b66b7963e1c..0fd32455b24 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 c9645d53e0a..225870ba3a4 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 8e3d55f1eab..8b54364a999 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 c2df7126864..e0fe2460626 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.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 String getName() { 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 7c2f67b724f..d1920b5c1a2 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 @@ protected Object resultByBlockHash( 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 @@ private List getStorageKeys(final JsonRpcRequestContext request) { 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 34ed62b6329..a171fc16d1d 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 @@ protected String resultByBlockHash(final JsonRpcRequestContext request, final Ha 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 9c7cf5e7a85..917c09a3265 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 a5383f6680d..338a8783688 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.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 String getName() { 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 @@ protected Object resultByBlockNumber( 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 90e7a6a1edc..5d8b0085226 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 a9916099eac..4e26f8ee989 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.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 @@ protected BlockParameterOrBlockHash blockParameterOrBlockHash( 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 @@ protected Object pendingResult(final JsonRpcRequestContext request) { 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 @@ protected String resultByBlockHash(final JsonRpcRequestContext request, final Ha 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 a437cd86dc2..44e4cfe0d6c 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 9269bf965c0..f76b461ceff 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.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 @@ private BlockResult blockResult(final JsonRpcRequestContext requestContext) { 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 a6c5e6d89df..f7c9ecb0dd9 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.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 String getName() { 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 @@ protected BlockResult resultByBlockNumber( 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 9a5a3b225ba..02cd3c42425 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 ddd130542c6..8d935942add 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 @@ 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 String getName() { @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 7578b43a2ed..d6edccd2e7a 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 272014d3bc4..10582e7a1ce 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 c0763e77f6d..488f89b3a58 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 9474fec7bad..9002b2a0ddf 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 b51dc1f4fd3..8771343ecfc 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 7d7bd013bea..df593f9fbc3 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 @@ 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 static JsonCallParameter validateAndGetCallParams(final JsonRpcRequestCon 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 f895008e232..3761b8114af 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 5ec46e08cc4..adacf01e764 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.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 String getName() { 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 9882257143c..082283a8158 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 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 @@ private Set getTraceTypes( 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 2cbeb8ee7f8..10d4018bce2 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.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 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { 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 a3d6b2561f7..74bfec87c29 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 b346637ec25..e1c27aed798 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 a7205698752..71c8247784c 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 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 a8b3bbc46de..202d2ddbbbc 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.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 String getName() { 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 @@ protected ArrayNode resultByBlockNumber( 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 b79b9620e8d..be694236811 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 8dc38135c60..81c366926a6 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .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 b70ad760519..e34a462800a 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 7df76973ac9..11ec3d04c59 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 a6f94ac00e0..d95b532e77a 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { 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 02ccf5d2311..78b96796cbd 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 624d9bebddc..2666888ed63 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) () -> { 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 67b86575336..924e8ac989c 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 0e6b62d320f..facbd026d4e 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { 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 ec5d5bf6045..2d21a7282ae 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { 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 JsonRpcResponse syncResponse(final JsonRpcRequestContext request) { 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 e55cfb1506e..c4bca218031 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.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 JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext) 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 f1b949ad639..cd1b033dc47 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 d6676a60740..f30db35e77e 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } 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 5b9bc581dbe..51395e24f77 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { .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 59c18b80dbb..733ed3a8f3c 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 9c217b0c23c..b1bf4338f77 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 f3407ba10d6..32459b3b4cb 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 2aec3b6f955..5f8374a884e 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 a39acd5e9cd..ac7bffdf578 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 862b694f4f8..16e3bc234ac 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 a8b5fb7dc8a..22fb511ef4b 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 T required(final Object[] params, final int index, final Class par * @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 Optional optional( 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 Optional optional( 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 Optional> optionalList( 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 bbd7189ffa3..4ef7e0aa1c3 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 4436c33b502..ea6a5894a33 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.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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 c1e122578ab..eb41a1dad4e 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.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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 12c496b639d..e96a08eb7d4 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 e09d5966cf5..5d9edc63b9d 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.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 String getName() { 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 @@ protected Object resultByBlockNumber( 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 @@ private JsonCallParameter validateAndGetCallParams(final JsonRpcRequestContext r 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 ae35506298f..568125a2762 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 9ee5d57b3b4..dc0fc90f661 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.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 String getName() { 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 @@ protected Object resultByBlockNumber( 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 5c6f929c5c2..61b7791b3c0 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 39003358ede..aac4df3d2c9 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 8f0e8290842..7e823232237 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 5d9498f3bd4..7042d357f12 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.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 String getName() { 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 @@ protected String resultByBlockNumber( 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 @@ protected String resultByBlockNumber( 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 31bfc52c804..9f231f41c06 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 d0c75da33fb..6947ea5e546 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 0629b2d55d4..8779181599e 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 2cbcc655359..d8757dc2fbd 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 a1844841f00..287793ddc01 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 e73b0c141c6..49fc11f4b82 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.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 String getName() { @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 JsonRpcResponse response(final JsonRpcRequestContext request) { 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 b1802b07eb7..07d663bef55 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 @@ 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 String getName() { @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 e6cf056989d..0a66d1aa73b 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 7235a81987a..8bc35798495 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 @@ 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 SubscribeRequest mapSubscribeRequest(final JsonRpcRequestContext jsonRpcR 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 @@ private boolean includeTransactions(final WebSocketRpcRequest webSocketRpcReques 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 @@ private SubscribeRequest parseLogsRequest(final WebSocketRpcRequest request) { 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 UnsubscribeRequest mapUnsubscribeRequest(final JsonRpcRequestContext json 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 PrivateSubscribeRequest mapPrivateSubscribeRequest( 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 PrivateSubscribeRequest mapPrivateSubscribeRequest( 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 PrivateSubscribeRequest mapPrivateSubscribeRequest( 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 PrivateUnsubscribeRequest mapPrivateUnsubscribeRequest( 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 PrivateUnsubscribeRequest mapPrivateUnsubscribeRequest( 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 9cc6947b260..1eef04fb93a 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 void shouldReturnsErrorIfInvalidPredicate() { 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 void shouldReturnsErrorIfInvalidNumberOfPredicate() { 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 void shouldReturnsErrorIfInvalidPredicateUsedForFromField() { 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 void shouldReturnsErrorIfInvalidPredicateUsedForToField() { 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 4de9f8bb56e..9c5067f7a83 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.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 void shouldReturnPayloadId() { } @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 e4fd7bcff27..398d72d6653 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 516dc2f55f1..580b107a8b5 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 7907cee3f78..80a4872442d 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.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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 d9cfafbaeab..717cf41b459 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 d5adb36a243..d9b847af425 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 @@ 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 JsonRpcResponse response(final JsonRpcRequestContext requestContext) { 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 308d15f6f11..4311647948d 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.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 @@ private void handleMiningSubmit(final JsonRpcRequest message, final Consumer Date: Wed, 21 Aug 2024 02:29:50 +1000 Subject: [PATCH 101/124] update error message in test files (#7493) Signed-off-by: Sally MacFarlane Signed-off-by: gconnect --- .../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 ac5947c79be..ec5e2251791 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 41718648049..0fe0a15dfc8 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 c1425294cd2175ab23bb58af648dcbdfbbbeba82 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 21 Aug 2024 01:02:53 +0200 Subject: [PATCH 102/124] Update parameterized acceptance tests so they enumerate with --dry-run (#7498) Signed-off-by: Fabio Di Fabio Signed-off-by: gconnect --- .../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 cac4deb9d9b..4072c6f1bc1 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.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 @@ protected void waitForBlockHeight(final Node node, final long blockchainHeight) 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 92d9273e8f8..0cf24b57364 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 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 @@ protected void waitForBlockHeight(final Node node, final long blockchainHeight) 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 d88b1ed8b55..12907491763 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.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 @@ public static Stream testCasesFromPath(final String testCasesPath) 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 bdf21fc3877599242c57f8761c058c710ba2e860 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Wed, 21 Aug 2024 01:24:46 +0200 Subject: [PATCH 103/124] 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 Signed-off-by: gconnect --- .../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 0913fd227f3..a2ffc9b36da 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 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 void verify(final Node node) { 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 001406cb781..c6621960929 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 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.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.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 void startNode(final BesuNode node) { 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 void startNode(final BesuNode node) { .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 void startNode(final BesuNode node) { .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 void startNode(final BesuNode node) { .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 void startConsoleCapture() { 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 d54bf908726..520cd7d5741 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 @@ private PrivacyStorageProvider createKeyValueStorageProvider( 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 39cc5ad26fc..8fbd0d3d625 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 void setUp() throws Exception { 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 7eef4a216c2..286ca7a30fc 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 6bb3fb117c1..ddb75fcdedc 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 BesuController build() { 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 f10ebcce474..1f014ee0610 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.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 e43bf1c054e..eda202f6d4d 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.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 5d7df73b2ef..dcfe29146e7 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.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 5605fe49b5f..c3905c304bc 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.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 dd5d822ccc3..6629da690e8 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.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 46af0a6ea54..1e1f94fb324 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.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 c7049c9aa0a..8595a3c030b 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.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 8ec00e81703..54cce205a36 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.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 a246d18d2ff..00000000000 --- 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 6298b70a953..ceb0be40fe6 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.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.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.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.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 void setUp() throws IOException { .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 void privacyGroupHeadIsTracked() { // 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 void reorgToChainAtEqualHeight() { // 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 void reorgToChainAtEqualHeight() { 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 void reorgToLongerChain() { } @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 @@ private BlockDataGenerator.BlockOptions getBlockOptions( .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 4d488ced3bc..dc5b7003c84 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 @@ 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.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 @@ private PrecompiledContract getPrecompile( 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 5fefc7ef224..5b2a56078f5 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.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 @@ private BesuController getController( .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 bbc7dea1abb..05057f15c83 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 @@ 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 @@ private static BesuController createController(final @TempDir Path dataDir) thro .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 7b1a4bc7d2c..73015afd005 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 @@ 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 @@ protected BesuController createController(final GenesisConfigFile genesisConfigF .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 7d4fabb2225..e37b8a5fd08 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 @@ 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 void blockImport() throws IOException { .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 void blockImportRejectsBadPow() throws IOException { .gasLimitCalculator(GasLimitCalculator.constant()) .evmConfiguration(EvmConfiguration.DEFAULT) .networkConfiguration(NetworkingConfiguration.create()) - .besuComponent(mock(BesuComponent.class)) .build(); assertThatThrownBy( @@ -144,7 +140,6 @@ public void blockImportCanSkipPow() throws IOException { .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 20f9c1bf497..00000000000 --- 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 ae82b8b9288..00000000000 --- 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 743b4ee8de9..00000000000 --- 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 e7807e3d759..00000000000 --- 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 0b8fcf744ff..00000000000 --- 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 13cafe1ab45..00000000000 --- 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 c7caf62ec2a..731fd2ac568 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.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 void setup() throws JsonProcessingException { .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 aa79b944a11..82f98ba8266 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.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 void setup() throws JsonProcessingException { .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 c788f417103..0e4948ddd5c 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.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 @@ MergeBesuControllerBuilder visitWithMockConfigs(final MergeBesuControllerBuilder .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 e087edd4312..e1d158f3fce 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 Builder ipAddress(final String ip) { 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 Builder ipAddress( 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 b796ba754374790d03d72f768b8a6a40eb87edd1 Mon Sep 17 00:00:00 2001 From: Sally MacFarlane Date: Wed, 21 Aug 2024 09:50:07 +1000 Subject: [PATCH 104/124] 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 Signed-off-by: gconnect --- .../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 77f0dcf1a3f..4c6283b5959 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1663,15 +1663,17 @@ private void validateChainDataPruningParams() { } 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 33e74be18b0..4bac8cdcf1c 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -172,6 +172,60 @@ public void tearDown() { 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 731fd2ac568..f9e671f522d 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 void setup() throws JsonProcessingException { 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 82f98ba8266..39904df798d 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 void setup() throws JsonProcessingException { "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 0e4948ddd5c..544b6330152 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 void setup() { 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 bd1e117773b..453c38dac20 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 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 static GenesisConfigFile fromConfig(final ObjectNode config) { } /** - * 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 9f014b7d4d2..3e6b488b9bd 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 @@ void shouldGetBaseFeeExplicitlyAtGenesis() { @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 @@ void assertMainnetTerminalTotalDifficulty() { 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 @@ void testOverridePresent() { 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 @@ void testOverrideNull() { 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 @@ void testOverrideCaseInsensitivity() { // 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 @@ void testOverrideEmptyString() { 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 @@ void testConstantinopleFixShouldNotBeSupportedAlongPetersburg() { 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 00733de1f8e..cfb56d1ebc1 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 static Stream getTestParametersForConfig() throws IOException "/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 ba787460b491b8e992b6b6ee7130a17f3f90ff72 Mon Sep 17 00:00:00 2001 From: Simon Dudley Date: Wed, 21 Aug 2024 16:27:21 +1000 Subject: [PATCH 105/124] Add new lodestar bootnode for holesky (#7500) Signed-off-by: Simon Dudley Signed-off-by: gconnect --- 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 f04fcfb345f..82a60615a5b 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 6ae6942a8cf..d91971b3515 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 87119fec5ed537a04d33e3b061cb1700d4e3f97f Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Wed, 21 Aug 2024 08:40:17 +0100 Subject: [PATCH 106/124] For test node runners use provided data storage config (#7495) Signed-off-by: Matthew Whitehead Signed-off-by: gconnect --- .../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 37906761d1a..c6696b15a22 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.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 void startNode(final BesuNode node) { .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 c6621960929..f28a1d8876e 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.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 void startNode(final BesuNode node) { .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 55cbb16eb23493b4f2969773189a1bb03b15c6e9 Mon Sep 17 00:00:00 2001 From: Matt Whitehead Date: Wed, 21 Aug 2024 09:42:52 +0100 Subject: [PATCH 107/124] 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 Signed-off-by: gconnect --- .../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 ed4a28422dd..efbf91246b5 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.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 BesuNode createIbft2Node(final String name, final String genesisFile) thr .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 BesuNode createIbft2Node(final String name, final boolean fixedPort) thro 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 BesuNode createIbft2Node(final String name, final boolean fixedPort) thro .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 BesuNode createQbftNodeWithTLSPKCS11(final String name) throws IOExceptio 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 BesuNode createQbftNode(final String name, final boolean fixedPort) throw .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 15872070d00..2351f740bfb 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 static Stream getFactories() { @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 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 9861a7dab65..878e503ba39 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 void shouldBeStableDuringLongTest( // 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 a1051a69696002809229ab8ec24c4c1e40c91ed0 Mon Sep 17 00:00:00 2001 From: gconnect Date: Fri, 23 Aug 2024 06:30:14 +0100 Subject: [PATCH 108/124] Ran spotlessApply Signed-off-by: gconnect --- .../hyperledger/besu/util/GenerateEphemeryGenesisFile.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java b/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java index d6b2b62959b..231adb603fc 100644 --- a/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java +++ b/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java @@ -78,8 +78,8 @@ public void generate() throws IOException { if (currentTimestamp > (genesisTimestamp + periodInSeconds)) { - GenesisConfigFile.fromResource( - Optional.ofNullable(network).orElse(EPHEMERY).getGenesisFile()); + GenesisConfigFile.fromResource( + Optional.ofNullable(network).orElse(EPHEMERY).getGenesisFile()); Path ephemeryGenesisfilePath = Path.of(EPHEMERY.getGenesisFile()); try { ObjectMapper objectMapper = new ObjectMapper(); From 3cf88345596fffe202dfa09ffdd66e9634b9bec1 Mon Sep 17 00:00:00 2001 From: gconnect Date: Mon, 26 Aug 2024 12:41:39 +0100 Subject: [PATCH 109/124] Rename GenerateEphemeryGenesisFile to EphemeryGenesisFile Signed-off-by: gconnect --- .../org/hyperledger/besu/cli/BesuCommand.java | 7 ++++--- ...nesisFile.java => EphemeryGenesisFile.java} | 4 ++-- ...eTest.java => EphemeryGenesisFileTest.java} | 18 +++++++++--------- 3 files changed, 15 insertions(+), 14 deletions(-) rename besu/src/main/java/org/hyperledger/besu/util/{GenerateEphemeryGenesisFile.java => EphemeryGenesisFile.java} (97%) rename besu/src/test/java/org/hyperledger/besu/util/{GenerateEphemeryGenesisFileTest.java => EphemeryGenesisFileTest.java} (93%) 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 4c6283b5959..9e11bee73ee 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -197,6 +197,7 @@ import org.hyperledger.besu.services.TransactionSelectionServiceImpl; import org.hyperledger.besu.services.TransactionSimulationServiceImpl; import org.hyperledger.besu.services.kvstore.InMemoryStoragePlugin; +import org.hyperledger.besu.util.EphemeryGenesisFile; import org.hyperledger.besu.util.GenerateEphemeryGenesisFile; import org.hyperledger.besu.util.InvalidConfigurationException; import org.hyperledger.besu.util.LogConfigurator; @@ -1093,11 +1094,11 @@ public void run() { logger.warn(NetworkDeprecationMessage.generate(network)); } if (network == EPHEMERY) { - GenerateEphemeryGenesisFile generateEphemeryGenesisFile = - new GenerateEphemeryGenesisFile( + EphemeryGenesisFile ephemeryGenesisFile = + new EphemeryGenesisFile( network, readGenesisConfigFile(), readGenesisConfigOptions()); try { - generateEphemeryGenesisFile.generate(); + ephemeryGenesisFile.generate(); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java similarity index 97% rename from besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java rename to besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java index 231adb603fc..fca88dad7ae 100644 --- a/besu/src/main/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFile.java +++ b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java @@ -34,7 +34,7 @@ * The Generate Ephemery Genesis File. Checks for update based on the set period and update the * Ephemery genesis file */ -public class GenerateEphemeryGenesisFile { +public class EphemeryGenesisFile { private final NetworkName network; private final GenesisConfigFile genesisConfigFile; private final GenesisConfigOptions genesisConfigOptions; @@ -46,7 +46,7 @@ public class GenerateEphemeryGenesisFile { * @param genesisConfigFile the Genesis Config File * @param genesisConfigOptions the Genesis Config Options */ - public GenerateEphemeryGenesisFile( + public EphemeryGenesisFile( final NetworkName network, final GenesisConfigFile genesisConfigFile, final GenesisConfigOptions genesisConfigOptions) { diff --git a/besu/src/test/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFileTest.java b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java similarity index 93% rename from besu/src/test/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFileTest.java rename to besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java index f621d302567..959b3f0912f 100644 --- a/besu/src/test/java/org/hyperledger/besu/util/GenerateEphemeryGenesisFileTest.java +++ b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java @@ -45,13 +45,13 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -public class GenerateEphemeryGenesisFileTest { +public class EphemeryGenesisFileTest { private static ObjectMapper objectMapper; private static Path tempJsonFile; private GenesisConfigFile genesisConfigFile; private GenesisConfigOptions genesisConfigOptions; private NetworkName network; - GenerateEphemeryGenesisFile generateEphemeryGenesisFile; + private EphemeryGenesisFile ephemeryGenesisFile; private static final int GENESIS_CONFIG_TEST_CHAINID = 39438135; private static final long GENESIS_TEST_TIMESTAMP = 1609459200; private static final long CURRENT_TIMESTAMP = 1512041200; @@ -78,8 +78,8 @@ void setUp() throws IOException { network = mock(NetworkName.class); genesisConfigFile = mock(GenesisConfigFile.class); genesisConfigOptions = mock(GenesisConfigOptions.class); - generateEphemeryGenesisFile = - new GenerateEphemeryGenesisFile(network, genesisConfigFile, genesisConfigOptions); + ephemeryGenesisFile = + new EphemeryGenesisFile(network, genesisConfigFile, genesisConfigOptions); tempJsonFile = Files.createTempFile("temp-ephemery", ".json"); } @@ -175,7 +175,7 @@ public void testGenerateWhenChainIdAndTimestampIsPresent() throws IOException { when(genesisConfigFile.getTimestamp()).thenReturn(GENESIS_TEST_TIMESTAMP); when(genesisConfigOptions.getChainId()) .thenReturn(Optional.of(BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID))); - generateEphemeryGenesisFile.generate(); + ephemeryGenesisFile.generate(); verify(network).getGenesisFile(); verify(genesisConfigFile).getTimestamp(); verify(genesisConfigOptions).getChainId(); @@ -183,16 +183,16 @@ public void testGenerateWhenChainIdAndTimestampIsPresent() throws IOException { @Test public void testGenerateThrowIOException() throws IOException { - GenerateEphemeryGenesisFile spyGenerateEphemeryGenesisFile = spy(generateEphemeryGenesisFile); + EphemeryGenesisFile spyEphemeryGenesisFile = spy(ephemeryGenesisFile); doThrow(new IOException("Unable to update ephemery genesis file.")) - .when(spyGenerateEphemeryGenesisFile) + .when(spyEphemeryGenesisFile) .generate(); - assertThatThrownBy(spyGenerateEphemeryGenesisFile::generate) + assertThatThrownBy(spyEphemeryGenesisFile::generate) .isInstanceOf(IOException.class) .hasMessage("Unable to update ephemery genesis file."); - verify(spyGenerateEphemeryGenesisFile).generate(); + verify(spyEphemeryGenesisFile).generate(); } public Map createGenesisFile( From aad58e08ca28779cab5df0a34a6a341777df997d Mon Sep 17 00:00:00 2001 From: gconnect Date: Mon, 26 Aug 2024 13:32:17 +0100 Subject: [PATCH 110/124] Made changes based on requested changes. Update the conditional statement in the generate method and add extra param to the setNetworkId Signed-off-by: gconnect --- .../org/hyperledger/besu/cli/BesuCommand.java | 4 +--- .../besu/cli/config/NetworkName.java | 17 ++++++++++++----- .../besu/util/EphemeryGenesisFile.java | 18 ++++++++++-------- .../besu/util/EphemeryGenesisFileTest.java | 5 ++--- 4 files changed, 25 insertions(+), 19 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 9e11bee73ee..12dccae0392 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -198,7 +198,6 @@ import org.hyperledger.besu.services.TransactionSimulationServiceImpl; import org.hyperledger.besu.services.kvstore.InMemoryStoragePlugin; import org.hyperledger.besu.util.EphemeryGenesisFile; -import org.hyperledger.besu.util.GenerateEphemeryGenesisFile; import org.hyperledger.besu.util.InvalidConfigurationException; import org.hyperledger.besu.util.LogConfigurator; import org.hyperledger.besu.util.NetworkUtility; @@ -1095,8 +1094,7 @@ public void run() { } if (network == EPHEMERY) { EphemeryGenesisFile ephemeryGenesisFile = - new EphemeryGenesisFile( - network, readGenesisConfigFile(), readGenesisConfigOptions()); + new EphemeryGenesisFile(network, readGenesisConfigFile(), readGenesisConfigOptions()); try { ephemeryGenesisFile.generate(); } catch (IOException e) { diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java index dc464054707..8fda0f01724 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java @@ -31,7 +31,10 @@ public enum NetworkName { /** LUKSO mainnet network name. */ LUKSO("/lukso.json", BigInteger.valueOf(42)), - /** EPHEMERY network name. */ + /** + * EPHEMERY network name. The networkId is the default networkId that will be used to make update + * to the most recent networkId + */ EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135)), /** Dev network name. */ @@ -81,11 +84,15 @@ public BigInteger getNetworkId() { } /** - * Sets network id. This method is called only by the Ephemery network. It is required to update - * the networkid. + * This method is called only by the Ephemery network. It is required to update the networkid. + * + * @param networkId Sets network id . + * @param name Sets network name . */ - public void setNetworkId(final BigInteger networkId) { - this.networkId = networkId; + public void setNetworkId(final BigInteger networkId, final NetworkName name) { + if (name == EPHEMERY) { + this.networkId = networkId; + } } /** diff --git a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java index fca88dad7ae..5a65d8f2901 100644 --- a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java +++ b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java @@ -38,6 +38,8 @@ public class EphemeryGenesisFile { private final NetworkName network; private final GenesisConfigFile genesisConfigFile; private final GenesisConfigOptions genesisConfigOptions; + private static final int PERIOD = 28; + private static final long PERIOD_IN_SECONDS = (PERIOD * 24 * 60 * 60); /** * Instantiates a new Generate Ephemery genesis file. @@ -56,27 +58,27 @@ public EphemeryGenesisFile( } public void generate() throws IOException { - if (EPHEMERY.getGenesisFile() != null - || genesisConfigOptions != null - || genesisConfigFile != null) { + if (EPHEMERY.getGenesisFile() == null + || genesisConfigOptions == null + || genesisConfigFile == null) { + throw new IOException(); + } else { - final int PERIOD = 28; long genesisTimestamp = genesisConfigFile.getTimestamp(); Optional genesisChainId = genesisConfigOptions.getChainId(); - long periodInSeconds = (PERIOD * 24 * 60 * 60); long currentTimestamp = Instant.now().getEpochSecond(); long periodsSinceGenesis = ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) / PERIOD; - long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * periodInSeconds); + long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * PERIOD_IN_SECONDS); BigInteger updatedChainId = genesisChainId .orElseThrow(() -> new IllegalStateException("ChainId not present")) .add(BigInteger.valueOf(periodsSinceGenesis)); - EPHEMERY.setNetworkId(updatedChainId); + EPHEMERY.setNetworkId(updatedChainId, EPHEMERY); - if (currentTimestamp > (genesisTimestamp + periodInSeconds)) { + if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) { GenesisConfigFile.fromResource( Optional.ofNullable(network).orElse(EPHEMERY).getGenesisFile()); diff --git a/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java index 959b3f0912f..43528ecb004 100644 --- a/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java +++ b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java @@ -78,8 +78,7 @@ void setUp() throws IOException { network = mock(NetworkName.class); genesisConfigFile = mock(GenesisConfigFile.class); genesisConfigOptions = mock(GenesisConfigOptions.class); - ephemeryGenesisFile = - new EphemeryGenesisFile(network, genesisConfigFile, genesisConfigOptions); + ephemeryGenesisFile = new EphemeryGenesisFile(network, genesisConfigFile, genesisConfigOptions); tempJsonFile = Files.createTempFile("temp-ephemery", ".json"); } @@ -149,7 +148,7 @@ public void testGenerateWhenSuccessful() throws IOException { long expectedGenesisTimestamp = GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); - EPHEMERY.setNetworkId(expectedChainId); + EPHEMERY.setNetworkId(expectedChainId, EPHEMERY); configNode.put("chainId", expectedChainId); rootNode.put("timestamp", String.valueOf(expectedGenesisTimestamp)); From 01a61586133791de26455fc0137a7004843c7fe9 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Wed, 21 Aug 2024 13:01:35 -0700 Subject: [PATCH 111/124] EOF Differential Layout Fuzzer (#7488) Differential EOF Layout Fuzzer guided by Besu's layout parser. Signed-off-by: Danno Ferrin Signed-off-by: gconnect --- 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 7d2293b61e3..6a4f279666a 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 4c041198646..a3fff8e5dc3 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.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 String considerCode(final String hexCode) { ((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 dd7133f862e..d6b7359413c 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 @@ void testSingleValidViaInput() { 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 @@ void testMultipleViaInput() { 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 @@ void testSingleValidViaCli() { 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 @@ void testMultipleViaCli() { 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 @@ void testCliEclipsesInput() { 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 @@ void testInteriorCommentsSkipped() { 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 @@ void testBlankLinesAndCommentsSkipped() { 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 00000000000..9207cd65e02 --- /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 79658155591..fedeaa1bc05 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 061d8f0940c..439c69195a2 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 42934b612d0..354642f1ad7 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 static void executeTest(final GeneralStateTestCaseEipSpec spec) { .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 2a71fb70cd1..a289c665d2d 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 void tracePostExecution( } 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 46029c87c87..49c1e7f00c4 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 57f2acae37d..e0baf3bb46f 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 09a8d20d4c6..322383b32ca 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 00000000000..8f436d70117 --- /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 00000000000..1c967981559 --- /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 00000000000..6cde7588045 --- /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 00000000000..22165b5ffe8 --- /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 00000000000..efe84296cf0 --- /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 00000000000..e5505239ab7 --- /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 00000000000..e4ebb68cc88 --- /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 00000000000..802a6011aaf --- /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 00000000000..a59cd9326ff --- /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 00000000000..6a184dd90e9 --- /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 00000000000..59d8b83fbc7 --- /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 00000000000..2ce40892ef2 --- /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 608de7342957733d99ba08257ac106d2b5c4dc1e 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 112/124] 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 Signed-off-by: gconnect --- 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 82a60615a5b..1cd3f0126bd 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 89e6e4a2ae7..b5c74245ce4 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 @@ private void addLabelledObservation( @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 6e41fc9c1bf..d4830cb85a7 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 @@ 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.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 void shouldNestObservationsByLabel() { 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 aa13cdad73c593fbe2c0ab12b9b1bb4c114ec9c4 Mon Sep 17 00:00:00 2001 From: shubham kesri Date: Fri, 23 Aug 2024 06:12:12 +0530 Subject: [PATCH 113/124] Fixed | Initialising the encodedPubKey with empty String in case userInfo is null (#7508) Signed-off-by: kesrishubham2510 Co-authored-by: Sally MacFarlane Signed-off-by: gconnect --- 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 1cd3f0126bd..b9fccf29c48 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 bb85a3612f3..cd439eea063 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 @@ class ENRTreeLink implements 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 c0d237d08233ac6e9b71c2504bb41e48103939fe Mon Sep 17 00:00:00 2001 From: neowangreal Date: Fri, 23 Aug 2024 07:45:16 +0630 Subject: [PATCH 114/124] update link (#7506) Signed-off-by: Neo Co-authored-by: Sally MacFarlane Signed-off-by: gconnect --- 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 0acac729d4f..77deadd16aa 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 a8bc0d1c5acb12593464f9a8442c2393b8399cf1 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Fri, 23 Aug 2024 16:35:18 -0700 Subject: [PATCH 115/124] 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 Signed-off-by: gconnect --- .../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 898ede5d0d4..2e15e2ab82f 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 SynchronizationServiceImpl( @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 8a79c6d5acdc4d73d16c6c77fe7575cb5fa24906 Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Sun, 25 Aug 2024 22:33:05 -0600 Subject: [PATCH 116/124] 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 Signed-off-by: gconnect --- 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 b9fccf29c48..8c31d55fb7d 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 73eaddb7cad..85ec84b4ade 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 boolean finalized() { 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 46d2f0847a3..42f99fafb69 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 void writeTo(final RLPOutput out) { 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 06ee9676200..f9d7c0db476 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 void run() { .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 void run() { 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 static void dumpWorldState(final MutableWorldState worldState, final Prin 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 static void dumpWorldState(final MutableWorldState worldState, final Prin .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 6eae387a647..8512b5537e0 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.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.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 @@ static GenesisFileModule createGenesisModule() { 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 e36668f47c1..0ce7bf98f58 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.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 @@ ProtocolSchedule provideProtocolSchedule( } } - 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 c3b47b0b12ffe42e416312fff066adf09c3369dd Mon Sep 17 00:00:00 2001 From: Danno Ferrin Date: Sun, 25 Aug 2024 22:56:54 -0600 Subject: [PATCH 117/124] Fix fuzzing dependencies (#7519) The fuzzAll task depended on targets that didn't exist. Signed-off-by: Danno Ferrin Co-authored-by: Sally MacFarlane Signed-off-by: gconnect --- testfuzz/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testfuzz/build.gradle b/testfuzz/build.gradle index 1c967981559..e55cbe5983a 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 2de736becc3f34b8c61fab8d8b833dd41b00feaf Mon Sep 17 00:00:00 2001 From: Chaminda Divitotawela Date: Mon, 26 Aug 2024 16:19:30 +1000 Subject: [PATCH 118/124] 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 Signed-off-by: gconnect --- .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 721c26edbdd..413d68933fd 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 ef55bedc30b6c027f464acf53f7b00908c0f02f6 Mon Sep 17 00:00:00 2001 From: gconnect Date: Mon, 26 Aug 2024 13:46:32 +0100 Subject: [PATCH 119/124] Format the NetworkName file and update the Ephemery comment Signed-off-by: gconnect --- .../besu/cli/config/NetworkName.java | 212 ++++++++++-------- 1 file changed, 116 insertions(+), 96 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java index 8fda0f01724..9650d834337 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java @@ -20,114 +20,134 @@ import org.apache.commons.lang3.StringUtils; -/** The enum Network name. */ +/** + * The enum Network name. + */ public enum NetworkName { - /** Mainnet network name. */ - MAINNET("/mainnet.json", BigInteger.valueOf(1)), - /** Sepolia network name. */ - SEPOLIA("/sepolia.json", BigInteger.valueOf(11155111)), - /** Holešky network name. */ - HOLESKY("/holesky.json", BigInteger.valueOf(17000)), - /** LUKSO mainnet network name. */ - LUKSO("/lukso.json", BigInteger.valueOf(42)), + /** + * Mainnet network name. + */ + MAINNET("/mainnet.json", BigInteger.valueOf(1)), + /** + * Sepolia network name. + */ + SEPOLIA("/sepolia.json", BigInteger.valueOf(11155111)), + /** + * Holešky network name. + */ + HOLESKY("/holesky.json", BigInteger.valueOf(17000)), + /** + * LUKSO mainnet network name. + */ + LUKSO("/lukso.json", BigInteger.valueOf(42)), - /** - * EPHEMERY network name. The networkId is the default networkId that will be used to make update - * to the most recent networkId - */ - EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135)), + /** + * EPHEMERY network name. The networkId is the default networkId that will be + * used to make update to the most recent networkId. + */ + EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135)), - /** Dev network name. */ - DEV("/dev.json", BigInteger.valueOf(2018), false), - /** Future EIPs network name. */ - FUTURE_EIPS("/future.json", BigInteger.valueOf(2022), false), - /** Experimental EIPs network name. */ - EXPERIMENTAL_EIPS("/experimental.json", BigInteger.valueOf(2023), false), - /** Classic network name. */ - CLASSIC("/classic.json", BigInteger.valueOf(1)), - /** Mordor network name. */ - MORDOR("/mordor.json", BigInteger.valueOf(7)); + /** + * Dev network name. + */ + DEV("/dev.json", BigInteger.valueOf(2018), false), + /** + * Future EIPs network name. + */ + FUTURE_EIPS("/future.json", BigInteger.valueOf(2022), false), + /** + * Experimental EIPs network name. + */ + EXPERIMENTAL_EIPS("/experimental.json", BigInteger.valueOf(2023), false), + /** + * Classic network name. + */ + CLASSIC("/classic.json", BigInteger.valueOf(1)), + /** + * Mordor network name. + */ + MORDOR("/mordor.json", BigInteger.valueOf(7)); - private final String genesisFile; - private BigInteger networkId; - private final boolean canSnapSync; - private final String deprecationDate; + private final String genesisFile; + private BigInteger networkId; + private final boolean canSnapSync; + private final String deprecationDate; - NetworkName(final String genesisFile, final BigInteger networkId) { - this(genesisFile, networkId, true); - } + NetworkName(final String genesisFile, final BigInteger networkId) { + this(genesisFile, networkId, true); + } - NetworkName(final String genesisFile, final BigInteger networkId, final boolean canSnapSync) { - this.genesisFile = genesisFile; - this.networkId = networkId; - this.canSnapSync = canSnapSync; - // no deprecations planned - this.deprecationDate = null; - } + NetworkName(final String genesisFile, final BigInteger networkId, final boolean canSnapSync) { + this.genesisFile = genesisFile; + this.networkId = networkId; + this.canSnapSync = canSnapSync; + // no deprecations planned + this.deprecationDate = null; + } - /** - * Gets genesis file. - * - * @return the genesis file - */ - public String getGenesisFile() { - return genesisFile; - } + /** + * Gets genesis file. + * + * @return the genesis file + */ + public String getGenesisFile() { + return genesisFile; + } - /** - * Gets network id. - * - * @return the network id - */ - public BigInteger getNetworkId() { - return networkId; - } + /** + * Gets network id. + * + * @return the network id + */ + public BigInteger getNetworkId() { + return networkId; + } - /** - * This method is called only by the Ephemery network. It is required to update the networkid. - * - * @param networkId Sets network id . - * @param name Sets network name . - */ - public void setNetworkId(final BigInteger networkId, final NetworkName name) { - if (name == EPHEMERY) { - this.networkId = networkId; + /** + * This method is called only by the Ephemery network. It is required to update the networkid. + * + * @param networkId Sets network id . + * @param name Sets network name . + */ + public void setNetworkId(final BigInteger networkId, final NetworkName name) { + if (name == EPHEMERY) { + this.networkId = networkId; + } } - } - /** - * Can SNAP sync boolean. - * - * @return the boolean - */ - public boolean canSnapSync() { - return canSnapSync; - } + /** + * Can SNAP sync boolean. + * + * @return the boolean + */ + public boolean canSnapSync() { + return canSnapSync; + } - /** - * Normalize string. - * - * @return the string - */ - public String normalize() { - return StringUtils.capitalize(name().toLowerCase(Locale.ROOT)); - } + /** + * Normalize string. + * + * @return the string + */ + public String normalize() { + return StringUtils.capitalize(name().toLowerCase(Locale.ROOT)); + } - /** - * Is deprecated boolean. - * - * @return the boolean - */ - public boolean isDeprecated() { - return deprecationDate != null; - } + /** + * Is deprecated boolean. + * + * @return the boolean + */ + public boolean isDeprecated() { + return deprecationDate != null; + } - /** - * Gets deprecation date. - * - * @return the deprecation date - */ - public Optional getDeprecationDate() { - return Optional.ofNullable(deprecationDate); - } + /** + * Gets deprecation date. + * + * @return the deprecation date + */ + public Optional getDeprecationDate() { + return Optional.ofNullable(deprecationDate); + } } From 0a06caf39ab779c0785415ee3d27020fd4fc5aca Mon Sep 17 00:00:00 2001 From: gconnect Date: Wed, 28 Aug 2024 23:52:04 +0100 Subject: [PATCH 120/124] Use genesisConfig overrides in the EphemeryGenesisFile and update the test Signed-off-by: gconnect --- CHANGELOG.md | 1 + .../org/hyperledger/besu/cli/BesuCommand.java | 11 +- .../besu/cli/config/NetworkName.java | 212 ++++++++---------- .../besu/util/EphemeryGenesisFile.java | 79 +++---- .../hyperledger/besu/cli/BesuCommandTest.java | 2 +- .../besu/util/EphemeryGenesisFileTest.java | 48 ++-- 6 files changed, 149 insertions(+), 204 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c31d55fb7d..74eb964a031 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,7 @@ - `--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 network support for Ephemery Testnet [#7471](https://github.com/hyperledger/besu/pull/7471) ### 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 12dccae0392..afac6cc9fcb 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -866,6 +866,7 @@ static class PrivacyOptionGroup { private Collection staticNodes; private BesuController besuController; private BesuConfigurationImpl pluginCommonConfiguration; + private EphemeryGenesisFile ephemeryGenesisFile; private BesuComponent besuComponent; private final Supplier metricsSystem = @@ -1093,13 +1094,9 @@ public void run() { logger.warn(NetworkDeprecationMessage.generate(network)); } if (network == EPHEMERY) { - EphemeryGenesisFile ephemeryGenesisFile = - new EphemeryGenesisFile(network, readGenesisConfigFile(), readGenesisConfigOptions()); - try { - ephemeryGenesisFile.generate(); - } catch (IOException e) { - throw new RuntimeException(e); - } + ephemeryGenesisFile = + new EphemeryGenesisFile(readGenesisConfigFile(), readGenesisConfigOptions()); + ephemeryGenesisFile.updateGenesis(); } try { configureLogging(true); diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java index 9650d834337..9e7faf55b52 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java @@ -20,134 +20,114 @@ import org.apache.commons.lang3.StringUtils; -/** - * The enum Network name. - */ +/** The enum Network name. */ public enum NetworkName { - /** - * Mainnet network name. - */ - MAINNET("/mainnet.json", BigInteger.valueOf(1)), - /** - * Sepolia network name. - */ - SEPOLIA("/sepolia.json", BigInteger.valueOf(11155111)), - /** - * Holešky network name. - */ - HOLESKY("/holesky.json", BigInteger.valueOf(17000)), - /** - * LUKSO mainnet network name. - */ - LUKSO("/lukso.json", BigInteger.valueOf(42)), + /** Mainnet network name. */ + MAINNET("/mainnet.json", BigInteger.valueOf(1)), + /** Sepolia network name. */ + SEPOLIA("/sepolia.json", BigInteger.valueOf(11155111)), + /** Holešky network name. */ + HOLESKY("/holesky.json", BigInteger.valueOf(17000)), + /** LUKSO mainnet network name. */ + LUKSO("/lukso.json", BigInteger.valueOf(42)), - /** - * EPHEMERY network name. The networkId is the default networkId that will be - * used to make update to the most recent networkId. - */ - EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135)), + /** + * EPHEMERY network name. The networkId is the default networkId that will be used to make update + * to the most recent networkId. + */ + EPHEMERY("/ephemery.json", BigInteger.valueOf(39438135)), - /** - * Dev network name. - */ - DEV("/dev.json", BigInteger.valueOf(2018), false), - /** - * Future EIPs network name. - */ - FUTURE_EIPS("/future.json", BigInteger.valueOf(2022), false), - /** - * Experimental EIPs network name. - */ - EXPERIMENTAL_EIPS("/experimental.json", BigInteger.valueOf(2023), false), - /** - * Classic network name. - */ - CLASSIC("/classic.json", BigInteger.valueOf(1)), - /** - * Mordor network name. - */ - MORDOR("/mordor.json", BigInteger.valueOf(7)); + /** Dev network name. */ + DEV("/dev.json", BigInteger.valueOf(2018), false), + /** Future EIPs network name. */ + FUTURE_EIPS("/future.json", BigInteger.valueOf(2022), false), + /** Experimental EIPs network name. */ + EXPERIMENTAL_EIPS("/experimental.json", BigInteger.valueOf(2023), false), + /** Classic network name. */ + CLASSIC("/classic.json", BigInteger.valueOf(1)), + /** Mordor network name. */ + MORDOR("/mordor.json", BigInteger.valueOf(7)); - private final String genesisFile; - private BigInteger networkId; - private final boolean canSnapSync; - private final String deprecationDate; + private final String genesisFile; + private BigInteger networkId; + private final boolean canSnapSync; + private final String deprecationDate; - NetworkName(final String genesisFile, final BigInteger networkId) { - this(genesisFile, networkId, true); - } + NetworkName(final String genesisFile, final BigInteger networkId) { + this(genesisFile, networkId, true); + } - NetworkName(final String genesisFile, final BigInteger networkId, final boolean canSnapSync) { - this.genesisFile = genesisFile; - this.networkId = networkId; - this.canSnapSync = canSnapSync; - // no deprecations planned - this.deprecationDate = null; - } + NetworkName(final String genesisFile, final BigInteger networkId, final boolean canSnapSync) { + this.genesisFile = genesisFile; + this.networkId = networkId; + this.canSnapSync = canSnapSync; + // no deprecations planned + this.deprecationDate = null; + } - /** - * Gets genesis file. - * - * @return the genesis file - */ - public String getGenesisFile() { - return genesisFile; - } + /** + * Gets genesis file. + * + * @return the genesis file + */ + public String getGenesisFile() { + return genesisFile; + } - /** - * Gets network id. - * - * @return the network id - */ - public BigInteger getNetworkId() { - return networkId; - } + /** + * Gets network id. + * + * @return the network id + */ + public BigInteger getNetworkId() { + return networkId; + } - /** - * This method is called only by the Ephemery network. It is required to update the networkid. - * - * @param networkId Sets network id . - * @param name Sets network name . - */ - public void setNetworkId(final BigInteger networkId, final NetworkName name) { - if (name == EPHEMERY) { - this.networkId = networkId; - } + /** + * This method is called only by the Ephemery network. It is required to update the networkid. + * + * @param networkId Sets network id . + * @param name Sets network name . + */ + public void setNetworkId(final BigInteger networkId, final NetworkName name) { + if (name == EPHEMERY) { + this.networkId = networkId; } + } - /** - * Can SNAP sync boolean. - * - * @return the boolean - */ - public boolean canSnapSync() { - return canSnapSync; - } + /** + * Can SNAP sync boolean. + * + * @return the boolean + */ + public boolean canSnapSync() { + return canSnapSync; + } - /** - * Normalize string. - * - * @return the string - */ - public String normalize() { - return StringUtils.capitalize(name().toLowerCase(Locale.ROOT)); - } + /** + * Normalize string. + * + * @return the string + */ + public String normalize() { + return StringUtils.capitalize(name().toLowerCase(Locale.ROOT)); + } - /** - * Is deprecated boolean. - * - * @return the boolean - */ - public boolean isDeprecated() { - return deprecationDate != null; - } + /** + * Is deprecated boolean. + * + * @return the boolean + */ + public boolean isDeprecated() { + return deprecationDate != null; + } - /** - * Gets deprecation date. - * - * @return the deprecation date - */ - public Optional getDeprecationDate() { - return Optional.ofNullable(deprecationDate); - } + /** + * Gets deprecation date. + * + * @return the deprecation date + */ + public Optional getDeprecationDate() { + return Optional.ofNullable(deprecationDate); + } } diff --git a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java index 5a65d8f2901..a588c5d7b82 100644 --- a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java +++ b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java @@ -16,26 +16,22 @@ import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; -import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; import java.io.IOException; import java.math.BigInteger; -import java.nio.file.Path; import java.time.Instant; import java.time.temporal.ChronoUnit; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - /** * The Generate Ephemery Genesis File. Checks for update based on the set period and update the * Ephemery genesis file */ public class EphemeryGenesisFile { - private final NetworkName network; private final GenesisConfigFile genesisConfigFile; private final GenesisConfigOptions genesisConfigOptions; private static final int PERIOD = 28; @@ -44,61 +40,44 @@ public class EphemeryGenesisFile { /** * Instantiates a new Generate Ephemery genesis file. * - * @param network the Network * @param genesisConfigFile the Genesis Config File * @param genesisConfigOptions the Genesis Config Options */ public EphemeryGenesisFile( - final NetworkName network, - final GenesisConfigFile genesisConfigFile, - final GenesisConfigOptions genesisConfigOptions) { + final GenesisConfigFile genesisConfigFile, final GenesisConfigOptions genesisConfigOptions) { this.genesisConfigFile = genesisConfigFile; - this.network = network; this.genesisConfigOptions = genesisConfigOptions; } - public void generate() throws IOException { - if (EPHEMERY.getGenesisFile() == null - || genesisConfigOptions == null - || genesisConfigFile == null) { - throw new IOException(); - } else { - - long genesisTimestamp = genesisConfigFile.getTimestamp(); - Optional genesisChainId = genesisConfigOptions.getChainId(); - - long currentTimestamp = Instant.now().getEpochSecond(); - long periodsSinceGenesis = - ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) / PERIOD; - long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * PERIOD_IN_SECONDS); - BigInteger updatedChainId = - genesisChainId - .orElseThrow(() -> new IllegalStateException("ChainId not present")) - .add(BigInteger.valueOf(periodsSinceGenesis)); - - EPHEMERY.setNetworkId(updatedChainId, EPHEMERY); - - if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) { - - GenesisConfigFile.fromResource( - Optional.ofNullable(network).orElse(EPHEMERY).getGenesisFile()); - Path ephemeryGenesisfilePath = Path.of(EPHEMERY.getGenesisFile()); - try { - ObjectMapper objectMapper = new ObjectMapper(); - ObjectNode rootNode = - (ObjectNode) objectMapper.readTree(ephemeryGenesisfilePath.toFile()); - - ObjectNode configNode = (ObjectNode) rootNode.path("config"); - configNode.put("chainId", updatedChainId.toString()); - rootNode.put("timestamp", String.valueOf(updatedTimestamp)); + public void updateGenesis() { + try { + if (EPHEMERY.getGenesisFile() == null + || genesisConfigOptions == null + || genesisConfigFile == null) { + throw new IOException("Genesis file or config options are null"); + } else { + long genesisTimestamp = genesisConfigFile.getTimestamp(); + Optional genesisChainId = genesisConfigOptions.getChainId(); + long currentTimestamp = Instant.now().getEpochSecond(); + long periodsSinceGenesis = + ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) + / PERIOD; + long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * PERIOD_IN_SECONDS); + BigInteger updatedChainId = + genesisChainId + .orElseThrow(() -> new IllegalStateException("ChainId not present")) + .add(BigInteger.valueOf(periodsSinceGenesis)); - objectMapper - .writerWithDefaultPrettyPrinter() - .writeValue(ephemeryGenesisfilePath.toFile(), rootNode); - } catch (IOException e) { - throw new IOException("Unable to update ephemery genesis file. " + e); + if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) { + EPHEMERY.setNetworkId(updatedChainId, EPHEMERY); + Map overrides = new HashMap<>(); + overrides.put("chainId", String.valueOf(updatedChainId)); + overrides.put("timestamp", String.valueOf(updatedTimestamp)); + genesisConfigFile.withOverrides(overrides); } } + } catch (IOException e) { + throw new RuntimeException("Error updating genesis file: " + e.getMessage(), e); } } } 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 0dc96bf0334..fd68a6a3ff0 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -1392,7 +1392,7 @@ public void parsesInvalidWhenFullSyncAndBonsaiLimitTrieLogsExplicitlyTrue() { assertThat(commandErrorOutput.toString(UTF_8)) .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 public void parsesValidBonsaiHistoricalBlockLimitOption() { diff --git a/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java index 43528ecb004..33f78c424cb 100644 --- a/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java +++ b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java @@ -24,7 +24,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.hyperledger.besu.cli.config.NetworkName; import org.hyperledger.besu.config.GenesisConfigFile; import org.hyperledger.besu.config.GenesisConfigOptions; @@ -50,12 +49,11 @@ public class EphemeryGenesisFileTest { private static Path tempJsonFile; private GenesisConfigFile genesisConfigFile; private GenesisConfigOptions genesisConfigOptions; - private NetworkName network; private EphemeryGenesisFile ephemeryGenesisFile; private static final int GENESIS_CONFIG_TEST_CHAINID = 39438135; - private static final long GENESIS_TEST_TIMESTAMP = 1609459200; - private static final long CURRENT_TIMESTAMP = 1512041200; - private static final long CURRENT_TIMESTAMP_HIGHER = 1622041200; + private static final long GENESIS_TEST_TIMESTAMP = 1720119600; + private static final long CURRENT_TIMESTAMP = 1712041200; + private static final long CURRENT_TIMESTAMP_HIGHER = 1922041200; private static final long PERIOD_IN_SECONDS = 28 * 24 * 60 * 60; private static final long PERIOD_SINCE_GENESIS = 3; @@ -75,15 +73,14 @@ public class EphemeryGenesisFileTest { @BeforeEach void setUp() throws IOException { objectMapper = new ObjectMapper(); - network = mock(NetworkName.class); genesisConfigFile = mock(GenesisConfigFile.class); genesisConfigOptions = mock(GenesisConfigOptions.class); - ephemeryGenesisFile = new EphemeryGenesisFile(network, genesisConfigFile, genesisConfigOptions); + ephemeryGenesisFile = new EphemeryGenesisFile(genesisConfigFile, genesisConfigOptions); tempJsonFile = Files.createTempFile("temp-ephemery", ".json"); } @Test - public void testGenerateWhenChainIdIsAbsent() throws IOException { + public void testEphemeryWhenChainIdIsAbsent() throws IOException { Map node = createGenesisFile(tempJsonFile, INVALID_GENESIS_JSON_WITHOUT_CHAINID); ObjectNode configNode = node.get("configNode"); @@ -93,7 +90,7 @@ public void testGenerateWhenChainIdIsAbsent() throws IOException { } @Test - public void testGenerateWhenTimestampIsAbsent() throws IOException { + public void testEphemeryWhenTimestampIsAbsent() throws IOException { Map node = createGenesisFile(tempJsonFile, INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP); ObjectNode rootNode = node.get("rootNode"); @@ -103,7 +100,7 @@ public void testGenerateWhenTimestampIsAbsent() throws IOException { } @Test - public void testGenerateWhenGenesisJsonIsInvalid() throws IOException { + public void testEphemeryWhenGenesisJsonIsInvalid() throws IOException { Map node = createGenesisFile(tempJsonFile, INVALID_GENESIS_VALID_JSON); ObjectNode rootNode = node.get("rootNode"); ObjectNode configNode = node.get("configNode"); @@ -115,7 +112,7 @@ public void testGenerateWhenGenesisJsonIsInvalid() throws IOException { } @Test - public void testGenerateWhenGenesisJsonIsValid() throws IOException { + public void testEphemeryWhenGenesisJsonIsValid() throws IOException { Map node = createGenesisFile(tempJsonFile, VALID_GENESIS_JSON); ObjectNode rootNode = node.get("rootNode"); ObjectNode configNode = node.get("configNode"); @@ -127,7 +124,7 @@ public void testGenerateWhenGenesisJsonIsValid() throws IOException { } @Test - public void testGenerateNotYetDueForUpdate() throws IOException { + public void testEphemeryNotYetDueForUpdate() throws IOException { Map node = createGenesisFile(tempJsonFile, VALID_GENESIS_JSON); ObjectNode rootNode = node.get("rootNode"); assertThat(CURRENT_TIMESTAMP) @@ -137,7 +134,7 @@ public void testGenerateNotYetDueForUpdate() throws IOException { } @Test - public void testGenerateWhenSuccessful() throws IOException { + public void testEphemeryWhenSuccessful() throws IOException { Map node = createGenesisFile(tempJsonFile, VALID_GENESIS_JSON); ObjectNode rootNode = node.get("rootNode"); ObjectNode configNode = node.get("configNode"); @@ -153,8 +150,6 @@ public void testGenerateWhenSuccessful() throws IOException { configNode.put("chainId", expectedChainId); rootNode.put("timestamp", String.valueOf(expectedGenesisTimestamp)); - objectMapper.writerWithDefaultPrettyPrinter().writeValue(tempJsonFile.toFile(), rootNode); - assertThat(CURRENT_TIMESTAMP_HIGHER) .isGreaterThan(rootNode.get("timestamp").asLong() + PERIOD_IN_SECONDS); assertThat(tempJsonFile).exists(); @@ -164,34 +159,27 @@ public void testGenerateWhenSuccessful() throws IOException { } @Test - public void testGenerateWhenGenesisFilePathIsNull() throws IOException { - final Path tempJsonFile = Path.of("invalid-path"); - assertThat(tempJsonFile).doesNotExist(); - } - - @Test - public void testGenerateWhenChainIdAndTimestampIsPresent() throws IOException { + public void testEphemeryWhenChainIdAndTimestampIsPresent() { when(genesisConfigFile.getTimestamp()).thenReturn(GENESIS_TEST_TIMESTAMP); when(genesisConfigOptions.getChainId()) .thenReturn(Optional.of(BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID))); - ephemeryGenesisFile.generate(); - verify(network).getGenesisFile(); + ephemeryGenesisFile.updateGenesis(); verify(genesisConfigFile).getTimestamp(); verify(genesisConfigOptions).getChainId(); } @Test - public void testGenerateThrowIOException() throws IOException { + public void testEphemeryThrowIOException() { EphemeryGenesisFile spyEphemeryGenesisFile = spy(ephemeryGenesisFile); - doThrow(new IOException("Unable to update ephemery genesis file.")) + doThrow(new RuntimeException("Unable to update ephemery genesis file.")) .when(spyEphemeryGenesisFile) - .generate(); + .updateGenesis(); - assertThatThrownBy(spyEphemeryGenesisFile::generate) - .isInstanceOf(IOException.class) + assertThatThrownBy(spyEphemeryGenesisFile::updateGenesis) + .isInstanceOf(RuntimeException.class) .hasMessage("Unable to update ephemery genesis file."); - verify(spyEphemeryGenesisFile).generate(); + verify(spyEphemeryGenesisFile).updateGenesis(); } public Map createGenesisFile( From 16a3e76598976d811e73b658a2e782308c2991c4 Mon Sep 17 00:00:00 2001 From: gconnect Date: Fri, 30 Aug 2024 05:47:53 +0100 Subject: [PATCH 121/124] Update setNetworkId method, EphemeryGenesisFile and Update the test Signed-off-by: gconnect --- .../org/hyperledger/besu/cli/BesuCommand.java | 2 +- .../besu/cli/config/NetworkName.java | 5 +- .../besu/util/EphemeryGenesisFile.java | 38 ++--- .../besu/util/EphemeryGenesisFileTest.java | 145 ++++++++---------- 4 files changed, 87 insertions(+), 103 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 afac6cc9fcb..8cdaf9b68aa 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -1093,7 +1093,7 @@ public void run() { if (network != null && network.isDeprecated()) { logger.warn(NetworkDeprecationMessage.generate(network)); } - if (network == EPHEMERY) { + if (network.equals(EPHEMERY)) { ephemeryGenesisFile = new EphemeryGenesisFile(readGenesisConfigFile(), readGenesisConfigOptions()); ephemeryGenesisFile.updateGenesis(); diff --git a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java index 9e7faf55b52..27cb673bb7b 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/config/NetworkName.java @@ -87,10 +87,9 @@ public BigInteger getNetworkId() { * This method is called only by the Ephemery network. It is required to update the networkid. * * @param networkId Sets network id . - * @param name Sets network name . */ - public void setNetworkId(final BigInteger networkId, final NetworkName name) { - if (name == EPHEMERY) { + public void setNetworkId(final BigInteger networkId) { + if (this == EPHEMERY) { this.networkId = networkId; } } diff --git a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java index a588c5d7b82..9c34909c48b 100644 --- a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java +++ b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java @@ -55,26 +55,26 @@ public void updateGenesis() { || genesisConfigOptions == null || genesisConfigFile == null) { throw new IOException("Genesis file or config options are null"); - } else { - long genesisTimestamp = genesisConfigFile.getTimestamp(); - Optional genesisChainId = genesisConfigOptions.getChainId(); - long currentTimestamp = Instant.now().getEpochSecond(); - long periodsSinceGenesis = - ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) - / PERIOD; - long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * PERIOD_IN_SECONDS); - BigInteger updatedChainId = - genesisChainId - .orElseThrow(() -> new IllegalStateException("ChainId not present")) - .add(BigInteger.valueOf(periodsSinceGenesis)); + } + + long genesisTimestamp = genesisConfigFile.getTimestamp(); + Optional genesisChainId = genesisConfigOptions.getChainId(); + long currentTimestamp = Instant.now().getEpochSecond(); + long periodsSinceGenesis = + ChronoUnit.DAYS.between(Instant.ofEpochSecond(genesisTimestamp), Instant.now()) / PERIOD; + + long updatedTimestamp = genesisTimestamp + (periodsSinceGenesis * PERIOD_IN_SECONDS); + BigInteger updatedChainId = + genesisChainId + .orElseThrow(() -> new IllegalStateException("ChainId not present")) + .add(BigInteger.valueOf(periodsSinceGenesis)); - if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) { - EPHEMERY.setNetworkId(updatedChainId, EPHEMERY); - Map overrides = new HashMap<>(); - overrides.put("chainId", String.valueOf(updatedChainId)); - overrides.put("timestamp", String.valueOf(updatedTimestamp)); - genesisConfigFile.withOverrides(overrides); - } + if (currentTimestamp > (genesisTimestamp + PERIOD_IN_SECONDS)) { + EPHEMERY.setNetworkId(updatedChainId); + Map overrides = new HashMap<>(); + overrides.put("chainId", String.valueOf(updatedChainId)); + overrides.put("timestamp", String.valueOf(updatedTimestamp)); + genesisConfigFile.withOverrides(overrides); } } catch (IOException e) { throw new RuntimeException("Error updating genesis file: " + e.getMessage(), e); diff --git a/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java index 33f78c424cb..334e82ff090 100644 --- a/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java +++ b/besu/src/test/java/org/hyperledger/besu/util/EphemeryGenesisFileTest.java @@ -14,10 +14,10 @@ */ package org.hyperledger.besu.util; -import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import static org.hyperledger.besu.cli.config.NetworkName.EPHEMERY; +import static org.hyperledger.besu.config.GenesisConfigFile.fromConfig; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -29,15 +29,12 @@ import java.io.IOException; import java.math.BigInteger; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.TreeMap; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import io.vertx.core.json.JsonObject; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -45,8 +42,6 @@ @ExtendWith(MockitoExtension.class) public class EphemeryGenesisFileTest { - private static ObjectMapper objectMapper; - private static Path tempJsonFile; private GenesisConfigFile genesisConfigFile; private GenesisConfigOptions genesisConfigOptions; private EphemeryGenesisFile ephemeryGenesisFile; @@ -62,7 +57,7 @@ public class EphemeryGenesisFileTest { .put("config", (new JsonObject()).put("chainId", GENESIS_CONFIG_TEST_CHAINID)) .put("timestamp", GENESIS_TEST_TIMESTAMP); - private static final JsonObject INVALID_GENESIS_VALID_JSON = new JsonObject(); + private static final GenesisConfigFile INVALID_GENESIS_JSON = fromConfig("{}"); private static final JsonObject INVALID_GENESIS_JSON_WITHOUT_CHAINID = (new JsonObject()).put("timestamp", GENESIS_TEST_TIMESTAMP); @@ -72,72 +67,70 @@ public class EphemeryGenesisFileTest { @BeforeEach void setUp() throws IOException { - objectMapper = new ObjectMapper(); genesisConfigFile = mock(GenesisConfigFile.class); genesisConfigOptions = mock(GenesisConfigOptions.class); ephemeryGenesisFile = new EphemeryGenesisFile(genesisConfigFile, genesisConfigOptions); - tempJsonFile = Files.createTempFile("temp-ephemery", ".json"); } @Test - public void testEphemeryWhenChainIdIsAbsent() throws IOException { - Map node = - createGenesisFile(tempJsonFile, INVALID_GENESIS_JSON_WITHOUT_CHAINID); - ObjectNode configNode = node.get("configNode"); - assertThat(configNode.has("chainId")).isFalse(); - assertThat(configNode.get("chainId")).isNull(); - Files.delete(tempJsonFile); + public void testEphemeryWhenChainIdIsAbsent() { + final GenesisConfigFile config = + GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_CHAINID.toString()); + Optional chainId = config.getConfigOptions().getChainId(); + assertThat(chainId).isNotPresent(); } @Test - public void testEphemeryWhenTimestampIsAbsent() throws IOException { - Map node = - createGenesisFile(tempJsonFile, INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP); - ObjectNode rootNode = node.get("rootNode"); - assertThat(rootNode.has("timestamp")).isFalse(); - assertThat(rootNode.get("timestamp")).isNull(); - Files.delete(tempJsonFile); + public void testShouldDefaultTimestampToZero() { + final GenesisConfigFile config = + GenesisConfigFile.fromConfig(INVALID_GENESIS_JSON_WITHOUT_TIMESTAMP.toString()); + assertThat(config.getTimestamp()).isZero(); } @Test - public void testEphemeryWhenGenesisJsonIsInvalid() throws IOException { - Map node = createGenesisFile(tempJsonFile, INVALID_GENESIS_VALID_JSON); - ObjectNode rootNode = node.get("rootNode"); - ObjectNode configNode = node.get("configNode"); - assertThat(rootNode.has("timestamp")).isFalse(); - assertThat(configNode.has("chainId")).isFalse(); - assertThat(rootNode.get("timestamp")).isNull(); - assertThat(configNode.get("chainId")).isNull(); - Files.delete(tempJsonFile); + public void testEphemeryWhenGenesisJsonIsInvalid() { + Assertions.assertThatThrownBy(INVALID_GENESIS_JSON::getDifficulty) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Invalid genesis block configuration"); } @Test - public void testEphemeryWhenGenesisJsonIsValid() throws IOException { - Map node = createGenesisFile(tempJsonFile, VALID_GENESIS_JSON); - ObjectNode rootNode = node.get("rootNode"); - ObjectNode configNode = node.get("configNode"); - assertThat(rootNode.has("timestamp")).isTrue(); - assertThat(configNode.has("chainId")).isTrue(); - assertThat(rootNode.get("timestamp")).isNotNull(); - assertThat(configNode.get("chainId")).isNotNull(); - Files.delete(tempJsonFile); + public void testEphemeryWhenGenesisJsonIsValid() { + final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); + assertThat(String.valueOf(config.getTimestamp())).isNotNull(); + assertThat(String.valueOf(config.getTimestamp())).isNotEmpty(); + assertThat(String.valueOf(config.getConfigOptions().getChainId())).isNotNull(); + assertThat(String.valueOf(config.getConfigOptions().getChainId())).isNotEmpty(); } @Test - public void testEphemeryNotYetDueForUpdate() throws IOException { - Map node = createGenesisFile(tempJsonFile, VALID_GENESIS_JSON); - ObjectNode rootNode = node.get("rootNode"); - assertThat(CURRENT_TIMESTAMP) - .isLessThan(rootNode.get("timestamp").asLong() + PERIOD_IN_SECONDS); - objectMapper.writerWithDefaultPrettyPrinter().writeValue(tempJsonFile.toFile(), rootNode); - Files.delete(tempJsonFile); + public void testEphemeryNotYetDueForUpdate() { + final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); + assertThat(CURRENT_TIMESTAMP).isLessThan(config.getTimestamp() + PERIOD_IN_SECONDS); } @Test - public void testEphemeryWhenSuccessful() throws IOException { - Map node = createGenesisFile(tempJsonFile, VALID_GENESIS_JSON); - ObjectNode rootNode = node.get("rootNode"); - ObjectNode configNode = node.get("configNode"); + void testOverrideWithUpdatedChainIdAndTimeStamp() { + BigInteger expectedChainId = + BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID) + .add(BigInteger.valueOf(PERIOD_SINCE_GENESIS)); + + long expectedGenesisTimestamp = + GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); + + final GenesisConfigFile config = GenesisConfigFile.fromResource("/ephemery.json"); + + final Map override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + override.put("chainId", String.valueOf(expectedChainId)); + override.put("timestamp", String.valueOf(expectedGenesisTimestamp)); + + assertThat(config.withOverrides(override).getConfigOptions().getChainId()).isPresent(); + assertThat(config.withOverrides(override).getTimestamp()).isNotNull(); + } + + @Test + public void testEphemeryWhenSuccessful() { + final GenesisConfigFile config = GenesisConfigFile.fromConfig(VALID_GENESIS_JSON.toString()); BigInteger expectedChainId = BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID) @@ -145,27 +138,37 @@ public void testEphemeryWhenSuccessful() throws IOException { long expectedGenesisTimestamp = GENESIS_TEST_TIMESTAMP + (PERIOD_SINCE_GENESIS * PERIOD_IN_SECONDS); - EPHEMERY.setNetworkId(expectedChainId, EPHEMERY); - configNode.put("chainId", expectedChainId); - rootNode.put("timestamp", String.valueOf(expectedGenesisTimestamp)); + EPHEMERY.setNetworkId(expectedChainId); + + final Map override = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + override.put("chainId", String.valueOf(expectedChainId)); + override.put("timestamp", String.valueOf(expectedGenesisTimestamp)); + config.withOverrides(override); assertThat(CURRENT_TIMESTAMP_HIGHER) - .isGreaterThan(rootNode.get("timestamp").asLong() + PERIOD_IN_SECONDS); - assertThat(tempJsonFile).exists(); - assertThat(rootNode.get("timestamp").asLong()).isEqualTo(expectedGenesisTimestamp); - assertThat(configNode.get("chainId").toString()).isEqualTo(expectedChainId.toString()); - Files.delete(tempJsonFile); + .isGreaterThan(Long.parseLong(String.valueOf(GENESIS_TEST_TIMESTAMP + PERIOD_IN_SECONDS))); + + assertThat(override.get("timestamp")).isEqualTo(String.valueOf(expectedGenesisTimestamp)); + assertThat(override.get("chainId")).isEqualTo(expectedChainId.toString()); } @Test public void testEphemeryWhenChainIdAndTimestampIsPresent() { + final GenesisConfigFile config = GenesisConfigFile.fromResource("/ephemery.json"); + Optional chainId = config.getConfigOptions().getChainId(); + long timestamp = config.getTimestamp(); when(genesisConfigFile.getTimestamp()).thenReturn(GENESIS_TEST_TIMESTAMP); when(genesisConfigOptions.getChainId()) .thenReturn(Optional.of(BigInteger.valueOf(GENESIS_CONFIG_TEST_CHAINID))); ephemeryGenesisFile.updateGenesis(); verify(genesisConfigFile).getTimestamp(); verify(genesisConfigOptions).getChainId(); + + assertThat(chainId).isPresent(); + assertThat(chainId).isNotEmpty(); + assertThat(String.valueOf(timestamp)).isNotNull(); + assertThat(String.valueOf(timestamp)).isNotEmpty(); } @Test @@ -181,22 +184,4 @@ public void testEphemeryThrowIOException() { .hasMessage("Unable to update ephemery genesis file."); verify(spyEphemeryGenesisFile).updateGenesis(); } - - public Map createGenesisFile( - final Path tempJsonFile, final JsonObject genesisData) throws IOException { - Files.write(tempJsonFile, genesisData.encodePrettily().getBytes(UTF_8)); - - ObjectMapper objectMapper = new ObjectMapper(); - ObjectNode rootNode = (ObjectNode) objectMapper.readTree(tempJsonFile.toFile()); - - ObjectNode configNode = - rootNode.has("config") - ? (ObjectNode) rootNode.path("config") - : objectMapper.createObjectNode(); - Map nodes = new HashMap<>(); - nodes.put("rootNode", rootNode); - nodes.put("configNode", configNode); - - return nodes; - } } From 7cee24acad77c4084e56019873eb83e3479237f4 Mon Sep 17 00:00:00 2001 From: gconnect Date: Fri, 30 Aug 2024 05:52:12 +0100 Subject: [PATCH 122/124] Remove check for genesisconfigfile --- .../java/org/hyperledger/besu/util/EphemeryGenesisFile.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java index 9c34909c48b..104c9def250 100644 --- a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java +++ b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java @@ -51,9 +51,7 @@ public EphemeryGenesisFile( public void updateGenesis() { try { - if (EPHEMERY.getGenesisFile() == null - || genesisConfigOptions == null - || genesisConfigFile == null) { + if (EPHEMERY.getGenesisFile() == null || genesisConfigOptions == null) { throw new IOException("Genesis file or config options are null"); } From 69c1b8334270a40d47a4c2a20221280b3012f94e Mon Sep 17 00:00:00 2001 From: gconnect Date: Fri, 30 Aug 2024 07:35:24 +0100 Subject: [PATCH 123/124] sign-off for commit 7cee24acad77c4084e56019873eb83e3479237f4 Signed-off-by: gconnect From a53b92b6e6250caf3e8936eb6a3a6cdc6c1ff95f Mon Sep 17 00:00:00 2001 From: gconnect Date: Fri, 30 Aug 2024 07:42:32 +0100 Subject: [PATCH 124/124] Add comment to EphemeryGenesisFile Signed-off-by: gconnect --- .../java/org/hyperledger/besu/util/EphemeryGenesisFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java index 104c9def250..4f1c77006ba 100644 --- a/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java +++ b/besu/src/main/java/org/hyperledger/besu/util/EphemeryGenesisFile.java @@ -29,7 +29,7 @@ /** * The Generate Ephemery Genesis File. Checks for update based on the set period and update the - * Ephemery genesis file + * Ephemery genesis file in memory */ public class EphemeryGenesisFile { private final GenesisConfigFile genesisConfigFile;