Skip to content

Commit cc65b2c

Browse files
author
Michal Mrozek
committed
[ECTM-104] Add more tests and logs
1 parent e0b5bec commit cc65b2c

File tree

9 files changed

+273
-132
lines changed

9 files changed

+273
-132
lines changed

src/it/scala/io/iohk/ethereum/sync/FastSyncItSpec.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ class FastSyncItSpec extends FlatSpecBase with Matchers with BeforeAndAfter {
6464
_ <- peer1.startFastSync().delayExecution(50.milliseconds)
6565
_ <- peer1.waitForFastSyncFinish()
6666
} yield {
67-
assert(peer1.bl.getBestBlockNumber() == peer2.bl.getBestBlockNumber() - peer2.testSyncConfig.targetBlockOffset)
68-
assert(peer1.bl.getBestBlockNumber() == peer3.bl.getBestBlockNumber() - peer3.testSyncConfig.targetBlockOffset)
67+
assert(peer1.bl.getBestBlockNumber() == peer2.bl.getBestBlockNumber() - peer2.testSyncConfig.pivotBlockOffset)
68+
assert(peer1.bl.getBestBlockNumber() == peer3.bl.getBestBlockNumber() - peer3.testSyncConfig.pivotBlockOffset)
6969
}
7070
}
7171

@@ -81,13 +81,13 @@ class FastSyncItSpec extends FlatSpecBase with Matchers with BeforeAndAfter {
8181
val trie = peer1.getBestBlockTrie()
8282
// due to the fact that function generating state is deterministic both peer2 and peer3 ends up with exactly same
8383
// state, so peer1 can get whole trie from both of them.
84-
assert(peer1.bl.getBestBlockNumber() == peer2.bl.getBestBlockNumber() - peer2.testSyncConfig.targetBlockOffset)
85-
assert(peer1.bl.getBestBlockNumber() == peer3.bl.getBestBlockNumber() - peer3.testSyncConfig.targetBlockOffset)
84+
assert(peer1.bl.getBestBlockNumber() == peer2.bl.getBestBlockNumber() - peer2.testSyncConfig.pivotBlockOffset)
85+
assert(peer1.bl.getBestBlockNumber() == peer3.bl.getBestBlockNumber() - peer3.testSyncConfig.pivotBlockOffset)
8686
assert(trie.isDefined)
8787
}
8888
}
8989

