Skip to content

Commit 89a3c1b

Browse files
committed
Apply BAL overlay after world state rolling and fix cherry-pick integration.
Attach BlockAccessListOverlay via PathBasedWorldStateProvider only after trie-log roll completes, simplify cache manager APIs, and align CLI/tests with the simplified BAL configuration without f0005e78. Signed-off-by: Karim Taam <karim.t2am@gmail.com>
1 parent e088e8e commit 89a3c1b

14 files changed

Lines changed: 94 additions & 409 deletions

File tree

app/src/main/java/org/hyperledger/besu/cli/options/BalConfigurationOptions.java

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
import org.hyperledger.besu.ethereum.mainnet.BalConfiguration;
1818
import org.hyperledger.besu.ethereum.mainnet.ImmutableBalConfiguration;
1919

20-
import java.time.Duration;
21-
2220
import picocli.CommandLine;
2321

2422
/** Command-line options for configuring Block Access List behaviour. */
@@ -47,20 +45,6 @@ public BalConfigurationOptions() {}
4745
description = "Log the constructed and block's BAL when they differ.")
4846
boolean balLogBalsOnMismatch = false;
4947

50-
@CommandLine.Option(
51-
names = {"--Xbal-state-root-timeout"},
52-
hidden = true,
53-
paramLabel = "<INTEGER>",
54-
description = "Timeout in milliseconds when waiting for the BAL-computed state root.")
55-
private long balStateRootTimeoutMs = -1;
56-
57-
@CommandLine.Option(
58-
names = {"--Xbal-processing-timeout"},
59-
hidden = true,
60-
paramLabel = "<INTEGER>",
61-
description = "Timeout in milliseconds when waiting for BAL transaction processing results.")
62-
private long balProcessingTimeoutMs = -1;
63-
6448
@CommandLine.Option(
6549
names = {"--Xbal-prefetch-reading-enabled"},
6650
hidden = true,
@@ -78,7 +62,7 @@ public BalConfigurationOptions() {}
7862
names = {"--Xbal-prefetch-batch-size"},
7963
hidden = true,
8064
description = "Enable custom BAL prefetch batch size (default: ${DEFAULT-VALUE}).")
81-
int balPreFetchBatch = 100;
65+
int balPreFetchBatch = 8;
8266

8367
/**
8468
* Builds the immutable {@link BalConfiguration} corresponding to the parsed CLI options.
@@ -93,8 +77,6 @@ public BalConfiguration toDomainObject() {
9377
.isBalPreFetchReadingEnabled(balPreFetchReadingEnabled)
9478
.isBalPreFetchSortingEnabled(balPreFetchSortingEnabled)
9579
.balPreFetchBatchSize(balPreFetchBatch)
96-
.balStateRootTimeout(Duration.ofMillis(balStateRootTimeoutMs))
97-
.balProcessingTimeout(Duration.ofMillis(balProcessingTimeoutMs))
9880
.build();
9981
}
10082
}

app/src/test/java/org/hyperledger/besu/RunnerTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ private StorageProvider createKeyValueStorageProvider(
413413
DEFAULT_IS_HIGH_SPEC,
414414
DEFAULT_ENABLE_READ_CACHE_FOR_SNAPSHOTS,
415415
false,
416+
false,
416417
Optional.empty(),
417418
Optional.empty()),
418419
Arrays.asList(KeyValueSegmentIdentifier.values()),

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/staterootcommitter/BalStateRootCommitterFactory.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.hyperledger.besu.datatypes.Hash;
1818
import org.hyperledger.besu.ethereum.ProtocolContext;
19+
import org.hyperledger.besu.ethereum.core.MutableWorldState;
1920
import org.hyperledger.besu.ethereum.mainnet.BalConfiguration;
2021
import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessList;
2122
import org.hyperledger.besu.ethereum.trie.forest.ForestWorldStateArchive;
@@ -27,8 +28,6 @@
2728
import org.hyperledger.besu.ethereum.trie.pathbased.common.worldview.accumulator.PathBasedWorldStateUpdateAccumulator;
2829
import org.hyperledger.besu.plugin.data.BlockHeader;
2930
import org.hyperledger.besu.plugin.services.storage.WorldStateKeyValueStorage;
30-
import org.hyperledger.besu.plugin.services.worldstate.MutableWorldState;
31-
import org.hyperledger.besu.plugin.services.worldstate.StateRootCommitter;
3231

3332
import java.util.Optional;
3433
import java.util.concurrent.CompletableFuture;

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/pathbased/bonsai/BonsaiCachedWorldStorageManager.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
*/
1515
package org.hyperledger.besu.ethereum.trie.pathbased.bonsai;
1616

