Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public class BonsaiWorldStateUpdateAccumulator
private final Map<Address, StorageConsumingMap<StorageSlotKey, BonsaiValue<UInt256>>>
storageToUpdate = new ConcurrentHashMap<>();

private final Map<UInt256, Hash> slotKeyToHashCache = new ConcurrentHashMap<>();
protected boolean isAccumulatorStateChanged;

public BonsaiWorldStateUpdateAccumulator(
Expand Down Expand Up @@ -142,7 +143,7 @@ public MutableAccount createAccount(final Address address, final long nonce, fin
new BonsaiAccount(
this,
address,
hashAndSavePreImage(address),
hashAndSaveAccountPreImage(address),
nonce,
balance,
Hash.EMPTY_TRIE_HASH,
Expand Down Expand Up @@ -364,11 +365,13 @@ public void commit() {
entries.forEach(
storageUpdate -> {
final UInt256 keyUInt = storageUpdate.getKey();
final Hash slotHash = hashAndSavePreImage(keyUInt);
final StorageSlotKey slotKey =
new StorageSlotKey(slotHash, Optional.of(keyUInt));
new StorageSlotKey(
hashAndSaveSlotPreImage(updatedAddress, keyUInt),
Optional.of(keyUInt)); // no compute Hash in this case
final UInt256 value = storageUpdate.getValue();
final BonsaiValue<UInt256> pendingValue = pendingStorageUpdates.get(slotKey);

if (pendingValue == null) {
pendingStorageUpdates.put(
slotKey,
Expand Down Expand Up @@ -409,7 +412,7 @@ public Optional<Bytes> getCode(final Address address, final Hash codeHash) {
@Override
public UInt256 getStorageValue(final Address address, final UInt256 slotKey) {
StorageSlotKey storageSlotKey =
new StorageSlotKey(hashAndSavePreImage(slotKey), Optional.of(slotKey));
new StorageSlotKey(hashAndSaveSlotPreImage(address, slotKey), Optional.of(slotKey));
return getStorageValueByStorageSlotKey(address, storageSlotKey).orElse(UInt256.ZERO);
}

Expand Down Expand Up @@ -453,7 +456,7 @@ public Optional<UInt256> getStorageValueByStorageSlotKey(
public UInt256 getPriorStorageValue(final Address address, final UInt256 storageKey) {
// TODO maybe log the read into the trie layer?
StorageSlotKey storageSlotKey =
new StorageSlotKey(hashAndSavePreImage(storageKey), Optional.of(storageKey));
new StorageSlotKey(hashAndSaveSlotPreImage(address, storageKey), Optional.of(storageKey));
final Map<StorageSlotKey, BonsaiValue<UInt256>> localAccountStorage =
storageToUpdate.get(address);
if (localAccountStorage != null) {
Expand Down Expand Up @@ -765,6 +768,7 @@ public void reset() {
resetAccumulatorStateChanged();
updatedAccounts.clear();
deletedAccounts.clear();
slotKeyToHashCache.clear();
}

public static class AccountConsumingMap<T> extends ForwardingMap<Address, T> {
Expand Down Expand Up @@ -828,8 +832,16 @@ public interface Consumer<T> {
void process(final Address address, T value);
}

protected Hash hashAndSavePreImage(final Bytes bytes) {
// by default do not save hash preImages
return Hash.hash(bytes);
protected Hash hashAndSaveAccountPreImage(final Address address) {
return Hash.hash(address);
}

protected Hash hashAndSaveSlotPreImage(final Address address, final UInt256 slotKey) {
Hash hash = slotKeyToHashCache.get(slotKey);
if (hash == null) {
hash = Hash.hash(slotKey);
slotKeyToHashCache.put(slotKey, hash);
}
return hash;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
*/
package org.hyperledger.besu.ethereum.referencetests;

import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.StorageSlotKey;
import org.hyperledger.besu.ethereum.trie.bonsai.BonsaiAccount;
import org.hyperledger.besu.ethereum.trie.bonsai.BonsaiValue;
Expand All @@ -25,50 +24,43 @@

import java.util.concurrent.ConcurrentHashMap;

import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt256;

public class BonsaiReferenceTestUpdateAccumulator extends BonsaiWorldStateUpdateAccumulator {
private final BonsaiPreImageProxy preImageProxy;

public BonsaiReferenceTestUpdateAccumulator(
final BonsaiWorldView world,
final Consumer<BonsaiValue<BonsaiAccount>> accountPreloader,
final Consumer<StorageSlotKey> storagePreloader,
final BonsaiPreImageProxy preImageProxy,
final EvmConfiguration evmConfiguration) {
final BonsaiWorldView world,
final Consumer<BonsaiValue<BonsaiAccount>> accountPreloader,
final Consumer<StorageSlotKey> storagePreloader,
final BonsaiPreImageProxy preImageProxy,
final EvmConfiguration evmConfiguration) {
super(world, accountPreloader, storagePreloader, evmConfiguration);
this.preImageProxy = preImageProxy;
}

@Override
protected Hash hashAndSavePreImage(final Bytes bytes) {
// by default do not save hash preImages
return preImageProxy.hashAndSavePreImage(bytes);
}

public BonsaiReferenceTestUpdateAccumulator createDetachedAccumulator() {
final BonsaiReferenceTestUpdateAccumulator copy =
new BonsaiReferenceTestUpdateAccumulator(
wrappedWorldView(),
accountPreloader,
storagePreloader,
preImageProxy,
evmConfiguration);
new BonsaiReferenceTestUpdateAccumulator(
wrappedWorldView(),
accountPreloader,
storagePreloader,
preImageProxy,
evmConfiguration);
getAccountsToUpdate().forEach((k, v) -> copy.getAccountsToUpdate().put(k, v.copy()));
getCodeToUpdate().forEach((k, v) -> copy.getCodeToUpdate().put(k, v.copy()));
copy.getStorageToClear().addAll(getStorageToClear());
getStorageToUpdate()
.forEach(
(k, v) -> {
StorageConsumingMap<StorageSlotKey, BonsaiValue<UInt256>> newMap =
new StorageConsumingMap<>(k, new ConcurrentHashMap<>(), v.getConsumer());
v.forEach((key, value) -> newMap.put(key, value.copy()));
copy.getStorageToUpdate().put(k, newMap);
});
.forEach(
(k, v) -> {
StorageConsumingMap<StorageSlotKey, BonsaiValue<UInt256>> newMap =
new StorageConsumingMap<>(k, new ConcurrentHashMap<>(), v.getConsumer());
v.forEach((key, value) -> newMap.put(key, value.copy()));
copy.getStorageToUpdate().put(k, newMap);
});
copy.updatedAccounts.putAll(updatedAccounts);
copy.deletedAccounts.addAll(deletedAccounts);
copy.isAccumulatorStateChanged = true;
return copy;
}
}
}