Web3signer: persistent public keys (#13682)

* WIP

* broken and still wip

* more wip improving saving

* wip

* removing cyclic dependency

* gaz

* fixes

* fixing more tests and how files load

* fixing wallet tests

* fixing test

* updating keymanager tests

* improving how the web3signer keymanager works

* WIP

* updated keymanager to read from file

* gaz

* reuse readkeyfile function and add in duplicate keys check

* adding in locks to increase safety

* refactored how saving keys work, more tests needed:

* fix test

* fix tests

* adding unit tests and cleaning up locks

* fixing tests

* tests were not fixed properly

* removing unneeded files

* Update cmd/validator/accounts/wallet_utils.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update validator/accounts/wallet/wallet.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* review feedback

* updating flags and e2e

* deepsource fix

* resolving feedback

* removing fatal test for now

* addressing manu's feedback

* gofmt

* fixing tests

* fixing unit tests

* more idomatic feedback

* updating log files

* updating based on preston's suggestion

* improving logs and event triggers

* addressing comments from manu

* truncating was not triggering key file reload

* fixing unit test

* removing wrong dependency

* fix another broken unit test

* fixing bad pathing on file

* handle errors in test

* fixing testdata dependency

* resolving deepsource and comment around logs

* removing unneeded buffer

* reworking ux of web3signer file, unit tests to come

* adding unit tests for file change retries

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>

* updating based on review feedback

* missed err check

* adding some aliases to make running easier

* Update validator/keymanager/remote-web3signer/log.go

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* radek's review

* Update validator/keymanager/remote-web3signer/internal/client.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* Update validator/keymanager/remote-web3signer/keymanager.go

Co-authored-by: Radosław Kapka <rkapka@wp.pl>

* addressing more review feedback and linting

* fixing tests

* adding log

* adding 1 more test

* improving logs

---------

Co-authored-by: Sammy Rosso <15244892+saolyn@users.noreply.github.com>
Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
james-prysm
2024-06-26 10:36:32 -05:00
committed by GitHub
parent aad29ff9fc
commit 539b981ac3
32 changed files with 1099 additions and 270 deletions

View File

@@ -148,6 +148,7 @@ go_test(
"@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
"@com_github_tyler_smith_go_bip39//:go_default_library",
"@com_github_urfave_cli_v2//:go_default_library",
"@com_github_wealdtech_go_eth2_wallet_encryptor_keystorev4//:go_default_library",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//metadata:go_default_library",

View File

@@ -484,7 +484,12 @@ func (s *Server) ImportRemoteKeys(w http.ResponseWriter, r *http.Request) {
log.Warnf("Setting the remote signer base url within the request is not supported. The remote signer url can only be set from the --%s flag.", flags.Web3SignerURLFlag.Name)
}
httputil.WriteJson(w, &RemoteKeysResponse{Data: adder.AddPublicKeys(remoteKeys)})
ks, err := adder.AddPublicKeys(remoteKeys)
if err != nil {
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, &RemoteKeysResponse{Data: ks})
}
// DeleteRemoteKeys deletes a list of public keys defined for web3signer keymanager type.
@@ -533,8 +538,12 @@ func (s *Server) DeleteRemoteKeys(w http.ResponseWriter, r *http.Request) {
httputil.WriteJson(w, &RemoteKeysResponse{Data: statuses})
return
}
httputil.WriteJson(w, RemoteKeysResponse{Data: deleter.DeletePublicKeys(req.Pubkeys)})
data, err := deleter.DeletePublicKeys(req.Pubkeys)
if err != nil {
httputil.HandleError(w, err.Error(), http.StatusInternalServerError)
return
}
httputil.WriteJson(w, RemoteKeysResponse{Data: data})
}
// ListFeeRecipientByPubkey returns the public key to eth address mapping object to the end user.

View File

