Skip to content

Commit 30136c1

Browse files
author
Jaap van der Plas
committed
mark PeerEventBus-based flow as temporary and use FetcherService SourceQueue
1 parent 4dee3df commit 30136c1

File tree

3 files changed

+34
-28
lines changed

3 files changed

+34
-28
lines changed

src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BranchBuffer.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ case class BranchBuffer(byParent: Map[Hash, Block] = Map.empty, branchFound: Que
4141
object BranchBuffer {
4242
type Hash = ByteString
4343

44-
def flow(blockchainReader: BlockchainReader): Flow[Seq[Block], NonEmptyList[Block], NotUsed] =
45-
Flow[Seq[Block]]
46-
.mapConcat(_.sortBy(_.number).reverse)
44+
def flow(blockchainReader: BlockchainReader): Flow[Block, NonEmptyList[Block], NotUsed] =
45+
Flow[Block]
4746
.scan(BranchBuffer()) { case (buffer, block) => buffer.handle(blockchainReader.getBestBranch(), block) }
4847
.collect { case BranchBuffer(_, head +: tail) => NonEmptyList(head, tail.toList) }
4948
}

src/main/scala/io/iohk/ethereum/blockchain/sync/regular/FetcherService.scala

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import io.iohk.ethereum.network.p2p.messages.ETH62.BlockHeaders
2727
import io.iohk.ethereum.utils.Config.SyncConfig
2828
import akka.stream.scaladsl.SourceQueue
2929
import akka.stream.QueueOfferResult.Enqueued
30+
import akka.NotUsed
3031

3132
//not used atm, a part of the future ExecutionSync
3233
class FetcherService(
@@ -48,10 +49,10 @@ class FetcherService(
4849

4950
//TODO: add private def requestStateNode(hash: ByteString): Task[Either[RequestFailed, Seq[ByteString]]] = ???
5051

51-
private def placeBlockInPeerStream(peer: Peer, block: Block): Task[Either[RequestFailed, Unit]] =
52+
def placeBlockInPeerStream(block: Block): Task[Either[String, Unit]] =
5253
Task.deferFuture(sourceQueue.offer(block)).map {
5354
case Enqueued => Right(())
54-
case result => Left(RequestFailed(peer, result.toString()))
55+
case reason => Left(s"SourceQueue.offer failed: $reason")
5556
}
5657

5758
def fetchBlocksUntil(
@@ -87,13 +88,11 @@ class FetcherService(
8788
bodies <- EitherT(requestBodies(headers.headers.map(_.hash)))
8889
blocks = buildBlocks(headers.headers, bodies.bodies)
8990
_ <- EitherT.cond[Task](blocks.length == headers.headers.length, (), RequestFailed(peer, "Unmatching bodies"))
90-
_ <- blocks.traverse(block => EitherT(placeBlockInPeerStream(peer, block)))
91+
_ <- blocks.traverse(block => EitherT(placeBlockInPeerStream(block)).leftMap(RequestFailed(peer, _)))
9192
} yield peer
9293
}
9394

9495
object FetcherService {
95-
type Hashes = Seq[ByteString]
96-
9796
case class BlockIdentifier(transactionsRoot: ByteString, ommersHash: ByteString)
9897
object BlockIdentifier {
9998
def apply(blockHeader: BlockHeader): BlockIdentifier =
@@ -117,31 +116,25 @@ object FetcherService {
117116
/** State of block fetching stream after processing a given incoming message with block headers or bodies
118117
*
119118
* @param outstanding headers that are yet to be matched to bodies
120-
* @param bodiesRequest information for requesting bodies corresponding to newly outstanding headers
121119
* @param result blocks produced by matching received headers with received bodies
122120
*/
123121
case class FetchState(
124122
outstanding: Set[BlockHeader],
125-
bodiesRequest: Option[(PeerId, Hashes)],
126123
result: Seq[Block]
127124
)
128125
object FetchState {
129-
val initial: FetchState = FetchState(Set.empty, None, Nil)
126+
val initial: FetchState = FetchState(Set.empty, Nil)
130127
}
131128

132-
def fetchBlocksForHeaders[M](bodyRequestor: Sink[(PeerId, Hashes), M]): Flow[MessageFromPeer, Seq[Block], M] =
129+
// TODO: remove once we have the FetcherService instance integrated
130+
val tempFlow: Flow[MessageFromPeer, Seq[Block], NotUsed] =
133131
Flow[MessageFromPeer]
134132
.scan(FetchState.initial) {
135-
case (FetchState(outstanding, _, _), MessageFromPeer(BlockHeaders(headers), peerId)) =>
136-
FetchState(outstanding.concat(headers), Some(peerId -> headers.map(_.hash)), Nil)
137-
case (FetchState(outstanding, _, _), MessageFromPeer(BlockBodies(bodies), _)) =>
133+
case (FetchState(outstanding, _), MessageFromPeer(BlockHeaders(headers), peerId)) =>
134+
FetchState(outstanding.concat(headers), Nil)
135+
case (FetchState(outstanding, _), MessageFromPeer(BlockBodies(bodies), _)) =>
138136
val blocks = buildBlocks(outstanding.toSeq, bodies)
139-
FetchState(outstanding.removedAll(blocks.map(_.header)), None, blocks)
137+
FetchState(outstanding.removedAll(blocks.map(_.header)), blocks)
140138
}
141-
.alsoToMat(
142-
Flow[FetchState]
143-
.collect { case FetchState(_, Some(bodiesRequest), _) => bodiesRequest }
144-
.toMat(bodyRequestor)(Keep.right)
145-
)(Keep.right)
146-
.collect { case FetchState(_, _, blocks) if blocks.nonEmpty => blocks }
139+
.collect { case FetchState(_, blocks) if blocks.nonEmpty => blocks }
147140
}

src/main/scala/io/iohk/ethereum/blockchain/sync/regular/RegularSync.scala

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ import io.iohk.ethereum.network.p2p.messages.ETH62
4545
import io.iohk.ethereum.nodebuilder.BlockchainConfigBuilder
4646
import io.iohk.ethereum.utils.ByteStringUtils
4747
import io.iohk.ethereum.utils.Config.SyncConfig
48+
import akka.stream.scaladsl.Source
49+
import io.iohk.ethereum.network.Peer
4850

4951
class RegularSync(
5052
peersClient: ActorRef,
@@ -107,11 +109,15 @@ class RegularSync(
107109
BlockFetcher.PrintStatus
108110
)
109111

112+
val (blockSourceQueue, blockSource) = Source.queue[Block](256, OverflowStrategy.fail).preMaterialize()
113+
val fetcherService = new FetcherService(blockchainReader, syncConfig, blockSourceQueue)
114+
110115
override def receive: Receive = running(
111116
ProgressState(startedFetching = false, initialBlock = 0, currentBlock = 0, bestKnownNetworkBlock = 0)
112117
)
113118

114-
private def startNewFlow() =
119+
private def startTemporaryBlockProducer() = {
120+
import monix.execution.Scheduler.Implicits.global
115121
PeerEventBusActor
116122
.messageSource(
117123
peerEventBus,
@@ -121,12 +127,20 @@ class RegularSync(
121127
PeerEventBusActor.PeerSelector.AllPeers
122128
)
123129
)
130+
.via(FetcherService.tempFlow)
124131
.buffer(256, OverflowStrategy.fail)
125-
.via(
126-
FetcherService.fetchBlocksForHeaders(
127-
Sink.ignore // BlockFetcher is relied on for requesting the bodies
128-
)
129-
)
132+
.mapConcat(identity)
133+
.runWith(Sink.foreachAsync(1) { block =>
134+
fetcherService
135+
.placeBlockInPeerStream(block)
136+
.runToFuture
137+
.collect { case Right(()) => () }
138+
139+
})
140+
}
141+
142+
private def startNewFlow() =
143+
blockSource
130144
.via(BranchBuffer.flow(blockchainReader))
131145
.runWith(Sink.foreach { blocks =>
132146
importer ! BlockFetcher.PickedBlocks(blocks)

0 commit comments

Comments
 (0)