Implement List Keystores for Standard API (#9863)

* start api

* keystores list

* gaz

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
Raul Jordan
2021-11-08 14:08:17 -05:00
committed by GitHub
parent 40eb718ba2
commit 6e731bdedd
3 changed files with 114 additions and 0 deletions

View File

@@ -11,6 +11,7 @@ go_library(
"log.go",
"server.go",
"slashing.go",
"standard_api.go",
"wallet.go",
],
importpath = "github.com/prysmaticlabs/prysm/validator/rpc",
@@ -30,6 +31,7 @@ go_library(
"//io/logs:go_default_library",
"//io/prompt:go_default_library",
"//monitoring/tracing:go_default_library",
"//proto/eth/service:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//proto/prysm/v1alpha1/validator-client:go_default_library",
"//runtime/version:go_default_library",
@@ -77,6 +79,7 @@ go_test(
"intercepter_test.go",
"server_test.go",
"slashing_test.go",
"standard_api_test.go",
"wallet_test.go",
],
embed = [":go_default_library"],

View File

@@ -0,0 +1,38 @@
package rpc
import (
"context"
"fmt"
"github.com/golang/protobuf/ptypes/empty"
ethpbservice "github.com/prysmaticlabs/prysm/proto/eth/service"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/derived"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// ListKeystores implements the standard validator key management API.
func (s Server) ListKeystores(
ctx context.Context, _ *empty.Empty,
) (*ethpbservice.ListKeystoresResponse, error) {
if !s.walletInitialized {
return nil, status.Error(codes.Internal, "Wallet not ready")
}
pubKeys, err := s.keymanager.FetchValidatingPublicKeys(ctx)
if err != nil {
return nil, status.Errorf(codes.Internal, "Could not list keystores: %v", err)
}
keystoreResponse := make([]*ethpbservice.ListKeystoresResponse_Keystore, len(pubKeys))
for i := 0; i < len(pubKeys); i++ {
keystoreResponse[i] = &ethpbservice.ListKeystoresResponse_Keystore{
ValidatingPubkey: pubKeys[i][:],
}
if s.wallet.KeymanagerKind() == keymanager.Derived {
keystoreResponse[i].DerivationPath = fmt.Sprintf(derived.ValidatingKeyDerivationPathTemplate, i)
}
}
return &ethpbservice.ListKeystoresResponse{
Keystores: keystoreResponse,
}, nil
}

View File

@@ -0,0 +1,73 @@
package rpc
import (
"context"
"fmt"
"testing"
"github.com/golang/protobuf/ptypes/empty"
"github.com/prysmaticlabs/prysm/testing/require"
"github.com/prysmaticlabs/prysm/validator/accounts"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/derived"
constant "github.com/prysmaticlabs/prysm/validator/testing"
)
func TestServer_ListKeystores(t *testing.T) {
t.Run("wallet not ready", func(t *testing.T) {
s := Server{}
_, err := s.ListKeystores(context.Background(), &empty.Empty{})
require.ErrorContains(t, "Wallet not ready", err)
})
ctx := context.Background()
localWalletDir := setupWalletDir(t)
defaultWalletPath = localWalletDir
w, err := accounts.CreateWalletWithKeymanager(ctx, &accounts.CreateWalletConfig{
WalletCfg: &wallet.Config{
WalletDir: defaultWalletPath,
KeymanagerKind: keymanager.Derived,
WalletPassword: strongPass,
},
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(ctx, iface.InitKeymanagerConfig{ListenForChanges: false})
require.NoError(t, err)
s := &Server{
keymanager: km,
walletInitialized: true,
wallet: w,
}
t.Run("no keystores found", func(t *testing.T) {
resp, err := s.ListKeystores(context.Background(), &empty.Empty{})
require.NoError(t, err)
require.Equal(t, true, len(resp.Keystores) == 0)
})
numAccounts := 50
dr, ok := km.(*derived.Keymanager)
require.Equal(t, true, ok)
err = dr.RecoverAccountsFromMnemonic(ctx, constant.TestMnemonic, "", numAccounts)
require.NoError(t, err)
expectedKeys, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
t.Run("returns proper data with existing keystores", func(t *testing.T) {
resp, err := s.ListKeystores(context.Background(), &empty.Empty{})
require.NoError(t, err)
require.Equal(t, numAccounts, len(resp.Keystores))
for i := 0; i < numAccounts; i++ {
require.DeepEqual(t, expectedKeys[i][:], resp.Keystores[i].ValidatingPubkey)
require.Equal(
t,
fmt.Sprintf(derived.ValidatingKeyDerivationPathTemplate, i),
resp.Keystores[i].DerivationPath,
)
}
})
}