use epoch ref to update fork choice

this dramatically speeds up startup in long periods of non-finality
This commit is contained in:
Jacek Sieka 2020-08-03 20:39:43 +02:00 committed by zah
parent a5d900d052
commit c6674de5d2
8 changed files with 53 additions and 41 deletions

View File

@ -44,20 +44,16 @@ proc init*(T: type AttestationPool, chainDag: ChainDAGRef, quarantine: Quarantin
blocks.add cur
cur = cur.parent
debug "Preloading fork choice with blocks", blocks = blocks.len
for blck in reversed(blocks):
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 =
let
epochRef = chainDag.getEpochRef(blck, blck.slot.compute_epoch_at_slot)
status =
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
info "Fork choice initialized",
justified_epoch = chainDag.headState.data.data.current_justified_checkpoint.epoch,
@ -208,13 +204,13 @@ proc addAttestation*(pool: var AttestationPool,
pool.addResolved(blck, attestation, wallSlot)
proc addForkChoice*(pool: var AttestationPool,
state: BeaconState,
epochRef: EpochRef,
blckRef: BlockRef,
blck: BeaconBlock,
wallSlot: Slot) =
## Add a verified block to the fork choice context
let state = pool.forkChoice.process_block(
pool.chainDag, state, blckRef, blck, wallSlot)
pool.chainDag, epochRef, blckRef, blck, wallSlot)
if state.isErr:
# TODO If this happens, it is effectively a bug - the BlockRef structure

View File

@ -344,8 +344,9 @@ proc storeBlock(
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# Callback add to fork choice if valid
let epochRef = getEpochInfo(blckRef, state.data)
node.attestationPool.addForkChoice(
state.data, blckRef, signedBlock.message,
epochRef, blckRef, signedBlock.message,
node.beaconClock.now().slotOrZero())
node.dumpBlock(signedBlock, blck)

View File

@ -137,8 +137,10 @@ type
runtimePreset*: RuntimePreset
EpochRef* = ref object
shuffled_active_validator_indices*: seq[ValidatorIndex]
epoch*: Epoch
current_justified_checkpoint*: Checkpoint
finalized_checkpoint*: Checkpoint
shuffled_active_validator_indices*: seq[ValidatorIndex]
BlockRef* = ref object
## Node in object graph guaranteed to lead back to tail block, and to have

View File

@ -66,6 +66,8 @@ func init*(T: type EpochRef, state: BeaconState): T =
let epoch = state.get_current_epoch()
EpochRef(
epoch: epoch,
current_justified_checkpoint: state.current_justified_checkpoint,
finalized_checkpoint: state.finalized_checkpoint,
shuffled_active_validator_indices:
get_shuffled_active_validator_indices(state, epoch))

View File

@ -166,36 +166,36 @@ proc get_balances_for_block(self: var Checkpoints, blck: BlockSlot, dag: ChainDA
proc process_state(self: var Checkpoints,
dag: ChainDAGRef,
state: BeaconState,
epochRef: EpochRef,
blck: BlockRef) =
trace "Processing state",
state_slot = state.slot,
state_justified = state.current_justified_checkpoint.epoch,
trace "Processing epoch",
epoch = epochRef.epoch,
state_justified = epochRef.current_justified_checkpoint.epoch,
current_justified = self.current.justified.epoch,
state_finalized = state.finalized_checkpoint.epoch,
state_finalized = epochRef.finalized_checkpoint.epoch,
current_finalized = self.current.finalized
if (state.current_justified_checkpoint.epoch > self.current.justified.epoch) and
(state.finalized_checkpoint.epoch >= self.current.finalized.epoch):
if (epochRef.current_justified_checkpoint.epoch > self.current.justified.epoch) and
(epochRef.finalized_checkpoint.epoch >= self.current.finalized.epoch):
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(
justified: BalanceCheckpoint(
blck: justifiedBlck.blck,
epoch: state.current_justified_checkpoint.epoch,
epoch: epochRef.current_justified_checkpoint.epoch,
balances: self.get_balances_for_block(justifiedBlck, dag),
),
finalized: state.finalized_checkpoint,
finalized: epochRef.finalized_checkpoint,
)
trace "Applying candidate",
justified_block = shortLog(candidate.justified.blck),
justified_epoch = shortLog(candidate.justified.epoch),
finalized = candidate.finalized,
state_finalized = state.finalized_checkpoint.epoch
state_finalized = epochRef.finalized_checkpoint.epoch
if self.current.justified.blck.isAncestorOf(justifiedBlck.blck):
trace "Updating current",
@ -249,11 +249,11 @@ proc process_block*(self: var ForkChoiceBackend,
proc process_block*(self: var ForkChoice,
dag: ChainDAGRef,
state: BeaconState,
epochRef: EpochRef,
blckRef: BlockRef,
blck: SomeBeaconBlock,
wallSlot: Slot): FcResult[void] =
process_state(self.checkpoints, dag, state, blckRef)
process_state(self.checkpoints, dag, epochRef, blckRef)
maybe_update(self.checkpoints, wallSlot)
@ -276,7 +276,7 @@ proc process_block*(self: var ForkChoice,
? process_block(
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",

View File

@ -221,8 +221,9 @@ proc proposeSignedBlock*(node: BeaconNode,
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# Callback add to fork choice if valid
let epochRef = getEpochInfo(blckRef, state.data)
node.attestationPool.addForkChoice(
state.data, blckRef, signedBlock.message,
epochRef, blckRef, signedBlock.message,
node.beaconClock.now().slotOrZero())
if newBlockRef.isErr:

View File

@ -142,7 +142,8 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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[]
chainDag.updateHead(added[])

View File

@ -168,7 +168,8 @@ suiteReport "Attestation pool processing" & preset():
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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)
@ -181,7 +182,8 @@ suiteReport "Attestation pool processing" & preset():
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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)
@ -196,7 +198,8 @@ suiteReport "Attestation pool processing" & preset():
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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)
@ -211,7 +214,8 @@ suiteReport "Attestation pool processing" & preset():
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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(
state.data.data, state.data.data.slot, 1.CommitteeIndex, cache)
@ -253,7 +257,8 @@ suiteReport "Attestation pool processing" & preset():
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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)
@ -267,7 +272,8 @@ suiteReport "Attestation pool processing" & preset():
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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
@ -281,7 +287,8 @@ suiteReport "Attestation pool processing" & preset():
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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)
@ -315,7 +322,8 @@ suiteReport "Attestation pool processing" & preset():
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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)
doassert: head == blockRef[]
@ -356,6 +364,7 @@ suiteReport "Attestation pool processing" & preset():
blckRef: BlockRef, signedBlock: SignedBeaconBlock,
state: HashedBeaconState):
# 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