From 0b95012c2ece8f12436727b4a2c0beb0c024cb4f Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Mon, 26 Aug 2024 15:54:59 +0200 Subject: [PATCH 1/6] Separate type for unaggregated network attestations As a complement to https://github.com/ethereum/consensus-specs/pull/3787, this PR introduces a `SingleAttestation` type used for network propagation only. In Electra, the on-chain attestation format introduced in [EIP-7549](https://github.com/ethereum/consensus-specs/pull/3559) presents several difficulties - not only are the new fields to be interpreted differently during network processing and onchain which adds complexity in clients, they also introduce inefficiency both in hash computation and bandwidth. The new type puts the validator and committee indices directly in the attestation type, this simplifying processing and increasing security. * placing the validator index directly in the attestation allows verifying the signature without computing a shuffling - this closes a loophole where clients either must drop attestations or risk being overwhelmed by shuffling computations during attestation verification * the simpler "structure" of the attestation saves several hash calls during processing (a single-item List has significant hashing overhead compared to a field) * we save a few bytes here and there - we can also put stricter bounds on message size on the attestation topic because `SingleAttestation` is now fixed-size * the ambiguity of interpreting the `attestation_bits` list indices which became contextual under EIP-7549 is removed Because this change only affects the network encoding (and not block contents), the implementation impact on clients should be minimal. --- specs/electra/beacon-chain.md | 14 +++++++++++++- specs/electra/p2p-interface.md | 5 +++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index cb5ee6a7a9..6a79a7012a 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -30,6 +30,7 @@ - [`WithdrawalRequest`](#withdrawalrequest) - [`ConsolidationRequest`](#consolidationrequest) - [`PendingConsolidation`](#pendingconsolidation) + - [`SingleAttestation`](#singleattestation) - [Modified Containers](#modified-containers) - [`AttesterSlashing`](#attesterslashing) - [Extended Containers](#extended-containers) @@ -258,6 +259,17 @@ class PendingConsolidation(Container): target_index: ValidatorIndex ``` + +#### `SingleAttestation` + +```python +class SingleAttestation(Container): + committee_index: CommitteeIndex + attester_index: ValidatorIndex + data: AttestationData + signature: BLSSignature +``` + ### Modified Containers #### `AttesterSlashing` @@ -875,7 +887,7 @@ def process_pending_balance_deposits(state: BeaconState) -> None: if processed_amount + deposit.amount > available_for_processing: break # Deposit fits in the churn, process it. Increase balance and consume churn. - else: + else: increase_balance(state, deposit.index, deposit.amount) processed_amount += deposit.amount # Regardless of how the deposit was handled, we move on in the queue. diff --git a/specs/electra/p2p-interface.md b/specs/electra/p2p-interface.md index 88d14813b3..aa6ed3789d 100644 --- a/specs/electra/p2p-interface.md +++ b/specs/electra/p2p-interface.md @@ -54,9 +54,10 @@ The following validations are added: ##### `beacon_attestation_{subnet_id}` +The topic is updated to propagate `SingleAttestation` objects. + The following convenience variables are re-defined -- `index = get_committee_indices(attestation.committee_bits)[0]` +- `index = attestation.committee_index` The following validations are added: -* [REJECT] `len(committee_indices) == 1`, where `committee_indices = get_committee_indices(attestation)`. * [REJECT] `attestation.data.index == 0` From 5761fb4d974b794d6d6dc0a0f82c3dff95ad618d Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Wed, 28 Aug 2024 07:31:49 +0200 Subject: [PATCH 2/6] update list of checks --- specs/electra/p2p-interface.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/specs/electra/p2p-interface.md b/specs/electra/p2p-interface.md index aa6ed3789d..9e4eff0a99 100644 --- a/specs/electra/p2p-interface.md +++ b/specs/electra/p2p-interface.md @@ -56,8 +56,16 @@ The following validations are added: The topic is updated to propagate `SingleAttestation` objects. -The following convenience variables are re-defined +The following convenience variables are re-defined: - `index = attestation.committee_index` The following validations are added: -* [REJECT] `attestation.data.index == 0` +- _[REJECT]_ `attestation.data.index == 0` +- _[REJECT]_ The attester is a member of the committtee -- i.e. + `atestation.attester_index in get_beacon_committee(state, attestation.data.slot, index)`. + +The following validations are removed: +- _[REJECT]_ The attestation is unaggregated -- + that is, it has exactly one participating validator (`len([bit for bit in aggregation_bits if bit]) == 1`, i.e. exactly 1 bit is set). +- _[REJECT]_ The number of aggregation bits matches the committee size -- i.e. + `len(aggregation_bits) == len(get_beacon_committee(state, attestation.data.slot, index))`. From 0833551328dc94e6f55f514c806291bb99743e6a Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Wed, 28 Aug 2024 07:35:12 +0200 Subject: [PATCH 3/6] spelling --- specs/electra/p2p-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/electra/p2p-interface.md b/specs/electra/p2p-interface.md index 9e4eff0a99..b8370c77f8 100644 --- a/specs/electra/p2p-interface.md +++ b/specs/electra/p2p-interface.md @@ -61,7 +61,7 @@ The following convenience variables are re-defined: The following validations are added: - _[REJECT]_ `attestation.data.index == 0` -- _[REJECT]_ The attester is a member of the committtee -- i.e. +- _[REJECT]_ The attester is a member of the committee -- i.e. `atestation.attester_index in get_beacon_committee(state, attestation.data.slot, index)`. The following validations are removed: From 1c529a858c13cccae60b69b3f35c14b02b214c69 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Fri, 20 Sep 2024 09:25:35 +0200 Subject: [PATCH 4/6] use SingleAttestation in honest validator spec --- specs/electra/validator.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/specs/electra/validator.md b/specs/electra/validator.md index f589e963c5..c27f02b9d1 100644 --- a/specs/electra/validator.md +++ b/specs/electra/validator.md @@ -152,11 +152,12 @@ def prepare_execution_payload(state: BeaconState, ### Construct attestation -- Set `attestation_data.index = 0`. -- Let `attestation.aggregation_bits` be a `Bitlist[MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT]` of length `len(committee)`, where the bit of the index of the validator in the `committee` is set to `0b1`. -- Let `attestation.committee_bits` be a `Bitvector[MAX_COMMITTEES_PER_SLOT]`, where the bit at the index associated with the validator's committee is set to `0b1`. +The validator creates `attestation` as a `SingleAttestation` container +with updated field assignments: -*Note*: Calling `get_attesting_indices(state, attestation)` should return a list of length equal to 1, containing `validator_index`. +- Set `attestation_data.index = 0`. +- Set `attestation.committee_index` to the index associated with the validator's committee. +- Set `attestation.attester_index` to the index of the validator. ## Attestation aggregation @@ -164,4 +165,4 @@ def prepare_execution_payload(state: BeaconState, - 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 same value as in each individual attestation. +- Set `attestation.committee_bits = committee_bits`, where `committee_bits` has the bit set corresponding to `committee_index` in each individual attestation. From 768fb454b1236c26ddee472501a8746bbc8b6558 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Fri, 20 Sep 2024 09:30:55 +0200 Subject: [PATCH 5/6] merge cleanup --- specs/electra/beacon-chain.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specs/electra/beacon-chain.md b/specs/electra/beacon-chain.md index 84d6b2fce3..2029c70843 100644 --- a/specs/electra/beacon-chain.md +++ b/specs/electra/beacon-chain.md @@ -30,6 +30,7 @@ - [`ConsolidationRequest`](#consolidationrequest) - [`PendingConsolidation`](#pendingconsolidation) - [`SingleAttestation`](#singleattestation) + - [`ExecutionRequests`](#executionrequests) - [Modified Containers](#modified-containers) - [`AttesterSlashing`](#attesterslashing) - [`BeaconBlockBody`](#beaconblockbody) @@ -257,7 +258,6 @@ class PendingConsolidation(Container): target_index: ValidatorIndex ``` - #### `SingleAttestation` ```python @@ -266,6 +266,7 @@ class SingleAttestation(Container): attester_index: ValidatorIndex data: AttestationData signature: BLSSignature +``` #### `ExecutionRequests` From 96fbfcb3ac7f958e7e2326c060e8249bfce8bfaf Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Mon, 7 Oct 2024 09:00:19 +0200 Subject: [PATCH 6/6] Update specs/electra/p2p-interface.md Co-authored-by: NC <17676176+ensi321@users.noreply.github.com> --- specs/electra/p2p-interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/electra/p2p-interface.md b/specs/electra/p2p-interface.md index b8370c77f8..d5fc70cbc0 100644 --- a/specs/electra/p2p-interface.md +++ b/specs/electra/p2p-interface.md @@ -62,7 +62,7 @@ The following convenience variables are re-defined: The following validations are added: - _[REJECT]_ `attestation.data.index == 0` - _[REJECT]_ The attester is a member of the committee -- i.e. - `atestation.attester_index in get_beacon_committee(state, attestation.data.slot, index)`. + `attestation.attester_index in get_beacon_committee(state, attestation.data.slot, index)`. The following validations are removed: - _[REJECT]_ The attestation is unaggregated --