@@ -4,9 +4,12 @@ import (
"bytes"
"context"
"encoding/json"
"flag"
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"time"
@@ -15,6 +18,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/gorilla/mux"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/prysmaticlabs/prysm/v5/cmd/validator/flags"
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/config/proposer"
@@ -40,6 +44,7 @@ import (
remoteweb3signer "github.com/prysmaticlabs/prysm/v5/validator/keymanager/remote-web3signer"
"github.com/prysmaticlabs/prysm/v5/validator/slashing-protection-history/format"
mocks "github.com/prysmaticlabs/prysm/v5/validator/testing"
"github.com/urfave/cli/v2"
"go.uber.org/mock/gomock"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/emptypb"
@@ -342,13 +347,18 @@ func TestServer_ImportKeystores(t *testing.T) {
func TestServer_ImportKeystores_WrongKeymanagerKind(t *testing.T) {
ctx := context.Background()
w := wallet.NewWalletForWeb3Signer()
app := cli.App{}
set := flag.NewFlagSet("test", 0)
newDir := filepath.Join(t.TempDir(), "new")
require.NoError(t, os.MkdirAll(newDir, 0700))
set.String(flags.WalletDirFlag.Name, newDir, "")
w := wallet.NewWalletForWeb3Signer(cli.NewContext(&app, set, nil))
root := make([]byte, fieldparams.RootLength)
root[0] = 1
km, err := w.InitializeKeymanager(ctx, iface.InitKeymanagerConfig{ListenForChanges: false, Web3SignerConfig: &remoteweb3signer.SetupConfig{
BaseEndpoint: "http://example.com",
GenesisValidatorsRoot: root,
PublicKeysURL: "http://example.com/public_keys",
ProvidedPublicKeys: []string{"0xa2b5aaad9c6efefe7bb9b1243a043404f3362937cfb6b31833929833173f476630ea2cfeb0d9ddf15f97ca8685948820"},
}})
require.NoError(t, err)
vs, err := client.NewValidatorService(ctx, &client.Config{
@@ -620,14 +630,19 @@ func TestServer_DeleteKeystores_FailedSlashingProtectionExport(t *testing.T) {
func TestServer_DeleteKeystores_WrongKeymanagerKind(t *testing.T) {
ctx := context.Background()
w := wallet.NewWalletForWeb3Signer()
app := cli.App{}
set := flag.NewFlagSet("test", 0)
newDir := filepath.Join(t.TempDir(), "new")
require.NoError(t, os.MkdirAll(newDir, 0700))
set.String(flags.WalletDirFlag.Name, newDir, "")
w := wallet.NewWalletForWeb3Signer(cli.NewContext(&app, set, nil))
root := make([]byte, fieldparams.RootLength)
root[0] = 1
km, err := w.InitializeKeymanager(ctx, iface.InitKeymanagerConfig{ListenForChanges: false,
Web3SignerConfig: &remoteweb3signer.SetupConfig{
BaseEndpoint: "http://example.com",
GenesisValidatorsRoot: root,
PublicKeysURL: "http://example.com/public_keys",
ProvidedPublicKeys: []string{"0xa2b5aaad9c6efefe7bb9b1243a043404f3362937cfb6b31833929833173f476630ea2cfeb0d9ddf15f97ca8685948820"},
}})
require.NoError(t, err)
vs, err := client.NewValidatorService(ctx, &client.Config{
@@ -1312,16 +1327,17 @@ func TestServer_DeleteGasLimit(t *testing.T) {
func TestServer_ListRemoteKeys(t *testing.T) {
ctx := context.Background()
w := wallet.NewWalletForWeb3Signer()
app := cli.App{}
set := flag.NewFlagSet("test", 0)
newDir := filepath.Join(t.TempDir(), "new")
set.String(flags.WalletDirFlag.Name, newDir, "")
w := wallet.NewWalletForWeb3Signer(cli.NewContext(&app, set, nil))
root := make([]byte, fieldparams.RootLength)
root[0] = 1
bytevalue, err := hexutil.Decode("0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a")
require.NoError(t, err)
pubkeys := [][fieldparams.BLSPubkeyLength]byte{bytesutil.ToBytes48(bytevalue)}
config := &remoteweb3signer.SetupConfig{
BaseEndpoint: "http://example.com",
GenesisValidatorsRoot: root,
ProvidedPublicKeys: pubkeys,
ProvidedPublicKeys: []string{"0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"},
}
km, err := w.InitializeKeymanager(ctx, iface.InitKeymanagerConfig{ListenForChanges: false, Web3SignerConfig: config})
require.NoError(t, err)
@@ -1357,7 +1373,11 @@ func TestServer_ListRemoteKeys(t *testing.T) {
func TestServer_ImportRemoteKeys(t *testing.T) {
ctx := context.Background()
w := wallet.NewWalletForWeb3Signer()
app := cli.App{}
set := flag.NewFlagSet("test", 0)
newDir := filepath.Join(t.TempDir(), "new")
set.String(flags.WalletDirFlag.Name, newDir, "")
w := wallet.NewWalletForWeb3Signer(cli.NewContext(&app, set, nil))
root := make([]byte, fieldparams.RootLength)
root[0] = 1
config := &remoteweb3signer.SetupConfig{
@@ -1414,17 +1434,18 @@ func TestServer_ImportRemoteKeys(t *testing.T) {
func TestServer_DeleteRemoteKeys(t *testing.T) {
ctx := context.Background()
w := wallet.NewWalletForWeb3Signer()
app := cli.App{}
set := flag.NewFlagSet("test", 0)
newDir := filepath.Join(t.TempDir(), "new")
set.String(flags.WalletDirFlag.Name, newDir, "")
w := wallet.NewWalletForWeb3Signer(cli.NewContext(&app, set, nil))
root := make([]byte, fieldparams.RootLength)
root[0] = 1
pkey := "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"
bytevalue, err := hexutil.Decode(pkey)
require.NoError(t, err)
pubkeys := [][fieldparams.BLSPubkeyLength]byte{bytesutil.ToBytes48(bytevalue)}
config := &remoteweb3signer.SetupConfig{
BaseEndpoint: "http://example.com",
GenesisValidatorsRoot: root,
ProvidedPublicKeys: pubkeys,
ProvidedPublicKeys: []string{pkey},
}
km, err := w.InitializeKeymanager(ctx, iface.InitKeymanagerConfig{ListenForChanges: false, Web3SignerConfig: config})
require.NoError(t, err)