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 <garyschulte@gmail.com>

* fixing on selfdestruct

Signed-off-by: Karim Taam <karim.t2am@gmail.com>
release-23.10.3 23.10.3-hotfix
garyschulte 11 months ago committed by GitHub
parent 4852f69279
commit f3751af18c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 28
      CHANGELOG.md
  2. 21
      consensus/merge/src/main/java/org/hyperledger/besu/consensus/merge/blockcreation/MergeCoordinator.java
  3. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/BonsaiWorldStateProvider.java
  4. 100
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/bonsai/worldview/BonsaiWorldState.java
  5. 2
      gradle.properties

@ -1,28 +1,11 @@
# Changelog # Changelog
## 23.10.4 ## 23.10.3-hotfix
- Hotfix for selfdestruct preimages on bonsai [#6359]((https://github.com/hyperledger/besu/pull/6359)
### Breaking Changes - mitigation for trielog failure [#6315]((https://github.com/hyperledger/besu/pull/6315)
### 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 ## 23.10.3
### Breaking Changes
### Deprecations
### Additions and Improvements ### Additions and Improvements
- Implement debug_traceCall [#5885](https://github.com/hyperledger/besu/pull/5885) - 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) - 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) - 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 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) - 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 ### Bug fixes
- Fix Docker image name clash between Besu and evmtool [#6194](https://github.com/hyperledger/besu/pull/6194) - 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) - 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 ## 23.10.2
### Breaking Changes ### Breaking Changes

@ -492,12 +492,21 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
@Override @Override
public Optional<BlockHeader> getOrSyncHeadByHash(final Hash headHash, final Hash finalizedHash) { public Optional<BlockHeader> getOrSyncHeadByHash(final Hash headHash, final Hash finalizedHash) {
final var chain = protocolContext.getBlockchain(); final var chain = protocolContext.getBlockchain();
final var maybeHeadHeader = chain.getBlockHeader(headHash); final var maybeHead =
chain
if (maybeHeadHeader.isPresent()) { .getBlockHeader(headHash)
// ensure we have the corresponding worldstate also:
.filter(
headHeader ->
protocolContext
.getWorldStateArchive()
.isWorldStateAvailable(
headHeader.getStateRoot(), headHeader.getBlockHash()));
if (maybeHead.isPresent()) {
LOG.atDebug() LOG.atDebug()
.setMessage("BlockHeader {} is already present in blockchain") .setMessage("BlockHeader and world state for {} is already present")
.addArgument(maybeHeadHeader.get()::toLogString) .addArgument(maybeHead.get()::toLogString)
.log(); .log();
} else { } else {
LOG.atDebug() LOG.atDebug()
@ -509,7 +518,7 @@ public class MergeCoordinator implements MergeMiningCoordinator, BadChainListene
.syncBackwardsUntil(headHash) .syncBackwardsUntil(headHash)
.thenRun(() -> updateFinalized(finalizedHash)); .thenRun(() -> updateFinalized(finalizedHash));
} }
return maybeHeadHeader; return maybeHead;
} }
private void updateFinalized(final Hash finalizedHash) { private void updateFinalized(final Hash finalizedHash) {

@ -252,7 +252,7 @@ public class BonsaiWorldStateProvider implements WorldStateArchive {
} catch (final Exception e) { } catch (final Exception e) {
// if we fail we must clean up the updater // if we fail we must clean up the updater
bonsaiUpdater.reset(); bonsaiUpdater.reset();
LOG.debug( LOG.error(
"State rolling failed on " "State rolling failed on "
+ mutableState.getWorldStateStorage().getClass().getSimpleName() + mutableState.getWorldStateStorage().getClass().getSimpleName()
+ " for block hash " + " for block hash "

@ -341,59 +341,55 @@ public class BonsaiWorldState
final Optional<BonsaiWorldStateKeyValueStorage.BonsaiUpdater> maybeStateUpdater, final Optional<BonsaiWorldStateKeyValueStorage.BonsaiUpdater> maybeStateUpdater,
final BonsaiWorldStateUpdateAccumulator worldStateUpdater) { final BonsaiWorldStateUpdateAccumulator worldStateUpdater) {
maybeStateUpdater.ifPresent( for (final Address address : worldStateUpdater.getStorageToClear()) {
bonsaiUpdater -> { // because we are clearing persisted values we need the account root as persisted
for (final Address address : worldStateUpdater.getStorageToClear()) { final BonsaiAccount oldAccount =
// because we are clearing persisted values we need the account root as persisted worldStateStorage
final BonsaiAccount oldAccount = .getAccount(address.addressHash())
worldStateStorage .map(bytes -> BonsaiAccount.fromRLP(BonsaiWorldState.this, address, bytes, true))
.getAccount(address.addressHash()) .orElse(null);
.map( if (oldAccount == null) {
bytes -> BonsaiAccount.fromRLP(BonsaiWorldState.this, address, bytes, true)) // This is when an account is both created and deleted within the scope of the same
.orElse(null); // block. A not-uncommon DeFi bot pattern.
if (oldAccount == null) { continue;
// This is when an account is both created and deleted within the scope of the same }
// block. A not-uncommon DeFi bot pattern. final Hash addressHash = address.addressHash();
continue; final MerkleTrie<Bytes, Bytes> storageTrie =
} createTrie(
final Hash addressHash = address.addressHash(); (location, key) -> getStorageTrieNode(addressHash, location, key),
final MerkleTrie<Bytes, Bytes> storageTrie = oldAccount.getStorageRoot());
createTrie( try {
(location, key) -> getStorageTrieNode(addressHash, location, key), final StorageConsumingMap<StorageSlotKey, BonsaiValue<UInt256>> storageToDelete =
oldAccount.getStorageRoot()); worldStateUpdater.getStorageToUpdate().get(address);
try { Map<Bytes32, Bytes> entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256);
while (!entriesToDelete.isEmpty()) {
final StorageConsumingMap<StorageSlotKey, BonsaiValue<UInt256>> storageToDelete = entriesToDelete.forEach(
worldStateUpdater.getStorageToUpdate().get(address); (k, v) -> {
Map<Bytes32, Bytes> entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256); final StorageSlotKey storageSlotKey =
while (!entriesToDelete.isEmpty()) { new StorageSlotKey(Hash.wrap(k), Optional.empty());
entriesToDelete.forEach( final UInt256 slotValue = UInt256.fromBytes(Bytes32.leftPad(RLP.decodeValue(v)));
(k, v) -> { maybeStateUpdater.ifPresent(
final StorageSlotKey storageSlotKey = bonsaiUpdater ->
new StorageSlotKey(Hash.wrap(k), Optional.empty()); bonsaiUpdater.removeStorageValueBySlotHash(
final UInt256 slotValue = address.addressHash(), storageSlotKey.getSlotHash()));
UInt256.fromBytes(Bytes32.leftPad(RLP.decodeValue(v))); storageToDelete
bonsaiUpdater.removeStorageValueBySlotHash( .computeIfAbsent(
address.addressHash(), storageSlotKey.getSlotHash()); storageSlotKey, key -> new BonsaiValue<>(slotValue, null, true))
storageToDelete .setPrior(slotValue);
.computeIfAbsent( });
storageSlotKey, key -> new BonsaiValue<>(slotValue, null, true)) entriesToDelete.keySet().forEach(storageTrie::remove);
.setPrior(slotValue); if (entriesToDelete.size() == 256) {
}); entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256);
entriesToDelete.keySet().forEach(storageTrie::remove); } else {
if (entriesToDelete.size() == 256) { break;
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());
}
} }
}); }
} 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 @Override

@ -1,4 +1,4 @@
version=23.10.3 version=23.10.3-hotfix
org.gradle.welcome=never org.gradle.welcome=never
# Set exports/opens flags required by Google Java Format and ErrorProne plugins. (JEP-396) # Set exports/opens flags required by Google Java Format and ErrorProne plugins. (JEP-396)

Loading…
Cancel
Save