mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-03 08:37:37 +00:00
5a66807989
* First take at updating everything to v5 * Patch gRPC gateway to use prysm v5 Fix patch * Update go ssz --------- Co-authored-by: Preston Van Loon <pvanloon@offchainlabs.com>
122 lines
3.9 KiB
Go
122 lines
3.9 KiB
Go
package validator
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/prysmaticlabs/prysm/v5/api/client"
|
|
"github.com/prysmaticlabs/prysm/v5/validator/rpc"
|
|
)
|
|
|
|
const (
|
|
localKeysPath = "/eth/v1/keystores"
|
|
remoteKeysPath = "/eth/v1/remotekeys"
|
|
feeRecipientPath = "/eth/v1/validator/{pubkey}/feerecipient"
|
|
)
|
|
|
|
// Client provides a collection of helper methods for calling the Keymanager API endpoints.
|
|
type Client struct {
|
|
*client.Client
|
|
}
|
|
|
|
// NewClient returns a new Client that includes functions for REST calls to keymanager APIs.
|
|
func NewClient(host string, opts ...client.ClientOpt) (*Client, error) {
|
|
c, err := client.NewClient(host, opts...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Client{c}, nil
|
|
}
|
|
|
|
// GetValidatorPubKeys gets the current list of web3signer or the local validator public keys in hex format.
|
|
func (c *Client) GetValidatorPubKeys(ctx context.Context) ([]string, error) {
|
|
jsonlocal, err := c.GetLocalValidatorKeys(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
jsonremote, err := c.GetRemoteValidatorKeys(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(jsonlocal.Data) == 0 && len(jsonremote.Data) == 0 {
|
|
return nil, errors.New("there are no local keys or remote keys on the validator")
|
|
}
|
|
|
|
hexKeys := make(map[string]bool)
|
|
|
|
for index := range jsonlocal.Data {
|
|
hexKeys[jsonlocal.Data[index].ValidatingPubkey] = true
|
|
}
|
|
for index := range jsonremote.Data {
|
|
hexKeys[jsonremote.Data[index].Pubkey] = true
|
|
}
|
|
keys := make([]string, 0)
|
|
for k := range hexKeys {
|
|
keys = append(keys, k)
|
|
}
|
|
return keys, nil
|
|
}
|
|
|
|
// GetLocalValidatorKeys calls the keymanager APIs for local validator keys
|
|
func (c *Client) GetLocalValidatorKeys(ctx context.Context) (*rpc.ListKeystoresResponse, error) {
|
|
localBytes, err := c.Get(ctx, localKeysPath, client.WithAuthorizationToken(c.Token()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
jsonlocal := &rpc.ListKeystoresResponse{}
|
|
if err := json.Unmarshal(localBytes, jsonlocal); err != nil {
|
|
return nil, errors.Wrap(err, "failed to parse local keystore list")
|
|
}
|
|
return jsonlocal, nil
|
|
}
|
|
|
|
// GetRemoteValidatorKeys calls the keymanager APIs for web3signer validator keys
|
|
func (c *Client) GetRemoteValidatorKeys(ctx context.Context) (*rpc.ListRemoteKeysResponse, error) {
|
|
remoteBytes, err := c.Get(ctx, remoteKeysPath, client.WithAuthorizationToken(c.Token()))
|
|
if err != nil {
|
|
if !strings.Contains(err.Error(), "Prysm Wallet is not of type Web3Signer") {
|
|
return nil, err
|
|
}
|
|
}
|
|
jsonremote := &rpc.ListRemoteKeysResponse{}
|
|
if len(remoteBytes) != 0 {
|
|
if err := json.Unmarshal(remoteBytes, jsonremote); err != nil {
|
|
return nil, errors.Wrap(err, "failed to parse remote keystore list")
|
|
}
|
|
}
|
|
return jsonremote, nil
|
|
}
|
|
|
|
// GetFeeRecipientAddresses takes a list of validators in hex format and returns an equal length list of fee recipients in hex format.
|
|
func (c *Client) GetFeeRecipientAddresses(ctx context.Context, validators []string) ([]string, error) {
|
|
feeRecipients := make([]string, len(validators))
|
|
for index, validator := range validators {
|
|
feejson, err := c.GetFeeRecipientAddress(ctx, validator)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, fmt.Sprintf("keymanager API failed to retrieve fee recipient for validator %s", validators[index]))
|
|
}
|
|
if feejson.Data == nil {
|
|
continue
|
|
}
|
|
feeRecipients[index] = feejson.Data.Ethaddress
|
|
}
|
|
return feeRecipients, nil
|
|
}
|
|
|
|
// GetFeeRecipientAddress takes a public key and calls the keymanager API to return its fee recipient.
|
|
func (c *Client) GetFeeRecipientAddress(ctx context.Context, pubkey string) (*rpc.GetFeeRecipientByPubkeyResponse, error) {
|
|
path := strings.Replace(feeRecipientPath, "{pubkey}", pubkey, 1)
|
|
b, err := c.Get(ctx, path, client.WithAuthorizationToken(c.Token()))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
feejson := &rpc.GetFeeRecipientByPubkeyResponse{}
|
|
if err := json.Unmarshal(b, feejson); err != nil {
|
|
return nil, errors.Wrap(err, "failed to parse fee recipient")
|
|
}
|
|
return feejson, nil
|
|
}
|