diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiArchiveWorldStateProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiArchiveWorldStateProvider.java index 417c97fe702..fbb5cf8445f 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiArchiveWorldStateProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiArchiveWorldStateProvider.java @@ -97,7 +97,7 @@ public Optional getMutable( trieLogManager.getMaxLayersToLoad()); Optional cachedWorldState = cachedWorldStorageManager - .getHeadWorldState(blockchain::getBlockHeader) + .getWorldState(chainHeadBlockHeader.getHash()) .map(MutableWorldState::disableTrie) .flatMap( worldState -> @@ -105,7 +105,6 @@ public Optional getMutable( // state (DiffBasedWorldState) worldState, blockHeader.getHash())) .map(MutableWorldState::freeze); - return cachedWorldState; } return super.getMutable(blockHeader, false); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java index 1cd39424240..c4667470ba9 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java @@ -105,7 +105,7 @@ public Optional getMutable( return cachedWorldStorageManager .getWorldState(blockHeader.getHash()) .or(() -> cachedWorldStorageManager.getNearestWorldState(blockHeader)) - .or(() -> cachedWorldStorageManager.getHeadWorldState(blockchain::getBlockHeader)) + .or(() -> cachedWorldStorageManager.getWorldState(chainHeadBlockHeader.getHash())) .flatMap(worldState -> rollMutableStateToBlockHash(worldState, blockHeader.getHash())) .map(MutableWorldState::freeze); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiSnapshotWorldStateKeyValueStorage.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiSnapshotWorldStateKeyValueStorage.java index 2437118d640..8226a6940cf 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiSnapshotWorldStateKeyValueStorage.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiSnapshotWorldStateKeyValueStorage.java @@ -71,7 +71,8 @@ public Updater updater() { return new Updater( ((SnappedKeyValueStorage) composedWorldStateStorage).getSnapshotTransaction(), trieLogStorage.startTransaction(), - getFlatDbStrategy()); + getFlatDbStrategy(), + composedWorldStateStorage); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java index 8f72c41d91a..5d10db56ad3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java @@ -187,7 +187,8 @@ public Updater updater() { return new Updater( composedWorldStateStorage.startTransaction(), trieLogStorage.startTransaction(), - getFlatDbStrategy()); + getFlatDbStrategy(), + composedWorldStateStorage); } public static class Updater implements DiffBasedWorldStateKeyValueStorage.Updater { @@ -195,19 +196,25 @@ public static class Updater implements DiffBasedWorldStateKeyValueStorage.Update private final SegmentedKeyValueStorageTransaction composedWorldStateTransaction; private final KeyValueStorageTransaction trieLogStorageTransaction; private final FlatDbStrategy flatDbStrategy; + private final SegmentedKeyValueStorage worldStorage; public Updater( final SegmentedKeyValueStorageTransaction composedWorldStateTransaction, final KeyValueStorageTransaction trieLogStorageTransaction, - final FlatDbStrategy flatDbStrategy) { + final FlatDbStrategy flatDbStrategy, + final SegmentedKeyValueStorage worldStorage) { this.composedWorldStateTransaction = composedWorldStateTransaction; this.trieLogStorageTransaction = trieLogStorageTransaction; this.flatDbStrategy = flatDbStrategy; + this.worldStorage = + worldStorage; // An update could need to read from world storage to decide how to PUT to + // it (i.e. Bonsai archive) } public Updater removeCode(final Hash accountHash, final Hash codeHash) { - flatDbStrategy.removeFlatCode(composedWorldStateTransaction, accountHash, codeHash); + flatDbStrategy.removeFlatCode( + worldStorage, composedWorldStateTransaction, accountHash, codeHash); return this; } @@ -222,12 +229,13 @@ public Updater putCode(final Hash accountHash, final Hash codeHash, final Bytes // Don't save empty values return this; } - flatDbStrategy.putFlatCode(composedWorldStateTransaction, accountHash, codeHash, code); + flatDbStrategy.putFlatCode( + worldStorage, composedWorldStateTransaction, accountHash, codeHash, code); return this; } public Updater removeAccountInfoState(final Hash accountHash) { - flatDbStrategy.removeFlatAccount(composedWorldStateTransaction, accountHash); + flatDbStrategy.removeFlatAccount(worldStorage, composedWorldStateTransaction, accountHash); return this; } @@ -236,7 +244,8 @@ public Updater putAccountInfoState(final Hash accountHash, final Bytes accountVa // Don't save empty values return this; } - flatDbStrategy.putFlatAccount(composedWorldStateTransaction, accountHash, accountValue); + flatDbStrategy.putFlatAccount( + worldStorage, composedWorldStateTransaction, accountHash, accountValue); return this; } @@ -283,14 +292,14 @@ public synchronized Updater putAccountStorageTrieNode( public synchronized Updater putStorageValueBySlotHash( final Hash accountHash, final Hash slotHash, final Bytes storageValue) { flatDbStrategy.putFlatAccountStorageValueByStorageSlotHash( - composedWorldStateTransaction, accountHash, slotHash, storageValue); + worldStorage, composedWorldStateTransaction, accountHash, slotHash, storageValue); return this; } public synchronized void removeStorageValueBySlotHash( final Hash accountHash, final Hash slotHash) { flatDbStrategy.removeFlatAccountStorageValueByStorageSlotHash( - composedWorldStateTransaction, accountHash, slotHash); + worldStorage, composedWorldStateTransaction, accountHash, slotHash); } @Override diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiArchiveFlatDbStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiArchiveFlatDbStrategy.java index 1bb0b1a095d..a3000f9e310 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiArchiveFlatDbStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiArchiveFlatDbStrategy.java @@ -18,10 +18,11 @@ import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_INFO_STATE_ARCHIVE; import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_STORAGE_ARCHIVE; import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_STORAGE_STORAGE; +import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE; +import static org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage.WORLD_BLOCK_NUMBER_KEY; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.StorageSlotKey; -import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.trie.NodeLoader; import org.hyperledger.besu.ethereum.trie.diffbased.common.BonsaiContext; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy; @@ -31,6 +32,7 @@ import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage; import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction; +import java.nio.charset.StandardCharsets; import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; @@ -44,18 +46,14 @@ import org.slf4j.LoggerFactory; public class BonsaiArchiveFlatDbStrategy extends BonsaiFullFlatDbStrategy { - private final BonsaiContext context; private static final Logger LOG = LoggerFactory.getLogger(BonsaiArchiveFlatDbStrategy.class); protected final Counter getAccountFromArchiveCounter; protected final Counter getStorageFromArchiveCounter; public BonsaiArchiveFlatDbStrategy( - final BonsaiContext context, - final MetricsSystem metricsSystem, - final CodeStorageStrategy codeStorageStrategy) { + final MetricsSystem metricsSystem, final CodeStorageStrategy codeStorageStrategy) { super(metricsSystem, codeStorageStrategy); - this.context = context; getAccountFromArchiveCounter = metricsSystem.createCounter( @@ -76,6 +74,26 @@ public BonsaiArchiveFlatDbStrategy( public static final byte[] DELETED_CODE_VALUE = new byte[0]; public static final byte[] DELETED_STORAGE_VALUE = new byte[0]; + public Optional getStateArchiveContext(final SegmentedKeyValueStorage storage) { + // For Bonsai archive update the flat DB strategy context to match the block the state/storage + // represents + Optional archiveContext = storage.get(TRIE_BRANCH_STORAGE, WORLD_BLOCK_NUMBER_KEY); + if (archiveContext.isPresent()) { + try { + // keyNearest, use MAX_BLOCK_SUFFIX in the absence of a block context: + return Optional.of( + new BonsaiContext( + Long.decode("0x" + (new String(archiveContext.get(), StandardCharsets.UTF_8))))); + } catch (NumberFormatException e) { + throw new IllegalStateException( + "World state archive context invalid format: " + + new String(archiveContext.get(), StandardCharsets.UTF_8)); + } + } + + throw new IllegalStateException("World state missing archive context"); + } + @Override public Optional getFlatAccount( final Supplier> worldStateRootHashSupplier, @@ -87,7 +105,9 @@ public Optional getFlatAccount( Optional accountFound; // keyNearest, use MAX_BLOCK_SUFFIX in the absence of a block context: - Bytes keyNearest = calculateArchiveKeyWithMaxSuffix(context, accountHash.toArrayUnsafe()); + Bytes keyNearest = + calculateArchiveKeyWithMaxSuffix( + getStateArchiveContext(storage).get(), accountHash.toArrayUnsafe()); // Find the nearest account state for this address and block context Optional nearestAccount = @@ -229,22 +249,29 @@ protected Stream> storageToPairStream( */ @Override public void putFlatAccount( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Bytes accountValue) { // key suffixed with block context, or MIN_BLOCK_SUFFIX if we have no context: - byte[] keySuffixed = calculateArchiveKeyWithMinSuffix(context, accountHash.toArrayUnsafe()); + byte[] keySuffixed = + calculateArchiveKeyWithMinSuffix( + getStateArchiveContext(storage).get(), accountHash.toArrayUnsafe()); transaction.put(ACCOUNT_INFO_STATE, keySuffixed, accountValue.toArrayUnsafe()); } @Override public void removeFlatAccount( - final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash) { + final SegmentedKeyValueStorage storage, + final SegmentedKeyValueStorageTransaction transaction, + final Hash accountHash) { // insert a key suffixed with block context, with 'deleted account' value - byte[] keySuffixed = calculateArchiveKeyWithMinSuffix(context, accountHash.toArrayUnsafe()); + byte[] keySuffixed = + calculateArchiveKeyWithMinSuffix( + getStateArchiveContext(storage).get(), accountHash.toArrayUnsafe()); transaction.put(ACCOUNT_INFO_STATE, keySuffixed, DELETED_ACCOUNT_VALUE); } @@ -271,7 +298,8 @@ public Optional getFlatStorageValueByStorageSlotKey( // get natural key from account hash and slot key byte[] naturalKey = calculateNaturalSlotKey(accountHash, storageSlotKey.getSlotHash()); // keyNearest, use MAX_BLOCK_SUFFIX in the absence of a block context: - Bytes keyNearest = calculateArchiveKeyWithMaxSuffix(context, naturalKey); + Bytes keyNearest = + calculateArchiveKeyWithMaxSuffix(getStateArchiveContext(storage).get(), naturalKey); // Find the nearest storage for this address, slot key hash, and block context Optional nearestStorage = @@ -321,6 +349,7 @@ public Optional getFlatStorageValueByStorageSlotKey( */ @Override public void putFlatAccountStorageValueByStorageSlotHash( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash slotHash, @@ -329,7 +358,8 @@ public void putFlatAccountStorageValueByStorageSlotHash( // get natural key from account hash and slot key byte[] naturalKey = calculateNaturalSlotKey(accountHash, slotHash); // keyNearest, use MIN_BLOCK_SUFFIX in the absence of a block context: - byte[] keyNearest = calculateArchiveKeyWithMinSuffix(context, naturalKey); + byte[] keyNearest = + calculateArchiveKeyWithMinSuffix(getStateArchiveContext(storage).get(), naturalKey); transaction.put(ACCOUNT_STORAGE_STORAGE, keyNearest, storageValue.toArrayUnsafe()); } @@ -339,6 +369,7 @@ public void putFlatAccountStorageValueByStorageSlotHash( */ @Override public void removeFlatAccountStorageValueByStorageSlotHash( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash slotHash) { @@ -346,7 +377,8 @@ public void removeFlatAccountStorageValueByStorageSlotHash( // get natural key from account hash and slot key byte[] naturalKey = calculateNaturalSlotKey(accountHash, slotHash); // insert a key suffixed with block context, with 'deleted account' value - byte[] keySuffixed = calculateArchiveKeyWithMinSuffix(context, naturalKey); + byte[] keySuffixed = + calculateArchiveKeyWithMinSuffix(getStateArchiveContext(storage).get(), naturalKey); transaction.put(ACCOUNT_STORAGE_STORAGE, keySuffixed, DELETED_STORAGE_VALUE); } @@ -391,14 +423,4 @@ public static byte[] calculateArchiveKeyWithSuffix( return orElseSuffix; })); } - - @Override - public void updateBlockContext(final Long blockNumber) { - context.setBlockNumber(blockNumber); - } - - @Override - public void updateBlockContext(final BlockHeader blockHeader) { - context.setBlockNumber(blockHeader.getNumber()); - } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategy.java index 3646cd132db..c9748bac2cf 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategy.java @@ -71,6 +71,7 @@ public abstract Optional getFlatStorageValueByStorageSlotKey( @Override public void putFlatAccount( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Bytes accountValue) { @@ -79,12 +80,15 @@ public void putFlatAccount( @Override public void removeFlatAccount( - final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash) { + final SegmentedKeyValueStorage storage, + final SegmentedKeyValueStorageTransaction transaction, + final Hash accountHash) { transaction.remove(ACCOUNT_INFO_STATE, accountHash.toArrayUnsafe()); } @Override public void putFlatAccountStorageValueByStorageSlotHash( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash slotHash, @@ -97,6 +101,7 @@ public void putFlatAccountStorageValueByStorageSlotHash( @Override public void removeFlatAccountStorageValueByStorageSlotHash( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash slotHash) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategyProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategyProvider.java index bea2747cc2f..065206da497 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategyProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategyProvider.java @@ -16,7 +16,6 @@ import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE; -import org.hyperledger.besu.ethereum.trie.diffbased.common.BonsaiContext; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategy; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategyProvider; @@ -91,8 +90,7 @@ protected FlatDbStrategy createFlatDbStrategy( if (flatDbMode == FlatDbMode.FULL) { return new BonsaiFullFlatDbStrategy(metricsSystem, codeStorageStrategy); } else if (flatDbMode == FlatDbMode.ARCHIVE) { - return new BonsaiArchiveFlatDbStrategy( - new BonsaiContext(), metricsSystem, codeStorageStrategy); + return new BonsaiArchiveFlatDbStrategy(metricsSystem, codeStorageStrategy); } else { return new BonsaiPartialFlatDbStrategy(metricsSystem, codeStorageStrategy); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFullFlatDbStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFullFlatDbStrategy.java index 52976bf53bd..7a251a03aef 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFullFlatDbStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFullFlatDbStrategy.java @@ -19,7 +19,6 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.StorageSlotKey; -import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.trie.NodeLoader; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy; import org.hyperledger.besu.metrics.BesuMetricCategory; @@ -101,14 +100,4 @@ public void resetOnResync(final SegmentedKeyValueStorage storage) { // NOOP // not need to reset anything in full mode } - - @Override - public void updateBlockContext(final Long blockNumber) { - // default no-op for strategies that do not care about bonsai context - } - - @Override - public void updateBlockContext(final BlockHeader blockHeader) { - // default no-op for strategies that do not care about bonsai context - } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiPartialFlatDbStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiPartialFlatDbStrategy.java index 46253efc774..197d49a4cc1 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiPartialFlatDbStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiPartialFlatDbStrategy.java @@ -19,7 +19,6 @@ import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.StorageSlotKey; -import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.ethereum.trie.NodeLoader; import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy; import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie; @@ -146,6 +145,7 @@ public Optional getFlatStorageValueByStorageSlotKey( return response; } + /* @Override public void updateBlockContext(final Long blockNumber) { // Not implemented @@ -154,5 +154,5 @@ public void updateBlockContext(final Long blockNumber) { @Override public void updateBlockContext(final BlockHeader blockHeader) { // Not implemented - } + }*/ } 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 d68590e7f2d..4e1103f7647 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 @@ -384,7 +384,10 @@ public Hash frontierRootHash() { return calculateRootHash( Optional.of( new BonsaiWorldStateKeyValueStorage.Updater( - noOpSegmentedTx, noOpTx, worldStateKeyValueStorage.getFlatDbStrategy())), + noOpSegmentedTx, + noOpTx, + worldStateKeyValueStorage.getFlatDbStrategy(), + worldStateKeyValueStorage.getComposedWorldStateStorage())), accumulator.copy()); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/BonsaiContext.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/BonsaiContext.java index fc05258e403..50662892c53 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/BonsaiContext.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/BonsaiContext.java @@ -23,19 +23,8 @@ public class BonsaiContext { private final AtomicReference blockNumber; /** Context for Bonsai storage i.e. the block the storage applies to */ - public BonsaiContext() { - blockNumber = new AtomicReference<>(); - } - - /** - * Set the new block header for the context - * - * @param blockNumber the new block header - * @return the updated context - */ - public BonsaiContext setBlockNumber(final Long blockNumber) { - this.blockNumber.set(blockNumber); - return this; + public BonsaiContext(final long blockNumber) { + this.blockNumber = new AtomicReference<>(blockNumber); } /** 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 6e86928b5c4..bbac527637d 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 @@ -222,8 +222,8 @@ public int archivePreviousAccountState( if (previousBlockHeader.isPresent()) { try { // Get the key for the previous block - final BonsaiContext previousContext = new BonsaiContext(); - previousContext.setBlockNumber(previousBlockHeader.get().getNumber()); + final BonsaiContext previousContext = + new BonsaiContext(previousBlockHeader.get().getNumber()); final Bytes previousKey = Bytes.of( BonsaiArchiveFlatDbStrategy.calculateArchiveKeyWithMinSuffix( @@ -293,8 +293,8 @@ public int archivePreviousStorageState( if (previousBlockHeader.isPresent()) { try { // Get the key for the previous block - final BonsaiContext previousContext = new BonsaiContext(); - previousContext.setBlockNumber(previousBlockHeader.get().getNumber()); + final BonsaiContext previousContext = + new BonsaiContext(previousBlockHeader.get().getNumber()); final Bytes previousKey = Bytes.of( BonsaiArchiveFlatDbStrategy.calculateArchiveKeyWithMinSuffix( diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/AccountHashCodeStorageStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/AccountHashCodeStorageStrategy.java index 58eb18b26d4..3ffd7330b5e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/AccountHashCodeStorageStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/AccountHashCodeStorageStrategy.java @@ -36,6 +36,7 @@ public Optional getFlatCode( @Override public void putFlatCode( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash codeHash, @@ -45,6 +46,7 @@ public void putFlatCode( @Override public void removeFlatCode( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash codeHash) { diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/CodeHashCodeStorageStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/CodeHashCodeStorageStrategy.java index 3d5516be00a..61da93e2099 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/CodeHashCodeStorageStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/CodeHashCodeStorageStrategy.java @@ -34,6 +34,7 @@ public Optional getFlatCode( @Override public void putFlatCode( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash codeHash, @@ -43,6 +44,7 @@ public void putFlatCode( @Override public void removeFlatCode( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash codeHash) {} diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/CodeStorageStrategy.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/CodeStorageStrategy.java index 8374a8774e6..e0533102ab3 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/CodeStorageStrategy.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/CodeStorageStrategy.java @@ -28,12 +28,14 @@ Optional getFlatCode( final Hash codeHash, final Hash accountHash, final SegmentedKeyValueStorage storage); void putFlatCode( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash codeHash, final Bytes code); void removeFlatCode( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash codeHash); 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 07004ae9c6f..1d809c71527 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 @@ -15,7 +15,6 @@ package org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat; import org.hyperledger.besu.datatypes.Hash; -import org.hyperledger.besu.ethereum.core.BlockHeader; import org.hyperledger.besu.metrics.BesuMetricCategory; import org.hyperledger.besu.plugin.services.MetricsSystem; import org.hyperledger.besu.plugin.services.metrics.Counter; @@ -100,38 +99,44 @@ public Optional getFlatCode( * Removes code for the given account hash. */ public void removeFlatCode( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash codeHash) { - codeStorageStrategy.removeFlatCode(transaction, accountHash, codeHash); + codeStorageStrategy.removeFlatCode(storage, transaction, accountHash, codeHash); } /* * Puts the code data for the given code hash and account hash. */ public void putFlatCode( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash codeHash, final Bytes code) { - codeStorageStrategy.putFlatCode(transaction, accountHash, codeHash, code); + codeStorageStrategy.putFlatCode(storage, transaction, accountHash, codeHash, code); } /* * Puts the account data for the given account hash, using the world state root hash supplier and node loader. */ public abstract void putFlatAccount( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Bytes accountValue); public abstract void removeFlatAccount( - final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash); + final SegmentedKeyValueStorage storage, + final SegmentedKeyValueStorageTransaction transaction, + final Hash accountHash); /* * Puts the storage value for the given account hash and storage slot key, using the world state root hash supplier, storage root supplier, and node loader. */ public abstract void putFlatAccountStorageValueByStorageSlotHash( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash slotHash, @@ -141,6 +146,7 @@ public abstract void putFlatAccountStorageValueByStorageSlotHash( * Removes the storage value for the given account hash and storage slot key, using the world state root hash supplier, storage root supplier, and node loader. */ public abstract void removeFlatAccountStorageValueByStorageSlotHash( + final SegmentedKeyValueStorage storage, final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash, final Hash slotHash); @@ -234,8 +240,4 @@ private NavigableMap toNavigableMap( pairStream.close(); return collected; } - - public abstract void updateBlockContext(final Long blockNumber); - - public abstract void updateBlockContext(final BlockHeader blockHeader); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProvider.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProvider.java index 5c629821bb5..bc432dfb786 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProvider.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/FlatDbStrategyProvider.java @@ -16,7 +16,6 @@ import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.CODE_STORAGE; import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE; -import static org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage.WORLD_BLOCK_NUMBER_KEY; import static org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage.WORLD_ROOT_HASH_KEY; import org.hyperledger.besu.ethereum.worldstate.DataStorageConfiguration; @@ -148,18 +147,6 @@ public FlatDbStrategy getFlatDbStrategy( if (flatDbStrategy == null) { loadFlatDbStrategy(composedWorldStateStorage); } - - if (this.flatDbMode == FlatDbMode.ARCHIVE) { - // For Bonsai archive update the flat DB strategy context to match the block the state/storage - // represents - Optional archiveContext = - composedWorldStateStorage.get(TRIE_BRANCH_STORAGE, WORLD_BLOCK_NUMBER_KEY); - if (archiveContext.isPresent()) { - // keyNearest, use MAX_BLOCK_SUFFIX in the absence of a block context: - this.flatDbStrategy.updateBlockContext( - Long.decode("0x" + (new String(archiveContext.get(), StandardCharsets.UTF_8)))); - } - } return flatDbStrategy; } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/DiffBasedWorldState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/DiffBasedWorldState.java index 3fc2ee46c4f..67dd5f58c9e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/DiffBasedWorldState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/common/worldview/DiffBasedWorldState.java @@ -170,15 +170,21 @@ public void persist(final BlockHeader blockHeader) { // Update the block context before putting entries to storage via calculateRootHash() // TODO - rename calculateRootHash() to be clearer that it updates state, it doesn't just // calculate a hash - if (worldStateKeyValueStorage.getFlatDbStrategy() instanceof BonsaiArchiveFlatDbStrategy - && blockHeader != null) { + if (worldStateKeyValueStorage.getFlatDbStrategy() instanceof BonsaiArchiveFlatDbStrategy) { + final long archiveContext; + if (blockHeader != null) { + archiveContext = blockHeader.getNumber(); + } else { + archiveContext = 0L; + } + DiffBasedWorldStateKeyValueStorage.Updater stateUpdater = worldStateKeyValueStorage.updater(); stateUpdater .getWorldStateTransaction() .put( TRIE_BRANCH_STORAGE, WORLD_BLOCK_NUMBER_KEY, - Long.toHexString(blockHeader.getNumber()).getBytes(StandardCharsets.UTF_8)); + Long.toHexString(archiveContext).getBytes(StandardCharsets.UTF_8)); stateUpdater.commit(); } diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/BonsaiFlatDbStrategyProviderTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/BonsaiFlatDbStrategyProviderTest.java index fc9dd929038..432d84be786 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/BonsaiFlatDbStrategyProviderTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/trie/diffbased/common/storage/flat/BonsaiFlatDbStrategyProviderTest.java @@ -180,7 +180,8 @@ void existingAccountHashDbUsesAccountHash(final boolean codeByHashEnabled) { new AccountHashCodeStorageStrategy(); // key representing account hash just needs to not be the code hash final Hash accountHash = Hash.wrap(Bytes32.fromHexString("0001")); - accountHashCodeStorageStrategy.putFlatCode(transaction, accountHash, null, Bytes.of(2)); + accountHashCodeStorageStrategy.putFlatCode( + composedWorldStateStorage, transaction, accountHash, null, Bytes.of(2)); transaction.commit(); flatDbStrategyProvider.loadFlatDbStrategy(composedWorldStateStorage); @@ -215,7 +216,8 @@ void existingAccountHashArchiveDbUsesAccountHash(final boolean codeByHashEnabled new AccountHashCodeStorageStrategy(); // key representing account hash just needs to not be the code hash final Hash accountHash = Hash.wrap(Bytes32.fromHexString("0001")); - accountHashCodeStorageStrategy.putFlatCode(transaction, accountHash, null, Bytes.of(2)); + accountHashCodeStorageStrategy.putFlatCode( + composedWorldStateStorage, transaction, accountHash, null, Bytes.of(2)); transaction.commit(); flatDbStrategyProvider.loadFlatDbStrategy(composedWorldStateStorage); @@ -247,7 +249,8 @@ void existingCodeHashDbUsesCodeHash(final boolean codeByHashEnabled) { final CodeHashCodeStorageStrategy codeHashCodeStorageStrategy = new CodeHashCodeStorageStrategy(); - codeHashCodeStorageStrategy.putFlatCode(transaction, null, Hash.hash(Bytes.of(1)), Bytes.of(1)); + codeHashCodeStorageStrategy.putFlatCode( + composedWorldStateStorage, transaction, null, Hash.hash(Bytes.of(1)), Bytes.of(1)); transaction.commit(); flatDbStrategyProvider.loadFlatDbStrategy(composedWorldStateStorage); @@ -281,7 +284,8 @@ void existingCodeHashArchiveDbUsesCodeHash(final boolean codeByHashEnabled) { final CodeHashCodeStorageStrategy codeHashCodeStorageStrategy = new CodeHashCodeStorageStrategy(); - codeHashCodeStorageStrategy.putFlatCode(transaction, null, Hash.hash(Bytes.of(1)), Bytes.of(1)); + codeHashCodeStorageStrategy.putFlatCode( + composedWorldStateStorage, transaction, null, Hash.hash(Bytes.of(1)), Bytes.of(1)); transaction.commit(); flatDbStrategyProvider.loadFlatDbStrategy(composedWorldStateStorage); 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 f0d1830b19d..59abe5d989b 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 @@ -861,7 +861,8 @@ static SnapTestAccount createTestContractAccount( // Only Bonsai archive cares about this. Do everything as if we're at // block 1 so we know which entry to retrieve from the DB - flatdb.updateBlockContext(generateBonsaiArchiveContextHeader(1)); + // MRW + // flatdb.updateBlockContext(generateBonsaiArchiveContextHeader(1)); var updater = storage.updater(); updater.putCode(Hash.hash(mockCode), mockCode); @@ -874,6 +875,7 @@ static SnapTestAccount createTestContractAccount( rlpOut.writeBytes(mockBytes32); trie.put(mockBytes32, rlpOut.encoded()); flatdb.putFlatAccountStorageValueByStorageSlotHash( + null, // MRW updater.getWorldStateTransaction(), acctHash, Hash.wrap(mockBytes32),