diff --git a/src/main/java/org/hyperledger/besu/ethereum/trie/verkle/VerkleTrieBatchHasher.java b/src/main/java/org/hyperledger/besu/ethereum/trie/verkle/VerkleTrieBatchHasher.java index d6ccd65..16ae3d5 100644 --- a/src/main/java/org/hyperledger/besu/ethereum/trie/verkle/VerkleTrieBatchHasher.java +++ b/src/main/java/org/hyperledger/besu/ethereum/trie/verkle/VerkleTrieBatchHasher.java @@ -59,16 +59,19 @@ public class VerkleTrieBatchHasher { * Adds a node for future batching. If the node is a NullNode or NullLeafNode and the location is * not empty, it removes the node from the batch. * - * @param location The location of the node. + * @param maybeLocation The location of the node. * @param node The node to add. */ - public void addNodeToBatch(final Optional location, final Node node) { - if ((node instanceof NullNode || node instanceof NullLeafNode) - && !location.orElseThrow().isEmpty()) { - updatedNodes.remove(location.orElseThrow()); - } else { - updatedNodes.put(location.orElseThrow(), node); - } + public void addNodeToBatch(final Optional maybeLocation, final Node node) { + maybeLocation.ifPresent( + location -> { + if ((node instanceof NullNode || node instanceof NullLeafNode) + && !location.isEmpty()) { + updatedNodes.remove(location); + } else { + updatedNodes.put(location, node); + } + }); } /** diff --git a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/SimpleBatchedVerkleTrieTest.java b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/SimpleBatchedVerkleTrieTest.java index d7c3bd8..66335dc 100644 --- a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/SimpleBatchedVerkleTrieTest.java +++ b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/SimpleBatchedVerkleTrieTest.java @@ -50,6 +50,21 @@ public void testOneValue() { assertThat(trie.getRootHash()).as("Retrieve root hash").isEqualByComparingTo(expectedRootHash); } + @Test + public void testDeleteAlreadyDeletedValue() { + final VerkleTrieBatchHasher batchProcessor = new VerkleTrieBatchHasher(); + SimpleBatchedVerkleTrie trie = + new SimpleBatchedVerkleTrie(batchProcessor); + Bytes32 key = + Bytes32.fromHexString("0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"); + Bytes32 value = + Bytes32.fromHexString("0x1000000000000000000000000000000000000000000000000000000000000000"); + trie.put(key, value); + trie.remove(key); + trie.remove(key); + assertThat(trie.getRootHash()).isEqualTo(Bytes32.ZERO); + } + @Test public void testTwoValuesAtSameStem() throws Exception { final VerkleTrieBatchHasher batchProcessor = new VerkleTrieBatchHasher(); diff --git a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/SimpleVerkleTrieTest.java b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/SimpleVerkleTrieTest.java index af3b17e..f83cff9 100644 --- a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/SimpleVerkleTrieTest.java +++ b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/SimpleVerkleTrieTest.java @@ -47,6 +47,19 @@ public void testOneValue() { assertThat(trie.getRootHash()).as("Retrieve root hash").isEqualByComparingTo(expectedRootHash); } + @Test + public void testDeleteAlreadyDeletedValue() { + SimpleVerkleTrie trie = new SimpleVerkleTrie(); + Bytes32 key = + Bytes32.fromHexString("0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"); + Bytes32 value = + Bytes32.fromHexString("0x1000000000000000000000000000000000000000000000000000000000000000"); + trie.put(key, value); + trie.remove(key); + trie.remove(key); + assertThat(trie.getRootHash()).isEqualTo(Bytes32.ZERO); + } + @Test public void testTwoValuesAtSameStem() throws Exception { SimpleVerkleTrie trie = new SimpleVerkleTrie(); diff --git a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/StoredBatchedVerkleTrieTest.java b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/StoredBatchedVerkleTrieTest.java index 0325cbc..979ca75 100644 --- a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/StoredBatchedVerkleTrieTest.java +++ b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/StoredBatchedVerkleTrieTest.java @@ -68,6 +68,27 @@ public void testOneValue() { assertThat(storedTrie.get(key).orElse(null)).as("Retrieved value").isEqualTo(value); } + @Test + public void testDeleteAlreadyDeletedValue() { + NodeUpdaterMock nodeUpdater = new NodeUpdaterMock(); + NodeLoaderMock nodeLoader = new NodeLoaderMock(nodeUpdater.storage); + VerkleTrieBatchHasher batchProcessor = new VerkleTrieBatchHasher(); + StoredNodeFactory nodeFactory = + new StoredNodeFactory<>(nodeLoader, value -> (Bytes32) value); + StoredBatchedVerkleTrie trie = + new StoredBatchedVerkleTrie(batchProcessor, nodeFactory); + Bytes32 key = + Bytes32.fromHexString("0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"); + Bytes32 value = + Bytes32.fromHexString("0x1000000000000000000000000000000000000000000000000000000000000000"); + trie.put(key, value); + trie.remove(key); + trie.remove(key); + StoredBatchedVerkleTrie storedTrie = + new StoredBatchedVerkleTrie(batchProcessor, nodeFactory); + assertThat(storedTrie.getRootHash()).isEqualTo(Bytes32.ZERO); + } + @Test public void testTwoValuesAtSameStem() throws Exception { NodeUpdaterMock nodeUpdater = new NodeUpdaterMock(); diff --git a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/StoredVerkleTrieTest.java b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/StoredVerkleTrieTest.java index b6b225b..1ec7fa5 100644 --- a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/StoredVerkleTrieTest.java +++ b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/StoredVerkleTrieTest.java @@ -64,6 +64,23 @@ public void testOneValue() { assertThat(storedTrie.get(key).orElse(null)).as("Retrieved value").isEqualTo(value); } + @Test + public void testDeleteAlreadyDeletedValue() { + NodeUpdaterMock nodeUpdater = new NodeUpdaterMock(); + NodeLoaderMock nodeLoader = new NodeLoaderMock(nodeUpdater.storage); + StoredNodeFactory nodeFactory = + new StoredNodeFactory<>(nodeLoader, value -> (Bytes32) value); + StoredVerkleTrie trie = new StoredVerkleTrie(nodeFactory); + Bytes32 key = + Bytes32.fromHexString("0x00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff"); + Bytes32 value = + Bytes32.fromHexString("0x1000000000000000000000000000000000000000000000000000000000000000"); + trie.put(key, value); + trie.remove(key); + trie.remove(key); + assertThat(trie.getRootHash()).isEqualTo(Bytes32.ZERO); + } + @Test public void testTwoValuesAtSameStem() throws Exception { NodeUpdaterMock nodeUpdater = new NodeUpdaterMock();