@@ -18,35 +18,92 @@ import (
1818 "context"
1919 "encoding/json"
2020 "errors"
21+ "strings"
2122
23+ client "github.com/attestantio/go-eth2-client"
2224 "github.com/attestantio/go-eth2-client/api"
23- "github.com/attestantio/go-eth2-client/spec/phase0 "
25+ "github.com/attestantio/go-eth2-client/spec"
2426)
2527
26- // SubmitAttestations submits attestations.
27- func (s * Service ) SubmitAttestations (ctx context.Context , attestations [] * phase0. Attestation ) error {
28+ // SubmitAttestations submits versioned attestations.
29+ func (s * Service ) SubmitAttestations (ctx context.Context , opts * api. SubmitAttestationsOpts ) error {
2830 if err := s .assertIsSynced (ctx ); err != nil {
2931 return err
3032 }
33+ if opts == nil {
34+ return client .ErrNoOptions
35+ }
36+ if len (opts .Attestations ) == 0 {
37+ return errors .Join (errors .New ("no attestations supplied" ), client .ErrInvalidOptions )
38+ }
39+ attestations := opts .Attestations
40+ unversionedAttestations , err := createUnversionedAttestations (attestations )
41+ if err != nil {
42+ return err
43+ }
3144
32- specJSON , err := json .Marshal (attestations )
45+ specJSON , err := json .Marshal (unversionedAttestations )
3346 if err != nil {
3447 return errors .Join (errors .New ("failed to marshal JSON" ), err )
3548 }
3649
37- endpoint := "/eth/v1 /beacon/pool/attestations"
50+ endpoint := "/eth/v2 /beacon/pool/attestations"
3851 query := ""
3952
40- if _ , err := s .post (ctx ,
53+ headers := make (map [string ]string )
54+ headers ["Eth-Consensus-Version" ] = strings .ToLower (attestations [0 ].Version .String ())
55+ if _ , err = s .post (ctx ,
4156 endpoint ,
4257 query ,
43- & api. CommonOpts {} ,
58+ & opts . Common ,
4459 bytes .NewReader (specJSON ),
4560 ContentTypeJSON ,
46- map [ string ] string {} ,
61+ headers ,
4762 ); err != nil {
48- return errors .Join (errors .New ("failed to submit beacon attestations" ), err )
63+ return errors .Join (errors .New ("failed to submit versioned beacon attestations" ), err )
4964 }
5065
5166 return nil
5267}
68+
69+ func createUnversionedAttestations (attestations []* spec.VersionedAttestation ) ([]any , error ) {
70+ var version spec.DataVersion
71+ var unversionedAttestations []any
72+
73+ for i := range attestations {
74+ if attestations [i ] == nil {
75+ return nil , errors .Join (errors .New ("nil attestation version supplied" ), client .ErrInvalidOptions )
76+ }
77+
78+ // Ensure consistent versioning.
79+ if version == spec .DataVersionUnknown {
80+ version = attestations [i ].Version
81+ } else if version != attestations [i ].Version {
82+ return nil , errors .Join (errors .New ("attestations must all be of the same version" ), client .ErrInvalidOptions )
83+ }
84+
85+ // Append to unversionedAttestations.
86+ switch attestations [i ].Version {
87+ case spec .DataVersionPhase0 :
88+ unversionedAttestations = append (unversionedAttestations , attestations [i ].Phase0 )
89+ case spec .DataVersionAltair :
90+ unversionedAttestations = append (unversionedAttestations , attestations [i ].Altair )
91+ case spec .DataVersionBellatrix :
92+ unversionedAttestations = append (unversionedAttestations , attestations [i ].Bellatrix )
93+ case spec .DataVersionCapella :
94+ unversionedAttestations = append (unversionedAttestations , attestations [i ].Capella )
95+ case spec .DataVersionDeneb :
96+ unversionedAttestations = append (unversionedAttestations , attestations [i ].Deneb )
97+ case spec .DataVersionElectra :
98+ singleAttestation , err := attestations [i ].Electra .ToSingleAttestation ()
99+ if err != nil {
100+ return nil , errors .Join (errors .New ("failed to convert attestation to single attestation" ), err )
101+ }
102+ unversionedAttestations = append (unversionedAttestations , singleAttestation )
103+ default :
104+ return nil , errors .Join (errors .New ("unknown attestation version" ), client .ErrInvalidOptions )
105+ }
106+ }
107+
108+ return unversionedAttestations , nil
109+ }
0 commit comments