17-
import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessListOverlay;
1817
import org.hyperledger.besu.ethereum.trie.pathbased.bonsai.cache.CodeCache;
1918
import org.hyperledger.besu.ethereum.trie.pathbased.bonsai.storage.BonsaiSnapshotWorldStateKeyValueStorage;
2019
import org.hyperledger.besu.ethereum.trie.pathbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
@@ -27,7 +26,6 @@
2726
import org.hyperledger.besu.ethereum.trie.pathbased.common.worldview.WorldStateConfig;
2827
import org.hyperledger.besu.evm.internal.EvmConfiguration;
2928

30-
import java.util.Optional;
3129
import java.util.concurrent.ConcurrentHashMap;
3230

3331
public class BonsaiCachedWorldStorageManager extends PathBasedCachedWorldStorageManager {
@@ -53,15 +51,13 @@ public BonsaiCachedWorldStorageManager(
5351
public PathBasedWorldState createWorldState(
5452
final PathBasedWorldStateProvider archive,
5553
final PathBasedWorldStateKeyValueStorage worldStateKeyValueStorage,
56-
final EvmConfiguration evmConfiguration,
57-
final Optional<BlockAccessListOverlay> maybeBlockAccessListOverlay) {
54+
final EvmConfiguration evmConfiguration) {
5855
return new BonsaiWorldState(
5956
(BonsaiWorldStateProvider) archive,
6057
(BonsaiWorldStateKeyValueStorage) worldStateKeyValueStorage,
6158
evmConfiguration,
6259
WorldStateConfig.newBuilder(worldStateConfig).build(),
63-
codeCache,
64-
maybeBlockAccessListOverlay);
60+
codeCache);
6561
}
6662

6763
@Override

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/pathbased/bonsai/NoOpBonsaiCachedWorldStorageManager.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package org.hyperledger.besu.ethereum.trie.pathbased.bonsai;
1616

1717
import org.hyperledger.besu.datatypes.Hash;
18-
import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessListOverlay;
1918
import org.hyperledger.besu.ethereum.trie.pathbased.bonsai.cache.CodeCache;
2019
import org.hyperledger.besu.ethereum.trie.pathbased.bonsai.storage.BonsaiWorldStateKeyValueStorage;
2120
import org.hyperledger.besu.ethereum.trie.pathbased.common.worldview.PathBasedWorldState;

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

Lines changed: 20 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -66,38 +66,22 @@ public class BonsaiWorldState extends PathBasedWorldState {
6666

6767
protected BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader;
6868
private final CodeCache codeCache;
69+
private final EvmConfiguration evmConfiguration;
6970

7071
public BonsaiWorldState(
7172
final BonsaiWorldStateProvider archive,
7273
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage,
7374
final EvmConfiguration evmConfiguration,
7475
final WorldStateConfig worldStateConfig,
7576
final CodeCache codeCache) {
76-
this(
77-
archive,
78-
worldStateKeyValueStorage,
79-
evmConfiguration,
80-
worldStateConfig,
81-
codeCache,
82-
Optional.empty());
83-
}
84-
85-
public BonsaiWorldState(
86-
final BonsaiWorldStateProvider archive,
87-
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage,
88-
final EvmConfiguration evmConfiguration,
89-
final WorldStateConfig worldStateConfig,
90-
final CodeCache codeCache,
91-
final Optional<BlockAccessListOverlay> maybeBlockAccessListOverlay) {
9277
this(
9378
worldStateKeyValueStorage,
9479
archive.getCachedMerkleTrieLoader(),
9580
archive.getCachedWorldStorageManager(),
9681
archive.getTrieLogManager(),
9782
evmConfiguration,
9883
worldStateConfig,
99-
codeCache,
100-
maybeBlockAccessListOverlay);
84+
codeCache);
10185
}
10286

10387
public BonsaiWorldState(
@@ -108,51 +92,31 @@ public BonsaiWorldState(
10892
final EvmConfiguration evmConfiguration,
10993
final WorldStateConfig worldStateConfig,
11094
final CodeCache codeCache) {
111-
this(
112-
worldStateKeyValueStorage,
113-
bonsaiCachedMerkleTrieLoader,
114-
cachedWorldStorageManager,
115-
trieLogManager,
116-
evmConfiguration,
117-
worldStateConfig,
118-
codeCache,
119-
Optional.empty());
120-
}
121-
122-
public BonsaiWorldState(
123-
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage,
124-
final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader,
125-
final PathBasedCachedWorldStorageManager cachedWorldStorageManager,
126-
final TrieLogManager trieLogManager,
127-
final EvmConfiguration evmConfiguration,
128-
final WorldStateConfig worldStateConfig,
129-
final CodeCache codeCache,
130-
final Optional<BlockAccessListOverlay> maybeBlockAccessListOverlay) {
13195
super(worldStateKeyValueStorage, cachedWorldStorageManager, trieLogManager, worldStateConfig);
13296
this.bonsaiCachedMerkleTrieLoader = bonsaiCachedMerkleTrieLoader;
13397
this.worldStateKeyValueStorage = worldStateKeyValueStorage;
98+
this.evmConfiguration = evmConfiguration;
13499
this.setAccumulator(
135-
maybeBlockAccessListOverlay
136-
.map(
137-
overlay ->
138-
(BonsaiWorldStateUpdateAccumulator)
139-
new BonsaiBalWorldStateUpdateAccumulator(
140-
this, evmConfiguration, codeCache, overlay))
141-
.orElseGet(
142-
() ->
143-
new BonsaiWorldStateUpdateAccumulator(
144-
this,
145-
(addr, value) ->
146-
this.bonsaiCachedMerkleTrieLoader.preLoadAccount(
147-
getWorldStateStorage(), worldStateRootHash, addr),
148-
(addr, value) ->
149-
this.bonsaiCachedMerkleTrieLoader.preLoadStorageSlot(
150-
getWorldStateStorage(), addr, value),
151-
evmConfiguration,
152-
codeCache)));
100+
new BonsaiWorldStateUpdateAccumulator(
101+
this,
102+
(addr, value) ->
103+
this.bonsaiCachedMerkleTrieLoader.preLoadAccount(
104+
getWorldStateStorage(), worldStateRootHash, addr),
105+
(addr, value) ->
106+
this.bonsaiCachedMerkleTrieLoader.preLoadStorageSlot(
107+
getWorldStateStorage(), addr, value),
108+
evmConfiguration,
109+
codeCache));
153110
this.codeCache = codeCache;
154111
}
155112

113+
@Override
114+
public void applyBlockAccessListOverlay(final BlockAccessListOverlay blockAccessListOverlay) {
115+
setAccumulator(
116+
new BonsaiBalWorldStateUpdateAccumulator(
117+
this, evmConfiguration, codeCache, blockAccessListOverlay));
118+
}
119+
156120
@Override
157121
public Optional<Bytes> getCode(@NotNull final Address address, final Hash codeHash) {
158122
return getWorldStateStorage().getCode(codeHash, address.addressHash());

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/pathbased/common/cache/PathBasedCachedWorldStorageManager.java

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import org.hyperledger.besu.datatypes.Hash;
2020
import org.hyperledger.besu.ethereum.chain.Blockchain;
21-
import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessListOverlay;
2221
import org.hyperledger.besu.ethereum.trie.pathbased.bonsai.worldview.BonsaiWorldState;
2322
import org.hyperledger.besu.ethereum.trie.pathbased.common.StorageSubscriber;
2423
import org.hyperledger.besu.ethereum.trie.pathbased.common.provider.PathBasedWorldStateProvider;
@@ -134,11 +133,6 @@ private synchronized void scrubCachedLayers(final long newMaxHeight) {
134133
}
135134

136135
public Optional<PathBasedWorldState> getWorldState(final Hash blockHash) {
137-
return getWorldState(blockHash, Optional.empty());
138-
}
139-
140-
public Optional<PathBasedWorldState> getWorldState(
141-
final Hash blockHash, final Optional<BlockAccessListOverlay> maybeBlockAccessListOverlay) {
142136
if (cachedWorldStatesByHash.containsKey(blockHash)) {
143137
// return a new worldstate using worldstate storage and an isolated copy of the updater
144138
return Optional.ofNullable(cachedWorldStatesByHash.get(blockHash))
@@ -147,8 +141,7 @@ public Optional<PathBasedWorldState> getWorldState(
147141
createWorldState(
148142
archive,
149143
createLayeredKeyValueStorage(cached.getWorldStateStorage()),
150-
evmConfiguration,
151-
maybeBlockAccessListOverlay));
144+
evmConfiguration));
152145
}
153146
LOG.atDebug()
154147
.setMessage("did not find worldstate in cache for {}")
@@ -159,12 +152,6 @@ public Optional<PathBasedWorldState> getWorldState(
159152
}
160153

161154
public Optional<PathBasedWorldState> getNearestWorldState(final BlockHeader blockHeader) {
162-
return getNearestWorldState(blockHeader, Optional.empty());
163-
}
164-
165-
public Optional<PathBasedWorldState> getNearestWorldState(
166-
final BlockHeader blockHeader,
167-
final Optional<BlockAccessListOverlay> maybeBlockAccessListOverlay) {
168155
LOG.atDebug()
169156
.setMessage("getting nearest worldstate for {}")
170157
.addArgument(blockHeader::toLogString)
@@ -193,15 +180,11 @@ public Optional<PathBasedWorldState> getNearestWorldState(
193180
.map(
194181
storage ->
195182
createWorldState( // wrap the state in a layered worldstate
196-
archive,
197-
createLayeredKeyValueStorage(storage),
198-
evmConfiguration,
199-
maybeBlockAccessListOverlay));
183+
archive, createLayeredKeyValueStorage(storage), evmConfiguration));
200184
}
201185

