github.com/evdatsion/aphelion-dpos-bft@v0.32.1/types/priv_validator.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 8 "github.com/evdatsion/aphelion-dpos-bft/crypto" 9 "github.com/evdatsion/aphelion-dpos-bft/crypto/ed25519" 10 ) 11 12 // PrivValidator defines the functionality of a local Tendermint validator 13 // that signs votes and proposals, and never double signs. 14 type PrivValidator interface { 15 GetPubKey() crypto.PubKey 16 17 SignVote(chainID string, vote *Vote) error 18 SignProposal(chainID string, proposal *Proposal) error 19 } 20 21 //---------------------------------------- 22 // Misc. 23 24 type PrivValidatorsByAddress []PrivValidator 25 26 func (pvs PrivValidatorsByAddress) Len() int { 27 return len(pvs) 28 } 29 30 func (pvs PrivValidatorsByAddress) Less(i, j int) bool { 31 return bytes.Compare(pvs[i].GetPubKey().Address(), pvs[j].GetPubKey().Address()) == -1 32 } 33 34 func (pvs PrivValidatorsByAddress) Swap(i, j int) { 35 it := pvs[i] 36 pvs[i] = pvs[j] 37 pvs[j] = it 38 } 39 40 //---------------------------------------- 41 // MockPV 42 43 // MockPV implements PrivValidator without any safety or persistence. 44 // Only use it for testing. 45 type MockPV struct { 46 privKey crypto.PrivKey 47 breakProposalSigning bool 48 breakVoteSigning bool 49 } 50 51 func NewMockPV() *MockPV { 52 return &MockPV{ed25519.GenPrivKey(), false, false} 53 } 54 55 // NewMockPVWithParams allows one to create a MockPV instance, but with finer 56 // grained control over the operation of the mock validator. This is useful for 57 // mocking test failures. 58 func NewMockPVWithParams(privKey crypto.PrivKey, breakProposalSigning, breakVoteSigning bool) *MockPV { 59 return &MockPV{privKey, breakProposalSigning, breakVoteSigning} 60 } 61 62 // Implements PrivValidator. 63 func (pv *MockPV) GetPubKey() crypto.PubKey { 64 return pv.privKey.PubKey() 65 } 66 67 // Implements PrivValidator. 68 func (pv *MockPV) SignVote(chainID string, vote *Vote) error { 69 useChainID := chainID 70 if pv.breakVoteSigning { 71 useChainID = "incorrect-chain-id" 72 } 73 signBytes := vote.SignBytes(useChainID) 74 sig, err := pv.privKey.Sign(signBytes) 75 if err != nil { 76 return err 77 } 78 vote.Signature = sig 79 return nil 80 } 81 82 // Implements PrivValidator. 83 func (pv *MockPV) SignProposal(chainID string, proposal *Proposal) error { 84 useChainID := chainID 85 if pv.breakProposalSigning { 86 useChainID = "incorrect-chain-id" 87 } 88 signBytes := proposal.SignBytes(useChainID) 89 sig, err := pv.privKey.Sign(signBytes) 90 if err != nil { 91 return err 92 } 93 proposal.Signature = sig 94 return nil 95 } 96 97 // String returns a string representation of the MockPV. 98 func (pv *MockPV) String() string { 99 addr := pv.GetPubKey().Address() 100 return fmt.Sprintf("MockPV{%v}", addr) 101 } 102 103 // XXX: Implement. 104 func (pv *MockPV) DisableChecks() { 105 // Currently this does nothing, 106 // as MockPV has no safety checks at all. 107 } 108 109 type erroringMockPV struct { 110 *MockPV 111 } 112 113 var ErroringMockPVErr = errors.New("erroringMockPV always returns an error") 114 115 // Implements PrivValidator. 116 func (pv *erroringMockPV) SignVote(chainID string, vote *Vote) error { 117 return ErroringMockPVErr 118 } 119 120 // Implements PrivValidator. 121 func (pv *erroringMockPV) SignProposal(chainID string, proposal *Proposal) error { 122 return ErroringMockPVErr 123 } 124 125 // NewErroringMockPV returns a MockPV that fails on each signing request. Again, for testing only. 126 func NewErroringMockPV() *erroringMockPV { 127 return &erroringMockPV{&MockPV{ed25519.GenPrivKey(), false, false}} 128 }