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