Snap server GetTrieNodes to return empty bytes when trienode doesn't exist (#7305)

Signed-off-by: Jason Frame <jason.frame@consensys.net>
pull/7392/head
Jason Frame 4 months ago committed by GitHub
parent 51bb6c786e
commit d6f8645ae5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 32
      ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServer.java
  2. 23
      ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/snap/SnapServerTest.java

@ -518,15 +518,13 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener {
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 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener {
// 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<Bytes> storagePaths = triePath.subList(1, triePath.size());
for (var path : storagePaths) {
@ -547,14 +549,12 @@ class SnapServer implements BesuEvents.InitialSyncCompletionListener {
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);
}
}
}

@ -531,7 +531,25 @@ public class SnapServerTest {
assertThat(trieNodeRequest).isNotNull();
List<Bytes> 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<Bytes> trieNodes = trieNodeRequest.nodes(false);
assertThat(trieNodes).isNotNull();
assertThat(trieNodes.size()).isEqualTo(0);
}
@Test
@ -582,8 +600,7 @@ public class SnapServerTest {
assertThat(trieNodeRequest).isNotNull();
List<Bytes> 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

Loading…
Cancel
Save