diff --git a/ConsensusSpecPreset-mainnet.md b/ConsensusSpecPreset-mainnet.md index 76ffe9cf0..9e9f46fad 100644 --- a/ConsensusSpecPreset-mainnet.md +++ b/ConsensusSpecPreset-mainnet.md @@ -2536,6 +2536,55 @@ OK: 5/5 Fail: 0/5 Skip: 0/5 + Slashings reset - flush_slashings [Preset: mainnet] OK ``` 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] ```diff + [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 ---TOTAL--- -OK: 2792/2811 Fail: 0/2811 Skip: 19/2811 +OK: 2837/2856 Fail: 0/2856 Skip: 19/2856 diff --git a/ConsensusSpecPreset-minimal.md b/ConsensusSpecPreset-minimal.md index 8cccfb456..de62f0f14 100644 --- a/ConsensusSpecPreset-minimal.md +++ b/ConsensusSpecPreset-minimal.md @@ -2663,6 +2663,55 @@ OK: 1/1 Fail: 0/1 Skip: 0/1 + Sync committee updates - sync_committees_progress_not_genesis [Preset: minimal] OK ``` 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] ```diff + [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 ---TOTAL--- -OK: 3063/3085 Fail: 0/3085 Skip: 22/3085 +OK: 3108/3130 Fail: 0/3130 Skip: 22/3130 diff --git a/beacon_chain/consensus_object_pools/spec_cache.nim b/beacon_chain/consensus_object_pools/spec_cache.nim index ed2d0cc08..4fbda9759 100644 --- a/beacon_chain/consensus_object_pools/spec_cache.nim +++ b/beacon_chain/consensus_object_pools/spec_cache.nim @@ -90,7 +90,7 @@ func compatible_with_shuffling*( iterator get_attesting_indices*(shufflingRef: ShufflingRef, slot: Slot, committee_index: CommitteeIndex, - bits: CommitteeValidatorsBits | ElectraCommitteeValidatorsBits): + bits: CommitteeValidatorsBits): ValidatorIndex = if not bits.compatible_with_shuffling(shufflingRef, slot, committee_index): trace "get_attesting_indices: inconsistent aggregation and committee length" @@ -100,6 +100,14 @@ iterator get_attesting_indices*(shufflingRef: ShufflingRef, if bits[index_in_committee]: 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*( dag: ChainDAGRef, attestation: phase0.TrustedAttestation | electra.TrustedAttestation): ValidatorIndex = block: # `return` is not allowed in an inline iterator diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 0782858f1..4082cb3b2 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -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 iterator get_attesting_indices_iter*(state: ForkyBeaconState, data: AttestationData, - bits: CommitteeValidatorsBits | ElectraCommitteeValidatorsBits, + bits: CommitteeValidatorsBits, cache: var StateCache): ValidatorIndex = ## Return the set of attesting indices corresponding to ``data`` and ``bits`` ## or nothing if `data` is invalid ## This iterator must not be called in functions using a ## 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) if committee_index.isErr() or bits.lenu64 != get_beacon_committee_len( state, data.slot, committee_index.get(), cache): @@ -591,19 +589,55 @@ iterator get_attesting_indices_iter*(state: ForkyBeaconState, if bits[index_in_committee]: 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 -func get_attesting_indices*(state: ForkyBeaconState, - data: AttestationData, - bits: CommitteeValidatorsBits | ElectraCommitteeValidatorsBits, - cache: var StateCache): seq[ValidatorIndex] = +func get_attesting_indices*( + state: ForkyBeaconState, data: AttestationData, + aggregation_bits: CommitteeValidatorsBits, 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, 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; data: AttestationData; - bits: CommitteeValidatorsBits | ElectraCommitteeValidatorsBits; + bits: CommitteeValidatorsBits; cache: var StateCache): seq[ValidatorIndex] = # TODO when https://github.com/nim-lang/Nim/issues/18188 fixed, use an # iterator @@ -614,9 +648,25 @@ func get_attesting_indices*(state: ForkedHashedBeaconState; idxBuf.add vidx 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( - state: ForkyBeaconState, attestation: SomeAttestation, flags: UpdateFlags, - cache: var StateCache): Result[void, cstring] = + state: ForkyBeaconState, + attestation: SomeAttestation, + 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 @@ -642,6 +692,35 @@ proc is_valid_indexed_attestation( 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 # ------------------------------------------------------------------------------------------ # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#attestations @@ -839,11 +918,46 @@ proc check_attestation*( ok() -debugRaiseAssert "implement check_attestation for Electra attestations" - proc check_attestation*( - state: ForkyBeaconState, attestation: electra.Attestation | electra.TrustedAttestation, flags: UpdateFlags, - cache: var StateCache): Result[void, cstring] = + state: electra.BeaconState, + 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() # 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, cache: var StateCache, epoch_participation: var EpochParticipationFlags): Gwei = - debugRaiseAssert "implement get_proposal_reward for Electra attestations" - 0.Gwei + let participation_flag_indices = get_attestation_participation_flag_indices( + 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*( state: var ForkyBeaconState, attestation: SomeAttestation, flags: UpdateFlags, @@ -969,8 +1100,25 @@ proc process_attestation*( attestation: electra.Attestation | electra.TrustedAttestation, flags: UpdateFlags, base_reward_per_increment: Gwei, cache: var StateCache): Result[Gwei, cstring] = - debugRaiseAssert "electra process_attestation" - ok(0.Gwei) + ? check_attestation(state, attestation, flags, cache) + + 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 func get_next_sync_committee_keys( diff --git a/beacon_chain/spec/datatypes/electra.nim b/beacon_chain/spec/datatypes/electra.nim index 76e098f2a..fa456a2c7 100644 --- a/beacon_chain/spec/datatypes/electra.nim +++ b/beacon_chain/spec/datatypes/electra.nim @@ -592,7 +592,7 @@ type Attestation* = object aggregation_bits*: ElectraCommitteeValidatorsBits 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 TrustedAttestation* = object @@ -601,7 +601,7 @@ type # Currently the code MUST verify the state transition as soon as the signature is verified aggregation_bits*: ElectraCommitteeValidatorsBits 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 SomeSignedBeaconBlock* = diff --git a/beacon_chain/spec/signatures_batch.nim b/beacon_chain/spec/signatures_batch.nim index a72ccb3cd..c4d4a64d6 100644 --- a/beacon_chain/spec/signatures_batch.nim +++ b/beacon_chain/spec/signatures_batch.nim @@ -368,11 +368,20 @@ proc collectSignatureSets*( # fixed in 1.4.2 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 - key = ? aggregateAttesters( - get_attesting_indices( - state, attestation.data, attestation.aggregation_bits, cache), - validatorKeys) sig = attestation.signature.load().valueOr: return err("Invalid attestation signature") diff --git a/ncli/ncli_common.nim b/ncli/ncli_common.nim index 5846d6044..21e63eefa 100644 --- a/ncli/ncli_common.nim +++ b/ncli/ncli_common.nim @@ -394,10 +394,18 @@ func collectFromAttestations( rewardsAndPenalties[forkyBlck.message.proposer_index] .proposer_outcome += proposerReward.int64 let inclusionDelay = forkyState.data.slot - attestation.data.slot - for index in get_attesting_indices( - forkyState.data, attestation.data, attestation.aggregation_bits, - cache): - rewardsAndPenalties[index].inclusion_delay = some(inclusionDelay.uint64) + when consensusFork >= ConsensusFork.Electra: + for index in get_attesting_indices( + forkyState.data, attestation.data, attestation.aggregation_bits, + 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( rewardsAndPenalties: var seq[RewardsAndPenalties], diff --git a/tests/consensus_spec/electra/test_fixture_operations.nim b/tests/consensus_spec/electra/test_fixture_operations.nim index a0674bddf..647fda969 100644 --- a/tests/consensus_spec/electra/test_fixture_operations.nim +++ b/tests/consensus_spec/electra/test_fixture_operations.nim @@ -82,28 +82,26 @@ proc runTest[T, U]( else: check: done.isErr() # No post state = processing should fail -when false: - debugRaiseAssert "when these are fixed..." - suite baseDescription & "Attestation " & preset(): - func applyAttestation( - preState: var electra.BeaconState, attestation: Attestation): - Result[void, cstring] = - var cache: StateCache - let - total_active_balance = get_total_active_balance(preState, cache) - base_reward_per_increment = - get_base_reward_per_increment(total_active_balance) +suite baseDescription & "Attestation " & preset(): + proc applyAttestation( + preState: var electra.BeaconState, attestation: electra.Attestation): + Result[void, cstring] = + var cache: StateCache + let + total_active_balance = get_total_active_balance(preState, cache) + base_reward_per_increment = + get_base_reward_per_increment(total_active_balance) - # This returns the proposer reward for including the attestation, which - # isn't tested here. - discard ? process_attestation( - preState, attestation, {strictVerification}, base_reward_per_increment, cache) - ok() + # This returns the proposer reward for including the attestation, which + # isn't tested here. + discard ? process_attestation( + preState, attestation, {strictVerification}, base_reward_per_increment, cache) + ok() - for path in walkTests(OpAttestationsDir): - runTest[Attestation, typeof applyAttestation]( - OpAttestationsDir, suiteName, "Attestation", "attestation", - applyAttestation, path) + for path in walkTests(OpAttestationsDir): + runTest[electra.Attestation, typeof applyAttestation]( + OpAttestationsDir, suiteName, "Attestation", "attestation", + applyAttestation, path) suite baseDescription & "Attester Slashing " & preset(): proc applyAttesterSlashing(