@@ -131,7 +131,6 @@ class FastSync(
131
131
private var currentSkeletonState : Option [HeaderSkeleton ] = None
132
132
private var skeletonHandler : Option [ActorRef ] = None
133
133
private var batchFailuresCount = 0
134
- private var blockHeadersQueue : Seq [HeaderRange ] = Nil
135
134
136
135
private var requestedBlockBodies : Map [ActorRef , Seq [ByteString ]] = Map .empty
137
136
private var requestedReceipts : Map [ActorRef , Seq [ByteString ]] = Map .empty
@@ -260,9 +259,13 @@ class FastSync(
260
259
updatedSkeleton.batchStartingHeaderNumbers.mkString(" , " )
261
260
)
262
261
currentSkeletonState = Some (updatedSkeleton)
263
- blockHeadersQueue ++= updatedSkeleton.batchStartingHeaderNumbers.map(from =>
264
- HeaderRange (from, updatedSkeleton.batchSize)
265
- )
262
+
263
+ val blockHeadersToRequest =
264
+ updatedSkeleton.batchStartingHeaderNumbers.map { from =>
265
+ HeaderRange (from, updatedSkeleton.batchSize)
266
+ }
267
+
268
+ syncState = syncState.enqueueHeaderRanges(blockHeadersToRequest)
266
269
}
267
270
}
268
271
}
@@ -333,7 +336,7 @@ class FastSync(
333
336
def handleMasterPeerFailure (header : BlockHeader ): Unit = {
334
337
batchFailuresCount += 1
335
338
if (batchFailuresCount > fastSyncMaxBatchRetries) {
336
- log.info(" Max skeleton batch failures reached. Master peer must be wrong ." )
339
+ log.info(" Max number of allowed failures reached. Switching branch and master peer ." )
337
340
handleRewind(header, masterPeer.get, fastSyncBlockValidationN, blacklistDuration)
338
341
339
342
// Start branch resolution and wait for response from the FastSyncBranchResolver actor.
@@ -343,14 +346,14 @@ class FastSync(
343
346
}
344
347
}
345
348
346
- blockHeadersQueue :+= request
349
+ syncState = syncState.enqueueHeaderRange( request)
347
350
error match {
348
351
// These are the reasons that make the master peer suspicious
349
352
case InvalidPenultimateHeader (_, header) => handleMasterPeerFailure(header)
350
353
case InvalidBatchHash (_, header) => handleMasterPeerFailure(header)
351
354
// Otherwise probably it's just this peer's fault
352
355
case _ =>
353
- log.info (error.msg)
356
+ log.warning (error.msg)
354
357
blockHeadersError(peer, reason)
355
358
}
356
359
}
@@ -677,17 +680,16 @@ class FastSync(
677
680
private def handleRequestFailure (peer : Peer , handler : ActorRef , reason : BlacklistReason ): Unit = {
678
681
removeRequestHandler(handler)
679
682
683
+ requestedHeaders.get(peer).foreach(requested => syncState = syncState.enqueueHeaderRange(requested))
680
684
syncState = syncState
681
685
.enqueueBlockBodies(requestedBlockBodies.getOrElse(handler, Nil ))
682
686
.enqueueReceipts(requestedReceipts.getOrElse(handler, Nil ))
683
687
688
+ requestedHeaders -= peer
684
689
requestedBlockBodies = requestedBlockBodies - handler
685
690
requestedReceipts = requestedReceipts - handler
686
691
687
- requestedHeaders -= peer
688
- if (handshakedPeers.contains(peer.id)) {
689
- blacklist.add(peer.id, blacklistDuration, reason)
690
- }
692
+ blacklistIfHandshaked(peer.id, blacklistDuration, reason)
691
693
}
692
694
693
695
/**
@@ -872,7 +874,7 @@ class FastSync(
872
874
requestReceipts(peer)
873
875
} else if (syncState.blockBodiesQueue.nonEmpty) {
874
876
requestBlockBodies(peer)
875
- } else if (blockHeadersQueue.nonEmpty) {
877
+ } else if (syncState. blockHeadersQueue.nonEmpty) {
876
878
requestBlockHeaders(peer)
877
879
} else if (shouldRequestNewSkeleton(peerInfo)) {
878
880
requestSkeletonHeaders(peer)
@@ -934,31 +936,36 @@ class FastSync(
934
936
}
935
937
936
938
def requestBlockHeaders (peer : Peer ): Unit = {
937
- val (request, remaining) = (blockHeadersQueue.head, blockHeadersQueue.tail)
939
+ val (toRequest, remaining) = (syncState.blockHeadersQueue.headOption, syncState.blockHeadersQueue.tail)
940
+
941
+ toRequest match {
942
+ case Some (request) =>
943
+ log.debug(
944
+ " Requesting [{}] block headers starting at block header [{}] from peer [{}]" ,
945
+ request.limit,
946
+ request.from,
947
+ peer.id.value
948
+ )
938
949
939
- log.debug(
940
- " Requesting [{}] block headers starting at block header [{}] from peer [{}]" ,
941
- request.limit,
942
- request.from,
943
- peer.id.value
944
- )
950
+ val handler = context.actorOf(
951
+ PeerRequestHandler .props[GetBlockHeaders , BlockHeaders ](
952
+ peer,
953
+ peerResponseTimeout,
954
+ etcPeerManager,
955
+ peerEventBus,
956
+ requestMsg = GetBlockHeaders (Left (request.from), request.limit, skip = 0 , reverse = false ),
957
+ responseMsgCode = Codes .BlockHeadersCode
958
+ )
959
+ )
945
960
946
- val handler = context.actorOf(
947
- PeerRequestHandler .props[GetBlockHeaders , BlockHeaders ](
948
- peer,
949
- peerResponseTimeout,
950
- etcPeerManager,
951
- peerEventBus,
952
- requestMsg = GetBlockHeaders (Left (request.from), request.limit, skip = 0 , reverse = false ),
953
- responseMsgCode = Codes .BlockHeadersCode
954
- )
955
- )
961
+ context watch handler
962
+ assignedHandlers += (handler -> peer)
963
+ requestedHeaders += (peer -> request)
964
+ syncState = syncState.copy(blockHeadersQueue = remaining)
965
+ peerRequestsTime += (peer -> Instant .now())
966
+ case None => log.warning(" Tried to request more block headers but work queue was empty." )
967
+ }
956
968
957
- context watch handler
958
- assignedHandlers += (handler -> peer)
959
- requestedHeaders += (peer -> request)
960
- blockHeadersQueue = remaining
961
- peerRequestsTime += (peer -> Instant .now())
962
969
}
963
970
964
971
def requestSkeletonHeaders (peer : Peer ): Unit = {
@@ -1071,10 +1078,11 @@ object FastSync {
1071
1078
private case object PersistSyncState
1072
1079
private case object PrintStatus
1073
1080
1074
- case class SyncState (
1081
+ final case class SyncState (
1075
1082
pivotBlock : BlockHeader ,
1076
1083
lastFullBlockNumber : BigInt = 0 ,
1077
1084
safeDownloadTarget : BigInt = 0 ,
1085
+ blockHeadersQueue : Seq [HeaderRange ] = Nil ,
1078
1086
blockBodiesQueue : Seq [ByteString ] = Nil ,
1079
1087
receiptsQueue : Seq [ByteString ] = Nil ,
1080
1088
downloadedNodesCount : Long = 0 ,
@@ -1086,13 +1094,20 @@ object FastSync {
1086
1094
stateSyncFinished : Boolean = false
1087
1095
) {
1088
1096
1097
+ def enqueueHeaderRange (headerRange : HeaderRange ): SyncState =
1098
+ copy(blockHeadersQueue = blockHeadersQueue :+ headerRange)
1099
+
1100
+ def enqueueHeaderRanges (headerRanges : Seq [HeaderRange ]): SyncState =
1101
+ copy(blockHeadersQueue = blockHeadersQueue ++ headerRanges)
1102
+
1089
1103
def enqueueBlockBodies (blockBodies : Seq [ByteString ]): SyncState =
1090
1104
copy(blockBodiesQueue = blockBodiesQueue ++ blockBodies)
1091
1105
1092
1106
def enqueueReceipts (receipts : Seq [ByteString ]): SyncState =
1093
1107
copy(receiptsQueue = receiptsQueue ++ receipts)
1094
1108
1095
- def blockChainWorkQueued : Boolean = blockBodiesQueue.nonEmpty || receiptsQueue.nonEmpty
1109
+ def blockChainWorkQueued : Boolean =
1110
+ blockHeadersQueue.nonEmpty || blockBodiesQueue.nonEmpty || receiptsQueue.nonEmpty
1096
1111
1097
1112
def updateNextBlockToValidate (header : BlockHeader , K : Int , X : Int ): SyncState = copy(
1098
1113
nextBlockToFullyValidate =
@@ -1149,5 +1164,5 @@ object FastSync {
1149
1164
case object LastBlockValidationFailed extends PivotBlockUpdateReason
1150
1165
case object SyncRestart extends PivotBlockUpdateReason
1151
1166
1152
- private final case class HeaderRange (from : BigInt , limit : BigInt )
1167
+ private [fast] final case class HeaderRange (from : BigInt , limit : BigInt )
1153
1168
}
0 commit comments