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,
|
beaconstate, crypto, datatypes, digest, helpers, presets, signatures,
|
||||||
validator],
|
validator],
|
||||||
../extras,
|
../extras,
|
||||||
./block_pools_types
|
./block_pools_types, ./chain_dag
|
||||||
|
|
||||||
# Spec functions implemented based on cached values instead of the full state
|
# Spec functions implemented based on cached values instead of the full state
|
||||||
func count_active_validators*(epochInfo: EpochRef): uint64 =
|
func count_active_validators*(epochInfo: EpochRef): uint64 =
|
||||||
|
@ -122,3 +122,31 @@ proc is_valid_indexed_attestation*(
|
||||||
return false
|
return false
|
||||||
|
|
||||||
true
|
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],
|
eth/[keys, async_utils], eth/p2p/discoveryv5/[protocol, enr],
|
||||||
|
|
||||||
# Local modules
|
# Local modules
|
||||||
spec/[datatypes, digest, crypto, beaconstate, helpers, validator, network],
|
spec/[datatypes, digest, crypto, helpers, validator, network],
|
||||||
spec/state_transition,
|
spec/state_transition,
|
||||||
conf, time, validator_pool,
|
conf, time, validator_pool,
|
||||||
attestation_pool, block_pools/[spec_cache, chain_dag, clearance],
|
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
|
info "Local validators attached ", count = node.attachedValidators.count
|
||||||
|
|
||||||
|
proc getAttachedValidator*(node: BeaconNode,
|
||||||
|
pubkey: ValidatorPubKey): AttachedValidator =
|
||||||
|
node.attachedValidators.getValidator(pubkey)
|
||||||
|
|
||||||
proc getAttachedValidator*(node: BeaconNode,
|
proc getAttachedValidator*(node: BeaconNode,
|
||||||
state: BeaconState,
|
state: BeaconState,
|
||||||
idx: ValidatorIndex): AttachedValidator =
|
idx: ValidatorIndex): AttachedValidator =
|
||||||
let validatorKey = state.validators[idx].pubkey.initPubKey
|
if idx < state.validators.len.ValidatorIndex:
|
||||||
node.attachedValidators.getValidator(validatorKey)
|
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 =
|
proc isSynced*(node: BeaconNode, head: BlockRef): bool =
|
||||||
## TODO This function is here as a placeholder for some better heurestics to
|
## 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
|
# In case blocks went missing, this means advancing past the latest block
|
||||||
# using empty slots as fillers.
|
# using empty slots as fillers.
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/validator.md#validator-assignments
|
# 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
|
let
|
||||||
|
epochRef = node.chainDag.getEpochRef(
|
||||||
|
attestationHead.blck, slot.compute_epoch_at_slot())
|
||||||
committees_per_slot =
|
committees_per_slot =
|
||||||
get_committee_count_per_slot(state, slot.epoch, cache)
|
get_committee_count_per_slot(epochRef)
|
||||||
num_active_validators =
|
num_active_validators = count_active_validators(epochRef)
|
||||||
count_active_validators(state, slot.compute_epoch_at_slot, cache)
|
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:
|
for committee_index in 0'u64..<committees_per_slot:
|
||||||
let committee = get_beacon_committee(
|
let committee = get_beacon_committee(
|
||||||
state, slot, committee_index.CommitteeIndex, cache)
|
epochRef, slot, committee_index.CommitteeIndex)
|
||||||
|
|
||||||
for index_in_committee, validatorIdx in committee:
|
for index_in_committee, validatorIdx in committee:
|
||||||
let validator = node.getAttachedValidator(state, validatorIdx)
|
let validator = node.getAttachedValidator(epochRef, validatorIdx)
|
||||||
if validator != nil:
|
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))
|
attestations.add((ad, committee.len, index_in_committee, validator))
|
||||||
|
|
||||||
for a in attestations:
|
for a in attestations:
|
||||||
traceAsyncErrors createAndSendAttestation(
|
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)
|
a.committeeLen, a.indexInCommittee, num_active_validators)
|
||||||
|
|
||||||
proc handleProposal(node: BeaconNode, head: BlockRef, slot: Slot):
|
proc handleProposal(node: BeaconNode, head: BlockRef, slot: Slot):
|
||||||
|
@ -359,7 +375,7 @@ proc handleProposal(node: BeaconNode, head: BlockRef, slot: Slot):
|
||||||
return head
|
return head
|
||||||
|
|
||||||
let validator =
|
let validator =
|
||||||
node.attachedValidators.getValidator(proposer.get()[1].initPubKey())
|
node.attachedValidators.getValidator(proposer.get()[1])
|
||||||
|
|
||||||
if validator != nil:
|
if validator != nil:
|
||||||
return await proposeBlock(node, validator, proposer.get()[0], head, slot)
|
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)
|
info "Local validator attached", pubKey, validator = shortLog(v)
|
||||||
|
|
||||||
func getValidator*(pool: ValidatorPool,
|
proc getValidator*(pool: ValidatorPool,
|
||||||
validatorKey: ValidatorPubKey): AttachedValidator =
|
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
|
# TODO: Honest validator - https://github.com/ethereum/eth2.0-specs/blob/v0.12.2/specs/phase0/validator.md
|
||||||
proc signBlockProposal*(v: AttachedValidator, fork: Fork,
|
proc signBlockProposal*(v: AttachedValidator, fork: Fork,
|
||||||
|
|
Loading…
Reference in New Issue