You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
1.9 KiB

  1. package privval
  2. import (
  3. "errors"
  4. "time"
  5. "github.com/tendermint/tendermint/crypto"
  6. "github.com/tendermint/tendermint/types"
  7. )
  8. // RetrySignerClient wraps SignerClient adding retry for each operation (except
  9. // Ping) w/ a timeout.
  10. type RetrySignerClient struct {
  11. next *SignerClient
  12. retries int
  13. timeout time.Duration
  14. }
  15. // NewRetrySignerClient returns RetrySignerClient. If +retries+ is 0, the
  16. // client will be retrying each operation indefinitely.
  17. func NewRetrySignerClient(sc *SignerClient, retries int, timeout time.Duration) *RetrySignerClient {
  18. return &RetrySignerClient{sc, retries, timeout}
  19. }
  20. var _ types.PrivValidator = (*RetrySignerClient)(nil)
  21. func (sc *RetrySignerClient) Close() error {
  22. return sc.next.Close()
  23. }
  24. func (sc *RetrySignerClient) IsConnected() bool {
  25. return sc.next.IsConnected()
  26. }
  27. func (sc *RetrySignerClient) WaitForConnection(maxWait time.Duration) error {
  28. return sc.next.WaitForConnection(maxWait)
  29. }
  30. //--------------------------------------------------------
  31. // Implement PrivValidator
  32. func (sc *RetrySignerClient) Ping() error {
  33. return sc.next.Ping()
  34. }
  35. func (sc *RetrySignerClient) GetPubKey() crypto.PubKey {
  36. for i := 0; i < sc.retries || sc.retries == 0; i++ {
  37. pk := sc.next.GetPubKey()
  38. if pk != nil {
  39. return pk
  40. }
  41. time.Sleep(sc.timeout)
  42. }
  43. return nil
  44. }
  45. func (sc *RetrySignerClient) SignVote(chainID string, vote *types.Vote) error {
  46. for i := 0; i < sc.retries || sc.retries == 0; i++ {
  47. err := sc.next.SignVote(chainID, vote)
  48. if err == nil {
  49. return nil
  50. }
  51. time.Sleep(sc.timeout)
  52. }
  53. return errors.New("exhausted all attempts to sign vote")
  54. }
  55. func (sc *RetrySignerClient) SignProposal(chainID string, proposal *types.Proposal) error {
  56. for i := 0; i < sc.retries || sc.retries == 0; i++ {
  57. err := sc.next.SignProposal(chainID, proposal)
  58. if err == nil {
  59. return nil
  60. }
  61. time.Sleep(sc.timeout)
  62. }
  63. return errors.New("exhausted all attempts to sign proposal")
  64. }