don't used sorted() in get_indexed_attestation()

This commit is contained in:
Dustin Brody 2021-01-28 17:57:25 +01:00 committed by zah
parent f7e327234f
commit 490e4c7666
4 changed files with 28 additions and 83 deletions

View File

@ -8,7 +8,7 @@
{.push raises: [Defect].}
import
std/[algorithm, intsets, math, options, sequtils, tables],
std/[algorithm, collections/heapqueue, math, options, sequtils, tables],
stew/assign2,
json_serialization/std/sets,
chronicles,
@ -475,35 +475,12 @@ proc is_valid_indexed_attestation*(
ok()
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_attesting_indices
iterator get_attesting_indices*(bits: CommitteeValidatorsBits,
committee: openArray[ValidatorIndex]):
ValidatorIndex =
if bits.len == committee.len:
for i, index in committee:
if bits[i]:
yield index
else:
# This shouldn't happen if one begins with a valid BeaconState and applies
# valid updates, but one can construct a BeaconState where it does. Do not
# do anything here since the PendingAttestation wouldn't have made it past
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#attestations
# which checks len(attestation.aggregation_bits) == len(committee) that in
# nimbus-eth2 lives in check_attestation(...).
# Addresses https://github.com/status-im/nimbus-eth2/issues/922
trace "get_attesting_indices: inconsistent aggregation and committee length"
func get_attesting_indices*(bits: CommitteeValidatorsBits,
committee: openArray[ValidatorIndex]): IntSet =
for idx in get_attesting_indices(bits, committee):
result.incl idx.int
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_attesting_indices
iterator get_attesting_indices*(state: BeaconState,
data: AttestationData,
bits: CommitteeValidatorsBits,
cache: var StateCache): ValidatorIndex =
## Return the set of attesting indices corresponding to ``data`` and ``bits``.
if bits.lenu64 != get_beacon_committee_len(state, data.slot, data.index.CommitteeIndex, cache):
trace "get_attesting_indices: inconsistent aggregation and committee length"
else:
@ -513,28 +490,30 @@ iterator get_attesting_indices*(state: BeaconState,
yield index
inc i
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_attesting_indices
func get_attesting_indices*(state: BeaconState,
data: AttestationData,
bits: CommitteeValidatorsBits,
cache: var StateCache): IntSet =
# Return the set of attesting indices corresponding to ``data`` and ``bits``.
iterator get_sorted_attesting_indices*(state: BeaconState,
data: AttestationData,
bits: CommitteeValidatorsBits,
cache: var StateCache): ValidatorIndex =
var heap = initHeapQueue[ValidatorIndex]()
for index in get_attesting_indices(state, data, bits, cache):
result.incl index.int
heap.push(index)
while heap.len > 0:
yield heap.pop()
func get_sorted_attesting_indices_list*(
state: BeaconState, data: AttestationData, bits: CommitteeValidatorsBits,
cache: var StateCache): List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE] =
for index in get_sorted_attesting_indices(state, data, bits, cache):
result.add index.uint64
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/beacon-chain.md#get_indexed_attestation
func get_indexed_attestation(state: BeaconState, attestation: Attestation,
cache: var StateCache): IndexedAttestation =
## Return the indexed attestation corresponding to ``attestation``.
let
attesting_indices =
get_attesting_indices(
state, attestation.data, attestation.aggregation_bits, cache)
IndexedAttestation(
attesting_indices:
List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE].init(
sorted(mapIt(attesting_indices.toSeq, it.uint64), system.cmp)),
attesting_indices: get_sorted_attesting_indices_list(
state, attestation.data, attestation.aggregation_bits, cache),
data: attestation.data,
signature: attestation.signature
)
@ -542,15 +521,9 @@ func get_indexed_attestation(state: BeaconState, attestation: Attestation,
func get_indexed_attestation(state: BeaconState, attestation: TrustedAttestation,
cache: var StateCache): TrustedIndexedAttestation =
## Return the indexed attestation corresponding to ``attestation``.
let
attesting_indices =
get_attesting_indices(
state, attestation.data, attestation.aggregation_bits, cache)
TrustedIndexedAttestation(
attesting_indices:
List[uint64, Limit MAX_VALIDATORS_PER_COMMITTEE].init(
sorted(mapIt(attesting_indices.toSeq, it.uint64), system.cmp)),
attesting_indices: get_sorted_attesting_indices_list(
state, attestation.data, attestation.aggregation_bits, cache),
data: attestation.data,
signature: attestation.signature
)

View File

@ -86,6 +86,7 @@ func getAttestationTopic*(forkDigest: ForkDigest, subnetIndex: uint64):
except ValueError as e:
raiseAssert e.msg
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/validator.md#validator-assignments
iterator get_committee_assignments*(
state: BeaconState, epoch: Epoch,
validator_indices: IntSet,

View File

@ -369,31 +369,3 @@ func get_beacon_proposer_index*(state: BeaconState, cache: var StateCache, slot:
func get_beacon_proposer_index*(state: BeaconState, cache: var StateCache):
Option[ValidatorIndex] =
get_beacon_proposer_index(state, cache, state.slot)
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/validator.md#validator-assignments
func get_committee_assignment*(
state: BeaconState, epoch: Epoch,
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.
let next_epoch = get_current_epoch(state) + 1
doAssert epoch <= next_epoch
var cache = StateCache()
let
start_slot = compute_start_slot_at_epoch(epoch)
committee_count_per_slot =
get_committee_count_per_slot(state, epoch, cache)
for slot in start_slot ..< start_slot + SLOTS_PER_EPOCH:
for index in 0'u64 ..< committee_count_per_slot:
let idx = index.CommitteeIndex
let committee = get_beacon_committee(state, slot, idx, cache)
if validator_index in committee:
return some((committee, idx, slot))
none(tuple[a: seq[ValidatorIndex], b: CommitteeIndex, c: Slot])

View File

@ -58,16 +58,15 @@ proc mockAttestationData(
proc signMockAttestation*(state: BeaconState, attestation: var Attestation) =
var cache = StateCache()
let participants = get_attesting_indices(
state,
attestation.data,
attestation.aggregation_bits,
cache
)
var agg {.noInit.}: AggregateSignature
var first_iter = true # Can't do while loop on hashset
for validator_index in participants:
for validator_index in get_attesting_indices(
state,
attestation.data,
attestation.aggregation_bits,
cache
):
let sig = get_attestation_signature(
state.fork, state.genesis_validators_root, attestation.data,
MockPrivKeys[validator_index]