github.com/pokt-network/tendermint@v0.32.11-0.20230426215212-59310158d3e9/privval/retry_signer_client.go (about) 1 package privval 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/tendermint/tendermint/crypto" 8 "github.com/tendermint/tendermint/types" 9 ) 10 11 // RetrySignerClient wraps SignerClient adding retry for each operation (except 12 // Ping) w/ a timeout. 13 type RetrySignerClient struct { 14 next *SignerClient 15 retries int 16 timeout time.Duration 17 } 18 19 // NewRetrySignerClient returns RetrySignerClient. If +retries+ is 0, the 20 // client will be retrying each operation indefinitely. 21 func NewRetrySignerClient(sc *SignerClient, retries int, timeout time.Duration) *RetrySignerClient { 22 return &RetrySignerClient{sc, retries, timeout} 23 } 24 25 var _ types.PrivValidator = (*RetrySignerClient)(nil) 26 27 func (sc *RetrySignerClient) Close() error { 28 return sc.next.Close() 29 } 30 31 func (sc *RetrySignerClient) IsConnected() bool { 32 return sc.next.IsConnected() 33 } 34 35 func (sc *RetrySignerClient) WaitForConnection(maxWait time.Duration) error { 36 return sc.next.WaitForConnection(maxWait) 37 } 38 39 //-------------------------------------------------------- 40 // Implement PrivValidator 41 42 func (sc *RetrySignerClient) Ping() error { 43 return sc.next.Ping() 44 } 45 46 func (sc *RetrySignerClient) GetPubKey() (crypto.PubKey, error) { 47 var ( 48 pk crypto.PubKey 49 err error 50 ) 51 for i := 0; i < sc.retries || sc.retries == 0; i++ { 52 pk, err = sc.next.GetPubKey() 53 if err == nil { 54 return pk, nil 55 } 56 // If remote signer errors, we don't retry. 57 if _, ok := err.(*RemoteSignerError); ok { 58 return nil, err 59 } 60 time.Sleep(sc.timeout) 61 } 62 return nil, fmt.Errorf("exhausted all attempts to get pubkey: %w", err) 63 } 64 65 func (sc *RetrySignerClient) SignVote(chainID string, vote *types.Vote) error { 66 var err error 67 for i := 0; i < sc.retries || sc.retries == 0; i++ { 68 err = sc.next.SignVote(chainID, vote) 69 if err == nil { 70 return nil 71 } 72 // If remote signer errors, we don't retry. 73 if _, ok := err.(*RemoteSignerError); ok { 74 return err 75 } 76 time.Sleep(sc.timeout) 77 } 78 return fmt.Errorf("exhausted all attempts to sign vote: %w", err) 79 } 80 81 func (sc *RetrySignerClient) SignProposal(chainID string, proposal *types.Proposal) error { 82 var err error 83 for i := 0; i < sc.retries || sc.retries == 0; i++ { 84 err = sc.next.SignProposal(chainID, proposal) 85 if err == nil { 86 return nil 87 } 88 // If remote signer errors, we don't retry. 89 if _, ok := err.(*RemoteSignerError); ok { 90 return err 91 } 92 time.Sleep(sc.timeout) 93 } 94 return fmt.Errorf("exhausted all attempts to sign proposal: %w", err) 95 }