diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index c366b9c3f9..f415b779aa 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -34,6 +34,7 @@ - [`ConsolidationRequest`](#consolidationrequest) - [`ExecutionRequests`](#executionrequests) - [`SingleAttestation`](#singleattestation) + - [`CommitteeAttestation`](#committeeattestation) - [Modified Containers](#modified-containers) - [`AttesterSlashing`](#attesterslashing) - [`BeaconBlockBody`](#beaconblockbody) @@ -288,8 +289,6 @@ class ConsolidationRequest(Container): target_pubkey: BLSPubkey ``` -#### `ExecutionRequests` - *Note*: This container holds requests from the execution layer that are received in [ `ExecutionPayloadV4`](https://github.com/ethereum/execution-apis/blob/main/src/engine/prague.md#executionpayloadv4) via the Engine API. These requests are required for CL state transition (see `BeaconBlockBody`). @@ -311,6 +310,16 @@ class SingleAttestation(Container): signature: BLSSignature ``` +#### `CommitteeAttestation` + +```python +class CommitteeAttestation(Container): + aggregation_bits: Bitlist[MAX_VALIDATORS_PER_COMMITTEE] + data: AttestationData + committee_index: CommitteeIndex + signature: BLSSignature +``` + ### Modified Containers #### `AttesterSlashing` diff --git a/specs/electra/p2p-interface.md b/specs/electra/p2p-interface.md index d0663943f1..2f59a70bdf 100644 --- a/specs/electra/p2p-interface.md +++ b/specs/electra/p2p-interface.md @@ -72,10 +72,9 @@ The derivation of the `message-id` remains stable. ###### `beacon_aggregate_and_proof` The following convenience variables are re-defined -- `index = get_committee_indices(aggregate.committee_bits)[0]` +- `index = aggregate.committee_index` The following validations are added: -* [REJECT] `len(committee_indices) == 1`, where `committee_indices = get_committee_indices(aggregate)`. * [REJECT] `aggregate.data.index == 0` ###### `blob_sidecar_{subnet_id}` diff --git a/specs/electra/validator.md b/specs/electra/validator.md index 3620c30790..da0cb6a891 100644 --- a/specs/electra/validator.md +++ b/specs/electra/validator.md @@ -30,6 +30,7 @@ - [Construct attestation](#construct-attestation) - [Attestation aggregation](#attestation-aggregation) - [Construct aggregate](#construct-aggregate) + - [Broadcast aggregate](#broadcast-aggregate) @@ -68,7 +69,7 @@ class GetPayloadResponse(object): ```python class AggregateAndProof(Container): aggregator_index: ValidatorIndex - aggregate: Attestation # [Modified in Electra:EIP7549] + aggregate: CommitteeAttestation # [Modified in Electra:EIP7549] selection_proof: BLSSignature ``` @@ -111,14 +112,14 @@ Changed the max attester slashings size to `MAX_ATTESTER_SLASHINGS_ELECTRA`. Changed the max attestations size to `MAX_ATTESTATIONS_ELECTRA`. The network attestation aggregates contain only the assigned committee attestations. -Attestation aggregates received by the block proposer from the committee aggregators with disjoint `committee_bits` sets and equal `AttestationData` SHOULD be consolidated into a single `Attestation` object. -The proposer should run the following function to construct an on chain final aggregate form a list of network aggregates with equal `AttestationData`: +Committee attestations received by the block proposer from the committee aggregators with different `committee_index` sets and equal `AttestationData` SHOULD be consolidated into a single `Attestation` object. +The proposer should run the following function to construct an on-chain final aggregate from a list of committee attestations with equal `AttestationData`: ```python -def compute_on_chain_aggregate(network_aggregates: Sequence[Attestation]) -> Attestation: - aggregates = sorted(network_aggregates, key=lambda a: get_committee_indices(a.committee_bits)[0]) +def compute_on_chain_aggregate(committee_attestations: Sequence[CommitteeAttestation]) -> Attestation: + attestations = sorted(committee_attestations, key=lambda a: a.committee_index) - data = aggregates[0].data + data = attestations[0].data aggregation_bits = Bitlist[MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT]() for a in aggregates: for b in a.aggregation_bits: @@ -126,7 +127,7 @@ def compute_on_chain_aggregate(network_aggregates: Sequence[Attestation]) -> Att signature = bls.Aggregate([a.signature for a in aggregates]) - committee_indices = [get_committee_indices(a.committee_bits)[0] for a in aggregates] + committee_indices = [a.committee_index for a in aggregates] committee_flags = [(index in committee_indices) for index in range(0, MAX_COMMITTEES_PER_SLOT)] committee_bits = Bitvector[MAX_COMMITTEES_PER_SLOT](committee_flags) @@ -270,4 +271,4 @@ with updated field assignments: - Set `attestation_data.index = 0`. - Let `aggregation_bits` be a `Bitlist[MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT]` of length `len(committee)`, where each bit set from each individual attestation is set to `0b1`. -- Set `attestation.committee_bits = committee_bits`, where `committee_bits` has the bit set corresponding to `committee_index` in each individual attestation. +- Set `attestation.committee_index` to the index associated with the validator's committee. \ No newline at end of file