From f3751af18c4e320dbce8a986be9c3133ff8174db Mon Sep 17 00:00:00 2001 From: garyschulte Date: Sat, 6 Jan 2024 15:59:59 -0800 Subject: [PATCH] Hotfix 23.10.3-hotfix Log/Address Trielog rolling failure (#6315) * trigger a BWS if we do not have a valid worldstate available during fcU raise log rolling failure loglevel to error from debug Signed-off-by: garyschulte * fixing on selfdestruct Signed-off-by: Karim Taam --- CHANGELOG.md | 28 ++--- .../merge/blockcreation/MergeCoordinator.java | 21 ++-- .../trie/bonsai/BonsaiWorldStateProvider.java | 2 +- .../bonsai/worldview/BonsaiWorldState.java | 100 +++++++++--------- gradle.properties | 2 +- 5 files changed, 73 insertions(+), 80 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0275bd837a5..2ad2d843009 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,28 +1,11 @@ # Changelog -## 23.10.4 - -### Breaking Changes - -### Deprecations -- Forest pruning (`pruning-enabled` options) is deprecated and will be removed soon. To save disk space consider switching to Bonsai data storage format [#6230](https://github.com/hyperledger/besu/pull/6230) - -### Additions and Improvements -- Add error messages on authentication failures with username and password [#6212](https://github.com/hyperledger/besu/pull/6212) -- New `Sequenced` transaction pool. The pool is an evolution of the `legacy` pool and is likely to be more suitable to enterprise or permissioned chains than the `layered` transaction pool. Select to use this pool with `--tx-pool=sequenced`. Supports the same options as the `legacy` pool [#6211](https://github.com/hyperledger/besu/issues/6211) -- Set Ethereum Classic mainnet activation block for Spiral network upgrade [#6267](https://github.com/hyperledger/besu/pull/6267) -- Add custom genesis file name to config overview if specified [#6297](https://github.com/hyperledger/besu/pull/6297) -- Update Gradle plugins and replace unmaintained License Gradle Plugin with the actively maintained Gradle License Report [#6275](https://github.com/hyperledger/besu/pull/6275) - -### Bug fixes - +## 23.10.3-hotfix +- Hotfix for selfdestruct preimages on bonsai [#6359]((https://github.com/hyperledger/besu/pull/6359) +- mitigation for trielog failure [#6315]((https://github.com/hyperledger/besu/pull/6315) ## 23.10.3 -### Breaking Changes - -### Deprecations - ### Additions and Improvements - Implement debug_traceCall [#5885](https://github.com/hyperledger/besu/pull/5885) - Transactions that takes too long to evaluate, during block creation, are dropped from the txpool [#6163](https://github.com/hyperledger/besu/pull/6163) @@ -34,11 +17,16 @@ - Update OpenJ9 Docker image to latest version [#6226](https://github.com/hyperledger/besu/pull/6226) - Add error messages on authentication failures with username and password [#6212](https://github.com/hyperledger/besu/pull/6212) - Add `rocksdb usage` to the `storage` subcommand to allow users and dev to check columns families usage [#6185](https://github.com/hyperledger/besu/pull/6185) +- Ethereum Classic Spiral network upgrade [#6078](https://github.com/hyperledger/besu/pull/6078) ### Bug fixes - Fix Docker image name clash between Besu and evmtool [#6194](https://github.com/hyperledger/besu/pull/6194) - Fix `logIndex` in `eth_getTransactionReceipt` JSON RPC method [#6206](https://github.com/hyperledger/besu/pull/6206) +### Download Links +https://hyperledger.jfrog.io/artifactory/besu-binaries/besu/23.10.3/besu-23.10.3.zip / sha256 da7ef8a6ceb88d3e327cacddcdb32218d1750b464c14165a74068f6dc6e0871a +https://hyperledger.jfrog.io/artifactory/besu-binaries/besu/23.10.3/besu-23.10.3.tar.gz / sha256 73c834cf32c7bbe255d7d8cc7ca5d1eb0df8430b9114935c8dcf3a675b2acbc2 + ## 23.10.2 ### Breaking Changes diff --git a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java index 5773a468251..e1fd8ee8a10 100644 --- a/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java +++ b/consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java @@ -492,12 +492,21 @@ private boolean canRetryBlockCreation(final Throwable throwable) { @Override public Optional getOrSyncHeadByHash(final Hash headHash, final Hash finalizedHash) { final var chain = protocolContext.getBlockchain(); - final var maybeHeadHeader = chain.getBlockHeader(headHash); - - if (maybeHeadHeader.isPresent()) { + final var maybeHead = + chain + .getBlockHeader(headHash) + // ensure we have the corresponding worldstate also: + .filter( + headHeader -> + protocolContext + .getWorldStateArchive() + .isWorldStateAvailable( + headHeader.getStateRoot(), headHeader.getBlockHash())); + + if (maybeHead.isPresent()) { LOG.atDebug() - .setMessage("BlockHeader {} is already present in blockchain") - .addArgument(maybeHeadHeader.get()::toLogString) + .setMessage("BlockHeader and world state for {} is already present") + .addArgument(maybeHead.get()::toLogString) .log(); } else { LOG.atDebug() @@ -509,7 +518,7 @@ public Optional getOrSyncHeadByHash(final Hash headHash, final Hash .syncBackwardsUntil(headHash) .thenRun(() -> updateFinalized(finalizedHash)); } - return maybeHeadHeader; + return maybeHead; } private void updateFinalized(final Hash finalizedHash) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/BonsaiWorldStateProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/BonsaiWorldStateProvider.java index 4c783888c09..f3a4c7f57f1 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/BonsaiWorldStateProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/BonsaiWorldStateProvider.java @@ -252,7 +252,7 @@ Optional rollMutableStateToBlockHash( } catch (final Exception e) { // if we fail we must clean up the updater bonsaiUpdater.reset(); - LOG.debug( + LOG.error( "State rolling failed on " + mutableState.getWorldStateStorage().getClass().getSimpleName() + " for block hash " diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/worldview/BonsaiWorldState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/worldview/BonsaiWorldState.java index 323a9e510e5..548a3a1c414 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/worldview/BonsaiWorldState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/worldview/BonsaiWorldState.java @@ -341,59 +341,55 @@ private void clearStorage( final Optional maybeStateUpdater, final BonsaiWorldStateUpdateAccumulator worldStateUpdater) { - maybeStateUpdater.ifPresent( - bonsaiUpdater -> { - for (final Address address : worldStateUpdater.getStorageToClear()) { - // because we are clearing persisted values we need the account root as persisted - final BonsaiAccount oldAccount = - worldStateStorage - .getAccount(address.addressHash()) - .map( - bytes -> BonsaiAccount.fromRLP(BonsaiWorldState.this, address, bytes, true)) - .orElse(null); - if (oldAccount == null) { - // This is when an account is both created and deleted within the scope of the same - // block. A not-uncommon DeFi bot pattern. - continue; - } - final Hash addressHash = address.addressHash(); - final MerkleTrie storageTrie = - createTrie( - (location, key) -> getStorageTrieNode(addressHash, location, key), - oldAccount.getStorageRoot()); - try { - - final StorageConsumingMap> storageToDelete = - worldStateUpdater.getStorageToUpdate().get(address); - Map entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256); - while (!entriesToDelete.isEmpty()) { - entriesToDelete.forEach( - (k, v) -> { - final StorageSlotKey storageSlotKey = - new StorageSlotKey(Hash.wrap(k), Optional.empty()); - final UInt256 slotValue = - UInt256.fromBytes(Bytes32.leftPad(RLP.decodeValue(v))); - bonsaiUpdater.removeStorageValueBySlotHash( - address.addressHash(), storageSlotKey.getSlotHash()); - storageToDelete - .computeIfAbsent( - storageSlotKey, key -> new BonsaiValue<>(slotValue, null, true)) - .setPrior(slotValue); - }); - entriesToDelete.keySet().forEach(storageTrie::remove); - if (entriesToDelete.size() == 256) { - entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256); - } else { - break; - } - } - } catch (MerkleTrieException e) { - // need to throw to trigger the heal - throw new MerkleTrieException( - e.getMessage(), Optional.of(Address.wrap(address)), e.getHash(), e.getLocation()); - } + for (final Address address : worldStateUpdater.getStorageToClear()) { + // because we are clearing persisted values we need the account root as persisted + final BonsaiAccount oldAccount = + worldStateStorage + .getAccount(address.addressHash()) + .map(bytes -> BonsaiAccount.fromRLP(BonsaiWorldState.this, address, bytes, true)) + .orElse(null); + if (oldAccount == null) { + // This is when an account is both created and deleted within the scope of the same + // block. A not-uncommon DeFi bot pattern. + continue; + } + final Hash addressHash = address.addressHash(); + final MerkleTrie storageTrie = + createTrie( + (location, key) -> getStorageTrieNode(addressHash, location, key), + oldAccount.getStorageRoot()); + try { + final StorageConsumingMap> storageToDelete = + worldStateUpdater.getStorageToUpdate().get(address); + Map entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256); + while (!entriesToDelete.isEmpty()) { + entriesToDelete.forEach( + (k, v) -> { + final StorageSlotKey storageSlotKey = + new StorageSlotKey(Hash.wrap(k), Optional.empty()); + final UInt256 slotValue = UInt256.fromBytes(Bytes32.leftPad(RLP.decodeValue(v))); + maybeStateUpdater.ifPresent( + bonsaiUpdater -> + bonsaiUpdater.removeStorageValueBySlotHash( + address.addressHash(), storageSlotKey.getSlotHash())); + storageToDelete + .computeIfAbsent( + storageSlotKey, key -> new BonsaiValue<>(slotValue, null, true)) + .setPrior(slotValue); + }); + entriesToDelete.keySet().forEach(storageTrie::remove); + if (entriesToDelete.size() == 256) { + entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256); + } else { + break; } - }); + } + } catch (MerkleTrieException e) { + // need to throw to trigger the heal + throw new MerkleTrieException( + e.getMessage(), Optional.of(Address.wrap(address)), e.getHash(), e.getLocation()); + } + } } @Override diff --git a/gradle.properties b/gradle.properties index d07fe373827..ddd8cadb5e4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=23.10.3 +version=23.10.3-hotfix org.gradle.welcome=never # Set exports/opens flags required by Google Java Format and ErrorProne plugins. (JEP-396)