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  }