Skip to content

Commit 24be091

Browse files
garyschultematktmacfarla
authored andcommitted
Snap client fixes (besu-eth#6847)
* manage empty range for storage * round rather than floor on max remote connections so that maxpeers=1 still can accept remote connections --------- Signed-off-by: garyschulte <garyschulte@gmail.com> Co-authored-by: Karim Taam <karim.t2am@gmail.com> Co-authored-by: Sally MacFarlane <macfarla.github@gmail.com>
1 parent a7ca8a9 commit 24be091

File tree

4 files changed

+40
-11
lines changed

4 files changed

+40
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
- In JSON-RPC return optional `v` fields for type 1 and type 2 transactions [#6762](https://github.com/hyperledger/besu/pull/6762)
4040
- Fix Shanghai/QBFT block import bug when syncing new nodes [#6765](https://github.com/hyperledger/besu/pull/6765)
4141
- Fix to avoid broadcasting full blob txs, instead of only the tx announcement, to a subset of nodes [#6835](https://github.com/hyperledger/besu/pull/6835)
42+
- Snap client fixes discovered during snap server testing [#6847](https://github.com/hyperledger/besu/pull/6847)
4243

4344
### Download Links
4445

besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1554,7 +1554,7 @@ private void ensureValidPeerBoundParams() {
15541554
checkState(
15551555
fraction >= 0.0 && fraction <= 1.0,
15561556
"Fraction of remote connections allowed must be between 0.0 and 1.0 (inclusive).");
1557-
maxRemoteInitiatedPeers = (int) Math.floor(fraction * maxPeers);
1557+
maxRemoteInitiatedPeers = Math.round(fraction * maxPeers);
15581558
} else {
15591559
maxRemoteInitiatedPeers = maxPeers;
15601560
}

ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/RequestDataStep.java

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import java.util.HashMap;
4242
import java.util.List;
4343
import java.util.Map;
44+
import java.util.NavigableMap;
4445
import java.util.TreeMap;
4546
import java.util.concurrent.CompletableFuture;
4647
import java.util.stream.Collectors;
@@ -49,9 +50,11 @@
4950
import kotlin.collections.ArrayDeque;
5051
import org.apache.tuweni.bytes.Bytes;
5152
import org.apache.tuweni.bytes.Bytes32;
53+
import org.slf4j.Logger;
54+
import org.slf4j.LoggerFactory;
5255

5356
public class RequestDataStep {
54-
57+
private static final Logger LOG = LoggerFactory.getLogger(RequestDataStep.class);
5558
private final WorldStateStorageCoordinator worldStateStorageCoordinator;
5659
private final SnapSyncProcessState fastSyncState;
5760
private final SnapWorldDownloadState downloadState;
@@ -131,15 +134,36 @@ public CompletableFuture<List<Task<SnapDataRequest>>> requestStorage(
131134
(response, error) -> {
132135
if (response != null) {
133136
downloadState.removeOutstandingTask(getStorageRangeTask);
134-
for (int i = 0; i < response.slots().size(); i++) {
135-
final StorageRangeDataRequest request =
136-
(StorageRangeDataRequest) requestTasks.get(i).getData();
137-
request.setRootHash(blockHeader.getStateRoot());
138-
request.addResponse(
139-
downloadState,
140-
worldStateProofProvider,
141-
response.slots().get(i),
142-
i < response.slots().size() - 1 ? new ArrayDeque<>() : response.proofs());
137+
final ArrayDeque<NavigableMap<Bytes32, Bytes>> slots = new ArrayDeque<>();
138+
// Check if we have an empty range
139+
140+
/*
141+
* Checks if the response represents an "empty range".
142+
*
143+
* An "empty range" is defined as a response where at least one proof exists
144+
* and either no slots are present, or the first slot is empty
145+
*/
146+
try {
147+
final boolean isEmptyRange =
148+
(response.slots().isEmpty() || response.slots().get(0).isEmpty())
149+
&& !response.proofs().isEmpty();
150+
if (isEmptyRange) { // empty range detected
151+
slots.add(new TreeMap<>());
152+
} else {
153+
slots.addAll(response.slots());
154+
}
155+
for (int i = 0; i < slots.size(); i++) {
156+
final StorageRangeDataRequest request =
157+
(StorageRangeDataRequest) requestTasks.get(i).getData();
158+
request.setRootHash(blockHeader.getStateRoot());
159+
request.addResponse(
160+
downloadState,
161+
worldStateProofProvider,
162+
slots.get(i),
163+
i < slots.size() - 1 ? new ArrayDeque<>() : response.proofs());
164+
}
165+
} catch (final Exception e) {
166+
LOG.error("Error while processing storage range response", e);
143167
}
144168
}
145169
return requestTasks;

ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/sync/snapsync/StackTrie.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ public void commit(final FlatDatabaseUpdater flatDatabaseUpdater, final NodeUpda
114114
keys.putAll(taskElement.keys());
115115
});
116116

117+
if (keys.isEmpty()) {
118+
return; // empty range we can ignore it
119+
}
120+
117121
final Map<Bytes32, Bytes> proofsEntries = new HashMap<>();
118122
for (Bytes proof : proofs) {
119123
proofsEntries.put(Hash.hash(proof), proof);

0 commit comments

Comments
 (0)