@@ -145,6 +145,68 @@ class SyncControllerSpec extends AnyFlatSpec with Matchers with BeforeAndAfter w
145
145
peerMessageBus.expectMsg(Subscribe (MessageClassifier (Set (BlockHeaders .code), PeerSelector .WithId (peer1.id))))
146
146
}
147
147
148
+ it should " gracefully handle receiving empty receipts while syncing" in new TestSetup () {
149
+
150
+ val newSafeTarget = defaultExpectedTargetBlock + syncConfig.fastSyncBlockValidationX
151
+ val bestBlockNumber = defaultExpectedTargetBlock
152
+ val firstNewBlock = bestBlockNumber + 1
153
+
154
+ startWithState(defaultState.copy(
155
+ bestBlockHeaderNumber = bestBlockNumber,
156
+ safeDownloadTarget = newSafeTarget)
157
+ )
158
+
159
+ Thread .sleep(1 .seconds.toMillis)
160
+
161
+ syncController ! SyncController .Start
162
+
163
+ val handshakedPeers = HandshakedPeers (singlePeer)
164
+ updateHandshakedPeers(handshakedPeers)
165
+ etcPeerManager.setAutoPilot(new AutoPilot {
166
+ def run (sender : ActorRef , msg : Any ): AutoPilot = {
167
+ if (msg == EtcPeerManagerActor .GetHandshakedPeers ) {
168
+ sender ! handshakedPeers
169
+ }
170
+
171
+ this
172
+ }
173
+ })
174
+
175
+ val watcher = TestProbe ()
176
+ watcher.watch(syncController)
177
+
178
+ val newBlocks = getHeaders(firstNewBlock, syncConfig.blockHeadersPerRequest)
179
+ val newReceipts = newBlocks.map(_.hash).map(_ => Seq .empty[Receipt ])
180
+ val newBodies = newBlocks.map(_ => BlockBody .empty)
181
+
182
+ // wait for peers throttle
183
+ Thread .sleep(syncConfig.fastSyncThrottle.toMillis)
184
+ sendBlockHeaders(firstNewBlock, newBlocks, peer1, newBlocks.size)
185
+
186
+ Thread .sleep(syncConfig.fastSyncThrottle.toMillis)
187
+ sendNewTargetBlock(defaultTargetBlockHeader.copy(number = defaultTargetBlockHeader.number + 1 ), peer1, peer1Status, handshakedPeers)
188
+
189
+ Thread .sleep(1 .second.toMillis)
190
+ sendReceipts(newBlocks.map(_.hash), Seq (), peer1)
191
+
192
+ // Peer will be blacklisted for empty response, so wait he is blacklisted
193
+ Thread .sleep(2 .second.toMillis)
194
+ sendReceipts(newBlocks.map(_.hash), newReceipts, peer1)
195
+
196
+ Thread .sleep(syncConfig.fastSyncThrottle.toMillis)
197
+ sendBlockBodies(newBlocks.map(_.hash), newBodies, peer1)
198
+
199
+ Thread .sleep(syncConfig.fastSyncThrottle.toMillis)
200
+ sendNodes(Seq (defaultTargetBlockHeader.stateRoot), Seq (defaultStateMptLeafWithAccount), peer1)
201
+
202
+ // switch to regular download
203
+ etcPeerManager.expectMsg(EtcPeerManagerActor .SendMessage (
204
+ GetBlockHeaders (Left (defaultTargetBlockHeader.number + 1 ), syncConfig.blockHeadersPerRequest, 0 , reverse = false ),
205
+ peer1.id))
206
+ peerMessageBus.expectMsg(Subscribe (MessageClassifier (Set (BlockHeaders .code), PeerSelector .WithId (peer1.id))))
207
+ }
208
+
209
+
148
210
it should " handle blocks that fail validation" in new TestSetup (_validators = new Mocks .MockValidatorsAlwaysSucceed {
149
211
override val blockHeaderValidator : BlockHeaderValidator = { (blockHeader, getBlockHeaderByHash) => Left (HeaderPoWError ) }
150
212
}) {
@@ -444,11 +506,12 @@ class SyncControllerSpec extends AnyFlatSpec with Matchers with BeforeAndAfter w
444
506
peerMessageBus.expectMsg(Unsubscribe ())
445
507
446
508
// response timeout
447
- Thread .sleep(2 .seconds.toMillis)
448
- etcPeerManager.expectNoMessage()
509
+ Thread .sleep(1 .seconds.toMillis)
510
+
511
+ etcPeerManager.expectNoMessage(1 .second)
449
512
450
513
// wait for blacklist timeout
451
- Thread .sleep(6 .seconds.toMillis)
514
+ Thread .sleep(2 .seconds.toMillis)
452
515
453
516
// peer should not be blacklisted anymore
454
517
etcPeerManager.expectMsg(EtcPeerManagerActor .SendMessage (GetNodeData (Seq (defaultTargetBlockHeader.stateRoot)), peer1.id))
@@ -577,7 +640,8 @@ class SyncControllerSpec extends AnyFlatSpec with Matchers with BeforeAndAfter w
577
640
minPeersToChooseTargetBlock = 1 ,
578
641
peersScanInterval = 500 .milliseconds,
579
642
redownloadMissingStateNodes = false ,
580
- fastSyncBlockValidationX = 10
643
+ fastSyncBlockValidationX = 10 ,
644
+ blacklistDuration = 1 .second
581
645
)
582
646
583
647
lazy val syncController = TestActorRef (Props (new SyncController (
0 commit comments