Skip to content

Commit 04d6529

Browse files
author
Leonor Boga
committed
ETCM-1058 Refactor ConsensusImpl
1 parent 39f6410 commit 04d6529

File tree

1 file changed

+47
-36
lines changed

1 file changed

+47
-36
lines changed

src/main/scala/io/iohk/ethereum/consensus/ConsensusImpl.scala

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ class ConsensusImpl(
4444

4545
/** Tries to import the block as the new best block in the chain or enqueue it for later processing.
4646
*
47-
* @param block block to be imported
48-
* @param blockExecutionContext threadPool on which the execution should be run
47+
* @param block block to be imported
48+
* @param blockExecutionScheduler threadPool on which the execution should be run
49+
* @param blockchainConfig blockchain configuration
4950
* @return One of:
5051
* - [[BlockImportedToTop]] - if the block was added as the new best block
5152
* - [[BlockEnqueued]] - block is stored in the [[io.iohk.ethereum.ledger.BlockQueue]]
@@ -59,36 +60,42 @@ class ConsensusImpl(
5960
blockchainReader.getBestBlock() match {
6061
case Some(bestBlock) =>
6162
if (isBlockADuplicate(block.header, bestBlock.header.number)) {
62-
Task(log.debug(s"Ignoring duplicate block: (${block.idTag})"))
63-
.map(_ => DuplicateBlock)
63+
log.debug("Ignoring duplicated block: {}", block.idTag)
64+
Task.now(DuplicateBlock)
6465
} else {
6566
val hash = bestBlock.header.hash
6667
blockchain.getChainWeightByHash(hash) match {
6768
case Some(weight) =>
6869
val importResult = if (isPossibleNewBestBlock(block.header, bestBlock.header)) {
6970
importToTop(block, bestBlock, weight)
7071
} else {
71-
reorganise(block, bestBlock, weight)
72+
reorganiseOrEnqueue(block, bestBlock, weight)
7273
}
7374
importResult.foreach(measureBlockMetrics)
7475
importResult
75-
case None =>
76-
log.error(
77-
"Getting total difficulty for current best block with hash: {} failed",
78-
bestBlock.header.hashAsHexString
79-
)
80-
Task.now(
81-
BlockImportFailed(
82-
s"Couldn't get total difficulty for current best block with hash: ${bestBlock.header.hashAsHexString}"
83-
)
84-
)
76+
case None => returnNoTotalDifficulty(bestBlock)
8577
}
8678
}
87-
case None =>
88-
log.error("Getting current best block failed")
89-
Task.now(BlockImportFailed("Couldn't find the current best block"))
79+
case None => returnNoBestBlock()
9080
}
9181

82+
private def returnNoTotalDifficulty(bestBlock: Block): Task[BlockImportFailed] = {
83+
log.error(
84+
"Getting total difficulty for current best block with hash: {} failed",
85+
bestBlock.header.hashAsHexString
86+
)
87+
Task.now(
88+
BlockImportFailed(
89+
s"Couldn't get total difficulty for current best block with hash: ${bestBlock.header.hashAsHexString}"
90+
)
91+
)
92+
}
93+
94+
private def returnNoBestBlock(): Task[BlockImportFailed] = {
95+
log.error("Getting current best block failed")
96+
Task.now(BlockImportFailed("Couldn't find the current best block"))
97+
}
98+
9299
private def isBlockADuplicate(block: BlockHeader, currentBestBlockNumber: BigInt): Boolean = {
93100
val hash = block.hash
94101
blockchainReader.getBlockByHash(hash).isDefined && block.number <= currentBestBlockNumber || blockQueue.isQueued(
@@ -97,7 +104,7 @@ class ConsensusImpl(
97104
}
98105

99106
private def isPossibleNewBestBlock(newBlock: BlockHeader, currentBestBlock: BlockHeader): Boolean =
100-
newBlock.parentHash == currentBestBlock.hash && newBlock.number == currentBestBlock.number + 1
107+
newBlock.number == currentBestBlock.number + 1 && newBlock.parentHash == currentBestBlock.hash
101108

102109
private def measureBlockMetrics(importResult: BlockImportResult): Unit =
103110
importResult match {
@@ -120,17 +127,23 @@ class ConsensusImpl(
120127
.evalOnce(importBlockToTop(block, currentBestBlock.header.number, currentWeight))
121128
.executeOn(blockExecutionScheduler)
122129

123-
Task.parMap2(validationResult, importResult) { case (validationResult, importResult) =>
130+
Task.map2(validationResult, importResult) { case (validationResult, importResult) =>
124131
validationResult.fold(
125132
error => {
126-
log.error("Error while validation block before execution: {}", error.reason)
133+
log.error("Error while validating block before execution: {}", error.reason)
127134
handleImportTopValidationError(error, block, importResult)
128135
},
129136
_ => importResult
130137
)
131138
}
132139
}
133140

141+
/** *
142+
* Open for discussion: this is code that was in BlockImport. Even thought is tested (before) that only one block
143+
* is being added to the blockchain, this code assumes that the import may be of more than one block (a branch)
144+
* and because it is assuming that it may be dealing with a branch the code to handle errors assumes several scenarios.
145+
* Is there is reason for this over-complication?
146+
*/
134147
private def importBlockToTop(block: Block, bestBlockNumber: BigInt, currentWeight: ChainWeight)(implicit
135148
blockchainConfig: BlockchainConfig
136149
): BlockImportResult = {
@@ -143,8 +156,7 @@ class ConsensusImpl(
143156
executionResult match {
144157
case Some((importedBlocks, maybeError, topBlocks)) =>
145158
val result = maybeError match {
146-
case None =>
147-
BlockImportedToTop(importedBlocks)
159+
case None => BlockImportedToTop(importedBlocks)
148160

149161
case Some(MPTError(reason)) if reason.isInstanceOf[MissingNodeException] =>
150162
BlockImportFailedDueToMissingNode(reason.asInstanceOf[MissingNodeException])
@@ -159,15 +171,15 @@ class ConsensusImpl(
159171
}
160172
BlockImportedToTop(importedBlocks)
161173
}
162-
log.debug(
163-
"{}", {
164-
val result = importedBlocks.map { blockData =>
165-
val header = blockData.block.header
166-
s"Imported new block (${header.number}: ${Hex.toHexString(header.hash.toArray)}) to the top of chain \n"
167-
}
168-
result.toString
169-
}
170-
)
174+
175+
importedBlocks.foreach { blockData =>
176+
val header = blockData.block.header
177+
log.debug(
178+
"Imported new block ({}: {}) to the top of chain \n",
179+
header.number,
180+
Hex.toHexString(header.hash.toArray)
181+
)
182+
}
171183

172184
result
173185

@@ -204,11 +216,11 @@ class ConsensusImpl(
204216
BlockImportFailed(reason.toString)
205217
}
206218

207-
private def reorganise(
219+
private def reorganiseOrEnqueue(
208220
block: Block,
209221
currentBestBlock: Block,
210222
currentWeight: ChainWeight
211-
)(implicit blockchainConfig: BlockchainConfig): Task[BlockImportResult] =
223+
)(implicit blockExecutionScheduler: Scheduler, blockchainConfig: BlockchainConfig): Task[BlockImportResult] =
212224
Task.evalOnce {
213225
blockValidation
214226
.validateBlockBeforeExecution(block)
@@ -217,7 +229,6 @@ class ConsensusImpl(
217229
_ =>
218230
blockQueue.enqueueBlock(block, currentBestBlock.header.number) match {
219231
case Some(Leaf(leafHash, leafWeight)) if leafWeight > currentWeight =>
220-
log.debug("Found a better chain, about to reorganise")
221232
reorganiseChainFromQueue(leafHash)
222233

223234
case _ =>
@@ -236,7 +247,7 @@ class ConsensusImpl(
236247
private def reorganiseChainFromQueue(
237248
queuedLeaf: ByteString
238249
)(implicit blockchainConfig: BlockchainConfig): BlockImportResult = {
239-
log.debug("Reorganising chain from leaf {}", ByteStringUtils.hash2string(queuedLeaf))
250+
log.info("Reorganising chain from leaf {}", ByteStringUtils.hash2string(queuedLeaf))
240251
val newBranch = blockQueue.getBranch(queuedLeaf, dequeue = true)
241252
val bestNumber = blockchainReader.getBestBlockNumber()
242253

0 commit comments

Comments
 (0)