90-
it should "should update target block" in customTestCaseResourceM(FakePeer.start2FakePeersRes()) {
90+
it should "should update pivot block" in customTestCaseResourceM(FakePeer.start2FakePeersRes()) {
9191
case (peer1, peer2) =>
9292
for {
9393
_ <- peer2.importBlocksUntil(1000)(IdentityUpdate)
@@ -96,7 +96,7 @@ class FastSyncItSpec extends FlatSpecBase with Matchers with BeforeAndAfter {
9696
_ <- peer1.startFastSync().delayExecution(50.milliseconds)
9797
_ <- peer1.waitForFastSyncFinish()
9898
} yield {
99-
assert(peer1.bl.getBestBlockNumber() == peer2.bl.getBestBlockNumber() - peer2.testSyncConfig.targetBlockOffset)
99+
assert(peer1.bl.getBestBlockNumber() == peer2.bl.getBestBlockNumber() - peer2.testSyncConfig.pivotBlockOffset)
100100
}
101101
}
102102
}
@@ -308,7 +308,7 @@ object FastSyncItSpec {
308308
lazy val validators = new MockValidatorsAlwaysSucceed
309309

310310
val testSyncConfig = syncConfig.copy(
311-
minPeersToChooseTargetBlock = 1,
311+
minPeersToChoosePivotBlock = 1,
312312
peersScanInterval = 5.milliseconds,
313313
blockHeadersPerRequest = 200,
314314
blockBodiesPerRequest = 50,

src/main/resources/application.conf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,12 +320,12 @@ mantis {
320320
# Requested number of MPT nodes when syncing from other peers
321321
nodes-per-request = 384
322322

323-
# Minimum number of peers required to start fast-sync (by determining the target block)
324-
min-peers-to-choose-target-block = 2
323+
# Minimum number of peers required to start fast-sync (by determining the pivot block)
324+
min-peers-to-choose-pivot-block = 3
325325

326326
# During fast-sync when most up to date block is determined from peers, the actual target block number
327327
# will be decreased by this value
328-
target-block-offset = 128
328+
pivot-block-offset = 128
329329

330330
# How often to query peers for new blocks after the top of the chain has been reached
331331
check-for-new-block-interval = 10.seconds

src/main/scala/io/iohk/ethereum/blockchain/sync/FastSync.scala

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class FastSync(
140140
scheduler.scheduleWithFixedDelay(syncRetryInterval, syncRetryInterval * 2, self, ProcessSyncing)
141141

142142
def receive: Receive = handleCommonMessages orElse {
143-
case UpdateTargetBlock(state) => updateTargetBlock(state)
143+
case UpdatePivotBlock(state) => updatePivotBlock(state)
144144
case ProcessSyncing => processSyncing()
145145
case PrintStatus => printStatus()
146146
case PersistSyncState => persistSyncState()
@@ -189,34 +189,34 @@ class FastSync(
189189
}
190190

191191
def waitingForTargetBlockUpdate(processState: FinalBlockProcessingResult): Receive = handleCommonMessages orElse {
192-
case FastSyncPivotBlockSelector.Result(targetBlockHeader) =>
193-
log.info(s"new target block with number ${targetBlockHeader.number} received")
194-
if (targetBlockHeader.number >= syncState.pivotBlock.number) {
195-
updateTargetSyncState(processState, targetBlockHeader)
192+
case FastSyncPivotBlockSelector.Result(pivotBlockHeader) =>
193+
log.info(s"New pivot block with number ${pivotBlockHeader.number} received")
194+
if (pivotBlockHeader.number >= syncState.pivotBlock.number) {
195+
updatePivotSyncState(processState, pivotBlockHeader)
196196
syncState = syncState.copy(updatingTargetBlock = false)
197197
context become this.receive
198198
processSyncing()
199199
} else {
200200
syncState = syncState.copy(targetBlockUpdateFailures = syncState.targetBlockUpdateFailures + 1)
201-
scheduler.scheduleOnce(syncRetryInterval, self, UpdateTargetBlock(processState))
201+
scheduler.scheduleOnce(syncRetryInterval, self, UpdatePivotBlock(processState))
202202
}
203203

204204
case PersistSyncState => persistSyncState()
205205

206-
case UpdateTargetBlock(state) => updateTargetBlock(state)
206+
case UpdatePivotBlock(state) => updatePivotBlock(state)
207207
}
208208

209-
private def updateTargetBlock(state: FinalBlockProcessingResult): Unit = {
209+
private def updatePivotBlock(state: FinalBlockProcessingResult): Unit = {
210210
syncState = syncState.copy(updatingTargetBlock = true)
211211
if (syncState.targetBlockUpdateFailures <= syncConfig.maximumTargetUpdateFailures) {
212212
if (assignedHandlers.nonEmpty) {
213213
log.info(s"Still waiting for some responses, rescheduling target block update")
214-
scheduler.scheduleOnce(syncRetryInterval, self, UpdateTargetBlock(state))
214+
scheduler.scheduleOnce(syncRetryInterval, self, UpdatePivotBlock(state))
215215
} else {
216-
log.info("Asking for new target block")
217-
val targetBlockSelector =
216+
log.info("Asking for new pivot block")
217+
val pivotBlockSelector =
218218
context.actorOf(FastSyncPivotBlockSelector.props(etcPeerManager, peerEventBus, syncConfig, scheduler))
219-
targetBlockSelector ! FastSyncPivotBlockSelector.ChoosePivotBlock
219+
pivotBlockSelector ! FastSyncPivotBlockSelector.ChoosePivotBlock
220220
context become waitingForTargetBlockUpdate(state)
221221
}
222222
} else {
@@ -225,7 +225,7 @@ class FastSync(
225225
}
226226
}
227227

228-
private def updateTargetSyncState(state: FinalBlockProcessingResult, targetBlockHeader: BlockHeader): Unit =
228+
private def updatePivotSyncState(state: FinalBlockProcessingResult, targetBlockHeader: BlockHeader): Unit =
229229
state match {
230230
case ImportedLastBlock =>
231231
if (targetBlockHeader.number - syncState.pivotBlock.number <= syncConfig.maxTargetDifference) {
@@ -340,7 +340,7 @@ class FastSync(
340340
discardLastBlocks(header.number, N)
341341
syncState = syncState.updateDiscardedBlocks(header, N)
342342
if (header.number >= syncState.pivotBlock.number) {
343-
updateTargetBlock(LastBlockValidationFailed)
343+
updatePivotBlock(LastBlockValidationFailed)
344344
} else {
345345
processSyncing()
346346
}
@@ -361,7 +361,7 @@ class FastSync(
361361
case HeadersProcessingFinished =>
362362
processSyncing()
363363
case ImportedTargetBlock =>
364-
updateTargetBlock(ImportedLastBlock)
364+
updatePivotBlock(ImportedLastBlock)
365365
case ValidationFailed(header, peerToBlackList) =>
366366
log.warning(s"validation fo header ${header.idTag} failed")
367367
handleRewind(header, peerToBlackList, syncConfig.fastSyncBlockValidationN)
@@ -839,7 +839,7 @@ object FastSync {
839839
)
840840
)
841841

842-
private case class UpdateTargetBlock(state: FinalBlockProcessingResult)
842+
private case class UpdatePivotBlock(state: FinalBlockProcessingResult)
843843
private case object ProcessSyncing
844844
private[sync] case object PersistSyncState
845845
private case object PrintStatus

src/main/scala/io/iohk/ethereum/blockchain/sync/FastSyncPivotBlockSelector.scala

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,21 @@ class FastSyncPivotBlockSelector(
3434
def idle: Receive = handleCommonMessages orElse { case ChoosePivotBlock =>
3535
val peersUsedToChooseTarget = peersToDownloadFrom.filter(_._2.forkAccepted)
3636

37-
if (peersUsedToChooseTarget.size >= minPeersToChooseTargetBlock) {
37+
if (peersUsedToChooseTarget.size >= minPeersToChoosePivotBlock) {
3838
peersUsedToChooseTarget.foreach { case (peer, PeerInfo(status, _, _, _, _)) =>
3939
peerEventBus ! Subscribe(MessageClassifier(Set(BlockHeaders.code), PeerSelector.WithId(peer.id)))
4040
etcPeerManager ! EtcPeerManagerActor.SendMessage(
4141
GetBlockHeaders(Right(status.bestHash), 1, 0, reverse = false),
4242
peer.id
4343
)
4444
}
45-
log.debug("Asking {} peers for block headers", peersUsedToChooseTarget.size)
45+
log.info("Asking {} peers for block headers", peersUsedToChooseTarget.size)
4646
val timeout = scheduler.scheduleOnce(peerResponseTimeout, self, BlockHeadersTimeout)
4747
context become waitingForBlockHeaders(peersUsedToChooseTarget.keySet, Map.empty, timeout)
4848
} else {
4949
log.info(
5050
"Cannot pick pivot block. Need at least {} peers, but there are only {} available at the moment. Retrying in {}",
51-
minPeersToChooseTargetBlock,
51+
minPeersToChoosePivotBlock,
5252
peersUsedToChooseTarget.size,
5353
startRetryInterval
5454
)
@@ -61,6 +61,12 @@ class FastSyncPivotBlockSelector(
6161
handleCommonMessages orElse {
6262
case MessageFromPeer(BlockHeaders(Seq(blockHeader)), peerId) =>
6363
peerEventBus ! Unsubscribe(MessageClassifier(Set(BlockHeaders.code), PeerSelector.WithId(peerId)))
64+
log.info(
65+
s"Received block header [number: {}, hash: {}] from peer: {}",
66+
blockHeader.number,
67+
blockHeader.hashAsHexString,
68+
peerId.value
69+
)
6470

6571
val newWaitingFor = waitingFor.filterNot(_.id == peerId)
6672

@@ -98,12 +104,10 @@ class FastSyncPivotBlockSelector(
98104

99105
def tryChooseTargetBlock(receivedHeaders: Map[Peer, BlockHeader]): Unit = {
100106
log.debug("Trying to choose fast sync pivot block. Received {} block headers", receivedHeaders.size)
101-
if (receivedHeaders.size >= minPeersToChooseTargetBlock) {
102-
107+
if (receivedHeaders.size >= minPeersToChoosePivotBlock) {
103108
val peersWithBestHeaders = receivedHeaders.toList.sortBy(-_._2.number)
104-
105109
val bestPeerBestBlockNumber = peersWithBestHeaders.head._2.number
106-
val targetBlock = bestPeerBestBlockNumber - syncConfig.targetBlockOffset
110+
val targetBlock = (bestPeerBestBlockNumber - syncConfig.pivotBlockOffset).max(0)
107111

108112
val peersToAsk = peersWithBestHeaders.takeWhile(_._2.number >= targetBlock).map(_._1)
109113

@@ -116,12 +120,12 @@ class FastSyncPivotBlockSelector(
116120
}
117121

118122
val timeout = scheduler.scheduleOnce(peerResponseTimeout, self, PivotBlockTimeout)
119-
context become waitingForTargetBlock(peersToAsk.map(_.id).toSet, targetBlock, timeout, Map.empty)
123+
context become waitingForPivotBlock(peersToAsk.map(_.id).toSet, targetBlock, timeout, Map.empty)
120124

121125
} else {
122126
log.info(
123127
"Cannot pick pivot block. Need to receive block headers from at least {} peers, but received only from {}. Retrying in {}",
124-
minPeersToChooseTargetBlock,
128+
minPeersToChoosePivotBlock,
125129
receivedHeaders.size,
126130
startRetryInterval
127131
)
@@ -130,7 +134,7 @@ class FastSyncPivotBlockSelector(
130134
}
131135
}
132136

133-
def waitingForTargetBlock(
137+
def waitingForPivotBlock(
134138
peersToAsk: Set[PeerId],
135139
targetBlockNumber: BigInt,
136140
timeout: Cancellable,
@@ -144,23 +148,25 @@ class FastSyncPivotBlockSelector(
144148

145149
targetBlockHeaderOpt match {
146150
case Some(targetBlockHeader) =>
151+
log.info("Received vote for {} from {}", targetBlockHeader.hashAsHexString, peerId.value)
147152
val newValue = headers.find(_._1 == targetBlockHeader).map(_._2 + 1).getOrElse(1)
148153
val updatedHeaders = headers.updated(targetBlockHeader, newValue)
149154
val (mostPopularBlockHeader, votes) = updatedHeaders.maxBy(_._2)
150-
if (votes >= minPeersToChooseTargetBlock) {
155+
if (votes >= minPeersToChoosePivotBlock) {
151156
timeout.cancel()
152157
sendResponseAndCleanup(mostPopularBlockHeader)
153-
} else if (updatedPeersToAsk.isEmpty) {
158+
} else if (updatedPeersToAsk.size + votes < minPeersToChoosePivotBlock) {
154159
timeout.cancel()
160+
peerEventBus ! Unsubscribe()
155161
log.info("Not enough votes for pivot block. Retrying in {}", startRetryInterval)
156162
scheduleRetry(startRetryInterval)
157163
context become idle
158164
} else {
159-
context become waitingForTargetBlock(updatedPeersToAsk, targetBlockNumber, timeout, updatedHeaders)
165+
context become waitingForPivotBlock(updatedPeersToAsk, targetBlockNumber, timeout, updatedHeaders)
160166
}
161167
case None =>
162168
blacklist(peerId, blacklistDuration, "Did not respond with pivot block header, blacklisting")
163-
context become waitingForTargetBlock(updatedPeersToAsk, targetBlockNumber, timeout, headers)
169+
context become waitingForPivotBlock(updatedPeersToAsk, targetBlockNumber, timeout, headers)
164170
}
165171
case PivotBlockTimeout =>
166172
peersToAsk.foreach { peerId =>

0 commit comments

Comments
 (0)