Skip to content

Commit 7d42770

Browse files
committed
Move context management out of flat DB strategy
1 parent 25c5bc6 commit 7d42770

20 files changed

+121
-99
lines changed

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiArchiveWorldStateProvider.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,14 @@ public Optional<MutableWorldState> getMutable(
9797
trieLogManager.getMaxLayersToLoad());
9898
Optional<MutableWorldState> cachedWorldState =
9999
cachedWorldStorageManager
100-
.getHeadWorldState(blockchain::getBlockHeader)
100+
.getWorldState(chainHeadBlockHeader.getHash())
101101
.map(MutableWorldState::disableTrie)
102102
.flatMap(
103103
worldState ->
104104
rollMutableArchiveStateToBlockHash( // This is a tiny action for archive
105105
// state
106106
(DiffBasedWorldState) worldState, blockHeader.getHash()))
107107
.map(MutableWorldState::freeze);
108-
109108
return cachedWorldState;
110109
}
111110
return super.getMutable(blockHeader, false);

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/BonsaiWorldStateProvider.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public Optional<MutableWorldState> getMutable(
105105
return cachedWorldStorageManager
106106
.getWorldState(blockHeader.getHash())
107107
.or(() -> cachedWorldStorageManager.getNearestWorldState(blockHeader))
108-
.or(() -> cachedWorldStorageManager.getHeadWorldState(blockchain::getBlockHeader))
108+
.or(() -> cachedWorldStorageManager.getWorldState(chainHeadBlockHeader.getHash()))
109109
.flatMap(worldState -> rollMutableStateToBlockHash(worldState, blockHeader.getHash()))
110110
.map(MutableWorldState::freeze);
111111
}

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiSnapshotWorldStateKeyValueStorage.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ public Updater updater() {
7171
return new Updater(
7272
((SnappedKeyValueStorage) composedWorldStateStorage).getSnapshotTransaction(),
7373
trieLogStorage.startTransaction(),
74-
getFlatDbStrategy());
74+
getFlatDbStrategy(),
75+
composedWorldStateStorage);
7576
}
7677

7778
@Override

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/BonsaiWorldStateKeyValueStorage.java

+17-8
Original file line numberDiff line numberDiff line change
@@ -187,27 +187,34 @@ public Updater updater() {
187187
return new Updater(
188188
composedWorldStateStorage.startTransaction(),
189189
trieLogStorage.startTransaction(),
190-
getFlatDbStrategy());
190+
getFlatDbStrategy(),
191+
composedWorldStateStorage);
191192
}
192193

193194
public static class Updater implements DiffBasedWorldStateKeyValueStorage.Updater {
194195

195196
private final SegmentedKeyValueStorageTransaction composedWorldStateTransaction;
196197
private final KeyValueStorageTransaction trieLogStorageTransaction;
197198
private final FlatDbStrategy flatDbStrategy;
199+
private final SegmentedKeyValueStorage worldStorage;
198200

199201
public Updater(
200202
final SegmentedKeyValueStorageTransaction composedWorldStateTransaction,
201203
final KeyValueStorageTransaction trieLogStorageTransaction,
202-
final FlatDbStrategy flatDbStrategy) {
204+
final FlatDbStrategy flatDbStrategy,
205+
final SegmentedKeyValueStorage worldStorage) {
203206

204207
this.composedWorldStateTransaction = composedWorldStateTransaction;
205208
this.trieLogStorageTransaction = trieLogStorageTransaction;
206209
this.flatDbStrategy = flatDbStrategy;
210+
this.worldStorage =
211+
worldStorage; // An update could need to read from world storage to decide how to PUT to
212+
// it (i.e. Bonsai archive)
207213
}
208214

209215
public Updater removeCode(final Hash accountHash, final Hash codeHash) {
210-
flatDbStrategy.removeFlatCode(composedWorldStateTransaction, accountHash, codeHash);
216+
flatDbStrategy.removeFlatCode(
217+
worldStorage, composedWorldStateTransaction, accountHash, codeHash);
211218
return this;
212219
}
213220

@@ -222,12 +229,13 @@ public Updater putCode(final Hash accountHash, final Hash codeHash, final Bytes
222229
// Don't save empty values
223230
return this;
224231
}
225-
flatDbStrategy.putFlatCode(composedWorldStateTransaction, accountHash, codeHash, code);
232+
flatDbStrategy.putFlatCode(
233+
worldStorage, composedWorldStateTransaction, accountHash, codeHash, code);
226234
return this;
227235
}
228236

