compute correct withdrawals for lookahead proposal fcUs at epoch boundaries (#4820)
This commit is contained in:
parent
ae45e11f8e
commit
f6062a2be1
|
@ -310,27 +310,39 @@ proc runProposalForkchoiceUpdated*(
|
||||||
debug "runProposalForkchoiceUpdated: expected to be proposing next slot",
|
debug "runProposalForkchoiceUpdated: expected to be proposing next slot",
|
||||||
nextWallSlot, validatorIndex, nextProposer
|
nextWallSlot, validatorIndex, nextProposer
|
||||||
|
|
||||||
withState(self.dag.headState):
|
|
||||||
let
|
|
||||||
nextSlotFork = self.dag.cfg.forkAtEpoch(nextWallSlot.epoch)
|
|
||||||
nextSlotForkVersion = self.dag.cfg.forkVersionAtEpoch(nextWallSlot.epoch)
|
|
||||||
if nextSlotForkVersion == self.dag.cfg.CAPELLA_FORK_VERSION and
|
|
||||||
forkyState.data.fork.current_version != nextSlotFork.current_version:
|
|
||||||
debug "runProposalForkchoiceUpdated: about to do Capella transition; don't have appropriate state to fcU ahead",
|
|
||||||
nextWallSlot, validatorIndex, nextProposer, nextSlotFork,
|
|
||||||
nextSlotForkVersion, stateFork = forkyState.data.fork
|
|
||||||
|
|
||||||
# Approximately lines up with validator_duties version. Used optimistically/
|
# Approximately lines up with validator_duties version. Used optimistically/
|
||||||
# opportunistically, so mismatches are fine if not too frequent.
|
# opportunistically, so mismatches are fine if not too frequent.
|
||||||
let
|
let
|
||||||
timestamp = withState(self.dag.headState):
|
timestamp = withState(self.dag.headState):
|
||||||
compute_timestamp_at_slot(forkyState.data, nextWallSlot)
|
compute_timestamp_at_slot(forkyState.data, nextWallSlot)
|
||||||
|
# If the current head block still forms the basis of the eventual proposal
|
||||||
|
# state, then its `get_randao_mix` will remain unchanged as well, as it is
|
||||||
|
# constant until the next block.
|
||||||
randomData = withState(self.dag.headState):
|
randomData = withState(self.dag.headState):
|
||||||
get_randao_mix(forkyState.data, get_current_epoch(forkyState.data)).data
|
get_randao_mix(forkyState.data, get_current_epoch(forkyState.data)).data
|
||||||
feeRecipient = self[].getFeeRecipient(
|
feeRecipient = self[].getFeeRecipient(
|
||||||
nextProposer, Opt.some(validatorIndex), nextWallSlot.epoch)
|
nextProposer, Opt.some(validatorIndex), nextWallSlot.epoch)
|
||||||
withdrawals = withState(self.dag.headState):
|
withdrawals = withState(self.dag.headState):
|
||||||
when consensusFork >= ConsensusFork.Capella:
|
when consensusFork >= ConsensusFork.Capella:
|
||||||
|
# Within an epoch, so long as there's no block, the withdrawals also
|
||||||
|
# remain unchanged. Balances change at epoch boundaries, however, so
|
||||||
|
# if and only if the proposal slot is the first slot of an epoch the
|
||||||
|
# beacon node must transition epochs to compute correct balances.
|
||||||
|
if nextWallSlot.is_epoch:
|
||||||
|
var cache: StateCache
|
||||||
|
let proposalState = self.dag.getProposalState(
|
||||||
|
self.dag.head, nextWallSlot, cache).valueOr:
|
||||||
|
warn "Failed to create proposal state for withdrawals",
|
||||||
|
err = error, nextWallSlot, validatorIndex, nextProposer
|
||||||
|
return
|
||||||
|
withState(proposalState[]):
|
||||||
|
when consensusFork >= ConsensusFork.Capella:
|
||||||
|
Opt.some get_expected_withdrawals(forkyState.data)
|
||||||
|
else:
|
||||||
|
Opt.none(seq[Withdrawal])
|
||||||
|
else:
|
||||||
|
# Head state is not eventual proposal state, but withdrawals will be
|
||||||
|
# identical.
|
||||||
Opt.some get_expected_withdrawals(forkyState.data)
|
Opt.some get_expected_withdrawals(forkyState.data)
|
||||||
else:
|
else:
|
||||||
Opt.none(seq[Withdrawal])
|
Opt.none(seq[Withdrawal])
|
||||||
|
|
Loading…
Reference in New Issue