@@ -2,34 +2,40 @@ package io.iohk.ethereum.blockchain.sync.regular
22
33import akka .actor .Actor .Receive
44import akka .actor .{Actor , ActorLogging , ActorRef , NotInfluenceReceiveTimeout , Props , ReceiveTimeout }
5+ import akka .util .ByteString
56import cats .data .NonEmptyList
67import cats .instances .future ._
78import cats .instances .list ._
89import cats .syntax .apply ._
910import io .iohk .ethereum .blockchain .sync .regular .BlockBroadcasterActor .BroadcastBlocks
10- import io .iohk .ethereum .crypto .kec256
11- import io .iohk .ethereum .domain .{Block , Blockchain , SignedTransaction }
11+ import io .iohk .ethereum .consensus .blocks .CheckpointBlockGenerator
12+ import io .iohk .ethereum .crypto .{ECDSASignature , kec256 }
13+ import io .iohk .ethereum .domain .{Block , Blockchain , Checkpoint , SignedTransaction }
1214import io .iohk .ethereum .ledger ._
1315import io .iohk .ethereum .mpt .MerklePatriciaTrie .MissingNodeException
1416import io .iohk .ethereum .network .PeerId
1517import io .iohk .ethereum .network .p2p .messages .CommonMessages .NewBlock
1618import io .iohk .ethereum .ommers .OmmersPool .{AddOmmers , RemoveOmmers }
1719import io .iohk .ethereum .transactions .PendingTransactionsManager
1820import io .iohk .ethereum .transactions .PendingTransactionsManager .{AddUncheckedTransactions , RemoveTransactions }
21+ import io .iohk .ethereum .utils .ByteStringUtils
1922import io .iohk .ethereum .utils .Config .SyncConfig
2023import io .iohk .ethereum .utils .FunctorOps ._
2124
2225import scala .concurrent .{ExecutionContext , Future }
26+ import scala .concurrent .duration ._
2327import scala .util .{Failure , Success }
2428
29+ // scalastyle:off cyclomatic.complexity
2530class BlockImporter (
2631 fetcher : ActorRef ,
2732 ledger : Ledger ,
2833 blockchain : Blockchain ,
2934 syncConfig : SyncConfig ,
3035 ommersPool : ActorRef ,
3136 broadcaster : ActorRef ,
32- pendingTransactionsManager : ActorRef
37+ pendingTransactionsManager : ActorRef ,
38+ checkpointBlockGenerator : CheckpointBlockGenerator
3339) extends Actor
3440 with ActorLogging {
3541 import BlockImporter ._
@@ -56,15 +62,35 @@ class BlockImporter(
5662
5763 private def running (state : ImporterState ): Receive = handleTopMessages(state, running) orElse {
5864 case ReceiveTimeout => self ! PickBlocks
65+
5966 case PrintStatus => log.info(" Block: {}, is on top?: {}" , blockchain.getBestBlockNumber(), state.isOnTop)
67+
6068 case BlockFetcher .PickedBlocks (blocks) =>
6169 SignedTransaction .retrieveSendersInBackGround(blocks.toList.map(_.body))
6270 importBlocks(blocks)(state)
71+
6372 case MinedBlock (block) =>
6473 if (! state.importing) {
6574 importMinedBlock(block, state)
6675 }
76+
77+ case nc @ NewCheckpoint (parentHash, signatures) =>
78+ if (state.importing) {
79+ // TODO: is this ok? What delay?
80+ context.system.scheduler.scheduleOnce(100 .millis, self, nc)
81+ } else {
82+ ledger.getBlockByHash(parentHash) match {
83+ case Some (parent) =>
84+ val checkpointBlock = checkpointBlockGenerator.generate(parent, Checkpoint (signatures))
85+ importCheckpointBlock(checkpointBlock, state)
86+
87+ case None =>
88+ log.error(s " Could not find parent ( ${ByteStringUtils .hash2string(parentHash)}) for new checkpoint block " )
89+ }
90+ }
91+
6792 case ImportNewBlock (block, peerId) if state.isOnTop && ! state.importing => importNewBlock(block, peerId, state)
93+
6894 case ImportDone (newBehavior) =>
6995 val newState = state.notImportingBlocks().branchResolved()
7096 val behavior : Behavior = getBehavior(newBehavior)
@@ -177,6 +203,9 @@ class BlockImporter(
177203 private def importMinedBlock (block : Block , state : ImporterState ): Unit =
178204 importBlock(block, new MinedBlockImportMessages (block), informFetcherOnFail = false )(state)
179205
206+ private def importCheckpointBlock (block : Block , state : ImporterState ): Unit =
207+ importBlock(block, new CheckpointBlockImportMessages (block), informFetcherOnFail = false )(state)
208+
180209 private def importNewBlock (block : Block , peerId : PeerId , state : ImporterState ): Unit =
181210 importBlock(block, new NewBlockImportMessages (block, peerId), informFetcherOnFail = true )(state)
182211
@@ -294,10 +323,20 @@ object BlockImporter {
294323 syncConfig : SyncConfig ,
295324 ommersPool : ActorRef ,
296325 broadcaster : ActorRef ,
297- pendingTransactionsManager : ActorRef
326+ pendingTransactionsManager : ActorRef ,
327+ checkpointBlockGenerator : CheckpointBlockGenerator
298328 ): Props =
299329 Props (
300- new BlockImporter (fetcher, ledger, blockchain, syncConfig, ommersPool, broadcaster, pendingTransactionsManager)
330+ new BlockImporter (
331+ fetcher,
332+ ledger,
333+ blockchain,
334+ syncConfig,
335+ ommersPool,
336+ broadcaster,
337+ pendingTransactionsManager,
338+ checkpointBlockGenerator
339+ )
301340 )
302341
303342 type Behavior = ImporterState => Receive
@@ -308,6 +347,7 @@ object BlockImporter {
308347 case object OnTop extends ImporterMsg
309348 case object NotOnTop extends ImporterMsg
310349 case class MinedBlock (block : Block ) extends ImporterMsg
350+ case class NewCheckpoint (parentHash : ByteString , signatures : Seq [ECDSASignature ]) extends ImporterMsg
311351 case class ImportNewBlock (block : Block , peerId : PeerId ) extends ImporterMsg
312352 case class ImportDone (newBehavior : NewBehavior ) extends ImporterMsg
313353 case object PickBlocks extends ImporterMsg
0 commit comments