2021-03-18 15:05:15 +00:00
|
|
|
# Nimbus
|
|
|
|
# Copyright (c) 2021 Status Research & Development GmbH
|
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
|
|
# at your option.
|
|
|
|
# This file may not be copied, modified, or distributed except according to
|
|
|
|
# those terms.
|
|
|
|
|
|
|
|
import
|
2021-08-11 19:37:00 +00:00
|
|
|
chronicles, eth/[common, rlp], stew/io2,
|
2021-09-11 14:58:01 +00:00
|
|
|
./p2p/chain, ./db/[db_chain, select_backend]
|
2021-03-18 15:05:15 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
# trick the rlp decoder
|
|
|
|
# so we can separate the body and header
|
|
|
|
EthHeader = object
|
|
|
|
header: BlockHeader
|
|
|
|
|
2022-04-20 07:57:50 +00:00
|
|
|
proc importRlpBlock*(blocksRlp: openArray[byte]; chainDB: BaseChainDB; importFile: string = ""): bool =
|
2021-06-24 15:29:21 +00:00
|
|
|
var
|
|
|
|
# the encoded rlp can contains one or more blocks
|
2022-04-20 07:57:50 +00:00
|
|
|
rlp = rlpFromBytes(blocksRlp)
|
2021-06-24 15:29:21 +00:00
|
|
|
chain = newChain(chainDB, extraValidation = true)
|
|
|
|
errorCount = 0
|
|
|
|
let
|
|
|
|
head = chainDB.getCanonicalHead()
|
2021-03-18 15:05:15 +00:00
|
|
|
|
2021-06-24 15:29:21 +00:00
|
|
|
while rlp.hasData:
|
|
|
|
try:
|
|
|
|
let
|
|
|
|
header = rlp.read(EthHeader).header
|
|
|
|
body = rlp.readRecordType(BlockBody, false)
|
2021-05-17 11:43:44 +00:00
|
|
|
if header.blockNumber > head.blockNumber:
|
2021-06-24 15:29:21 +00:00
|
|
|
if chain.persistBlocks([header], [body]) == ValidationResult.Error:
|
|
|
|
# register one more error and continue
|
|
|
|
errorCount.inc
|
|
|
|
except RlpError as e:
|
|
|
|
# terminate if there was a decoding error
|
|
|
|
error "rlp error",
|
|
|
|
fileName = importFile,
|
|
|
|
msg = e.msg,
|
|
|
|
exception = e.name
|
|
|
|
return false
|
|
|
|
except CatchableError as e:
|
|
|
|
# otherwise continue
|
|
|
|
error "import error",
|
|
|
|
fileName = importFile,
|
|
|
|
msg = e.msg,
|
|
|
|
exception = e.name
|
|
|
|
errorCount.inc
|
2021-03-18 15:05:15 +00:00
|
|
|
|
2021-06-24 15:29:21 +00:00
|
|
|
return errorCount == 0
|
2022-04-20 07:57:50 +00:00
|
|
|
|
|
|
|
proc importRlpBlock*(importFile: string; chainDB: BaseChainDB): bool =
|
|
|
|
let res = io2.readAllBytes(importFile)
|
|
|
|
if res.isErr:
|
|
|
|
error "failed to import",
|
|
|
|
fileName = importFile
|
|
|
|
return false
|
|
|
|
|
|
|
|
importRlpBlock(res.get, chainDB, importFile)
|
|
|
|
|