From 84fe2abe452e8e39f1ee7c3e551d2ef67f71cb8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gianguido=20Sor=C3=A0?= Date: Tue, 25 Jun 2024 12:38:02 +0200 Subject: [PATCH] *: cherry-pick for v1.0.0-rc7 (#3154) - #3144 - #3149 - #3150 category: misc ticket: none --- core/bcast/bcast.go | 31 +++++++++++++--- core/tracker/inclusion.go | 53 ++++++++++++++++++++++----- core/tracker/tracker_internal_test.go | 46 +++++++++++++++++++++-- 3 files changed, 113 insertions(+), 17 deletions(-) diff --git a/core/bcast/bcast.go b/core/bcast/bcast.go index ccf65de2b..379031243 100644 --- a/core/bcast/bcast.go +++ b/core/bcast/bcast.go @@ -73,18 +73,39 @@ func (b Broadcaster) Broadcast(ctx context.Context, duty core.Duty, set core.Sig return err } - block, ok := aggData.(core.VersionedSignedProposal) + var ( + block core.VersionedSignedProposal + blindedBlock core.VersionedSignedBlindedProposal + + blinded bool + ok bool + ) + + block, ok = aggData.(core.VersionedSignedProposal) if !ok { - return errors.New("invalid proposal") + // check if it's a blinded proposal + blindedBlock, blinded = aggData.(core.VersionedSignedBlindedProposal) + if !blinded { + return errors.New("invalid proposal") + } + } + + switch blinded { + case true: + err = b.eth2Cl.SubmitBlindedProposal(ctx, ð2api.SubmitBlindedProposalOpts{ + Proposal: &blindedBlock.VersionedSignedBlindedProposal, + }) + default: + err = b.eth2Cl.SubmitProposal(ctx, ð2api.SubmitProposalOpts{ + Proposal: &block.VersionedSignedProposal, + }) } - err = b.eth2Cl.SubmitProposal(ctx, ð2api.SubmitProposalOpts{ - Proposal: &block.VersionedSignedProposal, - }) if err == nil { log.Info(ctx, "Successfully submitted block proposal to beacon node", z.Any("delay", b.delayFunc(duty.Slot)), z.Any("pubkey", pubkey), + z.Bool("blinded", blinded), ) } diff --git a/core/tracker/inclusion.go b/core/tracker/inclusion.go index 55de50fa4..7cdbc873a 100644 --- a/core/tracker/inclusion.go +++ b/core/tracker/inclusion.go @@ -76,14 +76,13 @@ type inclusionCore struct { // Submitted is called when a duty is submitted to the beacon node. // It adds the duty to the list of submitted duties. -func (i *inclusionCore) Submitted(duty core.Duty, pubkey core.PubKey, data core.SignedData, delay time.Duration) error { +func (i *inclusionCore) Submitted(duty core.Duty, pubkey core.PubKey, data core.SignedData, delay time.Duration) (err error) { if !inclSupported[duty.Type] { return nil } var ( attRoot eth2p0.Root - err error ) if duty.Type == core.DutyAttester { att, ok := data.(core.Attestation) @@ -104,15 +103,51 @@ func (i *inclusionCore) Submitted(duty core.Duty, pubkey core.PubKey, data core. return errors.Wrap(err, "hash aggregate") } } else if duty.Type == core.DutyProposer { - proposal, ok := data.(core.VersionedSignedProposal) + var ( + block core.VersionedSignedProposal + blindedBlock core.VersionedSignedBlindedProposal + + blinded bool + ok bool + ) + + block, ok = data.(core.VersionedSignedProposal) if !ok { - return errors.New("invalid block") + blindedBlock, blinded = data.(core.VersionedSignedBlindedProposal) + if !blinded { + return errors.New("invalid block") + } } - if eth2wrap.IsSyntheticProposal(&proposal.VersionedSignedProposal) { - // Report inclusion for synthetic blocks as it is already included on-chain. - i.trackerInclFunc(duty, pubkey, data, nil) - return nil + defer func() { + if r := recover(); r != nil { + proposal := fmt.Sprintf("%+v", block) + if blinded { + proposal = fmt.Sprintf("%+v", blindedBlock) + } + + err = errors.New("could not determine if proposal was synthetic or not", + z.Str("proposal", proposal), + z.Bool("blinded", blinded), + ) + } + }() + + switch blinded { + case true: + if eth2wrap.IsSyntheticBlindedBlock(&blindedBlock.VersionedSignedBlindedProposal) { + // Report inclusion for synthetic blocks as it is already included on-chain. + i.trackerInclFunc(duty, pubkey, data, nil) + + return nil + } + default: + if eth2wrap.IsSyntheticProposal(&block.VersionedSignedProposal) { + // Report inclusion for synthetic blocks as it is already included on-chain. + i.trackerInclFunc(duty, pubkey, data, nil) + + return nil + } } } else if duty.Type == core.DutyBuilderProposer { return core.ErrDeprecatedDutyBuilderProposer @@ -130,7 +165,7 @@ func (i *inclusionCore) Submitted(duty core.Duty, pubkey core.PubKey, data core. Delay: delay, } - return nil + return err } // Trim removes all duties that are older than the specified slot. diff --git a/core/tracker/tracker_internal_test.go b/core/tracker/tracker_internal_test.go index 0bad6e0cb..3cbd68e11 100644 --- a/core/tracker/tracker_internal_test.go +++ b/core/tracker/tracker_internal_test.go @@ -7,10 +7,13 @@ import ( "math/rand" "net/http" "reflect" + "sync" "testing" + "time" eth2api "github.com/attestantio/go-eth2-client/api" eth2v1 "github.com/attestantio/go-eth2-client/api/v1" + eth2spec "github.com/attestantio/go-eth2-client/spec" eth2p0 "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/stretchr/testify/require" @@ -1111,12 +1114,26 @@ func TestIsParSigEventExpected(t *testing.T) { } func TestAnalyseParSigs(t *testing.T) { + t.Run("full block", func(t *testing.T) { + analyseParSigs(t, func() core.SignedData { + return testutil.RandomDenebCoreVersionedSignedProposal() + }) + }) + + t.Run("blinded block", func(t *testing.T) { + analyseParSigs(t, func() core.SignedData { + return testutil.RandomDenebVersionedSignedBlindedProposal() + }) + }) +} + +func analyseParSigs(t *testing.T, dataGen func() core.SignedData) { + t.Helper() require.Empty(t, extractParSigs(context.Background(), nil)) var events []event - makeEvents := func(n int, pubkey string) { - data := testutil.RandomBellatrixCoreVersionedSignedProposal() + makeEvents := func(n int, pubkey string, data core.SignedData) { offset := len(events) for i := 0; i < n; i++ { data, err := data.SetSignature(testutil.RandomCoreSignature()) @@ -1137,7 +1154,8 @@ func TestAnalyseParSigs(t *testing.T) { 6: "b", } for n, pubkey := range expect { - makeEvents(n, pubkey) + data := dataGen() + makeEvents(n, pubkey, data) } allParSigMsgs := extractParSigs(context.Background(), events) @@ -1304,3 +1322,25 @@ func TestIgnoreUnsupported(t *testing.T) { func randomStep() step { return step(rand.Intn(int(sentinel))) } + +func TestSubmittedProposals(t *testing.T) { + ic := inclusionCore{ + mu: sync.Mutex{}, + submissions: make(map[subkey]submission), + } + + err := ic.Submitted(core.NewProposerDuty(42), testutil.RandomCorePubKey(t), testutil.RandomDenebCoreVersionedSignedProposal(), 1*time.Millisecond) + require.NoError(t, err) + + err = ic.Submitted(core.NewProposerDuty(42), testutil.RandomCorePubKey(t), testutil.RandomDenebVersionedSignedBlindedProposal(), 1*time.Millisecond) + require.NoError(t, err) + + require.NotPanics(t, func() { + err = ic.Submitted(core.NewProposerDuty(42), testutil.RandomCorePubKey(t), core.VersionedSignedBlindedProposal{ + VersionedSignedBlindedProposal: eth2api.VersionedSignedBlindedProposal{ + Version: eth2spec.DataVersionDeneb, + }, + }, 1*time.Millisecond) + require.ErrorContains(t, err, "could not determine if proposal was synthetic or not") + }) +}