From 764ce3a87ca1d03dc5cbb3f559f579a14b92d6e1 Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Tue, 17 Sep 2024 11:47:42 +0100 Subject: [PATCH 1/4] add missing VerkleAccount equals and hashcode Signed-off-by: Luis Pinto --- .../trie/diffbased/verkle/VerkleAccount.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/VerkleAccount.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/VerkleAccount.java index 692dd19f731..bd7170dd71e 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/VerkleAccount.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/VerkleAccount.java @@ -37,6 +37,7 @@ public class VerkleAccount extends DiffBasedAccount { private Hash storageRoot; // TODO REMOVE AS USELESS + private int hashCode; public VerkleAccount( final DiffBasedWorldView context, @@ -180,4 +181,33 @@ public static void assertCloseEnoughForDiffing( public boolean isStorageEmpty() { return true; // TODO need to find a way to manage that with verkle } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } else if (!(other instanceof VerkleAccount)) { + return false; + } + VerkleAccount otherVerkleAccount = (VerkleAccount) other; + return Objects.equals(this.address, otherVerkleAccount.address) + && this.nonce == otherVerkleAccount.nonce + && Objects.equals(this.balance, otherVerkleAccount.balance) + && Objects.equals(this.codeHash, otherVerkleAccount.codeHash); + } + + @Override + public int hashCode() { + if (!immutable) { + return computeHashCode(); + } + if (hashCode == 0) { + hashCode = computeHashCode(); + } + return hashCode; + } + + private int computeHashCode() { + return Objects.hash(address, nonce, balance, codeHash); + } } From b4983e6b2c278f1082e71b2c3b3d28a64fd76fc0 Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Tue, 17 Sep 2024 16:17:37 +0100 Subject: [PATCH 2/4] fixup! refactor VerkleWorldState::internalCalculateRootHash minor change and method renames Signed-off-by: Luis Pinto --- .../diffbased/verkle/worldview/VerkleWorldState.java | 12 +++++++----- .../besu/ethereum/verkletrie/TrieKeyPreloader.java | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/worldview/VerkleWorldState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/worldview/VerkleWorldState.java index 017847fa08f..286a1f621d1 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/worldview/VerkleWorldState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/worldview/VerkleWorldState.java @@ -126,7 +126,7 @@ protected Hash internalCalculateRootHash( // generate account triekeys final List accountKeyIds = new ArrayList<>(); if (!accountUpdate.getValue().isUnchanged()) { - accountKeyIds.addAll(trieKeyPreloader.generateAccountKeyIds()); + accountKeyIds.add(trieKeyPreloader.generateAccountKeyId()); } // generate storage triekeys @@ -207,7 +207,8 @@ private void generateAccountValues( final DiffBasedValue accountUpdate) { if (accountUpdate.isUnchanged()) { return; - } else if (accountUpdate.getUpdated() == null) { + } + if (accountUpdate.getUpdated() == null) { verkleEntryFactory.generateAccountKeysForRemoval(accountKey); final Hash addressHash = hashAndSavePreImage(accountKey); maybeStateUpdater.ifPresent( @@ -237,7 +238,8 @@ private void generateCodeValues( || codeUpdate.isUnchanged() || (codeIsEmpty(codeUpdate.getPrior()) && codeIsEmpty(codeUpdate.getUpdated()))) { return; - } else if (codeUpdate.getUpdated() == null) { + } + if (codeUpdate.getUpdated() == null) { final Hash priorCodeHash = Hash.hash(codeUpdate.getPrior()); verkleEntryFactory.generateCodeKeysForRemoval(accountKey, codeUpdate.getPrior()); final Hash accountHash = accountKey.addressHash(); @@ -257,7 +259,7 @@ private void generateCodeValues( } } - private void generateStorageValue( + private void generateStorageValues( final Address accountKey, final VerkleEntryFactory verkleEntryFactory, final Optional maybeStateUpdater, @@ -311,7 +313,7 @@ private void updateState( maybeStateUpdater, worldStateUpdater.getCodeToUpdate().get(accountKey)); - generateStorageValue( + generateStorageValues( accountKey, verkleEntryFactory, maybeStateUpdater, diff --git a/ethereum/verkletrie/src/main/java/org/hyperledger/besu/ethereum/verkletrie/TrieKeyPreloader.java b/ethereum/verkletrie/src/main/java/org/hyperledger/besu/ethereum/verkletrie/TrieKeyPreloader.java index d99107976f6..d7bf2e92acb 100644 --- a/ethereum/verkletrie/src/main/java/org/hyperledger/besu/ethereum/verkletrie/TrieKeyPreloader.java +++ b/ethereum/verkletrie/src/main/java/org/hyperledger/besu/ethereum/verkletrie/TrieKeyPreloader.java @@ -42,8 +42,8 @@ public TrieKeyPreloader() { trieKeyAdapter = new TrieKeyBatchAdapter(hasher); } - public List generateAccountKeyIds() { - return List.of(Parameters.BASIC_DATA_LEAF_KEY); + public Bytes32 generateAccountKeyId() { + return Parameters.BASIC_DATA_LEAF_KEY; } public List generateCodeChunkKeyIds(final Bytes code) { From 2d12b659a7478f155f9a7be52e1dfed6dfcb3c7d Mon Sep 17 00:00:00 2001 From: Luis Pinto Date: Tue, 17 Sep 2024 17:51:21 +0100 Subject: [PATCH 3/4] fixup! Move SuffixTrieEncoder to besu-verkle-trie project use 0.0.3-SNAPSHOT with timestamp Signed-off-by: Luis Pinto --- gradle/versions.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/versions.gradle b/gradle/versions.gradle index b0e4202fb68..fbe2ebf69ca 100644 --- a/gradle/versions.gradle +++ b/gradle/versions.gradle @@ -169,7 +169,7 @@ dependencyManagement { entry 'ipa-multipoint' } - dependency 'org.hyperledger.besu:besu-verkle-trie:0.0.2' + dependency 'org.hyperledger.besu:besu-verkle-trie:0.0.3-20240917.164246-1' dependencySet(group: 'org.immutables', version: '2.10.0') { entry 'value-annotations' From 2e3ba71dabcf26f30c8f3571f897148a1a9451c3 Mon Sep 17 00:00:00 2001 From: Karim Taam Date: Mon, 23 Sep 2024 10:27:48 +0200 Subject: [PATCH 4/4] fix persist when unchanged account Signed-off-by: Karim Taam --- .../verkle/worldview/VerkleWorldState.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/worldview/VerkleWorldState.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/worldview/VerkleWorldState.java index 286a1f621d1..f02ce535134 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/worldview/VerkleWorldState.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/trie/diffbased/verkle/worldview/VerkleWorldState.java @@ -44,6 +44,7 @@ import org.hyperledger.besu.plugin.services.storage.SegmentedKeyValueStorageTransaction; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -119,13 +120,15 @@ protected Hash internalCalculateRootHash( final Map preloadedHashers = new ConcurrentHashMap<>(); - worldStateUpdater.getAccountsToUpdate().entrySet().parallelStream() + final Set
addressesToPersist = getAddressesToPersist(worldStateUpdater); + addressesToPersist.parallelStream() .forEach( - accountUpdate -> { - final Address accountKey = accountUpdate.getKey(); + accountKey -> { + final DiffBasedValue accountUpdate = + worldStateUpdater.getAccountsToUpdate().get(accountKey); // generate account triekeys final List accountKeyIds = new ArrayList<>(); - if (!accountUpdate.getValue().isUnchanged()) { + if (accountUpdate != null && !accountUpdate.isUnchanged()) { accountKeyIds.add(trieKeyPreloader.generateAccountKeyId()); } @@ -167,7 +170,7 @@ protected Hash internalCalculateRootHash( accountKey, accountKeyIds, storageKeyIds, codeKeyIds)); }); - for (final Address accountKey : worldStateUpdater.getAccountsToUpdate().keySet()) { + for (final Address accountKey : addressesToPersist) { updateState( accountKey, stateTrie, @@ -205,7 +208,7 @@ private void generateAccountValues( final VerkleEntryFactory verkleEntryFactory, final Optional maybeStateUpdater, final DiffBasedValue accountUpdate) { - if (accountUpdate.isUnchanged()) { + if (accountUpdate == null || accountUpdate.isUnchanged()) { return; } if (accountUpdate.getUpdated() == null) { @@ -355,6 +358,16 @@ private void updateState( }); } + public Set
getAddressesToPersist( + final DiffBasedWorldStateUpdateAccumulator accumulator) { + Set
mergedAddresses = + new HashSet<>(accumulator.getAccountsToUpdate().keySet()); // accountsToUpdate + mergedAddresses.addAll(accumulator.getCodeToUpdate().keySet()); // codeToUpdate + mergedAddresses.addAll(accumulator.getStorageToClear()); // storageToClear + mergedAddresses.addAll(accumulator.getStorageToUpdate().keySet()); // storageToUpdate + return mergedAddresses; + } + @Override public MutableWorldState freeze() { this.worldStateConfig.setFrozen(true);