mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-01-11 14:54:12 +00:00
use epoch ref to update fork choice
this dramatically speeds up startup in long periods of non-finality
This commit is contained in:
parent
a5d900d052
commit
c6674de5d2
@ -44,18 +44,14 @@ proc init*(T: type AttestationPool, chainDag: ChainDAGRef, quarantine: Quarantin
|
|||||||
blocks.add cur
|
blocks.add cur
|
||||||
cur = cur.parent
|
cur = cur.parent
|
||||||
|
|
||||||
for blck in reversed(blocks):
|
debug "Preloading fork choice with blocks", blocks = blocks.len
|
||||||
chainDag.withState(chainDag.tmpState, blck.atSlot(blck.slot)):
|
|
||||||
debug "Preloading fork choice with block",
|
|
||||||
block_root = shortlog(blck.root),
|
|
||||||
parent_root = shortlog(blck.parent.root),
|
|
||||||
justified_epoch = state.current_justified_checkpoint.epoch,
|
|
||||||
finalized_epoch = state.finalized_checkpoint.epoch,
|
|
||||||
slot = blck.slot
|
|
||||||
|
|
||||||
let status =
|
for blck in reversed(blocks):
|
||||||
|
let
|
||||||
|
epochRef = chainDag.getEpochRef(blck, blck.slot.compute_epoch_at_slot)
|
||||||
|
status =
|
||||||
forkChoice.process_block(
|
forkChoice.process_block(
|
||||||
chainDag, state, blck, chainDag.get(blck).data.message, blck.slot)
|
chainDag, epochRef, blck, chainDag.get(blck).data.message, blck.slot)
|
||||||
|
|
||||||
doAssert status.isOk(), "Error in preloading the fork choice: " & $status.error
|
doAssert status.isOk(), "Error in preloading the fork choice: " & $status.error
|
||||||
|
|
||||||
@ -208,13 +204,13 @@ proc addAttestation*(pool: var AttestationPool,
|
|||||||
pool.addResolved(blck, attestation, wallSlot)
|
pool.addResolved(blck, attestation, wallSlot)
|
||||||
|
|
||||||
proc addForkChoice*(pool: var AttestationPool,
|
proc addForkChoice*(pool: var AttestationPool,
|
||||||
state: BeaconState,
|
epochRef: EpochRef,
|
||||||
blckRef: BlockRef,
|
blckRef: BlockRef,
|
||||||
blck: BeaconBlock,
|
blck: BeaconBlock,
|
||||||
wallSlot: Slot) =
|
wallSlot: Slot) =
|
||||||
## Add a verified block to the fork choice context
|
## Add a verified block to the fork choice context
|
||||||
let state = pool.forkChoice.process_block(
|
let state = pool.forkChoice.process_block(
|
||||||
pool.chainDag, state, blckRef, blck, wallSlot)
|
pool.chainDag, epochRef, blckRef, blck, wallSlot)
|
||||||
|
|
||||||
if state.isErr:
|
if state.isErr:
|
||||||
# TODO If this happens, it is effectively a bug - the BlockRef structure
|
# TODO If this happens, it is effectively a bug - the BlockRef structure
|
||||||
|
@ -344,8 +344,9 @@ proc storeBlock(
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
node.attestationPool.addForkChoice(
|
node.attestationPool.addForkChoice(
|
||||||
state.data, blckRef, signedBlock.message,
|
epochRef, blckRef, signedBlock.message,
|
||||||
node.beaconClock.now().slotOrZero())
|
node.beaconClock.now().slotOrZero())
|
||||||
|
|
||||||
node.dumpBlock(signedBlock, blck)
|
node.dumpBlock(signedBlock, blck)
|
||||||
|
@ -137,8 +137,10 @@ type
|
|||||||
runtimePreset*: RuntimePreset
|
runtimePreset*: RuntimePreset
|
||||||
|
|
||||||
EpochRef* = ref object
|
EpochRef* = ref object
|
||||||
shuffled_active_validator_indices*: seq[ValidatorIndex]
|
|
||||||
epoch*: Epoch
|
epoch*: Epoch
|
||||||
|
current_justified_checkpoint*: Checkpoint
|
||||||
|
finalized_checkpoint*: Checkpoint
|
||||||
|
shuffled_active_validator_indices*: seq[ValidatorIndex]
|
||||||
|
|
||||||
BlockRef* = ref object
|
BlockRef* = ref object
|
||||||
## Node in object graph guaranteed to lead back to tail block, and to have
|
## Node in object graph guaranteed to lead back to tail block, and to have
|
||||||
|
@ -66,6 +66,8 @@ func init*(T: type EpochRef, state: BeaconState): T =
|
|||||||
let epoch = state.get_current_epoch()
|
let epoch = state.get_current_epoch()
|
||||||
EpochRef(
|
EpochRef(
|
||||||
epoch: epoch,
|
epoch: epoch,
|
||||||
|
current_justified_checkpoint: state.current_justified_checkpoint,
|
||||||
|
finalized_checkpoint: state.finalized_checkpoint,
|
||||||
shuffled_active_validator_indices:
|
shuffled_active_validator_indices:
|
||||||
get_shuffled_active_validator_indices(state, epoch))
|
get_shuffled_active_validator_indices(state, epoch))
|
||||||
|
|
||||||
|
@ -166,36 +166,36 @@ proc get_balances_for_block(self: var Checkpoints, blck: BlockSlot, dag: ChainDA
|
|||||||
|
|
||||||
proc process_state(self: var Checkpoints,
|
proc process_state(self: var Checkpoints,
|
||||||
dag: ChainDAGRef,
|
dag: ChainDAGRef,
|
||||||
state: BeaconState,
|
epochRef: EpochRef,
|
||||||
blck: BlockRef) =
|
blck: BlockRef) =
|
||||||
trace "Processing state",
|
trace "Processing epoch",
|
||||||
state_slot = state.slot,
|
epoch = epochRef.epoch,
|
||||||
state_justified = state.current_justified_checkpoint.epoch,
|
state_justified = epochRef.current_justified_checkpoint.epoch,
|
||||||
current_justified = self.current.justified.epoch,
|
current_justified = self.current.justified.epoch,
|
||||||
state_finalized = state.finalized_checkpoint.epoch,
|
state_finalized = epochRef.finalized_checkpoint.epoch,
|
||||||
current_finalized = self.current.finalized
|
current_finalized = self.current.finalized
|
||||||
|
|
||||||
if (state.current_justified_checkpoint.epoch > self.current.justified.epoch) and
|
if (epochRef.current_justified_checkpoint.epoch > self.current.justified.epoch) and
|
||||||
(state.finalized_checkpoint.epoch >= self.current.finalized.epoch):
|
(epochRef.finalized_checkpoint.epoch >= self.current.finalized.epoch):
|
||||||
let justifiedBlck = blck.atEpochStart(
|
let justifiedBlck = blck.atEpochStart(
|
||||||
state.current_justified_checkpoint.epoch)
|
epochRef.current_justified_checkpoint.epoch)
|
||||||
|
|
||||||
doAssert justifiedBlck.blck.root == state.current_justified_checkpoint.root
|
doAssert justifiedBlck.blck.root == epochRef.current_justified_checkpoint.root
|
||||||
|
|
||||||
let candidate = FFGCheckpoints(
|
let candidate = FFGCheckpoints(
|
||||||
justified: BalanceCheckpoint(
|
justified: BalanceCheckpoint(
|
||||||
blck: justifiedBlck.blck,
|
blck: justifiedBlck.blck,
|
||||||
epoch: state.current_justified_checkpoint.epoch,
|
epoch: epochRef.current_justified_checkpoint.epoch,
|
||||||
balances: self.get_balances_for_block(justifiedBlck, dag),
|
balances: self.get_balances_for_block(justifiedBlck, dag),
|
||||||
),
|
),
|
||||||
finalized: state.finalized_checkpoint,
|
finalized: epochRef.finalized_checkpoint,
|
||||||
)
|
)
|
||||||
|
|
||||||
trace "Applying candidate",
|
trace "Applying candidate",
|
||||||
justified_block = shortLog(candidate.justified.blck),
|
justified_block = shortLog(candidate.justified.blck),
|
||||||
justified_epoch = shortLog(candidate.justified.epoch),
|
justified_epoch = shortLog(candidate.justified.epoch),
|
||||||
finalized = candidate.finalized,
|
finalized = candidate.finalized,
|
||||||
state_finalized = state.finalized_checkpoint.epoch
|
state_finalized = epochRef.finalized_checkpoint.epoch
|
||||||
|
|
||||||
if self.current.justified.blck.isAncestorOf(justifiedBlck.blck):
|
if self.current.justified.blck.isAncestorOf(justifiedBlck.blck):
|
||||||
trace "Updating current",
|
trace "Updating current",
|
||||||
@ -249,11 +249,11 @@ proc process_block*(self: var ForkChoiceBackend,
|
|||||||
|
|
||||||
proc process_block*(self: var ForkChoice,
|
proc process_block*(self: var ForkChoice,
|
||||||
dag: ChainDAGRef,
|
dag: ChainDAGRef,
|
||||||
state: BeaconState,
|
epochRef: EpochRef,
|
||||||
blckRef: BlockRef,
|
blckRef: BlockRef,
|
||||||
blck: SomeBeaconBlock,
|
blck: SomeBeaconBlock,
|
||||||
wallSlot: Slot): FcResult[void] =
|
wallSlot: Slot): FcResult[void] =
|
||||||
process_state(self.checkpoints, dag, state, blckRef)
|
process_state(self.checkpoints, dag, epochRef, blckRef)
|
||||||
|
|
||||||
maybe_update(self.checkpoints, wallSlot)
|
maybe_update(self.checkpoints, wallSlot)
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ proc process_block*(self: var ForkChoice,
|
|||||||
|
|
||||||
? process_block(
|
? process_block(
|
||||||
self.backend, blckRef.root, blck.parent_root,
|
self.backend, blckRef.root, blck.parent_root,
|
||||||
state.current_justified_checkpoint.epoch, state.finalized_checkpoint.epoch
|
epochRef.current_justified_checkpoint.epoch, epochRef.finalized_checkpoint.epoch
|
||||||
)
|
)
|
||||||
|
|
||||||
trace "Integrating block in fork choice",
|
trace "Integrating block in fork choice",
|
||||||
|
@ -221,8 +221,9 @@ proc proposeSignedBlock*(node: BeaconNode,
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
node.attestationPool.addForkChoice(
|
node.attestationPool.addForkChoice(
|
||||||
state.data, blckRef, signedBlock.message,
|
epochRef, blckRef, signedBlock.message,
|
||||||
node.beaconClock.now().slotOrZero())
|
node.beaconClock.now().slotOrZero())
|
||||||
|
|
||||||
if newBlockRef.isErr:
|
if newBlockRef.isErr:
|
||||||
|
@ -142,7 +142,8 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
attPool.addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
attPool.addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
blck() = added[]
|
blck() = added[]
|
||||||
chainDag.updateHead(added[])
|
chainDag.updateHead(added[])
|
||||||
|
@ -168,7 +168,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
pool[].addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
let head = pool[].selectHead(b1Add[].slot)
|
let head = pool[].selectHead(b1Add[].slot)
|
||||||
|
|
||||||
@ -181,7 +182,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
pool[].addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
let head2 = pool[].selectHead(b2Add[].slot)
|
let head2 = pool[].selectHead(b2Add[].slot)
|
||||||
|
|
||||||
@ -196,7 +198,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
pool[].addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
let head = pool[].selectHead(b10Add[].slot)
|
let head = pool[].selectHead(b10Add[].slot)
|
||||||
|
|
||||||
@ -211,7 +214,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
pool[].addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
bc1 = get_beacon_committee(
|
bc1 = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot, 1.CommitteeIndex, cache)
|
state.data.data, state.data.data.slot, 1.CommitteeIndex, cache)
|
||||||
@ -253,7 +257,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
pool[].addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
let head = pool[].selectHead(b10Add[].slot)
|
let head = pool[].selectHead(b10Add[].slot)
|
||||||
|
|
||||||
@ -267,7 +272,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
pool[].addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
doAssert: b10Add_clone.error == Duplicate
|
doAssert: b10Add_clone.error == Duplicate
|
||||||
|
|
||||||
@ -281,7 +287,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
pool[].addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
let head = pool[].selectHead(b10Add[].slot)
|
let head = pool[].selectHead(b10Add[].slot)
|
||||||
|
|
||||||
@ -315,7 +322,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
pool[].addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
let head = pool[].selectHead(blockRef[].slot)
|
let head = pool[].selectHead(blockRef[].slot)
|
||||||
doassert: head == blockRef[]
|
doassert: head == blockRef[]
|
||||||
@ -356,6 +364,7 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
|
||||||
state: HashedBeaconState):
|
state: HashedBeaconState):
|
||||||
# Callback add to fork choice if valid
|
# Callback add to fork choice if valid
|
||||||
pool[].addForkChoice(state.data, blckRef, signedBlock.message, blckRef.slot)
|
let epochRef = getEpochInfo(blckRef, state.data)
|
||||||
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
doAssert: b10Add_clone.error == Duplicate
|
doAssert: b10Add_clone.error == Duplicate
|
||||||
|
Loading…
x
Reference in New Issue
Block a user