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