diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bd7d98de539..cba8fb64f8ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,8 +18,11 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Add field param placeholder for Electra blob target and max to pass spec tests. - Add EIP-7691: Blob throughput increase. - SSZ files generation: Remove the `// Hash: ...` header. +- DB optimization for saving light client bootstraps (save unique sync committees only). - Trace IDONTWANT Messages in Pubsub. - Add Fulu fork boilerplate. +- Separate type for unaggregated network attestations. [PR](https://github.com/prysmaticlabs/prysm/pull/14659) +- Update spec tests to v1.5.0-beta.0. ### Changed @@ -39,6 +42,10 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Update our `go-libp2p-pubsub` dependency. - Re-organize the content of files to ease the creation of a new fork boilerplate. - Fixed Metadata errors for peers connected via QUIC. +- Process light client finality updates only for new finalized epochs instead of doing it for every block. +- Update blobs by rpc topics from V2 to V1. +- Updated geth to 1.14 ~ +- E2e tests start from bellatrix ### Deprecated @@ -47,11 +54,13 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - Cleanup ProcessSlashings method to remove unnecessary argument. - Remove `/proto/eth/v2` directory. [PR](https://github.com/prysmaticlabs/prysm/pull/14765) +- Remove `/memsize/` pprof endpoint as it will no longer be supported in go 1.23, geth also removed in https://github.com/ethereum/go-ethereum/commit/e4675771eda550e7eeb63a8884816982c1980644 ### Fixed - Added check to prevent nil pointer deference or out of bounds array access when validating the BLSToExecutionChange on an impossibly nil validator. - EIP-7691: Ensure new blobs subnets are subscribed on epoch in advance. +- Fix kzg commitment inclusion proof depth minimal value. ### Security diff --git a/api/server/structs/conversions.go b/api/server/structs/conversions.go index 74af3c41aba5..780ebb50e3fa 100644 --- a/api/server/structs/conversions.go +++ b/api/server/structs/conversions.go @@ -432,6 +432,32 @@ func (a *AttestationElectra) ToConsensus() (*eth.AttestationElectra, error) { }, nil } +func (a *SingleAttestation) ToConsensus() (*eth.SingleAttestation, error) { + ci, err := strconv.ParseUint(a.CommitteeIndex, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "CommitteeIndex") + } + ai, err := strconv.ParseUint(a.AttesterIndex, 10, 64) + if err != nil { + return nil, server.NewDecodeError(err, "AttesterIndex") + } + data, err := a.Data.ToConsensus() + if err != nil { + return nil, server.NewDecodeError(err, "Data") + } + sig, err := bytesutil.DecodeHexWithLength(a.Signature, fieldparams.BLSSignatureLength) + if err != nil { + return nil, server.NewDecodeError(err, "Signature") + } + + return ð.SingleAttestation{ + CommitteeId: primitives.CommitteeIndex(ci), + AttesterIndex: primitives.ValidatorIndex(ai), + Data: data, + Signature: sig, + }, nil +} + func AttElectraFromConsensus(a *eth.AttestationElectra) *AttestationElectra { return &AttestationElectra{ AggregationBits: hexutil.Encode(a.AggregationBits), diff --git a/api/server/structs/other.go b/api/server/structs/other.go index e81789cb208c..ef5a00c56f90 100644 --- a/api/server/structs/other.go +++ b/api/server/structs/other.go @@ -36,6 +36,13 @@ type AttestationElectra struct { CommitteeBits string `json:"committee_bits"` } +type SingleAttestation struct { + CommitteeIndex string `json:"committee_index"` + AttesterIndex string `json:"attester_index"` + Data *AttestationData `json:"data"` + Signature string `json:"signature"` +} + type AttestationData struct { Slot string `json:"slot"` CommitteeIndex string `json:"index"` diff --git a/beacon-chain/blockchain/kzg/kzg.go b/beacon-chain/blockchain/kzg/kzg.go index a4b8bfdaad38..30829d454f50 100644 --- a/beacon-chain/blockchain/kzg/kzg.go +++ b/beacon-chain/blockchain/kzg/kzg.go @@ -39,7 +39,8 @@ type CellsAndProofs struct { } func BlobToKZGCommitment(blob *Blob) (Commitment, error) { - comm, err := kzg4844.BlobToCommitment(kzg4844.Blob(*blob)) + kzgBlob := kzg4844.Blob(*blob) + comm, err := kzg4844.BlobToCommitment(&kzgBlob) if err != nil { return Commitment{}, err } @@ -47,7 +48,8 @@ func BlobToKZGCommitment(blob *Blob) (Commitment, error) { } func ComputeBlobKZGProof(blob *Blob, commitment Commitment) (Proof, error) { - proof, err := kzg4844.ComputeBlobProof(kzg4844.Blob(*blob), kzg4844.Commitment(commitment)) + kzgBlob := kzg4844.Blob(*blob) + proof, err := kzg4844.ComputeBlobProof(&kzgBlob, kzg4844.Commitment(commitment)) if err != nil { return [48]byte{}, err } diff --git a/beacon-chain/blockchain/kzg/validation.go b/beacon-chain/blockchain/kzg/validation.go index 6689d59d4a38..dd0c6f6d00b0 100644 --- a/beacon-chain/blockchain/kzg/validation.go +++ b/beacon-chain/blockchain/kzg/validation.go @@ -20,16 +20,17 @@ func Verify(sidecars ...blocks.ROBlob) error { cmts := make([]GoKZG.KZGCommitment, len(sidecars)) proofs := make([]GoKZG.KZGProof, len(sidecars)) for i, sidecar := range sidecars { - blobs[i] = bytesToBlob(sidecar.Blob) + blobs[i] = *bytesToBlob(sidecar.Blob) cmts[i] = bytesToCommitment(sidecar.KzgCommitment) proofs[i] = bytesToKZGProof(sidecar.KzgProof) } return kzgContext.VerifyBlobKZGProofBatch(blobs, cmts, proofs) } -func bytesToBlob(blob []byte) (ret GoKZG.Blob) { +func bytesToBlob(blob []byte) *GoKZG.Blob { + var ret GoKZG.Blob copy(ret[:], blob) - return + return &ret } func bytesToCommitment(commitment []byte) (ret GoKZG.KZGCommitment) { diff --git a/beacon-chain/blockchain/kzg/validation_test.go b/beacon-chain/blockchain/kzg/validation_test.go index 62bb21bb5b74..5416ebb0e6ac 100644 --- a/beacon-chain/blockchain/kzg/validation_test.go +++ b/beacon-chain/blockchain/kzg/validation_test.go @@ -10,11 +10,11 @@ import ( ) func GenerateCommitmentAndProof(blob GoKZG.Blob) (GoKZG.KZGCommitment, GoKZG.KZGProof, error) { - commitment, err := kzgContext.BlobToKZGCommitment(blob, 0) + commitment, err := kzgContext.BlobToKZGCommitment(&blob, 0) if err != nil { return GoKZG.KZGCommitment{}, GoKZG.KZGProof{}, err } - proof, err := kzgContext.ComputeBlobKZGProof(blob, commitment, 0) + proof, err := kzgContext.ComputeBlobKZGProof(&blob, commitment, 0) if err != nil { return GoKZG.KZGCommitment{}, GoKZG.KZGProof{}, err } @@ -31,7 +31,7 @@ func TestBytesToAny(t *testing.T) { blob := GoKZG.Blob{0x01, 0x02} commitment := GoKZG.KZGCommitment{0x01, 0x02} proof := GoKZG.KZGProof{0x01, 0x02} - require.DeepEqual(t, blob, bytesToBlob(bytes)) + require.DeepEqual(t, blob, *bytesToBlob(bytes)) require.DeepEqual(t, commitment, bytesToCommitment(bytes)) require.DeepEqual(t, proof, bytesToKZGProof(bytes)) } diff --git a/beacon-chain/blockchain/process_block.go b/beacon-chain/blockchain/process_block.go index 6427b860a552..885ce732efab 100644 --- a/beacon-chain/blockchain/process_block.go +++ b/beacon-chain/blockchain/process_block.go @@ -71,6 +71,7 @@ func (s *Service) postBlockProcess(cfg *postBlockProcessConfig) error { if features.Get().EnableLightClient && slots.ToEpoch(s.CurrentSlot()) >= params.BeaconConfig().AltairForkEpoch { defer s.processLightClientUpdates(cfg) defer s.saveLightClientUpdate(cfg) + defer s.saveLightClientBootstrap(cfg) } defer s.sendStateFeedOnBlock(cfg) defer reportProcessingTime(startTime) diff --git a/beacon-chain/core/helpers/attestation.go b/beacon-chain/core/helpers/attestation.go index 1c176a142955..0dc7d845be19 100644 --- a/beacon-chain/core/helpers/attestation.go +++ b/beacon-chain/core/helpers/attestation.go @@ -32,6 +32,9 @@ func ValidateNilAttestation(attestation ethpb.Att) error { if attestation.GetData().Target == nil { return errors.New("attestation's target can't be nil") } + if attestation.IsSingle() { + return nil + } if attestation.GetAggregationBits() == nil { return errors.New("attestation's bitfield can't be nil") } diff --git a/beacon-chain/core/helpers/attestation_test.go b/beacon-chain/core/helpers/attestation_test.go index 5459a6ac8b9a..e936abdddb40 100644 --- a/beacon-chain/core/helpers/attestation_test.go +++ b/beacon-chain/core/helpers/attestation_test.go @@ -308,6 +308,16 @@ func TestValidateNilAttestation(t *testing.T) { }, errString: "", }, + { + name: "single attestation", + attestation: ðpb.SingleAttestation{ + Data: ðpb.AttestationData{ + Target: ðpb.Checkpoint{}, + Source: ðpb.Checkpoint{}, + }, + }, + errString: "", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/beacon-chain/core/helpers/beacon_committee_test.go b/beacon-chain/core/helpers/beacon_committee_test.go index 007685617e22..a9a95facc43c 100644 --- a/beacon-chain/core/helpers/beacon_committee_test.go +++ b/beacon-chain/core/helpers/beacon_committee_test.go @@ -97,6 +97,13 @@ func TestVerifyBitfieldLength_OK(t *testing.T) { assert.NoError(t, helpers.VerifyBitfieldLength(bf, committeeSize), "Bitfield is not validated when it was supposed to be") } +func TestVerifyBitfieldLength_Incorrect(t *testing.T) { + helpers.ClearCache() + + bf := bitfield.NewBitlist(1) + require.ErrorContains(t, "wanted participants bitfield length 2, got: 1", helpers.VerifyBitfieldLength(bf, 2)) +} + func TestCommitteeAssignments_CannotRetrieveFutureEpoch(t *testing.T) { helpers.ClearCache() diff --git a/beacon-chain/db/kv/BUILD.bazel b/beacon-chain/db/kv/BUILD.bazel index 714bfb1f26d4..1e57289ca041 100644 --- a/beacon-chain/db/kv/BUILD.bazel +++ b/beacon-chain/db/kv/BUILD.bazel @@ -41,6 +41,7 @@ go_library( "//beacon-chain/state/genesis:go_default_library", "//beacon-chain/state/state-native:go_default_library", "//config/features:go_default_library", + "//config/fieldparams:go_default_library", "//config/params:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", diff --git a/beacon-chain/db/kv/kv.go b/beacon-chain/db/kv/kv.go index 128b17eddf24..684eac07592e 100644 --- a/beacon-chain/db/kv/kv.go +++ b/beacon-chain/db/kv/kv.go @@ -109,6 +109,7 @@ var Buckets = [][]byte{ stateValidatorsBucket, lightClientUpdatesBucket, lightClientBootstrapBucket, + lightClientSyncCommitteeBucket, // Indices buckets. blockSlotIndicesBucket, stateSlotIndicesBucket, diff --git a/beacon-chain/db/kv/lightclient.go b/beacon-chain/db/kv/lightclient.go index 2e3c8dc9c417..cc1655c18cde 100644 --- a/beacon-chain/db/kv/lightclient.go +++ b/beacon-chain/db/kv/lightclient.go @@ -7,6 +7,8 @@ import ( "github.com/golang/snappy" "github.com/pkg/errors" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces" light_client "github.com/prysmaticlabs/prysm/v5/consensus-types/light-client" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" @@ -35,9 +37,35 @@ func (s *Store) SaveLightClientBootstrap(ctx context.Context, blockRoot []byte, _, span := trace.StartSpan(ctx, "BeaconDB.SaveLightClientBootstrap") defer span.End() + bootstrapCopy, err := light_client.NewWrappedBootstrap(proto.Clone(bootstrap.Proto())) + if err != nil { + return errors.Wrap(err, "could not clone light client bootstrap") + } + syncCommitteeHash, err := bootstrapCopy.CurrentSyncCommittee().HashTreeRoot() + if err != nil { + return errors.Wrap(err, "could not hash current sync committee") + } + return s.db.Update(func(tx *bolt.Tx) error { + syncCommitteeBucket := tx.Bucket(lightClientSyncCommitteeBucket) + syncCommitteeAlreadyExists := syncCommitteeBucket.Get(syncCommitteeHash[:]) != nil + if !syncCommitteeAlreadyExists { + enc, err := bootstrapCopy.CurrentSyncCommittee().MarshalSSZ() + if err != nil { + return errors.Wrap(err, "could not marshal current sync committee") + } + if err := syncCommitteeBucket.Put(syncCommitteeHash[:], enc); err != nil { + return errors.Wrap(err, "could not save current sync committee") + } + } + + err = bootstrapCopy.SetCurrentSyncCommittee(createEmptySyncCommittee()) + if err != nil { + return errors.Wrap(err, "could not set current sync committee to zero while saving") + } + bkt := tx.Bucket(lightClientBootstrapBucket) - enc, err := encodeLightClientBootstrap(bootstrap) + enc, err := encodeLightClientBootstrap(bootstrapCopy, syncCommitteeHash) if err != nil { return err } @@ -50,20 +78,49 @@ func (s *Store) LightClientBootstrap(ctx context.Context, blockRoot []byte) (int defer span.End() var bootstrap interfaces.LightClientBootstrap + var syncCommitteeHash []byte err := s.db.View(func(tx *bolt.Tx) error { bkt := tx.Bucket(lightClientBootstrapBucket) + syncCommitteeBucket := tx.Bucket(lightClientSyncCommitteeBucket) enc := bkt.Get(blockRoot) if enc == nil { return nil } var err error - bootstrap, err = decodeLightClientBootstrap(enc) + bootstrap, syncCommitteeHash, err = decodeLightClientBootstrap(enc) + if err != nil { + return errors.Wrap(err, "could not decode light client bootstrap") + } + var syncCommitteeBytes = syncCommitteeBucket.Get(syncCommitteeHash) + if syncCommitteeBytes == nil { + return errors.New("sync committee not found") + } + syncCommittee := ðpb.SyncCommittee{} + if err := syncCommittee.UnmarshalSSZ(syncCommitteeBytes); err != nil { + return errors.Wrap(err, "could not unmarshal sync committee") + } + err = bootstrap.SetCurrentSyncCommittee(syncCommittee) + if err != nil { + return errors.Wrap(err, "could not set current sync committee while retrieving") + } return err }) return bootstrap, err } -func encodeLightClientBootstrap(bootstrap interfaces.LightClientBootstrap) ([]byte, error) { +func createEmptySyncCommittee() *ethpb.SyncCommittee { + syncCom := make([][]byte, params.BeaconConfig().SyncCommitteeSize) + for i := 0; uint64(i) < params.BeaconConfig().SyncCommitteeSize; i++ { + syncCom[i] = make([]byte, fieldparams.BLSPubkeyLength) + } + + return ðpb.SyncCommittee{ + Pubkeys: syncCom, + AggregatePubkey: make([]byte, fieldparams.BLSPubkeyLength), + } +} + +func encodeLightClientBootstrap(bootstrap interfaces.LightClientBootstrap, syncCommitteeHash [32]byte) ([]byte, error) { key, err := keyForLightClientUpdate(bootstrap.Version()) if err != nil { return nil, err @@ -72,48 +129,56 @@ func encodeLightClientBootstrap(bootstrap interfaces.LightClientBootstrap) ([]by if err != nil { return nil, errors.Wrap(err, "could not marshal light client bootstrap") } - fullEnc := make([]byte, len(key)+len(enc)) + fullEnc := make([]byte, len(key)+32+len(enc)) copy(fullEnc, key) - copy(fullEnc[len(key):], enc) - return snappy.Encode(nil, fullEnc), nil + copy(fullEnc[len(key):len(key)+32], syncCommitteeHash[:]) + copy(fullEnc[len(key)+32:], enc) + compressedEnc := snappy.Encode(nil, fullEnc) + return compressedEnc, nil } -func decodeLightClientBootstrap(enc []byte) (interfaces.LightClientBootstrap, error) { +func decodeLightClientBootstrap(enc []byte) (interfaces.LightClientBootstrap, []byte, error) { var err error enc, err = snappy.Decode(nil, enc) if err != nil { - return nil, errors.Wrap(err, "could not snappy decode light client bootstrap") + return nil, nil, errors.Wrap(err, "could not snappy decode light client bootstrap") } var m proto.Message + var syncCommitteeHash []byte switch { case hasAltairKey(enc): bootstrap := ðpb.LightClientBootstrapAltair{} - if err := bootstrap.UnmarshalSSZ(enc[len(altairKey):]); err != nil { - return nil, errors.Wrap(err, "could not unmarshal Altair light client bootstrap") + if err := bootstrap.UnmarshalSSZ(enc[len(altairKey)+32:]); err != nil { + return nil, nil, errors.Wrap(err, "could not unmarshal Altair light client bootstrap") } m = bootstrap + syncCommitteeHash = enc[len(altairKey) : len(altairKey)+32] case hasCapellaKey(enc): bootstrap := ðpb.LightClientBootstrapCapella{} - if err := bootstrap.UnmarshalSSZ(enc[len(capellaKey):]); err != nil { - return nil, errors.Wrap(err, "could not unmarshal Capella light client bootstrap") + if err := bootstrap.UnmarshalSSZ(enc[len(capellaKey)+32:]); err != nil { + return nil, nil, errors.Wrap(err, "could not unmarshal Capella light client bootstrap") } m = bootstrap + syncCommitteeHash = enc[len(capellaKey) : len(capellaKey)+32] case hasDenebKey(enc): bootstrap := ðpb.LightClientBootstrapDeneb{} - if err := bootstrap.UnmarshalSSZ(enc[len(denebKey):]); err != nil { - return nil, errors.Wrap(err, "could not unmarshal Deneb light client bootstrap") + if err := bootstrap.UnmarshalSSZ(enc[len(denebKey)+32:]); err != nil { + return nil, nil, errors.Wrap(err, "could not unmarshal Deneb light client bootstrap") } m = bootstrap + syncCommitteeHash = enc[len(denebKey) : len(denebKey)+32] case hasElectraKey(enc): bootstrap := ðpb.LightClientBootstrapElectra{} - if err := bootstrap.UnmarshalSSZ(enc[len(electraKey):]); err != nil { - return nil, errors.Wrap(err, "could not unmarshal Electra light client bootstrap") + if err := bootstrap.UnmarshalSSZ(enc[len(electraKey)+32:]); err != nil { + return nil, nil, errors.Wrap(err, "could not unmarshal Electra light client bootstrap") } m = bootstrap + syncCommitteeHash = enc[len(electraKey) : len(electraKey)+32] default: - return nil, errors.New("decoding of saved light client bootstrap is unsupported") + return nil, nil, errors.New("decoding of saved light client bootstrap is unsupported") } - return light_client.NewWrappedBootstrap(m) + bootstrap, err := light_client.NewWrappedBootstrap(m) + return bootstrap, syncCommitteeHash, err } func (s *Store) LightClientUpdates(ctx context.Context, startPeriod, endPeriod uint64) (map[uint64]interfaces.LightClientUpdate, error) { diff --git a/beacon-chain/db/kv/lightclient_test.go b/beacon-chain/db/kv/lightclient_test.go index 4c526933a4c9..ad5b879f8dc7 100644 --- a/beacon-chain/db/kv/lightclient_test.go +++ b/beacon-chain/db/kv/lightclient_test.go @@ -18,6 +18,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/testing/util" "github.com/prysmaticlabs/prysm/v5/time/slots" + bolt "go.etcd.io/bbolt" "google.golang.org/protobuf/proto" ) @@ -611,7 +612,13 @@ func TestStore_LightClientBootstrap_CanSaveRetrieve(t *testing.T) { retrievedBootstrap, err := db.LightClientBootstrap(ctx, []byte("blockRootAltair")) require.NoError(t, err) - require.DeepEqual(t, bootstrap, retrievedBootstrap, "retrieved bootstrap does not match saved bootstrap") + require.DeepEqual(t, bootstrap.Header(), retrievedBootstrap.Header(), "retrieved bootstrap header does not match saved bootstrap header") + require.DeepEqual(t, bootstrap.CurrentSyncCommittee(), retrievedBootstrap.CurrentSyncCommittee(), "retrieved bootstrap sync committee does not match saved bootstrap sync committee") + savedBranch, err := bootstrap.CurrentSyncCommitteeBranch() + require.NoError(t, err) + retrievedBranch, err := retrievedBootstrap.CurrentSyncCommitteeBranch() + require.NoError(t, err) + require.DeepEqual(t, savedBranch, retrievedBranch, "retrieved bootstrap sync committee branch does not match saved bootstrap sync committee branch") }) t.Run("Capella", func(t *testing.T) { @@ -626,7 +633,13 @@ func TestStore_LightClientBootstrap_CanSaveRetrieve(t *testing.T) { retrievedBootstrap, err := db.LightClientBootstrap(ctx, []byte("blockRootCapella")) require.NoError(t, err) - require.DeepEqual(t, bootstrap, retrievedBootstrap, "retrieved bootstrap does not match saved bootstrap") + require.DeepEqual(t, bootstrap.Header(), retrievedBootstrap.Header(), "retrieved bootstrap header does not match saved bootstrap header") + require.DeepEqual(t, bootstrap.CurrentSyncCommittee(), retrievedBootstrap.CurrentSyncCommittee(), "retrieved bootstrap sync committee does not match saved bootstrap sync committee") + savedBranch, err := bootstrap.CurrentSyncCommitteeBranch() + require.NoError(t, err) + retrievedBranch, err := retrievedBootstrap.CurrentSyncCommitteeBranch() + require.NoError(t, err) + require.DeepEqual(t, savedBranch, retrievedBranch, "retrieved bootstrap sync committee branch does not match saved bootstrap sync committee branch") }) t.Run("Deneb", func(t *testing.T) { @@ -641,7 +654,13 @@ func TestStore_LightClientBootstrap_CanSaveRetrieve(t *testing.T) { retrievedBootstrap, err := db.LightClientBootstrap(ctx, []byte("blockRootDeneb")) require.NoError(t, err) - require.DeepEqual(t, bootstrap, retrievedBootstrap, "retrieved bootstrap does not match saved bootstrap") + require.DeepEqual(t, bootstrap.Header(), retrievedBootstrap.Header(), "retrieved bootstrap header does not match saved bootstrap header") + require.DeepEqual(t, bootstrap.CurrentSyncCommittee(), retrievedBootstrap.CurrentSyncCommittee(), "retrieved bootstrap sync committee does not match saved bootstrap sync committee") + savedBranch, err := bootstrap.CurrentSyncCommitteeBranch() + require.NoError(t, err) + retrievedBranch, err := retrievedBootstrap.CurrentSyncCommitteeBranch() + require.NoError(t, err) + require.DeepEqual(t, savedBranch, retrievedBranch, "retrieved bootstrap sync committee branch does not match saved bootstrap sync committee branch") }) t.Run("Electra", func(t *testing.T) { @@ -656,10 +675,138 @@ func TestStore_LightClientBootstrap_CanSaveRetrieve(t *testing.T) { retrievedBootstrap, err := db.LightClientBootstrap(ctx, []byte("blockRootElectra")) require.NoError(t, err) - require.DeepEqual(t, bootstrap, retrievedBootstrap, "retrieved bootstrap does not match saved bootstrap") + require.DeepEqual(t, bootstrap.Header(), retrievedBootstrap.Header(), "retrieved bootstrap header does not match saved bootstrap header") + require.DeepEqual(t, bootstrap.CurrentSyncCommittee(), retrievedBootstrap.CurrentSyncCommittee(), "retrieved bootstrap sync committee does not match saved bootstrap sync committee") + savedBranch, err := bootstrap.CurrentSyncCommitteeBranchElectra() + require.NoError(t, err) + retrievedBranch, err := retrievedBootstrap.CurrentSyncCommitteeBranchElectra() + require.NoError(t, err) + require.DeepEqual(t, savedBranch, retrievedBranch, "retrieved bootstrap sync committee branch does not match saved bootstrap sync committee branch") }) } +func TestStore_LightClientBootstrap_MultipleBootstrapsWithSameSyncCommittee(t *testing.T) { + params.SetupTestConfigCleanup(t) + cfg := params.BeaconConfig() + cfg.AltairForkEpoch = 0 + cfg.CapellaForkEpoch = 1 + cfg.DenebForkEpoch = 2 + cfg.ElectraForkEpoch = 3 + cfg.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(cfg) + + db := setupDB(t) + ctx := context.Background() + + bootstrap1, err := createDefaultLightClientBootstrap(primitives.Slot(uint64(params.BeaconConfig().AltairForkEpoch) * uint64(params.BeaconConfig().SlotsPerEpoch))) + require.NoError(t, err) + bootstrap2, err := createDefaultLightClientBootstrap(primitives.Slot(uint64(params.BeaconConfig().AltairForkEpoch) * uint64(params.BeaconConfig().SlotsPerEpoch))) + require.NoError(t, err) + + randomSyncCommittee := createRandomSyncCommittee() + + err = bootstrap1.SetCurrentSyncCommittee(randomSyncCommittee) + require.NoError(t, err) + err = bootstrap2.SetCurrentSyncCommittee(randomSyncCommittee) + require.NoError(t, err) + + err = db.SaveLightClientBootstrap(ctx, []byte("blockRootAltair1"), bootstrap1) + require.NoError(t, err) + err = db.SaveLightClientBootstrap(ctx, []byte("blockRootAltair2"), bootstrap2) + require.NoError(t, err) + + retrievedBootstrap1, err := db.LightClientBootstrap(ctx, []byte("blockRootAltair1")) + require.NoError(t, err) + retrievedBootstrap2, err := db.LightClientBootstrap(ctx, []byte("blockRootAltair2")) + require.NoError(t, err) + + require.DeepEqual(t, bootstrap1.Header(), retrievedBootstrap1.Header(), "retrieved bootstrap1 header does not match saved bootstrap1 header") + require.DeepEqual(t, randomSyncCommittee, retrievedBootstrap1.CurrentSyncCommittee(), "retrieved bootstrap1 sync committee does not match saved bootstrap1 sync committee") + savedBranch, err := bootstrap1.CurrentSyncCommitteeBranch() + require.NoError(t, err) + retrievedBranch, err := retrievedBootstrap1.CurrentSyncCommitteeBranch() + require.NoError(t, err) + require.DeepEqual(t, savedBranch, retrievedBranch, "retrieved bootstrap1 sync committee branch does not match saved bootstrap1 sync committee branch") + + require.DeepEqual(t, bootstrap2.Header(), retrievedBootstrap2.Header(), "retrieved bootstrap1 header does not match saved bootstrap1 header") + require.DeepEqual(t, randomSyncCommittee, retrievedBootstrap2.CurrentSyncCommittee(), "retrieved bootstrap1 sync committee does not match saved bootstrap1 sync committee") + savedBranch2, err := bootstrap2.CurrentSyncCommitteeBranch() + require.NoError(t, err) + retrievedBranch2, err := retrievedBootstrap2.CurrentSyncCommitteeBranch() + require.NoError(t, err) + require.DeepEqual(t, savedBranch2, retrievedBranch2, "retrieved bootstrap1 sync committee branch does not match saved bootstrap1 sync committee branch") + + // Ensure that the sync committee is only stored once + err = db.db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket(lightClientSyncCommitteeBucket) + require.NotNil(t, bucket) + count := bucket.Stats().KeyN + require.Equal(t, 1, count) + return nil + }) + require.NoError(t, err) +} + +func TestStore_LightClientBootstrap_MultipleBootstrapsWithDifferentSyncCommittees(t *testing.T) { + params.SetupTestConfigCleanup(t) + cfg := params.BeaconConfig() + cfg.AltairForkEpoch = 0 + cfg.CapellaForkEpoch = 1 + cfg.DenebForkEpoch = 2 + cfg.ElectraForkEpoch = 3 + cfg.EpochsPerSyncCommitteePeriod = 1 + params.OverrideBeaconConfig(cfg) + + db := setupDB(t) + ctx := context.Background() + + bootstrap1, err := createDefaultLightClientBootstrap(primitives.Slot(uint64(params.BeaconConfig().AltairForkEpoch) * uint64(params.BeaconConfig().SlotsPerEpoch))) + require.NoError(t, err) + bootstrap2, err := createDefaultLightClientBootstrap(primitives.Slot(uint64(params.BeaconConfig().AltairForkEpoch) * uint64(params.BeaconConfig().SlotsPerEpoch))) + require.NoError(t, err) + + err = bootstrap1.SetCurrentSyncCommittee(createRandomSyncCommittee()) + require.NoError(t, err) + err = bootstrap2.SetCurrentSyncCommittee(createRandomSyncCommittee()) + require.NoError(t, err) + + err = db.SaveLightClientBootstrap(ctx, []byte("blockRootAltair1"), bootstrap1) + require.NoError(t, err) + err = db.SaveLightClientBootstrap(ctx, []byte("blockRootAltair2"), bootstrap2) + require.NoError(t, err) + + retrievedBootstrap1, err := db.LightClientBootstrap(ctx, []byte("blockRootAltair1")) + require.NoError(t, err) + retrievedBootstrap2, err := db.LightClientBootstrap(ctx, []byte("blockRootAltair2")) + require.NoError(t, err) + + require.DeepEqual(t, bootstrap1.Header(), retrievedBootstrap1.Header(), "retrieved bootstrap1 header does not match saved bootstrap1 header") + require.DeepEqual(t, bootstrap1.CurrentSyncCommittee(), retrievedBootstrap1.CurrentSyncCommittee(), "retrieved bootstrap1 sync committee does not match saved bootstrap1 sync committee") + savedBranch, err := bootstrap1.CurrentSyncCommitteeBranch() + require.NoError(t, err) + retrievedBranch, err := retrievedBootstrap1.CurrentSyncCommitteeBranch() + require.NoError(t, err) + require.DeepEqual(t, savedBranch, retrievedBranch, "retrieved bootstrap1 sync committee branch does not match saved bootstrap1 sync committee branch") + + require.DeepEqual(t, bootstrap2.Header(), retrievedBootstrap2.Header(), "retrieved bootstrap1 header does not match saved bootstrap1 header") + require.DeepEqual(t, bootstrap2.CurrentSyncCommittee(), retrievedBootstrap2.CurrentSyncCommittee(), "retrieved bootstrap1 sync committee does not match saved bootstrap1 sync committee") + savedBranch2, err := bootstrap2.CurrentSyncCommitteeBranch() + require.NoError(t, err) + retrievedBranch2, err := retrievedBootstrap2.CurrentSyncCommitteeBranch() + require.NoError(t, err) + require.DeepEqual(t, savedBranch2, retrievedBranch2, "retrieved bootstrap1 sync committee branch does not match saved bootstrap1 sync committee branch") + + // Ensure that the sync committee is stored twice + err = db.db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket(lightClientSyncCommitteeBucket) + require.NotNil(t, bucket) + count := bucket.Stats().KeyN + require.Equal(t, 2, count) + return nil + }) + require.NoError(t, err) +} + func createDefaultLightClientBootstrap(currentSlot primitives.Slot) (interfaces.LightClientBootstrap, error) { currentEpoch := slots.ToEpoch(currentSlot) syncCommitteeSize := params.BeaconConfig().SyncCommitteeSize diff --git a/beacon-chain/db/kv/schema.go b/beacon-chain/db/kv/schema.go index 378f10e41210..7d359a9897fb 100644 --- a/beacon-chain/db/kv/schema.go +++ b/beacon-chain/db/kv/schema.go @@ -18,8 +18,9 @@ var ( registrationBucket = []byte("registration") // Light Client Updates Bucket - lightClientUpdatesBucket = []byte("light-client-updates") - lightClientBootstrapBucket = []byte("light-client-bootstrap") + lightClientUpdatesBucket = []byte("light-client-updates") + lightClientBootstrapBucket = []byte("light-client-bootstrap") + lightClientSyncCommitteeBucket = []byte("light-client-sync-committee") // Deprecated: This bucket was migrated in PR 6461. Do not use, except for migrations. slotsHasObjectBucket = []byte("slots-has-objects") diff --git a/beacon-chain/execution/BUILD.bazel b/beacon-chain/execution/BUILD.bazel index b33fb4d0d8a8..641db3540d6a 100644 --- a/beacon-chain/execution/BUILD.bazel +++ b/beacon-chain/execution/BUILD.bazel @@ -131,11 +131,11 @@ go_test( "//testing/util:go_default_library", "//time/slots:go_default_library", "@com_github_ethereum_go_ethereum//:go_default_library", - "@com_github_ethereum_go_ethereum//accounts/abi/bind/backends:go_default_library", "@com_github_ethereum_go_ethereum//beacon/engine:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_ethereum_go_ethereum//core/types:go_default_library", + "@com_github_ethereum_go_ethereum//ethclient/simulated:go_default_library", "@com_github_ethereum_go_ethereum//rpc:go_default_library", "@com_github_holiman_uint256//:go_default_library", "@com_github_pkg_errors//:go_default_library", diff --git a/beacon-chain/execution/block_reader_test.go b/beacon-chain/execution/block_reader_test.go index 6dbda1d2118f..10d10b81590a 100644 --- a/beacon-chain/execution/block_reader_test.go +++ b/beacon-chain/execution/block_reader_test.go @@ -12,6 +12,7 @@ import ( dbutil "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/testing" mockExecution "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution/testing" "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution/types" + "github.com/prysmaticlabs/prysm/v5/config/params" contracts "github.com/prysmaticlabs/prysm/v5/contracts/deposit" "github.com/prysmaticlabs/prysm/v5/contracts/deposit/mock" "github.com/prysmaticlabs/prysm/v5/testing/assert" @@ -44,7 +45,7 @@ func TestLatestMainchainInfo_OK(t *testing.T) { web3Service = setDefaultMocks(web3Service) web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend} - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) testAcc.Backend.Commit() @@ -141,7 +142,7 @@ func TestBlockExists_ValidHash(t *testing.T) { web3Service = setDefaultMocks(web3Service) web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend} testAcc.Backend.Commit() - block, err := testAcc.Backend.BlockByNumber(context.Background(), big.NewInt(0)) + block, err := testAcc.Backend.Client().BlockByNumber(context.Background(), big.NewInt(0)) assert.NoError(t, err) exists, height, err := web3Service.BlockExists(context.Background(), block.Hash()) @@ -201,8 +202,10 @@ func TestBlockExists_UsesCachedBlockInfo(t *testing.T) { } func TestService_BlockNumberByTimestamp(t *testing.T) { + ctx := context.Background() beaconDB := dbutil.SetupDB(t) testAcc, err := mock.Setup() + require.NoError(t, err, "Unable to set up simulated backend") server, endpoint, err := mockExecution.SetupRPCServer() require.NoError(t, err) @@ -216,16 +219,22 @@ func TestService_BlockNumberByTimestamp(t *testing.T) { require.NoError(t, err) web3Service = setDefaultMocks(web3Service) web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend} - + // simulated backend sets eth1 block + params.SetupTestConfigCleanup(t) + conf := params.BeaconConfig().Copy() + conf.SecondsPerETH1Block = 1 + params.OverrideBeaconConfig(conf) + initialHead, err := testAcc.Backend.Client().HeaderByNumber(ctx, nil) + require.NoError(t, err) for i := 0; i < 200; i++ { testAcc.Backend.Commit() } - ctx := context.Background() - hd, err := testAcc.Backend.HeaderByNumber(ctx, nil) + + hd, err := testAcc.Backend.Client().HeaderByNumber(ctx, nil) require.NoError(t, err) web3Service.latestEth1Data.BlockTime = hd.Time web3Service.latestEth1Data.BlockHeight = hd.Number.Uint64() - blk, err := web3Service.BlockByTimestamp(ctx, 1000 /* time */) + blk, err := web3Service.BlockByTimestamp(ctx, initialHead.Time+100 /* time */) require.NoError(t, err) if blk.Number.Cmp(big.NewInt(0)) == 0 { t.Error("Returned a block with zero number, expected to be non zero") @@ -253,7 +262,7 @@ func TestService_BlockNumberByTimestampLessTargetTime(t *testing.T) { testAcc.Backend.Commit() } ctx := context.Background() - hd, err := testAcc.Backend.HeaderByNumber(ctx, nil) + hd, err := testAcc.Backend.Client().HeaderByNumber(ctx, nil) require.NoError(t, err) web3Service.latestEth1Data.BlockTime = hd.Time // Use extremely small deadline to illustrate that context deadlines are respected. @@ -291,7 +300,7 @@ func TestService_BlockNumberByTimestampMoreTargetTime(t *testing.T) { testAcc.Backend.Commit() } ctx := context.Background() - hd, err := testAcc.Backend.HeaderByNumber(ctx, nil) + hd, err := testAcc.Backend.Client().HeaderByNumber(ctx, nil) require.NoError(t, err) web3Service.latestEth1Data.BlockTime = hd.Time // Use extremely small deadline to illustrate that context deadlines are respected. diff --git a/beacon-chain/execution/log_processing_test.go b/beacon-chain/execution/log_processing_test.go index 4120ca136f8e..c7f46239d71b 100644 --- a/beacon-chain/execution/log_processing_test.go +++ b/beacon-chain/execution/log_processing_test.go @@ -47,7 +47,7 @@ func TestProcessDepositLog_OK(t *testing.T) { ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) testAcc.Backend.Commit() @@ -72,7 +72,7 @@ func TestProcessDepositLog_OK(t *testing.T) { }, } - logs, err := testAcc.Backend.FilterLogs(web3Service.ctx, query) + logs, err := testAcc.Backend.Client().FilterLogs(web3Service.ctx, query) require.NoError(t, err, "Unable to retrieve logs") if len(logs) == 0 { @@ -116,7 +116,7 @@ func TestProcessDepositLog_InsertsPendingDeposit(t *testing.T) { ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) testAcc.Backend.Commit() @@ -144,7 +144,7 @@ func TestProcessDepositLog_InsertsPendingDeposit(t *testing.T) { }, } - logs, err := testAcc.Backend.FilterLogs(web3Service.ctx, query) + logs, err := testAcc.Backend.Client().FilterLogs(web3Service.ctx, query) require.NoError(t, err, "Unable to retrieve logs") web3Service.chainStartData.Chainstarted = true @@ -176,7 +176,7 @@ func TestUnpackDepositLogData_OK(t *testing.T) { ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) testAcc.Backend.Commit() @@ -199,7 +199,7 @@ func TestUnpackDepositLogData_OK(t *testing.T) { }, } - logz, err := testAcc.Backend.FilterLogs(web3Service.ctx, query) + logz, err := testAcc.Backend.Client().FilterLogs(web3Service.ctx, query) require.NoError(t, err, "Unable to retrieve logs") loggedPubkey, withCreds, _, loggedSig, index, err := contracts.UnpackDepositLogData(logz[0].Data) @@ -232,7 +232,7 @@ func TestProcessETH2GenesisLog_8DuplicatePubkeys(t *testing.T) { ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) params.SetupTestConfigCleanup(t) @@ -269,7 +269,7 @@ func TestProcessETH2GenesisLog_8DuplicatePubkeys(t *testing.T) { }, } - logs, err := testAcc.Backend.FilterLogs(web3Service.ctx, query) + logs, err := testAcc.Backend.Client().FilterLogs(web3Service.ctx, query) require.NoError(t, err, "Unable to retrieve logs") for i := range logs { @@ -307,7 +307,7 @@ func TestProcessETH2GenesisLog(t *testing.T) { ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend} require.NoError(t, err) params.SetupTestConfigCleanup(t) @@ -342,7 +342,7 @@ func TestProcessETH2GenesisLog(t *testing.T) { }, } - logs, err := testAcc.Backend.FilterLogs(web3Service.ctx, query) + logs, err := testAcc.Backend.Client().FilterLogs(web3Service.ctx, query) require.NoError(t, err, "Unable to retrieve logs") require.Equal(t, depositsReqForChainStart, len(logs)) @@ -400,16 +400,18 @@ func TestProcessETH2GenesisLog_CorrectNumOfDeposits(t *testing.T) { ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend} - web3Service.httpLogger = testAcc.Backend + web3Service.httpLogger = testAcc.Backend.Client() web3Service.latestEth1Data.LastRequestedBlock = 0 - web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().Number.Uint64() - web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time + block, err := testAcc.Backend.Client().BlockByNumber(context.Background(), nil) + require.NoError(t, err) + web3Service.latestEth1Data.BlockHeight = block.NumberU64() + web3Service.latestEth1Data.BlockTime = block.Time() bConfig := params.MinimalSpecConfig().Copy() bConfig.MinGenesisTime = 0 - bConfig.SecondsPerETH1Block = 10 + bConfig.SecondsPerETH1Block = 1 params.OverrideBeaconConfig(bConfig) nConfig := params.BeaconNetworkConfig() nConfig.ContractDeploymentBlock = 0 @@ -444,8 +446,10 @@ func TestProcessETH2GenesisLog_CorrectNumOfDeposits(t *testing.T) { for i := uint64(0); i < params.BeaconConfig().Eth1FollowDistance; i++ { testAcc.Backend.Commit() } - web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().Number.Uint64() - web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time + b, err := testAcc.Backend.Client().BlockByNumber(context.Background(), nil) + require.NoError(t, err) + web3Service.latestEth1Data.BlockHeight = b.NumberU64() + web3Service.latestEth1Data.BlockTime = b.Time() // Set up our subscriber now to listen for the chain started event. stateChannel := make(chan *feed.Event, 1) @@ -497,13 +501,15 @@ func TestProcessETH2GenesisLog_LargePeriodOfNoLogs(t *testing.T) { ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend} - web3Service.httpLogger = testAcc.Backend + web3Service.httpLogger = testAcc.Backend.Client() web3Service.latestEth1Data.LastRequestedBlock = 0 - web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().Number.Uint64() - web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time + b, err := testAcc.Backend.Client().BlockByNumber(context.Background(), nil) + require.NoError(t, err) + web3Service.latestEth1Data.BlockHeight = b.NumberU64() + web3Service.latestEth1Data.BlockTime = b.Time() bConfig := params.MinimalSpecConfig().Copy() bConfig.SecondsPerETH1Block = 10 params.OverrideBeaconConfig(bConfig) @@ -540,14 +546,19 @@ func TestProcessETH2GenesisLog_LargePeriodOfNoLogs(t *testing.T) { for i := uint64(0); i < 1500; i++ { testAcc.Backend.Commit() } - wantedGenesisTime := testAcc.Backend.Blockchain().CurrentBlock().Time + genesisBlock, err := testAcc.Backend.Client().BlockByNumber(context.Background(), nil) + require.NoError(t, err) + + wantedGenesisTime := genesisBlock.Time() // Forward the chain to account for the follow distance for i := uint64(0); i < params.BeaconConfig().Eth1FollowDistance; i++ { testAcc.Backend.Commit() } - web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().Number.Uint64() - web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time + currBlock, err := testAcc.Backend.Client().BlockByNumber(context.Background(), nil) + require.NoError(t, err) + web3Service.latestEth1Data.BlockHeight = currBlock.NumberU64() + web3Service.latestEth1Data.BlockTime = currBlock.Time() // Set the genesis time 500 blocks ahead of the last // deposit log. @@ -608,7 +619,7 @@ func newPowchainService(t *testing.T, eth1Backend *mock.TestAccount, beaconDB db ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(eth1Backend.ContractAddr, eth1Backend.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(eth1Backend.ContractAddr, eth1Backend.Backend.Client()) require.NoError(t, err) web3Service.rpcClient = &mockExecution.RPCClient{Backend: eth1Backend.Backend} diff --git a/beacon-chain/execution/service_test.go b/beacon-chain/execution/service_test.go index e6b6e2ea075e..901b82c143c1 100644 --- a/beacon-chain/execution/service_test.go +++ b/beacon-chain/execution/service_test.go @@ -8,10 +8,10 @@ import ( "time" "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" gethTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient/simulated" "github.com/ethereum/go-ethereum/rpc" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v5/async/event" @@ -44,7 +44,7 @@ var _ POWBlockFetcher = (*Service)(nil) var _ Chain = (*Service)(nil) type goodLogger struct { - backend *backends.SimulatedBackend + backend *simulated.Backend } func (_ *goodLogger) Close() {} @@ -53,7 +53,7 @@ func (g *goodLogger) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQ if g.backend == nil { return new(event.Feed).Subscribe(ch), nil } - return g.backend.SubscribeFilterLogs(ctx, q, ch) + return g.backend.Client().SubscribeFilterLogs(ctx, q, ch) } func (g *goodLogger) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]gethTypes.Log, error) { @@ -69,7 +69,7 @@ func (g *goodLogger) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([] } return logs, nil } - return g.backend.FilterLogs(ctx, q) + return g.backend.Client().FilterLogs(ctx, q) } type goodNotifier struct { @@ -109,7 +109,7 @@ func TestStart_OK(t *testing.T) { require.NoError(t, err, "unable to setup execution service") web3Service = setDefaultMocks(web3Service) web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend} - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) testAcc.Backend.Commit() @@ -156,7 +156,7 @@ func TestStop_OK(t *testing.T) { ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) testAcc.Backend.Commit() @@ -186,10 +186,12 @@ func TestService_Eth1Synced(t *testing.T) { ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") web3Service = setDefaultMocks(web3Service) - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) - currTime := testAcc.Backend.Blockchain().CurrentHeader().Time + header, err := testAcc.Backend.Client().HeaderByNumber(context.Background(), nil) + require.NoError(t, err) + currTime := header.Time now := time.Now() assert.NoError(t, testAcc.Backend.AdjustTime(now.Sub(time.Unix(int64(currTime), 0)))) testAcc.Backend.Commit() @@ -212,22 +214,29 @@ func TestFollowBlock_OK(t *testing.T) { require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") // simulated backend sets eth1 block - // time as 10 seconds params.SetupTestConfigCleanup(t) conf := params.BeaconConfig().Copy() - conf.SecondsPerETH1Block = 10 + conf.SecondsPerETH1Block = 1 params.OverrideBeaconConfig(conf) web3Service = setDefaultMocks(web3Service) web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend} - baseHeight := testAcc.Backend.Blockchain().CurrentBlock().Number.Uint64() + block, err := testAcc.Backend.Client().BlockByNumber(context.Background(), nil) + require.NoError(t, err) + baseHeight := block.NumberU64() // process follow_distance blocks + var lastHash common.Hash for i := 0; i < int(params.BeaconConfig().Eth1FollowDistance); i++ { - testAcc.Backend.Commit() + lastHash = testAcc.Backend.Commit() } + lb, err := testAcc.Backend.Client().BlockByHash(context.Background(), lastHash) + require.NoError(t, err) + log.Println(lb.NumberU64()) // set current height - web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().Number.Uint64() - web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time + block, err = testAcc.Backend.Client().BlockByNumber(context.Background(), nil) + require.NoError(t, err) + web3Service.latestEth1Data.BlockHeight = block.NumberU64() + web3Service.latestEth1Data.BlockTime = block.Time() h, err := web3Service.followedBlockHeight(context.Background()) require.NoError(t, err) @@ -238,9 +247,12 @@ func TestFollowBlock_OK(t *testing.T) { for i := uint64(0); i < numToForward; i++ { testAcc.Backend.Commit() } + + newBlock, err := testAcc.Backend.Client().BlockByNumber(context.Background(), nil) + require.NoError(t, err) // set current height - web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentBlock().Number.Uint64() - web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentBlock().Time + web3Service.latestEth1Data.BlockHeight = newBlock.NumberU64() + web3Service.latestEth1Data.BlockTime = newBlock.Time() h, err = web3Service.followedBlockHeight(context.Background()) require.NoError(t, err) @@ -325,11 +337,11 @@ func TestLogTillGenesis_OK(t *testing.T) { WithDatabase(beaconDB), ) require.NoError(t, err, "unable to setup web3 ETH1.0 chain service") - web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend) + web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client()) require.NoError(t, err) web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend} - web3Service.httpLogger = testAcc.Backend + web3Service.httpLogger = testAcc.Backend.Client() for i := 0; i < 30; i++ { testAcc.Backend.Commit() } @@ -485,15 +497,18 @@ func TestNewService_EarliestVotingBlock(t *testing.T) { for i := 0; i < numToForward; i++ { testAcc.Backend.Commit() } - currTime := testAcc.Backend.Blockchain().CurrentHeader().Time + currHeader, err := testAcc.Backend.Client().HeaderByNumber(context.Background(), nil) + require.NoError(t, err) + currTime := currHeader.Time now := time.Now() err = testAcc.Backend.AdjustTime(now.Sub(time.Unix(int64(currTime), 0))) require.NoError(t, err) testAcc.Backend.Commit() - - currTime = testAcc.Backend.Blockchain().CurrentHeader().Time - web3Service.latestEth1Data.BlockHeight = testAcc.Backend.Blockchain().CurrentHeader().Number.Uint64() - web3Service.latestEth1Data.BlockTime = testAcc.Backend.Blockchain().CurrentHeader().Time + currHeader, err = testAcc.Backend.Client().HeaderByNumber(context.Background(), nil) + require.NoError(t, err) + currTime = currHeader.Time + web3Service.latestEth1Data.BlockHeight = currHeader.Number.Uint64() + web3Service.latestEth1Data.BlockTime = currHeader.Time web3Service.chainStartData.GenesisTime = currTime // With a current slot of zero, only request follow_blocks behind. diff --git a/beacon-chain/execution/testing/BUILD.bazel b/beacon-chain/execution/testing/BUILD.bazel index ba5b27f98f6a..e9b1ef77e238 100644 --- a/beacon-chain/execution/testing/BUILD.bazel +++ b/beacon-chain/execution/testing/BUILD.bazel @@ -25,10 +25,10 @@ go_library( "//encoding/bytesutil:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", - "@com_github_ethereum_go_ethereum//accounts/abi/bind/backends:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_ethereum_go_ethereum//core/types:go_default_library", + "@com_github_ethereum_go_ethereum//ethclient/simulated:go_default_library", "@com_github_ethereum_go_ethereum//rpc:go_default_library", "@com_github_holiman_uint256//:go_default_library", "@com_github_pkg_errors//:go_default_library", diff --git a/beacon-chain/execution/testing/mock_execution_chain.go b/beacon-chain/execution/testing/mock_execution_chain.go index 95b8718d2668..287738e18909 100644 --- a/beacon-chain/execution/testing/mock_execution_chain.go +++ b/beacon-chain/execution/testing/mock_execution_chain.go @@ -9,10 +9,10 @@ import ( "net/http/httptest" "time" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" gethTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient/simulated" "github.com/ethereum/go-ethereum/rpc" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v5/async/event" @@ -141,7 +141,7 @@ func (m *Chain) ETH1ConnectionErrors() []error { // RPCClient defines the mock rpc client. type RPCClient struct { - Backend *backends.SimulatedBackend + Backend *simulated.Backend BlockNumMap map[uint64]*types.HeaderInfo } @@ -195,7 +195,7 @@ func (r *RPCClient) CallContext(ctx context.Context, obj interface{}, methodName return err } } - h, err := r.Backend.HeaderByNumber(ctx, num) + h, err := r.Backend.Client().HeaderByNumber(ctx, num) if err != nil { return err } @@ -213,7 +213,7 @@ func (r *RPCClient) CallContext(ctx context.Context, obj interface{}, methodName if !ok { return errors.Errorf("wrong argument type provided: %T", args[0]) } - h, err := r.Backend.HeaderByHash(ctx, val) + h, err := r.Backend.Client().HeaderByHash(ctx, val) if err != nil { return err } @@ -241,7 +241,7 @@ func (r *RPCClient) BatchCall(b []rpc.BatchElem) error { if err != nil { return err } - h, err := r.Backend.HeaderByNumber(context.Background(), num) + h, err := r.Backend.Client().HeaderByNumber(context.Background(), num) if err != nil { return err } diff --git a/beacon-chain/p2p/broadcaster_test.go b/beacon-chain/p2p/broadcaster_test.go index 3ef08b72222a..499394f825ff 100644 --- a/beacon-chain/p2p/broadcaster_test.go +++ b/beacon-chain/p2p/broadcaster_test.go @@ -213,7 +213,7 @@ func TestService_BroadcastAttestation(t *testing.T) { func TestService_BroadcastAttestationWithDiscoveryAttempts(t *testing.T) { // Setup bootnode. - cfg := &Config{} + cfg := &Config{PingInterval: testPingInterval} port := 2000 cfg.UDPPort = uint(port) _, pkey := createAddrAndPrivKey(t) @@ -238,12 +238,16 @@ func TestService_BroadcastAttestationWithDiscoveryAttempts(t *testing.T) { cfg = &Config{ Discv5BootStrapAddrs: []string{bootNode.String()}, MaxPeers: 2, + PingInterval: testPingInterval, } // Setup 2 different hosts for i := 1; i <= 2; i++ { h, pkey, ipAddr := createHost(t, port+i) cfg.UDPPort = uint(port + i) cfg.TCPPort = uint(port + i) + if len(listeners) > 0 { + cfg.Discv5BootStrapAddrs = append(cfg.Discv5BootStrapAddrs, listeners[len(listeners)-1].Self().String()) + } s := &Service{ cfg: cfg, genesisTime: genesisTime, diff --git a/beacon-chain/p2p/config.go b/beacon-chain/p2p/config.go index 3da7d055cbb2..943d2d3fa673 100644 --- a/beacon-chain/p2p/config.go +++ b/beacon-chain/p2p/config.go @@ -1,6 +1,8 @@ package p2p import ( + "time" + statefeed "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed/state" "github.com/prysmaticlabs/prysm/v5/beacon-chain/db" "github.com/prysmaticlabs/prysm/v5/beacon-chain/startup" @@ -15,6 +17,7 @@ type Config struct { NoDiscovery bool EnableUPnP bool StaticPeerID bool + DisableLivenessCheck bool StaticPeers []string Discv5BootStrapAddrs []string RelayNodeAddr string @@ -27,6 +30,7 @@ type Config struct { QUICPort uint TCPPort uint UDPPort uint + PingInterval time.Duration MaxPeers uint QueueSize uint AllowListCIDR string diff --git a/beacon-chain/p2p/discovery.go b/beacon-chain/p2p/discovery.go index 98e8aaffede9..d50e3fde03ce 100644 --- a/beacon-chain/p2p/discovery.go +++ b/beacon-chain/p2p/discovery.go @@ -458,8 +458,10 @@ func (s *Service) createListener( } dv5Cfg := discover.Config{ - PrivateKey: privKey, - Bootnodes: bootNodes, + PrivateKey: privKey, + Bootnodes: bootNodes, + PingInterval: s.cfg.PingInterval, + NoFindnodeLivenessCheck: s.cfg.DisableLivenessCheck, } listener, err := discover.ListenV5(conn, localNode, dv5Cfg) diff --git a/beacon-chain/p2p/discovery_test.go b/beacon-chain/p2p/discovery_test.go index dd5cce80e869..ae970b034c96 100644 --- a/beacon-chain/p2p/discovery_test.go +++ b/beacon-chain/p2p/discovery_test.go @@ -88,7 +88,7 @@ func TestStartDiscV5_DiscoverAllPeers(t *testing.T) { genesisTime := time.Now() genesisValidatorsRoot := make([]byte, 32) s := &Service{ - cfg: &Config{UDPPort: uint(port)}, + cfg: &Config{UDPPort: uint(port), PingInterval: testPingInterval, DisableLivenessCheck: true}, genesisTime: genesisTime, genesisValidatorsRoot: genesisValidatorsRoot, } @@ -96,6 +96,10 @@ func TestStartDiscV5_DiscoverAllPeers(t *testing.T) { require.NoError(t, err) defer bootListener.Close() + // Allow bootnode's table to have its initial refresh. This allows + // inbound nodes to be added in. + time.Sleep(5 * time.Second) + bootNode := bootListener.Self() var listeners []*listenerWrapper @@ -104,6 +108,8 @@ func TestStartDiscV5_DiscoverAllPeers(t *testing.T) { cfg := &Config{ Discv5BootStrapAddrs: []string{bootNode.String()}, UDPPort: uint(port), + PingInterval: testPingInterval, + DisableLivenessCheck: true, } ipAddr, pkey := createAddrAndPrivKey(t) s = &Service{ diff --git a/beacon-chain/p2p/fork_test.go b/beacon-chain/p2p/fork_test.go index 7c3d889e9675..0d192653506a 100644 --- a/beacon-chain/p2p/fork_test.go +++ b/beacon-chain/p2p/fork_test.go @@ -34,8 +34,10 @@ func TestStartDiscv5_DifferentForkDigests(t *testing.T) { genesisValidatorsRoot := make([]byte, fieldparams.RootLength) s := &Service{ cfg: &Config{ - UDPPort: uint(port), - StateNotifier: &mock.MockStateNotifier{}, + UDPPort: uint(port), + StateNotifier: &mock.MockStateNotifier{}, + PingInterval: testPingInterval, + DisableLivenessCheck: true, }, genesisTime: genesisTime, genesisValidatorsRoot: genesisValidatorsRoot, @@ -44,11 +46,17 @@ func TestStartDiscv5_DifferentForkDigests(t *testing.T) { require.NoError(t, err) defer bootListener.Close() + // Allow bootnode's table to have its initial refresh. This allows + // inbound nodes to be added in. + time.Sleep(5 * time.Second) + bootNode := bootListener.Self() cfg := &Config{ Discv5BootStrapAddrs: []string{bootNode.String()}, UDPPort: uint(port), StateNotifier: &mock.MockStateNotifier{}, + PingInterval: testPingInterval, + DisableLivenessCheck: true, } var listeners []*listenerWrapper @@ -124,7 +132,7 @@ func TestStartDiscv5_SameForkDigests_DifferentNextForkData(t *testing.T) { genesisTime := time.Now() genesisValidatorsRoot := make([]byte, 32) s := &Service{ - cfg: &Config{UDPPort: uint(port)}, + cfg: &Config{UDPPort: uint(port), PingInterval: testPingInterval, DisableLivenessCheck: true}, genesisTime: genesisTime, genesisValidatorsRoot: genesisValidatorsRoot, } @@ -132,10 +140,16 @@ func TestStartDiscv5_SameForkDigests_DifferentNextForkData(t *testing.T) { require.NoError(t, err) defer bootListener.Close() + // Allow bootnode's table to have its initial refresh. This allows + // inbound nodes to be added in. + time.Sleep(5 * time.Second) + bootNode := bootListener.Self() cfg := &Config{ Discv5BootStrapAddrs: []string{bootNode.String()}, UDPPort: uint(port), + PingInterval: testPingInterval, + DisableLivenessCheck: true, } var listeners []*listenerWrapper @@ -143,7 +157,6 @@ func TestStartDiscv5_SameForkDigests_DifferentNextForkData(t *testing.T) { port := 3000 + i cfg.UDPPort = uint(port) ipAddr, pkey := createAddrAndPrivKey(t) - c := params.BeaconConfig().Copy() nextForkEpoch := primitives.Epoch(i) c.ForkVersionSchedule[[4]byte{'A', 'B', 'C', 'D'}] = nextForkEpoch diff --git a/beacon-chain/p2p/gossip_topic_mappings.go b/beacon-chain/p2p/gossip_topic_mappings.go index a3be2c7f9463..2b4f3e6dedb3 100644 --- a/beacon-chain/p2p/gossip_topic_mappings.go +++ b/beacon-chain/p2p/gossip_topic_mappings.go @@ -51,7 +51,7 @@ func GossipTopicMappings(topic string, epoch primitives.Epoch) proto.Message { return gossipMessage(topic) case AttestationSubnetTopicFormat: if epoch >= params.BeaconConfig().ElectraForkEpoch { - return ðpb.AttestationElectra{} + return ðpb.SingleAttestation{} } return gossipMessage(topic) case AttesterSlashingSubnetTopicFormat: @@ -110,7 +110,7 @@ func init() { // Specially handle Electra objects. GossipTypeMapping[reflect.TypeOf(ðpb.SignedBeaconBlockElectra{})] = BlockSubnetTopicFormat - GossipTypeMapping[reflect.TypeOf(ðpb.AttestationElectra{})] = AttestationSubnetTopicFormat + GossipTypeMapping[reflect.TypeOf(ðpb.SingleAttestation{})] = AttestationSubnetTopicFormat GossipTypeMapping[reflect.TypeOf(ðpb.AttesterSlashingElectra{})] = AttesterSlashingSubnetTopicFormat GossipTypeMapping[reflect.TypeOf(ðpb.SignedAggregateAttestationAndProofElectra{})] = AggregateAndProofSubnetTopicFormat diff --git a/beacon-chain/p2p/gossip_topic_mappings_test.go b/beacon-chain/p2p/gossip_topic_mappings_test.go index bbfba9f39ffc..3bf5c938a54b 100644 --- a/beacon-chain/p2p/gossip_topic_mappings_test.go +++ b/beacon-chain/p2p/gossip_topic_mappings_test.go @@ -121,7 +121,7 @@ func TestGossipTopicMappings_CorrectType(t *testing.T) { _, ok = pMessage.(*ethpb.SignedBeaconBlockElectra) assert.Equal(t, true, ok) pMessage = GossipTopicMappings(AttestationSubnetTopicFormat, electraForkEpoch) - _, ok = pMessage.(*ethpb.AttestationElectra) + _, ok = pMessage.(*ethpb.SingleAttestation) assert.Equal(t, true, ok) pMessage = GossipTopicMappings(AttesterSlashingSubnetTopicFormat, electraForkEpoch) _, ok = pMessage.(*ethpb.AttesterSlashingElectra) diff --git a/beacon-chain/p2p/rpc_topic_mappings.go b/beacon-chain/p2p/rpc_topic_mappings.go index 1bb6b906e4e0..60d85f6198c3 100644 --- a/beacon-chain/p2p/rpc_topic_mappings.go +++ b/beacon-chain/p2p/rpc_topic_mappings.go @@ -90,18 +90,10 @@ const ( RPCBlocksByRootTopicV2 = protocolPrefix + BeaconBlocksByRootsMessageName + SchemaVersionV2 // RPCMetaDataTopicV2 defines the v2 topic for the metadata rpc method. RPCMetaDataTopicV2 = protocolPrefix + MetadataMessageName + SchemaVersionV2 - // RPCBlobSidecarsByRangeTopicV2 defines the v2 topic for the blob sidecars by range rpc method. - RPCBlobSidecarsByRangeTopicV2 = protocolPrefix + BlobSidecarsByRangeName + SchemaVersionV2 - // RPCBlobSidecarsByRootTopicV2 defines the v2 topic for the blob sidecars by root rpc method. - RPCBlobSidecarsByRootTopicV2 = protocolPrefix + BlobSidecarsByRootName + SchemaVersionV2 // V3 RPC Topics // RPCMetaDataTopicV3 defines the v3 topic for the metadata rpc method. RPCMetaDataTopicV3 = protocolPrefix + MetadataMessageName + SchemaVersionV3 - // RPCBlobSidecarsByRangeTopicV3 defines the v3 topic for the blob sidecars by range rpc method. - RPCBlobSidecarsByRangeTopicV3 = protocolPrefix + BlobSidecarsByRangeName + SchemaVersionV3 - // RPCBlobSidecarsByRootTopicV3 defines the v3 topic for the blob sidecars by root rpc method. - RPCBlobSidecarsByRootTopicV3 = protocolPrefix + BlobSidecarsByRootName + SchemaVersionV3 ) // RPC errors for topic parsing. diff --git a/beacon-chain/p2p/service_test.go b/beacon-chain/p2p/service_test.go index 7908eea35629..5471f837f3dd 100644 --- a/beacon-chain/p2p/service_test.go +++ b/beacon-chain/p2p/service_test.go @@ -26,6 +26,8 @@ import ( logTest "github.com/sirupsen/logrus/hooks/test" ) +const testPingInterval = 100 * time.Millisecond + type mockListener struct { localNode *enode.LocalNode } @@ -184,7 +186,7 @@ func TestListenForNewNodes(t *testing.T) { params.SetupTestConfigCleanup(t) // Setup bootnode. notifier := &mock.MockStateNotifier{} - cfg := &Config{StateNotifier: notifier} + cfg := &Config{StateNotifier: notifier, PingInterval: testPingInterval, DisableLivenessCheck: true} port := 2000 cfg.UDPPort = uint(port) _, pkey := createAddrAndPrivKey(t) @@ -200,6 +202,17 @@ func TestListenForNewNodes(t *testing.T) { require.NoError(t, err) defer bootListener.Close() + // Allow bootnode's table to have its initial refresh. This allows + // inbound nodes to be added in. + time.Sleep(5 * time.Second) + + // Use shorter period for testing. + currentPeriod := pollingPeriod + pollingPeriod = 1 * time.Second + defer func() { + pollingPeriod = currentPeriod + }() + bootNode := bootListener.Self() var listeners []*listenerWrapper @@ -208,6 +221,8 @@ func TestListenForNewNodes(t *testing.T) { cs := startup.NewClockSynchronizer() cfg = &Config{ Discv5BootStrapAddrs: []string{bootNode.String()}, + PingInterval: testPingInterval, + DisableLivenessCheck: true, MaxPeers: 30, ClockWaiter: cs, } diff --git a/beacon-chain/p2p/subnets_test.go b/beacon-chain/p2p/subnets_test.go index 668324025d52..5de61f378499 100644 --- a/beacon-chain/p2p/subnets_test.go +++ b/beacon-chain/p2p/subnets_test.go @@ -66,7 +66,7 @@ func TestStartDiscV5_FindPeersWithSubnet(t *testing.T) { genesisTime := time.Now() bootNodeService := &Service{ - cfg: &Config{UDPPort: 2000, TCPPort: 3000, QUICPort: 3000}, + cfg: &Config{UDPPort: 2000, TCPPort: 3000, QUICPort: 3000, DisableLivenessCheck: true, PingInterval: testPingInterval}, genesisTime: genesisTime, genesisValidatorsRoot: genesisValidatorsRoot, } @@ -78,6 +78,10 @@ func TestStartDiscV5_FindPeersWithSubnet(t *testing.T) { require.NoError(t, err) defer bootListener.Close() + // Allow bootnode's table to have its initial refresh. This allows + // inbound nodes to be added in. + time.Sleep(5 * time.Second) + bootNodeENR := bootListener.Self().String() // Create 3 nodes, each subscribed to a different subnet. @@ -92,6 +96,8 @@ func TestStartDiscV5_FindPeersWithSubnet(t *testing.T) { UDPPort: uint(2000 + i), TCPPort: uint(3000 + i), QUICPort: uint(3000 + i), + PingInterval: testPingInterval, + DisableLivenessCheck: true, }) require.NoError(t, err) @@ -133,6 +139,8 @@ func TestStartDiscV5_FindPeersWithSubnet(t *testing.T) { cfg := &Config{ Discv5BootStrapAddrs: []string{bootNodeENR}, + PingInterval: testPingInterval, + DisableLivenessCheck: true, MaxPeers: 30, UDPPort: 2010, TCPPort: 3010, diff --git a/beacon-chain/p2p/types/object_mapping.go b/beacon-chain/p2p/types/object_mapping.go index 7a502f39d174..4e26606713d6 100644 --- a/beacon-chain/p2p/types/object_mapping.go +++ b/beacon-chain/p2p/types/object_mapping.go @@ -120,7 +120,7 @@ func InitializeDataMaps() { return ðpb.Attestation{}, nil }, bytesutil.ToBytes4(params.BeaconConfig().ElectraForkVersion): func() (ethpb.Att, error) { - return ðpb.AttestationElectra{}, nil + return ðpb.SingleAttestation{}, nil }, bytesutil.ToBytes4(params.BeaconConfig().FuluForkVersion): func() (ethpb.Att, error) { return ðpb.AttestationElectra{}, nil diff --git a/beacon-chain/rpc/endpoints.go b/beacon-chain/rpc/endpoints.go index 14d5ad147329..97682b995fee 100644 --- a/beacon-chain/rpc/endpoints.go +++ b/beacon-chain/rpc/endpoints.go @@ -532,6 +532,7 @@ func (s *Service) beaconEndpoints( FinalizationFetcher: s.cfg.FinalizationFetcher, ForkchoiceFetcher: s.cfg.ForkchoiceFetcher, CoreService: coreService, + AttestationStateFetcher: s.cfg.AttestationReceiver, } const namespace = "beacon" diff --git a/beacon-chain/rpc/eth/beacon/handlers.go b/beacon-chain/rpc/eth/beacon/handlers.go index c90c84daa25c..0438ed450724 100644 --- a/beacon-chain/rpc/eth/beacon/handlers.go +++ b/beacon-chain/rpc/eth/beacon/handlers.go @@ -1229,7 +1229,8 @@ func (s *Server) validateBlobSidecars(blk interfaces.SignedBeaconBlock, blobs [] return errors.New("number of blobs, proofs, and commitments do not match") } for i, blob := range blobs { - if err := kzg4844.VerifyBlobProof(kzg4844.Blob(blob), kzg4844.Commitment(kzgs[i]), kzg4844.Proof(proofs[i])); err != nil { + b := kzg4844.Blob(blob) + if err := kzg4844.VerifyBlobProof(&b, kzg4844.Commitment(kzgs[i]), kzg4844.Proof(proofs[i])); err != nil { return errors.Wrap(err, "could not verify blob proof") } } diff --git a/beacon-chain/rpc/eth/beacon/handlers_pool.go b/beacon-chain/rpc/eth/beacon/handlers_pool.go index 978913b49032..7e5f31951398 100644 --- a/beacon-chain/rpc/eth/beacon/handlers_pool.go +++ b/beacon-chain/rpc/eth/beacon/handlers_pool.go @@ -285,8 +285,11 @@ func (s *Server) SubmitAttestationsV2(w http.ResponseWriter, r *http.Request) { } } -func (s *Server) handleAttestationsElectra(ctx context.Context, data json.RawMessage) (attFailures []*server.IndexedVerificationFailure, failedBroadcasts []string, err error) { - var sourceAttestations []*structs.AttestationElectra +func (s *Server) handleAttestationsElectra( + ctx context.Context, + data json.RawMessage, +) (attFailures []*server.IndexedVerificationFailure, failedBroadcasts []string, err error) { + var sourceAttestations []*structs.SingleAttestation if err = json.Unmarshal(data, &sourceAttestations); err != nil { return nil, nil, errors.Wrap(err, "failed to unmarshal attestation") @@ -296,7 +299,7 @@ func (s *Server) handleAttestationsElectra(ctx context.Context, data json.RawMes return nil, nil, errors.New("no data submitted") } - var validAttestations []*eth.AttestationElectra + var validAttestations []*eth.SingleAttestation for i, sourceAtt := range sourceAttestations { att, err := sourceAtt.ToConsensus() if err != nil { @@ -316,18 +319,23 @@ func (s *Server) handleAttestationsElectra(ctx context.Context, data json.RawMes validAttestations = append(validAttestations, att) } - for i, att := range validAttestations { - // Broadcast the unaggregated attestation on a feed to notify other services in the beacon node - // of a received unaggregated attestation. - // Note we can't send for aggregated att because we don't have selection proof. - if !att.IsAggregated() { - s.OperationNotifier.OperationFeed().Send(&feed.Event{ - Type: operation.UnaggregatedAttReceived, - Data: &operation.UnAggregatedAttReceivedData{ - Attestation: att, - }, - }) + for i, singleAtt := range validAttestations { + targetState, err := s.AttestationStateFetcher.AttestationTargetState(ctx, singleAtt.Data.Target) + if err != nil { + return nil, nil, errors.Wrap(err, "could not get target state for attestation") + } + committee, err := corehelpers.BeaconCommitteeFromState(ctx, targetState, singleAtt.Data.Slot, singleAtt.CommitteeId) + if err != nil { + return nil, nil, errors.Wrap(err, "could not get committee for attestation") } + att := singleAtt.ToAttestationElectra(committee) + + s.OperationNotifier.OperationFeed().Send(&feed.Event{ + Type: operation.UnaggregatedAttReceived, + Data: &operation.UnAggregatedAttReceivedData{ + Attestation: att, + }, + }) wantedEpoch := slots.ToEpoch(att.Data.Slot) vals, err := s.HeadFetcher.HeadValidatorsIndices(ctx, wantedEpoch) @@ -335,12 +343,8 @@ func (s *Server) handleAttestationsElectra(ctx context.Context, data json.RawMes failedBroadcasts = append(failedBroadcasts, strconv.Itoa(i)) continue } - committeeIndex, err := att.GetCommitteeIndex() - if err != nil { - return nil, nil, errors.Wrap(err, "failed to retrieve attestation committee index") - } - subnet := corehelpers.ComputeSubnetFromCommitteeAndSlot(uint64(len(vals)), committeeIndex, att.Data.Slot) - if err = s.Broadcaster.BroadcastAttestation(ctx, subnet, att); err != nil { + subnet := corehelpers.ComputeSubnetFromCommitteeAndSlot(uint64(len(vals)), att.GetCommitteeIndex(), att.Data.Slot) + if err = s.Broadcaster.BroadcastAttestation(ctx, subnet, singleAtt); err != nil { log.WithError(err).Errorf("could not broadcast attestation at index %d", i) failedBroadcasts = append(failedBroadcasts, strconv.Itoa(i)) continue @@ -350,13 +354,9 @@ func (s *Server) handleAttestationsElectra(ctx context.Context, data json.RawMes if err = s.AttestationCache.Add(att); err != nil { log.WithError(err).Error("could not save attestation") } - } else if att.IsAggregated() { - if err = s.AttestationsPool.SaveAggregatedAttestation(att); err != nil { - log.WithError(err).Error("could not save aggregated attestation") - } } else { if err = s.AttestationsPool.SaveUnaggregatedAttestation(att); err != nil { - log.WithError(err).Error("could not save unaggregated attestation") + log.WithError(err).Error("could not save attestation") } } } diff --git a/beacon-chain/rpc/eth/beacon/handlers_pool_test.go b/beacon-chain/rpc/eth/beacon/handlers_pool_test.go index be3f31a3883e..f612f942c816 100644 --- a/beacon-chain/rpc/eth/beacon/handlers_pool_test.go +++ b/beacon-chain/rpc/eth/beacon/handlers_pool_test.go @@ -498,13 +498,17 @@ func TestSubmitAttestations(t *testing.T) { c.SlotsPerEpoch = 1 params.OverrideBeaconConfig(c) - _, keys, err := util.DeterministicDepositsAndKeys(1) + _, keys, err := util.DeterministicDepositsAndKeys(2) require.NoError(t, err) validators := []*ethpbv1alpha1.Validator{ { PublicKey: keys[0].PublicKey().Marshal(), ExitEpoch: params.BeaconConfig().FarFutureEpoch, }, + { + PublicKey: keys[1].PublicKey().Marshal(), + ExitEpoch: params.BeaconConfig().FarFutureEpoch, + }, } bs, err := util.NewBeaconState(func(state *ethpbv1alpha1.BeaconState) error { state.Validators = validators @@ -521,9 +525,10 @@ func TestSubmitAttestations(t *testing.T) { chainService := &blockchainmock.ChainService{State: bs} s := &Server{ - HeadFetcher: chainService, - ChainInfoFetcher: chainService, - OperationNotifier: &blockchainmock.MockOperationNotifier{}, + HeadFetcher: chainService, + ChainInfoFetcher: chainService, + OperationNotifier: &blockchainmock.MockOperationNotifier{}, + AttestationStateFetcher: chainService, } t.Run("V1", func(t *testing.T) { t.Run("single", func(t *testing.T) { @@ -732,7 +737,7 @@ func TestSubmitAttestations(t *testing.T) { assert.Equal(t, http.StatusOK, writer.Code) assert.Equal(t, true, broadcaster.BroadcastCalled.Load()) assert.Equal(t, 1, broadcaster.NumAttestations()) - assert.Equal(t, "0x03", hexutil.Encode(broadcaster.BroadcastAttestations[0].GetAggregationBits())) + assert.Equal(t, primitives.ValidatorIndex(1), broadcaster.BroadcastAttestations[0].GetAttestingIndex()) assert.Equal(t, "0x8146f4397bfd8fd057ebbcd6a67327bdc7ed5fb650533edcb6377b650dea0b6da64c14ecd60846d5c0a0cd43893d6972092500f82c9d8a955e2b58c5ed3cbe885d84008ace6bd86ba9e23652f58e2ec207cec494c916063257abf285b9b15b15", hexutil.Encode(broadcaster.BroadcastAttestations[0].GetSignature())) assert.Equal(t, primitives.Slot(0), broadcaster.BroadcastAttestations[0].GetData().Slot) assert.Equal(t, primitives.CommitteeIndex(0), broadcaster.BroadcastAttestations[0].GetData().CommitteeIndex) @@ -2344,8 +2349,8 @@ var ( ]` singleAttElectra = `[ { - "aggregation_bits": "0x03", - "committee_bits": "0x0100000000000000", + "committee_index": "0", + "attester_index": "1", "signature": "0x8146f4397bfd8fd057ebbcd6a67327bdc7ed5fb650533edcb6377b650dea0b6da64c14ecd60846d5c0a0cd43893d6972092500f82c9d8a955e2b58c5ed3cbe885d84008ace6bd86ba9e23652f58e2ec207cec494c916063257abf285b9b15b15", "data": { "slot": "0", @@ -2364,8 +2369,8 @@ var ( ]` multipleAttsElectra = `[ { - "aggregation_bits": "0x03", - "committee_bits": "0x0100000000000000", + "committee_index": "0", + "attester_index": "0", "signature": "0x8146f4397bfd8fd057ebbcd6a67327bdc7ed5fb650533edcb6377b650dea0b6da64c14ecd60846d5c0a0cd43893d6972092500f82c9d8a955e2b58c5ed3cbe885d84008ace6bd86ba9e23652f58e2ec207cec494c916063257abf285b9b15b15", "data": { "slot": "0", @@ -2382,8 +2387,8 @@ var ( } }, { - "aggregation_bits": "0x03", - "committee_bits": "0x0100000000000000", + "committee_index": "0", + "attester_index": "1", "signature": "0x8146f4397bfd8fd057ebbcd6a67327bdc7ed5fb650533edcb6377b650dea0b6da64c14ecd60846d5c0a0cd43893d6972092500f82c9d8a955e2b58c5ed3cbe885d84008ace6bd86ba9e23652f58e2ec207cec494c916063257abf285b9b15b15", "data": { "slot": "0", @@ -2403,8 +2408,8 @@ var ( // signature is invalid invalidAttElectra = `[ { - "aggregation_bits": "0x03", - "committee_bits": "0x0100000000000000", + "committee_index": "0", + "attester_index": "0", "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "data": { "slot": "0", diff --git a/beacon-chain/rpc/eth/beacon/server.go b/beacon-chain/rpc/eth/beacon/server.go index f0af9e9f539c..4ac573288705 100644 --- a/beacon-chain/rpc/eth/beacon/server.go +++ b/beacon-chain/rpc/eth/beacon/server.go @@ -50,4 +50,5 @@ type Server struct { BLSChangesPool blstoexec.PoolManager ForkchoiceFetcher blockchain.ForkchoiceFetcher CoreService *core.Service + AttestationStateFetcher blockchain.AttestationStateFetcher } diff --git a/beacon-chain/rpc/eth/config/handlers_test.go b/beacon-chain/rpc/eth/config/handlers_test.go index 2d1aec5b7024..eaa7c64697c7 100644 --- a/beacon-chain/rpc/eth/config/handlers_test.go +++ b/beacon-chain/rpc/eth/config/handlers_test.go @@ -191,7 +191,7 @@ func TestGetSpec(t *testing.T) { data, ok := resp.Data.(map[string]interface{}) require.Equal(t, true, ok) - assert.Equal(t, 165, len(data)) + assert.Equal(t, 164, len(data)) for k, v := range data { t.Run(k, func(t *testing.T) { switch k { @@ -538,8 +538,6 @@ func TestGetSpec(t *testing.T) { assert.Equal(t, "9", v) case "MAX_REQUEST_BLOB_SIDECARS_ELECTRA": assert.Equal(t, "1152", v) - case "MAX_REQUEST_BLOB_SIDECARS_FULU": - assert.Equal(t, "1536", v) case "NUMBER_OF_CUSTODY_GROUPS": assert.Equal(t, "128", v) case "CUSTODY_REQUIREMENT": diff --git a/beacon-chain/rpc/eth/light-client/handlers.go b/beacon-chain/rpc/eth/light-client/handlers.go index 5e550c1855c3..84db74dc067b 100644 --- a/beacon-chain/rpc/eth/light-client/handlers.go +++ b/beacon-chain/rpc/eth/light-client/handlers.go @@ -10,7 +10,6 @@ import ( "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v5/api" "github.com/prysmaticlabs/prysm/v5/api/server/structs" - lightclient "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/light-client" "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared" "github.com/prysmaticlabs/prysm/v5/config/features" "github.com/prysmaticlabs/prysm/v5/config/params" @@ -35,41 +34,34 @@ func (s *Server) GetLightClientBootstrap(w http.ResponseWriter, req *http.Reques // Get the block blockRootParam, err := hexutil.Decode(req.PathValue("block_root")) if err != nil { - httputil.HandleError(w, "invalid block root: "+err.Error(), http.StatusBadRequest) + httputil.HandleError(w, "Invalid block root: "+err.Error(), http.StatusBadRequest) return } blockRoot := bytesutil.ToBytes32(blockRootParam) - blk, err := s.Blocker.Block(ctx, blockRoot[:]) - if !shared.WriteBlockFetchError(w, blk, err) { - return - } - - // Get the state - state, err := s.Stater.StateBySlot(ctx, blk.Block().Slot()) + bootstrap, err := s.BeaconDB.LightClientBootstrap(ctx, blockRoot[:]) if err != nil { - httputil.HandleError(w, "could not get state: "+err.Error(), http.StatusInternalServerError) + httputil.HandleError(w, "Could not get light client bootstrap: "+err.Error(), http.StatusInternalServerError) return } - - bootstrap, err := lightclient.NewLightClientBootstrapFromBeaconState(ctx, s.ChainInfoFetcher.CurrentSlot(), state, blk) - if err != nil { - httputil.HandleError(w, "could not get light client bootstrap: "+err.Error(), http.StatusInternalServerError) + if bootstrap == nil { + httputil.HandleError(w, "Light client bootstrap not found", http.StatusNotFound) return } + w.Header().Set(api.VersionHeader, version.String(bootstrap.Version())) if httputil.RespondWithSsz(req) { ssz, err := bootstrap.MarshalSSZ() if err != nil { - httputil.HandleError(w, "could not marshal bootstrap to SSZ: "+err.Error(), http.StatusInternalServerError) + httputil.HandleError(w, "Could not marshal bootstrap to SSZ: "+err.Error(), http.StatusInternalServerError) return } httputil.WriteSsz(w, ssz, "light_client_bootstrap.ssz") } else { data, err := structs.LightClientBootstrapFromConsensus(bootstrap) if err != nil { - httputil.HandleError(w, "could not marshal bootstrap to JSON: "+err.Error(), http.StatusInternalServerError) + httputil.HandleError(w, "Could not marshal bootstrap to JSON: "+err.Error(), http.StatusInternalServerError) return } response := &structs.LightClientBootstrapResponse{ diff --git a/beacon-chain/rpc/eth/light-client/handlers_test.go b/beacon-chain/rpc/eth/light-client/handlers_test.go index 8679c25c0913..ee15a8d34be2 100644 --- a/beacon-chain/rpc/eth/light-client/handlers_test.go +++ b/beacon-chain/rpc/eth/light-client/handlers_test.go @@ -53,27 +53,28 @@ func TestLightClientHandler_GetLightClientBootstrap(t *testing.T) { l := util.NewTestLightClient(t).SetupTestAltair() slot := primitives.Slot(params.BeaconConfig().AltairForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1) - stateRoot, err := l.State.HashTreeRoot(l.Ctx) + blockRoot, err := l.Block.Block().HashTreeRoot() + require.NoError(t, err) + + bootstrap, err := lightclient.NewLightClientBootstrapFromBeaconState(l.Ctx, slot, l.State, l.Block) + require.NoError(t, err) + + db := dbtesting.SetupDB(t) + + err = db.SaveLightClientBootstrap(l.Ctx, blockRoot[:], bootstrap) require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - mockChainInfoFetcher := &mock.ChainService{Slot: &slot} s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - ChainInfoFetcher: mockChainInfoFetcher, + BeaconDB: db, } request := httptest.NewRequest("GET", "http://foo.com/", nil) - request.SetPathValue("block_root", hexutil.Encode(stateRoot[:])) + request.SetPathValue("block_root", hexutil.Encode(blockRoot[:])) writer := httptest.NewRecorder() writer.Body = &bytes.Buffer{} s.GetLightClientBootstrap(writer, request) require.Equal(t, http.StatusOK, writer.Code) + var resp structs.LightClientBootstrapResponse err = json.Unmarshal(writer.Body.Bytes(), &resp) require.NoError(t, err) @@ -90,6 +91,32 @@ func TestLightClientHandler_GetLightClientBootstrap(t *testing.T) { require.NotNil(t, resp.Data.CurrentSyncCommittee) require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) }) + t.Run("altair - no bootstrap found", func(t *testing.T) { + l := util.NewTestLightClient(t).SetupTestAltair() + + slot := primitives.Slot(params.BeaconConfig().AltairForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1) + blockRoot, err := l.Block.Block().HashTreeRoot() + require.NoError(t, err) + + bootstrap, err := lightclient.NewLightClientBootstrapFromBeaconState(l.Ctx, slot, l.State, l.Block) + require.NoError(t, err) + + db := dbtesting.SetupDB(t) + + err = db.SaveLightClientBootstrap(l.Ctx, blockRoot[1:], bootstrap) + require.NoError(t, err) + + s := &Server{ + BeaconDB: db, + } + request := httptest.NewRequest("GET", "http://foo.com/", nil) + request.SetPathValue("block_root", hexutil.Encode(blockRoot[:])) + writer := httptest.NewRecorder() + writer.Body = &bytes.Buffer{} + + s.GetLightClientBootstrap(writer, request) + require.Equal(t, http.StatusNotFound, writer.Code) + }) t.Run("bellatrix", func(t *testing.T) { l := util.NewTestLightClient(t).SetupTestBellatrix() @@ -97,16 +124,16 @@ func TestLightClientHandler_GetLightClientBootstrap(t *testing.T) { blockRoot, err := l.Block.Block().HashTreeRoot() require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + bootstrap, err := lightclient.NewLightClientBootstrapFromBeaconState(l.Ctx, slot, l.State, l.Block) + require.NoError(t, err) + + db := dbtesting.SetupDB(t) + + err = db.SaveLightClientBootstrap(l.Ctx, blockRoot[:], bootstrap) + require.NoError(t, err) + s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - ChainInfoFetcher: mockChainInfoFetcher, + BeaconDB: db, } request := httptest.NewRequest("GET", "http://foo.com/", nil) request.SetPathValue("block_root", hexutil.Encode(blockRoot[:])) @@ -138,16 +165,16 @@ func TestLightClientHandler_GetLightClientBootstrap(t *testing.T) { blockRoot, err := l.Block.Block().HashTreeRoot() require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + bootstrap, err := lightclient.NewLightClientBootstrapFromBeaconState(l.Ctx, slot, l.State, l.Block) + require.NoError(t, err) + + db := dbtesting.SetupDB(t) + + err = db.SaveLightClientBootstrap(l.Ctx, blockRoot[:], bootstrap) + require.NoError(t, err) + s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - ChainInfoFetcher: mockChainInfoFetcher, + BeaconDB: db, } request := httptest.NewRequest("GET", "http://foo.com/", nil) request.SetPathValue("block_root", hexutil.Encode(blockRoot[:])) @@ -179,16 +206,16 @@ func TestLightClientHandler_GetLightClientBootstrap(t *testing.T) { blockRoot, err := l.Block.Block().HashTreeRoot() require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - mockChainInfoFetcher := &mock.ChainService{Slot: &slot} + bootstrap, err := lightclient.NewLightClientBootstrapFromBeaconState(l.Ctx, slot, l.State, l.Block) + require.NoError(t, err) + + db := dbtesting.SetupDB(t) + + err = db.SaveLightClientBootstrap(l.Ctx, blockRoot[:], bootstrap) + require.NoError(t, err) + s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - ChainInfoFetcher: mockChainInfoFetcher, + BeaconDB: db, } request := httptest.NewRequest("GET", "http://foo.com/", nil) request.SetPathValue("block_root", hexutil.Encode(blockRoot[:])) @@ -220,57 +247,16 @@ func TestLightClientHandler_GetLightClientBootstrap(t *testing.T) { blockRoot, err := l.Block.Block().HashTreeRoot() require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - mockChainInfoFetcher := &mock.ChainService{Slot: &slot} - s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - ChainInfoFetcher: mockChainInfoFetcher, - } - request := httptest.NewRequest("GET", "http://foo.com/", nil) - request.SetPathValue("block_root", hexutil.Encode(blockRoot[:])) - writer := httptest.NewRecorder() - writer.Body = &bytes.Buffer{} - - s.GetLightClientBootstrap(writer, request) - require.Equal(t, http.StatusOK, writer.Code) - var resp structs.LightClientBootstrapResponse - err = json.Unmarshal(writer.Body.Bytes(), &resp) - require.NoError(t, err) - var respHeader structs.LightClientHeader - err = json.Unmarshal(resp.Data.Header, &respHeader) - require.NoError(t, err) - require.Equal(t, "electra", resp.Version) - - blockHeader, err := l.Block.Header() + bootstrap, err := lightclient.NewLightClientBootstrapFromBeaconState(l.Ctx, slot, l.State, l.Block) require.NoError(t, err) - require.Equal(t, hexutil.Encode(blockHeader.Header.BodyRoot), respHeader.Beacon.BodyRoot) - require.Equal(t, strconv.FormatUint(uint64(blockHeader.Header.Slot), 10), respHeader.Beacon.Slot) - require.NotNil(t, resp.Data.CurrentSyncCommittee) - require.NotNil(t, resp.Data.CurrentSyncCommitteeBranch) - }) - t.Run("fulu", func(t *testing.T) { - l := util.NewTestLightClient(t).SetupTestFulu(false) // result is same for true and false + db := dbtesting.SetupDB(t) - slot := primitives.Slot(params.BeaconConfig().FuluForkEpoch * primitives.Epoch(params.BeaconConfig().SlotsPerEpoch)).Add(1) - blockRoot, err := l.Block.Block().HashTreeRoot() + err = db.SaveLightClientBootstrap(l.Ctx, blockRoot[:], bootstrap) require.NoError(t, err) - mockBlocker := &testutil.MockBlocker{BlockToReturn: l.Block} - mockChainService := &mock.ChainService{Optimistic: true, Slot: &slot} - mockChainInfoFetcher := &mock.ChainService{Slot: &slot} s := &Server{ - Stater: &testutil.MockStater{StatesBySlot: map[primitives.Slot]state.BeaconState{ - slot: l.State, - }}, - Blocker: mockBlocker, - HeadFetcher: mockChainService, - ChainInfoFetcher: mockChainInfoFetcher, + BeaconDB: db, } request := httptest.NewRequest("GET", "http://foo.com/", nil) request.SetPathValue("block_root", hexutil.Encode(blockRoot[:])) diff --git a/beacon-chain/rpc/eth/validator/handlers.go b/beacon-chain/rpc/eth/validator/handlers.go index 255b28deeb07..913169e8e884 100644 --- a/beacon-chain/rpc/eth/validator/handlers.go +++ b/beacon-chain/rpc/eth/validator/handlers.go @@ -198,35 +198,20 @@ func matchingAtts(atts []ethpbalpha.Att, slot primitives.Slot, attDataRoot []byt continue } + root, err := att.GetData().HashTreeRoot() + if err != nil { + return nil, errors.Wrap(err, "could not get attestation data root") + } + if !bytes.Equal(root[:], attDataRoot) { + continue + } + // We ignore the committee index from the request before Electra. // This is because before Electra the committee index is part of the attestation data, // meaning that comparing the data root is sufficient. // Post-Electra the committee index in the data root is always 0, so we need to // compare the committee index separately. - if postElectra { - if att.Version() >= version.Electra { - ci, err := att.GetCommitteeIndex() - if err != nil { - return nil, err - } - if ci != index { - continue - } - } else { - continue - } - } else { - // If postElectra is false and att.Version >= version.Electra, ignore the attestation. - if att.Version() >= version.Electra { - continue - } - } - - root, err := att.GetData().HashTreeRoot() - if err != nil { - return nil, errors.Wrap(err, "could not get attestation data root") - } - if bytes.Equal(root[:], attDataRoot) { + if (!postElectra && att.Version() < version.Electra) || (postElectra && att.Version() >= version.Electra && att.GetCommitteeIndex() == index) { result = append(result, att) } } diff --git a/beacon-chain/rpc/prysm/v1alpha1/debug/server.go b/beacon-chain/rpc/prysm/v1alpha1/debug/server.go index d6bd27b41e47..e565a645651a 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/debug/server.go +++ b/beacon-chain/rpc/prysm/v1alpha1/debug/server.go @@ -56,9 +56,7 @@ func (_ *Server) SetLoggingLevel(_ context.Context, req *pbrpc.LoggingLevelReque // Libp2p specific logging. golog.SetAllLoggers(golog.LevelDebug) // Geth specific logging. - glogger := gethlog.NewGlogHandler(gethlog.StreamHandler(os.Stderr, gethlog.TerminalFormat(true))) - glogger.Verbosity(gethlog.LvlTrace) - gethlog.Root().SetHandler(glogger) + gethlog.SetDefault(gethlog.NewLogger(gethlog.NewTerminalHandlerWithLevel(os.Stderr, gethlog.LvlTrace, true))) } return &empty.Empty{}, nil } diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/attester.go b/beacon-chain/rpc/prysm/v1alpha1/validator/attester.go index cde312e8e197..72767fd2f791 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/attester.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/attester.go @@ -13,6 +13,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/crypto/bls" "github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/time/slots" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -45,7 +46,7 @@ func (vs *Server) ProposeAttestation(ctx context.Context, att *ethpb.Attestation ctx, span := trace.StartSpan(ctx, "AttesterServer.ProposeAttestation") defer span.End() - resp, err := vs.proposeAtt(ctx, att, att.GetData().CommitteeIndex) + resp, err := vs.proposeAtt(ctx, att, nil, att.GetData().CommitteeIndex) if err != nil { return nil, err } @@ -69,20 +70,27 @@ func (vs *Server) ProposeAttestation(ctx context.Context, att *ethpb.Attestation // ProposeAttestationElectra is a function called by an attester to vote // on a block via an attestation object as defined in the Ethereum specification. -func (vs *Server) ProposeAttestationElectra(ctx context.Context, att *ethpb.AttestationElectra) (*ethpb.AttestResponse, error) { +func (vs *Server) ProposeAttestationElectra(ctx context.Context, singleAtt *ethpb.SingleAttestation) (*ethpb.AttestResponse, error) { ctx, span := trace.StartSpan(ctx, "AttesterServer.ProposeAttestationElectra") defer span.End() - committeeIndex, err := att.GetCommitteeIndex() + targetState, err := vs.AttestationStateFetcher.AttestationTargetState(ctx, singleAtt.Data.Target) if err != nil { - return nil, err + return nil, status.Error(codes.Internal, "Could not get target state") + } + committeeIndex := singleAtt.GetCommitteeIndex() + committee, err := helpers.BeaconCommitteeFromState(ctx, targetState, singleAtt.Data.Slot, committeeIndex) + if err != nil { + return nil, status.Error(codes.Internal, "Could not get committee") } - resp, err := vs.proposeAtt(ctx, att, committeeIndex) + resp, err := vs.proposeAtt(ctx, singleAtt, committee, committeeIndex) if err != nil { return nil, err } + singleAttCopy := singleAtt.Copy() + att := singleAttCopy.ToAttestationElectra(committee) if features.Get().EnableExperimentalAttestationPool { if err = vs.AttestationCache.Add(att); err != nil { log.WithError(err).Error("Could not save attestation") @@ -90,8 +98,7 @@ func (vs *Server) ProposeAttestationElectra(ctx context.Context, att *ethpb.Atte } else { go func() { ctx = trace.NewContext(context.Background(), trace.FromContext(ctx)) - attCopy := att.Copy() - if err := vs.AttPool.SaveUnaggregatedAttestation(attCopy); err != nil { + if err := vs.AttPool.SaveUnaggregatedAttestation(att); err != nil { log.WithError(err).Error("Could not save unaggregated attestation") return } @@ -149,14 +156,29 @@ func (vs *Server) SubscribeCommitteeSubnets(ctx context.Context, req *ethpb.Comm return &emptypb.Empty{}, nil } -func (vs *Server) proposeAtt(ctx context.Context, att ethpb.Att, committee primitives.CommitteeIndex) (*ethpb.AttestResponse, error) { +func (vs *Server) proposeAtt( + ctx context.Context, + att ethpb.Att, + committee []primitives.ValidatorIndex, // required post-Electra + committeeIndex primitives.CommitteeIndex, +) (*ethpb.AttestResponse, error) { if _, err := bls.SignatureFromBytes(att.GetSignature()); err != nil { return nil, status.Error(codes.InvalidArgument, "Incorrect attestation signature") } root, err := att.GetData().HashTreeRoot() if err != nil { - return nil, status.Errorf(codes.Internal, "Could not tree hash attestation: %v", err) + return nil, status.Errorf(codes.Internal, "Could not get attestation root: %v", err) + } + + var singleAtt *ethpb.SingleAttestation + if att.Version() >= version.Electra { + var ok bool + singleAtt, ok = att.(*ethpb.SingleAttestation) + if !ok { + return nil, status.Errorf(codes.Internal, "Attestation has wrong type (expected %T, got %T)", ðpb.SingleAttestation{}, att) + } + att = singleAtt.ToAttestationElectra(committee) } // Broadcast the unaggregated attestation on a feed to notify other services in the beacon node @@ -174,10 +196,16 @@ func (vs *Server) proposeAtt(ctx context.Context, att ethpb.Att, committee primi if err != nil { return nil, err } - subnet := helpers.ComputeSubnetFromCommitteeAndSlot(uint64(len(vals)), committee, att.GetData().Slot) + subnet := helpers.ComputeSubnetFromCommitteeAndSlot(uint64(len(vals)), committeeIndex, att.GetData().Slot) // Broadcast the new attestation to the network. - if err := vs.P2P.BroadcastAttestation(ctx, subnet, att); err != nil { + var attToBroadcast ethpb.Att + if singleAtt != nil { + attToBroadcast = singleAtt + } else { + attToBroadcast = att + } + if err := vs.P2P.BroadcastAttestation(ctx, subnet, attToBroadcast); err != nil { return nil, status.Errorf(codes.Internal, "Could not broadcast attestation: %v", err) } diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/attester_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/attester_test.go index 556afed89f20..6a5bab8c9bb4 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/attester_test.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/attester_test.go @@ -31,11 +31,13 @@ import ( ) func TestProposeAttestation(t *testing.T) { + chainService := &mock.ChainService{} attesterServer := &Server{ - HeadFetcher: &mock.ChainService{}, - P2P: &mockp2p.MockBroadcaster{}, - AttPool: attestations.NewPool(), - OperationNotifier: (&mock.ChainService{}).OperationNotifier(), + HeadFetcher: chainService, + P2P: &mockp2p.MockBroadcaster{}, + AttPool: attestations.NewPool(), + OperationNotifier: (&mock.ChainService{}).OperationNotifier(), + AttestationStateFetcher: chainService, } head := util.NewBeaconBlock() head.Block.Slot = 999 @@ -79,81 +81,19 @@ func TestProposeAttestation(t *testing.T) { require.NoError(t, err) require.NoError(t, state.SetSlot(params.BeaconConfig().SlotsPerEpoch+1)) require.NoError(t, state.SetValidators(validators)) + chainService.State = state - cb := primitives.NewAttestationCommitteeBits() - cb.SetBitAt(0, true) - req := ðpb.AttestationElectra{ + req := ðpb.SingleAttestation{ Signature: sig.Marshal(), Data: ðpb.AttestationData{ BeaconBlockRoot: root[:], Source: ðpb.Checkpoint{Root: make([]byte, 32)}, Target: ðpb.Checkpoint{Root: make([]byte, 32)}, }, - CommitteeBits: cb, } _, err = attesterServer.ProposeAttestationElectra(context.Background(), req) assert.NoError(t, err) }) - t.Run("Electra - non-zero committee index", func(t *testing.T) { - state, err := util.NewBeaconStateElectra() - require.NoError(t, err) - require.NoError(t, state.SetSlot(params.BeaconConfig().SlotsPerEpoch+1)) - require.NoError(t, state.SetValidators(validators)) - - cb := primitives.NewAttestationCommitteeBits() - cb.SetBitAt(0, true) - req := ðpb.AttestationElectra{ - Signature: sig.Marshal(), - Data: ðpb.AttestationData{ - BeaconBlockRoot: root[:], - Source: ðpb.Checkpoint{Root: make([]byte, 32)}, - Target: ðpb.Checkpoint{Root: make([]byte, 32)}, - CommitteeIndex: 1, - }, - CommitteeBits: cb, - } - _, err = attesterServer.ProposeAttestationElectra(context.Background(), req) - assert.ErrorContains(t, "attestation data's committee index must be 0 but was 1", err) - }) - t.Run("Electra - no committee bit set", func(t *testing.T) { - state, err := util.NewBeaconStateElectra() - require.NoError(t, err) - require.NoError(t, state.SetSlot(params.BeaconConfig().SlotsPerEpoch+1)) - require.NoError(t, state.SetValidators(validators)) - - req := ðpb.AttestationElectra{ - Signature: sig.Marshal(), - Data: ðpb.AttestationData{ - BeaconBlockRoot: root[:], - Source: ðpb.Checkpoint{Root: make([]byte, 32)}, - Target: ðpb.Checkpoint{Root: make([]byte, 32)}, - }, - CommitteeBits: primitives.NewAttestationCommitteeBits(), - } - _, err = attesterServer.ProposeAttestationElectra(context.Background(), req) - assert.ErrorContains(t, "exactly 1 committee index must be set but 0 were set", err) - }) - t.Run("Electra - multiple committee bits set", func(t *testing.T) { - state, err := util.NewBeaconStateElectra() - require.NoError(t, err) - require.NoError(t, state.SetSlot(params.BeaconConfig().SlotsPerEpoch+1)) - require.NoError(t, state.SetValidators(validators)) - - cb := primitives.NewAttestationCommitteeBits() - cb.SetBitAt(0, true) - cb.SetBitAt(1, true) - req := ðpb.AttestationElectra{ - Signature: sig.Marshal(), - Data: ðpb.AttestationData{ - BeaconBlockRoot: root[:], - Source: ðpb.Checkpoint{Root: make([]byte, 32)}, - Target: ðpb.Checkpoint{Root: make([]byte, 32)}, - }, - CommitteeBits: cb, - } - _, err = attesterServer.ProposeAttestationElectra(context.Background(), req) - assert.ErrorContains(t, "exactly 1 committee index must be set but 2 were set", err) - }) } func TestProposeAttestation_IncorrectSignature(t *testing.T) { diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/server.go b/beacon-chain/rpc/prysm/v1alpha1/validator/server.go index da0f3e1ed89d..24cffce1d76c 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/server.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/server.go @@ -42,44 +42,45 @@ import ( // and committees in which particular validators need to perform their responsibilities, // and more. type Server struct { - Ctx context.Context - PayloadIDCache *cache.PayloadIDCache - TrackedValidatorsCache *cache.TrackedValidatorsCache - HeadFetcher blockchain.HeadFetcher - ForkFetcher blockchain.ForkFetcher - ForkchoiceFetcher blockchain.ForkchoiceFetcher - GenesisFetcher blockchain.GenesisFetcher - FinalizationFetcher blockchain.FinalizationFetcher - TimeFetcher blockchain.TimeFetcher - BlockFetcher execution.POWBlockFetcher - DepositFetcher cache.DepositFetcher - ChainStartFetcher execution.ChainStartFetcher - Eth1InfoFetcher execution.ChainInfoFetcher - OptimisticModeFetcher blockchain.OptimisticModeFetcher - SyncChecker sync.Checker - StateNotifier statefeed.Notifier - BlockNotifier blockfeed.Notifier - P2P p2p.Broadcaster - AttestationCache *cache.AttestationCache - AttPool attestations.Pool - SlashingsPool slashings.PoolManager - ExitPool voluntaryexits.PoolManager - SyncCommitteePool synccommittee.Pool - BlockReceiver blockchain.BlockReceiver - BlobReceiver blockchain.BlobReceiver - DataColumnReceiver blockchain.DataColumnReceiver - MockEth1Votes bool - Eth1BlockFetcher execution.POWBlockFetcher - PendingDepositsFetcher depositsnapshot.PendingDepositsFetcher - OperationNotifier opfeed.Notifier - StateGen stategen.StateManager - ReplayerBuilder stategen.ReplayerBuilder - BeaconDB db.HeadAccessDatabase - ExecutionEngineCaller execution.EngineCaller - BlockBuilder builder.BlockBuilder - BLSChangesPool blstoexec.PoolManager - ClockWaiter startup.ClockWaiter - CoreService *core.Service + Ctx context.Context + PayloadIDCache *cache.PayloadIDCache + TrackedValidatorsCache *cache.TrackedValidatorsCache + HeadFetcher blockchain.HeadFetcher + ForkFetcher blockchain.ForkFetcher + ForkchoiceFetcher blockchain.ForkchoiceFetcher + GenesisFetcher blockchain.GenesisFetcher + FinalizationFetcher blockchain.FinalizationFetcher + TimeFetcher blockchain.TimeFetcher + BlockFetcher execution.POWBlockFetcher + DepositFetcher cache.DepositFetcher + ChainStartFetcher execution.ChainStartFetcher + Eth1InfoFetcher execution.ChainInfoFetcher + OptimisticModeFetcher blockchain.OptimisticModeFetcher + SyncChecker sync.Checker + StateNotifier statefeed.Notifier + BlockNotifier blockfeed.Notifier + P2P p2p.Broadcaster + AttestationCache *cache.AttestationCache + AttPool attestations.Pool + SlashingsPool slashings.PoolManager + ExitPool voluntaryexits.PoolManager + SyncCommitteePool synccommittee.Pool + BlockReceiver blockchain.BlockReceiver + BlobReceiver blockchain.BlobReceiver + DataColumnReceiver blockchain.DataColumnReceiver + MockEth1Votes bool + Eth1BlockFetcher execution.POWBlockFetcher + PendingDepositsFetcher depositsnapshot.PendingDepositsFetcher + OperationNotifier opfeed.Notifier + StateGen stategen.StateManager + ReplayerBuilder stategen.ReplayerBuilder + BeaconDB db.HeadAccessDatabase + ExecutionEngineCaller execution.EngineCaller + BlockBuilder builder.BlockBuilder + BLSChangesPool blstoexec.PoolManager + ClockWaiter startup.ClockWaiter + CoreService *core.Service + AttestationStateFetcher blockchain.AttestationStateFetcher } // WaitForActivation checks if a validator public key exists in the active validator registry of the current diff --git a/beacon-chain/rpc/service.go b/beacon-chain/rpc/service.go index c51f91b07f19..7d35ff21db0e 100644 --- a/beacon-chain/rpc/service.go +++ b/beacon-chain/rpc/service.go @@ -213,44 +213,45 @@ func NewService(ctx context.Context, cfg *Config) *Service { OptimisticModeFetcher: s.cfg.OptimisticModeFetcher, } validatorServer := &validatorv1alpha1.Server{ - Ctx: s.ctx, - AttestationCache: s.cfg.AttestationCache, - AttPool: s.cfg.AttestationsPool, - ExitPool: s.cfg.ExitPool, - HeadFetcher: s.cfg.HeadFetcher, - ForkFetcher: s.cfg.ForkFetcher, - ForkchoiceFetcher: s.cfg.ForkchoiceFetcher, - GenesisFetcher: s.cfg.GenesisFetcher, - FinalizationFetcher: s.cfg.FinalizationFetcher, - TimeFetcher: s.cfg.GenesisTimeFetcher, - BlockFetcher: s.cfg.ExecutionChainService, - DepositFetcher: s.cfg.DepositFetcher, - ChainStartFetcher: s.cfg.ChainStartFetcher, - Eth1InfoFetcher: s.cfg.ExecutionChainService, - OptimisticModeFetcher: s.cfg.OptimisticModeFetcher, - SyncChecker: s.cfg.SyncService, - StateNotifier: s.cfg.StateNotifier, - BlockNotifier: s.cfg.BlockNotifier, - OperationNotifier: s.cfg.OperationNotifier, - P2P: s.cfg.Broadcaster, - BlockReceiver: s.cfg.BlockReceiver, - BlobReceiver: s.cfg.BlobReceiver, - DataColumnReceiver: s.cfg.DataColumnReceiver, - MockEth1Votes: s.cfg.MockEth1Votes, - Eth1BlockFetcher: s.cfg.ExecutionChainService, - PendingDepositsFetcher: s.cfg.PendingDepositFetcher, - SlashingsPool: s.cfg.SlashingsPool, - StateGen: s.cfg.StateGen, - SyncCommitteePool: s.cfg.SyncCommitteeObjectPool, - ReplayerBuilder: ch, - ExecutionEngineCaller: s.cfg.ExecutionEngineCaller, - BeaconDB: s.cfg.BeaconDB, - BlockBuilder: s.cfg.BlockBuilder, - BLSChangesPool: s.cfg.BLSChangesPool, - ClockWaiter: s.cfg.ClockWaiter, - CoreService: coreService, - TrackedValidatorsCache: s.cfg.TrackedValidatorsCache, - PayloadIDCache: s.cfg.PayloadIDCache, + Ctx: s.ctx, + AttestationCache: s.cfg.AttestationCache, + AttPool: s.cfg.AttestationsPool, + ExitPool: s.cfg.ExitPool, + HeadFetcher: s.cfg.HeadFetcher, + ForkFetcher: s.cfg.ForkFetcher, + ForkchoiceFetcher: s.cfg.ForkchoiceFetcher, + GenesisFetcher: s.cfg.GenesisFetcher, + FinalizationFetcher: s.cfg.FinalizationFetcher, + TimeFetcher: s.cfg.GenesisTimeFetcher, + BlockFetcher: s.cfg.ExecutionChainService, + DepositFetcher: s.cfg.DepositFetcher, + ChainStartFetcher: s.cfg.ChainStartFetcher, + Eth1InfoFetcher: s.cfg.ExecutionChainService, + OptimisticModeFetcher: s.cfg.OptimisticModeFetcher, + SyncChecker: s.cfg.SyncService, + StateNotifier: s.cfg.StateNotifier, + BlockNotifier: s.cfg.BlockNotifier, + OperationNotifier: s.cfg.OperationNotifier, + P2P: s.cfg.Broadcaster, + BlockReceiver: s.cfg.BlockReceiver, + BlobReceiver: s.cfg.BlobReceiver, + DataColumnReceiver: s.cfg.DataColumnReceiver, + MockEth1Votes: s.cfg.MockEth1Votes, + Eth1BlockFetcher: s.cfg.ExecutionChainService, + PendingDepositsFetcher: s.cfg.PendingDepositFetcher, + SlashingsPool: s.cfg.SlashingsPool, + StateGen: s.cfg.StateGen, + SyncCommitteePool: s.cfg.SyncCommitteeObjectPool, + ReplayerBuilder: ch, + ExecutionEngineCaller: s.cfg.ExecutionEngineCaller, + BeaconDB: s.cfg.BeaconDB, + BlockBuilder: s.cfg.BlockBuilder, + BLSChangesPool: s.cfg.BLSChangesPool, + ClockWaiter: s.cfg.ClockWaiter, + CoreService: coreService, + TrackedValidatorsCache: s.cfg.TrackedValidatorsCache, + PayloadIDCache: s.cfg.PayloadIDCache, + AttestationStateFetcher: s.cfg.AttestationReceiver, } s.validatorServer = validatorServer nodeServer := &nodev1alpha1.Server{ diff --git a/beacon-chain/sync/BUILD.bazel b/beacon-chain/sync/BUILD.bazel index 69fd93bd92e6..798e929e6641 100644 --- a/beacon-chain/sync/BUILD.bazel +++ b/beacon-chain/sync/BUILD.bazel @@ -49,7 +49,6 @@ go_library( "validate_aggregate_proof.go", "validate_attester_slashing.go", "validate_beacon_attestation.go", - "validate_beacon_attestation_electra.go", "validate_beacon_blocks.go", "validate_blob.go", "validate_bls_to_execution_change.go", @@ -190,7 +189,6 @@ go_test( "sync_test.go", "validate_aggregate_proof_test.go", "validate_attester_slashing_test.go", - "validate_beacon_attestation_electra_test.go", "validate_beacon_attestation_test.go", "validate_beacon_blocks_test.go", "validate_blob_test.go", diff --git a/beacon-chain/sync/blobs_test.go b/beacon-chain/sync/blobs_test.go index 5b22de484fb7..8415a8c4fec1 100644 --- a/beacon-chain/sync/blobs_test.go +++ b/beacon-chain/sync/blobs_test.go @@ -220,16 +220,8 @@ func (c *blobsTestCase) setup(t *testing.T) (*Service, []blocks.ROBlob, func()) byRootRate := params.BeaconConfig().MaxRequestBlobSidecars * uint64(params.BeaconConfig().MaxBlobsPerBlock(0)) byRangeRate := params.BeaconConfig().MaxRequestBlobSidecars * uint64(params.BeaconConfig().MaxBlobsPerBlock(0)) - byRootRateElectra := params.BeaconConfig().MaxRequestBlobSidecarsElectra * uint64(params.BeaconConfig().MaxBlobsPerBlock(0)) - byRangeRateElectra := params.BeaconConfig().MaxRequestBlobSidecarsElectra * uint64(params.BeaconConfig().MaxBlobsPerBlock(0)) - byRootRateFulu := params.BeaconConfig().MaxRequestBlobSidecarsFulu * uint64(params.BeaconConfig().MaxBlobsPerBlock(0)) - byRangeRateFulu := params.BeaconConfig().MaxRequestBlobSidecarsFulu * uint64(params.BeaconConfig().MaxBlobsPerBlock(0)) s.setRateCollector(p2p.RPCBlobSidecarsByRootTopicV1, leakybucket.NewCollector(0.000001, int64(byRootRate), time.Second, false)) s.setRateCollector(p2p.RPCBlobSidecarsByRangeTopicV1, leakybucket.NewCollector(0.000001, int64(byRangeRate), time.Second, false)) - s.setRateCollector(p2p.RPCBlobSidecarsByRootTopicV2, leakybucket.NewCollector(0.000001, int64(byRootRateElectra), time.Second, false)) - s.setRateCollector(p2p.RPCBlobSidecarsByRangeTopicV2, leakybucket.NewCollector(0.000001, int64(byRangeRateElectra), time.Second, false)) - s.setRateCollector(p2p.RPCBlobSidecarsByRootTopicV3, leakybucket.NewCollector(0.000001, int64(byRootRateFulu), time.Second, false)) - s.setRateCollector(p2p.RPCBlobSidecarsByRangeTopicV3, leakybucket.NewCollector(0.000001, int64(byRangeRateFulu), time.Second, false)) return s, sidecars, cleanup } diff --git a/beacon-chain/sync/decode_pubsub_test.go b/beacon-chain/sync/decode_pubsub_test.go index 009737227807..403c39304b75 100644 --- a/beacon-chain/sync/decode_pubsub_test.go +++ b/beacon-chain/sync/decode_pubsub_test.go @@ -276,7 +276,7 @@ func TestExtractDataType(t *testing.T) { return wsb }(), wantMd: wrapper.WrappedMetadataV1(ðpb.MetaDataV1{}), - wantAtt: ðpb.AttestationElectra{}, + wantAtt: ðpb.SingleAttestation{}, wantAggregate: ðpb.SignedAggregateAttestationAndProofElectra{}, wantErr: false, }, diff --git a/beacon-chain/sync/fork_watcher_test.go b/beacon-chain/sync/fork_watcher_test.go index fc6c49d6ebcd..0263add8492f 100644 --- a/beacon-chain/sync/fork_watcher_test.go +++ b/beacon-chain/sync/fork_watcher_test.go @@ -228,8 +228,8 @@ func TestService_CheckForNextEpochFork(t *testing.T) { for _, p := range s.cfg.p2p.Host().Mux().Protocols() { rpcMap[string(p)] = true } - assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRangeTopicV2+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist") - assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRootTopicV2+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist") + assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRangeTopicV1+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist") + assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRootTopicV1+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist") }, }, { @@ -272,8 +272,8 @@ func TestService_CheckForNextEpochFork(t *testing.T) { for _, p := range s.cfg.p2p.Host().Mux().Protocols() { rpcMap[string(p)] = true } - assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRangeTopicV3+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist") - assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRootTopicV3+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist") + assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRangeTopicV1+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist") + assert.Equal(t, true, rpcMap[p2p.RPCBlobSidecarsByRootTopicV1+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist") assert.Equal(t, true, rpcMap[p2p.RPCMetaDataTopicV3+s.cfg.p2p.Encoding().ProtocolSuffix()], "topic doesn't exist") }, }, diff --git a/beacon-chain/sync/pending_attestations_queue.go b/beacon-chain/sync/pending_attestations_queue.go index 4201737af5e6..90f0f8fbb3e2 100644 --- a/beacon-chain/sync/pending_attestations_queue.go +++ b/beacon-chain/sync/pending_attestations_queue.go @@ -91,86 +91,127 @@ func (s *Service) processPendingAtts(ctx context.Context) error { func (s *Service) processAttestations(ctx context.Context, attestations []ethpb.SignedAggregateAttAndProof) { for _, signedAtt := range attestations { - aggregate := signedAtt.AggregateAttestationAndProof().AggregateVal() - data := aggregate.GetData() + att := signedAtt.AggregateAttestationAndProof().AggregateVal() // The pending attestations can arrive in both aggregated and unaggregated forms, // each from has distinct validation steps. - if aggregate.IsAggregated() { - // Save the pending aggregated attestation to the pool if it passes the aggregated - // validation steps. - valRes, err := s.validateAggregatedAtt(ctx, signedAtt) - if err != nil { - log.WithError(err).Debug("Pending aggregated attestation failed validation") - } - aggValid := pubsub.ValidationAccept == valRes - if s.validateBlockInAttestation(ctx, signedAtt) && aggValid { - if features.Get().EnableExperimentalAttestationPool { - if err = s.cfg.attestationCache.Add(aggregate); err != nil { - log.WithError(err).Debug("Could not save aggregate attestation") - continue - } - } else { - if err := s.cfg.attPool.SaveAggregatedAttestation(aggregate); err != nil { - log.WithError(err).Debug("Could not save aggregate attestation") - continue - } - } - - s.setAggregatorIndexEpochSeen(data.Target.Epoch, signedAtt.AggregateAttestationAndProof().GetAggregatorIndex()) - - // Broadcasting the signed attestation again once a node is able to process it. - if err := s.cfg.p2p.Broadcast(ctx, signedAtt); err != nil { - log.WithError(err).Debug("Could not broadcast") - } - } + if att.IsAggregated() { + s.processAggregated(ctx, signedAtt) } else { - // This is an important validation before retrieving attestation pre state to defend against - // attestation's target intentionally reference checkpoint that's long ago. - // Verify current finalized checkpoint is an ancestor of the block defined by the attestation's beacon block root. - if !s.cfg.chain.InForkchoice(bytesutil.ToBytes32(data.BeaconBlockRoot)) { - log.WithError(blockchain.ErrNotDescendantOfFinalized).Debug("Could not verify finalized consistency") - continue - } - if err := s.cfg.chain.VerifyLmdFfgConsistency(ctx, aggregate); err != nil { - log.WithError(err).Debug("Could not verify FFG consistency") - continue + s.processUnaggregated(ctx, att) + } + } +} + +func (s *Service) processAggregated(ctx context.Context, att ethpb.SignedAggregateAttAndProof) { + aggregate := att.AggregateAttestationAndProof().AggregateVal() + + // Save the pending aggregated attestation to the pool if it passes the aggregated + // validation steps. + valRes, err := s.validateAggregatedAtt(ctx, att) + if err != nil { + log.WithError(err).Debug("Pending aggregated attestation failed validation") + } + aggValid := pubsub.ValidationAccept == valRes + if s.validateBlockInAttestation(ctx, att) && aggValid { + if features.Get().EnableExperimentalAttestationPool { + if err = s.cfg.attestationCache.Add(aggregate); err != nil { + log.WithError(err).Debug("Could not save aggregate attestation") + return } - preState, err := s.cfg.chain.AttestationTargetState(ctx, data.Target) - if err != nil { - log.WithError(err).Debug("Could not retrieve attestation prestate") - continue + } else { + if err := s.cfg.attPool.SaveAggregatedAttestation(aggregate); err != nil { + log.WithError(err).Debug("Could not save aggregate attestation") + return } + } + + s.setAggregatorIndexEpochSeen(aggregate.GetData().Target.Epoch, att.AggregateAttestationAndProof().GetAggregatorIndex()) - valid, err := s.validateUnaggregatedAttWithState(ctx, aggregate, preState) - if err != nil { - log.WithError(err).Debug("Pending unaggregated attestation failed validation") - continue + // Broadcasting the signed attestation again once a node is able to process it. + if err := s.cfg.p2p.Broadcast(ctx, att); err != nil { + log.WithError(err).Debug("Could not broadcast") + } + } +} + +func (s *Service) processUnaggregated(ctx context.Context, att ethpb.Att) { + data := att.GetData() + + // This is an important validation before retrieving attestation pre state to defend against + // attestation's target intentionally reference checkpoint that's long ago. + // Verify current finalized checkpoint is an ancestor of the block defined by the attestation's beacon block root. + if !s.cfg.chain.InForkchoice(bytesutil.ToBytes32(data.BeaconBlockRoot)) { + log.WithError(blockchain.ErrNotDescendantOfFinalized).Debug("Could not verify finalized consistency") + return + } + if err := s.cfg.chain.VerifyLmdFfgConsistency(ctx, att); err != nil { + log.WithError(err).Debug("Could not verify FFG consistency") + return + } + preState, err := s.cfg.chain.AttestationTargetState(ctx, data.Target) + if err != nil { + log.WithError(err).Debug("Could not retrieve attestation prestate") + return + } + committee, err := helpers.BeaconCommitteeFromState(ctx, preState, data.Slot, att.GetCommitteeIndex()) + if err != nil { + log.WithError(err).Debug("Could not retrieve committee from state") + return + } + valid, err := validateAttesterData(ctx, att, committee) + if err != nil { + log.WithError(err).Debug("Could not validate attester data") + return + } else if valid != pubsub.ValidationAccept { + log.Debug("Attestation failed attester data validation") + return + } + + var singleAtt *ethpb.SingleAttestation + if att.Version() >= version.Electra { + var ok bool + singleAtt, ok = att.(*ethpb.SingleAttestation) + if !ok { + log.Debugf("Attestation has wrong type (expected %T, got %T)", ðpb.SingleAttestation{}, att) + return + } + att = singleAtt.ToAttestationElectra(committee) + } + + valid, err = s.validateUnaggregatedAttWithState(ctx, att, preState) + if err != nil { + log.WithError(err).Debug("Pending unaggregated attestation failed validation") + return + } + if valid == pubsub.ValidationAccept { + if features.Get().EnableExperimentalAttestationPool { + if err = s.cfg.attestationCache.Add(att); err != nil { + log.WithError(err).Debug("Could not save unaggregated attestation") + return } - if valid == pubsub.ValidationAccept { - if features.Get().EnableExperimentalAttestationPool { - if err = s.cfg.attestationCache.Add(aggregate); err != nil { - log.WithError(err).Debug("Could not save unaggregated attestation") - continue - } - } else { - if err := s.cfg.attPool.SaveUnaggregatedAttestation(aggregate); err != nil { - log.WithError(err).Debug("Could not save unaggregated attestation") - continue - } - } - s.setSeenCommitteeIndicesSlot(data.Slot, data.CommitteeIndex, aggregate.GetAggregationBits()) - - valCount, err := helpers.ActiveValidatorCount(ctx, preState, slots.ToEpoch(data.Slot)) - if err != nil { - log.WithError(err).Debug("Could not retrieve active validator count") - continue - } - // Broadcasting the signed attestation again once a node is able to process it. - if err := s.cfg.p2p.BroadcastAttestation(ctx, helpers.ComputeSubnetForAttestation(valCount, aggregate), aggregate); err != nil { - log.WithError(err).Debug("Could not broadcast") - } + } else { + if err := s.cfg.attPool.SaveUnaggregatedAttestation(att); err != nil { + log.WithError(err).Debug("Could not save unaggregated attestation") + return } } + s.setSeenCommitteeIndicesSlot(data.Slot, data.CommitteeIndex, att.GetAggregationBits()) + + valCount, err := helpers.ActiveValidatorCount(ctx, preState, slots.ToEpoch(data.Slot)) + if err != nil { + log.WithError(err).Debug("Could not retrieve active validator count") + return + } + // Broadcasting the signed attestation again once a node is able to process it. + var attToBroadcast ethpb.Att + if singleAtt != nil { + attToBroadcast = singleAtt + } else { + attToBroadcast = att + } + if err := s.cfg.p2p.BroadcastAttestation(ctx, helpers.ComputeSubnetForAttestation(valCount, attToBroadcast), attToBroadcast); err != nil { + log.WithError(err).Debug("Could not broadcast") + } } } @@ -211,6 +252,10 @@ func (s *Service) savePendingAtt(att ethpb.SignedAggregateAttAndProof) { } func attsAreEqual(a, b ethpb.SignedAggregateAttAndProof) bool { + if a.Version() != b.Version() { + return false + } + if a.GetSignature() != nil { return b.GetSignature() != nil && a.AggregateAttestationAndProof().GetAggregatorIndex() == b.AggregateAttestationAndProof().GetAggregatorIndex() } @@ -228,6 +273,12 @@ func attsAreEqual(a, b ethpb.SignedAggregateAttAndProof) bool { } if a.Version() >= version.Electra { + if aAggregate.IsSingle() != bAggregate.IsSingle() { + return false + } + if aAggregate.IsSingle() && aAggregate.GetAttestingIndex() != bAggregate.GetAttestingIndex() { + return false + } if !bytes.Equal(aAggregate.CommitteeBitsVal().Bytes(), bAggregate.CommitteeBitsVal().Bytes()) { return false } diff --git a/beacon-chain/sync/pending_attestations_queue_test.go b/beacon-chain/sync/pending_attestations_queue_test.go index cccdefa1fbc0..93aeb4389d73 100644 --- a/beacon-chain/sync/pending_attestations_queue_test.go +++ b/beacon-chain/sync/pending_attestations_queue_test.go @@ -92,18 +92,9 @@ func TestProcessPendingAtts_HasBlockSaveUnAggregatedAtt(t *testing.T) { att.Signature = privKeys[i].Sign(hashTreeRoot[:]).Marshal() } - // Arbitrary aggregator index for testing purposes. - aggregatorIndex := committee[0] - sszUint := primitives.SSZUint64(att.Data.Slot) - sig, err := signing.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[aggregatorIndex]) - require.NoError(t, err) aggregateAndProof := ðpb.AggregateAttestationAndProof{ - SelectionProof: sig, - Aggregate: att, - AggregatorIndex: aggregatorIndex, + Aggregate: att, } - aggreSig, err := signing.ComputeDomainAndSign(beaconState, 0, aggregateAndProof, params.BeaconConfig().DomainAggregateAndProof, privKeys[aggregatorIndex]) - require.NoError(t, err) require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix()))) @@ -134,7 +125,7 @@ func TestProcessPendingAtts_HasBlockSaveUnAggregatedAtt(t *testing.T) { require.NoError(t, err) require.NoError(t, r.cfg.beaconDB.SaveState(context.Background(), s, root)) - r.blkRootToPendingAtts[root] = []ethpb.SignedAggregateAttAndProof{ðpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof, Signature: aggreSig}} + r.blkRootToPendingAtts[root] = []ethpb.SignedAggregateAttAndProof{ðpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof}} require.NoError(t, r.processPendingAtts(context.Background())) atts, err := r.cfg.attPool.UnaggregatedAttestations() @@ -146,6 +137,80 @@ func TestProcessPendingAtts_HasBlockSaveUnAggregatedAtt(t *testing.T) { cancel() } +func TestProcessPendingAtts_HasBlockSaveUnAggregatedAttElectra(t *testing.T) { + hook := logTest.NewGlobal() + db := dbtest.SetupDB(t) + p1 := p2ptest.NewTestP2P(t) + validators := uint64(256) + + beaconState, privKeys := util.DeterministicGenesisStateElectra(t, validators) + + sb := util.NewBeaconBlockElectra() + util.SaveBlock(t, context.Background(), db, sb) + root, err := sb.Block.HashTreeRoot() + require.NoError(t, err) + + att := ðpb.SingleAttestation{ + Data: ðpb.AttestationData{ + BeaconBlockRoot: root[:], + Source: ðpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)}, + Target: ðpb.Checkpoint{Epoch: 0, Root: root[:]}, + }, + } + aggregateAndProof := ðpb.AggregateAttestationAndProofSingle{ + Aggregate: att, + } + + committee, err := helpers.BeaconCommitteeFromState(context.Background(), beaconState, att.Data.Slot, att.Data.CommitteeIndex) + assert.NoError(t, err) + att.AttesterIndex = committee[0] + attesterDomain, err := signing.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorsRoot()) + require.NoError(t, err) + hashTreeRoot, err := signing.ComputeSigningRoot(att.Data, attesterDomain) + assert.NoError(t, err) + att.Signature = privKeys[committee[0]].Sign(hashTreeRoot[:]).Marshal() + + require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix()))) + + chain := &mock.ChainService{Genesis: time.Now(), + State: beaconState, + FinalizedCheckPoint: ðpb.Checkpoint{ + Root: aggregateAndProof.Aggregate.Data.BeaconBlockRoot, + Epoch: 0, + }, + } + ctx, cancel := context.WithCancel(context.Background()) + r := &Service{ + ctx: ctx, + cfg: &config{ + p2p: p1, + beaconDB: db, + chain: chain, + clock: startup.NewClock(chain.Genesis, chain.ValidatorsRoot), + attPool: attestations.NewPool(), + }, + blkRootToPendingAtts: make(map[[32]byte][]ethpb.SignedAggregateAttAndProof), + seenUnAggregatedAttestationCache: lruwrpr.New(10), + signatureChan: make(chan *signatureVerifier, verifierLimit), + } + go r.verifierRoutine() + + s, err := util.NewBeaconStateElectra() + require.NoError(t, err) + require.NoError(t, r.cfg.beaconDB.SaveState(context.Background(), s, root)) + + r.blkRootToPendingAtts[root] = []ethpb.SignedAggregateAttAndProof{ðpb.SignedAggregateAttestationAndProofSingle{Message: aggregateAndProof}} + require.NoError(t, r.processPendingAtts(context.Background())) + + atts, err := r.cfg.attPool.UnaggregatedAttestations() + require.NoError(t, err) + require.Equal(t, 1, len(atts), "Did not save unaggregated att") + assert.DeepEqual(t, att.ToAttestationElectra(committee), atts[0], "Incorrect saved att") + assert.Equal(t, 0, len(r.cfg.attPool.AggregatedAttestations()), "Did save aggregated att") + require.LogsContain(t, hook, "Verified and saved pending attestations to pool") + cancel() +} + func TestProcessPendingAtts_NoBroadcastWithBadSignature(t *testing.T) { db := dbtest.SetupDB(t) p1 := p2ptest.NewTestP2P(t) @@ -465,12 +530,12 @@ func Test_attsAreEqual_Committee(t *testing.T) { Message: ðpb.AggregateAttestationAndProof{ Aggregate: ðpb.Attestation{ Data: ðpb.AttestationData{ - CommitteeIndex: 123}}}} + CommitteeIndex: 0}}}} att2 := ðpb.SignedAggregateAttestationAndProof{ Message: ðpb.AggregateAttestationAndProof{ Aggregate: ðpb.Attestation{ Data: ðpb.AttestationData{ - CommitteeIndex: 123}}}} + CommitteeIndex: 0}}}} assert.Equal(t, true, attsAreEqual(att1, att2)) }) t.Run("Phase 0 not equal", func(t *testing.T) { @@ -478,12 +543,12 @@ func Test_attsAreEqual_Committee(t *testing.T) { Message: ðpb.AggregateAttestationAndProof{ Aggregate: ðpb.Attestation{ Data: ðpb.AttestationData{ - CommitteeIndex: 123}}}} + CommitteeIndex: 0}}}} att2 := ðpb.SignedAggregateAttestationAndProof{ Message: ðpb.AggregateAttestationAndProof{ Aggregate: ðpb.Attestation{ Data: ðpb.AttestationData{ - CommitteeIndex: 456}}}} + CommitteeIndex: 1}}}} assert.Equal(t, false, attsAreEqual(att1, att2)) }) t.Run("Electra equal", func(t *testing.T) { @@ -524,4 +589,72 @@ func Test_attsAreEqual_Committee(t *testing.T) { }}} assert.Equal(t, false, attsAreEqual(att1, att2)) }) + t.Run("Single and Electra not equal", func(t *testing.T) { + cb := primitives.NewAttestationCommitteeBits() + cb.SetBitAt(0, true) + att1 := ðpb.SignedAggregateAttestationAndProofElectra{ + Message: ðpb.AggregateAttestationAndProofElectra{ + Aggregate: ðpb.AttestationElectra{ + Data: ðpb.AttestationData{}, + CommitteeBits: cb, + }}} + att2 := ðpb.SignedAggregateAttestationAndProofSingle{ + Message: ðpb.AggregateAttestationAndProofSingle{ + Aggregate: ðpb.SingleAttestation{ + CommitteeId: 0, + AttesterIndex: 0, + Data: ðpb.AttestationData{}, + }, + }, + } + assert.Equal(t, false, attsAreEqual(att1, att2)) + }) + t.Run("Single equal", func(t *testing.T) { + att1 := ðpb.SignedAggregateAttestationAndProofSingle{ + Message: ðpb.AggregateAttestationAndProofSingle{ + Aggregate: ðpb.SingleAttestation{ + CommitteeId: 0, + AttesterIndex: 0, + Data: ðpb.AttestationData{}, + }, + }, + } + att2 := ðpb.SignedAggregateAttestationAndProofSingle{ + Message: ðpb.AggregateAttestationAndProofSingle{ + Aggregate: ðpb.SingleAttestation{ + CommitteeId: 0, + AttesterIndex: 0, + Data: ðpb.AttestationData{}, + }, + }, + } + assert.Equal(t, true, attsAreEqual(att1, att2)) + }) + t.Run("Single not equal", func(t *testing.T) { + // Same AttesterIndex but different CommitteeId + att1 := ðpb.SignedAggregateAttestationAndProofSingle{ + Message: ðpb.AggregateAttestationAndProofSingle{ + Aggregate: ðpb.SingleAttestation{ + CommitteeId: 0, + AttesterIndex: 0, + Data: ðpb.AttestationData{}, + }, + }, + } + att2 := ðpb.SignedAggregateAttestationAndProofSingle{ + Message: ðpb.AggregateAttestationAndProofSingle{ + Aggregate: ðpb.SingleAttestation{ + CommitteeId: 1, + AttesterIndex: 0, + Data: ðpb.AttestationData{}, + }, + }, + } + assert.Equal(t, false, attsAreEqual(att1, att2)) + + // Same CommitteeId but different AttesterIndex + att2.Message.Aggregate.CommitteeId = 0 + att2.Message.Aggregate.AttesterIndex = 1 + assert.Equal(t, false, attsAreEqual(att1, att2)) + }) } diff --git a/beacon-chain/sync/rate_limiter.go b/beacon-chain/sync/rate_limiter.go index bc35ff3e6ff0..fe299e9e8749 100644 --- a/beacon-chain/sync/rate_limiter.go +++ b/beacon-chain/sync/rate_limiter.go @@ -88,8 +88,6 @@ func newRateLimiter(p2pProvider p2p.P2P) *limiter { topicMap[addEncoding(p2p.RPCBlobSidecarsByRootTopicV1)] = blobCollector // BlobSidecarsByRangeV1 topicMap[addEncoding(p2p.RPCBlobSidecarsByRangeTopicV1)] = blobCollector - topicMap[addEncoding(p2p.RPCBlobSidecarsByRootTopicV2)] = blobCollector - topicMap[addEncoding(p2p.RPCBlobSidecarsByRangeTopicV2)] = blobCollector // DataColumnSidecarsByRootV1 topicMap[addEncoding(p2p.RPCDataColumnSidecarsByRootTopicV1)] = columnCollector diff --git a/beacon-chain/sync/rate_limiter_test.go b/beacon-chain/sync/rate_limiter_test.go index b1c22a4c45ff..1514b6459b39 100644 --- a/beacon-chain/sync/rate_limiter_test.go +++ b/beacon-chain/sync/rate_limiter_test.go @@ -18,7 +18,7 @@ import ( func TestNewRateLimiter(t *testing.T) { rlimiter := newRateLimiter(mockp2p.NewTestP2P(t)) - assert.Equal(t, 17, len(rlimiter.limiterMap), "correct number of topics not registered") + assert.Equal(t, 15, len(rlimiter.limiterMap), "correct number of topics not registered") } func TestNewRateLimiter_FreeCorrectly(t *testing.T) { diff --git a/beacon-chain/sync/rpc.go b/beacon-chain/sync/rpc.go index fb145bb13876..4ab7b6d39c68 100644 --- a/beacon-chain/sync/rpc.go +++ b/beacon-chain/sync/rpc.go @@ -46,9 +46,9 @@ func (s *Service) rpcHandlerByTopicFromFork(forkIndex int) (map[string]rpcHandle p2p.RPCBlocksByRangeTopicV2: s.beaconBlocksByRangeRPCHandler, p2p.RPCBlocksByRootTopicV2: s.beaconBlocksRootRPCHandler, p2p.RPCPingTopicV1: s.pingHandler, - p2p.RPCMetaDataTopicV3: s.metaDataHandler, // Modified in Fulu - p2p.RPCBlobSidecarsByRootTopicV3: s.blobSidecarByRootRPCHandler, // Modified in Fulu - p2p.RPCBlobSidecarsByRangeTopicV3: s.blobSidecarsByRangeRPCHandler, // Modified in Fulu + p2p.RPCMetaDataTopicV3: s.metaDataHandler, // Updated in Fulu + p2p.RPCBlobSidecarsByRootTopicV1: s.blobSidecarByRootRPCHandler, + p2p.RPCBlobSidecarsByRangeTopicV1: s.blobSidecarsByRangeRPCHandler, p2p.RPCDataColumnSidecarsByRootTopicV1: s.dataColumnSidecarByRootRPCHandler, // Added in Fulu p2p.RPCDataColumnSidecarsByRangeTopicV1: s.dataColumnSidecarsByRangeRPCHandler, // Added in Fulu }, nil @@ -63,8 +63,8 @@ func (s *Service) rpcHandlerByTopicFromFork(forkIndex int) (map[string]rpcHandle p2p.RPCBlocksByRootTopicV2: s.beaconBlocksRootRPCHandler, p2p.RPCPingTopicV1: s.pingHandler, p2p.RPCMetaDataTopicV2: s.metaDataHandler, - p2p.RPCBlobSidecarsByRootTopicV2: s.blobSidecarByRootRPCHandler, // Modified in Electra - p2p.RPCBlobSidecarsByRangeTopicV2: s.blobSidecarsByRangeRPCHandler, // Modified in Electra + p2p.RPCBlobSidecarsByRootTopicV1: s.blobSidecarByRootRPCHandler, // Modified in Electra + p2p.RPCBlobSidecarsByRangeTopicV1: s.blobSidecarsByRangeRPCHandler, // Modified in Electra }, nil } @@ -73,8 +73,8 @@ func (s *Service) rpcHandlerByTopicFromFork(forkIndex int) (map[string]rpcHandle return map[string]rpcHandler{ p2p.RPCStatusTopicV1: s.statusRPCHandler, p2p.RPCGoodByeTopicV1: s.goodbyeRPCHandler, - p2p.RPCBlocksByRangeTopicV2: s.beaconBlocksByRangeRPCHandler, - p2p.RPCBlocksByRootTopicV2: s.beaconBlocksRootRPCHandler, + p2p.RPCBlocksByRangeTopicV2: s.beaconBlocksByRangeRPCHandler, // Modified in Deneb + p2p.RPCBlocksByRootTopicV2: s.beaconBlocksRootRPCHandler, // Modified in Deneb p2p.RPCPingTopicV1: s.pingHandler, p2p.RPCMetaDataTopicV2: s.metaDataHandler, p2p.RPCBlobSidecarsByRootTopicV1: s.blobSidecarByRootRPCHandler, // Added in Deneb @@ -89,10 +89,10 @@ func (s *Service) rpcHandlerByTopicFromFork(forkIndex int) (map[string]rpcHandle return map[string]rpcHandler{ p2p.RPCStatusTopicV1: s.statusRPCHandler, p2p.RPCGoodByeTopicV1: s.goodbyeRPCHandler, - p2p.RPCBlocksByRangeTopicV2: s.beaconBlocksByRangeRPCHandler, // Modified in Altair - p2p.RPCBlocksByRootTopicV2: s.beaconBlocksRootRPCHandler, // Modified in Altair + p2p.RPCBlocksByRangeTopicV2: s.beaconBlocksByRangeRPCHandler, // Updated in Altair and modified in Capella + p2p.RPCBlocksByRootTopicV2: s.beaconBlocksRootRPCHandler, // Updated in Altair and modified in Capella p2p.RPCPingTopicV1: s.pingHandler, - p2p.RPCMetaDataTopicV2: s.metaDataHandler, // Modified in Altair + p2p.RPCMetaDataTopicV2: s.metaDataHandler, // Updated in Altair }, nil } diff --git a/beacon-chain/sync/rpc_blob_sidecars_by_range.go b/beacon-chain/sync/rpc_blob_sidecars_by_range.go index c399b6c9042e..b1d8984829dd 100644 --- a/beacon-chain/sync/rpc_blob_sidecars_by_range.go +++ b/beacon-chain/sync/rpc_blob_sidecars_by_range.go @@ -110,10 +110,6 @@ func (s *Service) blobSidecarsByRangeRPCHandler(ctx context.Context, msg interfa wQuota = beaconConfig.MaxRequestBlobSidecarsElectra } - if currentEpoch >= beaconConfig.FuluForkEpoch { - wQuota = beaconConfig.MaxRequestBlobSidecarsFulu - } - for batch, ok = batcher.next(ctx, stream); ok; batch, ok = batcher.next(ctx, stream) { batchStart := time.Now() wQuota, err = s.streamBlobBatch(ctx, batch, wQuota, stream) diff --git a/beacon-chain/sync/rpc_blob_sidecars_by_root.go b/beacon-chain/sync/rpc_blob_sidecars_by_root.go index 53be92d096e2..6e8a01564902 100644 --- a/beacon-chain/sync/rpc_blob_sidecars_by_root.go +++ b/beacon-chain/sync/rpc_blob_sidecars_by_root.go @@ -111,14 +111,6 @@ func validateBlobByRootRequest(blobIdents types.BlobSidecarsByRootReq, slot prim epoch := slots.ToEpoch(slot) blobIdentCount := uint64(len(blobIdents)) - if epoch >= beaconConfig.FuluForkEpoch { - if blobIdentCount > beaconConfig.MaxRequestBlobSidecarsFulu { - return types.ErrMaxBlobReqExceeded - } - - return nil - } - if epoch >= beaconConfig.ElectraForkEpoch { if blobIdentCount > beaconConfig.MaxRequestBlobSidecarsElectra { return types.ErrMaxBlobReqExceeded diff --git a/beacon-chain/sync/rpc_send_request.go b/beacon-chain/sync/rpc_send_request.go index 94b00c074b25..68e2f61c5992 100644 --- a/beacon-chain/sync/rpc_send_request.go +++ b/beacon-chain/sync/rpc_send_request.go @@ -182,10 +182,6 @@ func SendBlobsByRangeRequest(ctx context.Context, tor blockchain.TemporalOracle, max = beaconConfig.MaxRequestBlobSidecarsElectra } - if startEpoch >= beaconConfig.FuluForkEpoch { - max = beaconConfig.MaxRequestBlobSidecarsFulu - } - if max > req.Count*maxBlobsPerBlock { max = req.Count * maxBlobsPerBlock } @@ -224,10 +220,6 @@ func SendBlobSidecarByRoot( max = beaconConfig.MaxRequestBlobSidecarsElectra } - if epoch >= beaconConfig.FuluForkEpoch { - max = beaconConfig.MaxRequestBlobSidecarsFulu - } - maxBlobCount := beaconConfig.MaxBlobsPerBlock(slot) if max > uint64(len(*req)*maxBlobCount) { max = uint64(len(*req) * maxBlobCount) diff --git a/beacon-chain/sync/subscriber_beacon_attestation.go b/beacon-chain/sync/subscriber_beacon_attestation.go index 15142c6d1baf..37c4c7972429 100644 --- a/beacon-chain/sync/subscriber_beacon_attestation.go +++ b/beacon-chain/sync/subscriber_beacon_attestation.go @@ -26,10 +26,7 @@ func (s *Service) committeeIndexBeaconAttestationSubscriber(_ context.Context, m if data == nil { return errors.New("nil attestation") } - committeeIndex, err := a.GetCommitteeIndex() - if err != nil { - return errors.Wrap(err, "committeeIndexBeaconAttestationSubscriber failed to get committee index") - } + committeeIndex := a.GetCommitteeIndex() s.setSeenCommitteeIndicesSlot(data.Slot, committeeIndex, a.GetAggregationBits()) if features.Get().EnableExperimentalAttestationPool { diff --git a/beacon-chain/sync/validate_aggregate_proof.go b/beacon-chain/sync/validate_aggregate_proof.go index e3a61d02e86c..ec692854fa3f 100644 --- a/beacon-chain/sync/validate_aggregate_proof.go +++ b/beacon-chain/sync/validate_aggregate_proof.go @@ -190,9 +190,16 @@ func (s *Service) validateAggregatedAtt(ctx context.Context, signed ethpb.Signed return result, err } - committee, result, err := s.validateBitLength(ctx, bs, aggregate.GetData().Slot, committeeIndex, aggregate.GetAggregationBits()) - if result != pubsub.ValidationAccept { - return result, err + committee, err := helpers.BeaconCommitteeFromState(ctx, bs, aggregate.GetData().Slot, committeeIndex) + if err != nil { + tracing.AnnotateError(span, err) + return pubsub.ValidationIgnore, err + } + + // Verify number of aggregation bits matches the committee size. + if err = helpers.VerifyBitfieldLength(aggregate.GetAggregationBits(), uint64(len(committee))); err != nil { + tracing.AnnotateError(span, err) + return pubsub.ValidationReject, err } // Verify validator index is within the beacon committee. diff --git a/beacon-chain/sync/validate_aggregate_proof_test.go b/beacon-chain/sync/validate_aggregate_proof_test.go index 6376e3f42d6e..b3e49fc8ac90 100644 --- a/beacon-chain/sync/validate_aggregate_proof_test.go +++ b/beacon-chain/sync/validate_aggregate_proof_test.go @@ -94,13 +94,6 @@ func TestVerifyIndexInCommittee_ExistsInBeaconCommittee(t *testing.T) { assert.ErrorContains(t, wanted, err) assert.Equal(t, pubsub.ValidationReject, result) - att.AggregationBits = bitfield.NewBitlist(1) - committeeIndex, err := att.GetCommitteeIndex() - require.NoError(t, err) - _, result, err = service.validateBitLength(ctx, s, att.Data.Slot, committeeIndex, att.AggregationBits) - require.ErrorContains(t, "wanted participants bitfield length 4, got: 1", err) - assert.Equal(t, pubsub.ValidationReject, result) - att.Data.CommitteeIndex = 10000 _, _, result, err = service.validateCommitteeIndexAndCount(ctx, att, s) require.ErrorContains(t, "committee index 10000 > 2", err) diff --git a/beacon-chain/sync/validate_beacon_attestation.go b/beacon-chain/sync/validate_beacon_attestation.go index 11c842e484bf..7948846cd70d 100644 --- a/beacon-chain/sync/validate_beacon_attestation.go +++ b/beacon-chain/sync/validate_beacon_attestation.go @@ -9,7 +9,6 @@ import ( pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p/core/peer" "github.com/pkg/errors" - "github.com/prysmaticlabs/go-bitfield" "github.com/prysmaticlabs/prysm/v5/beacon-chain/blockchain" "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks" "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/feed" @@ -71,14 +70,6 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p if data.Slot == 0 { return pubsub.ValidationIgnore, nil } - // Broadcast the unaggregated attestation on a feed to notify other services in the beacon node - // of a received unaggregated attestation. - s.cfg.attestationNotifier.OperationFeed().Send(&feed.Event{ - Type: operation.UnaggregatedAttReceived, - Data: &operation.UnAggregatedAttReceivedData{ - Attestation: att, - }, - }) // Attestation's slot is within ATTESTATION_PROPAGATION_SLOT_RANGE and early attestation // processing tolerance. @@ -91,14 +82,7 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p return pubsub.ValidationReject, err } - var validationRes pubsub.ValidationResult - - committeeIndex, result, err := s.validateCommitteeIndex(ctx, att) - if result != pubsub.ValidationAccept { - wrappedErr := errors.Wrapf(err, "could not validate committee index for %s version", version.String(att.Version())) - tracing.AnnotateError(span, wrappedErr) - return result, wrappedErr - } + committeeIndex := att.GetCommitteeIndex() if !features.Get().EnableSlasher { // Verify this the first attestation received for the participating validator for the slot. @@ -115,33 +99,19 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p } } + var validationRes pubsub.ValidationResult + // Verify the block being voted and the processed state is in beaconDB and the block has passed validation if it's in the beaconDB. blockRoot := bytesutil.ToBytes32(data.BeaconBlockRoot) if !s.hasBlockAndState(ctx, blockRoot) { - // A node doesn't have the block, it'll request from peer while saving the pending attestation to a queue. - if att.Version() >= version.Electra { - a, ok := att.(*eth.AttestationElectra) - // This will never fail in practice because we asserted the version - if !ok { - return pubsub.ValidationIgnore, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ð.AttestationElectra{}, att) - } - s.savePendingAtt(ð.SignedAggregateAttestationAndProofElectra{Message: ð.AggregateAttestationAndProofElectra{Aggregate: a}}) - } else { - a, ok := att.(*eth.Attestation) - // This will never fail in practice because we asserted the version - if !ok { - return pubsub.ValidationIgnore, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ð.Attestation{}, att) - } - s.savePendingAtt(ð.SignedAggregateAttestationAndProof{Message: ð.AggregateAttestationAndProof{Aggregate: a}}) - } - return pubsub.ValidationIgnore, nil + return s.saveToPendingAttPool(att) } if !s.cfg.chain.InForkchoice(bytesutil.ToBytes32(data.BeaconBlockRoot)) { tracing.AnnotateError(span, blockchain.ErrNotDescendantOfFinalized) return pubsub.ValidationIgnore, blockchain.ErrNotDescendantOfFinalized } - if err := s.cfg.chain.VerifyLmdFfgConsistency(ctx, att); err != nil { + if err = s.cfg.chain.VerifyLmdFfgConsistency(ctx, att); err != nil { tracing.AnnotateError(span, err) attBadLmdConsistencyCount.Inc() return pubsub.ValidationReject, err @@ -158,6 +128,25 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p return validationRes, err } + committee, err := helpers.BeaconCommitteeFromState(ctx, preState, att.GetData().Slot, committeeIndex) + if err != nil { + tracing.AnnotateError(span, err) + return pubsub.ValidationIgnore, err + } + + validationRes, err = validateAttesterData(ctx, att, committee) + if validationRes != pubsub.ValidationAccept { + return validationRes, err + } + + if att.Version() >= version.Electra { + singleAtt, ok := att.(*eth.SingleAttestation) + if !ok { + return pubsub.ValidationIgnore, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ð.SingleAttestation{}, att) + } + att = singleAtt.ToAttestationElectra(committee) + } + validationRes, err = s.validateUnaggregatedAttWithState(ctx, att, preState) if validationRes != pubsub.ValidationAccept { return validationRes, err @@ -192,6 +181,15 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p }() } + // Broadcast the unaggregated attestation on a feed to notify other services in the beacon node + // of a received unaggregated attestation. + s.cfg.attestationNotifier.OperationFeed().Send(&feed.Event{ + Type: operation.UnaggregatedAttReceived, + Data: &operation.UnAggregatedAttReceivedData{ + Attestation: att, + }, + }) + s.setSeenCommitteeIndicesSlot(data.Slot, committeeIndex, att.GetAggregationBits()) msg.ValidatorData = att @@ -227,44 +225,39 @@ func (s *Service) validateCommitteeIndexAndCount( a eth.Att, bs state.ReadOnlyBeaconState, ) (primitives.CommitteeIndex, uint64, pubsub.ValidationResult, error) { - ci, result, err := s.validateCommitteeIndex(ctx, a) - if result != pubsub.ValidationAccept { - return 0, 0, result, err + // - [REJECT] attestation.data.index == 0 + if a.Version() >= version.Electra && a.GetData().CommitteeIndex != 0 { + return 0, 0, pubsub.ValidationReject, errors.New("attestation data's committee index must be 0") } valCount, err := helpers.ActiveValidatorCount(ctx, bs, slots.ToEpoch(a.GetData().Slot)) if err != nil { return 0, 0, pubsub.ValidationIgnore, err } count := helpers.SlotCommitteeCount(valCount) + ci := a.GetCommitteeIndex() if uint64(ci) > count { - return 0, 0, pubsub.ValidationReject, fmt.Errorf("committee index %d > %d", a.GetData().CommitteeIndex, count) + return 0, 0, pubsub.ValidationReject, fmt.Errorf("committee index %d > %d", ci, count) } return ci, valCount, pubsub.ValidationAccept, nil } -func (s *Service) validateCommitteeIndex(ctx context.Context, a eth.Att) (primitives.CommitteeIndex, pubsub.ValidationResult, error) { +func validateAttesterData( + ctx context.Context, + a eth.Att, + committee []primitives.ValidatorIndex, +) (pubsub.ValidationResult, error) { if a.Version() >= version.Electra { - return validateCommitteeIndexElectra(ctx, a) - } - return a.GetData().CommitteeIndex, pubsub.ValidationAccept, nil -} - -// This validates beacon unaggregated attestation using the given state, the validation consists of bitfield length and count consistency -// and signature verification. -func (s *Service) validateUnaggregatedAttWithState(ctx context.Context, a eth.Att, bs state.ReadOnlyBeaconState) (pubsub.ValidationResult, error) { - ctx, span := trace.StartSpan(ctx, "sync.validateUnaggregatedAttWithState") - defer span.End() - - committeeIndex, err := a.GetCommitteeIndex() - if err != nil { - return pubsub.ValidationIgnore, err + singleAtt, ok := a.(*eth.SingleAttestation) + if !ok { + return pubsub.ValidationIgnore, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ð.SingleAttestation{}, a) + } + return validateAttestingIndex(ctx, singleAtt.AttesterIndex, committee) } - committee, result, err := s.validateBitLength(ctx, bs, a.GetData().Slot, committeeIndex, a.GetAggregationBits()) - if result != pubsub.ValidationAccept { - return result, err + // Verify number of aggregation bits matches the committee size. + if err := helpers.VerifyBitfieldLength(a.GetAggregationBits(), uint64(len(committee))); err != nil { + return pubsub.ValidationReject, err } - // Attestation must be unaggregated and the bit index must exist in the range of committee indices. // Note: The Ethereum Beacon chain spec suggests (len(get_attesting_indices(state, attestation.data, attestation.aggregation_bits)) == 1) // however this validation can be achieved without use of get_attesting_indices which is an O(n) lookup. @@ -272,33 +265,46 @@ func (s *Service) validateUnaggregatedAttWithState(ctx context.Context, a eth.At return pubsub.ValidationReject, errors.New("attestation bitfield is invalid") } + return pubsub.ValidationAccept, nil +} + +// This validates beacon unaggregated attestation using the given state, the validation consists of signature verification. +func (s *Service) validateUnaggregatedAttWithState(ctx context.Context, a eth.Att, bs state.ReadOnlyBeaconState) (pubsub.ValidationResult, error) { + ctx, span := trace.StartSpan(ctx, "sync.validateUnaggregatedAttWithState") + defer span.End() + set, err := blocks.AttestationSignatureBatch(ctx, bs, []eth.Att{a}) if err != nil { tracing.AnnotateError(span, err) attBadSignatureBatchCount.Inc() return pubsub.ValidationReject, err } + return s.validateWithBatchVerifier(ctx, "attestation", set) } -func (s *Service) validateBitLength( +func validateAttestingIndex( ctx context.Context, - bs state.ReadOnlyBeaconState, - slot primitives.Slot, - committeeIndex primitives.CommitteeIndex, - aggregationBits bitfield.Bitlist, -) ([]primitives.ValidatorIndex, pubsub.ValidationResult, error) { - committee, err := helpers.BeaconCommitteeFromState(ctx, bs, slot, committeeIndex) - if err != nil { - return nil, pubsub.ValidationIgnore, err - } + attestingIndex primitives.ValidatorIndex, + committee []primitives.ValidatorIndex, +) (pubsub.ValidationResult, error) { + _, span := trace.StartSpan(ctx, "sync.validateAttestingIndex") + defer span.End() - // Verify number of aggregation bits matches the committee size. - if err := helpers.VerifyBitfieldLength(aggregationBits, uint64(len(committee))); err != nil { - return nil, pubsub.ValidationReject, err + // _[REJECT]_ The attester is a member of the committee -- i.e. + // `attestation.attester_index in get_beacon_committee(state, attestation.data.slot, index)`. + inCommittee := false + for _, ix := range committee { + if attestingIndex == ix { + inCommittee = true + break + } + } + if !inCommittee { + return pubsub.ValidationReject, errors.New("attester is not a member of the committee") } - return committee, pubsub.ValidationAccept, nil + return pubsub.ValidationAccept, nil } // Returns true if the attestation was already seen for the participating validator for the slot. @@ -327,3 +333,31 @@ func (s *Service) hasBlockAndState(ctx context.Context, blockRoot [32]byte) bool hasState := hasStateSummary || s.cfg.beaconDB.HasState(ctx, blockRoot) return hasState && s.cfg.chain.HasBlock(ctx, blockRoot) } + +func (s *Service) saveToPendingAttPool(att eth.Att) (pubsub.ValidationResult, error) { + // A node doesn't have the block, it'll request from peer while saving the pending attestation to a queue. + if att.Version() >= version.Electra { + a, ok := att.(*eth.SingleAttestation) + // This will never fail in practice because we asserted the version + if !ok { + return pubsub.ValidationIgnore, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ð.SingleAttestation{}, att) + } + // Even though there is no AggregateAndProof type to hold a single attestation, our design of pending atts pool + // requires to have an AggregateAndProof object, even for unaggregated attestations. + // Because of this we need to have a single attestation version of it to be able to save single attestations into the pool. + // It's not possible to convert the single attestation into an electra attestation before saving to the pool + // because crucial verification steps can't be performed without the block, and converting prior to these checks + // opens up DoS attacks. + // The AggregateAndProof object is discarded once we process the pending attestation and code paths dealing + // with "real" AggregateAndProof objects (ones that hold actual aggregates) don't use the single attestation version anywhere. + s.savePendingAtt(ð.SignedAggregateAttestationAndProofSingle{Message: ð.AggregateAttestationAndProofSingle{Aggregate: a}}) + } else { + a, ok := att.(*eth.Attestation) + // This will never fail in practice because we asserted the version + if !ok { + return pubsub.ValidationIgnore, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ð.Attestation{}, att) + } + s.savePendingAtt(ð.SignedAggregateAttestationAndProof{Message: ð.AggregateAttestationAndProof{Aggregate: a}}) + } + return pubsub.ValidationIgnore, nil +} diff --git a/beacon-chain/sync/validate_beacon_attestation_electra.go b/beacon-chain/sync/validate_beacon_attestation_electra.go deleted file mode 100644 index 49c6fac2f5a4..000000000000 --- a/beacon-chain/sync/validate_beacon_attestation_electra.go +++ /dev/null @@ -1,28 +0,0 @@ -package sync - -import ( - "context" - "fmt" - - pubsub "github.com/libp2p/go-libp2p-pubsub" - "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - "github.com/prysmaticlabs/prysm/v5/monitoring/tracing/trace" - ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" -) - -// validateCommitteeIndexElectra implements the following checks from the spec: -// - [REJECT] len(committee_indices) == 1, where committee_indices = get_committee_indices(attestation). -// - [REJECT] attestation.data.index == 0 -func validateCommitteeIndexElectra(ctx context.Context, a ethpb.Att) (primitives.CommitteeIndex, pubsub.ValidationResult, error) { - _, span := trace.StartSpan(ctx, "sync.validateCommitteeIndexElectra") - defer span.End() - _, ok := a.(*ethpb.AttestationElectra) - if !ok { - return 0, pubsub.ValidationIgnore, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ðpb.AttestationElectra{}, a) - } - committeeIndex, err := a.GetCommitteeIndex() - if err != nil { - return 0, pubsub.ValidationReject, err - } - return committeeIndex, pubsub.ValidationAccept, nil -} diff --git a/beacon-chain/sync/validate_beacon_attestation_electra_test.go b/beacon-chain/sync/validate_beacon_attestation_electra_test.go deleted file mode 100644 index 81c8e2e9dff9..000000000000 --- a/beacon-chain/sync/validate_beacon_attestation_electra_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package sync - -import ( - "context" - "testing" - - pubsub "github.com/libp2p/go-libp2p-pubsub" - "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" - "github.com/prysmaticlabs/prysm/v5/testing/assert" - "github.com/prysmaticlabs/prysm/v5/testing/require" -) - -func Test_validateCommitteeIndexElectra(t *testing.T) { - ctx := context.Background() - - t.Run("valid", func(t *testing.T) { - cb := primitives.NewAttestationCommitteeBits() - cb.SetBitAt(1, true) - ci, res, err := validateCommitteeIndexElectra(ctx, ðpb.AttestationElectra{Data: ðpb.AttestationData{}, CommitteeBits: cb}) - require.NoError(t, err) - assert.Equal(t, pubsub.ValidationAccept, res) - assert.Equal(t, primitives.CommitteeIndex(1), ci) - }) - t.Run("non-zero data committee index", func(t *testing.T) { - cb := primitives.NewAttestationCommitteeBits() - cb.SetBitAt(1, true) - _, res, err := validateCommitteeIndexElectra(ctx, ðpb.AttestationElectra{Data: ðpb.AttestationData{CommitteeIndex: 1}, CommitteeBits: cb}) - assert.NotNil(t, err) - assert.Equal(t, pubsub.ValidationReject, res) - }) - t.Run("no committee bits set", func(t *testing.T) { - cb := primitives.NewAttestationCommitteeBits() - _, res, err := validateCommitteeIndexElectra(ctx, ðpb.AttestationElectra{Data: ðpb.AttestationData{}, CommitteeBits: cb}) - assert.NotNil(t, err) - assert.Equal(t, pubsub.ValidationReject, res) - }) - t.Run("more than 1 committee bit set", func(t *testing.T) { - cb := primitives.NewAttestationCommitteeBits() - cb.SetBitAt(0, true) - cb.SetBitAt(1, true) - _, res, err := validateCommitteeIndexElectra(ctx, ðpb.AttestationElectra{Data: ðpb.AttestationData{}, CommitteeBits: cb}) - assert.NotNil(t, err) - assert.Equal(t, pubsub.ValidationReject, res) - }) -} diff --git a/beacon-chain/sync/validate_beacon_attestation_test.go b/beacon-chain/sync/validate_beacon_attestation_test.go index 2451352fb421..70adc55e8534 100644 --- a/beacon-chain/sync/validate_beacon_attestation_test.go +++ b/beacon-chain/sync/validate_beacon_attestation_test.go @@ -20,6 +20,7 @@ import ( lruwrpr "github.com/prysmaticlabs/prysm/v5/cache/lru" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/testing/require" @@ -81,7 +82,7 @@ func TestService_validateCommitteeIndexBeaconAttestation(t *testing.T) { tests := []struct { name string - msg *ethpb.Attestation + msg ethpb.Att topic string validAttestationSignature bool want bool @@ -262,20 +263,20 @@ func TestService_validateCommitteeIndexBeaconAttestation(t *testing.T) { helpers.ClearCache() chain.ValidAttestation = tt.validAttestationSignature if tt.validAttestationSignature { - com, err := helpers.BeaconCommitteeFromState(context.Background(), savedState, tt.msg.Data.Slot, tt.msg.Data.CommitteeIndex) + com, err := helpers.BeaconCommitteeFromState(context.Background(), savedState, tt.msg.GetData().Slot, tt.msg.GetData().CommitteeIndex) require.NoError(t, err) - domain, err := signing.Domain(savedState.Fork(), tt.msg.Data.Target.Epoch, params.BeaconConfig().DomainBeaconAttester, savedState.GenesisValidatorsRoot()) + domain, err := signing.Domain(savedState.Fork(), tt.msg.GetData().Target.Epoch, params.BeaconConfig().DomainBeaconAttester, savedState.GenesisValidatorsRoot()) require.NoError(t, err) - attRoot, err := signing.ComputeSigningRoot(tt.msg.Data, domain) + attRoot, err := signing.ComputeSigningRoot(tt.msg.GetData(), domain) require.NoError(t, err) for i := 0; ; i++ { - if tt.msg.AggregationBits.BitAt(uint64(i)) { - tt.msg.Signature = keys[com[i]].Sign(attRoot[:]).Marshal() + if tt.msg.GetAggregationBits().BitAt(uint64(i)) { + tt.msg.SetSignature(keys[com[i]].Sign(attRoot[:]).Marshal()) break } } } else { - tt.msg.Signature = make([]byte, 96) + tt.msg.SetSignature(make([]byte, 96)) } buf := new(bytes.Buffer) _, err := p.Encoding().EncodeGossip(buf, tt.msg) @@ -305,6 +306,165 @@ func TestService_validateCommitteeIndexBeaconAttestation(t *testing.T) { } } +func TestService_validateCommitteeIndexBeaconAttestationElectra(t *testing.T) { + params.SetupTestConfigCleanup(t) + cfg := params.BeaconConfig() + fvs := map[[fieldparams.VersionLength]byte]primitives.Epoch{} + fvs[bytesutil.ToBytes4(cfg.GenesisForkVersion)] = 1 + fvs[bytesutil.ToBytes4(cfg.AltairForkVersion)] = 2 + fvs[bytesutil.ToBytes4(cfg.BellatrixForkVersion)] = 3 + fvs[bytesutil.ToBytes4(cfg.CapellaForkVersion)] = 4 + fvs[bytesutil.ToBytes4(cfg.DenebForkVersion)] = 5 + fvs[bytesutil.ToBytes4(cfg.FuluForkVersion)] = 6 + fvs[bytesutil.ToBytes4(cfg.ElectraForkVersion)] = 0 + cfg.ForkVersionSchedule = fvs + params.OverrideBeaconConfig(cfg) + + p := p2ptest.NewTestP2P(t) + db := dbtest.SetupDB(t) + chain := &mockChain.ChainService{ + // 1 slot ago. + Genesis: time.Now().Add(time.Duration(-1*int64(params.BeaconConfig().SecondsPerSlot)) * time.Second), + ValidatorsRoot: [32]byte{'A'}, + ValidAttestation: true, + DB: db, + Optimistic: true, + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + s := &Service{ + ctx: ctx, + cfg: &config{ + initialSync: &mockSync.Sync{IsSyncing: false}, + p2p: p, + beaconDB: db, + chain: chain, + clock: startup.NewClock(chain.Genesis, chain.ValidatorsRoot), + attestationNotifier: (&mockChain.ChainService{}).OperationNotifier(), + }, + blkRootToPendingAtts: make(map[[32]byte][]ethpb.SignedAggregateAttAndProof), + seenUnAggregatedAttestationCache: lruwrpr.New(10), + signatureChan: make(chan *signatureVerifier, verifierLimit), + } + s.initCaches() + go s.verifierRoutine() + + digest, err := s.currentForkDigest() + require.NoError(t, err) + + blk := util.NewBeaconBlock() + blk.Block.Slot = 1 + util.SaveBlock(t, ctx, db, blk) + + validBlockRoot, err := blk.Block.HashTreeRoot() + require.NoError(t, err) + chain.FinalizedCheckPoint = ðpb.Checkpoint{ + Root: validBlockRoot[:], + Epoch: 0, + } + + validators := uint64(64) + savedState, keys := util.DeterministicGenesisState(t, validators) + require.NoError(t, savedState.SetSlot(1)) + require.NoError(t, db.SaveState(context.Background(), savedState, validBlockRoot)) + chain.State = savedState + committee, err := helpers.BeaconCommitteeFromState(ctx, savedState, 1, 0) + require.NoError(t, err) + + tests := []struct { + name string + msg ethpb.Att + want bool + }{ + { + name: "valid", + msg: ðpb.SingleAttestation{ + Data: ðpb.AttestationData{ + BeaconBlockRoot: validBlockRoot[:], + CommitteeIndex: 0, + Slot: 1, + Target: ðpb.Checkpoint{ + Epoch: 0, + Root: validBlockRoot[:], + }, + Source: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)}, + }, + AttesterIndex: committee[0], + }, + want: true, + }, + { + name: "non-zero committee index in att data", + msg: ðpb.SingleAttestation{ + Data: ðpb.AttestationData{ + BeaconBlockRoot: validBlockRoot[:], + CommitteeIndex: 1, + Slot: 1, + Target: ðpb.Checkpoint{ + Epoch: 0, + Root: validBlockRoot[:], + }, + Source: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)}, + }, + AttesterIndex: committee[0], + }, + want: false, + }, + { + name: "attesting index not in committee", + msg: ðpb.SingleAttestation{ + Data: ðpb.AttestationData{ + BeaconBlockRoot: validBlockRoot[:], + CommitteeIndex: 1, + Slot: 1, + Target: ðpb.Checkpoint{ + Epoch: 0, + Root: validBlockRoot[:], + }, + Source: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)}, + }, + AttesterIndex: 999999, + }, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + helpers.ClearCache() + com, err := helpers.BeaconCommitteeFromState(context.Background(), savedState, tt.msg.GetData().Slot, tt.msg.GetData().CommitteeIndex) + require.NoError(t, err) + domain, err := signing.Domain(savedState.Fork(), tt.msg.GetData().Target.Epoch, params.BeaconConfig().DomainBeaconAttester, savedState.GenesisValidatorsRoot()) + require.NoError(t, err) + attRoot, err := signing.ComputeSigningRoot(tt.msg.GetData(), domain) + require.NoError(t, err) + tt.msg.SetSignature(keys[com[0]].Sign(attRoot[:]).Marshal()) + buf := new(bytes.Buffer) + _, err = p.Encoding().EncodeGossip(buf, tt.msg) + require.NoError(t, err) + topic := fmt.Sprintf("/eth2/%x/beacon_attestation_1", digest) + m := &pubsub.Message{ + Message: &pubsubpb.Message{ + Data: buf.Bytes(), + Topic: &topic, + }, + } + + res, err := s.validateCommitteeIndexBeaconAttestation(ctx, "", m) + received := res == pubsub.ValidationAccept + if received != tt.want { + t.Fatalf("Did not received wanted validation. Got %v, wanted %v", !tt.want, tt.want) + } + if tt.want && err != nil { + t.Errorf("Non nil error returned: %v", err) + } + if tt.want && m.ValidatorData == nil { + t.Error("Expected validator data to be set") + } + }) + } +} + func TestService_setSeenCommitteeIndicesSlot(t *testing.T) { s := NewService(context.Background(), WithP2P(p2ptest.NewTestP2P(t))) s.initCaches() diff --git a/cmd/beacon-chain/main.go b/cmd/beacon-chain/main.go index 07ce3dca6483..b2016990aa69 100644 --- a/cmd/beacon-chain/main.go +++ b/cmd/beacon-chain/main.go @@ -288,9 +288,7 @@ func startNode(ctx *cli.Context, cancel context.CancelFunc) error { // libp2p specific logging. golog.SetAllLoggers(golog.LevelDebug) // Geth specific logging. - glogger := gethlog.NewGlogHandler(gethlog.StreamHandler(os.Stderr, gethlog.TerminalFormat(true))) - glogger.Verbosity(gethlog.LvlTrace) - gethlog.Root().SetHandler(glogger) + gethlog.SetDefault(gethlog.NewLogger(gethlog.NewTerminalHandlerWithLevel(os.Stderr, gethlog.LvlTrace, true))) } blockchainFlagOpts, err := blockchaincmd.FlagOptions(ctx) diff --git a/cmd/prysmctl/testnet/generate_genesis.go b/cmd/prysmctl/testnet/generate_genesis.go index 4c79bf3d588f..814deac8fa5d 100644 --- a/cmd/prysmctl/testnet/generate_genesis.go +++ b/cmd/prysmctl/testnet/generate_genesis.go @@ -278,7 +278,6 @@ func generateGenesis(ctx context.Context) (state.BeaconState, error) { if v > version.Altair { // set ttd to zero so EL goes post-merge immediately gen.Config.TerminalTotalDifficulty = big.NewInt(0) - gen.Config.TerminalTotalDifficultyPassed = true } } else { gen = interop.GethTestnetGenesis(f.GenesisTime, params.BeaconConfig()) diff --git a/config/fieldparams/minimal.go b/config/fieldparams/minimal.go index fa74981e3b61..f3e1e7d99581 100644 --- a/config/fieldparams/minimal.go +++ b/config/fieldparams/minimal.go @@ -31,7 +31,7 @@ const ( BlobLength = 131072 // BlobLength defines the byte length of a blob. BlobSize = 131072 // defined to match blob.size in bazel ssz codegen BlobSidecarSize = 131928 // defined to match blob sidecar size in bazel ssz codegen - KzgCommitmentInclusionProofDepth = 17 // Merkle proof depth for blob_kzg_commitments list item + KzgCommitmentInclusionProofDepth = 10 // Merkle proof depth for blob_kzg_commitments list item ExecutionBranchDepth = 4 // ExecutionBranchDepth defines the number of leaves in a merkle proof of the execution payload header. SyncCommitteeBranchDepth = 5 // SyncCommitteeBranchDepth defines the number of leaves in a merkle proof of a sync committee. SyncCommitteeBranchDepthElectra = 6 // SyncCommitteeBranchDepthElectra defines the number of leaves in a merkle proof of a sync committee. diff --git a/config/params/config.go b/config/params/config.go index 126312624ea6..ffe861017557 100644 --- a/config/params/config.go +++ b/config/params/config.go @@ -239,7 +239,6 @@ type BeaconChainConfig struct { MinEpochsForBlobsSidecarsRequest primitives.Epoch `yaml:"MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS" spec:"true"` // MinEpochsForBlobsSidecarsRequest is the minimum number of epochs the node will keep the blobs for. MaxRequestBlobSidecars uint64 `yaml:"MAX_REQUEST_BLOB_SIDECARS" spec:"true"` // MaxRequestBlobSidecars is the maximum number of blobs to request in a single request. MaxRequestBlobSidecarsElectra uint64 `yaml:"MAX_REQUEST_BLOB_SIDECARS_ELECTRA" spec:"true"` // MaxRequestBlobSidecarsElectra is the maximum number of blobs to request in a single request after the electra epoch. - MaxRequestBlobSidecarsFulu uint64 `yaml:"MAX_REQUEST_BLOB_SIDECARS_FULU" spec:"true"` // MaxRequestBlobSidecarsFulu is the maximum number of blobs to request in a single request after the fulu epoch. MaxRequestBlocksDeneb uint64 `yaml:"MAX_REQUEST_BLOCKS_DENEB" spec:"true"` // MaxRequestBlocksDeneb is the maximum number of blocks in a single request after the deneb epoch. // Values introduced in Electra upgrade diff --git a/config/params/loader_test.go b/config/params/loader_test.go index 61fc4ac165d3..040b3c64ce37 100644 --- a/config/params/loader_test.go +++ b/config/params/loader_test.go @@ -38,8 +38,10 @@ var placeholderFields = []string{ "MAX_BLOB_COMMITMENTS_PER_BLOCK", // Compile time constant on BeaconBlockBodyDeneb.blob_kzg_commitments. "MAX_BYTES_PER_TRANSACTION", // Used for ssz of EL transactions. Unused in Prysm. "MAX_EXTRA_DATA_BYTES", // Compile time constant on ExecutionPayload.extra_data. - "MAX_REQUEST_PAYLOADS", // Compile time constant on BeaconBlockBody.ExecutionRequests - "MAX_TRANSACTIONS_PER_PAYLOAD", // Compile time constant on ExecutionPayload.transactions. + "MAX_PAYLOAD_SIZE", + "MAX_REQUEST_BLOB_SIDECARS_FULU", + "MAX_REQUEST_PAYLOADS", // Compile time constant on BeaconBlockBody.ExecutionRequests + "MAX_TRANSACTIONS_PER_PAYLOAD", // Compile time constant on ExecutionPayload.transactions. "REORG_HEAD_WEIGHT_THRESHOLD", "TARGET_NUMBER_OF_PEERS", "UPDATE_TIMEOUT", diff --git a/config/params/mainnet_config.go b/config/params/mainnet_config.go index 5befe7368e70..af9dd501b162 100644 --- a/config/params/mainnet_config.go +++ b/config/params/mainnet_config.go @@ -331,7 +331,6 @@ var mainnetBeaconConfig = &BeaconChainConfig{ DeprecatedMaxBlobsPerBlockElectra: 9, DeprecatedTargetBlobsPerBlockElectra: 6, MaxRequestBlobSidecarsElectra: 1152, - MaxRequestBlobSidecarsFulu: 1536, } // MainnetTestConfig provides a version of the mainnet config that has a different name diff --git a/consensus-types/interfaces/light_client.go b/consensus-types/interfaces/light_client.go index 867ceb281a0b..1a6576305535 100644 --- a/consensus-types/interfaces/light_client.go +++ b/consensus-types/interfaces/light_client.go @@ -26,6 +26,7 @@ type LightClientHeader interface { type LightClientBootstrap interface { ssz.Marshaler Version() int + Proto() proto.Message Header() LightClientHeader SetHeader(header LightClientHeader) error CurrentSyncCommittee() *pb.SyncCommittee diff --git a/consensus-types/light-client/bootstrap.go b/consensus-types/light-client/bootstrap.go index 7201b716b8a6..e9e583a657c9 100644 --- a/consensus-types/light-client/bootstrap.go +++ b/consensus-types/light-client/bootstrap.go @@ -86,6 +86,10 @@ func (h *bootstrapAltair) Version() int { return version.Altair } +func (h *bootstrapAltair) Proto() proto.Message { + return h.p +} + func (h *bootstrapAltair) Header() interfaces.LightClientHeader { return h.header } @@ -187,6 +191,10 @@ func (h *bootstrapCapella) Version() int { return version.Capella } +func (h *bootstrapCapella) Proto() proto.Message { + return h.p +} + func (h *bootstrapCapella) Header() interfaces.LightClientHeader { return h.header } @@ -288,6 +296,10 @@ func (h *bootstrapDeneb) Version() int { return version.Deneb } +func (h *bootstrapDeneb) Proto() proto.Message { + return h.p +} + func (h *bootstrapDeneb) Header() interfaces.LightClientHeader { return h.header } @@ -389,6 +401,10 @@ func (h *bootstrapElectra) Version() int { return version.Electra } +func (h *bootstrapElectra) Proto() proto.Message { + return h.p +} + func (h *bootstrapElectra) Header() interfaces.LightClientHeader { return h.header } diff --git a/contracts/deposit/contract_test.go b/contracts/deposit/contract_test.go index d163d07e6bba..892d36df8ee4 100644 --- a/contracts/deposit/contract_test.go +++ b/contracts/deposit/contract_test.go @@ -67,7 +67,7 @@ func TestValidatorRegister_OK(t *testing.T) { }, } - logs, err := testAccount.Backend.FilterLogs(context.Background(), query) + logs, err := testAccount.Backend.Client().FilterLogs(context.Background(), query) assert.NoError(t, err, "Unable to get logs of deposit contract") merkleTreeIndex := make([]uint64, 5) diff --git a/contracts/deposit/mock/BUILD.bazel b/contracts/deposit/mock/BUILD.bazel index 6ad8a6115305..328ec2ad63f5 100644 --- a/contracts/deposit/mock/BUILD.bazel +++ b/contracts/deposit/mock/BUILD.bazel @@ -10,10 +10,9 @@ go_library( "//contracts/deposit:go_default_library", "@com_github_ethereum_go_ethereum//accounts/abi:go_default_library", "@com_github_ethereum_go_ethereum//accounts/abi/bind:go_default_library", - "@com_github_ethereum_go_ethereum//accounts/abi/bind/backends:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", - "@com_github_ethereum_go_ethereum//core:go_default_library", "@com_github_ethereum_go_ethereum//core/types:go_default_library", "@com_github_ethereum_go_ethereum//crypto:go_default_library", + "@com_github_ethereum_go_ethereum//ethclient/simulated:go_default_library", ], ) diff --git a/contracts/deposit/mock/mock.go b/contracts/deposit/mock/mock.go index 7e15eeed77b7..030482a2780d 100644 --- a/contracts/deposit/mock/mock.go +++ b/contracts/deposit/mock/mock.go @@ -8,11 +8,10 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient/simulated" "github.com/prysmaticlabs/prysm/v5/contracts/deposit" ) @@ -28,13 +27,13 @@ type TestAccount struct { Addr common.Address ContractAddr common.Address Contract *deposit.DepositContract - Backend *backends.SimulatedBackend + Backend *simulated.Backend TxOpts *bind.TransactOpts } // Setup creates the simulated backend with the deposit contract deployed func Setup() (*TestAccount, error) { - genesis := make(core.GenesisAlloc) + genesis := make(types.GenesisAlloc) privKey, err := crypto.GenerateKey() if err != nil { return nil, err @@ -55,10 +54,10 @@ func Setup() (*TestAccount, error) { return nil, err } startingBalance, _ := new(big.Int).SetString("100000000000000000000000000000000000000", 10) - genesis[addr] = core.GenesisAccount{Balance: startingBalance} - backend := backends.NewSimulatedBackend(genesis, 210000000000) + genesis[addr] = types.Account{Balance: startingBalance} + backend := simulated.NewBackend(genesis, simulated.WithBlockGasLimit(210000000000)) - contractAddr, _, contract, err := DeployDepositContract(txOpts, backend) + contractAddr, _, contract, err := DeployDepositContract(txOpts, backend.Client()) if err != nil { return nil, err } diff --git a/deps.bzl b/deps.bzl index e4a22ac9dfff..39083a8d1071 100644 --- a/deps.bzl +++ b/deps.bzl @@ -295,8 +295,8 @@ def prysm_deps(): go_repository( name = "com_github_bits_and_blooms_bitset", importpath = "github.com/bits-and-blooms/bitset", - sum = "h1:RMyy2mBBShArUAhfVRZJ2xyBO58KCBCtZFShw3umo6k=", - version = "v1.11.0", + sum = "h1:1X2TS7aHz1ELcC0yU1y2stUs/0ig5oMU6STFZGrhvHI=", + version = "v1.17.0", ) go_repository( name = "com_github_bradfitz_go_smtpd", @@ -313,8 +313,8 @@ def prysm_deps(): go_repository( name = "com_github_btcsuite_btcd_btcec_v2", importpath = "github.com/btcsuite/btcd/btcec/v2", - sum = "h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U=", - version = "v2.3.2", + sum = "h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=", + version = "v2.3.4", ) go_repository( name = "com_github_btcsuite_btcd_chaincfg_chainhash", @@ -452,8 +452,14 @@ def prysm_deps(): name = "com_github_cockroachdb_errors", build_file_proto_mode = "disable_global", importpath = "github.com/cockroachdb/errors", - sum = "h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8=", - version = "v1.11.1", + sum = "h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I=", + version = "v1.11.3", + ) + go_repository( + name = "com_github_cockroachdb_fifo", + importpath = "github.com/cockroachdb/fifo", + sum = "h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4=", + version = "v0.0.0-20240606204812-0bbfbd93a7ce", ) go_repository( name = "com_github_cockroachdb_logtags", @@ -464,8 +470,8 @@ def prysm_deps(): go_repository( name = "com_github_cockroachdb_pebble", importpath = "github.com/cockroachdb/pebble", - sum = "h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A=", - version = "v0.0.0-20230928194634-aa077af62593", + sum = "h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA=", + version = "v1.1.2", ) go_repository( name = "com_github_cockroachdb_redact", @@ -473,12 +479,6 @@ def prysm_deps(): sum = "h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=", version = "v1.1.5", ) - go_repository( - name = "com_github_cockroachdb_sentry_go", - importpath = "github.com/cockroachdb/sentry-go", - sum = "h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM=", - version = "v0.6.1-cockroachdb.2", - ) go_repository( name = "com_github_cockroachdb_tokenbucket", importpath = "github.com/cockroachdb/tokenbucket", @@ -500,14 +500,14 @@ def prysm_deps(): go_repository( name = "com_github_consensys_bavard", importpath = "github.com/consensys/bavard", - sum = "h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=", - version = "v0.1.13", + sum = "h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI0A=", + version = "v0.1.22", ) go_repository( name = "com_github_consensys_gnark_crypto", importpath = "github.com/consensys/gnark-crypto", - sum = "h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M=", - version = "v0.12.1", + sum = "h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E=", + version = "v0.14.0", ) go_repository( name = "com_github_containerd_cgroups", @@ -549,14 +549,14 @@ def prysm_deps(): go_repository( name = "com_github_crate_crypto_go_ipa", importpath = "github.com/crate-crypto/go-ipa", - sum = "h1:DuBDHVjgGMPki7bAyh91+3cF1Vh34sAEdH8JQgbc2R0=", - version = "v0.0.0-20230601170251-1830d0757c80", + sum = "h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg=", + version = "v0.0.0-20240724233137-53bbb0ceb27a", ) go_repository( name = "com_github_crate_crypto_go_kzg_4844", importpath = "github.com/crate-crypto/go-kzg-4844", - sum = "h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA=", - version = "v0.7.0", + sum = "h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4=", + version = "v1.1.0", ) go_repository( name = "com_github_creack_pty", @@ -597,8 +597,8 @@ def prysm_deps(): go_repository( name = "com_github_deckarep_golang_set_v2", importpath = "github.com/deckarep/golang-set/v2", - sum = "h1:hn6cEZtQ0h3J8kFrHR/NrzyOoTnjgW1+FmNJzQ7y/sA=", - version = "v2.5.0", + sum = "h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM=", + version = "v2.6.0", ) go_repository( name = "com_github_decred_dcrd_crypto_blake256", @@ -654,6 +654,12 @@ def prysm_deps(): sum = "h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=", version = "v0.5.0", ) + go_repository( + name = "com_github_donovanhide_eventsource", + importpath = "github.com/donovanhide/eventsource", + sum = "h1:C7t6eeMaEQVy6e8CarIhscYQlNmw5e3G36y7l7Y21Ao=", + version = "v0.0.0-20210830082556-c59027999da0", + ) go_repository( name = "com_github_dop251_goja", importpath = "github.com/dop251/goja", @@ -747,14 +753,21 @@ def prysm_deps(): name = "com_github_ethereum_go_ethereum", build_directives = [ "gazelle:resolve go github.com/karalabe/usb @prysm//third_party/usb:go_default_library", + "gazelle:resolve go github.com/karalabe/hid @prysm//third_party/hid:go_default_library", ], importpath = "github.com/ethereum/go-ethereum", patch_args = ["-p1"], patches = [ "//third_party:com_github_ethereum_go_ethereum_secp256k1.patch", ], - sum = "h1:U6TCRciCqZRe4FPXmy1sMGxTfuk8P7u2UoinF3VbaFk=", - version = "v1.13.5", + sum = "h1:8hl57x77HSUo+cXExrURjU/w1VhL+ShCTJrTwcCQSe4=", + version = "v1.14.12", + ) + go_repository( + name = "com_github_ethereum_go_verkle", + importpath = "github.com/ethereum/go-verkle", + sum = "h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8=", + version = "v0.2.2", ) go_repository( name = "com_github_evanphx_json_patch", @@ -765,8 +778,8 @@ def prysm_deps(): go_repository( name = "com_github_fatih_color", importpath = "github.com/fatih/color", - sum = "h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=", - version = "v1.13.0", + sum = "h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=", + version = "v1.16.0", ) go_repository( name = "com_github_fatih_structs", @@ -783,8 +796,8 @@ def prysm_deps(): go_repository( name = "com_github_ferranbt_fastssz", importpath = "github.com/ferranbt/fastssz", - sum = "h1:9VDpsWq096+oGMDTT/SgBD/VgZYf4pTF+KTPmZ+OaKM=", - version = "v0.0.0-20210120143747-11b9eff30ea9", + sum = "h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo=", + version = "v0.1.3", ) go_repository( name = "com_github_fjl_gencodec", @@ -792,12 +805,6 @@ def prysm_deps(): sum = "h1:bBLctRc7kr01YGvaDfgLbTwjFNW5jdp5y5rj8XXBHfY=", version = "v0.0.0-20230517082657-f9840df7b83e", ) - go_repository( - name = "com_github_fjl_memsize", - importpath = "github.com/fjl/memsize", - sum = "h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=", - version = "v0.0.0-20190710130421-bcb5799ab5e5", - ) go_repository( name = "com_github_flosch_pongo2_v4", importpath = "github.com/flosch/pongo2/v4", @@ -879,20 +886,20 @@ def prysm_deps(): go_repository( name = "com_github_gballet_go_verkle", importpath = "github.com/gballet/go-verkle", - sum = "h1:vMT47RYsrftsHSTQhqXwC3BYflo38OLC3Y4LtXtLyU0=", - version = "v0.0.0-20230607174250-df487255f46b", + sum = "h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE=", + version = "v0.1.1-0.20231031103413-a67434b50f46", ) go_repository( name = "com_github_gdamore_encoding", importpath = "github.com/gdamore/encoding", - sum = "h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=", - version = "v1.0.0", + sum = "h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=", + version = "v1.0.1", ) go_repository( name = "com_github_gdamore_tcell_v2", importpath = "github.com/gdamore/tcell/v2", - sum = "h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg=", - version = "v2.6.0", + sum = "h1:sg6/UnTM9jGpZU+oFYAsDahfchWAFW8Xx2yFinNSAYU=", + version = "v2.7.4", ) go_repository( name = "com_github_getkin_kin_openapi", @@ -903,8 +910,8 @@ def prysm_deps(): go_repository( name = "com_github_getsentry_sentry_go", importpath = "github.com/getsentry/sentry-go", - sum = "h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI=", - version = "v0.25.0", + sum = "h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=", + version = "v0.27.0", ) go_repository( name = "com_github_ghemawat_stream", @@ -1137,8 +1144,8 @@ def prysm_deps(): go_repository( name = "com_github_golang_jwt_jwt_v4", importpath = "github.com/golang-jwt/jwt/v4", - sum = "h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=", - version = "v4.5.0", + sum = "h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=", + version = "v4.5.1", ) go_repository( name = "com_github_golang_lint", @@ -1163,8 +1170,8 @@ def prysm_deps(): go_repository( name = "com_github_golang_snappy", importpath = "github.com/golang/snappy", - sum = "h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=", - version = "v0.0.5-0.20220116011046-fa5810519dcb", + sum = "h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc=", + version = "v0.0.5-0.20231225225746-43d5d4cd4e0e", ) go_repository( name = "com_github_golangci_lint_1", @@ -1493,14 +1500,14 @@ def prysm_deps(): go_repository( name = "com_github_herumi_bls_eth_go_binary", importpath = "github.com/herumi/bls-eth-go-binary", - sum = "h1:wCMygKUQhmcQAjlk2Gquzq6dLmyMv2kF+llRspoRgrk=", - version = "v0.0.0-20210917013441-d37c07cfda4e", + sum = "h1:9eeW3EA4epCb7FIHt2luENpAW69MvKGL5jieHlBiP+w=", + version = "v1.31.0", ) go_repository( name = "com_github_holiman_billy", importpath = "github.com/holiman/billy", - sum = "h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw=", - version = "v0.0.0-20230718173358-1c7e68d277a7", + sum = "h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4=", + version = "v0.0.0-20240216141850-2abb0c79d3c4", ) go_repository( name = "com_github_holiman_bloomfilter_v2", @@ -1511,14 +1518,14 @@ def prysm_deps(): go_repository( name = "com_github_holiman_goevmlab", importpath = "github.com/holiman/goevmlab", - sum = "h1:J973NLskKmFIj3EGfpQ1ztUQKdwyJ+fG34638ief0eA=", - version = "v0.0.0-20231201084119-c73b3c97929c", + sum = "h1:JHZ8k9n9G9KXIo1qrvK5Cxah6ax5BR0qVTA9bFYl1oM=", + version = "v0.0.0-20241121133100-cfa6b078c8c4", ) go_repository( name = "com_github_holiman_uint256", importpath = "github.com/holiman/uint256", - sum = "h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=", - version = "v1.2.4", + sum = "h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=", + version = "v1.3.2", ) go_repository( name = "com_github_hpcloud_tail", @@ -1571,8 +1578,8 @@ def prysm_deps(): go_repository( name = "com_github_inconshreveable_mousetrap", importpath = "github.com/inconshreveable/mousetrap", - sum = "h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=", - version = "v1.0.0", + sum = "h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=", + version = "v1.1.0", ) go_repository( name = "com_github_influxdata_influxdb1_client", @@ -1745,10 +1752,10 @@ def prysm_deps(): version = "v0.0.0-20180517002512-3bf9e2903213", ) go_repository( - name = "com_github_karalabe_usb", - importpath = "github.com/karalabe/usb", - sum = "h1:AqsttAyEyIEsNz5WLRwuRwjiT5CMDUfLk6cFJDVPebs=", - version = "v0.0.3-0.20230711191512-61db3e06439c", + name = "com_github_karalabe_hid", + importpath = "github.com/karalabe/hid", + sum = "h1:msKODTL1m0wigztaqILOtla9HeW1ciscYG4xjLtvk5I=", + version = "v1.0.1-0.20240306101548-573246063e52", ) go_repository( name = "com_github_kataras_blocks", @@ -1903,8 +1910,8 @@ def prysm_deps(): go_repository( name = "com_github_leanovate_gopter", importpath = "github.com/leanovate/gopter", - sum = "h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=", - version = "v0.2.9", + sum = "h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4=", + version = "v0.2.11", ) go_repository( name = "com_github_leodido_go_urn", @@ -2064,14 +2071,14 @@ def prysm_deps(): go_repository( name = "com_github_mariusvanderwijden_fuzzyvm", importpath = "github.com/MariusVanDerWijden/FuzzyVM", - sum = "h1:BwEuC3xavrv4HTUDH2fUrKgKooiH3Q/nSVnFGtnzpN0=", - version = "v0.0.0-20240209103030-ec53fa766bf8", + sum = "h1:RQtzNvriR3Yu5CvVBTJPwDmfItBT90TWZ3fFondhc08=", + version = "v0.0.0-20240516070431-7828990cad7d", ) go_repository( name = "com_github_mariusvanderwijden_tx_fuzz", importpath = "github.com/MariusVanDerWijden/tx-fuzz", - sum = "h1:QDTh0xHorSykJ4+2VccBADMeRAVUbnHaWrCPIMtN+Vc=", - version = "v1.3.3-0.20240227085032-f70dd7c85c97", + sum = "h1:Tq4lXivsR8mtoP4RpasUDIUpDLHfN1YhFge/kzrzK78=", + version = "v1.4.0", ) go_repository( name = "com_github_marten_seemann_tcp", @@ -2130,8 +2137,8 @@ def prysm_deps(): go_repository( name = "com_github_microsoft_go_winio", importpath = "github.com/Microsoft/go-winio", - sum = "h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=", - version = "v0.6.1", + sum = "h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=", + version = "v0.6.2", ) go_repository( name = "com_github_miekg_dns", @@ -2775,8 +2782,20 @@ def prysm_deps(): go_repository( name = "com_github_protolambda_bls12_381_util", importpath = "github.com/protolambda/bls12-381-util", - sum = "h1:cZC+usqsYgHtlBaGulVnZ1hfKAi8iWtujBnRLQE698c=", - version = "v0.0.0-20220416220906-d8552aa452c7", + sum = "h1:05DU2wJN7DTU7z28+Q+zejXkIsA/MF8JZQGhtBZZiWk=", + version = "v0.1.0", + ) + go_repository( + name = "com_github_protolambda_zrnt", + importpath = "github.com/protolambda/zrnt", + sum = "h1:KZ48T+3UhsPXNdtE/5QEvGc9DGjUaRI17nJaoznoIaM=", + version = "v0.32.2", + ) + go_repository( + name = "com_github_protolambda_ztyp", + importpath = "github.com/protolambda/ztyp", + sum = "h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY=", + version = "v0.2.2", ) go_repository( name = "com_github_prysmaticlabs_fastssz", @@ -2854,8 +2873,8 @@ def prysm_deps(): go_repository( name = "com_github_rivo_tview", importpath = "github.com/rivo/tview", - sum = "h1:7UMY2qN9VlcY+x9jlhpYe5Bf1zrdhvmfZyLMk2u65BM=", - version = "v0.0.0-20231126152417-33a1d271f2b6", + sum = "h1:HxvWMyQ3vKQBlYZq9wfFtjbUeA6UUYZoLJmmwWee43s=", + version = "v0.0.0-20240519200218-0ac5f73025a8", ) go_repository( name = "com_github_rivo_uniseg", @@ -2864,8 +2883,8 @@ def prysm_deps(): "gazelle:exclude gen_properties.go", ], importpath = "github.com/rivo/uniseg", - sum = "h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=", - version = "v0.4.4", + sum = "h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=", + version = "v0.4.7", ) go_repository( name = "com_github_rogpeppe_fastuuid", @@ -3104,8 +3123,8 @@ def prysm_deps(): go_repository( name = "com_github_sirupsen_logrus", importpath = "github.com/sirupsen/logrus", - sum = "h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=", - version = "v1.9.0", + sum = "h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=", + version = "v1.9.3", ) go_repository( name = "com_github_smartystreets_assertions", @@ -3164,8 +3183,8 @@ def prysm_deps(): go_repository( name = "com_github_spf13_cobra", importpath = "github.com/spf13/cobra", - sum = "h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=", - version = "v1.5.0", + sum = "h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=", + version = "v1.8.1", ) go_repository( name = "com_github_spf13_jwalterweatherman", @@ -3317,6 +3336,12 @@ def prysm_deps(): sum = "h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=", version = "v1.2.7", ) + go_repository( + name = "com_github_umbracle_gohashtree", + importpath = "github.com/umbracle/gohashtree", + sum = "h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg=", + version = "v0.0.2-alpha.0.20230207094856-5b775a815c10", + ) go_repository( name = "com_github_urfave_cli", importpath = "github.com/urfave/cli", @@ -3326,8 +3351,8 @@ def prysm_deps(): go_repository( name = "com_github_urfave_cli_v2", importpath = "github.com/urfave/cli/v2", - sum = "h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI=", - version = "v2.26.0", + sum = "h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=", + version = "v2.27.1", ) go_repository( name = "com_github_urfave_negroni", @@ -3407,8 +3432,8 @@ def prysm_deps(): "gazelle:resolve go github.com/herumi/bls-eth-go-binary/bls @herumi_bls_eth_go_binary//:go_default_library", ], importpath = "github.com/wealdtech/go-eth2-types/v2", - sum = "h1:tiA6T88M6XQIbrV5Zz53l1G5HtRERcxQfmET225V4Ls=", - version = "v2.5.2", + sum = "h1:b5aXlNBLKgjAg/Fft9VvGlqAUCQMP5LzYhlHRrr4yPg=", + version = "v2.8.2", ) go_repository( name = "com_github_wealdtech_go_eth2_util", @@ -4397,8 +4422,8 @@ def prysm_deps(): go_repository( name = "in_gopkg_natefinch_lumberjack_v2", importpath = "gopkg.in/natefinch/lumberjack.v2", - sum = "h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=", - version = "v2.0.0", + sum = "h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=", + version = "v2.2.1", ) go_repository( name = "in_gopkg_redis_v4", diff --git a/go.mod b/go.mod index fea9381282fc..53257ddd3767 100644 --- a/go.mod +++ b/go.mod @@ -5,28 +5,27 @@ go 1.22.0 toolchain go1.22.10 require ( - github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20240209103030-ec53fa766bf8 - github.com/MariusVanDerWijden/tx-fuzz v1.3.3-0.20240227085032-f70dd7c85c97 + github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20240516070431-7828990cad7d + github.com/MariusVanDerWijden/tx-fuzz v1.4.0 github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96 github.com/bazelbuild/rules_go v0.23.2 - github.com/btcsuite/btcd/btcec/v2 v2.3.2 - github.com/consensys/gnark-crypto v0.12.1 - github.com/crate-crypto/go-kzg-4844 v0.7.0 + github.com/btcsuite/btcd/btcec/v2 v2.3.4 + github.com/consensys/gnark-crypto v0.14.0 + github.com/crate-crypto/go-kzg-4844 v1.1.0 github.com/d4l3k/messagediff v1.2.1 github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018 github.com/dustin/go-humanize v1.0.0 github.com/emicklei/dot v0.11.0 github.com/ethereum/c-kzg-4844/v2 v2.0.1 - github.com/ethereum/go-ethereum v1.13.5 - github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 + github.com/ethereum/go-ethereum v1.14.12 github.com/fsnotify/fsnotify v1.6.0 github.com/ghodss/yaml v1.0.0 github.com/go-yaml/yaml v2.1.0+incompatible github.com/gogo/protobuf v1.3.2 - github.com/golang-jwt/jwt/v4 v4.5.0 + github.com/golang-jwt/jwt/v4 v4.5.1 github.com/golang/gddo v0.0.0-20200528160355-8d077c1d8f4c github.com/golang/protobuf v1.5.4 - github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb + github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e github.com/google/go-cmp v0.6.0 github.com/google/gofuzz v1.2.0 github.com/google/uuid v1.6.0 @@ -34,8 +33,8 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d - github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e - github.com/holiman/uint256 v1.2.4 + github.com/herumi/bls-eth-go-binary v1.31.0 + github.com/holiman/uint256 v1.3.2 github.com/ianlancetaylor/cgosymbolizer v0.0.0-20200424224625-be1b05b0b279 github.com/ipfs/go-log/v2 v2.5.1 github.com/jedib0t/go-pretty/v6 v6.5.4 @@ -70,15 +69,15 @@ require ( github.com/r3labs/sse/v2 v2.10.0 github.com/rs/cors v1.7.0 github.com/schollz/progressbar/v3 v3.3.4 - github.com/sirupsen/logrus v1.9.0 + github.com/sirupsen/logrus v1.9.3 github.com/spf13/afero v1.10.0 github.com/status-im/keycard-go v0.2.0 github.com/stretchr/testify v1.9.0 - github.com/supranational/blst v0.3.12 + github.com/supranational/blst v0.3.13 github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279 github.com/tyler-smith/go-bip39 v1.1.0 - github.com/urfave/cli/v2 v2.26.0 + github.com/urfave/cli/v2 v2.27.1 github.com/uudashr/gocognit v1.0.5 github.com/wealdtech/go-bytesutil v1.1.1 github.com/wealdtech/go-eth2-util v1.6.3 @@ -110,27 +109,29 @@ require ( require ( github.com/BurntSushi/toml v1.3.2 // indirect github.com/DataDog/zstd v1.5.5 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/VictoriaMetrics/fastcache v1.12.2 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.11.0 // indirect + github.com/bits-and-blooms/bitset v1.17.0 // indirect github.com/cespare/cp v1.1.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect - github.com/cockroachdb/errors v1.11.1 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect + github.com/cockroachdb/pebble v1.1.2 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/bavard v0.1.22 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect - github.com/deckarep/golang-set/v2 v2.5.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/deepmap/oapi-codegen v1.8.2 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect @@ -138,15 +139,15 @@ require ( github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/elastic/gosigar v0.14.3 // indirect github.com/ethereum/c-kzg-4844 v1.0.3-0.20240715192038-0e753e2603db // indirect - github.com/ferranbt/fastssz v0.0.0-20210120143747-11b9eff30ea9 // indirect + github.com/ethereum/go-verkle v0.2.2 // indirect + github.com/ferranbt/fastssz v0.1.3 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect - github.com/getsentry/sentry-go v0.25.0 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -157,9 +158,9 @@ require ( github.com/graph-gophers/graphql-go v1.3.0 // indirect github.com/hashicorp/go-bexpr v0.1.10 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect - github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect + github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/goevmlab v0.0.0-20231201084119-c73b3c97929c // indirect + github.com/holiman/goevmlab v0.0.0-20241121133100-cfa6b078c8c4 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c // indirect @@ -168,7 +169,6 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect - github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect @@ -237,7 +237,7 @@ require ( github.com/quic-go/quic-go v0.48.2 // indirect github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect - github.com/rivo/uniseg v0.4.4 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect @@ -246,7 +246,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tklauser/go-sysconf v0.3.13 // indirect github.com/tklauser/numcpus v0.7.0 // indirect - github.com/wealdtech/go-eth2-types/v2 v2.5.2 // indirect + github.com/wealdtech/go-eth2-types/v2 v2.8.2 // indirect github.com/wlynxg/anet v0.0.4 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect @@ -263,7 +263,7 @@ require ( golang.org/x/time v0.5.0 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect lukechampine.com/blake3 v1.3.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect @@ -274,7 +274,7 @@ require ( require ( github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect diff --git a/go.sum b/go.sum index 17450be8df99..b5902e1f2ad2 100644 --- a/go.sum +++ b/go.sum @@ -51,12 +51,12 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20240209103030-ec53fa766bf8 h1:BwEuC3xavrv4HTUDH2fUrKgKooiH3Q/nSVnFGtnzpN0= -github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20240209103030-ec53fa766bf8/go.mod h1:L1QpLBqXlboJMOC2hndG95d1eiElzKsBhjzcuy8pxeM= -github.com/MariusVanDerWijden/tx-fuzz v1.3.3-0.20240227085032-f70dd7c85c97 h1:QDTh0xHorSykJ4+2VccBADMeRAVUbnHaWrCPIMtN+Vc= -github.com/MariusVanDerWijden/tx-fuzz v1.3.3-0.20240227085032-f70dd7c85c97/go.mod h1:xcjGtET6+7KeDHcwLQp3sIfyFALtoTjzZgY8Y+RUozM= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20240516070431-7828990cad7d h1:RQtzNvriR3Yu5CvVBTJPwDmfItBT90TWZ3fFondhc08= +github.com/MariusVanDerWijden/FuzzyVM v0.0.0-20240516070431-7828990cad7d/go.mod h1:gWTykV/ZinShgltWofTEJY4TsletuvGhB6l4+Ai2F+E= +github.com/MariusVanDerWijden/tx-fuzz v1.4.0 h1:Tq4lXivsR8mtoP4RpasUDIUpDLHfN1YhFge/kzrzK78= +github.com/MariusVanDerWijden/tx-fuzz v1.4.0/go.mod h1:gmOVECg7o5FY5VU3DQ/fY0zTk/ExBdMkUGz0vA8qqms= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -100,14 +100,12 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.11.0 h1:RMyy2mBBShArUAhfVRZJ2xyBO58KCBCtZFShw3umo6k= -github.com/bits-and-blooms/bitset v1.11.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.17.0 h1:1X2TS7aHz1ELcC0yU1y2stUs/0ig5oMU6STFZGrhvHI= +github.com/bits-and-blooms/bitset v1.17.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -141,21 +139,23 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= -github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= -github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= -github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/consensys/bavard v0.1.22 h1:Uw2CGvbXSZWhqK59X0VG/zOjpTFuOMcPLStrp1ihI0A= +github.com/consensys/bavard v0.1.22/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs= +github.com/consensys/gnark-crypto v0.14.0 h1:DDBdl4HaBtdQsq/wfMwJvZNE80sHidrK3Nfrefatm0E= +github.com/consensys/gnark-crypto v0.14.0/go.mod h1:CU4UijNPsHawiVGNxe9co07FkzCeWHHrb1li/n1XoU0= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= @@ -172,8 +172,10 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= -github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= +github.com/crate-crypto/go-kzg-4844 v1.1.0 h1:EN/u9k2TF6OWSHrCCDBBU6GLNMq88OspHHlMnHfoyU4= +github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= @@ -184,8 +186,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= -github.com/deckarep/golang-set/v2 v2.5.0 h1:hn6cEZtQ0h3J8kFrHR/NrzyOoTnjgW1+FmNJzQ7y/sA= -github.com/deckarep/golang-set/v2 v2.5.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= @@ -235,15 +237,16 @@ github.com/ethereum/c-kzg-4844 v1.0.3-0.20240715192038-0e753e2603db h1:GR54UuHLw github.com/ethereum/c-kzg-4844 v1.0.3-0.20240715192038-0e753e2603db/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/c-kzg-4844/v2 v2.0.1 h1:NuErvd0Ha5gLvvZ1m9Id9UZ11kcqMBUUXsbm7yXcAYI= github.com/ethereum/c-kzg-4844/v2 v2.0.1/go.mod h1:urP+cLBtKCW4BS5bnA2IXYs1PRGPpXmdotqpBuU6/5s= -github.com/ethereum/go-ethereum v1.13.5 h1:U6TCRciCqZRe4FPXmy1sMGxTfuk8P7u2UoinF3VbaFk= -github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84abZexQmTgenWk0= +github.com/ethereum/go-ethereum v1.14.12 h1:8hl57x77HSUo+cXExrURjU/w1VhL+ShCTJrTwcCQSe4= +github.com/ethereum/go-ethereum v1.14.12/go.mod h1:RAC2gVMWJ6FkxSPESfbshrcKpIokgQKsVKmAuqdekDY= +github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= +github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/ferranbt/fastssz v0.0.0-20210120143747-11b9eff30ea9 h1:9VDpsWq096+oGMDTT/SgBD/VgZYf4pTF+KTPmZ+OaKM= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/ferranbt/fastssz v0.0.0-20210120143747-11b9eff30ea9/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/ferranbt/fastssz v0.1.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo= +github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= @@ -264,8 +267,8 @@ github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8x github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= -github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= @@ -311,8 +314,6 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= @@ -331,8 +332,8 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/gddo v0.0.0-20200528160355-8d077c1d8f4c h1:HoqgYR60VYu5+0BuG6pjeGp7LKEPZnHt+dUClx9PeIs= github.com/golang/gddo v0.0.0-20200528160355-8d077c1d8f4c/go.mod h1:sam69Hju0uq+5uvLJUMDlsKlQ21Vrs1Kd/1YFPNYdOU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -372,8 +373,8 @@ github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8l github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= -github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e h1:4bw4WeyTYPp0smaXiJZCNnLrvVBqirQVreixayXezGc= +github.com/golang/snappy v0.0.5-0.20231225225746-43d5d4cd4e0e/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -482,16 +483,16 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/herumi/bls-eth-go-binary v0.0.0-20210130185500-57372fb27371/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= -github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e h1:wCMygKUQhmcQAjlk2Gquzq6dLmyMv2kF+llRspoRgrk= -github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/herumi/bls-eth-go-binary v1.31.0 h1:9eeW3EA4epCb7FIHt2luENpAW69MvKGL5jieHlBiP+w= +github.com/herumi/bls-eth-go-binary v1.31.0/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/goevmlab v0.0.0-20231201084119-c73b3c97929c h1:J973NLskKmFIj3EGfpQ1ztUQKdwyJ+fG34638ief0eA= -github.com/holiman/goevmlab v0.0.0-20231201084119-c73b3c97929c/go.mod h1:K6KFgcQq1U9ksldcRyLYcwtj4nUTPn4rEaZtX4Gjofc= -github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= -github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/goevmlab v0.0.0-20241121133100-cfa6b078c8c4 h1:JHZ8k9n9G9KXIo1qrvK5Cxah6ax5BR0qVTA9bFYl1oM= +github.com/holiman/goevmlab v0.0.0-20241121133100-cfa6b078c8c4/go.mod h1:+DBd7lup47uusCYWbkJPfHRG4LYjBHvyXU0c+z26/U4= +github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= +github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= @@ -536,12 +537,9 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg= github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= -github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c h1:AqsttAyEyIEsNz5WLRwuRwjiT5CMDUfLk6cFJDVPebs= -github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -576,8 +574,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -630,7 +628,6 @@ github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9v github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -920,8 +917,8 @@ github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtD github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= @@ -970,8 +967,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1016,8 +1013,8 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/supranational/blst v0.3.12 h1:Vfas2U2CFHhniv2QkUm2OVa1+pGTdqtpqm9NnhUUbZ8= -github.com/supranational/blst v0.3.12/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= @@ -1037,11 +1034,13 @@ github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279 h1:+Ly github.com/trailofbits/go-mutexasserts v0.0.0-20230328101604-8cdbc5f3d279/go.mod h1:GA3+Mq3kt3tYAfM0WZCu7ofy+GW9PuGysHfhr+6JX7s= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg= +github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI= -github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/uudashr/gocognit v1.0.5 h1:rrSex7oHr3/pPLQ0xoWq108XMU8s678FJcQ+aSfOHa4= github.com/uudashr/gocognit v1.0.5/go.mod h1:wgYz0mitoKOTysqxTDMOUXg+Jb5SvtihkfmugIZYpEA= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -1051,8 +1050,9 @@ github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49u github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/wealdtech/go-bytesutil v1.1.1 h1:ocEg3Ke2GkZ4vQw5lp46rmO+pfqCCTgq35gqOy8JKVc= github.com/wealdtech/go-bytesutil v1.1.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s= -github.com/wealdtech/go-eth2-types/v2 v2.5.2 h1:tiA6T88M6XQIbrV5Zz53l1G5HtRERcxQfmET225V4Ls= github.com/wealdtech/go-eth2-types/v2 v2.5.2/go.mod h1:8lkNUbgklSQ4LZ2oMSuxSdR7WwJW3L9ge1dcoCVyzws= +github.com/wealdtech/go-eth2-types/v2 v2.8.2 h1:b5aXlNBLKgjAg/Fft9VvGlqAUCQMP5LzYhlHRrr4yPg= +github.com/wealdtech/go-eth2-types/v2 v2.8.2/go.mod h1:IAz9Lz1NVTaHabQa+4zjk2QDKMv8LVYo0n46M9o/TXw= github.com/wealdtech/go-eth2-util v1.6.3 h1:2INPeOR35x5LdFFpSzyw954WzTD+DFyHe3yKlJnG5As= github.com/wealdtech/go-eth2-util v1.6.3/go.mod h1:0hFMj/qtio288oZFHmAbCnPQ9OB3c4WFzs5NVPKTY4k= github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3 h1:SxrDVSr+oXuT1x8kZt4uWqNCvv5xXEGV9zd7cuSrZS8= @@ -1628,8 +1628,8 @@ gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eR gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/nogo_config.json b/nogo_config.json index 5902a89ae109..c2f3034b2aab 100644 --- a/nogo_config.json +++ b/nogo_config.json @@ -208,5 +208,11 @@ "external/.*": "Third party code", "rules_go_work-.*": "Third party code" } + }, + "loopclosure": { + "exclude_files": { + "external/com_github_ethereum_go_ethereum/.*": "Unsafe third party code", + "rules_go_work-.*": "Third party code" + } } } diff --git a/proto/prysm/v1alpha1/BUILD.bazel b/proto/prysm/v1alpha1/BUILD.bazel index 8022b3700370..068e1f90f220 100644 --- a/proto/prysm/v1alpha1/BUILD.bazel +++ b/proto/prysm/v1alpha1/BUILD.bazel @@ -149,6 +149,7 @@ ssz_deneb_objs = [ ssz_electra_objs = [ "AggregateAttestationAndProofElectra", + "AggregateAttestationAndProofSingle", "AttestationElectra", "AttesterSlashingElectra", "BeaconBlockElectra", @@ -168,6 +169,7 @@ ssz_electra_objs = [ "PendingConsolidation", "PendingPartialWithdrawal", "SignedAggregateAttestationAndProofElectra", + "SignedAggregateAttestationAndProofSingle", "SignedBeaconBlockContentsElectra", "SignedBeaconBlockElectra", "SignedBlindedBeaconBlockElectra", @@ -384,8 +386,8 @@ ssz_proto_files( "beacon_block.proto", "beacon_state.proto", "blobs.proto", - "light_client.proto", "data_columns.proto", + "light_client.proto", "sync_committee.proto", "withdrawals.proto", ], diff --git a/proto/prysm/v1alpha1/attestation.go b/proto/prysm/v1alpha1/attestation.go index d5240294b446..493595d5a329 100644 --- a/proto/prysm/v1alpha1/attestation.go +++ b/proto/prysm/v1alpha1/attestation.go @@ -1,9 +1,6 @@ package eth import ( - "fmt" - - "github.com/pkg/errors" ssz "github.com/prysmaticlabs/fastssz" "github.com/prysmaticlabs/go-bitfield" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" @@ -20,14 +17,16 @@ type Att interface { ssz.HashRoot Version() int IsNil() bool + IsSingle() bool IsAggregated() bool Clone() Att GetAggregationBits() bitfield.Bitlist + GetAttestingIndex() primitives.ValidatorIndex GetData() *AttestationData CommitteeBitsVal() bitfield.Bitfield GetSignature() []byte SetSignature(sig []byte) - GetCommitteeIndex() (primitives.CommitteeIndex, error) + GetCommitteeIndex() primitives.CommitteeIndex } // IndexedAtt defines common functionality for all indexed attestation types. @@ -115,6 +114,11 @@ func (a *Attestation) IsNil() bool { return a == nil || a.Data == nil } +// IsSingle returns true when the attestation can have only a single attester index. +func (*Attestation) IsSingle() bool { + return false +} + // IsAggregated -- func (a *Attestation) IsAggregated() bool { return a.AggregationBits.Count() > 1 @@ -137,6 +141,11 @@ func (a *Attestation) Copy() *Attestation { } } +// GetAttestingIndex -- +func (*Attestation) GetAttestingIndex() primitives.ValidatorIndex { + return 0 +} + // CommitteeBitsVal -- func (a *Attestation) CommitteeBitsVal() bitfield.Bitfield { cb := primitives.NewAttestationCommitteeBits() @@ -150,11 +159,11 @@ func (a *Attestation) SetSignature(sig []byte) { } // GetCommitteeIndex -- -func (a *Attestation) GetCommitteeIndex() (primitives.CommitteeIndex, error) { +func (a *Attestation) GetCommitteeIndex() primitives.CommitteeIndex { if a == nil || a.Data == nil { - return 0, errors.New("nil attestation data") + return 0 } - return a.Data.CommitteeIndex, nil + return a.Data.CommitteeIndex } // Version -- @@ -167,6 +176,11 @@ func (a *PendingAttestation) IsNil() bool { return a == nil || a.Data == nil } +// IsSingle returns true when the attestation can have only a single attester index. +func (*PendingAttestation) IsSingle() bool { + return false +} + // IsAggregated -- func (a *PendingAttestation) IsAggregated() bool { return a.AggregationBits.Count() > 1 @@ -190,6 +204,11 @@ func (a *PendingAttestation) Copy() *PendingAttestation { } } +// GetAttestingIndex -- +func (*PendingAttestation) GetAttestingIndex() primitives.ValidatorIndex { + return 0 +} + // CommitteeBitsVal -- func (a *PendingAttestation) CommitteeBitsVal() bitfield.Bitfield { return nil @@ -204,11 +223,11 @@ func (a *PendingAttestation) GetSignature() []byte { func (a *PendingAttestation) SetSignature(_ []byte) {} // GetCommitteeIndex -- -func (a *PendingAttestation) GetCommitteeIndex() (primitives.CommitteeIndex, error) { +func (a *PendingAttestation) GetCommitteeIndex() primitives.CommitteeIndex { if a == nil || a.Data == nil { - return 0, errors.New("nil attestation data") + return 0 } - return a.Data.CommitteeIndex, nil + return a.Data.CommitteeIndex } // Version -- @@ -221,6 +240,11 @@ func (a *AttestationElectra) IsNil() bool { return a == nil || a.Data == nil } +// IsSingle returns true when the attestation can have only a single attester index. +func (*AttestationElectra) IsSingle() bool { + return false +} + // IsAggregated -- func (a *AttestationElectra) IsAggregated() bool { return a.AggregationBits.Count() > 1 @@ -244,6 +268,11 @@ func (a *AttestationElectra) Copy() *AttestationElectra { } } +// GetAttestingIndex -- +func (*AttestationElectra) GetAttestingIndex() primitives.ValidatorIndex { + return 0 +} + // CommitteeBitsVal -- func (a *AttestationElectra) CommitteeBitsVal() bitfield.Bitfield { return a.CommitteeBits @@ -255,21 +284,101 @@ func (a *AttestationElectra) SetSignature(sig []byte) { } // GetCommitteeIndex -- -func (a *AttestationElectra) GetCommitteeIndex() (primitives.CommitteeIndex, error) { - if a == nil || a.Data == nil { - return 0, errors.New("nil attestation data") - } +func (a *AttestationElectra) GetCommitteeIndex() primitives.CommitteeIndex { if len(a.CommitteeBits) == 0 { - return 0, errors.New("no committee bits found in attestation") - } - if a.Data.CommitteeIndex != 0 { - return 0, fmt.Errorf("attestation data's committee index must be 0 but was %d", a.Data.CommitteeIndex) + return 0 } indices := a.CommitteeBits.BitIndices() - if len(indices) != 1 { - return 0, fmt.Errorf("exactly 1 committee index must be set but %d were set", len(indices)) + if len(indices) == 0 { + return 0 + } + return primitives.CommitteeIndex(uint64(indices[0])) +} + +// Version -- +func (a *SingleAttestation) Version() int { + return version.Electra +} + +// IsNil -- +func (a *SingleAttestation) IsNil() bool { + return a == nil || a.Data == nil +} + +// IsAggregated -- +func (a *SingleAttestation) IsAggregated() bool { + return false +} + +// IsSingle returns true when the attestation can have only a single attester index. +func (*SingleAttestation) IsSingle() bool { + return true +} + +// Clone -- +func (a *SingleAttestation) Clone() Att { + return a.Copy() +} + +// Copy -- +func (a *SingleAttestation) Copy() *SingleAttestation { + if a == nil { + return nil + } + return &SingleAttestation{ + CommitteeId: a.CommitteeId, + AttesterIndex: a.AttesterIndex, + Data: a.Data.Copy(), + Signature: bytesutil.SafeCopyBytes(a.Signature), + } +} + +// GetAttestingIndex -- +func (a *SingleAttestation) GetAttestingIndex() primitives.ValidatorIndex { + return a.AttesterIndex +} + +// CommitteeBitsVal -- +func (a *SingleAttestation) CommitteeBitsVal() bitfield.Bitfield { + cb := primitives.NewAttestationCommitteeBits() + cb.SetBitAt(uint64(a.CommitteeId), true) + return cb +} + +// GetAggregationBits -- +func (a *SingleAttestation) GetAggregationBits() bitfield.Bitlist { + return nil +} + +// SetSignature -- +func (a *SingleAttestation) SetSignature(sig []byte) { + a.Signature = sig +} + +// GetCommitteeIndex -- +func (a *SingleAttestation) GetCommitteeIndex() primitives.CommitteeIndex { + return a.CommitteeId +} + +// ToAttestationElectra converts the attestation to an AttestationElectra. +func (a *SingleAttestation) ToAttestationElectra(committee []primitives.ValidatorIndex) *AttestationElectra { + cb := primitives.NewAttestationCommitteeBits() + cb.SetBitAt(uint64(a.CommitteeId), true) + + ab := bitfield.NewBitlist(uint64(len(committee))) + for i, ix := range committee { + if a.AttesterIndex == ix { + ab.SetBitAt(uint64(i), true) + break + } + } + + return &AttestationElectra{ + AggregationBits: ab, + Data: a.Data, + Signature: a.Signature, + CommitteeBits: cb, } - return primitives.CommitteeIndex(uint64(indices[0])), nil } // Version -- @@ -419,6 +528,21 @@ func (a *AggregateAttestationAndProofElectra) AggregateVal() Att { return a.Aggregate } +// Version -- +func (a *AggregateAttestationAndProofSingle) Version() int { + return version.Electra +} + +// IsNil -- +func (a *AggregateAttestationAndProofSingle) IsNil() bool { + return a == nil || a.Aggregate == nil || a.Aggregate.IsNil() +} + +// AggregateVal -- +func (a *AggregateAttestationAndProofSingle) AggregateVal() Att { + return a.Aggregate +} + // Version -- func (a *SignedAggregateAttestationAndProof) Version() int { return version.Phase0 @@ -448,3 +572,18 @@ func (a *SignedAggregateAttestationAndProofElectra) IsNil() bool { func (a *SignedAggregateAttestationAndProofElectra) AggregateAttestationAndProof() AggregateAttAndProof { return a.Message } + +// Version -- +func (a *SignedAggregateAttestationAndProofSingle) Version() int { + return version.Electra +} + +// IsNil -- +func (a *SignedAggregateAttestationAndProofSingle) IsNil() bool { + return a == nil || a.Message == nil || a.Message.IsNil() +} + +// AggregateAttestationAndProof -- +func (a *SignedAggregateAttestationAndProofSingle) AggregateAttestationAndProof() AggregateAttAndProof { + return a.Message +} diff --git a/proto/prysm/v1alpha1/attestation.pb.go b/proto/prysm/v1alpha1/attestation.pb.go index 8bb6572d6236..f8c6fa5f92cf 100755 --- a/proto/prysm/v1alpha1/attestation.pb.go +++ b/proto/prysm/v1alpha1/attestation.pb.go @@ -528,6 +528,124 @@ func (x *AttestationElectra) GetCommitteeBits() github_com_prysmaticlabs_go_bitf return github_com_prysmaticlabs_go_bitfield.Bitvector64(nil) } +type SignedAggregateAttestationAndProofSingle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *AggregateAttestationAndProofSingle `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty" ssz-size:"96"` +} + +func (x *SignedAggregateAttestationAndProofSingle) Reset() { + *x = SignedAggregateAttestationAndProofSingle{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignedAggregateAttestationAndProofSingle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignedAggregateAttestationAndProofSingle) ProtoMessage() {} + +func (x *SignedAggregateAttestationAndProofSingle) ProtoReflect() protoreflect.Message { + mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignedAggregateAttestationAndProofSingle.ProtoReflect.Descriptor instead. +func (*SignedAggregateAttestationAndProofSingle) Descriptor() ([]byte, []int) { + return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{8} +} + +func (x *SignedAggregateAttestationAndProofSingle) GetMessage() *AggregateAttestationAndProofSingle { + if x != nil { + return x.Message + } + return nil +} + +func (x *SignedAggregateAttestationAndProofSingle) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +type AggregateAttestationAndProofSingle struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AggregatorIndex github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex `protobuf:"varint,1,opt,name=aggregator_index,json=aggregatorIndex,proto3" json:"aggregator_index,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.ValidatorIndex"` + Aggregate *SingleAttestation `protobuf:"bytes,3,opt,name=aggregate,proto3" json:"aggregate,omitempty"` + SelectionProof []byte `protobuf:"bytes,2,opt,name=selection_proof,json=selectionProof,proto3" json:"selection_proof,omitempty" ssz-size:"96"` +} + +func (x *AggregateAttestationAndProofSingle) Reset() { + *x = AggregateAttestationAndProofSingle{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AggregateAttestationAndProofSingle) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AggregateAttestationAndProofSingle) ProtoMessage() {} + +func (x *AggregateAttestationAndProofSingle) ProtoReflect() protoreflect.Message { + mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AggregateAttestationAndProofSingle.ProtoReflect.Descriptor instead. +func (*AggregateAttestationAndProofSingle) Descriptor() ([]byte, []int) { + return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{9} +} + +func (x *AggregateAttestationAndProofSingle) GetAggregatorIndex() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex { + if x != nil { + return x.AggregatorIndex + } + return github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex(0) +} + +func (x *AggregateAttestationAndProofSingle) GetAggregate() *SingleAttestation { + if x != nil { + return x.Aggregate + } + return nil +} + +func (x *AggregateAttestationAndProofSingle) GetSelectionProof() []byte { + if x != nil { + return x.SelectionProof + } + return nil +} + type SingleAttestation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -542,7 +660,7 @@ type SingleAttestation struct { func (x *SingleAttestation) Reset() { *x = SingleAttestation{} if protoimpl.UnsafeEnabled { - mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[8] + mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -555,7 +673,7 @@ func (x *SingleAttestation) String() string { func (*SingleAttestation) ProtoMessage() {} func (x *SingleAttestation) ProtoReflect() protoreflect.Message { - mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[8] + mi := &file_proto_prysm_v1alpha1_attestation_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -568,7 +686,7 @@ func (x *SingleAttestation) ProtoReflect() protoreflect.Message { // Deprecated: Use SingleAttestation.ProtoReflect.Descriptor instead. func (*SingleAttestation) Descriptor() ([]byte, []int) { - return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{8} + return file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP(), []int{10} } func (x *SingleAttestation) GetCommitteeId() github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.CommitteeIndex { @@ -730,39 +848,68 @@ var file_proto_prysm_v1alpha1_attestation_proto_rawDesc = []byte{ 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x67, 0x6f, 0x2d, 0x62, 0x69, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x42, 0x69, 0x74, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x36, 0x34, 0x8a, 0xb5, 0x18, 0x01, 0x38, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, - 0x65, 0x42, 0x69, 0x74, 0x73, 0x22, 0xe1, 0x02, 0x0a, 0x11, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, - 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x72, 0x0a, 0x0c, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, - 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, - 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, - 0x76, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x64, - 0x65, 0x78, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x64, 0x12, - 0x76, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, - 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, - 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, - 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, - 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x3a, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, - 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x74, - 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x9b, 0x01, 0x0a, 0x19, 0x6f, 0x72, - 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, - 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, - 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, - 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x42, 0x69, 0x74, 0x73, 0x22, 0xa5, 0x01, 0x0a, 0x28, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x53, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x12, 0x53, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, + 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x99, 0x02, + 0x0a, 0x22, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x53, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x12, 0x7a, 0x0a, 0x10, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, + 0x82, 0xb5, 0x18, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, + 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, + 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, + 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x12, 0x46, 0x0a, 0x09, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x61, + 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x0f, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xe1, 0x02, 0x0a, 0x11, 0x53, 0x69, + 0x6e, 0x67, 0x6c, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x72, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, + 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, + 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, + 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x65, 0x49, 0x64, 0x12, 0x76, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x5f, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4f, 0x82, 0xb5, 0x18, + 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, + 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, + 0x76, 0x35, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0d, 0x61, 0x74, + 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x3a, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x65, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, + 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, + 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x42, 0x9b, 0x01, + 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x10, 0x41, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, + 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, + 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, + 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x15, 0x45, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5c, 0x45, + 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -777,7 +924,7 @@ func file_proto_prysm_v1alpha1_attestation_proto_rawDescGZIP() []byte { return file_proto_prysm_v1alpha1_attestation_proto_rawDescData } -var file_proto_prysm_v1alpha1_attestation_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_proto_prysm_v1alpha1_attestation_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_proto_prysm_v1alpha1_attestation_proto_goTypes = []interface{}{ (*SignedAggregateAttestationAndProof)(nil), // 0: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProof (*AggregateAttestationAndProof)(nil), // 1: ethereum.eth.v1alpha1.AggregateAttestationAndProof @@ -787,23 +934,27 @@ var file_proto_prysm_v1alpha1_attestation_proto_goTypes = []interface{}{ (*SignedAggregateAttestationAndProofElectra)(nil), // 5: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProofElectra (*AggregateAttestationAndProofElectra)(nil), // 6: ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra (*AttestationElectra)(nil), // 7: ethereum.eth.v1alpha1.AttestationElectra - (*SingleAttestation)(nil), // 8: ethereum.eth.v1alpha1.SingleAttestation + (*SignedAggregateAttestationAndProofSingle)(nil), // 8: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProofSingle + (*AggregateAttestationAndProofSingle)(nil), // 9: ethereum.eth.v1alpha1.AggregateAttestationAndProofSingle + (*SingleAttestation)(nil), // 10: ethereum.eth.v1alpha1.SingleAttestation } var file_proto_prysm_v1alpha1_attestation_proto_depIdxs = []int32{ - 1, // 0: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProof.message:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof - 2, // 1: ethereum.eth.v1alpha1.AggregateAttestationAndProof.aggregate:type_name -> ethereum.eth.v1alpha1.Attestation - 3, // 2: ethereum.eth.v1alpha1.Attestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData - 4, // 3: ethereum.eth.v1alpha1.AttestationData.source:type_name -> ethereum.eth.v1alpha1.Checkpoint - 4, // 4: ethereum.eth.v1alpha1.AttestationData.target:type_name -> ethereum.eth.v1alpha1.Checkpoint - 6, // 5: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProofElectra.message:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra - 7, // 6: ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra.aggregate:type_name -> ethereum.eth.v1alpha1.AttestationElectra - 3, // 7: ethereum.eth.v1alpha1.AttestationElectra.data:type_name -> ethereum.eth.v1alpha1.AttestationData - 3, // 8: ethereum.eth.v1alpha1.SingleAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData - 9, // [9:9] is the sub-list for method output_type - 9, // [9:9] is the sub-list for method input_type - 9, // [9:9] is the sub-list for extension type_name - 9, // [9:9] is the sub-list for extension extendee - 0, // [0:9] is the sub-list for field type_name + 1, // 0: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProof.message:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProof + 2, // 1: ethereum.eth.v1alpha1.AggregateAttestationAndProof.aggregate:type_name -> ethereum.eth.v1alpha1.Attestation + 3, // 2: ethereum.eth.v1alpha1.Attestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData + 4, // 3: ethereum.eth.v1alpha1.AttestationData.source:type_name -> ethereum.eth.v1alpha1.Checkpoint + 4, // 4: ethereum.eth.v1alpha1.AttestationData.target:type_name -> ethereum.eth.v1alpha1.Checkpoint + 6, // 5: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProofElectra.message:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra + 7, // 6: ethereum.eth.v1alpha1.AggregateAttestationAndProofElectra.aggregate:type_name -> ethereum.eth.v1alpha1.AttestationElectra + 3, // 7: ethereum.eth.v1alpha1.AttestationElectra.data:type_name -> ethereum.eth.v1alpha1.AttestationData + 9, // 8: ethereum.eth.v1alpha1.SignedAggregateAttestationAndProofSingle.message:type_name -> ethereum.eth.v1alpha1.AggregateAttestationAndProofSingle + 10, // 9: ethereum.eth.v1alpha1.AggregateAttestationAndProofSingle.aggregate:type_name -> ethereum.eth.v1alpha1.SingleAttestation + 3, // 10: ethereum.eth.v1alpha1.SingleAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData + 11, // [11:11] is the sub-list for method output_type + 11, // [11:11] is the sub-list for method input_type + 11, // [11:11] is the sub-list for extension type_name + 11, // [11:11] is the sub-list for extension extendee + 0, // [0:11] is the sub-list for field type_name } func init() { file_proto_prysm_v1alpha1_attestation_proto_init() } @@ -909,6 +1060,30 @@ func file_proto_prysm_v1alpha1_attestation_proto_init() { } } file_proto_prysm_v1alpha1_attestation_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignedAggregateAttestationAndProofSingle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_prysm_v1alpha1_attestation_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AggregateAttestationAndProofSingle); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_prysm_v1alpha1_attestation_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SingleAttestation); i { case 0: return &v.state @@ -927,7 +1102,7 @@ func file_proto_prysm_v1alpha1_attestation_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_prysm_v1alpha1_attestation_proto_rawDesc, NumEnums: 0, - NumMessages: 9, + NumMessages: 11, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/prysm/v1alpha1/attestation.proto b/proto/prysm/v1alpha1/attestation.proto index b48c58574f32..f3429a37b1b0 100644 --- a/proto/prysm/v1alpha1/attestation.proto +++ b/proto/prysm/v1alpha1/attestation.proto @@ -126,6 +126,25 @@ message AttestationElectra { bytes committee_bits = 4 [(ethereum.eth.ext.ssz_size) = "committee_bits.size", (ethereum.eth.ext.cast_type) = "committee_bits.type"]; } +message SignedAggregateAttestationAndProofSingle { + // The aggregated attestation and selection proof itself. + AggregateAttestationAndProofSingle message = 1; + + // 96 byte BLS aggregate signature signed by the aggregator over the message. + bytes signature = 2 [(ethereum.eth.ext.ssz_size) = "96"]; +} + +message AggregateAttestationAndProofSingle { + // The aggregator index that submitted this aggregated attestation and proof. + uint64 aggregator_index = 1 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.ValidatorIndex"]; + + // The aggregated attestation that was submitted. + SingleAttestation aggregate = 3; + + // 96 byte selection proof signed by the aggregator, which is the signature of the slot to aggregate. + bytes selection_proof = 2 [(ethereum.eth.ext.ssz_size) = "96"]; +} + message SingleAttestation { uint64 committee_id = 1 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.CommitteeIndex"]; uint64 attester_index = 2 [(ethereum.eth.ext.cast_type) = "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.ValidatorIndex"]; diff --git a/proto/prysm/v1alpha1/electra.ssz.go b/proto/prysm/v1alpha1/electra.ssz.go index 1029c5cde25a..2016b77baeeb 100644 --- a/proto/prysm/v1alpha1/electra.ssz.go +++ b/proto/prysm/v1alpha1/electra.ssz.go @@ -383,6 +383,181 @@ func (a *AttestationElectra) HashTreeRootWith(hh *ssz.Hasher) (err error) { return } +// MarshalSSZ ssz marshals the SignedAggregateAttestationAndProofSingle object +func (s *SignedAggregateAttestationAndProofSingle) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(s) +} + +// MarshalSSZTo ssz marshals the SignedAggregateAttestationAndProofSingle object to a target array +func (s *SignedAggregateAttestationAndProofSingle) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + + // Field (0) 'Message' + if s.Message == nil { + s.Message = new(AggregateAttestationAndProofSingle) + } + if dst, err = s.Message.MarshalSSZTo(dst); err != nil { + return + } + + // Field (1) 'Signature' + if size := len(s.Signature); size != 96 { + err = ssz.ErrBytesLengthFn("--.Signature", size, 96) + return + } + dst = append(dst, s.Signature...) + + return +} + +// UnmarshalSSZ ssz unmarshals the SignedAggregateAttestationAndProofSingle object +func (s *SignedAggregateAttestationAndProofSingle) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size != 440 { + return ssz.ErrSize + } + + // Field (0) 'Message' + if s.Message == nil { + s.Message = new(AggregateAttestationAndProofSingle) + } + if err = s.Message.UnmarshalSSZ(buf[0:344]); err != nil { + return err + } + + // Field (1) 'Signature' + if cap(s.Signature) == 0 { + s.Signature = make([]byte, 0, len(buf[344:440])) + } + s.Signature = append(s.Signature, buf[344:440]...) + + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the SignedAggregateAttestationAndProofSingle object +func (s *SignedAggregateAttestationAndProofSingle) SizeSSZ() (size int) { + size = 440 + return +} + +// HashTreeRoot ssz hashes the SignedAggregateAttestationAndProofSingle object +func (s *SignedAggregateAttestationAndProofSingle) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(s) +} + +// HashTreeRootWith ssz hashes the SignedAggregateAttestationAndProofSingle object with a hasher +func (s *SignedAggregateAttestationAndProofSingle) HashTreeRootWith(hh *ssz.Hasher) (err error) { + indx := hh.Index() + + // Field (0) 'Message' + if err = s.Message.HashTreeRootWith(hh); err != nil { + return + } + + // Field (1) 'Signature' + if size := len(s.Signature); size != 96 { + err = ssz.ErrBytesLengthFn("--.Signature", size, 96) + return + } + hh.PutBytes(s.Signature) + + hh.Merkleize(indx) + return +} + +// MarshalSSZ ssz marshals the AggregateAttestationAndProofSingle object +func (a *AggregateAttestationAndProofSingle) MarshalSSZ() ([]byte, error) { + return ssz.MarshalSSZ(a) +} + +// MarshalSSZTo ssz marshals the AggregateAttestationAndProofSingle object to a target array +func (a *AggregateAttestationAndProofSingle) MarshalSSZTo(buf []byte) (dst []byte, err error) { + dst = buf + + // Field (0) 'AggregatorIndex' + dst = ssz.MarshalUint64(dst, uint64(a.AggregatorIndex)) + + // Field (1) 'Aggregate' + if a.Aggregate == nil { + a.Aggregate = new(SingleAttestation) + } + if dst, err = a.Aggregate.MarshalSSZTo(dst); err != nil { + return + } + + // Field (2) 'SelectionProof' + if size := len(a.SelectionProof); size != 96 { + err = ssz.ErrBytesLengthFn("--.SelectionProof", size, 96) + return + } + dst = append(dst, a.SelectionProof...) + + return +} + +// UnmarshalSSZ ssz unmarshals the AggregateAttestationAndProofSingle object +func (a *AggregateAttestationAndProofSingle) UnmarshalSSZ(buf []byte) error { + var err error + size := uint64(len(buf)) + if size != 344 { + return ssz.ErrSize + } + + // Field (0) 'AggregatorIndex' + a.AggregatorIndex = github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex(ssz.UnmarshallUint64(buf[0:8])) + + // Field (1) 'Aggregate' + if a.Aggregate == nil { + a.Aggregate = new(SingleAttestation) + } + if err = a.Aggregate.UnmarshalSSZ(buf[8:248]); err != nil { + return err + } + + // Field (2) 'SelectionProof' + if cap(a.SelectionProof) == 0 { + a.SelectionProof = make([]byte, 0, len(buf[248:344])) + } + a.SelectionProof = append(a.SelectionProof, buf[248:344]...) + + return err +} + +// SizeSSZ returns the ssz encoded size in bytes for the AggregateAttestationAndProofSingle object +func (a *AggregateAttestationAndProofSingle) SizeSSZ() (size int) { + size = 344 + return +} + +// HashTreeRoot ssz hashes the AggregateAttestationAndProofSingle object +func (a *AggregateAttestationAndProofSingle) HashTreeRoot() ([32]byte, error) { + return ssz.HashWithDefaultHasher(a) +} + +// HashTreeRootWith ssz hashes the AggregateAttestationAndProofSingle object with a hasher +func (a *AggregateAttestationAndProofSingle) HashTreeRootWith(hh *ssz.Hasher) (err error) { + indx := hh.Index() + + // Field (0) 'AggregatorIndex' + hh.PutUint64(uint64(a.AggregatorIndex)) + + // Field (1) 'Aggregate' + if err = a.Aggregate.HashTreeRootWith(hh); err != nil { + return + } + + // Field (2) 'SelectionProof' + if size := len(a.SelectionProof); size != 96 { + err = ssz.ErrBytesLengthFn("--.SelectionProof", size, 96) + return + } + hh.PutBytes(a.SelectionProof) + + hh.Merkleize(indx) + return +} + // MarshalSSZ ssz marshals the SingleAttestation object func (s *SingleAttestation) MarshalSSZ() ([]byte, error) { return ssz.MarshalSSZ(s) diff --git a/proto/prysm/v1alpha1/validator.pb.go b/proto/prysm/v1alpha1/validator.pb.go index 1ced7c92328b..8f73326c64f2 100755 --- a/proto/prysm/v1alpha1/validator.pb.go +++ b/proto/prysm/v1alpha1/validator.pb.go @@ -3747,7 +3747,7 @@ var file_proto_prysm_v1alpha1_validator_proto_rawDesc = []byte{ 0x0a, 0x06, 0x45, 0x58, 0x49, 0x54, 0x45, 0x44, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x07, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, 0x4c, 0x59, 0x5f, 0x44, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x45, 0x44, 0x10, 0x08, - 0x32, 0xf5, 0x28, 0x0a, 0x13, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x56, + 0x32, 0xf4, 0x28, 0x0a, 0x13, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x80, 0x01, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x44, 0x75, 0x74, 0x69, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, @@ -3875,216 +3875,216 @@ var file_proto_prysm_v1alpha1_validator_proto_rawDesc = []byte{ 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x22, 0x23, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0xa5, 0x01, 0x0a, 0x19, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x41, 0x74, + 0x6f, 0x6e, 0x12, 0xa4, 0x01, 0x0a, 0x19, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, - 0x12, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, - 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x1a, 0x25, 0x2e, 0x65, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x3a, 0x01, 0x2a, 0x22, 0x2b, 0x2f, - 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0xb2, 0x01, 0x0a, 0x1d, 0x53, - 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x30, 0x2e, 0x65, - 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, - 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x65, - 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, - 0xc8, 0x01, 0x0a, 0x24, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, - 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, - 0x66, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0x30, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, - 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x65, 0x74, 0x68, + 0x12, 0x28, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x41, + 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x25, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, - 0x29, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0xbe, 0x01, 0x0a, 0x23, 0x53, - 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, - 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, - 0x6f, 0x66, 0x12, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, - 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x61, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x3a, 0x01, 0x2a, 0x22, 0x2b, 0x2f, 0x65, + 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0xb2, 0x01, 0x0a, 0x1d, 0x53, 0x75, + 0x62, 0x6d, 0x69, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x30, 0x2e, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x65, 0x74, + 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0xc8, + 0x01, 0x0a, 0x24, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, + 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, + 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0x30, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, - 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x62, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0xd4, 0x01, 0x0a, 0x2a, - 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, - 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, - 0x6f, 0x6f, 0x66, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0x3a, 0x2e, 0x65, 0x74, 0x68, - 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, + 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x65, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, + 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x65, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0xbe, 0x01, 0x0a, 0x23, 0x53, 0x75, + 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, + 0x66, 0x12, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x75, - 0x62, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, + 0x62, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x72, 0x61, 0x12, 0x8e, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x45, 0x78, - 0x69, 0x74, 0x12, 0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, - 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x64, 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x1a, 0x2a, - 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x45, 0x78, - 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x21, 0x3a, 0x01, 0x2a, 0x22, 0x1c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x65, - 0x78, 0x69, 0x74, 0x12, 0xa1, 0x01, 0x0a, 0x19, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, - 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, - 0x73, 0x12, 0x37, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x74, 0x65, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, - 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x01, 0x2a, 0x22, 0x28, 0x2f, - 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x2f, 0x73, 0x75, - 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x9a, 0x01, 0x0a, 0x11, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x44, 0x6f, 0x70, 0x70, 0x65, 0x6c, 0x47, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x12, 0x2a, 0x2e, - 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x6f, 0x70, 0x70, 0x65, 0x6c, 0x47, 0x61, 0x6e, 0x67, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, + 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0xd4, 0x01, 0x0a, 0x2a, 0x53, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, + 0x6f, 0x66, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0x3a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2e, 0x44, 0x6f, 0x70, 0x70, 0x65, 0x6c, 0x47, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, - 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x64, 0x6f, 0x70, 0x70, 0x65, 0x6c, 0x67, 0x61, - 0x6e, 0x67, 0x65, 0x72, 0x12, 0x9f, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x79, 0x6e, 0x63, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, - 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, - 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x12, 0x2f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x73, - 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x12, 0x89, 0x01, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x6d, 0x69, - 0x74, 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x2e, 0x65, - 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, - 0x65, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x65, - 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0xb4, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x75, - 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, - 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x75, 0x62, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, - 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, - 0x63, 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x64, - 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x27, 0x12, 0x25, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x74, 0x65, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0xc4, 0x01, 0x0a, 0x1c, 0x47, 0x65, - 0x74, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x2e, 0x65, 0x74, 0x68, - 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, - 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, - 0x22, 0x2e, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, - 0x12, 0xaf, 0x01, 0x0a, 0x20, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, - 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x31, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x65, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, - 0x67, 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x41, 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x40, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3a, 0x3a, 0x01, 0x2a, 0x22, 0x35, 0x2f, 0x65, 0x74, - 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, - 0x6f, 0x66, 0x12, 0x9e, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x6c, 0x6f, - 0x74, 0x73, 0x12, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, - 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x53, 0x6c, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x67, 0x6e, 0x65, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72, + 0x61, 0x12, 0x8e, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x45, 0x78, 0x69, + 0x74, 0x12, 0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x56, 0x6f, 0x6c, 0x75, 0x6e, 0x74, 0x61, 0x72, 0x79, 0x45, 0x78, 0x69, 0x74, 0x1a, 0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x6c, 0x6f, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2d, 0x12, 0x2b, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x73, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x73, 0x88, 0x02, - 0x01, 0x30, 0x01, 0x12, 0xa1, 0x01, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x73, 0x41, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x12, 0x2a, 0x2e, 0x65, 0x74, 0x68, - 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, - 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x65, 0x74, - 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x88, 0x02, 0x01, 0x30, 0x01, 0x12, 0x9e, 0x01, 0x0a, 0x1c, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x6f, 0x73, 0x65, 0x45, 0x78, 0x69, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x21, 0x3a, 0x01, 0x2a, 0x22, 0x1c, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x65, 0x78, + 0x69, 0x74, 0x12, 0xa1, 0x01, 0x0a, 0x19, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, + 0x12, 0x37, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, + 0x65, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x01, 0x2a, 0x22, 0x28, 0x2f, 0x65, + 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x2f, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x9a, 0x01, 0x0a, 0x11, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x44, 0x6f, 0x70, 0x70, 0x65, 0x6c, 0x47, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x12, 0x2a, 0x2e, 0x65, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x6f, 0x70, 0x70, 0x65, 0x6c, 0x47, 0x61, 0x6e, 0x67, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, - 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x56, 0x31, 0x1a, + 0x2e, 0x44, 0x6f, 0x70, 0x70, 0x65, 0x6c, 0x47, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, + 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x64, 0x6f, 0x70, 0x70, 0x65, 0x6c, 0x67, 0x61, 0x6e, + 0x67, 0x65, 0x72, 0x12, 0x9f, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, - 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0xae, 0x01, 0x0a, 0x17, 0x41, 0x73, 0x73, - 0x69, 0x67, 0x6e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x53, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x12, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, - 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x73, 0x73, - 0x69, 0x67, 0x6e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x53, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3e, 0x3a, 0x01, 0x2a, 0x22, 0x39, - 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x61, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, - 0x74, 0x6f, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x12, 0xec, 0x01, 0x0a, 0x1f, 0x41, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x41, 0x6e, 0x64, 0x41, 0x67, - 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x12, 0x3d, 0x2e, - 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, - 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, - 0x53, 0x69, 0x67, 0x41, 0x6e, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x42, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x65, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x52, 0x6f, 0x6f, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x31, 0x12, 0x2f, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x73, 0x79, + 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x12, 0x89, 0x01, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, + 0x53, 0x79, 0x6e, 0x63, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x2e, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, + 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x65, 0x74, + 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0xb4, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x75, 0x62, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x33, + 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x75, 0x62, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, + 0x53, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x27, 0x12, 0x25, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x73, 0x75, 0x62, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, + 0x65, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0xc4, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, + 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x2e, 0x65, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, 0x22, + 0x2e, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x12, + 0xaf, 0x01, 0x0a, 0x20, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x50, + 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x31, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, + 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, + 0x6e, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41, + 0x6e, 0x64, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x40, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3a, 0x3a, 0x01, 0x2a, 0x22, 0x35, 0x2f, 0x65, 0x74, 0x68, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x6f, + 0x66, 0x12, 0x9e, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x6c, 0x6f, 0x74, + 0x73, 0x12, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x53, 0x6c, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x65, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x53, 0x6c, 0x6f, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, + 0x12, 0x2b, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, + 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x73, 0x88, 0x02, 0x01, + 0x30, 0x01, 0x12, 0xa1, 0x01, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x73, 0x41, 0x6c, 0x74, 0x61, 0x69, 0x72, 0x12, 0x2a, 0x2e, 0x65, 0x74, 0x68, 0x65, + 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x65, 0x74, 0x68, + 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x88, 0x02, 0x01, 0x30, 0x01, 0x12, 0x9e, 0x01, 0x0a, 0x1c, 0x53, 0x75, 0x62, 0x6d, 0x69, + 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, + 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x56, 0x31, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, + 0x2a, 0x22, 0x24, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0xae, 0x01, 0x0a, 0x17, 0x41, 0x73, 0x73, 0x69, + 0x67, 0x6e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x53, 0x75, 0x62, + 0x6e, 0x65, 0x74, 0x12, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, + 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x69, + 0x67, 0x6e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x53, 0x75, 0x62, + 0x6e, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3e, 0x3a, 0x01, 0x2a, 0x22, 0x39, 0x2f, + 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x61, 0x73, + 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x74, + 0x6f, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x12, 0xec, 0x01, 0x0a, 0x1f, 0x41, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x41, 0x6e, 0x64, 0x41, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x69, 0x74, 0x73, 0x12, 0x3d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, 0x67, 0x41, 0x6e, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x42, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x44, 0x12, 0x42, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x73, 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x73, 0x69, 0x67, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x69, 0x74, 0x73, 0x42, 0x93, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, - 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, - 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, - 0x45, 0x74, 0x68, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, - 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x42, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3e, 0x2e, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x53, 0x69, + 0x67, 0x41, 0x6e, 0x64, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x44, 0x12, 0x42, 0x2f, 0x65, 0x74, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x73, 0x2f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, + 0x69, 0x67, 0x5f, 0x61, 0x6e, 0x64, 0x5f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x62, 0x69, 0x74, 0x73, 0x42, 0x93, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, + 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, + 0x65, 0x74, 0x68, 0xaa, 0x02, 0x0f, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, + 0x74, 0x68, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4169,7 +4169,7 @@ var file_proto_prysm_v1alpha1_validator_proto_goTypes = []interface{}{ (*emptypb.Empty)(nil), // 64: google.protobuf.Empty (*GenericSignedBeaconBlock)(nil), // 65: ethereum.eth.v1alpha1.GenericSignedBeaconBlock (*Attestation)(nil), // 66: ethereum.eth.v1alpha1.Attestation - (*AttestationElectra)(nil), // 67: ethereum.eth.v1alpha1.AttestationElectra + (*SingleAttestation)(nil), // 67: ethereum.eth.v1alpha1.SingleAttestation (*SignedVoluntaryExit)(nil), // 68: ethereum.eth.v1alpha1.SignedVoluntaryExit (*SignedContributionAndProof)(nil), // 69: ethereum.eth.v1alpha1.SignedContributionAndProof (*SignedValidatorRegistrationsV1)(nil), // 70: ethereum.eth.v1alpha1.SignedValidatorRegistrationsV1 @@ -4216,7 +4216,7 @@ var file_proto_prysm_v1alpha1_validator_proto_depIdxs = []int32{ 41, // 35: ethereum.eth.v1alpha1.BeaconNodeValidator.GetFeeRecipientByPubKey:input_type -> ethereum.eth.v1alpha1.FeeRecipientByPubKeyRequest 24, // 36: ethereum.eth.v1alpha1.BeaconNodeValidator.GetAttestationData:input_type -> ethereum.eth.v1alpha1.AttestationDataRequest 66, // 37: ethereum.eth.v1alpha1.BeaconNodeValidator.ProposeAttestation:input_type -> ethereum.eth.v1alpha1.Attestation - 67, // 38: ethereum.eth.v1alpha1.BeaconNodeValidator.ProposeAttestationElectra:input_type -> ethereum.eth.v1alpha1.AttestationElectra + 67, // 38: ethereum.eth.v1alpha1.BeaconNodeValidator.ProposeAttestationElectra:input_type -> ethereum.eth.v1alpha1.SingleAttestation 26, // 39: ethereum.eth.v1alpha1.BeaconNodeValidator.SubmitAggregateSelectionProof:input_type -> ethereum.eth.v1alpha1.AggregateSelectionRequest 26, // 40: ethereum.eth.v1alpha1.BeaconNodeValidator.SubmitAggregateSelectionProofElectra:input_type -> ethereum.eth.v1alpha1.AggregateSelectionRequest 29, // 41: ethereum.eth.v1alpha1.BeaconNodeValidator.SubmitSignedAggregateSelectionProof:input_type -> ethereum.eth.v1alpha1.SignedAggregateSubmitRequest @@ -4939,7 +4939,7 @@ type BeaconNodeValidatorClient interface { GetFeeRecipientByPubKey(ctx context.Context, in *FeeRecipientByPubKeyRequest, opts ...grpc.CallOption) (*FeeRecipientByPubKeyResponse, error) GetAttestationData(ctx context.Context, in *AttestationDataRequest, opts ...grpc.CallOption) (*AttestationData, error) ProposeAttestation(ctx context.Context, in *Attestation, opts ...grpc.CallOption) (*AttestResponse, error) - ProposeAttestationElectra(ctx context.Context, in *AttestationElectra, opts ...grpc.CallOption) (*AttestResponse, error) + ProposeAttestationElectra(ctx context.Context, in *SingleAttestation, opts ...grpc.CallOption) (*AttestResponse, error) SubmitAggregateSelectionProof(ctx context.Context, in *AggregateSelectionRequest, opts ...grpc.CallOption) (*AggregateSelectionResponse, error) SubmitAggregateSelectionProofElectra(ctx context.Context, in *AggregateSelectionRequest, opts ...grpc.CallOption) (*AggregateSelectionElectraResponse, error) SubmitSignedAggregateSelectionProof(ctx context.Context, in *SignedAggregateSubmitRequest, opts ...grpc.CallOption) (*SignedAggregateSubmitResponse, error) @@ -5134,7 +5134,7 @@ func (c *beaconNodeValidatorClient) ProposeAttestation(ctx context.Context, in * return out, nil } -func (c *beaconNodeValidatorClient) ProposeAttestationElectra(ctx context.Context, in *AttestationElectra, opts ...grpc.CallOption) (*AttestResponse, error) { +func (c *beaconNodeValidatorClient) ProposeAttestationElectra(ctx context.Context, in *SingleAttestation, opts ...grpc.CallOption) (*AttestResponse, error) { out := new(AttestResponse) err := c.cc.Invoke(ctx, "/ethereum.eth.v1alpha1.BeaconNodeValidator/ProposeAttestationElectra", in, out, opts...) if err != nil { @@ -5361,7 +5361,7 @@ type BeaconNodeValidatorServer interface { GetFeeRecipientByPubKey(context.Context, *FeeRecipientByPubKeyRequest) (*FeeRecipientByPubKeyResponse, error) GetAttestationData(context.Context, *AttestationDataRequest) (*AttestationData, error) ProposeAttestation(context.Context, *Attestation) (*AttestResponse, error) - ProposeAttestationElectra(context.Context, *AttestationElectra) (*AttestResponse, error) + ProposeAttestationElectra(context.Context, *SingleAttestation) (*AttestResponse, error) SubmitAggregateSelectionProof(context.Context, *AggregateSelectionRequest) (*AggregateSelectionResponse, error) SubmitAggregateSelectionProofElectra(context.Context, *AggregateSelectionRequest) (*AggregateSelectionElectraResponse, error) SubmitSignedAggregateSelectionProof(context.Context, *SignedAggregateSubmitRequest) (*SignedAggregateSubmitResponse, error) @@ -5426,7 +5426,7 @@ func (*UnimplementedBeaconNodeValidatorServer) GetAttestationData(context.Contex func (*UnimplementedBeaconNodeValidatorServer) ProposeAttestation(context.Context, *Attestation) (*AttestResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ProposeAttestation not implemented") } -func (*UnimplementedBeaconNodeValidatorServer) ProposeAttestationElectra(context.Context, *AttestationElectra) (*AttestResponse, error) { +func (*UnimplementedBeaconNodeValidatorServer) ProposeAttestationElectra(context.Context, *SingleAttestation) (*AttestResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ProposeAttestationElectra not implemented") } func (*UnimplementedBeaconNodeValidatorServer) SubmitAggregateSelectionProof(context.Context, *AggregateSelectionRequest) (*AggregateSelectionResponse, error) { @@ -5726,7 +5726,7 @@ func _BeaconNodeValidator_ProposeAttestation_Handler(srv interface{}, ctx contex } func _BeaconNodeValidator_ProposeAttestationElectra_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AttestationElectra) + in := new(SingleAttestation) if err := dec(in); err != nil { return nil, err } @@ -5738,7 +5738,7 @@ func _BeaconNodeValidator_ProposeAttestationElectra_Handler(srv interface{}, ctx FullMethod: "/ethereum.eth.v1alpha1.BeaconNodeValidator/ProposeAttestationElectra", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BeaconNodeValidatorServer).ProposeAttestationElectra(ctx, req.(*AttestationElectra)) + return srv.(BeaconNodeValidatorServer).ProposeAttestationElectra(ctx, req.(*SingleAttestation)) } return interceptor(ctx, in, info, handler) } diff --git a/proto/prysm/v1alpha1/validator.proto b/proto/prysm/v1alpha1/validator.proto index 9d981cb29c05..c6fe3aca431c 100644 --- a/proto/prysm/v1alpha1/validator.proto +++ b/proto/prysm/v1alpha1/validator.proto @@ -194,7 +194,7 @@ service BeaconNodeValidator { // The validator sends the newly signed attestation to the beacon node for the attestation to // be included in the beacon chain. The beacon node is expected to validate and publish attestation on // appropriate committee subnet. - rpc ProposeAttestationElectra(AttestationElectra) returns (AttestResponse) { + rpc ProposeAttestationElectra(SingleAttestation) returns (AttestResponse) { option (google.api.http) = { post: "/eth/v1alpha1/validator/attestation_electra" body: "*" diff --git a/runtime/debug/BUILD.bazel b/runtime/debug/BUILD.bazel index db34de5e7ed2..bd3d7bdcedc6 100644 --- a/runtime/debug/BUILD.bazel +++ b/runtime/debug/BUILD.bazel @@ -18,7 +18,6 @@ go_library( importpath = "github.com/prysmaticlabs/prysm/v5/runtime/debug", visibility = ["//visibility:public"], deps = [ - "@com_github_fjl_memsize//memsizeui:go_default_library", "@com_github_prometheus_client_golang//prometheus:go_default_library", "@com_github_prometheus_client_golang//prometheus/promauto:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", diff --git a/runtime/debug/debug.go b/runtime/debug/debug.go index ab79ec4bece8..45c6994c5e02 100644 --- a/runtime/debug/debug.go +++ b/runtime/debug/debug.go @@ -37,7 +37,6 @@ import ( "sync" "time" - "github.com/fjl/memsize/memsizeui" log "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" ) @@ -45,8 +44,6 @@ import ( // Handler is the global debugging handler. var Handler = new(HandlerT) -// Memsize is the memsizeui Handler(?). -var Memsize memsizeui.Handler var ( // PProfFlag to enable pprof HTTP server. PProfFlag = &cli.BoolFlag{ @@ -351,7 +348,6 @@ func Setup(ctx *cli.Context) error { } func startPProf(address string) { - http.Handle("/memsize/", http.StripPrefix("/memsize", &Memsize)) log.WithField("addr", fmt.Sprintf("http://%s/debug/pprof", address)).Info("Starting pprof server") go func() { srv := &http.Server{ diff --git a/runtime/interop/genesis.go b/runtime/interop/genesis.go index 001225cf4734..3a85b40b8673 100644 --- a/runtime/interop/genesis.go +++ b/runtime/interop/genesis.go @@ -1,13 +1,13 @@ package interop import ( - "fmt" "math" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" clparams "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/time/slots" @@ -127,47 +127,50 @@ func GethPragueTime(genesisTime uint64, cfg *clparams.BeaconChainConfig) *uint64 // customized as desired. func GethTestnetGenesis(genesisTime uint64, cfg *clparams.BeaconChainConfig) *core.Genesis { shanghaiTime := GethShanghaiTime(genesisTime, cfg) + if cfg.CapellaForkEpoch == 0 { + shanghaiTime = &genesisTime + } cancunTime := GethCancunTime(genesisTime, cfg) + if cfg.DenebForkEpoch == 0 { + cancunTime = &genesisTime + } pragueTime := GethPragueTime(genesisTime, cfg) + if cfg.ElectraForkEpoch == 0 { + pragueTime = &genesisTime + } cc := ¶ms.ChainConfig{ - ChainID: big.NewInt(defaultTestChainId), - HomesteadBlock: bigz, - DAOForkBlock: bigz, - EIP150Block: bigz, - EIP155Block: bigz, - EIP158Block: bigz, - ByzantiumBlock: bigz, - ConstantinopleBlock: bigz, - PetersburgBlock: bigz, - IstanbulBlock: bigz, - MuirGlacierBlock: bigz, - BerlinBlock: bigz, - LondonBlock: bigz, - ArrowGlacierBlock: bigz, - GrayGlacierBlock: bigz, - MergeNetsplitBlock: bigz, - TerminalTotalDifficultyPassed: true, - TerminalTotalDifficulty: bigz, - ShanghaiTime: shanghaiTime, - CancunTime: cancunTime, - PragueTime: pragueTime, + ChainID: big.NewInt(defaultTestChainId), + HomesteadBlock: bigz, + DAOForkBlock: bigz, + EIP150Block: bigz, + EIP155Block: bigz, + EIP158Block: bigz, + ByzantiumBlock: bigz, + ConstantinopleBlock: bigz, + PetersburgBlock: bigz, + IstanbulBlock: bigz, + MuirGlacierBlock: bigz, + BerlinBlock: bigz, + LondonBlock: bigz, + ArrowGlacierBlock: bigz, + GrayGlacierBlock: bigz, + MergeNetsplitBlock: bigz, + TerminalTotalDifficulty: bigz, + ShanghaiTime: shanghaiTime, + CancunTime: cancunTime, + PragueTime: pragueTime, } da := defaultDepositContractAllocation(cfg.DepositContractAddress) ma := minerAllocation() - extra, err := hexutil.Decode(DefaultCliqueSigner) - if err != nil { - panic(fmt.Sprintf("unable to decode DefaultCliqueSigner, with error %v", err.Error())) - } return &core.Genesis{ Config: cc, Nonce: 0, // overridden for authorized signer votes in clique, so we should leave it empty? Timestamp: genesisTime, - ExtraData: extra, GasLimit: cfg.DefaultBuilderGasLimit, Difficulty: common.HexToHash(defaultDifficulty).Big(), Mixhash: common.HexToHash(defaultMixhash), Coinbase: common.HexToAddress(defaultCoinbase), - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ da.Address: da.Account, ma.Address: ma.Account, }, @@ -177,13 +180,13 @@ func GethTestnetGenesis(genesisTime uint64, cfg *clparams.BeaconChainConfig) *co type depositAllocation struct { Address common.Address - Account core.GenesisAccount + Account types.Account } func minerAllocation() depositAllocation { return depositAllocation{ Address: common.HexToAddress(defaultMinerAddress), - Account: core.GenesisAccount{ + Account: types.Account{ Balance: minerBalance, }, } @@ -200,7 +203,7 @@ func defaultDepositContractAllocation(contractAddress string) depositAllocation } return depositAllocation{ Address: common.HexToAddress(contractAddress), - Account: core.GenesisAccount{ + Account: types.Account{ Code: codeBytes, Storage: s, Balance: bigz, diff --git a/runtime/interop/premine-state.go b/runtime/interop/premine-state.go index 695d6755f292..b073e303d87d 100644 --- a/runtime/interop/premine-state.go +++ b/runtime/interop/premine-state.go @@ -641,7 +641,7 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error { GasLimit: gb.GasLimit(), GasUsed: gb.GasUsed(), Timestamp: gb.Time(), - ExtraData: gb.Extra()[:32], + ExtraData: gb.Extra(), BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength), BlockHash: gb.Hash().Bytes(), Transactions: make([][]byte, 0), @@ -680,7 +680,7 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error { GasLimit: gb.GasLimit(), GasUsed: gb.GasUsed(), Timestamp: gb.Time(), - ExtraData: gb.Extra()[:32], + ExtraData: gb.Extra(), BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength), BlockHash: gb.Hash().Bytes(), Transactions: make([][]byte, 0), @@ -696,7 +696,6 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error { if err != nil { return err } - ed, err := blocks.WrappedExecutionPayloadHeaderCapella(eph) if err != nil { return err @@ -717,7 +716,7 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error { GasLimit: gb.GasLimit(), GasUsed: gb.GasUsed(), Timestamp: gb.Time(), - ExtraData: gb.Extra()[:32], + ExtraData: gb.Extra(), BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength), BlockHash: gb.Hash().Bytes(), Transactions: make([][]byte, 0), diff --git a/testing/endtoend/components/eth1/BUILD.bazel b/testing/endtoend/components/eth1/BUILD.bazel index 46bc9c0a7c92..93facd8b3be1 100644 --- a/testing/endtoend/components/eth1/BUILD.bazel +++ b/testing/endtoend/components/eth1/BUILD.bazel @@ -28,12 +28,14 @@ go_library( "//testing/endtoend/types:go_default_library", "//testing/middleware/engine-api-proxy:go_default_library", "//testing/util:go_default_library", + "@com_github_ethereum_go_ethereum//:go_default_library", "@com_github_ethereum_go_ethereum//accounts/abi/bind:go_default_library", "@com_github_ethereum_go_ethereum//accounts/keystore:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//core/types:go_default_library", "@com_github_ethereum_go_ethereum//crypto/kzg4844:go_default_library", "@com_github_ethereum_go_ethereum//ethclient:go_default_library", + "@com_github_ethereum_go_ethereum//ethclient/gethclient:go_default_library", "@com_github_ethereum_go_ethereum//rpc:go_default_library", "@com_github_holiman_uint256//:go_default_library", "@com_github_mariusvanderwijden_fuzzyvm//filler:go_default_library", diff --git a/testing/endtoend/components/eth1/miner.go b/testing/endtoend/components/eth1/miner.go index 9d7998ea6ac0..461c293993c3 100644 --- a/testing/endtoend/components/eth1/miner.go +++ b/testing/endtoend/components/eth1/miner.go @@ -143,11 +143,9 @@ func (m *Miner) initAttempt(ctx context.Context, attempt int) (*os.File, error) "--ws.origins=\"*\"", "--ipcdisable", "--verbosity=4", - "--mine", fmt.Sprintf("--unlock=%s", EthAddress), "--allow-insecure-unlock", "--syncmode=full", - fmt.Sprintf("--miner.etherbase=%s", EthAddress), fmt.Sprintf("--txpool.locals=%s", EthAddress), fmt.Sprintf("--password=%s", pwFile), } diff --git a/testing/endtoend/components/eth1/node.go b/testing/endtoend/components/eth1/node.go index e0cef7d32838..e3296dcc80da 100644 --- a/testing/endtoend/components/eth1/node.go +++ b/testing/endtoend/components/eth1/node.go @@ -127,12 +127,16 @@ func (node *Node) Start(ctx context.Context) error { if err = runCmd.Start(); err != nil { return fmt.Errorf("failed to start eth1 chain: %w", err) } - if err = helpers.WaitForTextInFile(errLog, "Started P2P networking"); err != nil { + // TODO: the log is not very descriptive but it's always the first log where the chain has + // - a peer + // - http server started + // - genesis synced + if err = helpers.WaitForTextInFile(errLog, "Node revalidated"); err != nil { kerr := runCmd.Process.Kill() if kerr != nil { log.WithError(kerr).Error("error sending kill to failed node command process") } - retryErr = fmt.Errorf("P2P log not found, this means the eth1 chain had issues starting: %w", err) + retryErr = fmt.Errorf("the first node revalidated log not found, this means the eth1 chain had issues starting: %w", err) continue } node.cmd = runCmd diff --git a/testing/endtoend/components/eth1/transactions.go b/testing/endtoend/components/eth1/transactions.go index 5426adae257d..71afaef9326c 100644 --- a/testing/endtoend/components/eth1/transactions.go +++ b/testing/endtoend/components/eth1/transactions.go @@ -12,11 +12,13 @@ import ( "github.com/MariusVanDerWijden/FuzzyVM/filler" txfuzz "github.com/MariusVanDerWijden/tx-fuzz" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/ethclient/gethclient" "github.com/ethereum/go-ethereum/rpc" "github.com/holiman/uint256" "github.com/pkg/errors" @@ -257,27 +259,47 @@ func RandomBlobTx(rpc *rpc.Client, f *filler.Filler, sender common.Address, nonc // 4844 transaction without AL tip, feecap, err := getCaps(rpc, gasPrice) if err != nil { - return nil, err + return nil, errors.Wrap(err, "getCaps") } data, err := randomBlobData() if err != nil { - return nil, err + return nil, errors.Wrap(err, "randomBlobData") } return New4844Tx(nonce, &to, gas, chainID, tip, feecap, value, code, big.NewInt(1000000), data, make(types.AccessList, 0)), nil case 1: - // 4844 transaction with AL - tx := types.NewTransaction(nonce, to, value, gas, gasPrice, code) - al, err := txfuzz.CreateAccessList(rpc, tx, sender) + // 4844 transaction with AL nonce, to, value, gas, gasPrice, code + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + To: &to, + Value: value, + Gas: gas, + GasPrice: gasPrice, + Data: code, + }) + + // TODO: replace call with al, err := txfuzz.CreateAccessList(rpc, tx, sender) when txfuzz is fixed in new release + // an error occurs mentioning error="CreateAccessList: both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified" + msg := ethereum.CallMsg{ + From: sender, + To: tx.To(), + Gas: tx.Gas(), + GasPrice: tx.GasPrice(), + Value: tx.Value(), + Data: tx.Data(), + AccessList: nil, + } + geth := gethclient.New(rpc) + al, _, _, err := geth.CreateAccessList(context.Background(), msg) if err != nil { - return nil, err + return nil, errors.Wrap(err, "CreateAccessList") } tip, feecap, err := getCaps(rpc, gasPrice) if err != nil { - return nil, err + return nil, errors.Wrap(err, "getCaps") } data, err := randomBlobData() if err != nil { - return nil, err + return nil, errors.Wrap(err, "randomBlobData") } return New4844Tx(nonce, &to, gas, chainID, tip, feecap, value, code, big.NewInt(1000000), data, *al), nil } @@ -342,17 +364,18 @@ func EncodeBlobs(data []byte) ([]kzg4844.Blob, []kzg4844.Commitment, []kzg4844.P versionedHashes []common.Hash ) for _, blob := range blobs { - commit, err := kzg4844.BlobToCommitment(blob) + b := blob + commit, err := kzg4844.BlobToCommitment(&b) if err != nil { return nil, nil, nil, nil, err } commits = append(commits, commit) - proof, err := kzg4844.ComputeBlobProof(blob, commit) + proof, err := kzg4844.ComputeBlobProof(&b, commit) if err != nil { return nil, nil, nil, nil, err } - if err := kzg4844.VerifyBlobProof(blob, commit, proof); err != nil { + if err := kzg4844.VerifyBlobProof(&b, commit, proof); err != nil { return nil, nil, nil, nil, err } proofs = append(proofs, proof) diff --git a/testing/endtoend/endtoend_setup_test.go b/testing/endtoend/endtoend_setup_test.go index d43295d46734..d3cd9b6725ba 100644 --- a/testing/endtoend/endtoend_setup_test.go +++ b/testing/endtoend/endtoend_setup_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" ev "github.com/prysmaticlabs/prysm/v5/testing/endtoend/evaluators" "github.com/prysmaticlabs/prysm/v5/testing/endtoend/evaluators/beaconapi" e2eParams "github.com/prysmaticlabs/prysm/v5/testing/endtoend/params" @@ -38,6 +39,11 @@ func e2eMinimal(t *testing.T, cfg *params.BeaconChainConfig, cfgo ...types.E2ECo evals := []types.Evaluator{ //ev.TransactionsPresent, TODO: Re-enable Transaction evaluator once it tx pool issues are fixed. } + evals = addIfForkSet(evals, cfg.AltairForkEpoch, ev.AltairForkTransition) + evals = addIfForkSet(evals, cfg.BellatrixForkEpoch, ev.BellatrixForkTransition) + evals = addIfForkSet(evals, cfg.CapellaForkEpoch, ev.CapellaForkTransition) + evals = addIfForkSet(evals, cfg.DenebForkEpoch, ev.DenebForkTransition) + testConfig := &types.E2EConfig{ BeaconFlags: []string{ fmt.Sprintf("--slots-per-archive-point=%d", params.BeaconConfig().SlotsPerEpoch*16), @@ -103,15 +109,16 @@ func e2eMainnet(t *testing.T, usePrysmSh, useMultiClient bool, cfg *params.Beaco ev.ValidatorsHaveWithdrawn, ev.DepositedValidatorsAreActive, ev.ColdStateCheckpoint, - ev.AltairForkTransition, - ev.BellatrixForkTransition, - ev.CapellaForkTransition, - ev.DenebForkTransition, ev.FinishedSyncing, ev.AllNodesHaveSameHead, ev.FeeRecipientIsPresent, //ev.TransactionsPresent, TODO: Re-enable Transaction evaluator once it tx pool issues are fixed. } + evals = addIfForkSet(evals, cfg.AltairForkEpoch, ev.AltairForkTransition) + evals = addIfForkSet(evals, cfg.BellatrixForkEpoch, ev.BellatrixForkTransition) + evals = addIfForkSet(evals, cfg.CapellaForkEpoch, ev.CapellaForkTransition) + evals = addIfForkSet(evals, cfg.DenebForkEpoch, ev.DenebForkTransition) + testConfig := &types.E2EConfig{ BeaconFlags: []string{ fmt.Sprintf("--slots-per-archive-point=%d", params.BeaconConfig().SlotsPerEpoch*16), @@ -147,6 +154,18 @@ func e2eMainnet(t *testing.T, usePrysmSh, useMultiClient bool, cfg *params.Beaco return newTestRunner(t, testConfig) } +// addIfForkSet appends the specified transition if epoch is valid. +func addIfForkSet( + evals []types.Evaluator, + fork primitives.Epoch, + transition types.Evaluator, +) []types.Evaluator { + if fork != 0 && fork != params.BeaconConfig().FarFutureEpoch { + evals = append(evals, transition) + } + return evals +} + func scenarioEvals() []types.Evaluator { return []types.Evaluator{ ev.PeersConnect, diff --git a/testing/endtoend/evaluators/builder.go b/testing/endtoend/evaluators/builder.go index e9a7f8ebc21b..c696e8982da9 100644 --- a/testing/endtoend/evaluators/builder.go +++ b/testing/endtoend/evaluators/builder.go @@ -3,11 +3,13 @@ package evaluators import ( "context" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/encoding/ssz" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/v5/runtime/version" "github.com/prysmaticlabs/prysm/v5/testing/endtoend/policies" e2etypes "github.com/prysmaticlabs/prysm/v5/testing/endtoend/types" "github.com/prysmaticlabs/prysm/v5/time/slots" @@ -64,7 +66,7 @@ func builderActive(_ *e2etypes.EvaluationContext, conns ...*grpc.ClientConn) err if err != nil { return err } - if forkStartSlot == b.Block().Slot() || forkStartSlot+1 == b.Block().Slot() { + if forkStartSlot == b.Block().Slot() || forkStartSlot+1 == b.Block().Slot() || lowestBound <= 1 { // Skip fork slot and the next one, as we don't send FCUs yet. continue } @@ -82,10 +84,10 @@ func builderActive(_ *e2etypes.EvaluationContext, conns ...*grpc.ClientConn) err continue } if string(execPayload.ExtraData()) != "prysm-builder" { - return errors.Errorf("block with slot %d was not built by the builder. It has an extra data of %s", b.Block().Slot(), string(execPayload.ExtraData())) + return errors.Errorf("%s block with slot %d was not built by the builder. It has an extra data of %s and txRoot of %s", version.String(b.Version()), b.Block().Slot(), string(execPayload.ExtraData()), hexutil.Encode(txRoot)) } if execPayload.GasLimit() == 0 { - return errors.Errorf("block with slot %d has a gas limit of 0, when it should be in the 30M range", b.Block().Slot()) + return errors.Errorf("%s block with slot %d has a gas limit of 0, when it should be in the 30M range", version.String(b.Version()), b.Block().Slot()) } } if lowestBound == currEpoch { @@ -107,7 +109,7 @@ func builderActive(_ *e2etypes.EvaluationContext, conns ...*grpc.ClientConn) err if err != nil { return err } - if forkStartSlot == b.Block().Slot() || forkStartSlot+1 == b.Block().Slot() { + if forkStartSlot == b.Block().Slot() || forkStartSlot+1 == b.Block().Slot() || lowestBound <= 1 { // Skip fork slot and the next one, as we don't send FCUs yet. continue } @@ -125,10 +127,10 @@ func builderActive(_ *e2etypes.EvaluationContext, conns ...*grpc.ClientConn) err continue } if string(execPayload.ExtraData()) != "prysm-builder" { - return errors.Errorf("block with slot %d was not built by the builder. It has an extra data of %s", b.Block().Slot(), string(execPayload.ExtraData())) + return errors.Errorf("%s block with slot %d was not built by the builder. It has an extra data of %s and txRoot of %s", version.String(b.Version()), b.Block().Slot(), string(execPayload.ExtraData()), hexutil.Encode(txRoot)) } if execPayload.GasLimit() == 0 { - return errors.Errorf("block with slot %d has a gas limit of 0, when it should be in the 30M range", b.Block().Slot()) + return errors.Errorf("%s block with slot %d has a gas limit of 0, when it should be in the 30M range", version.String(b.Version()), b.Block().Slot()) } } return nil diff --git a/testing/endtoend/geth_deps.go b/testing/endtoend/geth_deps.go index b021138818c7..d06d54c1bc50 100644 --- a/testing/endtoend/geth_deps.go +++ b/testing/endtoend/geth_deps.go @@ -12,7 +12,6 @@ import ( _ "github.com/ethereum/go-ethereum/eth" // Required for go-ethereum e2e. _ "github.com/ethereum/go-ethereum/eth/downloader" // Required for go-ethereum e2e. _ "github.com/ethereum/go-ethereum/ethclient" // Required for go-ethereum e2e. - _ "github.com/ethereum/go-ethereum/les" // Required for go-ethereum e2e. _ "github.com/ethereum/go-ethereum/log" // Required for go-ethereum e2e. _ "github.com/ethereum/go-ethereum/metrics" // Required for go-ethereum e2e. _ "github.com/ethereum/go-ethereum/node" // Required for go-ethereum e2e. diff --git a/testing/endtoend/mainnet_e2e_test.go b/testing/endtoend/mainnet_e2e_test.go index 409b6bf8d6ee..feaa908b56c6 100644 --- a/testing/endtoend/mainnet_e2e_test.go +++ b/testing/endtoend/mainnet_e2e_test.go @@ -10,10 +10,10 @@ import ( // Run mainnet e2e config with the current release validator against latest beacon node. func TestEndToEnd_MainnetConfig_ValidatorAtCurrentRelease(t *testing.T) { - r := e2eMainnet(t, true, false, types.InitForkCfg(version.Phase0, version.Deneb, params.E2EMainnetTestConfig())) + r := e2eMainnet(t, true, false, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2EMainnetTestConfig())) r.run() } func TestEndToEnd_MainnetConfig_MultiClient(t *testing.T) { - e2eMainnet(t, false, true, types.InitForkCfg(version.Phase0, version.Deneb, params.E2EMainnetTestConfig()), types.WithValidatorCrossClient()).run() + e2eMainnet(t, false, true, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2EMainnetTestConfig()), types.WithValidatorCrossClient()).run() } diff --git a/testing/endtoend/mainnet_scenario_e2e_test.go b/testing/endtoend/mainnet_scenario_e2e_test.go index 956dc9991278..0c41a2cfc468 100644 --- a/testing/endtoend/mainnet_scenario_e2e_test.go +++ b/testing/endtoend/mainnet_scenario_e2e_test.go @@ -9,7 +9,7 @@ import ( ) func TestEndToEnd_MultiScenarioRun_Multiclient(t *testing.T) { - runner := e2eMainnet(t, false, true, types.InitForkCfg(version.Phase0, version.Deneb, params.E2EMainnetTestConfig()), types.WithEpochs(24)) + runner := e2eMainnet(t, false, true, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2EMainnetTestConfig()), types.WithEpochs(24)) runner.config.Evaluators = scenarioEvalsMulti() runner.config.EvalInterceptor = runner.multiScenarioMulticlient runner.scenarioRunner() diff --git a/testing/endtoend/minimal_builder_e2e_test.go b/testing/endtoend/minimal_builder_e2e_test.go index 600adbcbd8f7..f47677505463 100644 --- a/testing/endtoend/minimal_builder_e2e_test.go +++ b/testing/endtoend/minimal_builder_e2e_test.go @@ -9,11 +9,11 @@ import ( ) func TestEndToEnd_MinimalConfig_WithBuilder(t *testing.T) { - r := e2eMinimal(t, types.InitForkCfg(version.Phase0, version.Deneb, params.E2ETestConfig()), types.WithCheckpointSync(), types.WithBuilder()) + r := e2eMinimal(t, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig()), types.WithCheckpointSync(), types.WithBuilder()) r.run() } func TestEndToEnd_MinimalConfig_WithBuilder_ValidatorRESTApi(t *testing.T) { - r := e2eMinimal(t, types.InitForkCfg(version.Phase0, version.Deneb, params.E2ETestConfig()), types.WithCheckpointSync(), types.WithBuilder(), types.WithValidatorRESTApi()) + r := e2eMinimal(t, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig()), types.WithCheckpointSync(), types.WithBuilder(), types.WithValidatorRESTApi()) r.run() } diff --git a/testing/endtoend/minimal_scenario_e2e_test.go b/testing/endtoend/minimal_scenario_e2e_test.go index 33628927a709..e542859fe053 100644 --- a/testing/endtoend/minimal_scenario_e2e_test.go +++ b/testing/endtoend/minimal_scenario_e2e_test.go @@ -9,7 +9,7 @@ import ( ) func TestEndToEnd_MultiScenarioRun(t *testing.T) { - runner := e2eMinimal(t, types.InitForkCfg(version.Phase0, version.Deneb, params.E2ETestConfig()), types.WithEpochs(26)) + runner := e2eMinimal(t, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig()), types.WithEpochs(26)) runner.config.Evaluators = scenarioEvals() runner.config.EvalInterceptor = runner.multiScenario @@ -17,20 +17,20 @@ func TestEndToEnd_MultiScenarioRun(t *testing.T) { } func TestEndToEnd_MinimalConfig_Web3Signer(t *testing.T) { - e2eMinimal(t, types.InitForkCfg(version.Phase0, version.Deneb, params.E2ETestConfig()), types.WithRemoteSigner()).run() + e2eMinimal(t, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig()), types.WithRemoteSigner()).run() } func TestEndToEnd_MinimalConfig_Web3Signer_PersistentKeys(t *testing.T) { - e2eMinimal(t, types.InitForkCfg(version.Phase0, version.Deneb, params.E2ETestConfig()), types.WithRemoteSignerAndPersistentKeysFile()).run() + e2eMinimal(t, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig()), types.WithRemoteSignerAndPersistentKeysFile()).run() } func TestEndToEnd_MinimalConfig_ValidatorRESTApi(t *testing.T) { - e2eMinimal(t, types.InitForkCfg(version.Phase0, version.Deneb, params.E2ETestConfig()), types.WithCheckpointSync(), types.WithValidatorRESTApi()).run() + e2eMinimal(t, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig()), types.WithCheckpointSync(), types.WithValidatorRESTApi()).run() } func TestEndToEnd_ScenarioRun_EEOffline(t *testing.T) { t.Skip("TODO(#10242) Prysm is current unable to handle an offline e2e") - runner := e2eMinimal(t, types.InitForkCfg(version.Phase0, version.Deneb, params.E2ETestConfig())) + runner := e2eMinimal(t, types.InitForkCfg(version.Bellatrix, version.Deneb, params.E2ETestConfig())) runner.config.Evaluators = scenarioEvals() runner.config.EvalInterceptor = runner.eeOffline diff --git a/testing/middleware/builder/builder.go b/testing/middleware/builder/builder.go index a09569301de0..52300a15acf5 100644 --- a/testing/middleware/builder/builder.go +++ b/testing/middleware/builder/builder.go @@ -757,7 +757,8 @@ func modifyExecutionPayload(execPayload engine.ExecutableData, fees *big.Int, pr if err != nil { return &engine.ExecutionPayloadEnvelope{}, err } - return engine.BlockToExecutableData(modifiedBlock, fees, nil /*blobs*/), nil + // TODO: update to include requests for electra + return engine.BlockToExecutableData(modifiedBlock, fees, nil /*blobs*/, nil /*requests*/), nil } // This modifies the provided payload to imprint the builder's extra data @@ -798,7 +799,13 @@ func executableDataToBlock(params engine.ExecutableData, prevBeaconRoot []byte) pRoot := common.Hash(prevBeaconRoot) header.ParentBeaconRoot = &pRoot } - block := gethTypes.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */).WithWithdrawals(params.Withdrawals) + // TODO: update requests with requests for electra + body := gethTypes.Body{ + Transactions: txs, + Uncles: nil, + Withdrawals: params.Withdrawals, + } + block := gethTypes.NewBlockWithHeader(header).WithBody(body) return block, nil } diff --git a/testing/mock/beacon_service_mock.go b/testing/mock/beacon_service_mock.go index 49b8b66d46d9..f5e506ba34d2 100644 --- a/testing/mock/beacon_service_mock.go +++ b/testing/mock/beacon_service_mock.go @@ -429,7 +429,7 @@ func (m *MockBeaconChainClient) SubmitAttesterSlashing(arg0 context.Context, arg for _, a := range arg2 { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "SubmitAttesterSlashings", varargs...) + ret := m.ctrl.Call(m, "SubmitAttesterSlashing", varargs...) ret0, _ := ret[0].(*eth.SubmitSlashingResponse) ret1, _ := ret[1].(error) return ret0, ret1 @@ -439,7 +439,7 @@ func (m *MockBeaconChainClient) SubmitAttesterSlashing(arg0 context.Context, arg func (mr *MockBeaconChainClientMockRecorder) SubmitAttesterSlashing(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() varargs := append([]any{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitAttesterSlashings", reflect.TypeOf((*MockBeaconChainClient)(nil).SubmitAttesterSlashing), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubmitAttesterSlashing", reflect.TypeOf((*MockBeaconChainClient)(nil).SubmitAttesterSlashing), varargs...) } // SubmitAttesterSlashingElectra mocks base method. diff --git a/testing/mock/beacon_validator_client_mock.go b/testing/mock/beacon_validator_client_mock.go index 233e91c8ffc6..d104bb76439b 100644 --- a/testing/mock/beacon_validator_client_mock.go +++ b/testing/mock/beacon_validator_client_mock.go @@ -324,7 +324,7 @@ func (mr *MockBeaconNodeValidatorClientMockRecorder) ProposeAttestation(arg0, ar } // ProposeAttestationElectra mocks base method. -func (m *MockBeaconNodeValidatorClient) ProposeAttestationElectra(arg0 context.Context, arg1 *eth.AttestationElectra, arg2 ...grpc.CallOption) (*eth.AttestResponse, error) { +func (m *MockBeaconNodeValidatorClient) ProposeAttestationElectra(arg0 context.Context, arg1 *eth.SingleAttestation, arg2 ...grpc.CallOption) (*eth.AttestResponse, error) { m.ctrl.T.Helper() varargs := []any{arg0, arg1} for _, a := range arg2 { @@ -786,6 +786,129 @@ func (mr *MockBeaconNodeValidator_WaitForChainStartClientMockRecorder) Trailer() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockBeaconNodeValidator_WaitForChainStartClient)(nil).Trailer)) } +// MockBeaconNodeValidator_WaitForActivationClient is a mock of BeaconNodeValidator_WaitForActivationClient interface. +type MockBeaconNodeValidator_WaitForActivationClient struct { + ctrl *gomock.Controller + recorder *MockBeaconNodeValidator_WaitForActivationClientMockRecorder +} + +// MockBeaconNodeValidator_WaitForActivationClientMockRecorder is the mock recorder for MockBeaconNodeValidator_WaitForActivationClient. +type MockBeaconNodeValidator_WaitForActivationClientMockRecorder struct { + mock *MockBeaconNodeValidator_WaitForActivationClient +} + +// NewMockBeaconNodeValidator_WaitForActivationClient creates a new mock instance. +func NewMockBeaconNodeValidator_WaitForActivationClient(ctrl *gomock.Controller) *MockBeaconNodeValidator_WaitForActivationClient { + mock := &MockBeaconNodeValidator_WaitForActivationClient{ctrl: ctrl} + mock.recorder = &MockBeaconNodeValidator_WaitForActivationClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBeaconNodeValidator_WaitForActivationClient) EXPECT() *MockBeaconNodeValidator_WaitForActivationClientMockRecorder { + return m.recorder +} + +// CloseSend mocks base method. +func (m *MockBeaconNodeValidator_WaitForActivationClient) CloseSend() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CloseSend") + ret0, _ := ret[0].(error) + return ret0 +} + +// CloseSend indicates an expected call of CloseSend. +func (mr *MockBeaconNodeValidator_WaitForActivationClientMockRecorder) CloseSend() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockBeaconNodeValidator_WaitForActivationClient)(nil).CloseSend)) +} + +// Context mocks base method. +func (m *MockBeaconNodeValidator_WaitForActivationClient) Context() context.Context { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Context") + ret0, _ := ret[0].(context.Context) + return ret0 +} + +// Context indicates an expected call of Context. +func (mr *MockBeaconNodeValidator_WaitForActivationClientMockRecorder) Context() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockBeaconNodeValidator_WaitForActivationClient)(nil).Context)) +} + +// Header mocks base method. +func (m *MockBeaconNodeValidator_WaitForActivationClient) Header() (metadata.MD, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Header") + ret0, _ := ret[0].(metadata.MD) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Header indicates an expected call of Header. +func (mr *MockBeaconNodeValidator_WaitForActivationClientMockRecorder) Header() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockBeaconNodeValidator_WaitForActivationClient)(nil).Header)) +} + +// Recv mocks base method. +func (m *MockBeaconNodeValidator_WaitForActivationClient) Recv() (*eth.ValidatorActivationResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Recv") + ret0, _ := ret[0].(*eth.ValidatorActivationResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Recv indicates an expected call of Recv. +func (mr *MockBeaconNodeValidator_WaitForActivationClientMockRecorder) Recv() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockBeaconNodeValidator_WaitForActivationClient)(nil).Recv)) +} + +// RecvMsg mocks base method. +func (m *MockBeaconNodeValidator_WaitForActivationClient) RecvMsg(arg0 any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RecvMsg", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// RecvMsg indicates an expected call of RecvMsg. +func (mr *MockBeaconNodeValidator_WaitForActivationClientMockRecorder) RecvMsg(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockBeaconNodeValidator_WaitForActivationClient)(nil).RecvMsg), arg0) +} + +// SendMsg mocks base method. +func (m *MockBeaconNodeValidator_WaitForActivationClient) SendMsg(arg0 any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendMsg", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SendMsg indicates an expected call of SendMsg. +func (mr *MockBeaconNodeValidator_WaitForActivationClientMockRecorder) SendMsg(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockBeaconNodeValidator_WaitForActivationClient)(nil).SendMsg), arg0) +} + +// Trailer mocks base method. +func (m *MockBeaconNodeValidator_WaitForActivationClient) Trailer() metadata.MD { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Trailer") + ret0, _ := ret[0].(metadata.MD) + return ret0 +} + +// Trailer indicates an expected call of Trailer. +func (mr *MockBeaconNodeValidator_WaitForActivationClientMockRecorder) Trailer() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockBeaconNodeValidator_WaitForActivationClient)(nil).Trailer)) +} + // MockBeaconNodeValidator_StreamSlotsClient is a mock of BeaconNodeValidator_StreamSlotsClient interface. type MockBeaconNodeValidator_StreamSlotsClient struct { ctrl *gomock.Controller diff --git a/testing/mock/beacon_validator_server_mock.go b/testing/mock/beacon_validator_server_mock.go index 9643784dfc27..d610f37b9c00 100644 --- a/testing/mock/beacon_validator_server_mock.go +++ b/testing/mock/beacon_validator_server_mock.go @@ -253,7 +253,7 @@ func (mr *MockBeaconNodeValidatorServerMockRecorder) ProposeAttestation(arg0, ar } // ProposeAttestationElectra mocks base method. -func (m *MockBeaconNodeValidatorServer) ProposeAttestationElectra(arg0 context.Context, arg1 *eth.AttestationElectra) (*eth.AttestResponse, error) { +func (m *MockBeaconNodeValidatorServer) ProposeAttestationElectra(arg0 context.Context, arg1 *eth.SingleAttestation) (*eth.AttestResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ProposeAttestationElectra", arg0, arg1) ret0, _ := ret[0].(*eth.AttestResponse) diff --git a/testing/validator-mock/validator_client_mock.go b/testing/validator-mock/validator_client_mock.go index afbe08b5e2a3..274ebb39d6c7 100644 --- a/testing/validator-mock/validator_client_mock.go +++ b/testing/validator-mock/validator_client_mock.go @@ -181,7 +181,7 @@ func (mr *MockValidatorClientMockRecorder) FeeRecipientByPubKey(arg0, arg1 any) // Host mocks base method. func (m *MockValidatorClient) Host() string { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HTTPHost") + ret := m.ctrl.Call(m, "Host") ret0, _ := ret[0].(string) return ret0 } @@ -189,7 +189,7 @@ func (m *MockValidatorClient) Host() string { // Host indicates an expected call of Host. func (mr *MockValidatorClientMockRecorder) Host() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HTTPHost", reflect.TypeOf((*MockValidatorClient)(nil).Host)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Host", reflect.TypeOf((*MockValidatorClient)(nil).Host)) } // MultipleValidatorStatus mocks base method. @@ -238,7 +238,7 @@ func (mr *MockValidatorClientMockRecorder) ProposeAttestation(arg0, arg1 any) *g } // ProposeAttestationElectra mocks base method. -func (m *MockValidatorClient) ProposeAttestationElectra(arg0 context.Context, arg1 *eth.AttestationElectra) (*eth.AttestResponse, error) { +func (m *MockValidatorClient) ProposeAttestationElectra(arg0 context.Context, arg1 *eth.SingleAttestation) (*eth.AttestResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ProposeAttestationElectra", arg0, arg1) ret0, _ := ret[0].(*eth.AttestResponse) @@ -501,21 +501,6 @@ func (mr *MockValidatorClientMockRecorder) ValidatorStatus(arg0, arg1 any) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorStatus", reflect.TypeOf((*MockValidatorClient)(nil).ValidatorStatus), arg0, arg1) } -// WaitForActivation mocks base method. -func (m *MockValidatorClient) WaitForActivation(arg0 context.Context, arg1 *eth.ValidatorActivationRequest) (eth.BeaconNodeValidator_WaitForActivationClient, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WaitForActivation", arg0, arg1) - ret0, _ := ret[0].(eth.BeaconNodeValidator_WaitForActivationClient) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// WaitForActivation indicates an expected call of WaitForActivation. -func (mr *MockValidatorClientMockRecorder) WaitForActivation(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WaitForActivation", reflect.TypeOf((*MockValidatorClient)(nil).WaitForActivation), arg0, arg1) -} - // WaitForChainStart mocks base method. func (m *MockValidatorClient) WaitForChainStart(arg0 context.Context, arg1 *emptypb.Empty) (*eth.ChainStartResponse, error) { m.ctrl.T.Helper() diff --git a/third_party/com_github_karalabe_hid.patch b/third_party/com_github_karalabe_hid.patch new file mode 100644 index 000000000000..3768703835b9 --- /dev/null +++ b/third_party/com_github_karalabe_hid.patch @@ -0,0 +1,77 @@ +diff --git a/BUILD.bazel b/BUILD.bazel +index 9be80a1..0e78457 100755 +--- a/BUILD.bazel ++++ b/BUILD.bazel +@@ -8,58 +8,7 @@ go_library( + srcs = [ + "hid.go", + "hid_disabled.go", +- "hid_enabled.go", +- "wchar.go", + ], +- cgo = True, +- clinkopts = select({ +- "@io_bazel_rules_go//go/platform:darwin": [ +- "-framework CoreFoundation -framework IOKit -lobjc", +- ], +- "@io_bazel_rules_go//go/platform:freebsd": [ +- "-lusb", +- ], +- "@io_bazel_rules_go//go/platform:linux": [ +- "-lrt", +- ], +- "@io_bazel_rules_go//go/platform:windows": [ +- "-lsetupapi", +- ], +- "//conditions:default": [], +- }), +- copts = select({ +- "@io_bazel_rules_go//go/platform:android": [ +- "-DDEFAULT_VISIBILITY=", +- "-DPOLL_NFDS_TYPE=int", +- "-Ihidapi/hidapi", +- "-Ilibusb/libusb -DOS_LINUX -D_GNU_SOURCE -DHAVE_SYS_TIME_H -DHAVE_CLOCK_GETTIME", +- ], +- "@io_bazel_rules_go//go/platform:darwin": [ +- "-DDEFAULT_VISIBILITY=", +- "-DOS_DARWIN -DHAVE_SYS_TIME_H", +- "-DPOLL_NFDS_TYPE=int", +- "-Ihidapi/hidapi", +- ], +- "@io_bazel_rules_go//go/platform:freebsd": [ +- "-DDEFAULT_VISIBILITY=", +- "-DOS_FREEBSD", +- "-DPOLL_NFDS_TYPE=int", +- "-Ihidapi/hidapi", +- ], +- "@io_bazel_rules_go//go/platform:linux": [ +- "-DDEFAULT_VISIBILITY=", +- "-DPOLL_NFDS_TYPE=int", +- "-Ihidapi/hidapi", +- "-Ilibusb/libusb -DOS_LINUX -D_GNU_SOURCE -DHAVE_SYS_TIME_H -DHAVE_CLOCK_GETTIME", +- ], +- "@io_bazel_rules_go//go/platform:windows": [ +- "-DDEFAULT_VISIBILITY=", +- "-DOS_WINDOWS", +- "-DPOLL_NFDS_TYPE=int", +- "-Ihidapi/hidapi", +- ], +- "//conditions:default": [], +- }), + importpath = "github.com/karalabe/hid", + visibility = ["//visibility:public"], + ) +diff --git a/hid_disabled.go b/hid_disabled.go +index fa2c504..0091853 100644 +--- a/hid_disabled.go ++++ b/hid_disabled.go +@@ -4,9 +4,6 @@ + // This file is released under the 3-clause BSD license. Note however that Linux + // support depends on libusb, released under GNU LGPL 2.1 or later. + +-//go:build (!freebsd && !linux && !darwin && !windows) || ios || !cgo +-// +build !freebsd,!linux,!darwin,!windows ios !cgo +- + package hid + + // Supported returns whether this platform is supported by the HID library or not. diff --git a/third_party/usb/AUTHORS b/third_party/hid/AUTHORS similarity index 100% rename from third_party/usb/AUTHORS rename to third_party/hid/AUTHORS diff --git a/third_party/usb/BUILD.bazel b/third_party/hid/BUILD.bazel similarity index 82% rename from third_party/usb/BUILD.bazel rename to third_party/hid/BUILD.bazel index a8a9d019ec2f..5618968123af 100644 --- a/third_party/usb/BUILD.bazel +++ b/third_party/hid/BUILD.bazel @@ -1,6 +1,6 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test") -# gazelle:prefix github.com/karalabe/usb +# gazelle:prefix github.com/karalabe/hid go_library( name = "go_default_library", @@ -10,7 +10,7 @@ go_library( "usb.go", "usb_disabled.go", ], - importpath = "github.com/karalabe/usb", + importpath = "github.com/karalabe/hid", visibility = ["@com_github_ethereum_go_ethereum//:__subpackages__"], ) diff --git a/third_party/usb/LICENSE b/third_party/hid/LICENSE similarity index 100% rename from third_party/usb/LICENSE rename to third_party/hid/LICENSE diff --git a/third_party/usb/README.md b/third_party/hid/README.md similarity index 100% rename from third_party/usb/README.md rename to third_party/hid/README.md diff --git a/third_party/usb/hid_disabled.go b/third_party/hid/hid_disabled.go similarity index 99% rename from third_party/usb/hid_disabled.go rename to third_party/hid/hid_disabled.go index e8134ecb5fc2..bfc1e8e9f023 100644 --- a/third_party/usb/hid_disabled.go +++ b/third_party/hid/hid_disabled.go @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Lesser General Public License along // with the library. If not, see . -package usb +package hid // HidDevice is a live HID USB connected device handle. On platforms that this file // implements, the type lacks the actual HID device and all methods are noop. diff --git a/third_party/usb/raw_disabled.go b/third_party/hid/raw_disabled.go similarity index 99% rename from third_party/usb/raw_disabled.go rename to third_party/hid/raw_disabled.go index e00fa5878f11..bb11dbb7fcd7 100644 --- a/third_party/usb/raw_disabled.go +++ b/third_party/hid/raw_disabled.go @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Lesser General Public License along // with the library. If not, see . -package usb +package hid // RawDevice is a live raw USB connected device handle. On platforms that this file // implements, the type lacks the actual USB device and all methods are noop. diff --git a/third_party/usb/usb.go b/third_party/hid/usb.go similarity index 97% rename from third_party/usb/usb.go rename to third_party/hid/usb.go index 96a1e2502c1b..4aa13353fe1c 100644 --- a/third_party/usb/usb.go +++ b/third_party/hid/usb.go @@ -13,8 +13,8 @@ // You should have received a copy of the GNU Lesser General Public License along // with the library. If not, see . -// Package usb provide interfaces for generic USB devices. -package usb +// Package hid provide interfaces for generic USB devices. +package hid import "errors" diff --git a/third_party/usb/usb_disabled.go b/third_party/hid/usb_disabled.go similarity index 99% rename from third_party/usb/usb_disabled.go rename to third_party/hid/usb_disabled.go index 6e4a30037a81..4f56a6a3ebe2 100644 --- a/third_party/usb/usb_disabled.go +++ b/third_party/hid/usb_disabled.go @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Lesser General Public License along // with the library. If not, see . -package usb +package hid // Supported returns whether this platform is supported by the USB library or not. // The goal of this method is to allow programmatically handling platforms that do diff --git a/third_party/usb/usb_test.go b/third_party/hid/usb_test.go similarity index 99% rename from third_party/usb/usb_test.go rename to third_party/hid/usb_test.go index c238c0af432f..c05e21785cb0 100644 --- a/third_party/usb/usb_test.go +++ b/third_party/hid/usb_test.go @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Lesser General Public License along // with the library. If not, see . -package usb +package hid import ( "os" diff --git a/time/slots/slottime.go b/time/slots/slottime.go index cdc7674edebb..412ad33d366a 100644 --- a/time/slots/slottime.go +++ b/time/slots/slottime.go @@ -286,8 +286,9 @@ func SyncCommitteePeriodStartEpoch(e primitives.Epoch) (primitives.Epoch, error) // SecondsSinceSlotStart returns the number of seconds elapsed since the // given slot start time func SecondsSinceSlotStart(s primitives.Slot, genesisTime, timeStamp uint64) (uint64, error) { - if timeStamp < genesisTime+uint64(s)*params.BeaconConfig().SecondsPerSlot { - return 0, errors.New("could not compute seconds since slot start: invalid timestamp") + limit := genesisTime + uint64(s)*params.BeaconConfig().SecondsPerSlot + if timeStamp < limit { + return 0, fmt.Errorf("could not compute seconds since slot %d start: invalid timestamp, got %d < want %d", s, timeStamp, limit) } return timeStamp - genesisTime - uint64(s)*params.BeaconConfig().SecondsPerSlot, nil } diff --git a/tools/analyzers/shadowpredecl/analyzer.go b/tools/analyzers/shadowpredecl/analyzer.go index 19fdc47cfbc8..1dfc8766e59a 100644 --- a/tools/analyzers/shadowpredecl/analyzer.go +++ b/tools/analyzers/shadowpredecl/analyzer.go @@ -6,6 +6,7 @@ import ( "errors" "go/ast" "go/token" + "slices" "golang.org/x/tools/go/analysis" "golang.org/x/tools/go/analysis/passes/inspect" @@ -100,10 +101,5 @@ func inspectFunctionParams(pass *analysis.Pass, paramList []*ast.Field) { } func shadows(name string) bool { - for _, identifier := range predeclared { - if identifier == name { - return true - } - } - return false + return slices.Contains(predeclared, name) } diff --git a/tools/bootnode/bootnode.go b/tools/bootnode/bootnode.go index a95e5c2ad9f2..2a41f1755e74 100644 --- a/tools/bootnode/bootnode.go +++ b/tools/bootnode/bootnode.go @@ -81,9 +81,7 @@ func main() { logrus.SetLevel(logrus.DebugLevel) // Geth specific logging. - glogger := gethlog.NewGlogHandler(gethlog.StreamHandler(os.Stderr, gethlog.TerminalFormat(false))) - glogger.Verbosity(gethlog.LvlTrace) - gethlog.Root().SetHandler(glogger) + gethlog.SetDefault(gethlog.NewLogger(gethlog.NewTerminalHandlerWithLevel(os.Stderr, gethlog.LvlTrace, true))) log.Debug("Debug logging enabled.") } diff --git a/tools/bootnode/bootnode_test.go b/tools/bootnode/bootnode_test.go index 6474fa244806..f9927954ec4a 100644 --- a/tools/bootnode/bootnode_test.go +++ b/tools/bootnode/bootnode_test.go @@ -31,10 +31,13 @@ func TestBootnode_OK(t *testing.T) { require.NoError(t, err) privKey := extractPrivateKey() cfg := discover.Config{ - PrivateKey: privKey, + PrivateKey: privKey, + PingInterval: 100 * time.Millisecond, + NoFindnodeLivenessCheck: true, } listener := createListener(ipAddr, 4000, cfg) defer listener.Close() + time.Sleep(5 * time.Second) cfg.PrivateKey = extractPrivateKey() bootNode, err := enode.Parse(enode.ValidSchemes, listener.Self().String()) diff --git a/validator/client/attest.go b/validator/client/attest.go index 0c2f92a83cc6..1ec917aa4736 100644 --- a/validator/client/attest.go +++ b/validator/client/attest.go @@ -122,23 +122,6 @@ func (v *validator) SubmitAttestation(ctx context.Context, slot primitives.Slot, return } - var indexInCommittee uint64 - var found bool - for i, vID := range duty.Committee { - if vID == duty.ValidatorIndex { - indexInCommittee = uint64(i) - found = true - break - } - } - if !found { - log.Errorf("Validator ID %d not found in committee of %v", duty.ValidatorIndex, duty.Committee) - if v.emitAccountMetrics { - ValidatorAttestFailVec.WithLabelValues(fmtKey).Inc() - } - return - } - // TODO: Extend to Electra phase0Att, ok := indexedAtt.(*ethpb.IndexedAttestation) if ok { @@ -153,21 +136,36 @@ func (v *validator) SubmitAttestation(ctx context.Context, slot primitives.Slot, } } - aggregationBitfield := bitfield.NewBitlist(uint64(len(duty.Committee))) - aggregationBitfield.SetBitAt(indexInCommittee, true) - committeeBits := primitives.NewAttestationCommitteeBits() + var aggregationBitfield bitfield.Bitlist var attResp *ethpb.AttestResponse if postElectra { - attestation := ðpb.AttestationElectra{ - Data: data, - AggregationBits: aggregationBitfield, - CommitteeBits: committeeBits, - Signature: sig, + attestation := ðpb.SingleAttestation{ + Data: data, + AttesterIndex: duty.ValidatorIndex, + CommitteeId: duty.CommitteeIndex, + Signature: sig, } - attestation.CommitteeBits.SetBitAt(uint64(req.CommitteeIndex), true) attResp, err = v.validatorClient.ProposeAttestationElectra(ctx, attestation) } else { + var indexInCommittee uint64 + var found bool + for i, vID := range duty.Committee { + if vID == duty.ValidatorIndex { + indexInCommittee = uint64(i) + found = true + break + } + } + if !found { + log.Errorf("Validator ID %d not found in committee of %v", duty.ValidatorIndex, duty.Committee) + if v.emitAccountMetrics { + ValidatorAttestFailVec.WithLabelValues(fmtKey).Inc() + } + return + } + aggregationBitfield = bitfield.NewBitlist(uint64(len(duty.Committee))) + aggregationBitfield.SetBitAt(indexInCommittee, true) attestation := ðpb.Attestation{ Data: data, AggregationBits: aggregationBitfield, @@ -199,11 +197,12 @@ func (v *validator) SubmitAttestation(ctx context.Context, slot primitives.Slot, trace.StringAttribute("blockRoot", fmt.Sprintf("%#x", data.BeaconBlockRoot)), trace.Int64Attribute("justifiedEpoch", int64(data.Source.Epoch)), trace.Int64Attribute("targetEpoch", int64(data.Target.Epoch)), - trace.StringAttribute("aggregationBitfield", fmt.Sprintf("%#x", aggregationBitfield)), ) if postElectra { - span.SetAttributes(trace.StringAttribute("committeeBitfield", fmt.Sprintf("%#x", committeeBits))) + span.SetAttributes(trace.Int64Attribute("attesterIndex", int64(duty.ValidatorIndex))) + span.SetAttributes(trace.Int64Attribute("committeeIndex", int64(duty.CommitteeIndex))) } else { + span.SetAttributes(trace.StringAttribute("aggregationBitfield", fmt.Sprintf("%#x", aggregationBitfield))) span.SetAttributes(trace.Int64Attribute("committeeIndex", int64(data.CommitteeIndex))) } diff --git a/validator/client/attest_test.go b/validator/client/attest_test.go index 68a5b2cce7ec..4ed02f666e6c 100644 --- a/validator/client/attest_test.go +++ b/validator/client/attest_test.go @@ -222,11 +222,11 @@ func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) { gomock.Any(), // epoch ).Times(2).Return(ðpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/) - var generatedAttestation *ethpb.AttestationElectra + var generatedAttestation *ethpb.SingleAttestation m.validatorClient.EXPECT().ProposeAttestationElectra( gomock.Any(), // ctx - gomock.AssignableToTypeOf(ðpb.AttestationElectra{}), - ).Do(func(_ context.Context, att *ethpb.AttestationElectra) { + gomock.AssignableToTypeOf(ðpb.SingleAttestation{}), + ).Do(func(_ context.Context, att *ethpb.SingleAttestation) { generatedAttestation = att }).Return(ðpb.AttestResponse{}, nil /* error */) @@ -236,15 +236,15 @@ func TestAttestToBlockHead_AttestsCorrectly(t *testing.T) { aggregationBitfield.SetBitAt(4, true) committeeBits := primitives.NewAttestationCommitteeBits() committeeBits.SetBitAt(5, true) - expectedAttestation := ðpb.AttestationElectra{ + expectedAttestation := ðpb.SingleAttestation{ Data: ðpb.AttestationData{ BeaconBlockRoot: beaconBlockRoot[:], Target: ðpb.Checkpoint{Root: targetRoot[:]}, Source: ðpb.Checkpoint{Root: sourceRoot[:], Epoch: 3}, }, - AggregationBits: aggregationBitfield, - CommitteeBits: committeeBits, - Signature: make([]byte, 96), + AttesterIndex: validatorIndex, + CommitteeId: 5, + Signature: make([]byte, 96), } root, err := signing.ComputeSigningRoot(expectedAttestation.Data, make([]byte, 32)) diff --git a/validator/client/beacon-api/BUILD.bazel b/validator/client/beacon-api/BUILD.bazel index 22e414219213..53e47dbf15f6 100644 --- a/validator/client/beacon-api/BUILD.bazel +++ b/validator/client/beacon-api/BUILD.bazel @@ -122,6 +122,7 @@ go_test( deps = [ "//api:go_default_library", "//api/server/structs:go_default_library", + "//beacon-chain/core/helpers:go_default_library", "//beacon-chain/rpc/eth/shared/testing:go_default_library", "//config/params:go_default_library", "//consensus-types/primitives:go_default_library", diff --git a/validator/client/beacon-api/beacon_api_validator_client.go b/validator/client/beacon-api/beacon_api_validator_client.go index b37f810fedb4..e0f923bbc713 100644 --- a/validator/client/beacon-api/beacon_api_validator_client.go +++ b/validator/client/beacon-api/beacon_api_validator_client.go @@ -154,7 +154,7 @@ func (c *beaconApiValidatorClient) ProposeAttestation(ctx context.Context, in *e }) } -func (c *beaconApiValidatorClient) ProposeAttestationElectra(ctx context.Context, in *ethpb.AttestationElectra) (*ethpb.AttestResponse, error) { +func (c *beaconApiValidatorClient) ProposeAttestationElectra(ctx context.Context, in *ethpb.SingleAttestation) (*ethpb.AttestResponse, error) { ctx, span := trace.StartSpan(ctx, "beacon-api.ProposeAttestationElectra") defer span.End() diff --git a/validator/client/beacon-api/beacon_block_json_helpers.go b/validator/client/beacon-api/beacon_block_json_helpers.go index f5ecf3c73909..c3e5ab552dfb 100644 --- a/validator/client/beacon-api/beacon_block_json_helpers.go +++ b/validator/client/beacon-api/beacon_block_json_helpers.go @@ -51,10 +51,10 @@ func jsonifyAttestations(attestations []*ethpb.Attestation) []*structs.Attestati return jsonAttestations } -func jsonifyAttestationsElectra(attestations []*ethpb.AttestationElectra) []*structs.AttestationElectra { - jsonAttestations := make([]*structs.AttestationElectra, len(attestations)) +func jsonifySingleAttestations(attestations []*ethpb.SingleAttestation) []*structs.SingleAttestation { + jsonAttestations := make([]*structs.SingleAttestation, len(attestations)) for index, attestation := range attestations { - jsonAttestations[index] = jsonifyAttestationElectra(attestation) + jsonAttestations[index] = jsonifySingleAttestation(attestation) } return jsonAttestations } @@ -181,6 +181,15 @@ func jsonifyAttestationElectra(attestation *ethpb.AttestationElectra) *structs.A } } +func jsonifySingleAttestation(attestation *ethpb.SingleAttestation) *structs.SingleAttestation { + return &structs.SingleAttestation{ + CommitteeIndex: uint64ToString(attestation.CommitteeId), + AttesterIndex: uint64ToString(attestation.AttesterIndex), + Data: jsonifyAttestationData(attestation.Data), + Signature: hexutil.Encode(attestation.Signature), + } +} + func jsonifySignedAggregateAndProof(signedAggregateAndProof *ethpb.SignedAggregateAttestationAndProof) *structs.SignedAggregateAttestationAndProof { return &structs.SignedAggregateAttestationAndProof{ Message: &structs.AggregateAttestationAndProof{ diff --git a/validator/client/beacon-api/mock/json_rest_handler_mock.go b/validator/client/beacon-api/mock/json_rest_handler_mock.go index 33722c5bb9e5..1e2e98499cd3 100644 --- a/validator/client/beacon-api/mock/json_rest_handler_mock.go +++ b/validator/client/beacon-api/mock/json_rest_handler_mock.go @@ -58,7 +58,7 @@ func (mr *MockJsonRestHandlerMockRecorder) Get(ctx, endpoint, resp any) *gomock. // Host mocks base method. func (m *MockJsonRestHandler) Host() string { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HTTPHost") + ret := m.ctrl.Call(m, "Host") ret0, _ := ret[0].(string) return ret0 } @@ -66,7 +66,7 @@ func (m *MockJsonRestHandler) Host() string { // Host indicates an expected call of Host. func (mr *MockJsonRestHandlerMockRecorder) Host() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HTTPHost", reflect.TypeOf((*MockJsonRestHandler)(nil).Host)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Host", reflect.TypeOf((*MockJsonRestHandler)(nil).Host)) } // HttpClient mocks base method. diff --git a/validator/client/beacon-api/propose_attestation.go b/validator/client/beacon-api/propose_attestation.go index 6dd32975c024..7b78e99b25a8 100644 --- a/validator/client/beacon-api/propose_attestation.go +++ b/validator/client/beacon-api/propose_attestation.go @@ -7,13 +7,14 @@ import ( "net/http" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/v5/network/httputil" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" ) func (c *beaconApiValidatorClient) proposeAttestation(ctx context.Context, attestation *ethpb.Attestation) (*ethpb.AttestResponse, error) { - if err := validateNilAttestation(attestation); err != nil { + if err := helpers.ValidateNilAttestation(attestation); err != nil { return nil, err } marshalledAttestation, err := json.Marshal(jsonifyAttestations([]*ethpb.Attestation{attestation})) @@ -58,11 +59,11 @@ func (c *beaconApiValidatorClient) proposeAttestation(ctx context.Context, attes return ðpb.AttestResponse{AttestationDataRoot: attestationDataRoot[:]}, nil } -func (c *beaconApiValidatorClient) proposeAttestationElectra(ctx context.Context, attestation *ethpb.AttestationElectra) (*ethpb.AttestResponse, error) { - if err := validateNilAttestation(attestation); err != nil { +func (c *beaconApiValidatorClient) proposeAttestationElectra(ctx context.Context, attestation *ethpb.SingleAttestation) (*ethpb.AttestResponse, error) { + if err := helpers.ValidateNilAttestation(attestation); err != nil { return nil, err } - marshalledAttestation, err := json.Marshal(jsonifyAttestationsElectra([]*ethpb.AttestationElectra{attestation})) + marshalledAttestation, err := json.Marshal(jsonifySingleAttestations([]*ethpb.SingleAttestation{attestation})) if err != nil { return nil, err } @@ -84,28 +85,3 @@ func (c *beaconApiValidatorClient) proposeAttestationElectra(ctx context.Context return ðpb.AttestResponse{AttestationDataRoot: attestationDataRoot[:]}, nil } - -func validateNilAttestation(attestation ethpb.Att) error { - if attestation == nil || attestation.IsNil() { - return errors.New("attestation can't be nil") - } - if attestation.GetData().Source == nil { - return errors.New("attestation's source can't be nil") - } - if attestation.GetData().Target == nil { - return errors.New("attestation's target can't be nil") - } - v := attestation.Version() - if len(attestation.GetAggregationBits()) == 0 { - return errors.New("attestation's bitfield can't be nil") - } - if len(attestation.GetSignature()) == 0 { - return errors.New("attestation signature can't be nil") - } - if v >= version.Electra { - if len(attestation.CommitteeBitsVal().BitIndices()) == 0 { - return errors.New("attestation committee bits can't be nil") - } - } - return nil -} diff --git a/validator/client/beacon-api/propose_attestation_test.go b/validator/client/beacon-api/propose_attestation_test.go index 3ead120bc3a4..250fc2c2f8f7 100644 --- a/validator/client/beacon-api/propose_attestation_test.go +++ b/validator/client/beacon-api/propose_attestation_test.go @@ -8,6 +8,7 @@ import ( "net/http" "testing" + "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers" "github.com/prysmaticlabs/prysm/v5/network/httputil" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime/version" @@ -51,7 +52,7 @@ func TestProposeAttestation(t *testing.T) { }, { name: "nil attestation", - expectedErrorMessage: "attestation can't be nil", + expectedErrorMessage: "attestation is nil", }, { name: "nil attestation data", @@ -59,7 +60,7 @@ func TestProposeAttestation(t *testing.T) { AggregationBits: testhelpers.FillByteSlice(4, 74), Signature: testhelpers.FillByteSlice(96, 82), }, - expectedErrorMessage: "attestation can't be nil", + expectedErrorMessage: "attestation is nil", }, { name: "nil source checkpoint", @@ -94,17 +95,6 @@ func TestProposeAttestation(t *testing.T) { }, expectedErrorMessage: "attestation's bitfield can't be nil", }, - { - name: "nil signature", - attestation: ðpb.Attestation{ - AggregationBits: testhelpers.FillByteSlice(4, 74), - Data: ðpb.AttestationData{ - Source: ðpb.Checkpoint{}, - Target: ðpb.Checkpoint{}, - }, - }, - expectedErrorMessage: "attestation signature can't be nil", - }, { name: "bad request", attestation: attestation, @@ -120,7 +110,7 @@ func TestProposeAttestation(t *testing.T) { jsonRestHandler := mock.NewMockJsonRestHandler(ctrl) var marshalledAttestations []byte - if validateNilAttestation(test.attestation) == nil { + if helpers.ValidateNilAttestation(test.attestation) == nil { b, err := json.Marshal(jsonifyAttestations([]*ethpb.Attestation{test.attestation})) require.NoError(t, err) marshalledAttestations = b @@ -181,7 +171,7 @@ func TestProposeAttestationFallBack(t *testing.T) { jsonRestHandler := mock.NewMockJsonRestHandler(ctrl) var marshalledAttestations []byte - if validateNilAttestation(attestation) == nil { + if helpers.ValidateNilAttestation(attestation) == nil { b, err := json.Marshal(jsonifyAttestations([]*ethpb.Attestation{attestation})) require.NoError(t, err) marshalledAttestations = b @@ -225,8 +215,8 @@ func TestProposeAttestationFallBack(t *testing.T) { } func TestProposeAttestationElectra(t *testing.T) { - attestation := ðpb.AttestationElectra{ - AggregationBits: testhelpers.FillByteSlice(4, 74), + attestation := ðpb.SingleAttestation{ + AttesterIndex: 74, Data: ðpb.AttestationData{ Slot: 75, CommitteeIndex: 76, @@ -240,13 +230,13 @@ func TestProposeAttestationElectra(t *testing.T) { Root: testhelpers.FillByteSlice(32, 81), }, }, - Signature: testhelpers.FillByteSlice(96, 82), - CommitteeBits: testhelpers.FillByteSlice(8, 83), + Signature: testhelpers.FillByteSlice(96, 82), + CommitteeId: 83, } tests := []struct { name string - attestation *ethpb.AttestationElectra + attestation *ethpb.SingleAttestation expectedErrorMessage string endpointError error endpointCall int @@ -258,86 +248,41 @@ func TestProposeAttestationElectra(t *testing.T) { }, { name: "nil attestation", - expectedErrorMessage: "attestation can't be nil", + expectedErrorMessage: "attestation is nil", }, { name: "nil attestation data", - attestation: ðpb.AttestationElectra{ - AggregationBits: testhelpers.FillByteSlice(4, 74), - Signature: testhelpers.FillByteSlice(96, 82), - CommitteeBits: testhelpers.FillByteSlice(8, 83), + attestation: ðpb.SingleAttestation{ + AttesterIndex: 74, + Signature: testhelpers.FillByteSlice(96, 82), + CommitteeId: 83, }, - expectedErrorMessage: "attestation can't be nil", + expectedErrorMessage: "attestation is nil", }, { name: "nil source checkpoint", - attestation: ðpb.AttestationElectra{ - AggregationBits: testhelpers.FillByteSlice(4, 74), + attestation: ðpb.SingleAttestation{ + AttesterIndex: 74, Data: ðpb.AttestationData{ Target: ðpb.Checkpoint{}, }, - Signature: testhelpers.FillByteSlice(96, 82), - CommitteeBits: testhelpers.FillByteSlice(8, 83), + Signature: testhelpers.FillByteSlice(96, 82), + CommitteeId: 83, }, expectedErrorMessage: "attestation's source can't be nil", }, { name: "nil target checkpoint", - attestation: ðpb.AttestationElectra{ - AggregationBits: testhelpers.FillByteSlice(4, 74), + attestation: ðpb.SingleAttestation{ + AttesterIndex: 74, Data: ðpb.AttestationData{ Source: ðpb.Checkpoint{}, }, - Signature: testhelpers.FillByteSlice(96, 82), - CommitteeBits: testhelpers.FillByteSlice(8, 83), + Signature: testhelpers.FillByteSlice(96, 82), + CommitteeId: 83, }, expectedErrorMessage: "attestation's target can't be nil", }, - { - name: "nil aggregation bits", - attestation: ðpb.AttestationElectra{ - Data: ðpb.AttestationData{ - Source: ðpb.Checkpoint{}, - Target: ðpb.Checkpoint{}, - }, - Signature: testhelpers.FillByteSlice(96, 82), - CommitteeBits: testhelpers.FillByteSlice(8, 83), - }, - expectedErrorMessage: "attestation's bitfield can't be nil", - }, - { - name: "nil signature", - attestation: ðpb.AttestationElectra{ - AggregationBits: testhelpers.FillByteSlice(4, 74), - Data: ðpb.AttestationData{ - Source: ðpb.Checkpoint{}, - Target: ðpb.Checkpoint{}, - }, - CommitteeBits: testhelpers.FillByteSlice(8, 83), - }, - expectedErrorMessage: "attestation signature can't be nil", - }, - { - name: "nil committee bits", - attestation: ðpb.AttestationElectra{ - AggregationBits: testhelpers.FillByteSlice(4, 74), - Data: ðpb.AttestationData{ - Slot: 75, - CommitteeIndex: 76, - BeaconBlockRoot: testhelpers.FillByteSlice(32, 38), - Source: ðpb.Checkpoint{ - Epoch: 78, - Root: testhelpers.FillByteSlice(32, 79), - }, - Target: ðpb.Checkpoint{ - Epoch: 80, - Root: testhelpers.FillByteSlice(32, 81), - }, - }, - Signature: testhelpers.FillByteSlice(96, 82), - }, - expectedErrorMessage: "attestation committee bits can't be nil", - }, { name: "bad request", attestation: attestation, @@ -353,8 +298,8 @@ func TestProposeAttestationElectra(t *testing.T) { jsonRestHandler := mock.NewMockJsonRestHandler(ctrl) var marshalledAttestations []byte - if validateNilAttestation(test.attestation) == nil { - b, err := json.Marshal(jsonifyAttestationsElectra([]*ethpb.AttestationElectra{test.attestation})) + if helpers.ValidateNilAttestation(test.attestation) == nil { + b, err := json.Marshal(jsonifySingleAttestations([]*ethpb.SingleAttestation{test.attestation})) require.NoError(t, err) marshalledAttestations = b } diff --git a/validator/client/grpc-api/grpc_validator_client.go b/validator/client/grpc-api/grpc_validator_client.go index 63eb07fa4c6d..4e9cdd4d3cd9 100644 --- a/validator/client/grpc-api/grpc_validator_client.go +++ b/validator/client/grpc-api/grpc_validator_client.go @@ -71,7 +71,7 @@ func (c *grpcValidatorClient) ProposeAttestation(ctx context.Context, in *ethpb. return c.beaconNodeValidatorClient.ProposeAttestation(ctx, in) } -func (c *grpcValidatorClient) ProposeAttestationElectra(ctx context.Context, in *ethpb.AttestationElectra) (*ethpb.AttestResponse, error) { +func (c *grpcValidatorClient) ProposeAttestationElectra(ctx context.Context, in *ethpb.SingleAttestation) (*ethpb.AttestResponse, error) { return c.beaconNodeValidatorClient.ProposeAttestationElectra(ctx, in) } diff --git a/validator/client/iface/validator_client.go b/validator/client/iface/validator_client.go index 0f5fc3c18c0a..5ff21ca6486e 100644 --- a/validator/client/iface/validator_client.go +++ b/validator/client/iface/validator_client.go @@ -133,7 +133,7 @@ type ValidatorClient interface { FeeRecipientByPubKey(ctx context.Context, in *ethpb.FeeRecipientByPubKeyRequest) (*ethpb.FeeRecipientByPubKeyResponse, error) AttestationData(ctx context.Context, in *ethpb.AttestationDataRequest) (*ethpb.AttestationData, error) ProposeAttestation(ctx context.Context, in *ethpb.Attestation) (*ethpb.AttestResponse, error) - ProposeAttestationElectra(ctx context.Context, in *ethpb.AttestationElectra) (*ethpb.AttestResponse, error) + ProposeAttestationElectra(ctx context.Context, in *ethpb.SingleAttestation) (*ethpb.AttestResponse, error) SubmitAggregateSelectionProof(ctx context.Context, in *ethpb.AggregateSelectionRequest, index primitives.ValidatorIndex, committeeLength uint64) (*ethpb.AggregateSelectionResponse, error) SubmitAggregateSelectionProofElectra(ctx context.Context, in *ethpb.AggregateSelectionRequest, _ primitives.ValidatorIndex, _ uint64) (*ethpb.AggregateSelectionElectraResponse, error) SubmitSignedAggregateSelectionProof(ctx context.Context, in *ethpb.SignedAggregateSubmitRequest) (*ethpb.SignedAggregateSubmitResponse, error)