229237
public Updater removeAccountInfoState(final Hash accountHash) {
230-
flatDbStrategy.removeFlatAccount(composedWorldStateTransaction, accountHash);
238+
flatDbStrategy.removeFlatAccount(worldStorage, composedWorldStateTransaction, accountHash);
231239
return this;
232240
}
233241

@@ -236,7 +244,8 @@ public Updater putAccountInfoState(final Hash accountHash, final Bytes accountVa
236244
// Don't save empty values
237245
return this;
238246
}
239-
flatDbStrategy.putFlatAccount(composedWorldStateTransaction, accountHash, accountValue);
247+
flatDbStrategy.putFlatAccount(
248+
worldStorage, composedWorldStateTransaction, accountHash, accountValue);
240249
return this;
241250
}
242251

@@ -283,14 +292,14 @@ public synchronized Updater putAccountStorageTrieNode(
283292
public synchronized Updater putStorageValueBySlotHash(
284293
final Hash accountHash, final Hash slotHash, final Bytes storageValue) {
285294
flatDbStrategy.putFlatAccountStorageValueByStorageSlotHash(
286-
composedWorldStateTransaction, accountHash, slotHash, storageValue);
295+
worldStorage, composedWorldStateTransaction, accountHash, slotHash, storageValue);
287296
return this;
288297
}
289298

290299
public synchronized void removeStorageValueBySlotHash(
291300
final Hash accountHash, final Hash slotHash) {
292301
flatDbStrategy.removeFlatAccountStorageValueByStorageSlotHash(
293-
composedWorldStateTransaction, accountHash, slotHash);
302+
worldStorage, composedWorldStateTransaction, accountHash, slotHash);
294303
}
295304

296305
@Override

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiArchiveFlatDbStrategy.java

+45-23
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@
1818
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_INFO_STATE_ARCHIVE;
1919
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_STORAGE_ARCHIVE;
2020
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.ACCOUNT_STORAGE_STORAGE;
21+
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE;
22+
import static org.hyperledger.besu.ethereum.trie.diffbased.common.storage.DiffBasedWorldStateKeyValueStorage.WORLD_BLOCK_NUMBER_KEY;
2123

2224
import org.hyperledger.besu.datatypes.Hash;
2325
import org.hyperledger.besu.datatypes.StorageSlotKey;
24-
import org.hyperledger.besu.ethereum.core.BlockHeader;
2526
import org.hyperledger.besu.ethereum.trie.NodeLoader;
2627
import org.hyperledger.besu.ethereum.trie.diffbased.common.BonsaiContext;
2728
import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy;
@@ -31,6 +32,7 @@
3132
import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorage;
3233
import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction;
3334

35+
import java.nio.charset.StandardCharsets;
3436
import java.util.Optional;
3537
import java.util.function.Function;
3638
import java.util.function.Supplier;
@@ -44,18 +46,14 @@
4446
import org.slf4j.LoggerFactory;
4547

