@@ -44,8 +44,9 @@ class ConsensusImpl(
44
44
45
45
/** Tries to import the block as the new best block in the chain or enqueue it for later processing.
46
46
*
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
49
50
* @return One of:
50
51
* - [[BlockImportedToTop ]] - if the block was added as the new best block
51
52
* - [[BlockEnqueued ]] - block is stored in the [[io.iohk.ethereum.ledger.BlockQueue ]]
@@ -59,36 +60,42 @@ class ConsensusImpl(
59
60
blockchainReader.getBestBlock() match {
60
61
case Some (bestBlock) =>
61
62
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 )
64
65
} else {
65
66
val hash = bestBlock.header.hash
66
67
blockchain.getChainWeightByHash(hash) match {
67
68
case Some (weight) =>
68
69
val importResult = if (isPossibleNewBestBlock(block.header, bestBlock.header)) {
69
70
importToTop(block, bestBlock, weight)
70
71
} else {
71
- reorganise (block, bestBlock, weight)
72
+ reorganiseOrEnqueue (block, bestBlock, weight)
72
73
}
73
74
importResult.foreach(measureBlockMetrics)
74
75
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)
85
77
}
86
78
}
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()
90
80
}
91
81
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
+
92
99
private def isBlockADuplicate (block : BlockHeader , currentBestBlockNumber : BigInt ): Boolean = {
93
100
val hash = block.hash
94
101
blockchainReader.getBlockByHash(hash).isDefined && block.number <= currentBestBlockNumber || blockQueue.isQueued(
@@ -97,7 +104,7 @@ class ConsensusImpl(
97
104
}
98
105
99
106
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
101
108
102
109
private def measureBlockMetrics (importResult : BlockImportResult ): Unit =
103
110
importResult match {
@@ -120,17 +127,23 @@ class ConsensusImpl(
120
127
.evalOnce(importBlockToTop(block, currentBestBlock.header.number, currentWeight))
121
128
.executeOn(blockExecutionScheduler)
122
129
123
- Task .parMap2 (validationResult, importResult) { case (validationResult, importResult) =>
130
+ Task .map2 (validationResult, importResult) { case (validationResult, importResult) =>
124
131
validationResult.fold(
125
132
error => {
126
- log.error(" Error while validation block before execution: {}" , error.reason)
133
+ log.error(" Error while validating block before execution: {}" , error.reason)
127
134
handleImportTopValidationError(error, block, importResult)
128
135
},
129
136
_ => importResult
130
137
)
131
138
}
132
139
}
133
140
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
+ */
134
147
private def importBlockToTop (block : Block , bestBlockNumber : BigInt , currentWeight : ChainWeight )(implicit
135
148
blockchainConfig : BlockchainConfig
136
149
): BlockImportResult = {
@@ -143,8 +156,7 @@ class ConsensusImpl(
143
156
executionResult match {
144
157
case Some ((importedBlocks, maybeError, topBlocks)) =>
145
158
val result = maybeError match {
146
- case None =>
147
- BlockImportedToTop (importedBlocks)
159
+ case None => BlockImportedToTop (importedBlocks)
148
160
149
161
case Some (MPTError (reason)) if reason.isInstanceOf [MissingNodeException ] =>
150
162
BlockImportFailedDueToMissingNode (reason.asInstanceOf [MissingNodeException ])
@@ -159,15 +171,15 @@ class ConsensusImpl(
159
171
}
160
172
BlockImportedToTop (importedBlocks)
161
173
}
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
+ }
171
183
172
184
result
173
185
@@ -204,11 +216,11 @@ class ConsensusImpl(
204
216
BlockImportFailed (reason.toString)
205
217
}
206
218
207
- private def reorganise (
219
+ private def reorganiseOrEnqueue (
208
220
block : Block ,
209
221
currentBestBlock : Block ,
210
222
currentWeight : ChainWeight
211
- )(implicit blockchainConfig : BlockchainConfig ): Task [BlockImportResult ] =
223
+ )(implicit blockExecutionScheduler : Scheduler , blockchainConfig : BlockchainConfig ): Task [BlockImportResult ] =
212
224
Task .evalOnce {
213
225
blockValidation
214
226
.validateBlockBeforeExecution(block)
@@ -217,7 +229,6 @@ class ConsensusImpl(
217
229
_ =>
218
230
blockQueue.enqueueBlock(block, currentBestBlock.header.number) match {
219
231
case Some (Leaf (leafHash, leafWeight)) if leafWeight > currentWeight =>
220
- log.debug(" Found a better chain, about to reorganise" )
221
232
reorganiseChainFromQueue(leafHash)
222
233
223
234
case _ =>
@@ -236,7 +247,7 @@ class ConsensusImpl(
236
247
private def reorganiseChainFromQueue (
237
248
queuedLeaf : ByteString
238
249
)(implicit blockchainConfig : BlockchainConfig ): BlockImportResult = {
239
- log.debug (" Reorganising chain from leaf {}" , ByteStringUtils .hash2string(queuedLeaf))
250
+ log.info (" Reorganising chain from leaf {}" , ByteStringUtils .hash2string(queuedLeaf))
240
251
val newBranch = blockQueue.getBranch(queuedLeaf, dequeue = true )
241
252
val bestNumber = blockchainReader.getBestBlockNumber()
242
253
0 commit comments