update compute_subnet_for_attestation() to use https://github.com/ethereum/eth2.0-specs/pull/1876 signature, which isn't in v0.12.1, which works with lookahead (#1346)
This commit is contained in:
parent
4a9a7be271
commit
6b77f3dda5
|
@ -171,7 +171,9 @@ proc isValidAttestation*(
|
|||
epochInfo = blck.getEpochInfo(state)
|
||||
requiredSubnetIndex =
|
||||
compute_subnet_for_attestation(
|
||||
epochInfo.shuffled_active_validator_indices.len.uint64, attestation)
|
||||
get_committee_count_at_slot(
|
||||
epochInfo.shuffled_active_validator_indices.len.uint64),
|
||||
attestation.data.slot, attestation.data.index.CommitteeIndex)
|
||||
|
||||
if requiredSubnetIndex != topicCommitteeIndex:
|
||||
debug "isValidAttestation: attestation's committee index not for the correct subnet",
|
||||
|
|
|
@ -58,26 +58,27 @@ func getAggregateAndProofsTopic*(forkDigest: ForkDigest): string =
|
|||
raiseAssert e.msg
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#broadcast-attestation
|
||||
# https://github.com/ethereum/eth2.0-specs/pull/1876
|
||||
func compute_subnet_for_attestation*(
|
||||
num_active_validators: uint64, attestation: Attestation): uint64 =
|
||||
committees_per_slot: uint64, slot: Slot, committee_index: CommitteeIndex):
|
||||
uint64 =
|
||||
# Compute the correct subnet for an attestation for Phase 0.
|
||||
# Note, this mimics expected Phase 1 behavior where attestations will be
|
||||
# mapped to their shard subnet.
|
||||
#
|
||||
# The spec version has params (state: BeaconState, attestation: Attestation),
|
||||
# but it's only to call get_committee_count_at_slot(), which needs only epoch
|
||||
# and the number of active validators.
|
||||
let
|
||||
slots_since_epoch_start = attestation.data.slot mod SLOTS_PER_EPOCH
|
||||
slots_since_epoch_start = slot mod SLOTS_PER_EPOCH
|
||||
committees_since_epoch_start =
|
||||
get_committee_count_at_slot(num_active_validators) * slots_since_epoch_start
|
||||
committees_per_slot * slots_since_epoch_start
|
||||
|
||||
(committees_since_epoch_start + attestation.data.index) mod ATTESTATION_SUBNET_COUNT
|
||||
(committees_since_epoch_start + committee_index.uint64) mod
|
||||
ATTESTATION_SUBNET_COUNT
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#broadcast-attestation
|
||||
func getAttestationTopic*(forkDigest: ForkDigest, subnetIndex: uint64):
|
||||
string =
|
||||
# This is for subscribing or broadcasting manually to a known index.
|
||||
doAssert subnetIndex < ATTESTATION_SUBNET_COUNT
|
||||
|
||||
try:
|
||||
&"/eth2/{$forkDigest}/beacon_attestation_{subnetIndex}/ssz"
|
||||
except ValueError as e:
|
||||
|
@ -86,4 +87,6 @@ func getAttestationTopic*(forkDigest: ForkDigest, subnetIndex: uint64):
|
|||
func getAttestationTopic*(forkDigest: ForkDigest, attestation: Attestation, num_active_validators: uint64): string =
|
||||
getAttestationTopic(
|
||||
forkDigest,
|
||||
compute_subnet_for_attestation(num_active_validators, attestation))
|
||||
compute_subnet_for_attestation(
|
||||
get_committee_count_at_slot(num_active_validators),
|
||||
attestation.data.slot, attestation.data.index.CommitteeIndex))
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
import
|
||||
algorithm, options, sequtils, math, tables, sets,
|
||||
./datatypes, ./digest, ./helpers
|
||||
./datatypes, ./digest, ./helpers, ./network
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#compute_shuffled_index
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#compute_committee
|
||||
|
@ -274,17 +274,14 @@ func get_beacon_proposer_index*(state: BeaconState, cache: var StateCache):
|
|||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#validator-assignments
|
||||
func get_committee_assignment*(
|
||||
state: BeaconState, epoch: Epoch,
|
||||
validator_indices: HashSet[ValidatorIndex]):
|
||||
Option[tuple[a: seq[ValidatorIndex], b: CommitteeIndex, c: Slot]] {.used.} =
|
||||
validator_index: ValidatorIndex):
|
||||
Option[tuple[a: seq[ValidatorIndex], b: CommitteeIndex, c: Slot]] =
|
||||
# Return the committee assignment in the ``epoch`` for ``validator_index``.
|
||||
# ``assignment`` returned is a tuple of the following form:
|
||||
# * ``assignment[0]`` is the list of validators in the committee
|
||||
# * ``assignment[1]`` is the index to which the committee is assigned
|
||||
# * ``assignment[2]`` is the slot at which the committee is assigned
|
||||
# Return None if no assignment.
|
||||
#
|
||||
# Slightly adapted from spec version to support multiple validator indices,
|
||||
# since each beacon_node supports many validators.
|
||||
let next_epoch = get_current_epoch(state) + 1
|
||||
doAssert epoch <= next_epoch
|
||||
|
||||
|
@ -295,10 +292,32 @@ func get_committee_assignment*(
|
|||
for index in 0 ..< get_committee_count_at_slot(state, slot):
|
||||
let idx = index.CommitteeIndex
|
||||
let committee = get_beacon_committee(state, slot, idx, cache)
|
||||
if not disjoint(validator_indices, toHashSet(committee)):
|
||||
if validator_index in committee:
|
||||
return some((committee, idx, slot))
|
||||
none(tuple[a: seq[ValidatorIndex], b: CommitteeIndex, c: Slot])
|
||||
|
||||
func get_committee_assignments*(
|
||||
state: BeaconState, epoch: Epoch,
|
||||
validator_indices: HashSet[ValidatorIndex]):
|
||||
seq[tuple[subnetIndex: uint64, slot: Slot]] =
|
||||
let next_epoch = get_current_epoch(state) + 1
|
||||
doAssert epoch <= next_epoch
|
||||
|
||||
var cache = StateCache()
|
||||
let start_slot = compute_start_slot_at_epoch(epoch)
|
||||
|
||||
# get_committee_count_at_slot is constant throughout an epoch
|
||||
let committee_count_at_slot = get_committee_count_at_slot(state, start_slot)
|
||||
|
||||
for slot in start_slot ..< start_slot + SLOTS_PER_EPOCH:
|
||||
for index in 0 ..< committee_count_at_slot:
|
||||
let idx = index.CommitteeIndex
|
||||
if not disjoint(validator_indices,
|
||||
get_beacon_committee(state, slot, idx, cache).toHashSet):
|
||||
result.add(
|
||||
(compute_subnet_for_attestation(committee_count_at_slot, slot, idx),
|
||||
slot))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#validator-assignments
|
||||
func is_proposer(
|
||||
state: BeaconState, validator_index: ValidatorIndex): bool {.used.} =
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import
|
||||
# Standard library
|
||||
tables, strutils, parseutils, sequtils, sets,
|
||||
tables, strutils, parseutils, sequtils,
|
||||
|
||||
# Nimble packages
|
||||
stew/[byteutils, objects],
|
||||
|
@ -356,8 +356,7 @@ proc installValidatorApiHandlers*(rpcServer: RpcServer, node: BeaconNode) =
|
|||
let idx = state.validators.asSeq.findIt(it.pubKey == pubkey)
|
||||
if idx == -1:
|
||||
continue
|
||||
let ca = state.get_committee_assignment(
|
||||
epoch, toHashSet([idx.ValidatorIndex]))
|
||||
let ca = state.get_committee_assignment(epoch, idx.ValidatorIndex)
|
||||
if ca.isSome:
|
||||
result.add((public_key: pubkey,
|
||||
committee_index: ca.get.b,
|
||||
|
|
|
@ -425,7 +425,7 @@ proc broadcastAggregatedAttestations(
|
|||
|
||||
proc handleValidatorDuties*(
|
||||
node: BeaconNode, lastSlot, slot: Slot) {.async.} =
|
||||
## Perform validator duties - create blocks, vote and aggreagte existing votes
|
||||
## Perform validator duties - create blocks, vote and aggregate existing votes
|
||||
var head = node.updateHead()
|
||||
if node.attachedValidators.count == 0:
|
||||
# Nothing to do because we have no validator attached
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
../beacon_chain/[beacon_chain_db, block_pool, extras],
|
||||
../beacon_chain/spec/[crypto, datatypes, digest, helpers,
|
||||
state_transition, validator, presets],
|
||||
../beacon_chain/sszdump, ../beacon_chain/ssz/merkleization,
|
||||
../research/simutils,
|
||||
../beacon_chain/sszdump, ../research/simutils,
|
||||
eth/db/[kvstore, kvstore_sqlite3]
|
||||
|
||||
type Timers = enum
|
||||
|
|
|
@ -151,7 +151,7 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
|
|||
|
||||
flushFile(stdout)
|
||||
|
||||
if (state[].data.slot) mod SLOTS_PER_EPOCH == 0:
|
||||
if (state[].data.slot).isEpoch:
|
||||
echo &" slot: {shortLog(state[].data.slot)} ",
|
||||
&"epoch: {shortLog(state[].data.slot.compute_epoch_at_slot)}"
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ proc addMockAttestations*(
|
|||
sufficient_support = false
|
||||
) =
|
||||
# We must be at the end of the epoch
|
||||
doAssert (state.slot + 1) mod SLOTS_PER_EPOCH == 0
|
||||
doAssert (state.slot + 1).isEpoch
|
||||
|
||||
# Alias the attestations container
|
||||
var attestations: ptr seq[PendingAttestation]
|
||||
|
|
Loading…
Reference in New Issue