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

Electra: Attestation, Aggregation and Proposal Alignment #511

Merged
merged 50 commits into from
Feb 16, 2025

Conversation

MatheusFranco99
Copy link
Contributor

@MatheusFranco99 MatheusFranco99 commented Nov 16, 2024

Overview

This PR aligns the construction of attestations, aggregations and proposals to the latest changes by the electra fork.

Proposal

Since a versioned data was already fetched and submitted to the beacon node, it was only necessary to accept the Electra version in the ValidatorConsensusData validation.

Attestation

The changes follow the ethereum electra spec for constructing attestations.

  • Starts using the spec.VersionedAttestation type as the output of the attestation duty. For DataVersionElectra, it represents a electra.Attestation object. For previous versions, it represents a phase0.Attestation.
  • For creating the input for consensus, the CommitteeRunner still fetches a phase0.AttestationData type since it remains unchanged and is sufficient for constructing the BeaconVote. However, when being constructed after electra, the Index field that identifies the committee is set to 0 (EIP-7549).

Note

The Ethereum specification states that, under electra, a electra.SingleAttestation object should be returned. However, the CommitteeRunner outputs a spec.VersionedAttestation to the BeaconNode as this is the type specified in the go-eth2-client library. Internally, the library transforms the versioned object into a electra.SingleAttestation later on.

Note

The CommitteeRunner will keep running consensus over a BeaconVote. Even though it doesn't include a DataVersion, operators are assumed to compute the correct DataVersion given the duty's slot.

Aggregation

The changes follow the ethereum electra spec for constructing aggregations.

Beacon Node

  • SubmitAttestation now accepts spec.VersionedAttestation rather than phase0.Attestation.
  • SubmitSignedAggregateSelectionProof now accepts spec.VersionedSignedAggregateAndProof rather than phase0.SignedAggregateAndProof.
  • SubmitAggregateSelectionProof now should return either a phase0.SignedAggregateAndProof or a electra.SignedAggregateAndProof, depending on the version.
  • A new method, DataVersion(epoch phase0.Epoch), is added to return the DataVersion given the epoch. Note that, for this frequent API call, it's recommended for the implementation to use a cache.

Tests

All tests for the Aggregator duty and Committee duty (that encompasses the Attester duty) became versioned with a test for version DataVersionPhase0 and another for DataVersionElectra. Tests for the Proposal duty now includes the Electra version.

Testing Utils

Major refactoring for better separating specific duties utils, and for versioning utils for the aggregator and committee duties.

alan-ssvlabs and others added 7 commits November 12, 2024 13:08
* remove ssz encoding for CommitteeMember and Share

* remove commented code

---------

Co-authored-by: Alan Li <[email protected]>
…labs#494)

* remove domaintype from committeeMember

* remove domaintype from share

* add config for ssv containing domainType

* add custom unmarshal for baserunner to avoid error in unmarshalling config

* move domainType to Network

* add testing domain in NewTestingNetwork function

