diff --git a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java index d6bfe900d9c..cb92941e5b6 100644 --- a/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java +++ b/ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java @@ -518,15 +518,13 @@ MessageData constructGetTrieNodesResponse(final MessageData message) { if (optStorage.isEmpty() && location.isEmpty()) { optStorage = Optional.of(MerkleTrie.EMPTY_TRIE_NODE); } - if (optStorage.isPresent()) { - if (!trieNodes.isEmpty() - && (sumListBytes(trieNodes) + optStorage.get().size() > maxResponseBytes - || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST)) { - break; - } - trieNodes.add(optStorage.get()); + var trieNode = optStorage.orElse(Bytes.EMPTY); + if (!trieNodes.isEmpty() + && (sumListBytes(trieNodes) + trieNode.size() > maxResponseBytes + || stopWatch.getTime() > StatefulPredicate.MAX_MILLIS_PER_REQUEST)) { + break; } - + trieNodes.add(trieNode); } else { // There must be at least one element in the path otherwise it is invalid if (triePath.isEmpty()) { @@ -537,7 +535,11 @@ MessageData constructGetTrieNodesResponse(final MessageData message) { // otherwise the first element should be account hash, and subsequent paths // are compact encoded account storage paths - final Bytes accountPrefix = Bytes32.leftPad(triePath.getFirst()); + final Bytes32 accountPrefix = Bytes32.leftPad(triePath.getFirst()); + var optAccount = storage.getAccount(Hash.wrap(accountPrefix)); + if (optAccount.isEmpty()) { + continue; + } List storagePaths = triePath.subList(1, triePath.size()); for (var path : storagePaths) { @@ -547,14 +549,12 @@ MessageData constructGetTrieNodesResponse(final MessageData message) { if (optStorage.isEmpty() && location.isEmpty()) { optStorage = Optional.of(MerkleTrie.EMPTY_TRIE_NODE); } - if (optStorage.isPresent()) { - if (!trieNodes.isEmpty() - && sumListBytes(trieNodes) + optStorage.get().size() - > maxResponseBytes) { - break; - } - trieNodes.add(optStorage.get()); + var trieNode = optStorage.orElse(Bytes.EMPTY); + if (!trieNodes.isEmpty() + && sumListBytes(trieNodes) + trieNode.size() > maxResponseBytes) { + break; } + trieNodes.add(trieNode); } } } diff --git a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java index 2103af41242..e252fe0335d 100644 --- a/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java +++ b/ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java @@ -531,7 +531,25 @@ public void assertStorageTriePathRequest() { assertThat(trieNodeRequest).isNotNull(); List trieNodes = trieNodeRequest.nodes(false); assertThat(trieNodes).isNotNull(); - assertThat(trieNodes.size()).isEqualTo(4); + assertThat(trieNodes.size()).isEqualTo(6); + assertThat(trieNodes.get(2)).isEqualTo(Bytes.EMPTY); + assertThat(trieNodes.get(5)).isEqualTo(Bytes.EMPTY); + } + + @Test + public void assertStorageTriePathRequest_accountNotPresent() { + insertTestAccounts(acct4); + var pathToSlot11 = CompactEncoding.encode(Bytes.fromHexStringLenient("0x0101")); + var trieNodeRequest = + requestTrieNodes( + storageTrie.getRootHash(), + List.of( + List.of(acct3.addressHash, pathToSlot11) // account not present + )); + assertThat(trieNodeRequest).isNotNull(); + List trieNodes = trieNodeRequest.nodes(false); + assertThat(trieNodes).isNotNull(); + assertThat(trieNodes.size()).isEqualTo(0); } @Test @@ -582,8 +600,7 @@ public void assertStorageTrieLimitRequest() { assertThat(trieNodeRequest).isNotNull(); List trieNodes = trieNodeRequest.nodes(false); assertThat(trieNodes).isNotNull(); - // TODO: adjust this assertion after sorting out the request fudge factor - assertThat(trieNodes.size()).isEqualTo(trieNodeLimit * 90 / 100); + assertThat(trieNodes.size()).isEqualTo(3); } @Test