Skip to content

Commit

Permalink
Multiple deletes of the same address in a single block causes Bonsai …
Browse files Browse the repository at this point in the history
…to fail the block

Signed-off-by: Matthew Whitehead <matthew1001@gmail.com>
  • Loading branch information
matthew1001 committed Oct 8, 2024
1 parent 75e57cc commit a6552df
Showing 1 changed file with 31 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,15 @@
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.rlp.RLP;
import org.apache.tuweni.units.bigints.UInt256;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BonsaiWorldState extends DiffBasedWorldState {

protected final BonsaiCachedMerkleTrieLoader bonsaiCachedMerkleTrieLoader;

private static final Logger LOG = LoggerFactory.getLogger(BonsaiWorldState.class);

public BonsaiWorldState(
final BonsaiWorldStateProvider archive,
final BonsaiWorldStateKeyValueStorage worldStateKeyValueStorage,
Expand Down Expand Up @@ -337,28 +341,34 @@ private void clearStorage(
try {
final StorageConsumingMap<StorageSlotKey, DiffBasedValue<UInt256>> storageToDelete =
worldStateUpdater.getStorageToUpdate().get(address);
Map<Bytes32, Bytes> entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256);
while (!entriesToDelete.isEmpty()) {
entriesToDelete.forEach(
(k, v) -> {
final StorageSlotKey storageSlotKey =
new StorageSlotKey(Hash.wrap(k), Optional.empty());
final UInt256 slotValue = UInt256.fromBytes(Bytes32.leftPad(RLP.decodeValue(v)));
maybeStateUpdater.ifPresent(
bonsaiUpdater ->
bonsaiUpdater.removeStorageValueBySlotHash(
address.addressHash(), storageSlotKey.getSlotHash()));
storageToDelete
.computeIfAbsent(
storageSlotKey, key -> new DiffBasedValue<>(slotValue, null, true))
.setPrior(slotValue);
});
entriesToDelete.keySet().forEach(storageTrie::remove);
if (entriesToDelete.size() == 256) {
entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256);
} else {
break;
if (storageToDelete != null) {
Map<Bytes32, Bytes> entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256);
while (!entriesToDelete.isEmpty()) {
entriesToDelete.forEach(
(k, v) -> {
final StorageSlotKey storageSlotKey =
new StorageSlotKey(Hash.wrap(k), Optional.empty());
final UInt256 slotValue = UInt256.fromBytes(Bytes32.leftPad(RLP.decodeValue(v)));
maybeStateUpdater.ifPresent(
bonsaiUpdater ->
bonsaiUpdater.removeStorageValueBySlotHash(
address.addressHash(), storageSlotKey.getSlotHash()));
storageToDelete
.computeIfAbsent(
storageSlotKey, key -> new DiffBasedValue<>(slotValue, null, true))
.setPrior(slotValue);
});
entriesToDelete.keySet().forEach(storageTrie::remove);
if (entriesToDelete.size() == 256) {
entriesToDelete = storageTrie.entriesFrom(Bytes32.ZERO, 256);
} else {
break;
}
}
} else {
LOG.warn(
"No storage entries to delete for deleted address {}. Address storage may already have been deleted in this block.",
address);
}
} catch (MerkleTrieException e) {
// need to throw to trigger the heal
Expand Down

0 comments on commit a6552df

Please sign in to comment.