github.com/pokt-network/tendermint@v0.32.11-0.20230426215212-59310158d3e9/privval/signer_client.go (about)

     1  package privval
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/pkg/errors"
     7  
     8  	"github.com/tendermint/tendermint/crypto"
     9  	"github.com/tendermint/tendermint/types"
    10  )
    11  
    12  // SignerClient implements PrivValidator.
    13  // Handles remote validator connections that provide signing services
    14  type SignerClient struct {
    15  	endpoint *SignerListenerEndpoint
    16  }
    17  
    18  var _ types.PrivValidator = (*SignerClient)(nil)
    19  
    20  // NewSignerClient returns an instance of SignerClient.
    21  // it will start the endpoint (if not already started)
    22  func NewSignerClient(endpoint *SignerListenerEndpoint) (*SignerClient, error) {
    23  	if !endpoint.IsRunning() {
    24  		if err := endpoint.Start(); err != nil {
    25  			return nil, errors.Wrap(err, "failed to start listener endpoint")
    26  		}
    27  	}
    28  
    29  	return &SignerClient{endpoint: endpoint}, nil
    30  }
    31  
    32  // Close closes the underlying connection
    33  func (sc *SignerClient) Close() error {
    34  	return sc.endpoint.Close()
    35  }
    36  
    37  // IsConnected indicates with the signer is connected to a remote signing service
    38  func (sc *SignerClient) IsConnected() bool {
    39  	return sc.endpoint.IsConnected()
    40  }
    41  
    42  // WaitForConnection waits maxWait for a connection or returns a timeout error
    43  func (sc *SignerClient) WaitForConnection(maxWait time.Duration) error {
    44  	return sc.endpoint.WaitForConnection(maxWait)
    45  }
    46  
    47  //--------------------------------------------------------
    48  // Implement PrivValidator
    49  
    50  // Ping sends a ping request to the remote signer
    51  func (sc *SignerClient) Ping() error {
    52  	response, err := sc.endpoint.SendRequest(&PingRequest{})
    53  	if err != nil {
    54  		sc.endpoint.Logger.Error("SignerClient::Ping", "err", err)
    55  		return nil
    56  	}
    57  
    58  	_, ok := response.(*PingResponse)
    59  	if !ok {
    60  		return ErrUnexpectedResponse
    61  	}
    62  
    63  	return nil
    64  }
    65  
    66  // GetPubKey retrieves a public key from a remote signer
    67  // returns an error if client is not able to provide the key
    68  func (sc *SignerClient) GetPubKey() (crypto.PubKey, error) {
    69  	response, err := sc.endpoint.SendRequest(&PubKeyRequest{})
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	pubKeyResp, ok := response.(*PubKeyResponse)
    75  	if !ok {
    76  		return nil, ErrUnexpectedResponse
    77  	}
    78  
    79  	if pubKeyResp.Error != nil {
    80  		return nil, pubKeyResp.Error
    81  	}
    82  
    83  	return pubKeyResp.PubKey, nil
    84  }
    85  
    86  // SignVote requests a remote signer to sign a vote
    87  func (sc *SignerClient) SignVote(chainID string, vote *types.Vote) error {
    88  	response, err := sc.endpoint.SendRequest(&SignVoteRequest{Vote: vote})
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	resp, ok := response.(*SignedVoteResponse)
    94  	if !ok {
    95  		return ErrUnexpectedResponse
    96  	}
    97  	if resp.Error != nil {
    98  		return resp.Error
    99  	}
   100  	*vote = *resp.Vote
   101  
   102  	return nil
   103  }
   104  
   105  // SignProposal requests a remote signer to sign a proposal
   106  func (sc *SignerClient) SignProposal(chainID string, proposal *types.Proposal) error {
   107  	response, err := sc.endpoint.SendRequest(&SignProposalRequest{Proposal: proposal})
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	resp, ok := response.(*SignedProposalResponse)
   113  	if !ok {
   114  		return ErrUnexpectedResponse
   115  	}
   116  	if resp.Error != nil {
   117  		return resp.Error
   118  	}
   119  	*proposal = *resp.Proposal
   120  
   121  	return nil
   122  }