4648
public class BonsaiArchiveFlatDbStrategy extends BonsaiFullFlatDbStrategy {
47-
private final BonsaiContext context;
4849
private static final Logger LOG = LoggerFactory.getLogger(BonsaiArchiveFlatDbStrategy.class);
4950

5051
protected final Counter getAccountFromArchiveCounter;
5152
protected final Counter getStorageFromArchiveCounter;
5253

5354
public BonsaiArchiveFlatDbStrategy(
54-
final BonsaiContext context,
55-
final MetricsSystem metricsSystem,
56-
final CodeStorageStrategy codeStorageStrategy) {
55+
final MetricsSystem metricsSystem, final CodeStorageStrategy codeStorageStrategy) {
5756
super(metricsSystem, codeStorageStrategy);
58-
this.context = context;
5957

6058
getAccountFromArchiveCounter =
6159
metricsSystem.createCounter(
@@ -76,6 +74,26 @@ public BonsaiArchiveFlatDbStrategy(
7674
public static final byte[] DELETED_CODE_VALUE = new byte[0];
7775
public static final byte[] DELETED_STORAGE_VALUE = new byte[0];
7876

77+
public Optional<BonsaiContext> getStateArchiveContext(final SegmentedKeyValueStorage storage) {
78+
// For Bonsai archive update the flat DB strategy context to match the block the state/storage
79+
// represents
80+
Optional<byte[]> archiveContext = storage.get(TRIE_BRANCH_STORAGE, WORLD_BLOCK_NUMBER_KEY);
81+
if (archiveContext.isPresent()) {
82+
try {
83+
// keyNearest, use MAX_BLOCK_SUFFIX in the absence of a block context:
84+
return Optional.of(
85+
new BonsaiContext(
86+
Long.decode("0x" + (new String(archiveContext.get(), StandardCharsets.UTF_8)))));
87+
} catch (NumberFormatException e) {
88+
throw new IllegalStateException(
89+
"World state archive context invalid format: "
90+
+ new String(archiveContext.get(), StandardCharsets.UTF_8));
91+
}
92+
}
93+
94+
throw new IllegalStateException("World state missing archive context");
95+
}
96+
7997
@Override
8098
public Optional<Bytes> getFlatAccount(
8199
final Supplier<Optional<Bytes>> worldStateRootHashSupplier,
@@ -87,7 +105,9 @@ public Optional<Bytes> getFlatAccount(
87105
Optional<Bytes> accountFound;
88106

89107
// keyNearest, use MAX_BLOCK_SUFFIX in the absence of a block context:
90-
Bytes keyNearest = calculateArchiveKeyWithMaxSuffix(context, accountHash.toArrayUnsafe());
108+
Bytes keyNearest =
109+
calculateArchiveKeyWithMaxSuffix(
110+
getStateArchiveContext(storage).get(), accountHash.toArrayUnsafe());
91111

92112
// Find the nearest account state for this address and block context
93113
Optional<SegmentedKeyValueStorage.NearestKeyValue> nearestAccount =
@@ -229,22 +249,29 @@ protected Stream<Pair<Bytes32, Bytes>> storageToPairStream(
229249
*/
230250
@Override
231251
public void putFlatAccount(
252+
final SegmentedKeyValueStorage storage,
232253
final SegmentedKeyValueStorageTransaction transaction,
233254
final Hash accountHash,
234255
final Bytes accountValue) {
235256

236257
// key suffixed with block context, or MIN_BLOCK_SUFFIX if we have no context:
237-
byte[] keySuffixed = calculateArchiveKeyWithMinSuffix(context, accountHash.toArrayUnsafe());
258+
byte[] keySuffixed =
259+
calculateArchiveKeyWithMinSuffix(
260+
getStateArchiveContext(storage).get(), accountHash.toArrayUnsafe());
238261

239262
transaction.put(ACCOUNT_INFO_STATE, keySuffixed, accountValue.toArrayUnsafe());
240263
}
241264

242265
@Override
243266
public void removeFlatAccount(
244-
final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash) {
267+
final SegmentedKeyValueStorage storage,
268+
final SegmentedKeyValueStorageTransaction transaction,
269+
final Hash accountHash) {
245270

246271
// insert a key suffixed with block context, with 'deleted account' value
247-
byte[] keySuffixed = calculateArchiveKeyWithMinSuffix(context, accountHash.toArrayUnsafe());
272+
byte[] keySuffixed =
273+
calculateArchiveKeyWithMinSuffix(
274+
getStateArchiveContext(storage).get(), accountHash.toArrayUnsafe());
248275

249276
transaction.put(ACCOUNT_INFO_STATE, keySuffixed, DELETED_ACCOUNT_VALUE);
250277
}
@@ -271,7 +298,8 @@ public Optional<Bytes> getFlatStorageValueByStorageSlotKey(
271298
// get natural key from account hash and slot key
272299
byte[] naturalKey = calculateNaturalSlotKey(accountHash, storageSlotKey.getSlotHash());
273300
// keyNearest, use MAX_BLOCK_SUFFIX in the absence of a block context:
274-
Bytes keyNearest = calculateArchiveKeyWithMaxSuffix(context, naturalKey);
301+
Bytes keyNearest =
302+
calculateArchiveKeyWithMaxSuffix(getStateArchiveContext(storage).get(), naturalKey);
275303

276304
// Find the nearest storage for this address, slot key hash, and block context
277305
Optional<SegmentedKeyValueStorage.NearestKeyValue> nearestStorage =
@@ -321,6 +349,7 @@ public Optional<Bytes> getFlatStorageValueByStorageSlotKey(
321349
*/
322350
@Override
323351
public void putFlatAccountStorageValueByStorageSlotHash(
352+
final SegmentedKeyValueStorage storage,
324353
final SegmentedKeyValueStorageTransaction transaction,
325354
final Hash accountHash,
326355
final Hash slotHash,
@@ -329,7 +358,8 @@ public void putFlatAccountStorageValueByStorageSlotHash(
329358
// get natural key from account hash and slot key
330359
byte[] naturalKey = calculateNaturalSlotKey(accountHash, slotHash);
331360
// keyNearest, use MIN_BLOCK_SUFFIX in the absence of a block context:
332-
byte[] keyNearest = calculateArchiveKeyWithMinSuffix(context, naturalKey);
361+
byte[] keyNearest =
362+
calculateArchiveKeyWithMinSuffix(getStateArchiveContext(storage).get(), naturalKey);
333363

334364
transaction.put(ACCOUNT_STORAGE_STORAGE, keyNearest, storageValue.toArrayUnsafe());
335365
}
@@ -339,14 +369,16 @@ public void putFlatAccountStorageValueByStorageSlotHash(
339369
*/
340370
@Override
341371
public void removeFlatAccountStorageValueByStorageSlotHash(
372+
final SegmentedKeyValueStorage storage,
342373
final SegmentedKeyValueStorageTransaction transaction,
343374
final Hash accountHash,
344375
final Hash slotHash) {
345376

346377
// get natural key from account hash and slot key
347378
byte[] naturalKey = calculateNaturalSlotKey(accountHash, slotHash);
348379
// insert a key suffixed with block context, with 'deleted account' value
349-
byte[] keySuffixed = calculateArchiveKeyWithMinSuffix(context, naturalKey);
380+
byte[] keySuffixed =
381+
calculateArchiveKeyWithMinSuffix(getStateArchiveContext(storage).get(), naturalKey);
350382

351383
transaction.put(ACCOUNT_STORAGE_STORAGE, keySuffixed, DELETED_STORAGE_VALUE);
352384
}
@@ -391,14 +423,4 @@ public static byte[] calculateArchiveKeyWithSuffix(
391423
return orElseSuffix;
392424
}));
393425
}
394-
395-
@Override
396-
public void updateBlockContext(final Long blockNumber) {
397-
context.setBlockNumber(blockNumber);
398-
}
399-
400-
@Override
401-
public void updateBlockContext(final BlockHeader blockHeader) {
402-
context.setBlockNumber(blockHeader.getNumber());
403-
}
404426
}

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategy.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public abstract Optional<Bytes> getFlatStorageValueByStorageSlotKey(
7171

7272
@Override
7373
public void putFlatAccount(
74+
final SegmentedKeyValueStorage storage,
7475
final SegmentedKeyValueStorageTransaction transaction,
7576
final Hash accountHash,
7677
final Bytes accountValue) {
@@ -79,12 +80,15 @@ public void putFlatAccount(
7980

8081
@Override
8182
public void removeFlatAccount(
82-
final SegmentedKeyValueStorageTransaction transaction, final Hash accountHash) {
83+
final SegmentedKeyValueStorage storage,
84+
final SegmentedKeyValueStorageTransaction transaction,
85+
final Hash accountHash) {
8386
transaction.remove(ACCOUNT_INFO_STATE, accountHash.toArrayUnsafe());
8487
}
8588

8689
@Override
8790
public void putFlatAccountStorageValueByStorageSlotHash(
91+
final SegmentedKeyValueStorage storage,
8892
final SegmentedKeyValueStorageTransaction transaction,
8993
final Hash accountHash,
9094
final Hash slotHash,
@@ -97,6 +101,7 @@ public void putFlatAccountStorageValueByStorageSlotHash(
97101

98102
@Override
99103
public void removeFlatAccountStorageValueByStorageSlotHash(
104+
final SegmentedKeyValueStorage storage,
100105
final SegmentedKeyValueStorageTransaction transaction,
101106
final Hash accountHash,
102107
final Hash slotHash) {

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFlatDbStrategyProvider.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import static org.hyperledger.besu.ethereum.storage.keyvalue.KeyValueSegmentIdentifier.TRIE_BRANCH_STORAGE;
1818

19-
import org.hyperledger.besu.ethereum.trie.diffbased.common.BonsaiContext;
2019
import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy;
2120
import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategy;
2221
import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.FlatDbStrategyProvider;
@@ -91,8 +90,7 @@ protected FlatDbStrategy createFlatDbStrategy(
9190
if (flatDbMode == FlatDbMode.FULL) {
9291
return new BonsaiFullFlatDbStrategy(metricsSystem, codeStorageStrategy);
9392
} else if (flatDbMode == FlatDbMode.ARCHIVE) {
94-
return new BonsaiArchiveFlatDbStrategy(
95-
new BonsaiContext(), metricsSystem, codeStorageStrategy);
93+
return new BonsaiArchiveFlatDbStrategy(metricsSystem, codeStorageStrategy);
9694
} else {
9795
return new BonsaiPartialFlatDbStrategy(metricsSystem, codeStorageStrategy);
9896
}

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiFullFlatDbStrategy.java

-11
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import org.hyperledger.besu.datatypes.Hash;
2121
import org.hyperledger.besu.datatypes.StorageSlotKey;
22-
import org.hyperledger.besu.ethereum.core.BlockHeader;
2322
import org.hyperledger.besu.ethereum.trie.NodeLoader;
2423
import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy;
2524
import org.hyperledger.besu.metrics.BesuMetricCategory;
@@ -101,14 +100,4 @@ public void resetOnResync(final SegmentedKeyValueStorage storage) {
101100
// NOOP
102101
// not need to reset anything in full mode
103102
}
104-
105-
@Override
106-
public void updateBlockContext(final Long blockNumber) {
107-
// default no-op for strategies that do not care about bonsai context
108-
}
109-
110-
@Override
111-
public void updateBlockContext(final BlockHeader blockHeader) {
112-
// default no-op for strategies that do not care about bonsai context
113-
}
114103
}

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/storage/flat/BonsaiPartialFlatDbStrategy.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import org.hyperledger.besu.datatypes.Hash;
2121
import org.hyperledger.besu.datatypes.StorageSlotKey;
22-
import org.hyperledger.besu.ethereum.core.BlockHeader;
2322
import org.hyperledger.besu.ethereum.trie.NodeLoader;
2423
import org.hyperledger.besu.ethereum.trie.diffbased.common.storage.flat.CodeStorageStrategy;
2524
import org.hyperledger.besu.ethereum.trie.patricia.StoredMerklePatriciaTrie;
@@ -146,6 +145,7 @@ public Optional<Bytes> getFlatStorageValueByStorageSlotKey(
146145
return response;
147146
}
148147

148+
/*
149149
@Override
150150
public void updateBlockContext(final Long blockNumber) {
151151
// Not implemented
@@ -154,5 +154,5 @@ public void updateBlockContext(final Long blockNumber) {
154154
@Override
155155
public void updateBlockContext(final BlockHeader blockHeader) {
156156
// Not implemented
157-
}
157+
}*/
158158
}

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/bonsai/worldview/BonsaiWorldState.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,10 @@ public Hash frontierRootHash() {
384384
return calculateRootHash(
385385
Optional.of(
386386
new BonsaiWorldStateKeyValueStorage.Updater(
387-
noOpSegmentedTx, noOpTx, worldStateKeyValueStorage.getFlatDbStrategy())),
387+
noOpSegmentedTx,
388+
noOpTx,
389+
worldStateKeyValueStorage.getFlatDbStrategy(),
390+
worldStateKeyValueStorage.getComposedWorldStateStorage())),
388391
accumulator.copy());
389392
}
390393

0 commit comments

Comments
 (0)