202186
public Optional<PathBasedWorldState> getHeadWorldState(
203-
final Function<Hash, Optional<BlockHeader>> hashBlockHeaderFunction,
204-
final Optional<BlockAccessListOverlay> maybeBlockAccessListOverlay) {
187+
final Function<Hash, Optional<BlockHeader>> hashBlockHeaderFunction) {
205188

206189
LOG.atDebug().setMessage("getting head worldstate").log();
207190

@@ -215,7 +198,7 @@ public Optional<PathBasedWorldState> getHeadWorldState(
215198
blockHeader,
216199
blockHeader.getStateRoot(),
217200
createWorldState(archive, rootWorldStateStorage, evmConfiguration));
218-
return getWorldState(blockHeader.getBlockHash(), maybeBlockAccessListOverlay);
201+
return getWorldState(blockHeader.getBlockHash());
219202
});
220203
}
221204

@@ -290,18 +273,10 @@ public void onCloseStorage() {
290273
this.cachedWorldStatesByHash.clear();
291274
}
292275

293-
public PathBasedWorldState createWorldState(
294-
final PathBasedWorldStateProvider archive,
295-
final PathBasedWorldStateKeyValueStorage worldStateKeyValueStorage,
296-
final EvmConfiguration evmConfiguration) {
297-
return createWorldState(archive, worldStateKeyValueStorage, evmConfiguration, Optional.empty());
298-
}
299-
300276
public abstract PathBasedWorldState createWorldState(
301277
final PathBasedWorldStateProvider archive,
302278
final PathBasedWorldStateKeyValueStorage worldStateKeyValueStorage,
303-
final EvmConfiguration evmConfiguration,
304-
final Optional<BlockAccessListOverlay> maybeBlockAccessListOverlay);
279+
final EvmConfiguration evmConfiguration);
305280

