diff --git a/beacon_chain/consensus_object_pools/spec_cache.nim b/beacon_chain/consensus_object_pools/spec_cache.nim index 5abffd6ca..b64ca9de1 100644 --- a/beacon_chain/consensus_object_pools/spec_cache.nim +++ b/beacon_chain/consensus_object_pools/spec_cache.nim @@ -260,9 +260,9 @@ func get_attesting_indices*(shufflingRef: ShufflingRef, slot: Slot, committee_index: CommitteeIndex, bits: ElectraCommitteeValidatorsBits, - on_chain: static bool): + on_chain: static bool = true): seq[ValidatorIndex] = - static: doAssert not on_chain, "only on_chain supported" + static: doAssert on_chain, "only on_chain supported" for idx in get_attesting_indices(shufflingRef, slot, committee_index, bits): result.add(idx) diff --git a/beacon_chain/gossip_processing/batch_validation.nim b/beacon_chain/gossip_processing/batch_validation.nim index 56be23d95..ae011ad37 100644 --- a/beacon_chain/gossip_processing/batch_validation.nim +++ b/beacon_chain/gossip_processing/batch_validation.nim @@ -419,8 +419,9 @@ proc scheduleAttestationCheck*( proc scheduleAggregateChecks*( batchCrypto: ref BatchCrypto, fork: Fork, - signedAggregateAndProof: phase0.SignedAggregateAndProof, dag: ChainDAGRef, - attesting_indices: openArray[ValidatorIndex] + signedAggregateAndProof: + phase0.SignedAggregateAndProof | electra.SignedAggregateAndProof, + dag: ChainDAGRef, attesting_indices: openArray[ValidatorIndex] ): Result[tuple[ aggregatorFut, slotFut, aggregateFut: FutureBatchResult, sig: CookedSig], cstring] = diff --git a/beacon_chain/gossip_processing/gossip_validation.nim b/beacon_chain/gossip_processing/gossip_validation.nim index 33d18789f..f4309bce9 100644 --- a/beacon_chain/gossip_processing/gossip_validation.nim +++ b/beacon_chain/gossip_processing/gossip_validation.nim @@ -1082,11 +1082,10 @@ proc validateAttestation*( # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.1/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/deneb/p2p-interface.md#beacon_aggregate_and_proof proc validateAggregate*( - pool: ref AttestationPool, - batchCrypto: ref BatchCrypto, - signedAggregateAndProof: phase0.SignedAggregateAndProof, - wallTime: BeaconTime, - checkSignature = true, checkCover = true): + pool: ref AttestationPool, batchCrypto: ref BatchCrypto, + signedAggregateAndProof: + phase0.SignedAggregateAndProof | electra.SignedAggregateAndProof, + wallTime: BeaconTime, checkSignature = true, checkCover = true): Future[Result[ tuple[attestingIndices: seq[ValidatorIndex], sig: CookedSig], ValidationError]] {.async: (raises: [CancelledError]).} = @@ -1293,104 +1292,6 @@ proc validateAggregate*( return ok((attesting_indices, sig)) -# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.10/specs/electra/p2p-interface.md#beacon_aggregate_and_proof -proc validateAggregate*( - pool: ref AttestationPool, - batchCrypto: ref BatchCrypto, - signedAggregateAndProof: electra.SignedAggregateAndProof, - wallTime: BeaconTime, - checkSignature = true, checkCover = true): - Future[Result[ - tuple[attestingIndices: seq[ValidatorIndex], sig: CookedSig], - ValidationError]] {.async: (raises: [CancelledError]).} = - template aggregate_and_proof: untyped = signedAggregateAndProof.message - template aggregate: untyped = aggregate_and_proof.aggregate - - # [REJECT] The aggregate attestation's epoch matches its target -- i.e. - # `aggregate.data.target.epoch == compute_epoch_at_slot(aggregate.data.slot)` - let slot = block: - let v = check_attestation_slot_target(aggregate.data) - if v.isErr(): - return pool.checkedReject(v.error) - v.get() - - # [IGNORE] aggregate.data.slot is within the last - # ATTESTATION_PROPAGATION_SLOT_RANGE slots (with a - # MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance) -- i.e. aggregate.data.slot + - # ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= aggregate.data.slot - # - # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.2/specs/deneb/p2p-interface.md#beacon_aggregate_and_proof - # modifies this for Deneb and newer forks. - block: - let v = check_propagation_slot_range( - pool.dag.cfg.consensusForkAtEpoch(wallTime.slotOrZero.epoch), slot, - wallTime) - if v.isErr(): # [IGNORE] - return err(v.error()) - - # [IGNORE] The aggregate is the first valid aggregate received for the - # aggregator with index aggregate_and_proof.aggregator_index for the epoch - # aggregate.data.target.epoch. - # Slightly modified to allow only newer attestations than were previously - # seen (no point in propagating older votes) - if (pool.nextAttestationEpoch.lenu64 > - aggregate_and_proof.aggregator_index) and - pool.nextAttestationEpoch[ - aggregate_and_proof.aggregator_index].aggregate > - aggregate.data.target.epoch: - return errIgnore("Aggregate: validator has already aggregated in epoch") - - # [REJECT] The attestation has participants -- that is, - # len(get_attesting_indices(state, aggregate.data, aggregate.aggregation_bits)) >= 1. - # - # get_attesting_indices() is: - # committee = get_beacon_committee(state, data.slot, data.index) - # return set(index for i, index in enumerate(committee) if bits[i]) - # - # the attestation doesn't have participants is iff either: - # (1) the aggregation bits are all 0; or - # (2) the non-zero aggregation bits don't overlap with extant committee - # members, i.e. they counts don't match. - # But (2) would reflect an invalid aggregation in other ways, so reject it - # either way. - block: - let v = check_aggregation_count(aggregate, singular = false) - if v.isErr(): # [REJECT] - return pool.checkedReject(v.error) - - # [REJECT] The block being voted for (aggregate.data.beacon_block_root) - # passes validation. - # [IGNORE] if block is unseen so far and enqueue it in missing blocks - let target = block: - let v = check_beacon_and_target_block(pool[], aggregate.data) - if v.isErr(): # [IGNORE/REJECT] - return pool.checkedResult(v.error) - v.get() - - let shufflingRef = - pool.dag.getShufflingRef(target.blck, target.slot.epoch, false).valueOr: - # Target is verified - shouldn't happen - warn "No shuffling for attestation - report bug", - aggregate = shortLog(aggregate), target = shortLog(target) - return errIgnore("Aggregate: no shuffling") - - # [REJECT] The committee index is within the expected range -- i.e. - # data.index < get_committee_count_per_slot(state, data.target.epoch). - let committee_index = block: - let idx = shufflingRef.get_committee_index(aggregate.data.index) - if idx.isErr(): - return pool.checkedReject( - "Attestation: committee index not within expected range") - idx.get() - let - attesting_indices = get_attesting_indices( - shufflingRef, slot, committee_index, aggregate.aggregation_bits, false) - sig = - aggregate.signature.load().valueOr: - return pool.checkedReject("Aggregate: unable to load signature") - - ok((attesting_indices, sig)) - # https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.9/specs/capella/p2p-interface.md#bls_to_execution_change proc validateBlsToExecutionChange*( pool: ValidatorChangePool, batchCrypto: ref BatchCrypto, diff --git a/beacon_chain/spec/signatures_batch.nim b/beacon_chain/spec/signatures_batch.nim index a298f98df..d8f9653e5 100644 --- a/beacon_chain/spec/signatures_batch.nim +++ b/beacon_chain/spec/signatures_batch.nim @@ -162,7 +162,7 @@ func block_signature_set*( # See also: verify_aggregate_and_proof_signature func aggregate_and_proof_signature_set*( fork: Fork, genesis_validators_root: Eth2Digest, - aggregate_and_proof: phase0.AggregateAndProof, + aggregate_and_proof: phase0.AggregateAndProof | electra.AggregateAndProof, pubkey: CookedPubKey, signature: CookedSig): SignatureSet = let signing_root = compute_aggregate_and_proof_signing_root( fork, genesis_validators_root, aggregate_and_proof)