create distinct CommitteeIndex type

This commit is contained in:
Dustin Brody 2020-04-15 11:01:36 +02:00 committed by tersec
parent f49dbf68e6
commit d559f4ee89
12 changed files with 48 additions and 35 deletions

View File

@ -12,9 +12,8 @@ import
./attestation_pool, ./beacon_node_types, ./ssz ./attestation_pool, ./beacon_node_types, ./ssz
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#aggregation-selection # https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#aggregation-selection
func is_aggregator(state: BeaconState, slot: Slot, index: uint64, func is_aggregator(state: BeaconState, slot: Slot, index: CommitteeIndex,
slot_signature: ValidatorSig): bool = slot_signature: ValidatorSig): bool =
# TODO index is a CommitteeIndex, aka uint64
var cache = get_empty_per_epoch_cache() var cache = get_empty_per_epoch_cache()
let let
@ -23,10 +22,8 @@ func is_aggregator(state: BeaconState, slot: Slot, index: uint64,
bytes_to_int(eth2hash(slot_signature.toRaw()).data[0..7]) mod modulo == 0 bytes_to_int(eth2hash(slot_signature.toRaw()).data[0..7]) mod modulo == 0
proc aggregate_attestations*( proc aggregate_attestations*(
pool: AttestationPool, state: BeaconState, index: uint64, pool: AttestationPool, state: BeaconState, index: CommitteeIndex,
privkey: ValidatorPrivKey, trailing_distance: uint64): Option[AggregateAndProof] = privkey: ValidatorPrivKey, trailing_distance: uint64): Option[AggregateAndProof] =
# TODO alias CommitteeIndex to actual type then convert various uint64's here
doAssert state.slot >= trailing_distance doAssert state.slot >= trailing_distance
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#configuration # https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#configuration
@ -41,7 +38,7 @@ proc aggregate_attestations*(
doAssert state.slot >= slot doAssert state.slot >= slot
# TODO performance issue for future, via get_active_validator_indices(...) # TODO performance issue for future, via get_active_validator_indices(...)
doAssert index < get_committee_count_at_slot(state, slot) doAssert index.uint64 < get_committee_count_at_slot(state, slot)
# TODO for testing purposes, refactor this into the condition check # TODO for testing purposes, refactor this into the condition check
# and just calculation # and just calculation
@ -54,7 +51,7 @@ proc aggregate_attestations*(
# TODO this won't actually match anything # TODO this won't actually match anything
let attestation_data = AttestationData( let attestation_data = AttestationData(
slot: slot, slot: slot,
index: index, index: index.uint64,
beacon_block_root: get_block_root_at_slot(state, slot)) beacon_block_root: get_block_root_at_slot(state, slot))
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#construct-aggregate # https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#construct-aggregate
@ -65,7 +62,7 @@ proc aggregate_attestations*(
if attestation.data == attestation_data: if attestation.data == attestation_data:
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#aggregateandproof # https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#aggregateandproof
return some(AggregateAndProof( return some(AggregateAndProof(
aggregator_index: index, aggregator_index: index.uint64,
aggregate: attestation, aggregate: attestation,
selection_proof: slot_signature)) selection_proof: slot_signature))

View File

@ -546,8 +546,8 @@ proc handleAttestations(node: BeaconNode, head: BlockRef, slot: Slot) =
let committees_per_slot = get_committee_count_at_slot(state, slot) let committees_per_slot = get_committee_count_at_slot(state, slot)
for committee_index in 0'u64..<committees_per_slot: for committee_index in 0'u64..<committees_per_slot:
let let committee = get_beacon_committee(
committee = get_beacon_committee(state, slot, committee_index, cache) state, slot, committee_index.CommitteeIndex, cache)
for index_in_committee, validatorIdx in committee: for index_in_committee, validatorIdx in committee:
let validator = node.getAttachedValidator(state, validatorIdx) let validator = node.getAttachedValidator(state, validatorIdx)
@ -617,8 +617,8 @@ proc broadcastAggregatedAttestations(
committees_per_slot = get_committee_count_at_slot(state, slot) committees_per_slot = get_committee_count_at_slot(state, slot)
var cache = get_empty_per_epoch_cache() var cache = get_empty_per_epoch_cache()
for committee_index in 0'u64..<committees_per_slot: for committee_index in 0'u64..<committees_per_slot:
let let committee = get_beacon_committee(
committee = get_beacon_committee(state, slot, committee_index, cache) state, slot, committee_index.CommitteeIndex, cache)
for index_in_committee, validatorIdx in committee: for index_in_committee, validatorIdx in committee:
let validator = node.getAttachedValidator(state, validatorIdx) let validator = node.getAttachedValidator(state, validatorIdx)
@ -629,7 +629,7 @@ proc broadcastAggregatedAttestations(
# one isSome() with test. # one isSome() with test.
let option_aggregateandproof = let option_aggregateandproof =
aggregate_attestations(node.attestationPool, state, aggregate_attestations(node.attestationPool, state,
committee_index, committee_index.CommitteeIndex,
# TODO https://github.com/status-im/nim-beacon-chain/issues/545 # TODO https://github.com/status-im/nim-beacon-chain/issues/545
# this assumes in-process private keys # this assumes in-process private keys
validator.privKey, validator.privKey,

View File

@ -420,7 +420,8 @@ func get_attesting_indices*(state: BeaconState,
HashSet[ValidatorIndex] = HashSet[ValidatorIndex] =
# Return the set of attesting indices corresponding to ``data`` and ``bits``. # Return the set of attesting indices corresponding to ``data`` and ``bits``.
result = initHashSet[ValidatorIndex]() result = initHashSet[ValidatorIndex]()
let committee = get_beacon_committee(state, data.slot, data.index, stateCache) let committee = get_beacon_committee(
state, data.slot, data.index.CommitteeIndex, stateCache)
for i, index in committee: for i, index in committee:
if bits[i]: if bits[i]:
result.incl index result.incl index
@ -485,7 +486,8 @@ proc check_attestation*(
state_slot = shortLog(stateSlot)) state_slot = shortLog(stateSlot))
return return
let committee = get_beacon_committee(state, data.slot, data.index, stateCache) let committee = get_beacon_committee(
state, data.slot, data.index.CommitteeIndex, stateCache)
if attestation.aggregation_bits.len != committee.len: if attestation.aggregation_bits.len != committee.len:
warn("Inconsistent aggregation and committee length", warn("Inconsistent aggregation and committee length",
aggregation_bits_len = attestation.aggregation_bits.len, aggregation_bits_len = attestation.aggregation_bits.len,

View File

@ -112,6 +112,7 @@ type
# range-limit. # range-limit.
ValidatorIndex* = distinct uint32 ValidatorIndex* = distinct uint32
Gwei* = uint64 Gwei* = uint64
CommitteeIndex* = distinct uint64
BitList*[maxLen: static int] = distinct BitSeq BitList*[maxLen: static int] = distinct BitSeq
@ -154,6 +155,9 @@ type
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/beacon-chain.md#AttestationData # https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/beacon-chain.md#AttestationData
AttestationData* = object AttestationData* = object
slot*: Slot slot*: Slot
# TODO this is actually a CommitteeIndex; remove some conversions by
# allowing SSZ to directly handle this
index*: uint64 index*: uint64
# LMD GHOST vote # LMD GHOST vote

View File

@ -57,6 +57,11 @@ func get_active_validator_indices*(state: BeaconState, epoch: Epoch):
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/beacon-chain.md#get_committee_count_at_slot # https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/beacon-chain.md#get_committee_count_at_slot
func get_committee_count_at_slot*(state: BeaconState, slot: Slot): uint64 = func get_committee_count_at_slot*(state: BeaconState, slot: Slot): uint64 =
# Return the number of committees at ``slot``. # Return the number of committees at ``slot``.
# TODO this is mostly used in for loops which have indexes which then need to
# be converted to CommitteeIndex types for get_beacon_committee(...); replace
# with better and more type-safe use pattern, probably beginning with using a
# CommitteeIndex return type here.
let epoch = compute_epoch_at_slot(slot) let epoch = compute_epoch_at_slot(slot)
let active_validator_indices = get_active_validator_indices(state, epoch) let active_validator_indices = get_active_validator_indices(state, epoch)
let committees_per_slot = clamp( let committees_per_slot = clamp(

View File

@ -112,7 +112,9 @@ func compute_committee(indices: seq[ValidatorIndex], seed: Eth2Digest,
indices[stateCache.beacon_committee_cache[key][it]]) indices[stateCache.beacon_committee_cache[key][it]])
# https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/beacon-chain.md#get_beacon_committee # https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/beacon-chain.md#get_beacon_committee
func get_beacon_committee*(state: BeaconState, slot: Slot, index: uint64, cache: var StateCache): seq[ValidatorIndex] = func get_beacon_committee*(
state: BeaconState, slot: Slot, index: CommitteeIndex,
cache: var StateCache): seq[ValidatorIndex] =
# Return the beacon committee at ``slot`` for ``index``. # Return the beacon committee at ``slot`` for ``index``.
let let
epoch = compute_epoch_at_slot(slot) epoch = compute_epoch_at_slot(slot)
@ -132,7 +134,8 @@ func get_beacon_committee*(state: BeaconState, slot: Slot, index: uint64, cache:
compute_committee( compute_committee(
cache.active_validator_indices_cache[epoch], cache.active_validator_indices_cache[epoch],
get_seed(state, epoch, DOMAIN_BEACON_ATTESTER), get_seed(state, epoch, DOMAIN_BEACON_ATTESTER),
(slot mod SLOTS_PER_EPOCH) * cache.committee_count_cache[epoch] + index, (slot mod SLOTS_PER_EPOCH) * cache.committee_count_cache[epoch] +
index.uint64,
cache.committee_count_cache[epoch] * SLOTS_PER_EPOCH, cache.committee_count_cache[epoch] * SLOTS_PER_EPOCH,
cache cache
) )
@ -197,7 +200,7 @@ func get_beacon_proposer_index*(state: BeaconState, stateCache: var StateCache):
# https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/validator.md#validator-assignments # https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/validator.md#validator-assignments
func get_committee_assignment( func get_committee_assignment(
state: BeaconState, epoch: Epoch, validator_index: ValidatorIndex): state: BeaconState, epoch: Epoch, validator_index: ValidatorIndex):
Option[tuple[a: seq[ValidatorIndex], b: uint64, c: Slot]] {.used.} = Option[tuple[a: seq[ValidatorIndex], b: CommitteeIndex, c: Slot]] {.used.} =
# Return the committee assignment in the ``epoch`` for ``validator_index``. # Return the committee assignment in the ``epoch`` for ``validator_index``.
# ``assignment`` returned is a tuple of the following form: # ``assignment`` returned is a tuple of the following form:
# * ``assignment[0]`` is the list of validators in the committee # * ``assignment[0]`` is the list of validators in the committee
@ -212,11 +215,12 @@ func get_committee_assignment(
let start_slot = compute_start_slot_at_epoch(epoch) let start_slot = compute_start_slot_at_epoch(epoch)
for slot in start_slot ..< start_slot + SLOTS_PER_EPOCH: for slot in start_slot ..< start_slot + SLOTS_PER_EPOCH:
for index in 0 ..< get_committee_count_at_slot(state, slot): for index in 0 ..< get_committee_count_at_slot(state, slot):
let idx = index.CommitteeIndex
let committee = let committee =
get_beacon_committee(state, slot, index, cache) get_beacon_committee(state, slot, idx, cache)
if validator_index in committee: if validator_index in committee:
return some((committee, index, slot)) return some((committee, idx, slot))
none(tuple[a: seq[ValidatorIndex], b: uint64, c: Slot]) none(tuple[a: seq[ValidatorIndex], b: CommitteeIndex, c: Slot])
# https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/validator.md#validator-assignments # https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/validator.md#validator-assignments
func is_proposer( func is_proposer(

View File

@ -146,7 +146,7 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
scass = withTimerRet(timers[tShuffle]): scass = withTimerRet(timers[tShuffle]):
mapIt( mapIt(
0'u64 ..< get_committee_count_at_slot(state, target_slot), 0'u64 ..< get_committee_count_at_slot(state, target_slot),
get_beacon_committee(state, target_slot, it, cache)) get_beacon_committee(state, target_slot, it.CommitteeIndex, cache))
for i, scas in scass: for i, scas in scass:
var var

View File

@ -86,7 +86,7 @@ proc mockAttestationImpl(
beacon_committee = get_beacon_committee( beacon_committee = get_beacon_committee(
state, state,
result.data.slot, result.data.slot,
result.data.index, result.data.index.CommitteeIndex,
cache cache
) )
committee_size = beacon_committee.len committee_size = beacon_committee.len
@ -117,7 +117,7 @@ proc fillAggregateAttestation*(state: BeaconState, attestation: var Attestation)
let beacon_committee = get_beacon_committee( let beacon_committee = get_beacon_committee(
state, state,
attestation.data.slot, attestation.data.slot,
attestation.data.index, attestation.data.index.CommitteeIndex,
cache cache
) )
for i in 0 ..< beacon_committee.len: for i in 0 ..< beacon_committee.len:

View File

@ -45,7 +45,7 @@ proc addMockAttestations*(
var cache = get_empty_per_epoch_cache() var cache = get_empty_per_epoch_cache()
let committee = get_beacon_committee( let committee = get_beacon_committee(
state, slot.Slot, index, cache) state, slot.Slot, index.CommitteeIndex, cache)
# Create a bitfield filled with the given count per attestation, # Create a bitfield filled with the given count per attestation,
# exactly on the right-most part of the committee field. # exactly on the right-most part of the committee field.

View File

@ -38,7 +38,7 @@ when const_preset == "minimal": # Too much stack space used on mainnet
let let
# Create an attestation for slot 1! # Create an attestation for slot 1!
beacon_committee = get_beacon_committee( beacon_committee = get_beacon_committee(
state.data.data, state.data.data.slot, 0, cache) state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
attestation = makeAttestation( attestation = makeAttestation(
state.data.data, state.blck.root, beacon_committee[0], cache) state.data.data, state.blck.root, beacon_committee[0], cache)
@ -56,7 +56,7 @@ when const_preset == "minimal": # Too much stack space used on mainnet
let let
# Create an attestation for slot 1! # Create an attestation for slot 1!
bc0 = get_beacon_committee( bc0 = get_beacon_committee(
state.data.data, state.data.data.slot, 0, cache) state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
attestation0 = makeAttestation( attestation0 = makeAttestation(
state.data.data, state.blck.root, bc0[0], cache) state.data.data, state.blck.root, bc0[0], cache)
@ -64,7 +64,7 @@ when const_preset == "minimal": # Too much stack space used on mainnet
let let
bc1 = get_beacon_committee(state.data.data, bc1 = get_beacon_committee(state.data.data,
state.data.data.slot, 0, cache) state.data.data.slot, 0.CommitteeIndex, cache)
attestation1 = makeAttestation( attestation1 = makeAttestation(
state.data.data, state.blck.root, bc1[0], cache) state.data.data, state.blck.root, bc1[0], cache)
@ -84,7 +84,7 @@ when const_preset == "minimal": # Too much stack space used on mainnet
let let
# Create an attestation for slot 1! # Create an attestation for slot 1!
bc0 = get_beacon_committee( bc0 = get_beacon_committee(
state.data.data, state.data.data.slot, 0, cache) state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
attestation0 = makeAttestation( attestation0 = makeAttestation(
state.data.data, state.blck.root, bc0[0], cache) state.data.data, state.blck.root, bc0[0], cache)
attestation1 = makeAttestation( attestation1 = makeAttestation(
@ -106,7 +106,7 @@ when const_preset == "minimal": # Too much stack space used on mainnet
var var
# Create an attestation for slot 1! # Create an attestation for slot 1!
bc0 = get_beacon_committee( bc0 = get_beacon_committee(
state.data.data, state.data.data.slot, 0, cache) state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
attestation0 = makeAttestation( attestation0 = makeAttestation(
state.data.data, state.blck.root, bc0[0], cache) state.data.data, state.blck.root, bc0[0], cache)
attestation1 = makeAttestation( attestation1 = makeAttestation(
@ -129,7 +129,7 @@ when const_preset == "minimal": # Too much stack space used on mainnet
var var
# Create an attestation for slot 1! # Create an attestation for slot 1!
bc0 = get_beacon_committee(state.data.data, bc0 = get_beacon_committee(state.data.data,
state.data.data.slot, 0, cache) state.data.data.slot, 0.CommitteeIndex, cache)
attestation0 = makeAttestation( attestation0 = makeAttestation(
state.data.data, state.blck.root, bc0[0], cache) state.data.data, state.blck.root, bc0[0], cache)
attestation1 = makeAttestation( attestation1 = makeAttestation(
@ -185,7 +185,7 @@ when const_preset == "minimal": # Too much stack space used on mainnet
b11Add = blockPool.add(b11Root, b11) b11Add = blockPool.add(b11Root, b11)
bc1 = get_beacon_committee( bc1 = get_beacon_committee(
state.data.data, state.data.data.slot, 1, cache) state.data.data, state.data.data.slot, 1.CommitteeIndex, cache)
attestation0 = makeAttestation(state.data.data, b10Root, bc1[0], cache) attestation0 = makeAttestation(state.data.data, b10Root, bc1[0], cache)
pool.add(attestation0) pool.add(attestation0)

View File

@ -85,7 +85,7 @@ suiteReport "Block processing" & preset():
let let
# Create an attestation for slot 1 signed by the only attester we have! # Create an attestation for slot 1 signed by the only attester we have!
beacon_committee = beacon_committee =
get_beacon_committee(state, state.slot, 0, cache) get_beacon_committee(state, state.slot, 0.CommitteeIndex, cache)
attestation = makeAttestation( attestation = makeAttestation(
state, previous_block_root, beacon_committee[0], cache) state, previous_block_root, beacon_committee[0], cache)

View File

@ -191,7 +191,7 @@ proc find_beacon_committee(
slot = ((epoch_committee_index mod SLOTS_PER_EPOCH) + slot = ((epoch_committee_index mod SLOTS_PER_EPOCH) +
epoch.compute_start_slot_at_epoch.uint64).Slot epoch.compute_start_slot_at_epoch.uint64).Slot
index = epoch_committee_index div SLOTS_PER_EPOCH index = epoch_committee_index div SLOTS_PER_EPOCH
committee = get_beacon_committee(state, slot, index, cache) committee = get_beacon_committee(state, slot, index.CommitteeIndex, cache)
if validator_index in committee: if validator_index in committee:
return (committee, slot, index) return (committee, slot, index)
doAssert false doAssert false
@ -216,7 +216,8 @@ proc makeFullAttestations*(
for index in 0..<count: for index in 0..<count:
let let
committee = get_beacon_committee(state, slot, index, cache) committee = get_beacon_committee(
state, slot, index.CommitteeIndex, cache)
data = makeAttestationData(state, slot, index, beacon_block_root) data = makeAttestationData(state, slot, index, beacon_block_root)
doAssert committee.len() >= 1 doAssert committee.len() >= 1