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.

132 lines
3.2 KiB

  1. package types
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "github.com/tendermint/tendermint/crypto"
  7. "github.com/tendermint/tendermint/crypto/ed25519"
  8. )
  9. // PrivValidator defines the functionality of a local Tendermint validator
  10. // that signs votes, proposals, and heartbeats, and never double signs.
  11. type PrivValidator interface {
  12. GetAddress() Address // redundant since .PubKey().Address()
  13. GetPubKey() crypto.PubKey
  14. SignVote(chainID string, vote *Vote) error
  15. SignProposal(chainID string, proposal *Proposal) error
  16. SignHeartbeat(chainID string, heartbeat *Heartbeat) error
  17. }
  18. //----------------------------------------
  19. // Misc.
  20. type PrivValidatorsByAddress []PrivValidator
  21. func (pvs PrivValidatorsByAddress) Len() int {
  22. return len(pvs)
  23. }
  24. func (pvs PrivValidatorsByAddress) Less(i, j int) bool {
  25. return bytes.Compare(pvs[i].GetAddress(), pvs[j].GetAddress()) == -1
  26. }
  27. func (pvs PrivValidatorsByAddress) Swap(i, j int) {
  28. it := pvs[i]
  29. pvs[i] = pvs[j]
  30. pvs[j] = it
  31. }
  32. //----------------------------------------
  33. // MockPV
  34. // MockPV implements PrivValidator without any safety or persistence.
  35. // Only use it for testing.
  36. type MockPV struct {
  37. privKey crypto.PrivKey
  38. }
  39. func NewMockPV() *MockPV {
  40. return &MockPV{ed25519.GenPrivKey()}
  41. }
  42. // Implements PrivValidator.
  43. func (pv *MockPV) GetAddress() Address {
  44. return pv.privKey.PubKey().Address()
  45. }
  46. // Implements PrivValidator.
  47. func (pv *MockPV) GetPubKey() crypto.PubKey {
  48. return pv.privKey.PubKey()
  49. }
  50. // Implements PrivValidator.
  51. func (pv *MockPV) SignVote(chainID string, vote *Vote) error {
  52. signBytes := vote.SignBytes(chainID)
  53. sig, err := pv.privKey.Sign(signBytes)
  54. if err != nil {
  55. return err
  56. }
  57. vote.Signature = sig
  58. return nil
  59. }
  60. // Implements PrivValidator.
  61. func (pv *MockPV) SignProposal(chainID string, proposal *Proposal) error {
  62. signBytes := proposal.SignBytes(chainID)
  63. sig, err := pv.privKey.Sign(signBytes)
  64. if err != nil {
  65. return err
  66. }
  67. proposal.Signature = sig
  68. return nil
  69. }
  70. // signHeartbeat signs the heartbeat without any checking.
  71. func (pv *MockPV) SignHeartbeat(chainID string, heartbeat *Heartbeat) error {
  72. sig, err := pv.privKey.Sign(heartbeat.SignBytes(chainID))
  73. if err != nil {
  74. return err
  75. }
  76. heartbeat.Signature = sig
  77. return nil
  78. }
  79. // String returns a string representation of the MockPV.
  80. func (pv *MockPV) String() string {
  81. return fmt.Sprintf("MockPV{%v}", pv.GetAddress())
  82. }
  83. // XXX: Implement.
  84. func (pv *MockPV) DisableChecks() {
  85. // Currently this does nothing,
  86. // as MockPV has no safety checks at all.
  87. }
  88. type erroringMockPV struct {
  89. *MockPV
  90. }
  91. var ErroringMockPVErr = errors.New("erroringMockPV always returns an error")
  92. // Implements PrivValidator.
  93. func (pv *erroringMockPV) SignVote(chainID string, vote *Vote) error {
  94. return ErroringMockPVErr
  95. }
  96. // Implements PrivValidator.
  97. func (pv *erroringMockPV) SignProposal(chainID string, proposal *Proposal) error {
  98. return ErroringMockPVErr
  99. }
  100. // signHeartbeat signs the heartbeat without any checking.
  101. func (pv *erroringMockPV) SignHeartbeat(chainID string, heartbeat *Heartbeat) error {
  102. return ErroringMockPVErr
  103. }
  104. // NewErroringMockPV returns a MockPV that fails on each signing request. Again, for testing only.
  105. func NewErroringMockPV() *erroringMockPV {
  106. return &erroringMockPV{&MockPV{ed25519.GenPrivKey()}}
  107. }