306281
public abstract PathBasedWorldStateKeyValueStorage createLayeredKeyValueStorage(
307282
final PathBasedWorldStateKeyValueStorage worldStateKeyValueStorage);

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/pathbased/common/provider/PathBasedWorldStateProvider.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ protected Optional<MutableWorldState> getFullWorldState(final WorldStateQueryPar
208208
* @return the full world state, if available
209209
*/
210210
private Optional<MutableWorldState> getFullWorldStateFromHead(final Hash blockHash) {
211-
return rollFullWorldStateToBlockHash(headWorldState, blockHash);
211+
return rollFullWorldStateToBlockHash(headWorldState, blockHash)
212+
.map(MutableWorldState.class::cast);
212213
}
213214

214215
/**
@@ -244,23 +245,26 @@ private Optional<MutableWorldState> getFullWorldStateFromCache(
244245
return Optional.empty();
245246
}
246247
return cachedWorldStorageManager
247-
.getWorldState(blockHeader.getBlockHash(), maybeBlockAccessListOverlay)
248-
.or(
249-
() ->
250-
cachedWorldStorageManager.getNearestWorldState(
251-
blockHeader, maybeBlockAccessListOverlay))
248+
.getWorldState(blockHeader.getBlockHash())
249+
.or(() -> cachedWorldStorageManager.getNearestWorldState(blockHeader))
252250
.or(
253251
() ->
254252
cachedWorldStorageManager.getHeadWorldState(
255253
blockHeaderHash ->
256-
blockchain.getBlockHeader(blockHeaderHash).map(BlockHeader.class::cast),
257-
maybeBlockAccessListOverlay))
254+
blockchain.getBlockHeader(blockHeaderHash).map(BlockHeader.class::cast)))
258255
.flatMap(
259256
worldState -> rollFullWorldStateToBlockHash(worldState, blockHeader.getBlockHash()))
257+
.map(
258+
worldState -> {
259+
// the BAL overlay is attached only once the world state has been rolled to the
260+
// target block, so overlay values never interfere with trie-log replay
261+
maybeBlockAccessListOverlay.ifPresent(worldState::applyBlockAccessListOverlay);
262+
return worldState;
263+
})
260264
.map(MutableWorldState::freezeStorage);
261265
}
262266

263-
private Optional<MutableWorldState> rollFullWorldStateToBlockHash(
267+
private Optional<PathBasedWorldState> rollFullWorldStateToBlockHash(
264268
final PathBasedWorldState mutableState, final Hash blockHash) {
265269
if (blockHash.equals(mutableState.blockHash())) {
266270
return Optional.of(mutableState);

ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/pathbased/common/worldview/PathBasedWorldState.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.hyperledger.besu.datatypes.Hash;
2424
import org.hyperledger.besu.datatypes.StorageSlotKey;
2525
import org.hyperledger.besu.ethereum.core.MutableWorldState;
26+
import org.hyperledger.besu.ethereum.mainnet.block.access.list.BlockAccessListOverlay;
2627
import org.hyperledger.besu.ethereum.mainnet.staterootcommitter.StateRootCommitter;
2728
import org.hyperledger.besu.ethereum.trie.common.StateRootMismatchException;
2829
import org.hyperledger.besu.ethereum.trie.pathbased.common.StorageSubscriber;
@@ -423,5 +424,14 @@ public abstract Hash calculateRootHash(
423424
final Optional<PathBasedWorldStateKeyValueStorage.Updater> maybeStateUpdater,
424425
final PathBasedWorldStateUpdateAccumulator<?> worldStateUpdater);
425426

427+
/**
428+
* Attaches a Block Access List overlay to this world state, replacing its accumulator with a
429+
* BAL-aware one. Must be called after the world state has been resolved (and rolled) to the
430+
* target block, so that overlay values never interfere with trie-log replay.
431+
*
432+
* @param blockAccessListOverlay the overlay to attach
433+
*/
434+
public abstract void applyBlockAccessListOverlay(BlockAccessListOverlay blockAccessListOverlay);
435+
426436
protected abstract Hash getEmptyTrieHash();
427437
}

0 commit comments

Comments
 (0)