|
|
- package grpc
-
- import (
- "context"
- "time"
-
- grpc "google.golang.org/grpc"
- "google.golang.org/grpc/status"
-
- "github.com/tendermint/tendermint/crypto"
- cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
- "github.com/tendermint/tendermint/libs/log"
- privvalproto "github.com/tendermint/tendermint/proto/tendermint/privval"
- tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
- "github.com/tendermint/tendermint/types"
- )
-
- // SignerClient implements PrivValidator.
- // Handles remote validator connections that provide signing services
- type SignerClient struct {
- logger log.Logger
-
- client privvalproto.PrivValidatorAPIClient
- conn *grpc.ClientConn
- chainID string
- }
-
- var _ types.PrivValidator = (*SignerClient)(nil)
-
- // NewSignerClient returns an instance of SignerClient.
- // it will start the endpoint (if not already started)
- func NewSignerClient(conn *grpc.ClientConn,
- chainID string, log log.Logger) (*SignerClient, error) {
-
- sc := &SignerClient{
- logger: log,
- chainID: chainID,
- client: privvalproto.NewPrivValidatorAPIClient(conn), // Create the Private Validator Client
- }
-
- return sc, nil
- }
-
- // Close closes the underlying connection
- func (sc *SignerClient) Close() error {
- sc.logger.Info("Stopping service")
- if sc.conn != nil {
- return sc.conn.Close()
- }
- return nil
- }
-
- //--------------------------------------------------------
- // Implement PrivValidator
-
- // GetPubKey retrieves a public key from a remote signer
- // returns an error if client is not able to provide the key
- func (sc *SignerClient) GetPubKey() (crypto.PubKey, error) {
- ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) // Todo: should this be configurable?
- defer cancel()
- resp, err := sc.client.GetPubKey(ctx, &privvalproto.PubKeyRequest{ChainId: sc.chainID})
- if err != nil {
- errStatus, _ := status.FromError(err)
- sc.logger.Error("SignerClient::GetPubKey", "err", errStatus.Message())
- return nil, errStatus.Err()
- }
-
- pk, err := cryptoenc.PubKeyFromProto(resp.PubKey)
- if err != nil {
- return nil, err
- }
-
- return pk, nil
- }
-
- // SignVote requests a remote signer to sign a vote
- func (sc *SignerClient) SignVote(chainID string, vote *tmproto.Vote) error {
- ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
- defer cancel()
- resp, err := sc.client.SignVote(ctx, &privvalproto.SignVoteRequest{ChainId: sc.chainID, Vote: vote})
- if err != nil {
- errStatus, _ := status.FromError(err)
- sc.logger.Error("Client SignVote", "err", errStatus.Message())
- return errStatus.Err()
- }
-
- *vote = resp.Vote
-
- return nil
- }
-
- // SignProposal requests a remote signer to sign a proposal
- func (sc *SignerClient) SignProposal(chainID string, proposal *tmproto.Proposal) error {
- ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
- defer cancel()
- resp, err := sc.client.SignProposal(
- ctx, &privvalproto.SignProposalRequest{ChainId: chainID, Proposal: proposal})
-
- if err != nil {
- errStatus, _ := status.FromError(err)
- sc.logger.Error("SignerClient::SignProposal", "err", errStatus.Message())
- return errStatus.Err()
- }
-
- *proposal = resp.Proposal
-
- return nil
- }
|