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  }