add EF consensus spec test Electra attestation operations fixture (#6248)
This commit is contained in:
parent
9f5d2e290c
commit
6119389c3a
|
@ -2536,6 +2536,55 @@ OK: 5/5 Fail: 0/5 Skip: 0/5
|
||||||
+ Slashings reset - flush_slashings [Preset: mainnet] OK
|
+ Slashings reset - flush_slashings [Preset: mainnet] OK
|
||||||
```
|
```
|
||||||
OK: 1/1 Fail: 0/1 Skip: 0/1
|
OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||||
|
## EF - Electra - Operations - Attestation [Preset: mainnet]
|
||||||
|
```diff
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_after_max_inclusion_slot OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_attestation_data_index_not_zer OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_attestation_signature OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_bad_source_root OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_before_inclusion_delay OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_committe_index OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_correct_attestation_included_a OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_current_source_root OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_empty_participants_seemingly_v OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_empty_participants_zeroes_sig OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_future_target_epoch OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_incorrect_head_and_target_incl OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_incorrect_head_included_after_ OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_incorrect_target_included_afte OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_index OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_mismatched_target_and_slot OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_new_source_epoch OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_nonset_committe_bits OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_old_source_epoch OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_old_target_epoch OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_previous_source_root OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_source_root_is_target_root OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_too_few_aggregation_bits OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_too_many_aggregation_bits OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_too_many_committe_bits OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_wrong_index_for_committee_sign OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_wrong_index_for_slot_0 OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_wrong_index_for_slot_1 OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - at_max_inclusion_slot OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - correct_attestation_included_at_max_in OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - correct_attestation_included_at_min_in OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - correct_attestation_included_at_one_ep OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - correct_attestation_included_at_sqrt_e OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_and_target_included_at_ OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_and_target_included_at_ OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_and_target_min_inclusio OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_included_at_max_inclusi OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_included_at_min_inclusi OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_included_at_sqrt_epoch_ OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_target_included_at_epoch_del OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_target_included_at_min_inclu OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_target_included_at_sqrt_epoc OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - multi_proposer_index_iterations OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - one_basic_attestation OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - previous_epoch OK
|
||||||
|
```
|
||||||
|
OK: 45/45 Fail: 0/45 Skip: 0/45
|
||||||
## EF - Electra - Operations - Attester Slashing [Preset: mainnet]
|
## EF - Electra - Operations - Attester Slashing [Preset: mainnet]
|
||||||
```diff
|
```diff
|
||||||
+ [Invalid] EF - Electra - Operations - Attester Slashing - invalid_all_empty_indices OK
|
+ [Invalid] EF - Electra - Operations - Attester Slashing - invalid_all_empty_indices OK
|
||||||
|
@ -3485,4 +3534,4 @@ OK: 69/88 Fail: 0/88 Skip: 19/88
|
||||||
OK: 3/3 Fail: 0/3 Skip: 0/3
|
OK: 3/3 Fail: 0/3 Skip: 0/3
|
||||||
|
|
||||||
---TOTAL---
|
---TOTAL---
|
||||||
OK: 2792/2811 Fail: 0/2811 Skip: 19/2811
|
OK: 2837/2856 Fail: 0/2856 Skip: 19/2856
|
||||||
|
|
|
@ -2663,6 +2663,55 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||||
+ Sync committee updates - sync_committees_progress_not_genesis [Preset: minimal] OK
|
+ Sync committee updates - sync_committees_progress_not_genesis [Preset: minimal] OK
|
||||||
```
|
```
|
||||||
OK: 5/5 Fail: 0/5 Skip: 0/5
|
OK: 5/5 Fail: 0/5 Skip: 0/5
|
||||||
|
## EF - Electra - Operations - Attestation [Preset: minimal]
|
||||||
|
```diff
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_after_max_inclusion_slot OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_attestation_data_index_not_zer OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_attestation_signature OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_bad_source_root OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_before_inclusion_delay OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_committe_index OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_correct_attestation_included_a OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_current_source_root OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_empty_participants_seemingly_v OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_empty_participants_zeroes_sig OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_future_target_epoch OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_incorrect_head_and_target_incl OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_incorrect_head_included_after_ OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_incorrect_target_included_afte OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_index OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_mismatched_target_and_slot OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_new_source_epoch OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_nonset_committe_bits OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_old_source_epoch OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_old_target_epoch OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_previous_source_root OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_source_root_is_target_root OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_too_few_aggregation_bits OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_too_many_aggregation_bits OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_too_many_committe_bits OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_wrong_index_for_committee_sign OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_wrong_index_for_slot_0 OK
|
||||||
|
+ [Invalid] EF - Electra - Operations - Attestation - invalid_wrong_index_for_slot_1 OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - at_max_inclusion_slot OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - correct_attestation_included_at_max_in OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - correct_attestation_included_at_min_in OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - correct_attestation_included_at_one_ep OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - correct_attestation_included_at_sqrt_e OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_and_target_included_at_ OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_and_target_included_at_ OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_and_target_min_inclusio OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_included_at_max_inclusi OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_included_at_min_inclusi OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_head_included_at_sqrt_epoch_ OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_target_included_at_epoch_del OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_target_included_at_min_inclu OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - incorrect_target_included_at_sqrt_epoc OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - multi_proposer_index_iterations OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - one_basic_attestation OK
|
||||||
|
+ [Valid] EF - Electra - Operations - Attestation - previous_epoch OK
|
||||||
|
```
|
||||||
|
OK: 45/45 Fail: 0/45 Skip: 0/45
|
||||||
## EF - Electra - Operations - Attester Slashing [Preset: minimal]
|
## EF - Electra - Operations - Attester Slashing [Preset: minimal]
|
||||||
```diff
|
```diff
|
||||||
+ [Invalid] EF - Electra - Operations - Attester Slashing - invalid_all_empty_indices OK
|
+ [Invalid] EF - Electra - Operations - Attester Slashing - invalid_all_empty_indices OK
|
||||||
|
@ -3787,4 +3836,4 @@ OK: 185/207 Fail: 0/207 Skip: 22/207
|
||||||
OK: 3/3 Fail: 0/3 Skip: 0/3
|
OK: 3/3 Fail: 0/3 Skip: 0/3
|
||||||
|
|
||||||
---TOTAL---
|
---TOTAL---
|
||||||
OK: 3063/3085 Fail: 0/3085 Skip: 22/3085
|
OK: 3108/3130 Fail: 0/3130 Skip: 22/3130
|
||||||
|
|
|
@ -90,7 +90,7 @@ func compatible_with_shuffling*(
|
||||||
iterator get_attesting_indices*(shufflingRef: ShufflingRef,
|
iterator get_attesting_indices*(shufflingRef: ShufflingRef,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
committee_index: CommitteeIndex,
|
committee_index: CommitteeIndex,
|
||||||
bits: CommitteeValidatorsBits | ElectraCommitteeValidatorsBits):
|
bits: CommitteeValidatorsBits):
|
||||||
ValidatorIndex =
|
ValidatorIndex =
|
||||||
if not bits.compatible_with_shuffling(shufflingRef, slot, committee_index):
|
if not bits.compatible_with_shuffling(shufflingRef, slot, committee_index):
|
||||||
trace "get_attesting_indices: inconsistent aggregation and committee length"
|
trace "get_attesting_indices: inconsistent aggregation and committee length"
|
||||||
|
@ -100,6 +100,14 @@ iterator get_attesting_indices*(shufflingRef: ShufflingRef,
|
||||||
if bits[index_in_committee]:
|
if bits[index_in_committee]:
|
||||||
yield validator_index
|
yield validator_index
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#modified-get_attesting_indices
|
||||||
|
iterator get_attesting_indices*(shufflingRef: ShufflingRef,
|
||||||
|
slot: Slot,
|
||||||
|
committee_index: CommitteeIndex,
|
||||||
|
bits: ElectraCommitteeValidatorsBits):
|
||||||
|
ValidatorIndex =
|
||||||
|
debugRaiseAssert "spec cache get_attesting_indices for electra"
|
||||||
|
|
||||||
iterator get_attesting_indices*(
|
iterator get_attesting_indices*(
|
||||||
dag: ChainDAGRef, attestation: phase0.TrustedAttestation | electra.TrustedAttestation): ValidatorIndex =
|
dag: ChainDAGRef, attestation: phase0.TrustedAttestation | electra.TrustedAttestation): ValidatorIndex =
|
||||||
block: # `return` is not allowed in an inline iterator
|
block: # `return` is not allowed in an inline iterator
|
||||||
|
|
|
@ -573,14 +573,12 @@ proc is_valid_indexed_attestation*(
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#get_attesting_indices
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#get_attesting_indices
|
||||||
iterator get_attesting_indices_iter*(state: ForkyBeaconState,
|
iterator get_attesting_indices_iter*(state: ForkyBeaconState,
|
||||||
data: AttestationData,
|
data: AttestationData,
|
||||||
bits: CommitteeValidatorsBits | ElectraCommitteeValidatorsBits,
|
bits: CommitteeValidatorsBits,
|
||||||
cache: var StateCache): ValidatorIndex =
|
cache: var StateCache): ValidatorIndex =
|
||||||
## Return the set of attesting indices corresponding to ``data`` and ``bits``
|
## Return the set of attesting indices corresponding to ``data`` and ``bits``
|
||||||
## or nothing if `data` is invalid
|
## or nothing if `data` is invalid
|
||||||
## This iterator must not be called in functions using a
|
## This iterator must not be called in functions using a
|
||||||
## ForkedHashedBeaconState due to https://github.com/nim-lang/Nim/issues/18188
|
## ForkedHashedBeaconState due to https://github.com/nim-lang/Nim/issues/18188
|
||||||
|
|
||||||
# Can't be an iterator due to https://github.com/nim-lang/Nim/issues/18188
|
|
||||||
let committee_index = CommitteeIndex.init(data.index)
|
let committee_index = CommitteeIndex.init(data.index)
|
||||||
if committee_index.isErr() or bits.lenu64 != get_beacon_committee_len(
|
if committee_index.isErr() or bits.lenu64 != get_beacon_committee_len(
|
||||||
state, data.slot, committee_index.get(), cache):
|
state, data.slot, committee_index.get(), cache):
|
||||||
|
@ -591,19 +589,55 @@ iterator get_attesting_indices_iter*(state: ForkyBeaconState,
|
||||||
if bits[index_in_committee]:
|
if bits[index_in_committee]:
|
||||||
yield validator_index
|
yield validator_index
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#modified-get_attesting_indices
|
||||||
|
iterator get_attesting_indices_iter*(
|
||||||
|
state: electra.BeaconState,
|
||||||
|
data: AttestationData,
|
||||||
|
aggregation_bits: ElectraCommitteeValidatorsBits,
|
||||||
|
committee_bits: auto,
|
||||||
|
cache: var StateCache): ValidatorIndex =
|
||||||
|
debugRaiseAssert "replace this implementation with actual iterator, after checking on conditions re repeat vals, ordering, etc; this is almost direct transcription of spec link algorithm in one of the places it doesn't make sense"
|
||||||
|
## Return the set of attesting indices corresponding to ``aggregation_bits``
|
||||||
|
## and ``committee_bits``.
|
||||||
|
var output: HashSet[ValidatorIndex]
|
||||||
|
let committee_indices = toSeq(committee_bits.oneIndices)
|
||||||
|
var committee_offset = 0
|
||||||
|
for index in committee_indices:
|
||||||
|
let committee = get_beacon_committee(state, data.slot, index.CommitteeIndex, cache)
|
||||||
|
var committee_attesters: HashSet[ValidatorIndex]
|
||||||
|
for i, index in committee:
|
||||||
|
if aggregation_bits[committee_offset + i]:
|
||||||
|
committee_attesters.incl index
|
||||||
|
output.incl committee_attesters
|
||||||
|
|
||||||
|
committee_offset += len(committee)
|
||||||
|
|
||||||
|
for validatorIndex in output:
|
||||||
|
yield validatorIndex
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#get_attesting_indices
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#get_attesting_indices
|
||||||
func get_attesting_indices*(state: ForkyBeaconState,
|
func get_attesting_indices*(
|
||||||
data: AttestationData,
|
state: ForkyBeaconState, data: AttestationData,
|
||||||
bits: CommitteeValidatorsBits | ElectraCommitteeValidatorsBits,
|
aggregation_bits: CommitteeValidatorsBits, cache: var StateCache):
|
||||||
cache: var StateCache): seq[ValidatorIndex] =
|
seq[ValidatorIndex] =
|
||||||
## Return the set of attesting indices corresponding to ``data`` and ``bits``
|
## Return the set of attesting indices corresponding to ``data`` and ``bits``
|
||||||
## or nothing if `data` is invalid
|
## or nothing if `data` is invalid
|
||||||
|
|
||||||
toSeq(get_attesting_indices_iter(state, data, bits, cache))
|
toSeq(get_attesting_indices_iter(state, data, aggregation_bits, cache))
|
||||||
|
|
||||||
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#get_attesting_indices
|
||||||
|
func get_attesting_indices*(
|
||||||
|
state: ForkyBeaconState, data: AttestationData,
|
||||||
|
aggregation_bits: ElectraCommitteeValidatorsBits, committee_bits: auto,
|
||||||
|
cache: var StateCache): seq[ValidatorIndex] =
|
||||||
|
## Return the set of attesting indices corresponding to ``data`` and ``bits``
|
||||||
|
## or nothing if `data` is invalid
|
||||||
|
|
||||||
|
toSeq(get_attesting_indices_iter(state, data, aggregation_bits, committee_bits, cache))
|
||||||
|
|
||||||
func get_attesting_indices*(state: ForkedHashedBeaconState;
|
func get_attesting_indices*(state: ForkedHashedBeaconState;
|
||||||
data: AttestationData;
|
data: AttestationData;
|
||||||
bits: CommitteeValidatorsBits | ElectraCommitteeValidatorsBits;
|
bits: CommitteeValidatorsBits;
|
||||||
cache: var StateCache): seq[ValidatorIndex] =
|
cache: var StateCache): seq[ValidatorIndex] =
|
||||||
# TODO when https://github.com/nim-lang/Nim/issues/18188 fixed, use an
|
# TODO when https://github.com/nim-lang/Nim/issues/18188 fixed, use an
|
||||||
# iterator
|
# iterator
|
||||||
|
@ -614,9 +648,25 @@ func get_attesting_indices*(state: ForkedHashedBeaconState;
|
||||||
idxBuf.add vidx
|
idxBuf.add vidx
|
||||||
idxBuf
|
idxBuf
|
||||||
|
|
||||||
|
func get_attesting_indices*(state: ForkedHashedBeaconState;
|
||||||
|
data: AttestationData;
|
||||||
|
aggregation_bits: ElectraCommitteeValidatorsBits;
|
||||||
|
committee_bits: auto,
|
||||||
|
cache: var StateCache): seq[ValidatorIndex] =
|
||||||
|
# TODO when https://github.com/nim-lang/Nim/issues/18188 fixed, use an
|
||||||
|
# iterator
|
||||||
|
|
||||||
|
var idxBuf: seq[ValidatorIndex]
|
||||||
|
withState(state):
|
||||||
|
when consensusFork >= ConsensusFork.Electra:
|
||||||
|
for vidx in forkyState.data.get_attesting_indices(data, aggregation_bits, committee_bits, cache):
|
||||||
|
idxBuf.add vidx
|
||||||
|
idxBuf
|
||||||
|
|
||||||
proc is_valid_indexed_attestation(
|
proc is_valid_indexed_attestation(
|
||||||
state: ForkyBeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
state: ForkyBeaconState,
|
||||||
cache: var StateCache): Result[void, cstring] =
|
attestation: SomeAttestation,
|
||||||
|
flags: UpdateFlags, cache: var StateCache): Result[void, cstring] =
|
||||||
# This is a variation on `is_valid_indexed_attestation` that works directly
|
# This is a variation on `is_valid_indexed_attestation` that works directly
|
||||||
# with an attestation instead of first constructing an `IndexedAttestation`
|
# with an attestation instead of first constructing an `IndexedAttestation`
|
||||||
# and then validating it - for the purpose of validating the signature, the
|
# and then validating it - for the purpose of validating the signature, the
|
||||||
|
@ -642,6 +692,35 @@ proc is_valid_indexed_attestation(
|
||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
|
proc is_valid_indexed_attestation(
|
||||||
|
state: ForkyBeaconState,
|
||||||
|
attestation: electra.Attestation | electra.TrustedAttestation,
|
||||||
|
flags: UpdateFlags, cache: var StateCache): Result[void, cstring] =
|
||||||
|
# This is a variation on `is_valid_indexed_attestation` that works directly
|
||||||
|
# with an attestation instead of first constructing an `IndexedAttestation`
|
||||||
|
# and then validating it - for the purpose of validating the signature, the
|
||||||
|
# order doesn't matter and we can proceed straight to validating the
|
||||||
|
# signature instead
|
||||||
|
|
||||||
|
let sigs = attestation.aggregation_bits.countOnes()
|
||||||
|
if sigs == 0:
|
||||||
|
return err("is_valid_indexed_attestation: no attesting indices")
|
||||||
|
|
||||||
|
# Verify aggregate signature
|
||||||
|
if not (skipBlsValidation in flags or attestation.signature is TrustedSig):
|
||||||
|
var
|
||||||
|
pubkeys = newSeqOfCap[ValidatorPubKey](sigs)
|
||||||
|
for index in get_attesting_indices_iter(
|
||||||
|
state, attestation.data, attestation.aggregation_bits, attestation.committee_bits, cache):
|
||||||
|
pubkeys.add(state.validators[index].pubkey)
|
||||||
|
|
||||||
|
if not verify_attestation_signature(
|
||||||
|
state.fork, state.genesis_validators_root, attestation.data,
|
||||||
|
pubkeys, attestation.signature):
|
||||||
|
return err("indexed attestation: signature verification failure")
|
||||||
|
|
||||||
|
ok()
|
||||||
|
|
||||||
# Attestation validation
|
# Attestation validation
|
||||||
# ------------------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------------------
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#attestations
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#attestations
|
||||||
|
@ -839,11 +918,46 @@ proc check_attestation*(
|
||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
debugRaiseAssert "implement check_attestation for Electra attestations"
|
|
||||||
|
|
||||||
proc check_attestation*(
|
proc check_attestation*(
|
||||||
state: ForkyBeaconState, attestation: electra.Attestation | electra.TrustedAttestation, flags: UpdateFlags,
|
state: electra.BeaconState,
|
||||||
cache: var StateCache): Result[void, cstring] =
|
attestation: electra.Attestation | electra.TrustedAttestation,
|
||||||
|
flags: UpdateFlags, cache: var StateCache): Result[void, cstring] =
|
||||||
|
## Check that an attestation follows the rules of being included in the state
|
||||||
|
## at the current slot. When acting as a proposer, the same rules need to
|
||||||
|
## be followed!
|
||||||
|
|
||||||
|
let
|
||||||
|
data = attestation.data
|
||||||
|
epoch = ? check_attestation_target_epoch(data, state.get_current_epoch())
|
||||||
|
slot = ? check_attestation_slot_target(data)
|
||||||
|
|
||||||
|
? check_attestation_inclusion((typeof state).kind, slot, state.slot)
|
||||||
|
|
||||||
|
# [Modified in Electra:EIP7549]
|
||||||
|
if not (data.index == 0):
|
||||||
|
return err("Electra attestation data index not 0")
|
||||||
|
|
||||||
|
var participants_count = 0
|
||||||
|
debugRaiseAssert "cache doesn't know about forks"
|
||||||
|
for index in attestation.committee_bits.oneIndices:
|
||||||
|
if not (index.uint64 < get_committee_count_per_slot(
|
||||||
|
state, data.target.epoch, cache)):
|
||||||
|
return err("foo")
|
||||||
|
let committee = get_beacon_committee(state, data.slot, index.CommitteeIndex, cache)
|
||||||
|
participants_count += len(committee)
|
||||||
|
|
||||||
|
if not (len(attestation.aggregation_bits) == participants_count):
|
||||||
|
return err("")
|
||||||
|
|
||||||
|
if epoch == get_current_epoch(state):
|
||||||
|
if not (data.source == state.current_justified_checkpoint):
|
||||||
|
return err("FFG data not matching current justified epoch")
|
||||||
|
else:
|
||||||
|
if not (data.source == state.previous_justified_checkpoint):
|
||||||
|
return err("FFG data not matching previous justified epoch")
|
||||||
|
|
||||||
|
? is_valid_indexed_attestation(state, attestation, flags, cache)
|
||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#new-process_bls_to_execution_change
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#new-process_bls_to_execution_change
|
||||||
|
@ -908,8 +1022,25 @@ func get_proposer_reward*(
|
||||||
base_reward_per_increment: Gwei,
|
base_reward_per_increment: Gwei,
|
||||||
cache: var StateCache,
|
cache: var StateCache,
|
||||||
epoch_participation: var EpochParticipationFlags): Gwei =
|
epoch_participation: var EpochParticipationFlags): Gwei =
|
||||||
debugRaiseAssert "implement get_proposal_reward for Electra attestations"
|
let participation_flag_indices = get_attestation_participation_flag_indices(
|
||||||
0.Gwei
|
state, attestation.data, state.slot - attestation.data.slot)
|
||||||
|
for index in get_attesting_indices_iter(
|
||||||
|
state, attestation.data, attestation.aggregation_bits, attestation.committee_bits, cache):
|
||||||
|
let
|
||||||
|
base_reward = get_base_reward(state, index, base_reward_per_increment)
|
||||||
|
for flag_index, weight in PARTICIPATION_FLAG_WEIGHTS:
|
||||||
|
if flag_index in participation_flag_indices and
|
||||||
|
not has_flag(epoch_participation.item(index), flag_index):
|
||||||
|
asList(epoch_participation)[index] =
|
||||||
|
add_flag(epoch_participation.item(index), flag_index)
|
||||||
|
# these are all valid; TODO statically verify or do it type-safely
|
||||||
|
result += base_reward * weight.uint64
|
||||||
|
|
||||||
|
let proposer_reward_denominator =
|
||||||
|
(WEIGHT_DENOMINATOR.uint64 - PROPOSER_WEIGHT.uint64) *
|
||||||
|
WEIGHT_DENOMINATOR.uint64 div PROPOSER_WEIGHT.uint64
|
||||||
|
|
||||||
|
result div proposer_reward_denominator
|
||||||
|
|
||||||
proc process_attestation*(
|
proc process_attestation*(
|
||||||
state: var ForkyBeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
state: var ForkyBeaconState, attestation: SomeAttestation, flags: UpdateFlags,
|
||||||
|
@ -969,8 +1100,25 @@ proc process_attestation*(
|
||||||
attestation: electra.Attestation | electra.TrustedAttestation,
|
attestation: electra.Attestation | electra.TrustedAttestation,
|
||||||
flags: UpdateFlags, base_reward_per_increment: Gwei,
|
flags: UpdateFlags, base_reward_per_increment: Gwei,
|
||||||
cache: var StateCache): Result[Gwei, cstring] =
|
cache: var StateCache): Result[Gwei, cstring] =
|
||||||
debugRaiseAssert "electra process_attestation"
|
? check_attestation(state, attestation, flags, cache)
|
||||||
ok(0.Gwei)
|
|
||||||
|
let proposer_index = get_beacon_proposer_index(state, cache).valueOr:
|
||||||
|
return err("process_attestation: no beacon proposer index and probably no active validators")
|
||||||
|
|
||||||
|
template updateParticipationFlags(epoch_participation: untyped): Gwei =
|
||||||
|
let proposer_reward = get_proposer_reward(
|
||||||
|
state, attestation, base_reward_per_increment, cache, epoch_participation)
|
||||||
|
increase_balance(state, proposer_index, proposer_reward)
|
||||||
|
proposer_reward
|
||||||
|
|
||||||
|
doAssert base_reward_per_increment > 0.Gwei
|
||||||
|
let proposer_reward =
|
||||||
|
if attestation.data.target.epoch == get_current_epoch(state):
|
||||||
|
updateParticipationFlags(state.current_epoch_participation)
|
||||||
|
else:
|
||||||
|
updateParticipationFlags(state.previous_epoch_participation)
|
||||||
|
|
||||||
|
ok(proposer_reward)
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_next_sync_committee_indices
|
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/altair/beacon-chain.md#get_next_sync_committee_indices
|
||||||
func get_next_sync_committee_keys(
|
func get_next_sync_committee_keys(
|
||||||
|
|
|
@ -592,7 +592,7 @@ type
|
||||||
Attestation* = object
|
Attestation* = object
|
||||||
aggregation_bits*: ElectraCommitteeValidatorsBits
|
aggregation_bits*: ElectraCommitteeValidatorsBits
|
||||||
data*: AttestationData
|
data*: AttestationData
|
||||||
commiteee_bits*: BitArray[static(MAX_COMMITTEES_PER_SLOT.int)] # [New in Electra:EIP7549]
|
committee_bits*: BitArray[static(MAX_COMMITTEES_PER_SLOT.int)] # [New in Electra:EIP7549]
|
||||||
signature*: ValidatorSig
|
signature*: ValidatorSig
|
||||||
|
|
||||||
TrustedAttestation* = object
|
TrustedAttestation* = object
|
||||||
|
@ -601,7 +601,7 @@ type
|
||||||
# Currently the code MUST verify the state transition as soon as the signature is verified
|
# Currently the code MUST verify the state transition as soon as the signature is verified
|
||||||
aggregation_bits*: ElectraCommitteeValidatorsBits
|
aggregation_bits*: ElectraCommitteeValidatorsBits
|
||||||
data*: AttestationData
|
data*: AttestationData
|
||||||
commiteee_bits*: BitArray[static(MAX_COMMITTEES_PER_SLOT.int)] # [New in Electra:EIP7549]
|
committee_bits*: BitArray[static(MAX_COMMITTEES_PER_SLOT.int)] # [New in Electra:EIP7549]
|
||||||
signature*: TrustedSig
|
signature*: TrustedSig
|
||||||
|
|
||||||
SomeSignedBeaconBlock* =
|
SomeSignedBeaconBlock* =
|
||||||
|
|
|
@ -368,11 +368,20 @@ proc collectSignatureSets*(
|
||||||
# fixed in 1.4.2
|
# fixed in 1.4.2
|
||||||
template attestation: untyped = signed_block.message.body.attestations[i]
|
template attestation: untyped = signed_block.message.body.attestations[i]
|
||||||
|
|
||||||
|
when typeof(signed_block).kind < ConsensusFork.Electra:
|
||||||
|
let
|
||||||
|
key = ? aggregateAttesters(
|
||||||
|
get_attesting_indices(
|
||||||
|
state, attestation.data, attestation.aggregation_bits, cache),
|
||||||
|
validatorKeys)
|
||||||
|
else:
|
||||||
|
let
|
||||||
|
key = ? aggregateAttesters(
|
||||||
|
get_attesting_indices(
|
||||||
|
state, attestation.data, attestation.aggregation_bits,
|
||||||
|
attestation.committee_bits, cache),
|
||||||
|
validatorKeys)
|
||||||
let
|
let
|
||||||
key = ? aggregateAttesters(
|
|
||||||
get_attesting_indices(
|
|
||||||
state, attestation.data, attestation.aggregation_bits, cache),
|
|
||||||
validatorKeys)
|
|
||||||
sig = attestation.signature.load().valueOr:
|
sig = attestation.signature.load().valueOr:
|
||||||
return err("Invalid attestation signature")
|
return err("Invalid attestation signature")
|
||||||
|
|
||||||
|
|
|
@ -394,10 +394,18 @@ func collectFromAttestations(
|
||||||
rewardsAndPenalties[forkyBlck.message.proposer_index]
|
rewardsAndPenalties[forkyBlck.message.proposer_index]
|
||||||
.proposer_outcome += proposerReward.int64
|
.proposer_outcome += proposerReward.int64
|
||||||
let inclusionDelay = forkyState.data.slot - attestation.data.slot
|
let inclusionDelay = forkyState.data.slot - attestation.data.slot
|
||||||
for index in get_attesting_indices(
|
when consensusFork >= ConsensusFork.Electra:
|
||||||
forkyState.data, attestation.data, attestation.aggregation_bits,
|
for index in get_attesting_indices(
|
||||||
cache):
|
forkyState.data, attestation.data, attestation.aggregation_bits,
|
||||||
rewardsAndPenalties[index].inclusion_delay = some(inclusionDelay.uint64)
|
attestation.committee_bits, cache):
|
||||||
|
rewardsAndPenalties[index].inclusion_delay =
|
||||||
|
some(inclusionDelay.uint64)
|
||||||
|
else:
|
||||||
|
for index in get_attesting_indices(
|
||||||
|
forkyState.data, attestation.data, attestation.aggregation_bits,
|
||||||
|
cache):
|
||||||
|
rewardsAndPenalties[index].inclusion_delay =
|
||||||
|
some(inclusionDelay.uint64)
|
||||||
|
|
||||||
proc collectFromDeposits(
|
proc collectFromDeposits(
|
||||||
rewardsAndPenalties: var seq[RewardsAndPenalties],
|
rewardsAndPenalties: var seq[RewardsAndPenalties],
|
||||||
|
|
|
@ -82,28 +82,26 @@ proc runTest[T, U](
|
||||||
else:
|
else:
|
||||||
check: done.isErr() # No post state = processing should fail
|
check: done.isErr() # No post state = processing should fail
|
||||||
|
|
||||||
when false:
|
suite baseDescription & "Attestation " & preset():
|
||||||
debugRaiseAssert "when these are fixed..."
|
proc applyAttestation(
|
||||||
suite baseDescription & "Attestation " & preset():
|
preState: var electra.BeaconState, attestation: electra.Attestation):
|
||||||
func applyAttestation(
|
Result[void, cstring] =
|
||||||
preState: var electra.BeaconState, attestation: Attestation):
|
var cache: StateCache
|
||||||
Result[void, cstring] =
|
let
|
||||||
var cache: StateCache
|
total_active_balance = get_total_active_balance(preState, cache)
|
||||||
let
|
base_reward_per_increment =
|
||||||
total_active_balance = get_total_active_balance(preState, cache)
|
get_base_reward_per_increment(total_active_balance)
|
||||||
base_reward_per_increment =
|
|
||||||
get_base_reward_per_increment(total_active_balance)
|
|
||||||
|
|
||||||
# This returns the proposer reward for including the attestation, which
|
# This returns the proposer reward for including the attestation, which
|
||||||
# isn't tested here.
|
# isn't tested here.
|
||||||
discard ? process_attestation(
|
discard ? process_attestation(
|
||||||
preState, attestation, {strictVerification}, base_reward_per_increment, cache)
|
preState, attestation, {strictVerification}, base_reward_per_increment, cache)
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
for path in walkTests(OpAttestationsDir):
|
for path in walkTests(OpAttestationsDir):
|
||||||
runTest[Attestation, typeof applyAttestation](
|
runTest[electra.Attestation, typeof applyAttestation](
|
||||||
OpAttestationsDir, suiteName, "Attestation", "attestation",
|
OpAttestationsDir, suiteName, "Attestation", "attestation",
|
||||||
applyAttestation, path)
|
applyAttestation, path)
|
||||||
|
|
||||||
suite baseDescription & "Attester Slashing " & preset():
|
suite baseDescription & "Attester Slashing " & preset():
|
||||||
proc applyAttesterSlashing(
|
proc applyAttesterSlashing(
|
||||||
|
|
Loading…
Reference in New Issue