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