diff --git a/beacon_chain/attestation_pool.nim b/beacon_chain/attestation_pool.nim index 81ecfbeee..1035c64bc 100644 --- a/beacon_chain/attestation_pool.nim +++ b/beacon_chain/attestation_pool.nim @@ -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 diff --git a/beacon_chain/beacon_node.nim b/beacon_chain/beacon_node.nim index 7d70456e9..1ad4bd8a8 100644 --- a/beacon_chain/beacon_node.nim +++ b/beacon_chain/beacon_node.nim @@ -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) diff --git a/beacon_chain/block_pools/block_pools_types.nim b/beacon_chain/block_pools/block_pools_types.nim index 0f470d780..ac8044565 100644 --- a/beacon_chain/block_pools/block_pools_types.nim +++ b/beacon_chain/block_pools/block_pools_types.nim @@ -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 diff --git a/beacon_chain/block_pools/chain_dag.nim b/beacon_chain/block_pools/chain_dag.nim index f99fe2dea..12432ec79 100644 --- a/beacon_chain/block_pools/chain_dag.nim +++ b/beacon_chain/block_pools/chain_dag.nim @@ -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)) diff --git a/beacon_chain/fork_choice/fork_choice.nim b/beacon_chain/fork_choice/fork_choice.nim index ebf69de2a..388bc6903 100644 --- a/beacon_chain/fork_choice/fork_choice.nim +++ b/beacon_chain/fork_choice/fork_choice.nim @@ -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", diff --git a/beacon_chain/validator_duties.nim b/beacon_chain/validator_duties.nim index 56a25703e..ec0d6149a 100644 --- a/beacon_chain/validator_duties.nim +++ b/beacon_chain/validator_duties.nim @@ -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: diff --git a/research/block_sim.nim b/research/block_sim.nim index 209df942d..767bab70c 100644 --- a/research/block_sim.nim +++ b/research/block_sim.nim @@ -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[]) diff --git a/tests/test_attestation_pool.nim b/tests/test_attestation_pool.nim index 0dcabe786..080fd0fcc 100644 --- a/tests/test_attestation_pool.nim +++ b/tests/test_attestation_pool.nim @@ -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