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  }