Fix verkle state root calculation for BASIC_DATA_LEAF and CODE_HASH_LEAF (#7681)

* Fix storing BASIC_DATA_LEAF values in Big endian order

Signed-off-by: Luis Pinto <luis.pinto@consensys.net>

* Write code hash on account creation in all cases

Signed-off-by: Luis Pinto <luis.pinto@consensys.net>

---------

Signed-off-by: Luis Pinto <luis.pinto@consensys.net>
pull/7714/head
Luis Pinto 2 months ago committed by GitHub
parent f61b2a4ec5
commit efb55c1f54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/worldview/VerkleWorldState.java
  2. 34
      ethereum/verkletrie/src/main/java/org/hyperledger/besu/ethereum/verkletrie/VerkleEntryFactory.java
  3. 2
      gradle/versions.gradle

@ -130,6 +130,9 @@ public class VerkleWorldState extends DiffBasedWorldState {
final List<Bytes32> accountKeyIds = new ArrayList<>();
if (accountUpdate != null && !accountUpdate.isUnchanged()) {
accountKeyIds.add(trieKeyPreloader.generateAccountKeyId());
if (accountUpdate.getPrior() == null) {
accountKeyIds.add(Parameters.CODE_HASH_LEAF_KEY);
}
}
// generate storage triekeys
@ -212,13 +215,16 @@ public class VerkleWorldState extends DiffBasedWorldState {
return;
}
if (accountUpdate.getUpdated() == null) {
verkleEntryFactory.generateAccountKeysForRemoval(accountKey);
verkleEntryFactory.generateAccountKeyForRemoval(accountKey);
final Hash addressHash = hashAndSavePreImage(accountKey);
maybeStateUpdater.ifPresent(
bonsaiUpdater -> bonsaiUpdater.removeAccountInfoState(addressHash));
return;
}
final VerkleAccount updatedAcount = accountUpdate.getUpdated();
if (accountUpdate.getPrior() == null) {
verkleEntryFactory.generateCodeHashKeyValueForUpdate(accountKey, updatedAcount.getCodeHash());
}
verkleEntryFactory.generateAccountKeyValueForUpdate(
accountKey, updatedAcount.getNonce(), updatedAcount.getBalance());
maybeStateUpdater.ifPresent(
@ -274,7 +280,7 @@ public class VerkleWorldState extends DiffBasedWorldState {
if (!storageUpdate.getValue().isUnchanged()) {
final UInt256 updatedStorage = storageUpdate.getValue().getUpdated();
if (updatedStorage == null) {
verkleEntryFactory.generateStorageKeysForRemoval(accountKey, storageUpdate.getKey());
verkleEntryFactory.generateStorageKeyForRemoval(accountKey, storageUpdate.getKey());
maybeStateUpdater.ifPresent(
diffBasedUpdater ->
diffBasedUpdater.removeStorageValueBySlotHash(updatedAddressHash, slotHash));
@ -328,7 +334,7 @@ public class VerkleWorldState extends DiffBasedWorldState {
.getNonStorageKeyValuesForUpdate()
.forEach(
(key, value) -> {
System.out.println("add key " + key + " leaf value " + value);
System.out.println("add key " + key + " leaf value " + value);
stateTrie.put(key, value);
});
verkleEntryFactory

@ -45,7 +45,7 @@ public class VerkleEntryFactory {
trieKeyAdapter = new TrieKeyBatchAdapter(hasher);
}
public void generateAccountKeysForRemoval(final Address address) {
public void generateAccountKeyForRemoval(final Address address) {
keysForRemoval.add(trieKeyAdapter.basicDataKey(address));
}
@ -58,8 +58,7 @@ public class VerkleEntryFactory {
}
}
public void generateStorageKeysForRemoval(
final Address address, final StorageSlotKey storageKey) {
public void generateStorageKeyForRemoval(final Address address, final StorageSlotKey storageKey) {
keysForRemoval.add(trieKeyAdapter.storageKey(address, storageKey.getSlotKey().orElseThrow()));
}
@ -69,32 +68,39 @@ public class VerkleEntryFactory {
Bytes32 basicDataValue;
if ((basicDataValue = nonStorageKeyValuesForUpdate.get(basicDataKey)) == null) {
basicDataValue = Bytes32.ZERO;
} else {
basicDataValue = SuffixTreeEncoder.eraseVersion(basicDataValue);
basicDataValue = SuffixTreeEncoder.eraseNonce(basicDataValue);
basicDataValue = SuffixTreeEncoder.eraseBalance(basicDataValue);
}
basicDataValue = SuffixTreeEncoder.addVersionIntoValue(basicDataValue, Bytes32.ZERO);
basicDataValue = SuffixTreeEncoder.addNonceIntoValue(basicDataValue, UInt256.valueOf(nonce));
basicDataValue = SuffixTreeEncoder.addBalanceIntoValue(basicDataValue, balance);
basicDataValue = SuffixTreeEncoder.setVersionInValue(basicDataValue, Bytes.of(0));
basicDataValue = SuffixTreeEncoder.setNonceInValue(basicDataValue, Bytes.ofUnsignedLong(nonce));
basicDataValue =
SuffixTreeEncoder.setBalanceInValue(
basicDataValue,
// balance size is exactly 16 bytes
balance.slice(16));
nonStorageKeyValuesForUpdate.put(basicDataKey, basicDataValue);
}
public void generateCodeHashKeyValueForUpdate(final Address address, final Hash codeHash) {
nonStorageKeyValuesForUpdate.put(trieKeyAdapter.codeHashKey(address), codeHash);
}
public void generateCodeKeyValuesForUpdate(
final Address address, final Bytes code, final Hash codeHash) {
Bytes32 basicDataKey = trieKeyAdapter.basicDataKey(address);
Bytes32 basicDataValue;
if ((basicDataValue = nonStorageKeyValuesForUpdate.get(basicDataKey)) == null) {
basicDataValue = Bytes32.ZERO;
} else {
basicDataValue = SuffixTreeEncoder.eraseCodeSize(basicDataValue);
}
basicDataValue =
SuffixTreeEncoder.addCodeSizeIntoValue(basicDataValue, UInt256.valueOf(code.size()));
SuffixTreeEncoder.setCodeSizeInValue(
basicDataValue,
// code size is exactly 3 bytes
Bytes.ofUnsignedInt(code.size()).slice(1));
nonStorageKeyValuesForUpdate.put(basicDataKey, basicDataValue);
nonStorageKeyValuesForUpdate.put(trieKeyAdapter.codeHashKey(address), codeHash);
generateCodeHashKeyValueForUpdate(address, codeHash);
List<UInt256> codeChunks = trieKeyAdapter.chunkifyCode(code);
for (int i = 0; i < codeChunks.size(); i++) {
nonStorageKeyValuesForUpdate.put(

@ -169,7 +169,7 @@ dependencyManagement {
entry 'ipa-multipoint'
}
dependency 'org.hyperledger.besu:besu-verkle-trie:0.0.3-20240917.164246-1'
dependency 'org.hyperledger.besu:besu-verkle-trie:0.0.3-20240926.131636-2'
dependencySet(group: 'org.immutables', version: '2.10.0') {
entry 'value-annotations'

Loading…
Cancel
Save