use epochcache for attesting (#1478)
This commit is contained in:
parent
280e72f3c9
commit
2a36949913
|
@ -12,7 +12,7 @@ import
|
|||
beaconstate, crypto, datatypes, digest, helpers, presets, signatures,
|
||||
validator],
|
||||
../extras,
|
||||
./block_pools_types
|
||||
./block_pools_types, ./chain_dag
|
||||
|
||||
# Spec functions implemented based on cached values instead of the full state
|
||||
func count_active_validators*(epochInfo: EpochRef): uint64 =
|
||||
|
@ -122,3 +122,31 @@ proc is_valid_indexed_attestation*(
|
|||
return false
|
||||
|
||||
true
|
||||
|
||||
func makeAttestationData*(
|
||||
epochRef: EpochRef, bs: BlockSlot,
|
||||
committee_index: uint64): AttestationData =
|
||||
## Create an attestation / vote for the block `bs` using the
|
||||
## data in `epochRef` to fill in the rest of the fields.
|
||||
## `epochRef` is the epoch information corresponding to the `bs` advanced to
|
||||
## the slot we're attesting to.
|
||||
|
||||
let
|
||||
slot = bs.slot
|
||||
current_epoch = slot.compute_epoch_at_slot()
|
||||
epoch_boundary_slot = compute_start_slot_at_epoch(current_epoch)
|
||||
epoch_boundary_block = bs.blck.atSlot(epoch_boundary_slot)
|
||||
|
||||
doAssert current_epoch == epochRef.epoch
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/validator.md#attestation-data
|
||||
AttestationData(
|
||||
slot: slot,
|
||||
index: committee_index,
|
||||
beacon_block_root: bs.blck.root,
|
||||
source: epochRef.current_justified_checkpoint,
|
||||
target: Checkpoint(
|
||||
epoch: current_epoch,
|
||||
root: epoch_boundary_block.blck.root
|
||||
)
|
||||
)
|
||||
|
|
|
@ -18,7 +18,7 @@ import
|
|||
eth/[keys, async_utils], eth/p2p/discoveryv5/[protocol, enr],
|
||||
|
||||
# Local modules
|
||||
spec/[datatypes, digest, crypto, beaconstate, helpers, validator, network],
|
||||
spec/[datatypes, digest, crypto, helpers, validator, network],
|
||||
spec/state_transition,
|
||||
conf, time, validator_pool,
|
||||
attestation_pool, block_pools/[spec_cache, chain_dag, clearance],
|
||||
|
@ -60,11 +60,29 @@ proc addLocalValidators*(node: BeaconNode) =
|
|||
|
||||
info "Local validators attached ", count = node.attachedValidators.count
|
||||
|
||||
proc getAttachedValidator*(node: BeaconNode,
|
||||
pubkey: ValidatorPubKey): AttachedValidator =
|
||||
node.attachedValidators.getValidator(pubkey)
|
||||
|
||||
proc getAttachedValidator*(node: BeaconNode,
|
||||
state: BeaconState,
|
||||
idx: ValidatorIndex): AttachedValidator =
|
||||
let validatorKey = state.validators[idx].pubkey.initPubKey
|
||||
node.attachedValidators.getValidator(validatorKey)
|
||||
if idx < state.validators.len.ValidatorIndex:
|
||||
node.getAttachedValidator(state.validators[idx].pubkey)
|
||||
else:
|
||||
warn "Validator index out of bounds",
|
||||
idx, stateSlot = state.slot, validators = state.validators.len
|
||||
nil
|
||||
|
||||
proc getAttachedValidator*(node: BeaconNode,
|
||||
epochRef: EpochRef,
|
||||
idx: ValidatorIndex): AttachedValidator =
|
||||
if idx < epochRef.validator_keys.len.ValidatorIndex:
|
||||
node.getAttachedValidator(epochRef.validator_keys[idx])
|
||||
else:
|
||||
warn "Validator index out of bounds",
|
||||
idx, epoch = epochRef.epoch, validators = epochRef.validator_keys.len
|
||||
nil
|
||||
|
||||
proc isSynced*(node: BeaconNode, head: BlockRef): bool =
|
||||
## TODO This function is here as a placeholder for some better heurestics to
|
||||
|
@ -318,31 +336,29 @@ proc handleAttestations(node: BeaconNode, head: BlockRef, slot: Slot) =
|
|||
# In case blocks went missing, this means advancing past the latest block
|
||||
# using empty slots as fillers.
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/validator.md#validator-assignments
|
||||
# TODO we could cache the validator assignment since it's valid for the entire
|
||||
# epoch since it doesn't change, but that has to be weighed against
|
||||
# the complexity of handling forks correctly - instead, we use an adapted
|
||||
# version here that calculates the committee for a single slot only
|
||||
node.chainDag.withState(node.chainDag.tmpState, attestationHead):
|
||||
var cache = getEpochCache(attestationHead.blck, state)
|
||||
let
|
||||
epochRef = node.chainDag.getEpochRef(
|
||||
attestationHead.blck, slot.compute_epoch_at_slot())
|
||||
committees_per_slot =
|
||||
get_committee_count_per_slot(state, slot.epoch, cache)
|
||||
num_active_validators =
|
||||
count_active_validators(state, slot.compute_epoch_at_slot, cache)
|
||||
get_committee_count_per_slot(epochRef)
|
||||
num_active_validators = count_active_validators(epochRef)
|
||||
fork = node.chainDag.headState.data.data.fork
|
||||
genesis_validators_root =
|
||||
node.chainDag.headState.data.data.genesis_validators_root
|
||||
|
||||
for committee_index in 0'u64..<committees_per_slot:
|
||||
let committee = get_beacon_committee(
|
||||
state, slot, committee_index.CommitteeIndex, cache)
|
||||
epochRef, slot, committee_index.CommitteeIndex)
|
||||
|
||||
for index_in_committee, validatorIdx in committee:
|
||||
let validator = node.getAttachedValidator(state, validatorIdx)
|
||||
let validator = node.getAttachedValidator(epochRef, validatorIdx)
|
||||
if validator != nil:
|
||||
let ad = makeAttestationData(state, slot, committee_index, blck.root)
|
||||
let ad = makeAttestationData(epochRef, attestationHead, committee_index)
|
||||
attestations.add((ad, committee.len, index_in_committee, validator))
|
||||
|
||||
for a in attestations:
|
||||
traceAsyncErrors createAndSendAttestation(
|
||||
node, state.fork, state.genesis_validators_root, a.validator, a.data,
|
||||
node, fork, genesis_validators_root, a.validator, a.data,
|
||||
a.committeeLen, a.indexInCommittee, num_active_validators)
|
||||
|
||||
proc handleProposal(node: BeaconNode, head: BlockRef, slot: Slot):
|
||||
|
@ -359,7 +375,7 @@ proc handleProposal(node: BeaconNode, head: BlockRef, slot: Slot):
|
|||
return head
|
||||
|
||||
let validator =
|
||||
node.attachedValidators.getValidator(proposer.get()[1].initPubKey())
|
||||
node.attachedValidators.getValidator(proposer.get()[1])
|
||||
|
||||
if validator != nil:
|
||||
return await proposeBlock(node, validator, proposer.get()[0], head, slot)
|
||||
|
|
|
@ -20,9 +20,9 @@ proc addLocalValidator*(pool: var ValidatorPool,
|
|||
|
||||
info "Local validator attached", pubKey, validator = shortLog(v)
|
||||
|
||||
func getValidator*(pool: ValidatorPool,
|
||||
proc getValidator*(pool: ValidatorPool,
|
||||
validatorKey: ValidatorPubKey): AttachedValidator =
|
||||
pool.validators.getOrDefault(validatorKey)
|
||||
pool.validators.getOrDefault(validatorKey.initPubKey)
|
||||
|
||||
# TODO: Honest validator - https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/validator.md
|
||||
proc signBlockProposal*(v: AttachedValidator, fork: Fork,
|
||||
|
|
Loading…
Reference in New Issue