Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command to fetch validator statuses + MultipleValidatorStatus #5784

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
a7a3ae0
Add method to fetch account statuses
michaelhly May 7, 2020
673c839
Add status command
michaelhly May 8, 2020
4e97a2a
gofmt
michaelhly May 8, 2020
3c357a1
Add comment about sorting
michaelhly May 8, 2020
1294fdf
Close conneciton when finished
michaelhly May 8, 2020
462f35f
Fix error
michaelhly May 8, 2020
d355b13
Refactor FetchAccountStatuses
michaelhly May 9, 2020
a2c2f45
Add status_test.go
michaelhly May 9, 2020
237620d
Move sorting out of FetchAccountStatuses
michaelhly May 9, 2020
15132b7
Remove unnecessary casting
michaelhly May 9, 2020
e8123b4
Expect ValidatorStatus to be called
michaelhly May 9, 2020
c0d837e
Wrap long comment
michaelhly May 9, 2020
7b7efef
Comment out sorting
michaelhly May 10, 2020
9635895
Add all necessary dial options
michaelhly May 10, 2020
348b799
Close connection before evaluating error from fetch
michaelhly May 11, 2020
c39e231
Small changes
michaelhly May 11, 2020
74c315b
Fix lint issues
michaelhly May 11, 2020
dbf8bee
Merge branch 'master' into validator-client-account-statuses
michaelhly May 11, 2020
c2558ec
Update dependencies for docker images
michaelhly May 11, 2020
3b0557e
Rename multipleValidatorStatus to activationStatus
michaelhly May 11, 2020
63694ef
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
michaelhly May 11, 2020
3ee1734
Update commit hash for ethereumapis
michaelhly May 11, 2020
1e1ade8
Implement MultipleValidatorStatus
michaelhly May 11, 2020
470edfe
Tests for MultipleValidatorStatus
michaelhly May 11, 2020
1c1abb0
Fix bugs
michaelhly May 12, 2020
8676c90
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
michaelhly May 12, 2020
4231332
Add export comment for MultipleValidatorStatus
michaelhly May 12, 2020
1bd716c
Run `go fmt` in prysm (#5815)
terencechain May 11, 2020
a67d182
Add fix for nil state in InitializeFromProto (#5817)
0xKiwi May 12, 2020
8b4bbba
Add export comment for MultipleValidatorStatus
michaelhly May 12, 2020
05e015c
Clean up comments
michaelhly May 12, 2020
d1a0e34
Update mock files for beacon_node_validator_service
michaelhly May 12, 2020
2dc898e
Merge branch 'validator-client-account-statuses' of https://github.co…
michaelhly May 12, 2020
6f65dfd
Run gazelle
michaelhly May 12, 2020
d7a6b2e
Fix mock issues
michaelhly May 12, 2020
3fc3f84
Fetch statuses in batches
michaelhly May 12, 2020
5a65093
Simplify public key generation for status_test
michaelhly May 12, 2020
81e0edc
Sort validator statuses by status type
michaelhly May 12, 2020
ea2e0ba
Format validator statuses and print to console
michaelhly May 12, 2020
4df5845
Fix lint issues
michaelhly May 12, 2020
a5f30db
Delimit with commas
michaelhly May 12, 2020
31c0dc0
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
michaelhly May 12, 2020
4b40102
Rename otheropts to extraopts
michaelhly May 12, 2020
e0b9705
Merge branch 'master' into validator-client-account-statuses
rauljordan May 13, 2020
e478ba9
Merge branch 'validator-client-account-statuses' of https://github.co…
michaelhly May 13, 2020
9b47c26
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
michaelhly May 13, 2020
550aca1
Clean up MultipleValidatorStatus tests
michaelhly May 13, 2020
5a3ae0d
Add sync checker to MultipleValidatorStatus
michaelhly May 13, 2020
87ecfa5
Update formatting
michaelhly May 13, 2020
b068f9e
Prepend 0x to validator keys
michaelhly May 13, 2020
d454abc
Check number of status blocks recieved in status_test
michaelhly May 13, 2020
1c6ceb3
Move sorting to goroutine
michaelhly May 13, 2020
9564ad4
Capitalize constants
michaelhly May 13, 2020
03d0905
Fix typo
michaelhly May 13, 2020
b55c67f
Use mock reponses in sort test
michaelhly May 13, 2020
c3d1f5d
Remove byteutils
michaelhly May 13, 2020
abb2a02
Fix ugly format
michaelhly May 13, 2020
42c3e9d
Add comment on MultipleValidatorStatus test
michaelhly May 13, 2020
b59c94e
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
michaelhly May 14, 2020
96593f1
Create entrypoint to run status command, and make unexported function…
michaelhly May 14, 2020
5bd7da8
Move merge step into FetchAccountStatuses
michaelhly May 14, 2020
33be715
Revert service.go
michaelhly May 14, 2020
a2422db
Remove responseToSortedMetadata
michaelhly May 14, 2020
93793be
Simplify mergeTwo
michaelhly May 14, 2020
de2f7a8
Replace fmt output with logrus
michaelhly May 15, 2020
5020326
Fix typo
michaelhly May 15, 2020
7591973
Merge branch 'master' into validator-client-account-statuses
michaelhly May 15, 2020
79ddcf1
Update comment
michaelhly May 15, 2020
6287a41
Merge branch 'validator-client-account-statuses' of https://github.co…
michaelhly May 15, 2020
decf519
Return error on bad credentials
michaelhly May 15, 2020
47bdf93
Merge branch 'master' into validator-client-account-statuses
rauljordan May 15, 2020
4a1142b
Merge branch 'master' into validator-client-account-statuses
rauljordan May 15, 2020
e4fa645
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
michaelhly May 15, 2020
d51659b
Skip merge step on error
michaelhly May 15, 2020
0286f5a
Fix conflicts
michaelhly May 15, 2020
fc78940
Fix mock paths
michaelhly May 15, 2020
2a7f94c
Add comments
michaelhly May 15, 2020
d3435bd
Convert some sprintfs to wrapfs
michaelhly May 15, 2020
c201cd6
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
michaelhly May 15, 2020
1e1fcbf
Rename ExtractPublicKeys to ExtractPublicKeysFromKeyStore and move to…
michaelhly May 15, 2020
bcdd032
Add support for keymanager
michaelhly May 15, 2020
8a82426
Add supported flags to flags list
michaelhly May 15, 2020
7dda2b0
Log warning on intermediary errors
michaelhly May 16, 2020
4952966
Update output
michaelhly May 17, 2020
a1463a1
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
michaelhly May 17, 2020
f77e5e6
Merge branch 'master' into validator-client-account-statuses
rauljordan May 18, 2020
1eea671
Fix conflicts
michaelhly May 19, 2020
c086663
Merge branch 'master' of https://github.com/prysmaticlabs/prysm into …
michaelhly May 19, 2020
3b1be09
Merge branch 'validator-client-account-statuses' of https://github.co…
michaelhly May 19, 2020
a786cb0
Set context timeout for FetchAccountStatuses
michaelhly May 19, 2020
1d78e7a
Remove deprecated grpc.WithTimeout
michaelhly May 19, 2020
9744278
gofmt
michaelhly May 19, 2020
9100ecb
Remove getters
michaelhly May 19, 2020
a15de80
Remove parallel stuff
michaelhly May 19, 2020
5472aac
Move grpc dialing out of status.go
michaelhly May 19, 2020
2f8ce09
Update logging based on feedback
michaelhly May 19, 2020
7861331
Update validator/accounts/status.go
May 19, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,7 @@ go_repository(

go_repository(
name = "com_github_prysmaticlabs_ethereumapis",
commit = "df460bd3d84be4ff3df0658395c7dc9d2a7e7b3d",
commit = "3444ffb75440161e4d6b9d38edef65212474cc48",
importpath = "github.com/prysmaticlabs/ethereumapis",
)

Expand Down
4 changes: 2 additions & 2 deletions beacon-chain/rpc/validator/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type Server struct {
// beacon state, if not, then it creates a stream which listens for canonical states which contain
// the validator with the public key as an active validator record.
func (vs *Server) WaitForActivation(req *ethpb.ValidatorActivationRequest, stream ethpb.BeaconNodeValidator_WaitForActivationServer) error {
activeValidatorExists, validatorStatuses, err := vs.multipleValidatorStatus(stream.Context(), req.PublicKeys)
activeValidatorExists, validatorStatuses, err := vs.activationStatus(stream.Context(), req.PublicKeys)
if err != nil {
return status.Errorf(codes.Internal, "Could not fetch validator status: %v", err)
}
Expand All @@ -95,7 +95,7 @@ func (vs *Server) WaitForActivation(req *ethpb.ValidatorActivationRequest, strea
select {
// Pinging every slot for activation.
case <-time.After(time.Duration(params.BeaconConfig().SecondsPerSlot) * time.Second):
activeValidatorExists, validatorStatuses, err := vs.multipleValidatorStatus(stream.Context(), req.PublicKeys)
activeValidatorExists, validatorStatuses, err := vs.activationStatus(stream.Context(), req.PublicKeys)
if err != nil {
return status.Errorf(codes.Internal, "Could not fetch validator status: %v", err)
}
Expand Down
48 changes: 46 additions & 2 deletions beacon-chain/rpc/validator/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,53 @@ func (vs *Server) ValidatorStatus(
return vs.validatorStatus(ctx, req.PublicKey, headState), nil
}

// multipleValidatorStatus returns the validator status response for the set of validators
// MultipleValidatorStatus is the same as ValidatorStatus. Supports retrieval of multiple
// validator statuses. Takes a list of public keys or a list of validator indices.
func (vs *Server) MultipleValidatorStatus(
ctx context.Context,
req *ethpb.MultipleValidatorStatusRequest) (*ethpb.MultipleValidatorStatusResponse, error) {
if vs.SyncChecker.Syncing() {
return nil, status.Errorf(codes.Unavailable, "Syncing to latest head, not ready to respond")
}
headState, err := vs.HeadFetcher.HeadState(ctx)
if err != nil {
return nil, status.Error(codes.Internal, "Could not get head state")
}
responseCap := len(req.PublicKeys) + len(req.Indices)
pubkeys := make([][]byte, 0, responseCap)
filtered := make(map[[48]byte]bool)
filtered[[48]byte{}] = true // Filter out keys with all zeros.
// Filter out duplicate public keys.
for _, pubKey := range req.PublicKeys {
pubkeyBytes := bytesutil.ToBytes48(pubKey)
if !filtered[pubkeyBytes] {
pubkeys = append(pubkeys, pubKey)
filtered[pubkeyBytes] = true
}
}
// Convert indices to public keys.
for _, idx := range req.Indices {
pubkeyBytes := headState.PubkeyAtIndex(uint64(idx))
if !filtered[pubkeyBytes] {
pubkeys = append(pubkeys, pubkeyBytes[:])
filtered[pubkeyBytes] = true
}
}
// Fetch statuses from beacon state.
statuses := make([]*ethpb.ValidatorStatusResponse, len(pubkeys))
for i, pubKey := range pubkeys {
statuses[i] = vs.validatorStatus(ctx, pubKey, headState)
}

return &ethpb.MultipleValidatorStatusResponse{
PublicKeys: pubkeys,
Statuses: statuses,
}, nil
}

// activationStatus returns the validator status response for the set of validators
// requested by their pub keys.
func (vs *Server) multipleValidatorStatus(
func (vs *Server) activationStatus(
ctx context.Context,
pubkeys [][]byte,
) (bool, []*ethpb.ValidatorActivationResponse_Status, error) {
Expand Down
212 changes: 210 additions & 2 deletions beacon-chain/rpc/validator/status_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package validator

import (
"bytes"
"context"
"math/big"
"testing"
Expand All @@ -16,6 +17,7 @@ import (
mockPOW "github.com/prysmaticlabs/prysm/beacon-chain/powchain/testing"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync/testing"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil"
Expand Down Expand Up @@ -539,7 +541,7 @@ func TestValidatorStatus_UnknownStatus(t *testing.T) {
}
}

func TestMultipleValidatorStatus_OK(t *testing.T) {
func TestActivationStatus_OK(t *testing.T) {
db := dbutil.SetupDB(t)
ctx := context.Background()

Expand Down Expand Up @@ -608,7 +610,7 @@ func TestMultipleValidatorStatus_OK(t *testing.T) {
DepositFetcher: depositCache,
HeadFetcher: &mockChain.ChainService{State: stateObj, Root: genesisRoot[:]},
}
activeExists, response, err := vs.multipleValidatorStatus(context.Background(), pubKeys)
activeExists, response, err := vs.activationStatus(context.Background(), pubKeys)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -901,3 +903,209 @@ func TestDepositBlockSlotBeforeGenesisTime(t *testing.T) {
t.Errorf("Wanted %v, got %v", expected, resp)
}
}

func TestMultipleValidatorStatus_Pubkeys(t *testing.T) {
db := dbutil.SetupDB(t)
ctx := context.Background()

pubKeys := [][]byte{pubKey(1), pubKey(2), pubKey(3), pubKey(4)}
stateObj, err := stateTrie.InitializeFromProtoUnsafe(&pbp2p.BeaconState{
Slot: 4000,
Validators: []*ethpb.Validator{
{
ActivationEpoch: 0,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: pubKeys[0],
},
{
ActivationEpoch: 0,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: pubKeys[1],
},
{
ActivationEligibilityEpoch: 700,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: pubKeys[3],
},
},
})
block := blk.NewGenesisBlock([]byte{})
genesisRoot, err := stateutil.BlockRoot(block.Block)
if err != nil {
t.Fatalf("Could not get signing root %v", err)
}
depData := &ethpb.Deposit_Data{
PublicKey: pubKey(1),
Signature: []byte("hi"),
WithdrawalCredentials: []byte("hey"),
Amount: 10,
}

dep := &ethpb.Deposit{
Data: depData,
}
depositTrie, err := trieutil.NewTrie(int(params.BeaconConfig().DepositContractTreeDepth))
if err != nil {
t.Fatalf("Could not setup deposit trie: %v", err)
}
depositCache := depositcache.NewDepositCache()
depositCache.InsertDeposit(ctx, dep, 10 /*blockNum*/, 0, depositTrie.Root())
depData = &ethpb.Deposit_Data{
PublicKey: pubKey(3),
Signature: []byte("hi"),
WithdrawalCredentials: []byte("hey"),
Amount: 10,
}

dep = &ethpb.Deposit{
Data: depData,
}
depositTrie.Insert(dep.Data.Signature, 15)
depositCache.InsertDeposit(context.Background(), dep, 0, 0, depositTrie.Root())

vs := &Server{
BeaconDB: db,
Ctx: context.Background(),
CanonicalStateChan: make(chan *pbp2p.BeaconState, 1),
ChainStartFetcher: &mockPOW.POWChain{},
BlockFetcher: &mockPOW.POWChain{},
Eth1InfoFetcher: &mockPOW.POWChain{},
DepositFetcher: depositCache,
HeadFetcher: &mockChain.ChainService{State: stateObj, Root: genesisRoot[:]},
SyncChecker: &mockSync.Sync{IsSyncing: false},
}

want := []*ethpb.ValidatorStatusResponse{
&ethpb.ValidatorStatusResponse{
Status: ethpb.ValidatorStatus_ACTIVE,
},
&ethpb.ValidatorStatusResponse{
Status: ethpb.ValidatorStatus_ACTIVE,
},
&ethpb.ValidatorStatusResponse{
Status: ethpb.ValidatorStatus_DEPOSITED,
DepositInclusionSlot: 53,
ActivationEpoch: 18446744073709551615,
},
&ethpb.ValidatorStatusResponse{
Status: ethpb.ValidatorStatus_DEPOSITED,
},
}

req := &ethpb.MultipleValidatorStatusRequest{PublicKeys: pubKeys}
response, err := vs.MultipleValidatorStatus(context.Background(), req)
if err != nil {
t.Fatal(err)
}

if len(response.PublicKeys) != len(pubKeys) {
t.Fatalf(
"Recieved %d public keys, wanted %d public keys", len(response.PublicKeys), len(pubKeys))
}
for i, resp := range response.PublicKeys {
if !bytes.Equal(pubKeys[i], resp) {
t.Fatalf("Wanted: %v\n Recieved: %v\n", pubKeys[i], resp)
}
}
if len(response.Statuses) != len(pubKeys) {
t.Fatalf("Recieved %d statuses, wanted %d statuses", len(response.Statuses), len(pubKeys))
}
for i, resp := range response.Statuses {
if !proto.Equal(want[i], resp) {
t.Fatalf("Wanted %v\n Recieved: %v\n", want[i], resp)
}
}
}

func TestMultipleValidatorStatus_Indices(t *testing.T) {
db := dbutil.SetupDB(t)
slot := uint64(10000)
epoch := helpers.SlotToEpoch(slot)
pubKeys := [][]byte{pubKey(1), pubKey(2), pubKey(3), pubKey(4)}
beaconState := &pbp2p.BeaconState{
Slot: 4000,
Validators: []*ethpb.Validator{
{
ActivationEpoch: 0,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: pubKeys[0],
},
{
ActivationEpoch: 0,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: pubKeys[1],
},
{
ActivationEligibilityEpoch: 700,
ExitEpoch: params.BeaconConfig().FarFutureEpoch,
PublicKey: pubKeys[2],
},
{
Slashed: true,
ExitEpoch: epoch + 1,
PublicKey: pubKeys[3],
},
},
}
stateObj, err := stateTrie.InitializeFromProtoUnsafe(beaconState)
block := blk.NewGenesisBlock([]byte{})
genesisRoot, err := stateutil.BlockRoot(block.Block)
if err != nil {
t.Fatalf("Could not get signing root %v", err)
}

vs := &Server{
BeaconDB: db,
Ctx: context.Background(),
CanonicalStateChan: make(chan *pbp2p.BeaconState, 1),
ChainStartFetcher: &mockPOW.POWChain{},
BlockFetcher: &mockPOW.POWChain{},
Eth1InfoFetcher: &mockPOW.POWChain{},
HeadFetcher: &mockChain.ChainService{State: stateObj, Root: genesisRoot[:]},
SyncChecker: &mockSync.Sync{IsSyncing: false},
}

want := []*ethpb.ValidatorStatusResponse{
&ethpb.ValidatorStatusResponse{
Status: ethpb.ValidatorStatus_ACTIVE,
},
&ethpb.ValidatorStatusResponse{
Status: ethpb.ValidatorStatus_ACTIVE,
},
&ethpb.ValidatorStatusResponse{
Status: ethpb.ValidatorStatus_DEPOSITED,
},
&ethpb.ValidatorStatusResponse{
Status: ethpb.ValidatorStatus_SLASHING,
},
}

// Note: Index 4 should be skipped.
req := &ethpb.MultipleValidatorStatusRequest{Indices: []int64{0, 1, 2, 3, 4}}
response, err := vs.MultipleValidatorStatus(context.Background(), req)
if err != nil {
t.Fatal(err)
}

if len(response.PublicKeys) != len(beaconState.Validators) {
t.Fatalf(
"Recieved %d public keys, wanted %d public keys",
len(response.PublicKeys), len(beaconState.Validators))
}
for i, resp := range response.PublicKeys {
expected := beaconState.Validators[i].PublicKey
if !bytes.Equal(expected, resp) {
t.Fatalf("Wanted: %v\n Recieved: %v\n", expected, resp)
}
}
if len(response.Statuses) != len(beaconState.Validators) {
t.Fatalf(
"Recieved %d statuses, wanted %d statuses",
len(response.Statuses), len(beaconState.Validators))
}
for i, resp := range response.Statuses {
if !proto.Equal(want[i], resp) {
t.Fatalf("Wanted %v\n Recieved: %v\n", want[i], resp)
}
}
}
25 changes: 22 additions & 3 deletions shared/mock/beacon_validator_client_mock.go

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

17 changes: 16 additions & 1 deletion shared/mock/beacon_validator_server_mock.go

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