Skip to content

Commit

Permalink
PrepareBeaconProposer API (#10367)
Browse files Browse the repository at this point in the history
* intial commit implementing prepare beacon proposal

* removing files accidently checked in by goland

* removing files accidently checked in by goland

* Delete BUILD 2

* Delete armeabi_cc_toolchain_config 2.bzl

* Delete builtin_include_directory_paths 2

* Delete cc_toolchain_config 2.bzl

* Delete BUILD 2.bazel

* Delete cc_wrapper 2.sh

* Delete module 2.modulemap

* Delete BUILD 2

* Delete BUILD 2

* Delete WORKSPACE 2

* Delete cc_toolchain_config_linux_arm64 2.bzl

* Delete cc_toolchain_config_osx 2.bzl

* Delete cc_toolchain_config_windows 2.bzl

* Delete 0258716f94e00f9df0da869fd97f9e0d0c6ac83eb528677d918f0ac9be5f4b8d 2

* Delete test-unmarshal-bad 2.json

* Delete test-unmarshal-good 2.json

* adding simple unit tests

* removing duplicate imports

* adding bazel changes

* adding validation and switched to table driven tests

* updating based on comments

* adding to test retrieve from db

* fixing bazel
  • Loading branch information
james-prysm authored Mar 16, 2022
1 parent 807b712 commit d55c0d7
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 6 deletions.
3 changes: 3 additions & 0 deletions beacon-chain/rpc/eth/validator/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ go_library(
"//proto/migration:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//time/slots:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
Expand Down Expand Up @@ -82,6 +84,7 @@ go_test(
"//testing/require:go_default_library",
"//testing/util:go_default_library",
"//time/slots:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_prysmaticlabs_eth2_types//:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@org_golang_google_protobuf//proto:go_default_library",
Expand Down
24 changes: 21 additions & 3 deletions beacon-chain/rpc/eth/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package validator
import (
"bytes"
"context"
"fmt"
"sort"
"strconv"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
Expand Down Expand Up @@ -325,11 +328,26 @@ func (vs *Server) ProduceBlockV2(ctx context.Context, req *ethpbv1.ProduceBlockR
return nil, status.Error(codes.InvalidArgument, "Unsupported block type")
}

// PrepareBeaconProposer --
// PrepareBeaconProposer caches and updates the fee recipient for the given proposer.
func (vs *Server) PrepareBeaconProposer(
_ context.Context, _ *ethpbv1.PrepareBeaconProposerRequest,
ctx context.Context, request *ethpbv1.PrepareBeaconProposerRequest,
) (*emptypb.Empty, error) {
return &emptypb.Empty{}, status.Error(codes.Unimplemented, "Unimplemented")
_, span := trace.StartSpan(ctx, "validator.PrepareBeaconProposer")
defer span.End()
var FeeRecipients []common.Address
var ValidatorIndices []types.ValidatorIndex
for _, recipientContainer := range request.Recipients {
recipient := hexutil.Encode(recipientContainer.FeeRecipient)
if !common.IsHexAddress(recipient) {
return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("Invalid fee recipient address: %v", recipient))
}
FeeRecipients = append(FeeRecipients, common.BytesToAddress(recipientContainer.FeeRecipient))
ValidatorIndices = append(ValidatorIndices, recipientContainer.ValidatorIndex)
}
if err := vs.V1Alpha1Server.BeaconDB.SaveFeeRecipientsByValidatorIDs(ctx, ValidatorIndices, FeeRecipients); err != nil {
return nil, status.Errorf(codes.Internal, "Could not save fee recipients: %v", err)
}
return &emptypb.Empty{}, nil
}

// ProduceAttestationData requests that the beacon node produces attestation data for
Expand Down
63 changes: 63 additions & 0 deletions beacon-chain/rpc/eth/validator/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"
"time"

"github.com/ethereum/go-ethereum/common"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/go-bitfield"
mockChain "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
Expand Down Expand Up @@ -2011,3 +2012,65 @@ func TestSubmitContributionAndProofs(t *testing.T) {
require.DeepEqual(t, expectedContributions, savedMsgs)
})
}

func TestPrepareBeaconProposer(t *testing.T) {
type args struct {
request *ethpbv1.PrepareBeaconProposerRequest
}
tests := []struct {
name string
args args
wantErr string
}{
{
name: "Happy Path",
args: args{
request: &ethpbv1.PrepareBeaconProposerRequest{
Recipients: []*ethpbv1.PrepareBeaconProposerRequest_FeeRecipientContainer{
{
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
ValidatorIndex: 1,
},
},
},
},
wantErr: "",
},
{
name: "invalid fee recipient length",
args: args{
request: &ethpbv1.PrepareBeaconProposerRequest{
Recipients: []*ethpbv1.PrepareBeaconProposerRequest_FeeRecipientContainer{
{
FeeRecipient: make([]byte, fieldparams.BLSPubkeyLength),
ValidatorIndex: 1,
},
},
},
},
wantErr: "Invalid fee recipient address",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db := dbutil.SetupDB(t)
ctx := context.Background()
v1Server := &v1alpha1validator.Server{
BeaconDB: db,
}
server := &Server{
V1Alpha1Server: v1Server,
}
_, err := server.PrepareBeaconProposer(ctx, tt.args.request)
if tt.wantErr != "" {
require.ErrorContains(t, tt.wantErr, err)
return
}
require.NoError(t, err)
address, err := server.V1Alpha1Server.BeaconDB.FeeRecipientByValidatorID(ctx, 1)
require.NoError(t, err)
require.Equal(t, common.BytesToAddress(tt.args.request.Recipients[0].FeeRecipient), address)
})
}

}
1 change: 1 addition & 0 deletions beacon-chain/rpc/prysm/v1alpha1/validator/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ go_library(
"//runtime/version:go_default_library",
"//time:go_default_library",
"//time/slots:go_default_library",
"@com_github_ethereum_go_ethereum//common:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_ferranbt_fastssz//:go_default_library",
"@com_github_holiman_uint256//:go_default_library",
Expand Down
24 changes: 21 additions & 3 deletions beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import (
"fmt"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
emptypb "github.com/golang/protobuf/ptypes/empty"
"github.com/pkg/errors"
types "github.com/prysmaticlabs/eth2-types"
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
blockfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/block"
"github.com/prysmaticlabs/prysm/beacon-chain/core/transition"
Expand Down Expand Up @@ -116,11 +119,26 @@ func (vs *Server) ProposeBlock(ctx context.Context, rBlk *ethpb.SignedBeaconBloc
return vs.proposeGenericBeaconBlock(ctx, blk)
}

// PrepareBeaconProposer --
// PrepareBeaconProposer caches and updates the fee recipient for the given proposer.
func (vs *Server) PrepareBeaconProposer(
_ context.Context, _ *ethpb.PrepareBeaconProposerRequest,
ctx context.Context, request *ethpb.PrepareBeaconProposerRequest,
) (*emptypb.Empty, error) {
return &emptypb.Empty{}, status.Error(codes.Unimplemented, "Unimplemented")
_, span := trace.StartSpan(ctx, "validator.PrepareBeaconProposer")
defer span.End()
var FeeRecipients []common.Address
var ValidatorIndices []types.ValidatorIndex
for _, recipientContainer := range request.Recipients {
recipient := hexutil.Encode(recipientContainer.FeeRecipient)
if !common.IsHexAddress(recipient) {
return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("Invalid fee recipient address: %v", recipient))
}
FeeRecipients = append(FeeRecipients, common.BytesToAddress(recipientContainer.FeeRecipient))
ValidatorIndices = append(ValidatorIndices, recipientContainer.ValidatorIndex)
}
if err := vs.BeaconDB.SaveFeeRecipientsByValidatorIDs(ctx, ValidatorIndices, FeeRecipients); err != nil {
return nil, status.Errorf(codes.Internal, "Could not save fee recipients: %v", err)
}
return &emptypb.Empty{}, nil
}

func (vs *Server) proposeGenericBeaconBlock(ctx context.Context, blk block.SignedBeaconBlock) (*ethpb.ProposeResponse, error) {
Expand Down
57 changes: 57 additions & 0 deletions beacon-chain/rpc/prysm/v1alpha1/validator/proposer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2431,6 +2431,63 @@ func TestProposer_GetSyncAggregate_OK(t *testing.T) {
require.DeepEqual(t, bitfield.NewBitvector512(), aggregate.SyncCommitteeBits)
}

func TestProposer_PrepareBeaconProposer(t *testing.T) {
type args struct {
request *ethpb.PrepareBeaconProposerRequest
}
tests := []struct {
name string
args args
wantErr string
}{
{
name: "Happy Path",
args: args{
request: &ethpb.PrepareBeaconProposerRequest{
Recipients: []*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer{
{
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
ValidatorIndex: 1,
},
},
},
},
wantErr: "",
},
{
name: "invalid fee recipient length",
args: args{
request: &ethpb.PrepareBeaconProposerRequest{
Recipients: []*ethpb.PrepareBeaconProposerRequest_FeeRecipientContainer{
{
FeeRecipient: make([]byte, fieldparams.BLSPubkeyLength),
ValidatorIndex: 1,
},
},
},
},
wantErr: "Invalid fee recipient address",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db := dbutil.SetupDB(t)
ctx := context.Background()
proposerServer := &Server{BeaconDB: db}
_, err := proposerServer.PrepareBeaconProposer(ctx, tt.args.request)
if tt.wantErr != "" {
require.ErrorContains(t, tt.wantErr, err)
return
}
require.NoError(t, err)
address, err := proposerServer.BeaconDB.FeeRecipientByValidatorID(ctx, 1)
require.NoError(t, err)
require.Equal(t, common.BytesToAddress(tt.args.request.Recipients[0].FeeRecipient), address)

})
}
}

func majorityVoteBoundaryTime(slot types.Slot) (uint64, uint64) {
slots := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().EpochsPerEth1VotingPeriod))
slotStartTime := uint64(mockPOW.GenesisTime) + uint64((slot - (slot % (slots))).Mul(params.BeaconConfig().SecondsPerSlot))
Expand Down

0 comments on commit d55c0d7

Please sign in to comment.