* Spec - filter committee duties per slot validator duties (ssvlabs#467)

* Filter shares for slot `CommitteeRunner` based on validators that have duty for that slot.

* Filter duty and create share map according to owned validators

* Add test: start duty with no shares for duty's validators

* Add test: happy flow for committee with fraction of duty's validators

* Generate JSON tests

* Apply suggestions

---------

Co-authored-by: MatheusFranco99 <[email protected]>

* Spec - check att and sync duties exist before submitting (ssvlabs#468)

* Meta - Update to go1.22 (ssvlabs#474)

* Update go1.20 to go1.22

* Update go.sum with mod tidy

* Meta - Update dependencies (ssvlabs#483)

* Update dependencies

* Fix lint issue

* Generate JSON tests to trigger actions

* Update fastssz

* Generate JSON tests and align ssz error

* Revert go-eth2-client version change

* Revert fastssz upgrade

* Generate SSZ and JSON tests

* Meta - Fix static analysis issues (ssvlabs#480)

* Solve potential file inclusion via variable

* Fix file permission (0644 to 0600)

* Add nosec comment for PRNG (pseudo-random number generator) used for testing

* Fix lint issue on nil check in []byte type

* Update permission from 0444 to 0600

* Update 0444 to 0400

* Meta - Drop unnecessary nolint comments (ssvlabs#477)

* Remove nolint comment and export timeout variables

* Drop unnecessary nolint

* Add comment

* Fix lint issue

* Spec - Share length validation (ssvlabs#478)

* Add share length validation in runner construction

* Align to error handling in runners constructions

* Add validation to committee runner

* Add runner construction tests

* Refactor runner construction in testingutil to deal with creation errors

* Generate JSON tests

* Fix lint issue

* Fix comments

* Meta - Drop redundant error (ssvlabs#475)

* Spec - Drop redundant validation for decided messages (ssvlabs#476)

* Remove redundant validation

* Align error string

* Spec - Sort signers in decided message (ssvlabs#484)

* Sort signers in decided message

* Add test for sorted signers in decided msg

* Generate JSON tests

* Fix lint issue

* Spec - Stop processing after decided (ssvlabs#487)

* Stop processing consensus messages after instance is decided

* Align error in qbft tests

* Align errors in ssv tests

* Generate JSON tests

* Fix lint issue

* Spec - Drop leftover error check (ssvlabs#469)

* Remove leftover err check

* Align argument variable name to type

* Spec - Secure key storage (ssvlabs#481)

* Implement secure key storage using PKCS8

* Fix lint issue

* Switch back PKCS8 to PKCS1

* Meta - Remove residual DKG (ssvlabs#502)

* Remove DKG signature type

* Remove DKG msg type

* Remove DKGOperators field from TestKeySet

* Remove unused ecdsaKeys field from TestingKeyStorage

* Remove unused "ecdsaSKFromHex" function

* Generate JSON tests

* Spec - Add GoSec action and fix issues (ssvlabs#505)

* Add github action and makefile command

* Fix issues in round robin proposer function

* Fix bad PutUint32 in GetCommitteeID

* Fix issue with HasQuorum and HasPartialQuorum

* Add role sanitization in GetRoleType and NewMessageType

* Add sanitization to BeaconNetwork methods

* Add sanitization in testingutils

* Add sanitization to height usage in test files

* Fix uint64 conversion in runner/postconsensus/valid_msg test

* Sanitize ValidatorIndex conversion

* Update action name

* Fix tests to use valid RunnerRoles

* Generate SSZ

* Generate JSON tests

* Revert the change on GetCommitteeID

* Add nosec G115 to GetCommitteeID

* revert the merge because it was merged with origin main by accident

---------

Co-authored-by: rehs0y <[email protected]>
Co-authored-by: MatheusFranco99 <[email protected]>
* Solve entropy in simple case in which a fixed key can be used

* Solve entropy in test type by changing the test spec: removing CypherText and using fixed keys
@MatheusFranco99 MatheusFranco99 self-assigned this Nov 16, 2024
@MatheusFranco99 MatheusFranco99 changed the base branch from main to dev November 16, 2024 13:53
@GalRogozinski GalRogozinski force-pushed the dev branch 3 times, most recently from b5bd1d3 to bf0ff16 Compare December 19, 2024 22:36
@GalRogozinski GalRogozinski deleted the branch ssvlabs:main January 9, 2025 08:21
@GalRogozinski GalRogozinski reopened this Jan 9, 2025
@MatheusFranco99 MatheusFranco99 changed the title Drop committee index Electra: Attestation Alignment Jan 20, 2025
@MatheusFranco99 MatheusFranco99 changed the title Electra: Attestation Alignment Electra: Attestation and Aggregation Alignment Jan 28, 2025
@MatheusFranco99 MatheusFranco99 changed the base branch from dev to main January 28, 2025 14:16
Copy link
Contributor

@GalRogozinski GalRogozinski left a comment

Choose a reason for hiding this comment

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

You have long switch case statements that go over all block versions... but we only need two in practice: Deneb and Electra.

so maybe reduce the code?

Also optionally (not a blocker) it will be nice to have all the Ethereum specific logic in another file, separate from committee runner. This is because those are specifications that don't relate to our protocol

@@ -7,6 +7,7 @@ import (
"github.com/attestantio/go-eth2-client/spec"
"github.com/attestantio/go-eth2-client/spec/altair"
Copy link
Contributor

Choose a reason for hiding this comment

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

and you need to adjust GetBlindedBlockData and GetBlockData to support electra

@MatheusFranco99 MatheusFranco99 changed the title Electra: Attestation and Aggregation Alignment Electra: Attestation, Aggregation and Proposal Alignment Feb 13, 2025
@GalRogozinski GalRogozinski self-requested a review February 13, 2025 15:44
Copy link
Contributor

@GalRogozinski GalRogozinski left a comment

Choose a reason for hiding this comment

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

Good job!
After you resolve conflicts and go over my comments Alan must review. This needs to be approved on Friday.

Comment on lines +248 to +278
case spec.DataVersionPhase0:
ret := &phase0.AggregateAndProof{}
if err := ret.UnmarshalSSZ(ci.DataSSZ); err != nil {
return nil, nil, errors.Wrap(err, "could not unmarshal ssz")
}

return &spec.VersionedAggregateAndProof{Version: ci.Version, Phase0: ret}, ret, nil

case spec.DataVersionAltair:
ret := &phase0.AggregateAndProof{}
if err := ret.UnmarshalSSZ(ci.DataSSZ); err != nil {
return nil, nil, errors.Wrap(err, "could not unmarshal ssz")
}

return &spec.VersionedAggregateAndProof{Version: ci.Version, Altair: ret}, ret, nil

case spec.DataVersionBellatrix:
ret := &phase0.AggregateAndProof{}
if err := ret.UnmarshalSSZ(ci.DataSSZ); err != nil {
return nil, nil, errors.Wrap(err, "could not unmarshal ssz")
}

return &spec.VersionedAggregateAndProof{Version: ci.Version, Bellatrix: ret}, ret, nil

case spec.DataVersionCapella:
ret := &phase0.AggregateAndProof{}
if err := ret.UnmarshalSSZ(ci.DataSSZ); err != nil {
return nil, nil, errors.Wrap(err, "could not unmarshal ssz")
}

return &spec.VersionedAggregateAndProof{Version: ci.Version, Capella: ret}, ret, nil
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we can delete the old versions?

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we could keep it? as on some testnets/devnets you could still use old versions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I think keeping is better

Comment on lines +332 to +351
case spec.DataVersionPhase0:
ret.Phase0 = &phase0.SignedAggregateAndProof{
Message: aggregateAndProof.Phase0,
Signature: signature,
}
case spec.DataVersionAltair:
ret.Altair = &phase0.SignedAggregateAndProof{
Message: aggregateAndProof.Altair,
Signature: signature,
}
case spec.DataVersionBellatrix:
ret.Bellatrix = &phase0.SignedAggregateAndProof{
Message: aggregateAndProof.Bellatrix,
Signature: signature,
}
case spec.DataVersionCapella:
ret.Capella = &phase0.SignedAggregateAndProof{
Message: aggregateAndProof.Capella,
Signature: signature,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

why do you have all the old versions?

Copy link
Contributor Author

@MatheusFranco99 MatheusFranco99 Feb 14, 2025

Choose a reason for hiding this comment

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

For this structure, I'm doing the same pattern as in go-eth2-client.

@@ -203,6 +205,12 @@ func (ci *ValidatorConsensusData) GetBlockData() (blk *api.VersionedProposal, si
return nil, nil, errors.Wrap(err, "could not unmarshal ssz")
}
return &api.VersionedProposal{Deneb: ret, Version: ci.Version}, ret.Block, nil
case spec.DataVersionElectra:
Copy link
Contributor

Choose a reason for hiding this comment

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

you may delete the Capella test

Copy link
Contributor Author

@MatheusFranco99 MatheusFranco99 Feb 14, 2025

Choose a reason for hiding this comment

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

I think it's worth keeping it for testnets, even for simulation/private ones, that could use an old version. Wdyt?

Comment on lines +248 to +277
case spec.DataVersionPhase0:
ret := &phase0.AggregateAndProof{}
if err := ret.UnmarshalSSZ(ci.DataSSZ); err != nil {
return nil, nil, errors.Wrap(err, "could not unmarshal ssz")
}

return &spec.VersionedAggregateAndProof{Version: ci.Version, Phase0: ret}, ret, nil

case spec.DataVersionAltair:
ret := &phase0.AggregateAndProof{}
if err := ret.UnmarshalSSZ(ci.DataSSZ); err != nil {
return nil, nil, errors.Wrap(err, "could not unmarshal ssz")
}

return &spec.VersionedAggregateAndProof{Version: ci.Version, Altair: ret}, ret, nil

case spec.DataVersionBellatrix:
ret := &phase0.AggregateAndProof{}
if err := ret.UnmarshalSSZ(ci.DataSSZ); err != nil {
return nil, nil, errors.Wrap(err, "could not unmarshal ssz")
}

return &spec.VersionedAggregateAndProof{Version: ci.Version, Bellatrix: ret}, ret, nil

case spec.DataVersionCapella:
ret := &phase0.AggregateAndProof{}
if err := ret.UnmarshalSSZ(ci.DataSSZ); err != nil {
return nil, nil, errors.Wrap(err, "could not unmarshal ssz")
}

Copy link
Contributor

Choose a reason for hiding this comment

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

no need for the old versions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see, but, for this structure, I'm doing the same pattern as in go-eth2-client.

@GalRogozinski GalRogozinski self-requested a review February 13, 2025 21:26
Copy link
Contributor

@GalRogozinski GalRogozinski left a comment

Choose a reason for hiding this comment

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

Good Job!

@GalRogozinski GalRogozinski merged commit de6806c into ssvlabs:main Feb 16, 2025
2 checks passed
@GalRogozinski GalRogozinski deleted the drop-committee-index branch February 16, 2025 10:47
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.

6 participants