Skip to content

Commit

Permalink
Fix failed reference tests, manage the case where the access list con…
Browse files Browse the repository at this point in the history
…tains accounts that are created during the transaction

Signed-off-by: Ameziane H <ameziane.hamlat@consensys.net>
  • Loading branch information
ahamlat committed Dec 18, 2022
1 parent ade955b commit 0d814da
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 19 deletions.
40 changes: 23 additions & 17 deletions evm/src/main/java/org/hyperledger/besu/evm/frame/MessageFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public enum Type {
private final Set<Address> selfDestructs;
private final Map<Address, Wei> refunds;
private final Set<Address> warmedUpAddresses;
private final Map<Address, Map<Bytes32, Bytes32>> warmedUpStorage;
public final Map<Address, Map<Bytes32, Optional<Bytes32>>> warmedUpStorage;

// Execution Environment fields.
private final Address recipient;
Expand Down Expand Up @@ -311,18 +311,24 @@ private MessageFrame(
this.warmedUpStorage = initWithAccessedList(accessListWarmStorage);
}

private Map<Address, Map<Bytes32, Bytes32>> initWithAccessedList(
private Map<Address, Map<Bytes32, Optional<Bytes32>>> initWithAccessedList(
final Multimap<Address, Bytes32> accessListWarmStorage) {

Map<Address, Map<Bytes32, Bytes32>> warmList = new ConcurrentHashMap<>();
Map<Address, Map<Bytes32, Optional<Bytes32>>> warmList = new ConcurrentHashMap<>();
Set<Address> addresses = accessListWarmStorage.keySet();
for (Address address : addresses) {
Optional.ofNullable(worldUpdater.get(address)).ifPresent(account -> {
Map<Bytes32, Bytes32> keyValuesMap = new ConcurrentHashMap<>();
Optional.ofNullable(worldUpdater.get(address)).ifPresentOrElse(account -> {
Map<Bytes32, Optional<Bytes32>> keyValuesMap = new ConcurrentHashMap<>();
for (Bytes32 key : accessListWarmStorage.get(address)) {
keyValuesMap.put(key, account.getStorageValue(UInt256.fromBytes(key)));
keyValuesMap.put(key, Optional.ofNullable(account.getStorageValue(UInt256.fromBytes(key))));
}
warmList.put(address, keyValuesMap);
}, () -> {
Map<Bytes32, Optional<Bytes32>> keyValuesMap2 = new ConcurrentHashMap<>();
for (Bytes32 key : accessListWarmStorage.get(address)) {
keyValuesMap2.put(key, Optional.empty());
}
warmList.put(address, keyValuesMap2);
});
}

Expand Down Expand Up @@ -870,12 +876,12 @@ private boolean isWarm(final Address address) {
public UInt256 warmUpStorage(final Account account, final Bytes32 slot) {
Address address = account.getAddress();
UInt256 storageValue = account.getStorageValue(UInt256.fromBytes(slot));
Map<Bytes32, Bytes32> accountKeyValues = getWarmedUpStorageKeys().get(address);
Map<Bytes32, Optional<Bytes32>> accountKeyValues = getWarmedUpStorageKeys().get(address);
if (accountKeyValues == null) {
accountKeyValues = new ConcurrentHashMap<>();
getWarmedUpStorageKeys().put(address, accountKeyValues);
}
accountKeyValues.put(slot, storageValue);
accountKeyValues.put(slot, Optional.ofNullable(storageValue));
return storageValue;
}

Expand All @@ -889,7 +895,7 @@ public UInt256 warmUpStorage(final Account account, final Bytes32 slot) {
public boolean isWarm(final Address address, final Bytes32 slot) {
MessageFrame frame = this;
while (frame != null) {
Map<Bytes32, Bytes32> addressWarmedStorage = frame.warmedUpStorage.get(address);
Map<Bytes32, Optional<Bytes32>> addressWarmedStorage = frame.warmedUpStorage.get(address);
if (addressWarmedStorage != null && addressWarmedStorage.containsKey(slot)) {
return true;
}
Expand All @@ -898,25 +904,25 @@ public boolean isWarm(final Address address, final Bytes32 slot) {
return false;
}

public Bytes getFromWarmedUpStorage(final Address address, final Bytes32 slot) {
public Optional<Bytes32> getFromWarmedUpStorage(final Address address, final Bytes32 slot) {
MessageFrame frame = this;
while (frame != null) {
if (frame.warmedUpStorage.containsKey(address)
&& frame.warmedUpStorage.get(address).containsKey(slot)) {
Map<Bytes32, Optional<Bytes32>> addressWarmedStorage = frame.warmedUpStorage.get(address);
if (addressWarmedStorage != null && addressWarmedStorage.containsKey(slot)) {
return frame.warmedUpStorage.get(address).get(slot);
}
frame = frame.parentMessageFrame;
}
return null;
return Optional.empty();
}

public void updateWarmUpStorage(final Address address, final UInt256 slot, final UInt256 value) {
Map<Bytes32, Bytes32> addressWarmedStorage = warmedUpStorage.get(address);
Map<Bytes32, Optional<Bytes32>> addressWarmedStorage = warmedUpStorage.get(address);
if (addressWarmedStorage != null ) {
addressWarmedStorage.put(slot, value);
addressWarmedStorage.put(slot, Optional.ofNullable(value));
} else {
addressWarmedStorage = new ConcurrentHashMap<>();
addressWarmedStorage.put(slot, value);
addressWarmedStorage.put(slot, Optional.ofNullable(value));
warmedUpStorage.put(address, addressWarmedStorage);
}
}
Expand Down Expand Up @@ -1341,7 +1347,7 @@ public MessageFrame build() {
}
}

public Map<Address, Map<Bytes32, Bytes32>> getWarmedUpStorageKeys() {
public Map<Address, Map<Bytes32, Optional<Bytes32>>> getWarmedUpStorageKeys() {
return warmedUpStorage;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) {
return new OperationResult(cost, ExceptionalHaltReason.INSUFFICIENT_GAS);
} else {
if (slotIsWarm) {
frame.pushStackItem(frame.getFromWarmedUpStorage(address, key));
if (!frame.getFromWarmedUpStorage(address, key).isPresent()) {
UInt256 storageValue = frame.warmUpStorage(account, key);
frame.pushStackItem(storageValue);
} else {
frame.pushStackItem(frame.getFromWarmedUpStorage(address, key).get());
}
return warmSuccess;
} else {
UInt256 storageValue = frame.warmUpStorage(account, key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) {
final Address address = account.getAddress();
final boolean slotIsWarm = frame.isWarm(address, key);
if (!slotIsWarm) {
// This is used to avoid getting the value again from disk during gas calculation
frame.warmUpStorage(account, key);
}
final long cost =
Expand Down

0 comments on commit 0d814da

Please sign in to comment.