2019-12-06 15:05:11 +00:00
|
|
|
# beacon_chain
|
2020-01-22 12:48:06 +00:00
|
|
|
# Copyright (c) 2019-2020 Status Research & Development GmbH
|
2019-12-06 15:05:11 +00:00
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2019-12-09 20:24:39 +00:00
|
|
|
# The other part is arguably part of attestation pool -- the validation's
|
|
|
|
# something that should be happing on receipt, not aggregation per se. In
|
|
|
|
# that part, check that messages conform -- so, check for each type
|
2020-01-27 12:21:50 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/p2p-interface.md#topics-and-messages
|
2019-12-09 20:24:39 +00:00
|
|
|
# specifies. So by the time this calls attestation pool, all validation's
|
|
|
|
# already done.
|
|
|
|
|
2019-12-06 12:05:00 +00:00
|
|
|
import
|
2019-12-10 13:44:22 +00:00
|
|
|
options,
|
2020-03-19 23:48:03 +00:00
|
|
|
./spec/[beaconstate, datatypes, crypto, digest, helpers, validator,
|
|
|
|
state_transition_block],
|
2019-12-09 20:24:39 +00:00
|
|
|
./attestation_pool, ./beacon_node_types, ./ssz
|
2019-12-06 12:05:00 +00:00
|
|
|
|
2020-04-01 09:59:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#aggregation-selection
|
2019-12-06 12:05:00 +00:00
|
|
|
func is_aggregator(state: BeaconState, slot: Slot, index: uint64,
|
|
|
|
slot_signature: ValidatorSig): bool =
|
|
|
|
# TODO index is a CommitteeIndex, aka uint64
|
|
|
|
var cache = get_empty_per_epoch_cache()
|
|
|
|
|
|
|
|
let
|
|
|
|
committee = get_beacon_committee(state, slot, index, cache)
|
|
|
|
modulo = max(1, len(committee) div TARGET_AGGREGATORS_PER_COMMITTEE).uint64
|
|
|
|
bytes_to_int(eth2hash(slot_signature.getBytes).data[0..7]) mod modulo == 0
|
|
|
|
|
2019-12-09 20:24:39 +00:00
|
|
|
proc aggregate_attestations*(
|
|
|
|
pool: AttestationPool, state: BeaconState, index: uint64,
|
2020-04-01 09:59:55 +00:00
|
|
|
privkey: ValidatorPrivKey, trailing_distance: uint64): Option[AggregateAndProof] =
|
2019-12-06 15:05:11 +00:00
|
|
|
# TODO alias CommitteeIndex to actual type then convert various uint64's here
|
|
|
|
|
2020-04-01 09:59:55 +00:00
|
|
|
doAssert state.slot >= trailing_distance
|
|
|
|
|
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#configuration
|
|
|
|
doAssert trailing_distance <= ATTESTATION_PROPAGATION_SLOT_RANGE
|
|
|
|
|
2019-12-10 13:44:22 +00:00
|
|
|
let
|
2020-04-01 09:59:55 +00:00
|
|
|
slot = state.slot - trailing_distance
|
|
|
|
slot_signature = get_slot_signature(
|
|
|
|
state.fork, state.genesis_validators_root, slot, privkey)
|
2019-12-10 13:44:22 +00:00
|
|
|
|
|
|
|
doAssert slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= state.slot
|
|
|
|
doAssert state.slot >= slot
|
|
|
|
|
2020-04-01 09:59:55 +00:00
|
|
|
# TODO performance issue for future, via get_active_validator_indices(...)
|
|
|
|
doAssert index < get_committee_count_at_slot(state, slot)
|
|
|
|
|
|
|
|
# TODO for testing purposes, refactor this into the condition check
|
|
|
|
# and just calculation
|
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#aggregation-selection
|
2019-12-10 13:44:22 +00:00
|
|
|
if not is_aggregator(state, slot, index, slot_signature):
|
|
|
|
return none(AggregateAndProof)
|
2019-12-06 15:05:11 +00:00
|
|
|
|
2020-04-01 09:59:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#attestation-data
|
|
|
|
# describes how to construct an attestation, which applies for makeAttestationData(...)
|
|
|
|
# TODO this won't actually match anything
|
|
|
|
let attestation_data = AttestationData(
|
|
|
|
slot: slot,
|
|
|
|
index: index,
|
|
|
|
beacon_block_root: get_block_root_at_slot(state, slot))
|
2019-12-10 13:44:22 +00:00
|
|
|
|
2020-04-01 09:59:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#construct-aggregate
|
|
|
|
# TODO once EV goes in w/ refactoring of getAttestationsForBlock, pull out the getSlot version and use
|
|
|
|
# it. This is incorrect.
|
|
|
|
for attestation in getAttestationsForBlock(pool, state):
|
|
|
|
# getAttestationsForBlock(...) already aggregates
|
2019-12-10 14:21:07 +00:00
|
|
|
if attestation.data == attestation_data:
|
2020-04-01 09:59:55 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#aggregateandproof
|
2019-12-10 13:44:22 +00:00
|
|
|
return some(AggregateAndProof(
|
|
|
|
aggregator_index: index,
|
|
|
|
aggregate: attestation,
|
|
|
|
selection_proof: slot_signature))
|
|
|
|
|
|
|
|
none(AggregateAndProof)
|