@@ -10,6 +10,7 @@ import monix.eval.Task
10
10
import monix .execution .Scheduler
11
11
import org .bouncycastle .util .encoders .Hex
12
12
13
+ import scala .annotation .tailrec
13
14
import scala .concurrent .ExecutionContext
14
15
15
16
class BlockImport (
@@ -152,7 +153,7 @@ class BlockImport(
152
153
bestNumber,
153
154
ByteStringUtils .hash2string(parentHash)
154
155
)
155
- val oldBlocksData = removeBlocksUntil(parentHash, bestNumber).reverse
156
+ val oldBlocksData = removeBlocksUntil(parentHash, bestNumber)
156
157
oldBlocksData.foreach(block => blockQueue.enqueueBlock(block.block))
157
158
handleBlockExecResult(newBranch, parentWeight, oldBlocksData)
158
159
}
@@ -226,26 +227,31 @@ class BlockImport(
226
227
* @return the list of removed blocks along with receipts and total difficulties
227
228
*/
228
229
private def removeBlocksUntil (parent : ByteString , fromNumber : BigInt ): List [BlockData ] = {
229
- blockchain.getBlockByNumber(fromNumber) match {
230
- case Some (block) if block.header.hash == parent || fromNumber == 0 =>
231
- Nil
230
+ @ tailrec
231
+ def removeBlocksUntil (parent : ByteString , fromNumber : BigInt , acc : List [BlockData ]): List [BlockData ] = {
232
+ blockchain.getBlockByNumber(fromNumber) match {
233
+ case Some (block) if block.header.hash == parent || fromNumber == 0 =>
234
+ acc
232
235
233
- case Some (block) =>
234
- val hash = block.header.hash
236
+ case Some (block) =>
237
+ val hash = block.header.hash
235
238
236
- val blockList = for {
237
- receipts <- blockchain.getReceiptsByHash(hash)
238
- weight <- blockchain.getChainWeightByHash(hash)
239
- } yield BlockData (block, receipts, weight) :: removeBlocksUntil(parent, fromNumber - 1 )
239
+ val blockDataOpt = for {
240
+ receipts <- blockchain.getReceiptsByHash(hash)
241
+ weight <- blockchain.getChainWeightByHash(hash)
242
+ } yield BlockData (block, receipts, weight)
240
243
241
- blockchain.removeBlock(hash, withState = true )
244
+ blockchain.removeBlock(hash, withState = true )
242
245
243
- blockList. getOrElse(Nil )
246
+ removeBlocksUntil(parent, fromNumber - 1 , blockDataOpt.map(_ :: acc). getOrElse(acc) )
244
247
245
- case None =>
246
- log.error(s " Unexpected missing block number: $fromNumber" )
247
- Nil
248
+ case None =>
249
+ log.error(s " Unexpected missing block number: $fromNumber" )
250
+ acc
251
+ }
248
252
}
253
+
254
+ removeBlocksUntil(parent, fromNumber, Nil )
249
255
}
250
256
}
251
257
0 commit comments