@ -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