prysm-pulse/validator/client/propose_test.go
terence tsao b400098296
Remove unused code (#8517)
* Remove unused code

* Go mod tidy

* Gazelle

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2021-02-25 18:13:13 +00:00

774 lines
23 KiB
Go

package client
import (
"context"
"encoding/hex"
"errors"
"strings"
"testing"
"time"
ptypes "github.com/gogo/protobuf/types"
"github.com/golang/mock/gomock"
lru "github.com/hashicorp/golang-lru"
types "github.com/prysmaticlabs/eth2-types"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
validatorpb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/mock"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
testing2 "github.com/prysmaticlabs/prysm/validator/db/testing"
"github.com/prysmaticlabs/prysm/validator/graffiti"
logTest "github.com/sirupsen/logrus/hooks/test"
)
type mocks struct {
validatorClient *mock.MockBeaconNodeValidatorClient
nodeClient *mock.MockNodeClient
signExitFunc func(context.Context, *validatorpb.SignRequest) (bls.Signature, error)
}
type mockSignature struct{}
func (mockSignature) Verify(bls.PublicKey, []byte) bool {
return true
}
func (mockSignature) AggregateVerify([]bls.PublicKey, [][32]byte) bool {
return true
}
func (mockSignature) FastAggregateVerify([]bls.PublicKey, [32]byte) bool {
return true
}
func (mockSignature) Marshal() []byte {
return make([]byte, 32)
}
func (m mockSignature) Copy() bls.Signature {
return m
}
func setup(t *testing.T) (*validator, *mocks, bls.SecretKey, func()) {
validatorKey, err := bls.RandKey()
require.NoError(t, err)
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
valDB := testing2.SetupDB(t, [][48]byte{pubKey})
ctrl := gomock.NewController(t)
m := &mocks{
validatorClient: mock.NewMockBeaconNodeValidatorClient(ctrl),
nodeClient: mock.NewMockNodeClient(ctrl),
signExitFunc: func(ctx context.Context, req *validatorpb.SignRequest) (bls.Signature, error) {
return mockSignature{}, nil
},
}
aggregatedSlotCommitteeIDCache, err := lru.New(int(params.BeaconConfig().MaxCommitteesPerSlot))
require.NoError(t, err)
copy(pubKey[:], validatorKey.PublicKey().Marshal())
km := &mockKeymanager{
keysMap: map[[48]byte]bls.SecretKey{
pubKey: validatorKey,
},
}
validator := &validator{
db: valDB,
keyManager: km,
validatorClient: m.validatorClient,
graffiti: []byte{},
attLogs: make(map[[32]byte]*attSubmitted),
aggregatedSlotCommitteeIDCache: aggregatedSlotCommitteeIDCache,
}
return validator, m, validatorKey, ctrl.Finish
}
func TestProposeBlock_DoesNotProposeGenesisBlock(t *testing.T) {
hook := logTest.NewGlobal()
validator, _, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.ProposeBlock(context.Background(), 0, pubKey)
require.LogsContain(t, hook, "Assigned to genesis slot, skipping proposal")
}
func TestProposeBlock_DomainDataFailed(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(nil /*response*/, errors.New("uh oh"))
validator.ProposeBlock(context.Background(), 1, pubKey)
require.LogsContain(t, hook, "Failed to sign randao reveal")
}
func TestProposeBlock_DomainDataIsNil(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(nil /*response*/, nil)
validator.ProposeBlock(context.Background(), 1, pubKey)
require.LogsContain(t, hook, domainDataErr)
}
func TestProposeBlock_RequestBlockFailed(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(), // block request
).Return(nil /*response*/, errors.New("uh oh"))
validator.ProposeBlock(context.Background(), 1, pubKey)
require.LogsContain(t, hook, "Failed to request block from beacon node")
}
func TestProposeBlock_ProposeBlockFailed(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(testutil.NewBeaconBlock().Block, nil /*err*/)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
m.validatorClient.EXPECT().ProposeBlock(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).Return(nil /*response*/, errors.New("uh oh"))
validator.ProposeBlock(context.Background(), 1, pubKey)
require.LogsContain(t, hook, "Failed to propose block")
}
func TestProposeBlock_BlocksDoubleProposal(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
dummyRoot := [32]byte{}
// Save a dummy proposal history at slot 0.
err := validator.db.SaveProposalHistoryForSlot(context.Background(), pubKey, 0, dummyRoot[:])
require.NoError(t, err)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Times(1).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
testBlock := testutil.NewBeaconBlock()
slot := params.BeaconConfig().SlotsPerEpoch*5 + 2
testBlock.Block.Slot = slot
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(testBlock.Block, nil /*err*/)
secondTestBlock := testutil.NewBeaconBlock()
secondTestBlock.Block.Slot = slot
graffiti := [32]byte{}
copy(graffiti[:], "someothergraffiti")
secondTestBlock.Block.Body.Graffiti = graffiti[:]
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(secondTestBlock.Block, nil /*err*/)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Times(3).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
m.validatorClient.EXPECT().ProposeBlock(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), slot, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
validator.ProposeBlock(context.Background(), slot, pubKey)
require.LogsContain(t, hook, failedPreBlockSignLocalErr)
}
func TestProposeBlock_BlocksDoubleProposal_After54KEpochs(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
dummyRoot := [32]byte{}
// Save a dummy proposal history at slot 0.
err := validator.db.SaveProposalHistoryForSlot(context.Background(), pubKey, 0, dummyRoot[:])
require.NoError(t, err)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Times(1).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
testBlock := testutil.NewBeaconBlock()
farFuture := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().WeakSubjectivityPeriod + 9))
testBlock.Block.Slot = farFuture
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(testBlock.Block, nil /*err*/)
secondTestBlock := testutil.NewBeaconBlock()
secondTestBlock.Block.Slot = farFuture
graffiti := [32]byte{}
copy(graffiti[:], "someothergraffiti")
secondTestBlock.Block.Body.Graffiti = graffiti[:]
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(secondTestBlock.Block, nil /*err*/)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Times(3).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
m.validatorClient.EXPECT().ProposeBlock(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), farFuture, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
validator.ProposeBlock(context.Background(), farFuture, pubKey)
require.LogsContain(t, hook, failedPreBlockSignLocalErr)
}
func TestProposeBlock_AllowsPastProposals(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
// Save a dummy proposal history at slot 0.
err := validator.db.SaveProposalHistoryForSlot(context.Background(), pubKey, 0, []byte{})
require.NoError(t, err)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Times(2).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
farAhead := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().WeakSubjectivityPeriod + 9))
blk := testutil.NewBeaconBlock()
blk.Block.Slot = farAhead
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(blk.Block, nil /*err*/)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Times(2).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
m.validatorClient.EXPECT().ProposeBlock(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).Times(2).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), farAhead, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
past := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().WeakSubjectivityPeriod - 400))
blk2 := testutil.NewBeaconBlock()
blk2.Block.Slot = past
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(blk2.Block, nil /*err*/)
validator.ProposeBlock(context.Background(), past, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
}
func TestProposeBlock_AllowsSameEpoch(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
// Save a dummy proposal history at slot 0.
err := validator.db.SaveProposalHistoryForSlot(context.Background(), pubKey, 0, []byte{})
require.NoError(t, err)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Times(2).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
farAhead := params.BeaconConfig().SlotsPerEpoch.Mul(uint64(params.BeaconConfig().WeakSubjectivityPeriod + 9))
blk := testutil.NewBeaconBlock()
blk.Block.Slot = farAhead
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(blk.Block, nil /*err*/)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Times(2).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
m.validatorClient.EXPECT().ProposeBlock(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).Times(2).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), farAhead, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
blk2 := testutil.NewBeaconBlock()
blk2.Block.Slot = farAhead - 4
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(blk2.Block, nil /*err*/)
validator.ProposeBlock(context.Background(), farAhead-4, pubKey)
require.LogsDoNotContain(t, hook, failedPreBlockSignLocalErr)
}
func TestProposeBlock_BroadcastsBlock(t *testing.T) {
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(testutil.NewBeaconBlock().Block, nil /*err*/)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
m.validatorClient.EXPECT().ProposeBlock(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).Return(&ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil /*error*/)
validator.ProposeBlock(context.Background(), 1, pubKey)
}
func TestProposeBlock_BroadcastsBlock_WithGraffiti(t *testing.T) {
validator, m, validatorKey, finish := setup(t)
defer finish()
pubKey := [48]byte{}
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.graffiti = []byte("12345678901234567890123456789012")
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
blk := testutil.NewBeaconBlock()
blk.Block.Body.Graffiti = validator.graffiti
m.validatorClient.EXPECT().GetBlock(
gomock.Any(), // ctx
gomock.Any(),
).Return(blk.Block, nil /*err*/)
m.validatorClient.EXPECT().DomainData(
gomock.Any(), // ctx
gomock.Any(), // epoch
).Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil /*err*/)
var sentBlock *ethpb.SignedBeaconBlock
m.validatorClient.EXPECT().ProposeBlock(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedBeaconBlock{}),
).DoAndReturn(func(ctx context.Context, block *ethpb.SignedBeaconBlock) (*ethpb.ProposeResponse, error) {
sentBlock = block
return &ethpb.ProposeResponse{BlockRoot: make([]byte, 32)}, nil
})
validator.ProposeBlock(context.Background(), 1, pubKey)
assert.Equal(t, string(validator.graffiti), string(sentBlock.Block.Body.Graffiti))
}
func TestProposeExit_ValidatorIndexFailed(t *testing.T) {
_, m, validatorKey, finish := setup(t)
defer finish()
m.validatorClient.EXPECT().ValidatorIndex(
gomock.Any(),
gomock.Any(),
).Return(nil, errors.New("uh oh"))
err := ProposeExit(
context.Background(),
m.validatorClient,
m.nodeClient,
m.signExitFunc,
validatorKey.PublicKey().Marshal(),
)
assert.NotNil(t, err)
assert.ErrorContains(t, "uh oh", err)
assert.ErrorContains(t, "gRPC call to get validator index failed", err)
}
func TestProposeExit_GetGenesisFailed(t *testing.T) {
_, m, validatorKey, finish := setup(t)
defer finish()
m.validatorClient.EXPECT().
ValidatorIndex(gomock.Any(), gomock.Any()).
Return(nil, nil)
m.nodeClient.EXPECT().
GetGenesis(gomock.Any(), gomock.Any()).
Return(nil, errors.New("uh oh"))
err := ProposeExit(
context.Background(),
m.validatorClient,
m.nodeClient,
m.signExitFunc,
validatorKey.PublicKey().Marshal(),
)
assert.NotNil(t, err)
assert.ErrorContains(t, "uh oh", err)
assert.ErrorContains(t, "gRPC call to get genesis time failed", err)
}
func TestProposeExit_DomainDataFailed(t *testing.T) {
_, m, validatorKey, finish := setup(t)
defer finish()
m.validatorClient.EXPECT().
ValidatorIndex(gomock.Any(), gomock.Any()).
Return(&ethpb.ValidatorIndexResponse{Index: 1}, nil)
// Any time in the past will suffice
genesisTime := &ptypes.Timestamp{
Seconds: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix(),
}
m.nodeClient.EXPECT().
GetGenesis(gomock.Any(), gomock.Any()).
Return(&ethpb.Genesis{GenesisTime: genesisTime}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), gomock.Any()).
Return(nil, errors.New("uh oh"))
err := ProposeExit(
context.Background(),
m.validatorClient,
m.nodeClient,
m.signExitFunc,
validatorKey.PublicKey().Marshal(),
)
assert.NotNil(t, err)
assert.ErrorContains(t, domainDataErr, err)
assert.ErrorContains(t, "uh oh", err)
assert.ErrorContains(t, "failed to sign voluntary exit", err)
}
func TestProposeExit_DomainDataIsNil(t *testing.T) {
_, m, validatorKey, finish := setup(t)
defer finish()
m.validatorClient.EXPECT().
ValidatorIndex(gomock.Any(), gomock.Any()).
Return(&ethpb.ValidatorIndexResponse{Index: 1}, nil)
// Any time in the past will suffice
genesisTime := &ptypes.Timestamp{
Seconds: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix(),
}
m.nodeClient.EXPECT().
GetGenesis(gomock.Any(), gomock.Any()).
Return(&ethpb.Genesis{GenesisTime: genesisTime}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), gomock.Any()).
Return(nil, nil)
err := ProposeExit(
context.Background(),
m.validatorClient,
m.nodeClient,
m.signExitFunc,
validatorKey.PublicKey().Marshal(),
)
assert.NotNil(t, err)
assert.ErrorContains(t, domainDataErr, err)
assert.ErrorContains(t, "failed to sign voluntary exit", err)
}
func TestProposeBlock_ProposeExitFailed(t *testing.T) {
_, m, validatorKey, finish := setup(t)
defer finish()
m.validatorClient.EXPECT().
ValidatorIndex(gomock.Any(), gomock.Any()).
Return(&ethpb.ValidatorIndexResponse{Index: 1}, nil)
// Any time in the past will suffice
genesisTime := &ptypes.Timestamp{
Seconds: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix(),
}
m.nodeClient.EXPECT().
GetGenesis(gomock.Any(), gomock.Any()).
Return(&ethpb.Genesis{GenesisTime: genesisTime}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), gomock.Any()).
Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil)
m.validatorClient.EXPECT().
ProposeExit(gomock.Any(), gomock.AssignableToTypeOf(&ethpb.SignedVoluntaryExit{})).
Return(nil, errors.New("uh oh"))
err := ProposeExit(
context.Background(),
m.validatorClient,
m.nodeClient,
m.signExitFunc,
validatorKey.PublicKey().Marshal(),
)
assert.NotNil(t, err)
assert.ErrorContains(t, "uh oh", err)
assert.ErrorContains(t, "failed to propose voluntary exit", err)
}
func TestProposeExit_BroadcastsBlock(t *testing.T) {
_, m, validatorKey, finish := setup(t)
defer finish()
m.validatorClient.EXPECT().
ValidatorIndex(gomock.Any(), gomock.Any()).
Return(&ethpb.ValidatorIndexResponse{Index: 1}, nil)
// Any time in the past will suffice
genesisTime := &ptypes.Timestamp{
Seconds: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).Unix(),
}
m.nodeClient.EXPECT().
GetGenesis(gomock.Any(), gomock.Any()).
Return(&ethpb.Genesis{GenesisTime: genesisTime}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), gomock.Any()).
Return(&ethpb.DomainResponse{SignatureDomain: make([]byte, 32)}, nil)
m.validatorClient.EXPECT().
ProposeExit(gomock.Any(), gomock.AssignableToTypeOf(&ethpb.SignedVoluntaryExit{})).
Return(&ethpb.ProposeExitResponse{}, nil)
assert.NoError(t, ProposeExit(
context.Background(),
m.validatorClient,
m.nodeClient,
m.signExitFunc,
validatorKey.PublicKey().Marshal(),
))
}
func TestSignBlock(t *testing.T) {
validator, m, _, finish := setup(t)
defer finish()
secretKey, err := bls.SecretKeyFromBytes(bytesutil.PadTo([]byte{1}, 32))
require.NoError(t, err, "Failed to generate key from bytes")
publicKey := secretKey.PublicKey()
proposerDomain := make([]byte, 32)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), gomock.Any()).
Return(&ethpb.DomainResponse{SignatureDomain: proposerDomain}, nil)
ctx := context.Background()
blk := testutil.NewBeaconBlock()
blk.Block.Slot = 1
blk.Block.ProposerIndex = 100
var pubKey [48]byte
copy(pubKey[:], publicKey.Marshal())
km := &mockKeymanager{
keysMap: map[[48]byte]bls.SecretKey{
pubKey: secretKey,
},
}
validator.keyManager = km
sig, domain, err := validator.signBlock(ctx, pubKey, 0, blk.Block)
require.NoError(t, err, "%x,%x,%v", sig, domain.SignatureDomain, err)
require.Equal(t, "a049e1dc723e5a8b5bd14f292973572dffd53785ddb337"+
"82f20bf762cbe10ee7b9b4f5ae1ad6ff2089d352403750bed402b94b58469c072536"+
"faa9a09a88beaff697404ca028b1c7052b0de37dbcff985dfa500459783370312bdd"+
"36d6e0f224", hex.EncodeToString(sig))
// proposer domain
require.DeepEqual(t, proposerDomain, domain.SignatureDomain)
}
func TestGetGraffiti_Ok(t *testing.T) {
ctrl := gomock.NewController(t)
m := &mocks{
validatorClient: mock.NewMockBeaconNodeValidatorClient(ctrl),
}
pubKey := [48]byte{'a'}
tests := []struct {
name string
v *validator
want []byte
}{
{name: "use default cli graffiti",
v: &validator{
graffiti: []byte{'b'},
graffitiStruct: &graffiti.Graffiti{
Default: "c",
Random: []string{"d", "e"},
Specific: map[types.ValidatorIndex]string{
1: "f",
2: "g",
},
},
},
want: []byte{'b'},
},
{name: "use default file graffiti",
v: &validator{
validatorClient: m.validatorClient,
graffitiStruct: &graffiti.Graffiti{
Default: "c",
},
},
want: []byte{'c'},
},
{name: "use random file graffiti",
v: &validator{
validatorClient: m.validatorClient,
graffitiStruct: &graffiti.Graffiti{
Random: []string{"d"},
Default: "c",
},
},
want: []byte{'d'},
},
{name: "use validator file graffiti, has validator",
v: &validator{
validatorClient: m.validatorClient,
graffitiStruct: &graffiti.Graffiti{
Random: []string{"d"},
Default: "c",
Specific: map[types.ValidatorIndex]string{
1: "f",
2: "g",
},
},
},
want: []byte{'g'},
},
{name: "use validator file graffiti, none specified",
v: &validator{
validatorClient: m.validatorClient,
graffitiStruct: &graffiti.Graffiti{},
},
want: []byte{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !strings.Contains(tt.name, "use default cli graffiti") {
m.validatorClient.EXPECT().
ValidatorIndex(gomock.Any(), &ethpb.ValidatorIndexRequest{PublicKey: pubKey[:]}).
Return(&ethpb.ValidatorIndexResponse{Index: 2}, nil)
}
got, err := tt.v.getGraffiti(context.Background(), pubKey)
require.NoError(t, err)
require.DeepEqual(t, tt.want, got)
})
}
}
func TestGetGraffitiOrdered_Ok(t *testing.T) {
pubKey := [48]byte{'a'}
valDB := testing2.SetupDB(t, [][48]byte{pubKey})
ctrl := gomock.NewController(t)
m := &mocks{
validatorClient: mock.NewMockBeaconNodeValidatorClient(ctrl),
}
m.validatorClient.EXPECT().
ValidatorIndex(gomock.Any(), &ethpb.ValidatorIndexRequest{PublicKey: pubKey[:]}).
Times(5).
Return(&ethpb.ValidatorIndexResponse{Index: 2}, nil)
v := &validator{
db: valDB,
validatorClient: m.validatorClient,
graffitiStruct: &graffiti.Graffiti{
Ordered: []string{"a", "b", "c"},
Default: "d",
},
}
for _, want := range [][]byte{{'a'}, {'b'}, {'c'}, {'d'}, {'d'}} {
got, err := v.getGraffiti(context.Background(), pubKey)
require.NoError(t, err)
require.DeepEqual(t, want, got)
}
}