Update fork choice import for resuming after stop (#2746)
* Update `ForkedChainRef` constructor why: Initialisation is based on the canonical head which is always zero after resuming a stopped `ForkedChainRef` based import. * Update new-base calculator why: There is some ambiguous code which might not do what the comment implies. In short, an unsigned condition like `2u - 3u < 1u => false` is coded where the comment suggests that `2 - 3 < 1 => true` is meant. This patch fixes notorious crashes when resuming import after a stop.
This commit is contained in:
parent
47337593c9
commit
7d41a992e6
|
@ -320,7 +320,7 @@ func calculateNewBase(c: ForkedChainRef,
|
||||||
max(headHeader.number, c.baseDistance) - c.baseDistance)
|
max(headHeader.number, c.baseDistance) - c.baseDistance)
|
||||||
|
|
||||||
# The distance is less than `baseDistance`, don't move the base
|
# The distance is less than `baseDistance`, don't move the base
|
||||||
if targetNumber - c.baseHeader.number <= c.baseDistance:
|
if targetNumber <= c.baseHeader.number + c.baseDistance:
|
||||||
return BaseDesc(hash: c.baseHash, header: c.baseHeader)
|
return BaseDesc(hash: c.baseHash, header: c.baseHeader)
|
||||||
|
|
||||||
shouldNotKeyError:
|
shouldNotKeyError:
|
||||||
|
@ -394,11 +394,55 @@ proc updateHeadIfNecessary(c: ForkedChainRef,
|
||||||
# Public functions
|
# Public functions
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
proc init*(
|
||||||
|
T: type ForkedChainRef;
|
||||||
|
com: CommonRef;
|
||||||
|
baseDistance = BaseDistance.uint64;
|
||||||
|
extraValidation = true;
|
||||||
|
): T =
|
||||||
|
## Constructor that uses the current database ledger state for initialising.
|
||||||
|
## This state coincides with the canonical head that would be used for
|
||||||
|
## setting up the descriptor.
|
||||||
|
##
|
||||||
|
## With `ForkedChainRef` based import, the canonical state lives only inside
|
||||||
|
## a level one database transaction. Thus it will readily be available on the
|
||||||
|
## running system with tools such as `getCanonicalHead()`. But it will never
|
||||||
|
## be saved on the database.
|
||||||
|
##
|
||||||
|
## This constructor also works well when resuming import after running
|
||||||
|
## `persistentBlocks()` used for `Era1` or `Era` import.
|
||||||
|
##
|
||||||
|
let
|
||||||
|
base = com.db.getSavedStateBlockNumber
|
||||||
|
var
|
||||||
|
baseHash: Hash32
|
||||||
|
baseHeader: Header
|
||||||
|
try:
|
||||||
|
baseHash = com.db.getBlockHash(base)
|
||||||
|
baseHeader = com.db.getBlockHeader(baseHash)
|
||||||
|
except BlockNotFound:
|
||||||
|
raiseAssert "Base header missing for #" & $base
|
||||||
|
|
||||||
|
# update global syncStart
|
||||||
|
com.syncStart = baseHeader.number
|
||||||
|
|
||||||
|
T(com: com,
|
||||||
|
db: com.db,
|
||||||
|
baseHeader: baseHeader,
|
||||||
|
cursorHash: baseHash,
|
||||||
|
baseHash: baseHash,
|
||||||
|
cursorHeader: baseHeader,
|
||||||
|
extraValidation: extraValidation,
|
||||||
|
baseDistance: baseDistance,
|
||||||
|
txRecords: initTable[Hash256, (Hash256, uint64)]())
|
||||||
|
|
||||||
proc newForkedChain*(com: CommonRef,
|
proc newForkedChain*(com: CommonRef,
|
||||||
baseHeader: Header,
|
baseHeader: Header,
|
||||||
baseDistance: uint64 = BaseDistance,
|
baseDistance: uint64 = BaseDistance,
|
||||||
extraValidation: bool = true): ForkedChainRef =
|
extraValidation: bool = true): ForkedChainRef =
|
||||||
|
## This constructor allows to set up the base state which might be needed
|
||||||
|
## for some particular test or other applications. Otherwise consider
|
||||||
|
## `init()`.
|
||||||
let baseHash = baseHeader.blockHash
|
let baseHash = baseHeader.blockHash
|
||||||
|
|
||||||
var chain = ForkedChainRef(
|
var chain = ForkedChainRef(
|
||||||
|
|
|
@ -42,9 +42,8 @@ proc basicServices(nimbus: NimbusNode,
|
||||||
# txPool must be informed of active head
|
# txPool must be informed of active head
|
||||||
# so it can know the latest account state
|
# so it can know the latest account state
|
||||||
# e.g. sender nonce, etc
|
# e.g. sender nonce, etc
|
||||||
let head = com.db.getCanonicalHead()
|
nimbus.chainRef = ForkedChainRef.init(com)
|
||||||
nimbus.chainRef = newForkedChain(com, head)
|
doAssert nimbus.txPool.smartHead(nimbus.chainRef.latestHeader,nimbus.chainRef)
|
||||||
doAssert nimbus.txPool.smartHead(head, nimbus.chainRef)
|
|
||||||
|
|
||||||
nimbus.beaconEngine = BeaconEngineRef.new(nimbus.txPool, nimbus.chainRef)
|
nimbus.beaconEngine = BeaconEngineRef.new(nimbus.txPool, nimbus.chainRef)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue