Coverage Summary for Class: DownloadingSkeletonSyncState (co.rsk.net.sync)
Class |
Class, %
|
Method, %
|
Line, %
|
DownloadingSkeletonSyncState |
0%
(0/1)
|
0%
(0/7)
|
0%
(0/36)
|
1 package co.rsk.net.sync;
2
3 import co.rsk.net.Peer;
4 import co.rsk.net.NodeID;
5 import co.rsk.scoring.EventType;
6 import org.ethereum.core.BlockIdentifier;
7
8 import java.time.Duration;
9 import java.util.*;
10
11 public class DownloadingSkeletonSyncState extends BaseSyncState {
12
13 private final PeersInformation peersInformation;
14 private final Map<Peer, List<BlockIdentifier>> skeletons;
15 private final Peer selectedPeer;
16 private final List<Peer> candidates;
17 private long connectionPoint;
18 private long expectedSkeletons;
19 private boolean selectedPeerAnswered;
20
21
22 public DownloadingSkeletonSyncState(SyncConfiguration syncConfiguration,
23 SyncEventsHandler syncEventsHandler,
24 PeersInformation peersInformation,
25 Peer peer,
26 long connectionPoint) {
27 super(syncEventsHandler, syncConfiguration);
28 this.selectedPeer = peer;
29 this.connectionPoint = connectionPoint;
30 this.skeletons = new HashMap<>();
31 this.selectedPeerAnswered = false;
32 this.peersInformation = peersInformation;
33 this.candidates = peersInformation.getPeerCandidates();
34 this.expectedSkeletons = 0;
35 }
36
37 @Override
38 public void newSkeleton(List<BlockIdentifier> skeleton, Peer peer) {
39 NodeID peerId = peer.getPeerNodeID();
40 boolean isSelectedPeer = peer.equals(selectedPeer);
41
42 // defensive programming: this should never happen
43 if (skeleton.size() < 2) {
44 peersInformation.reportEventWithLog("Invalid skeleton received from node {}",
45 peerId, EventType.INVALID_MESSAGE, peerId);
46
47 // when the selected peer fails automatically all process restarts
48 if (isSelectedPeer){
49 syncEventsHandler.stopSyncing();
50 return;
51 }
52 } else {
53 skeletons.put(peer, skeleton);
54 }
55
56 expectedSkeletons--;
57 selectedPeerAnswered = selectedPeerAnswered || isSelectedPeer;
58
59 if (expectedSkeletons <= 0){
60 if (skeletons.isEmpty()){
61 syncEventsHandler.stopSyncing();
62 return;
63 }
64 syncEventsHandler.startDownloadingHeaders(skeletons, connectionPoint, peer);
65 }
66 }
67
68 @Override
69 public void tick(Duration duration) {
70 timeElapsed = timeElapsed.plus(duration);
71 if (timeElapsed.compareTo(syncConfiguration.getTimeoutWaitingRequest()) >= 0) {
72 candidates.stream()
73 .filter(c -> !skeletons.containsKey(c))
74 .forEach(p ->
75 peersInformation.reportEventWithLog(
76 "Timeout waiting skeleton from node {}",
77 p.getPeerNodeID(),
78 EventType.TIMEOUT_MESSAGE, p));
79
80 // when the selected peer fails automatically all process restarts
81 if (!selectedPeerAnswered){
82 syncEventsHandler.stopSyncing();
83 return;
84 }
85
86 syncEventsHandler.startDownloadingHeaders(skeletons, connectionPoint, selectedPeer);
87 }
88 }
89
90 @Override
91 protected void onMessageTimeOut() {
92 syncEventsHandler.onErrorSyncing(
93 selectedPeer.getPeerNodeID(),
94 "Timeout waiting requests {}",
95 EventType.TIMEOUT_MESSAGE,
96 this.getClass(),
97 selectedPeer.getPeerNodeID());
98 }
99
100 @Override
101 public void onEnter() {
102 peersInformation.getPeerCandidates().forEach(p -> syncEventsHandler.sendSkeletonRequest(p, connectionPoint));
103 }
104 }