Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ETCM-972: Add skeleton for future ExecutionSync - fetching part
Scalafmt
- Loading branch information
1 parent
16703e8
commit 607f456
Showing
10 changed files
with
170 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
src/main/scala/io/iohk/ethereum/blockchain/sync/regular/BlockImporterService.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package io.iohk.ethereum.blockchain.sync.regular | ||
|
||
import cats.data.NonEmptyList | ||
import io.iohk.ethereum.blockchain.sync.regular.BlockImporter.{BlockImportType, ImportFn, ResolvingBranch} | ||
import io.iohk.ethereum.domain.Block | ||
|
||
//not used atm, a part of the future ExecutionSync | ||
class BlockImporterService() { | ||
|
||
private def importBlocks(blocks: NonEmptyList[Block], blockImportType: BlockImportType) = ??? | ||
|
||
private def importBlock(block: Block) = ??? | ||
|
||
} |
28 changes: 28 additions & 0 deletions
28
src/main/scala/io/iohk/ethereum/blockchain/sync/regular/ChainManagerService.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package io.iohk.ethereum.blockchain.sync.regular | ||
|
||
import cats.data.NonEmptyList | ||
import io.iohk.ethereum.blockchain.sync.regular.BlockImporter.BlockImportType | ||
import io.iohk.ethereum.domain.Block | ||
import io.iohk.ethereum.network.Peer | ||
import monix.eval.Task | ||
|
||
//not used atm, a part of the future ExecutionSync | ||
object ChainManagerService { | ||
|
||
type ValidationError | ||
type Branch | ||
|
||
//saves blocks to the storage | ||
def processBlocksFromFetcher(peer: Peer): Task[Either[ValidationError, Branch]] = ??? | ||
|
||
//saves blocks to the storage | ||
def processMinedBlocks(): Task[Either[ValidationError, Branch]] = ??? | ||
|
||
private def resolvingMissingNode(blocksToRetry: NonEmptyList[Block], blockImportType: BlockImportType) = ??? | ||
|
||
private def buildBranch() = ??? | ||
|
||
private def resolveBranch() = ??? | ||
|
||
private def discriminateBranch() = ??? | ||
} |
86 changes: 86 additions & 0 deletions
86
src/main/scala/io/iohk/ethereum/blockchain/sync/regular/FetcherService.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package io.iohk.ethereum.blockchain.sync.regular | ||
|
||
import akka.util.ByteString | ||
import cats.data.EitherT | ||
import io.iohk.ethereum.domain.{Block, BlockBody, BlockHeader, BlockchainReader} | ||
import io.iohk.ethereum.network.Peer | ||
import io.iohk.ethereum.network.p2p.messages.ETH62.{BlockBodies, BlockHeaders} | ||
import monix.eval.Task | ||
import io.iohk.ethereum.blockchain.sync.PeerRequestHandler.RequestFailed | ||
import io.iohk.ethereum.consensus.validators.BlockValidator | ||
import io.iohk.ethereum.utils.Config.SyncConfig | ||
import cats.implicits._ | ||
|
||
import scala.annotation.tailrec | ||
|
||
//not used atm, a part of the future ExecutionSync | ||
class FetcherService(validator: BlockValidator, blockchainReader: BlockchainReader, syncConfig: SyncConfig) { | ||
val batchSize = syncConfig.blockHeadersPerRequest | ||
|
||
private def requestHeaders( | ||
block: Either[BigInt, ByteString], | ||
amount: BigInt | ||
): Task[Either[RequestFailed, BlockHeaders]] = ??? | ||
|
||
private def requestBodies(hashes: Seq[ByteString]): Task[Either[RequestFailed, BlockBodies]] = ??? | ||
|
||
private def requestStateNode(hash: ByteString): Task[Either[RequestFailed, Seq[ByteString]]] = ??? | ||
|
||
private def placeBlockInQueue(block: Block, peer: Peer): Unit = ??? | ||
|
||
def fetchBlocksUntil( | ||
peer: Peer, | ||
startFromBlock: Either[BigInt, ByteString], | ||
fetchUntilBlock: Either[BigInt, ByteString] | ||
): EitherT[Task, RequestFailed, Unit] = { | ||
val endNumber: Option[BigInt] = | ||
fetchUntilBlock.fold(Some(_), blockchainReader.getBlockHeaderByHash(_).map(_.number)) | ||
val startNumber: Option[BigInt] = | ||
startFromBlock.fold(Some(_), blockchainReader.getBlockHeaderByHash(_).map(_.number)) | ||
|
||
//TODO: make sure negatives are not possible | ||
val startBatchBlocks: Option[Seq[BigInt]] = | ||
for { | ||
start <- startNumber | ||
end <- endNumber | ||
} yield start.to(end, batchSize) | ||
|
||
startBatchBlocks match { | ||
case None => EitherT.leftT(RequestFailed(peer, "couldn't find blocks to fetch")) | ||
case Some(seq) => seq.traverse(num => fetchBlocks(peer, batchSize, Left(num))).map(_ => ()) | ||
} | ||
} | ||
|
||
private def fetchBlocks( | ||
peer: Peer, | ||
amount: BigInt, | ||
block: Either[BigInt, ByteString] | ||
): EitherT[Task, RequestFailed, Unit] = | ||
for { | ||
headers <- EitherT(requestHeaders(block, amount)) | ||
bodies <- EitherT(requestBodies(headers.headers.map(_.hash))) | ||
blocks <- EitherT.fromOption[Task]( | ||
bodiesAreOrderedSubsetOfRequested(headers.headers, bodies.bodies), | ||
RequestFailed(peer, "Unmatching bodies") | ||
) | ||
_ = blocks.foreach(placeBlockInQueue(_, peer)) | ||
} yield () | ||
|
||
// Checks that the received block bodies are an ordered subset of the ones requested | ||
@tailrec | ||
private def bodiesAreOrderedSubsetOfRequested( | ||
requestedHeaders: Seq[BlockHeader], | ||
respondedBodies: Seq[BlockBody], | ||
matchedBlocks: Seq[Block] = Nil | ||
): Option[Seq[Block]] = | ||
(requestedHeaders, respondedBodies) match { | ||
case (Seq(), _ +: _) => None | ||
case (_, Seq()) => Some(matchedBlocks) | ||
case (header +: remainingHeaders, body +: remainingBodies) => | ||
val doMatch = validator.validateHeaderAndBody(header, body).isRight | ||
if (doMatch) | ||
bodiesAreOrderedSubsetOfRequested(remainingHeaders, remainingBodies, matchedBlocks :+ Block(header, body)) | ||
else | ||
bodiesAreOrderedSubsetOfRequested(remainingHeaders, respondedBodies, matchedBlocks) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters