Skip to content

Commit

Permalink
core: add interfaces and signed data for attestation aggregation (#1121)
Browse files Browse the repository at this point in the history
Adds required interfaces to eth2wrap and signed data for SignedAggregateAndProof.

category: feature
ticket: #1094
  • Loading branch information
dB2510 authored Sep 13, 2022
1 parent bd9bf85 commit 2f60f09
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 0 deletions.
41 changes: 41 additions & 0 deletions app/eth2wrap/eth2wrap_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions app/eth2wrap/genwrap/genwrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ type Client interface {

// interfaces defines all the interfaces to implement and whether to measure latency for each.
interfaces = map[string]bool{
"AggregateAttestationProvider": true,
"AggregateAttestationsSubmitter": true,
"AttestationDataProvider": true,
"AttestationsSubmitter": true,
"AttesterDutiesProvider": true,
Expand Down
55 changes: 55 additions & 0 deletions core/signeddata.go
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,61 @@ func (s *SignedBeaconCommitteeSubscription) UnmarshalJSON(input []byte) error {
return s.BeaconCommitteeSubscription.UnmarshalJSON(input)
}

// NewSignedAggregateAndProof is a convenience function which returns a new signed SignedAggregateAndProof.
func NewSignedAggregateAndProof(data *eth2p0.SignedAggregateAndProof) SignedAggregateAndProof {
return SignedAggregateAndProof{SignedAggregateAndProof: *data}
}

// NewPartialSignedAggregateAndProof is a convenience function which returns a new partially signed SignedAggregateAndProof.
func NewPartialSignedAggregateAndProof(data *eth2p0.SignedAggregateAndProof, shareIdx int) ParSignedData {
return ParSignedData{
SignedData: NewSignedAggregateAndProof(data),
ShareIdx: shareIdx,
}
}

// SignedAggregateAndProof wraps eth2p0.SignedAggregateAndProof and implements SignedData.
type SignedAggregateAndProof struct {
eth2p0.SignedAggregateAndProof
}

func (s SignedAggregateAndProof) Signature() Signature {
return SigFromETH2(s.SignedAggregateAndProof.Signature)
}

func (s SignedAggregateAndProof) SetSignature(sig Signature) (SignedData, error) {
resp, err := s.clone()
if err != nil {
return nil, err
}

resp.SignedAggregateAndProof.Signature = sig.ToETH2()

return resp, nil
}

func (s SignedAggregateAndProof) Clone() (SignedData, error) {
return s.clone()
}

func (s SignedAggregateAndProof) clone() (SignedAggregateAndProof, error) {
var resp SignedAggregateAndProof
err := cloneJSONMarshaler(s, &resp)
if err != nil {
return SignedAggregateAndProof{}, errors.Wrap(err, "clone signed aggregate and proof")
}

return resp, nil
}

func (s SignedAggregateAndProof) MarshalJSON() ([]byte, error) {
return s.SignedAggregateAndProof.MarshalJSON()
}

func (s *SignedAggregateAndProof) UnmarshalJSON(input []byte) error {
return s.SignedAggregateAndProof.UnmarshalJSON(input)
}

// cloneJSONMarshaler clones the marshaler by serialising to-from json
// since eth2 types contains pointers. The result is stored
// in the value pointed to by v.
Expand Down
15 changes: 15 additions & 0 deletions core/signeddata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
eth2v1 "github.com/attestantio/go-eth2-client/api/v1"
"github.com/attestantio/go-eth2-client/spec"
"github.com/attestantio/go-eth2-client/spec/bellatrix"
eth2p0 "github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/stretchr/testify/require"

"github.com/obolnetwork/charon/core"
Expand Down Expand Up @@ -72,13 +73,27 @@ func TestSignedDataSetSignature(t *testing.T) {
},
},
},
{
name: "signed aggregate and proof",
data: core.SignedAggregateAndProof{
SignedAggregateAndProof: eth2p0.SignedAggregateAndProof{
Message: &eth2p0.AggregateAndProof{
AggregatorIndex: 0,
Aggregate: testutil.RandomAttestation(),
SelectionProof: testutil.RandomEth2Signature(),
},
Signature: testutil.RandomEth2Signature(),
},
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
clone, err := test.data.SetSignature(testutil.RandomCoreSignature())
require.NoError(t, err)
require.NotEqual(t, clone.Signature(), test.data.Signature())
require.NotEmpty(t, clone.Signature())
})
}
}
10 changes: 10 additions & 0 deletions testutil/beaconmock/beaconmock.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ type Mock struct {
SlotsPerEpochFunc func(context.Context) (uint64, error)
SubmitBeaconCommitteeSubscriptionsV2Func func(context.Context, []*eth2exp.BeaconCommitteeSubscription) ([]*eth2exp.BeaconCommitteeSubscriptionResponse, error)
SubmitBeaconCommitteeSubscriptionsFunc func(ctx context.Context, subscriptions []*eth2v1.BeaconCommitteeSubscription) error
AggregateAttestationFunc func(ctx context.Context, slot eth2p0.Slot, attestationDataRoot eth2p0.Root) (*eth2p0.Attestation, error)
SubmitAggregateAttestationsFunc func(ctx context.Context, aggregateAndProofs []*eth2p0.SignedAggregateAndProof) error
}

func (m Mock) SubmitAttestations(ctx context.Context, attestations []*eth2p0.Attestation) error {
Expand Down Expand Up @@ -219,6 +221,14 @@ func (m Mock) SubmitBeaconCommitteeSubscriptions(ctx context.Context, subscripti
return m.SubmitBeaconCommitteeSubscriptionsFunc(ctx, subscriptions)
}

func (m Mock) AggregateAttestation(ctx context.Context, slot eth2p0.Slot, attestationDataRoot eth2p0.Root) (*eth2p0.Attestation, error) {
return m.AggregateAttestationFunc(ctx, slot, attestationDataRoot)
}

func (m Mock) SubmitAggregateAttestations(ctx context.Context, aggregateAndProofs []*eth2p0.SignedAggregateAndProof) error {
return m.SubmitAggregateAttestationsFunc(ctx, aggregateAndProofs)
}

func (m Mock) SlotsPerEpoch(ctx context.Context) (uint64, error) {
return m.SlotsPerEpochFunc(ctx)
}
Expand Down

0 comments on commit 2f60f09

Please sign in to comment.