Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate type for onchain attestation aggregates #3787

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from

Conversation

mkalinin
Copy link
Collaborator

@mkalinin mkalinin commented Jun 4, 2024

Experimental PR outlining an idea of having a separate container for on chain attestation aggregates proposed by @arnetheduck during ACDC#134.

Change set:

  • New OnchainAttestation type to be used for aggregates included into a block with the corresponding process_onchain_attestation function used during the block processing; the old process_attestation is preserved for the purpose of gossip and attestation mempool
  • New compute_signing_attestation_data which is used to compute signing attestation data. The reason for that is to keep the logic around Attestation container that is still used in the network as is as far as it is possible. EIP7549 requires signing data to have committee index set to 0, and to retain the logic around non-zero index field inside of the Attestation this PR employs a trick when the index is zeroed for the purpose of signing.
    There is the corresponding change to the honest validator doc and aggregate signature verification. OnchainAttestation contains signing AttestationData (i.e. with index always set to 0). The old process_attestation function should switch to the modified is_valid_indexed_attestation (not explicit in this PR)
  • p2p changes related to the modification of the Attestation type are dropped as the type remain unmodified, except for the signature verification part

Other changes that aren’t scoped in this PR:

  • Attestation mempool will have to support Attestation and OnchainAttestation types, and use different validation functions for them which depending on the pool design might have different impact on the client implementation
  • Fork choice on_attestation handler will have to be appended with on_onchain_attestation to handle the on chain aggregate type

P.S. The above scope of changes might not be exhaustive.

@dapplion
Copy link
Collaborator

dapplion commented Jun 5, 2024

I had the impression that @arnetheduck main goal was to have a separate type (e.g. UnaggregatedAttestation) only used in the beacon_attestation topic. And leave Attestation as is for the rest of usages.

@arnetheduck
Copy link
Contributor

arnetheduck commented Jun 5, 2024

+1 for UnaggregatedAttestation (used on the single-voter attestation topic) - it holds a ValidatorIndex so we don't have to do CommitteeIndex -> ValidatorIndex conversion here - and also +1 for OnChainAttestation - meaning that we leave Attestation as-is (in previous versions) on the aggregate attestation gossip channel.

arnetheduck added a commit to status-im/eth2.0-specs that referenced this pull request Aug 26, 2024
As a complement to
ethereum#3787, this PR
introduces a `SingleAttestation` type used for network propagation only.

In Electra, the on-chain attestation format introduced in
[EIP-7549](ethereum#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.
@arnetheduck
Copy link
Contributor

Attestation mempool will have to support Attestation and OnchainAttestation types, and use different validation functions for them which depending on the pool design might have different impact on the client implementation

Nimbus at least uses custom types in the attestation pool - from a software design perspective, the implementation would be more clean with separate types since these are separate concerns and encodings - the types would prevent accidental leakage of network format into the chain parts by construction.

@tbenr
Copy link
Contributor

tbenr commented Sep 20, 2024

aggregation_bits: Bitlist[MAX_VALIDATORS_PER_COMMITTEE * MAX_COMMITTEES_PER_SLOT]
data: AttestationData
committee_bits: Bitvector[MAX_COMMITTEES_PER_SLOT]
signature: BLSSignature
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to be consistent with the current Attestation by having committee_bits to be after the signature field

@@ -91,7 +89,7 @@ def compute_on_chain_aggregate(network_aggregates: Sequence[Attestation]) -> Att
committee_flags = [(index in committee_indices) for index in range(0, MAX_COMMITTEES_PER_SLOT)]
committee_bits = Bitvector[MAX_COMMITTEES_PER_SLOT](committee_flags)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

committee_bits is computed from Attestation.committee_bits. If that's true should we drop the checks in p2p-interface.md?

##### `beacon_aggregate_and_proof`

The following convenience variables are re-defined
- `index = get_committee_indices(aggregate.committee_bits)[0]`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

committee_bits is still used in compute_on_chain_aggregate below


The following validations are added:
* [REJECT] `len(committee_indices) == 1`, where `committee_indices = get_committee_indices(attestation)`.
* [REJECT] `attestation.data.index == 0`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the key thing of EIP-7549 is to have data.index = 0 so we should not remove this? same to above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants