From cb502ceb8c38833bd7960e2472b9308302046bcc Mon Sep 17 00:00:00 2001 From: terencechain Date: Tue, 23 Aug 2022 08:54:38 -0700 Subject: [PATCH] Skip updating fee recipient if it's the same (#11295) --- .../rpc/prysm/v1alpha1/validator/proposer.go | 22 +++++- .../prysm/v1alpha1/validator/proposer_test.go | 78 +++++++++++++++++++ 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go index c55e90208..4efd2f5cc 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go @@ -14,6 +14,7 @@ import ( "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/feed" blockfeed "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/feed/block" "github.com/prysmaticlabs/prysm/v3/beacon-chain/core/transition" + "github.com/prysmaticlabs/prysm/v3/beacon-chain/db/kv" "github.com/prysmaticlabs/prysm/v3/config/params" "github.com/prysmaticlabs/prysm/v3/consensus-types/blocks" "github.com/prysmaticlabs/prysm/v3/consensus-types/interfaces" @@ -81,7 +82,26 @@ func (vs *Server) PrepareBeaconProposer( defer span.End() var feeRecipients []common.Address var validatorIndices []types.ValidatorIndex - for _, recipientContainer := range request.Recipients { + + newRecipients := make([]*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer, 0, len(request.Recipients)) + for _, r := range request.Recipients { + f, err := vs.BeaconDB.FeeRecipientByValidatorID(ctx, r.ValidatorIndex) + switch { + case errors.Is(err, kv.ErrNotFoundFeeRecipient): + newRecipients = append(newRecipients, r) + case err != nil: + return nil, status.Errorf(codes.Internal, "Could not get fee recipient by validator index: %v", err) + default: + } + if common.BytesToAddress(r.FeeRecipient) != f { + newRecipients = append(newRecipients, r) + } + } + if len(newRecipients) == 0 { + return &emptypb.Empty{}, nil + } + + for _, recipientContainer := range newRecipients { recipient := hexutil.Encode(recipientContainer.FeeRecipient) if !common.IsHexAddress(recipient) { return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("Invalid fee recipient address: %v", recipient)) diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_test.go index 5b806bfdc..c21cf4c9c 100644 --- a/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_test.go +++ b/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_test.go @@ -2357,6 +2357,84 @@ func TestProposer_PrepareBeaconProposer(t *testing.T) { } } +func TestProposer_PrepareBeaconProposerOverlapping(t *testing.T) { + hook := logTest.NewGlobal() + db := dbutil.SetupDB(t) + ctx := context.Background() + proposerServer := &Server{BeaconDB: db} + + // New validator + f := bytesutil.PadTo([]byte{0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF}, fieldparams.FeeRecipientLength) + req := ðpb.PrepareBeaconProposerRequest{ + Recipients: []*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer{ + {FeeRecipient: f, ValidatorIndex: 1}, + }, + } + _, err := proposerServer.PrepareBeaconProposer(ctx, req) + require.NoError(t, err) + require.LogsContain(t, hook, "Updated fee recipient addresses for validator indices") + + // Same validator + hook.Reset() + _, err = proposerServer.PrepareBeaconProposer(ctx, req) + require.NoError(t, err) + require.LogsDoNotContain(t, hook, "Updated fee recipient addresses for validator indices") + + // Same validator with different fee recipient + hook.Reset() + f = bytesutil.PadTo([]byte{0x01, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF}, fieldparams.FeeRecipientLength) + req = ðpb.PrepareBeaconProposerRequest{ + Recipients: []*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer{ + {FeeRecipient: f, ValidatorIndex: 1}, + }, + } + _, err = proposerServer.PrepareBeaconProposer(ctx, req) + require.NoError(t, err) + require.LogsContain(t, hook, "Updated fee recipient addresses for validator indices") + + // More than one validator + hook.Reset() + f = bytesutil.PadTo([]byte{0x01, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF}, fieldparams.FeeRecipientLength) + req = ðpb.PrepareBeaconProposerRequest{ + Recipients: []*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer{ + {FeeRecipient: f, ValidatorIndex: 1}, + {FeeRecipient: f, ValidatorIndex: 2}, + }, + } + _, err = proposerServer.PrepareBeaconProposer(ctx, req) + require.NoError(t, err) + require.LogsContain(t, hook, "Updated fee recipient addresses for validator indices") + + // Same validators + hook.Reset() + _, err = proposerServer.PrepareBeaconProposer(ctx, req) + require.NoError(t, err) + require.LogsDoNotContain(t, hook, "Updated fee recipient addresses for validator indices") +} + +func BenchmarkServer_PrepareBeaconProposer(b *testing.B) { + db := dbutil.SetupDB(b) + ctx := context.Background() + proposerServer := &Server{BeaconDB: db} + + f := bytesutil.PadTo([]byte{0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF}, fieldparams.FeeRecipientLength) + recipients := make([]*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer, 0) + for i := 0; i < 10000; i++ { + recipients = append(recipients, ðpb.PrepareBeaconProposerRequest_FeeRecipientContainer{FeeRecipient: f, ValidatorIndex: types.ValidatorIndex(i)}) + } + + req := ðpb.PrepareBeaconProposerRequest{ + Recipients: recipients, + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := proposerServer.PrepareBeaconProposer(ctx, req) + if err != nil { + b.Fatal(err) + } + } +} + func TestProposer_SubmitValidatorRegistrations(t *testing.T) { ctx := context.Background() proposerServer := &Server{}