1919import static org .hyperledger .besu .ethereum .storage .keyvalue .KeyValueSegmentIdentifier .CODE_STORAGE ;
2020import static org .hyperledger .besu .ethereum .storage .keyvalue .KeyValueSegmentIdentifier .TRIE_BRANCH_STORAGE ;
2121
22- import org .apache . tuweni . units . bigints . UInt256 ;
22+ import org .hyperledger . besu . datatypes . Address ;
2323import org .hyperledger .besu .datatypes .Hash ;
2424import org .hyperledger .besu .datatypes .StorageSlotKey ;
25+ import org .hyperledger .besu .ethereum .bonsai .BonsaiAccount ;
2526import org .hyperledger .besu .ethereum .bonsai .storage .flat .FlatDbReaderStrategy ;
2627import org .hyperledger .besu .ethereum .bonsai .storage .flat .FullFlatDbReaderStrategy ;
2728import org .hyperledger .besu .ethereum .bonsai .storage .flat .PartialFlatDbReaderStrategy ;
29+ import org .hyperledger .besu .ethereum .bonsai .worldview .BonsaiWorldView ;
2830import org .hyperledger .besu .ethereum .storage .StorageProvider ;
2931import org .hyperledger .besu .ethereum .storage .keyvalue .KeyValueSegmentIdentifier ;
3032import org .hyperledger .besu .ethereum .trie .MerkleTrie ;
3335import org .hyperledger .besu .ethereum .worldstate .StateTrieAccountValue ;
3436import org .hyperledger .besu .ethereum .worldstate .WorldStateStorage ;
3537import org .hyperledger .besu .evm .account .AccountStorageEntry ;
38+ import org .hyperledger .besu .evm .worldstate .WorldState ;
3639import org .hyperledger .besu .metrics .ObservableMetricsSystem ;
3740import org .hyperledger .besu .plugin .services .storage .KeyValueStorage ;
3841import org .hyperledger .besu .plugin .services .storage .KeyValueStorageTransaction ;
4144import org .hyperledger .besu .util .Subscribers ;
4245
4346import java .nio .charset .StandardCharsets ;
47+ import java .util .Comparator ;
4448import java .util .List ;
4549import java .util .Map ;
4650import java .util .NavigableMap ;
4751import java .util .Optional ;
4852import java .util .TreeMap ;
4953import java .util .concurrent .atomic .AtomicBoolean ;
50- import java .util .function .Function ;
5154import java .util .function .Predicate ;
5255import java .util .function .Supplier ;
5356import java .util .stream .Collectors ;
57+ import java .util .stream .Stream ;
5458
5559import org .apache .tuweni .bytes .Bytes ;
5660import org .apache .tuweni .bytes .Bytes32 ;
61+ import org .apache .tuweni .units .bigints .UInt256 ;
5762import org .slf4j .Logger ;
5863import org .slf4j .LoggerFactory ;
5964
6065@ SuppressWarnings ("unused" )
6166public class BonsaiWorldStateKeyValueStorage implements WorldStateStorage , AutoCloseable {
62- Bytes32 BYTES32_MAX_VALUE = Bytes32 .fromHexString ("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" );
67+ Bytes32 BYTES32_MAX_VALUE =
68+ Bytes32 .fromHexString ("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" );
6369 private static final Logger LOG = LoggerFactory .getLogger (BonsaiWorldStateKeyValueStorage .class );
6470
6571 // 0x776f726c64526f6f74
@@ -85,18 +91,25 @@ public class BonsaiWorldStateKeyValueStorage implements WorldStateStorage, AutoC
8591
8692 protected final Subscribers <BonsaiStorageSubscriber > subscribers = Subscribers .create ();
8793
88- // no-op default hash preImage mapper:
89- protected Function <Hash , Optional <Bytes >> hashPreImageMapper = __ -> Optional .empty ();
94+ final BonsaiPreImageProxy preImageProxy ;
9095
9196 public BonsaiWorldStateKeyValueStorage (
9297 final StorageProvider provider , final ObservableMetricsSystem metricsSystem ) {
98+ this (provider , metricsSystem , new BonsaiPreImageProxy .NoOpPreImageProxy ());
99+ }
100+
101+ public BonsaiWorldStateKeyValueStorage (
102+ final StorageProvider provider ,
103+ final ObservableMetricsSystem metricsSystem ,
104+ final BonsaiPreImageProxy preImageProxy ) {
93105 this .composedWorldStateStorage =
94106 provider .getStorageBySegmentIdentifiers (
95107 List .of (
96108 ACCOUNT_INFO_STATE , CODE_STORAGE , ACCOUNT_STORAGE_STORAGE , TRIE_BRANCH_STORAGE ));
97109 this .trieLogStorage =
98110 provider .getStorageBySegmentIdentifier (KeyValueSegmentIdentifier .TRIE_LOG_STORAGE );
99111 this .metricsSystem = metricsSystem ;
112+ this .preImageProxy = preImageProxy ;
100113 loadFlatDbStrategy ();
101114 }
102115
@@ -105,12 +118,14 @@ public BonsaiWorldStateKeyValueStorage(
105118 final FlatDbReaderStrategy flatDbReaderStrategy ,
106119 final SegmentedKeyValueStorage composedWorldStateStorage ,
107120 final KeyValueStorage trieLogStorage ,
108- final ObservableMetricsSystem metricsSystem ) {
121+ final ObservableMetricsSystem metricsSystem ,
122+ final BonsaiPreImageProxy preImageProxy ) {
109123 this .flatDbMode = flatDbMode ;
110124 this .flatDbReaderStrategy = flatDbReaderStrategy ;
111125 this .composedWorldStateStorage = composedWorldStateStorage ;
112126 this .trieLogStorage = trieLogStorage ;
113127 this .metricsSystem = metricsSystem ;
128+ this .preImageProxy = preImageProxy ;
114129 }
115130
116131 public void loadFlatDbStrategy () {
@@ -267,31 +282,42 @@ public Map<Bytes32, Bytes> streamFlatStorages(
267282 composedWorldStateStorage , accountHash , startKeyHash , endKeyHash , max );
268283 }
269284
270- /**
271- * Provide a function to map hash values to an Optional wrapping their corresponding preImage
272- * or empty if the preImage is not available.
273- *
274- * @param hashPreImageMapper preImage mapper function
275- */
276- public void setPreImageMapper (final Function <Hash , Optional <Bytes >> hashPreImageMapper ) {
277- this .hashPreImageMapper = hashPreImageMapper ;
278- }
279-
280- public NavigableMap <Bytes32 , AccountStorageEntry > storageEntriesFrom (final Hash addressHash ,
281- final Bytes32 startKeyHash , final int limit ) {
282- return streamFlatStorages (addressHash , startKeyHash , BYTES32_MAX_VALUE , limit )
283- .entrySet ()
284- .stream ()
285- .collect (Collectors .toMap (
285+ public NavigableMap <Bytes32 , AccountStorageEntry > storageEntriesFrom (
286+ final Hash addressHash , final Bytes32 startKeyHash , final int limit ) {
287+ return streamFlatStorages (addressHash , startKeyHash , BYTES32_MAX_VALUE , limit )
288+ .entrySet ()
289+ // map back to slot keys using preImage provider:
290+ .stream ()
291+ .collect (
292+ Collectors .toMap (
286293 e -> e .getKey (),
287- e -> AccountStorageEntry .create (
288- UInt256 .fromBytes (e .getValue ()),
289- Hash .wrap (e .getKey ()),
290- hashPreImageMapper .apply (Hash .wrap (e .getKey ()))
291- .map (UInt256 ::fromBytes )),
292- (a ,b ) -> a ,
293- TreeMap ::new
294- ));
294+ e ->
295+ AccountStorageEntry .create (
296+ UInt256 .fromBytes (e .getValue ()),
297+ Hash .wrap (e .getKey ()),
298+ preImageProxy .getStorageTrieKeyPreimage (e .getKey ())),
299+ (a , b ) -> a ,
300+ TreeMap ::new ));
301+ }
302+
303+ public Stream <WorldState .StreamableAccount > streamAccounts (
304+ final BonsaiWorldView context , final Bytes32 startKeyHash , final int limit ) {
305+ return streamFlatAccounts (startKeyHash , BYTES32_MAX_VALUE , Long .MAX_VALUE )
306+ .entrySet ()
307+ // map back to addresses using preImage provider:
308+ .stream ()
309+ .map (
310+ entry ->
311+ preImageProxy
312+ .getAccountTrieKeyPreimage (entry .getKey ())
313+ .map (
314+ address ->
315+ new WorldState .StreamableAccount (
316+ Optional .of (address ),
317+ BonsaiAccount .fromRLP (context , address , entry .getValue (), false ))))
318+ .filter (Optional ::isPresent )
319+ .map (Optional ::get )
320+ .sorted (Comparator .comparing (account -> account .getAddress ().orElse (Address .ZERO )));
295321 }
296322
297323 @ Override
0 commit comments