From fd1b0b997a38e764345d8abc2b3c748c6bf9c688 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 18 Sep 2017 18:12:31 -0400 Subject: [PATCH] PrivValidator interface --- cmd/tendermint/commands/init.go | 2 +- .../commands/reset_priv_validator.go | 2 +- cmd/tendermint/commands/run_node.go | 4 +- cmd/tendermint/commands/testnet.go | 2 +- consensus/state.go | 24 +-- node/node.go | 14 +- types/priv_validator.go | 179 ++++++++++-------- types/priv_validator_test.go | 37 ++-- types/proposal_test.go | 6 +- types/validator.go | 4 +- types/validator_set.go | 4 +- types/vote_set_test.go | 60 +++--- 12 files changed, 178 insertions(+), 160 deletions(-) diff --git a/cmd/tendermint/commands/init.go b/cmd/tendermint/commands/init.go index 5e973335..25964504 100644 --- a/cmd/tendermint/commands/init.go +++ b/cmd/tendermint/commands/init.go @@ -30,7 +30,7 @@ func initFiles(cmd *cobra.Command, args []string) { ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)), } genDoc.Validators = []types.GenesisValidator{types.GenesisValidator{ - PubKey: privValidator.PubKey, + PubKey: privValidator.PubKey(), Power: 10, }} diff --git a/cmd/tendermint/commands/reset_priv_validator.go b/cmd/tendermint/commands/reset_priv_validator.go index 7f01c231..bedd3892 100644 --- a/cmd/tendermint/commands/reset_priv_validator.go +++ b/cmd/tendermint/commands/reset_priv_validator.go @@ -46,7 +46,7 @@ func resetPrivValidator(cmd *cobra.Command, args []string) { func resetPrivValidatorLocal(privValFile string, logger log.Logger) { // Get PrivValidator - var privValidator *types.PrivValidator + var privValidator types.PrivValidator if _, err := os.Stat(privValFile); err == nil { privValidator = types.LoadPrivValidator(privValFile) privValidator.Reset() diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go index b9d23a27..883ec6ec 100644 --- a/cmd/tendermint/commands/run_node.go +++ b/cmd/tendermint/commands/run_node.go @@ -41,9 +41,9 @@ func AddNodeFlags(cmd *cobra.Command) { // FuncSignerAndApp takes a config and returns a PrivValidator and ClientCreator. // It allows other projects to make Tendermint binaries with custom signers and applications. -type FuncSignerAndApp func(*cfg.Config) (*types.PrivValidator, proxy.ClientCreator) +type FuncSignerAndApp func(*cfg.Config) (types.PrivValidator, proxy.ClientCreator) -func DefaultSignerAndApp(config *cfg.Config) (*types.PrivValidator, proxy.ClientCreator) { +func DefaultSignerAndApp(config *cfg.Config) (types.PrivValidator, proxy.ClientCreator) { privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile()) clientCreator := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()) return privValidator, clientCreator diff --git a/cmd/tendermint/commands/testnet.go b/cmd/tendermint/commands/testnet.go index 617b6659..9412379a 100644 --- a/cmd/tendermint/commands/testnet.go +++ b/cmd/tendermint/commands/testnet.go @@ -47,7 +47,7 @@ func testnetFiles(cmd *cobra.Command, args []string) { privValFile := path.Join(dataDir, mach, "priv_validator.json") privVal := types.LoadPrivValidator(privValFile) genVals[i] = types.GenesisValidator{ - PubKey: privVal.PubKey, + PubKey: privVal.PubKey(), Power: 1, Name: mach, } diff --git a/consensus/state.go b/consensus/state.go index ac165620..f141cad5 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -180,14 +180,6 @@ func (ti *timeoutInfo) String() string { return fmt.Sprintf("%v ; %d/%d %v", ti.Duration, ti.Height, ti.Round, ti.Step) } -// PrivValidator is a validator that can sign votes and proposals. -type PrivValidator interface { - GetAddress() []byte - SignVote(chainID string, vote *types.Vote) error - SignProposal(chainID string, proposal *types.Proposal) error - SignHeartbeat(chainID string, heartbeat *types.Heartbeat) error -} - // ConsensusState handles execution of the consensus algorithm. // It processes votes and proposals, and upon reaching agreement, // commits blocks to the chain and executes them against the application. @@ -197,7 +189,7 @@ type ConsensusState struct { // config details config *cfg.ConsensusConfig - privValidator PrivValidator // for signing votes + privValidator types.PrivValidator // for signing votes // services for creating and executing blocks proxyAppConn proxy.AppConnConsensus @@ -308,7 +300,7 @@ func (cs *ConsensusState) GetValidators() (int, []*types.Validator) { } // SetPrivValidator sets the private validator account for signing votes. -func (cs *ConsensusState) SetPrivValidator(priv PrivValidator) { +func (cs *ConsensusState) SetPrivValidator(priv types.PrivValidator) { cs.mtx.Lock() defer cs.mtx.Unlock() cs.privValidator = priv @@ -825,7 +817,7 @@ func (cs *ConsensusState) needProofBlock(height int) bool { func (cs *ConsensusState) proposalHeartbeat(height, round int) { counter := 0 - addr := cs.privValidator.GetAddress() + addr := cs.privValidator.Address() valIndex, v := cs.Validators.GetByAddress(addr) if v == nil { // not a validator @@ -886,7 +878,7 @@ func (cs *ConsensusState) enterPropose(height int, round int) { if !cs.isProposer() { cs.Logger.Info("enterPropose: Not our turn to propose", "proposer", cs.Validators.GetProposer().Address, "privValidator", cs.privValidator) - if cs.Validators.HasAddress(cs.privValidator.GetAddress()) { + if cs.Validators.HasAddress(cs.privValidator.Address()) { cs.Logger.Debug("This node is a validator") } else { cs.Logger.Debug("This node is not a validator") @@ -899,7 +891,7 @@ func (cs *ConsensusState) enterPropose(height int, round int) { } func (cs *ConsensusState) isProposer() bool { - return bytes.Equal(cs.Validators.GetProposer().Address, cs.privValidator.GetAddress()) + return bytes.Equal(cs.Validators.GetProposer().Address, cs.privValidator.Address()) } func (cs *ConsensusState) defaultDecideProposal(height, round int) { @@ -1444,7 +1436,7 @@ func (cs *ConsensusState) tryAddVote(vote *types.Vote, peerKey string) error { if err == ErrVoteHeightMismatch { return err } else if _, ok := err.(*types.ErrVoteConflictingVotes); ok { - if bytes.Equal(vote.ValidatorAddress, cs.privValidator.GetAddress()) { + if bytes.Equal(vote.ValidatorAddress, cs.privValidator.Address()) { cs.Logger.Error("Found conflicting vote from ourselves. Did you unsafe_reset a validator?", "height", vote.Height, "round", vote.Round, "type", vote.Type) return err } @@ -1573,7 +1565,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerKey string) (added bool, } func (cs *ConsensusState) signVote(type_ byte, hash []byte, header types.PartSetHeader) (*types.Vote, error) { - addr := cs.privValidator.GetAddress() + addr := cs.privValidator.Address() valIndex, _ := cs.Validators.GetByAddress(addr) vote := &types.Vote{ ValidatorAddress: addr, @@ -1590,7 +1582,7 @@ func (cs *ConsensusState) signVote(type_ byte, hash []byte, header types.PartSet // sign the vote and publish on internalMsgQueue func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.PartSetHeader) *types.Vote { // if we don't have a key or we're not in the validator set, do nothing - if cs.privValidator == nil || !cs.Validators.HasAddress(cs.privValidator.GetAddress()) { + if cs.privValidator == nil || !cs.Validators.HasAddress(cs.privValidator.Address()) { return nil } vote, err := cs.signVote(type_, hash, header) diff --git a/node/node.go b/node/node.go index e831ba1d..a0a8c529 100644 --- a/node/node.go +++ b/node/node.go @@ -38,8 +38,8 @@ type Node struct { // config config *cfg.Config - genesisDoc *types.GenesisDoc // initial validator set - privValidator *types.PrivValidator // local node's validator key + genesisDoc *types.GenesisDoc // initial validator set + privValidator types.PrivValidator // local node's validator key // network privKey crypto.PrivKeyEd25519 // local node's p2p key @@ -65,7 +65,7 @@ func NewNodeDefault(config *cfg.Config, logger log.Logger) *Node { proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), logger) } -func NewNode(config *cfg.Config, privValidator *types.PrivValidator, clientCreator proxy.ClientCreator, logger log.Logger) *Node { +func NewNode(config *cfg.Config, privValidator types.PrivValidator, clientCreator proxy.ClientCreator, logger log.Logger) *Node { // Get BlockStore blockStoreDB := dbm.NewDB("blockstore", config.DBBackend, config.DBDir()) blockStore := bc.NewBlockStore(blockStoreDB) @@ -119,13 +119,13 @@ func NewNode(config *cfg.Config, privValidator *types.PrivValidator, clientCreat fastSync := config.FastSync if state.Validators.Size() == 1 { addr, _ := state.Validators.GetByIndex(0) - if bytes.Equal(privValidator.Address, addr) { + if bytes.Equal(privValidator.Address(), addr) { fastSync = false } } // Log whether this node is a validator or an observer - if state.Validators.HasAddress(privValidator.Address) { + if state.Validators.HasAddress(privValidator.PubKey().Address()) { consensusLogger.Info("This node is a validator") } else { consensusLogger.Info("This node is not a validator") @@ -314,7 +314,7 @@ func (n *Node) ConfigureRPC() { rpccore.SetConsensusState(n.consensusState) rpccore.SetMempool(n.mempoolReactor.Mempool) rpccore.SetSwitch(n.sw) - rpccore.SetPubKey(n.privValidator.PubKey) + rpccore.SetPubKey(n.privValidator.PubKey()) rpccore.SetGenesisDoc(n.genesisDoc) rpccore.SetAddrBook(n.addrBook) rpccore.SetProxyAppQuery(n.proxyApp.Query()) @@ -385,7 +385,7 @@ func (n *Node) EventSwitch() types.EventSwitch { } // XXX: for convenience -func (n *Node) PrivValidator() *types.PrivValidator { +func (n *Node) PrivValidator() types.PrivValidator { return n.privValidator } diff --git a/types/priv_validator.go b/types/priv_validator.go index 72d05c49..e8fb3e24 100644 --- a/types/priv_validator.go +++ b/types/priv_validator.go @@ -46,38 +46,43 @@ type Signer interface { // DefaultSigner implements Signer. // It uses a standard crypto.PrivKey. type DefaultSigner struct { - priv crypto.PrivKey + PrivKey crypto.PrivKey `json:"priv_key"` } // NewDefaultSigner returns an instance of DefaultSigner. func NewDefaultSigner(priv crypto.PrivKey) *DefaultSigner { - return &DefaultSigner{priv: priv} + return &DefaultSigner{PrivKey: priv} } // Sign implements Signer. It signs the byte slice with a private key. func (ds *DefaultSigner) Sign(msg []byte) (crypto.Signature, error) { - return ds.priv.Sign(msg), nil + return ds.PrivKey.Sign(msg), nil } // PubKey implements Signer. It should return the public key that corresponds // to the private key used for signing. func (ds *DefaultSigner) PubKey() crypto.PubKey { - return ds.priv.PubKey() + return ds.PrivKey.PubKey() } -// PrivValidator implements the functionality for signing blocks. -type PrivValidator struct { - Address data.Bytes `json:"address"` - PubKey crypto.PubKey `json:"pub_key"` - LastHeight int `json:"last_height"` - LastRound int `json:"last_round"` - LastStep int8 `json:"last_step"` - LastSignature crypto.Signature `json:"last_signature,omitempty"` // so we dont lose signatures - LastSignBytes data.Bytes `json:"last_signbytes,omitempty"` // so we dont lose signatures +type PrivValidator interface { + Address() data.Bytes // redundant since .PubKey().Address() + PubKey() crypto.PubKey - // PrivKey should be empty if a Signer other than the default is being used. - PrivKey crypto.PrivKey `json:"priv_key"` - Signer `json:"-"` + SignVote(chainID string, vote *Vote) error + SignProposal(chainID string, proposal *Proposal) error + SignHeartbeat(chainID string, heartbeat *Heartbeat) error + + Reset() + + SetFile(file string) + Save() +} + +// DefaultPrivValidator implements the functionality for signing blocks. +type DefaultPrivValidator struct { + Info PrivValidatorInfo `json:"info"` + Signer *DefaultSigner `json:"signer"` // For persistence. // Overloaded for testing. @@ -85,8 +90,26 @@ type PrivValidator struct { mtx sync.Mutex } -func LoadOrGenPrivValidator(filePath string) *PrivValidator { - var privValidator *PrivValidator +func (pv *DefaultPrivValidator) Address() data.Bytes { + return pv.Info.Address +} + +func (pv *DefaultPrivValidator) PubKey() crypto.PubKey { + return pv.Info.PubKey +} + +type PrivValidatorInfo struct { + Address data.Bytes `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` + LastHeight int `json:"last_height"` + LastRound int `json:"last_round"` + LastStep int8 `json:"last_step"` + LastSignature crypto.Signature `json:"last_signature,omitempty"` // so we dont lose signatures + LastSignBytes data.Bytes `json:"last_signbytes,omitempty"` // so we dont lose signatures +} + +func LoadOrGenPrivValidator(filePath string) *DefaultPrivValidator { + var privValidator *DefaultPrivValidator if _, err := os.Stat(filePath); err == nil { privValidator = LoadPrivValidator(filePath) } else { @@ -97,34 +120,33 @@ func LoadOrGenPrivValidator(filePath string) *PrivValidator { return privValidator } -func LoadPrivValidator(filePath string) *PrivValidator { +func LoadPrivValidator(filePath string) *DefaultPrivValidator { privValJSONBytes, err := ioutil.ReadFile(filePath) if err != nil { Exit(err.Error()) } - privVal := PrivValidator{} + privVal := DefaultPrivValidator{} err = json.Unmarshal(privValJSONBytes, &privVal) if err != nil { Exit(Fmt("Error reading PrivValidator from %v: %v\n", filePath, err)) } privVal.filePath = filePath - privVal.Signer = NewDefaultSigner(privVal.PrivKey) - privVal.setPubKeyAndAddress() return &privVal } // Generates a new validator with private key. -func GenPrivValidator() *PrivValidator { +func GenPrivValidator() *DefaultPrivValidator { privKey := crypto.GenPrivKeyEd25519().Wrap() pubKey := privKey.PubKey() - return &PrivValidator{ - Address: pubKey.Address(), - PubKey: pubKey, - PrivKey: privKey, - LastStep: stepNone, - filePath: "", + return &DefaultPrivValidator{ + Info: PrivValidatorInfo{ + Address: pubKey.Address(), + PubKey: pubKey, + LastStep: stepNone, + }, Signer: NewDefaultSigner(privKey), + filePath: "", } } @@ -132,40 +154,37 @@ func GenPrivValidator() *PrivValidator { // signer object. Tendermint tracks state in the PrivValidator that might be // saved to disk. Please supply a filepath where Tendermint can save the // private validator. -func LoadPrivValidatorWithSigner(signer Signer, filePath string) *PrivValidator { - return &PrivValidator{ - Address: signer.PubKey().Address(), - PubKey: signer.PubKey(), - LastStep: stepNone, - filePath: filePath, +func LoadPrivValidatorWithSigner(signer *DefaultSigner, filePath string) *DefaultPrivValidator { + return &DefaultPrivValidator{ + Info: PrivValidatorInfo{ + Address: signer.PubKey().Address(), + PubKey: signer.PubKey(), + LastStep: stepNone, + }, Signer: signer, + filePath: filePath, } } -func (privVal *PrivValidator) SetSigner(s Signer) { - privVal.Signer = s - privVal.setPubKeyAndAddress() -} - // Overwrite address and pubkey for convenience -func (privVal *PrivValidator) setPubKeyAndAddress() { +/*func (privVal *DefaultPrivValidator) setPubKeyAndAddress() { privVal.PubKey = privVal.Signer.PubKey() privVal.Address = privVal.PubKey.Address() -} +}*/ -func (privVal *PrivValidator) SetFile(filePath string) { +func (privVal *DefaultPrivValidator) SetFile(filePath string) { privVal.mtx.Lock() defer privVal.mtx.Unlock() privVal.filePath = filePath } -func (privVal *PrivValidator) Save() { +func (privVal *DefaultPrivValidator) Save() { privVal.mtx.Lock() defer privVal.mtx.Unlock() privVal.save() } -func (privVal *PrivValidator) save() { +func (privVal *DefaultPrivValidator) save() { if privVal.filePath == "" { PanicSanity("Cannot save PrivValidator: filePath not set") } @@ -182,20 +201,20 @@ func (privVal *PrivValidator) save() { } // NOTE: Unsafe! -func (privVal *PrivValidator) Reset() { - privVal.LastHeight = 0 - privVal.LastRound = 0 - privVal.LastStep = 0 - privVal.LastSignature = crypto.Signature{} - privVal.LastSignBytes = nil +func (privVal *DefaultPrivValidator) Reset() { + privVal.Info.LastHeight = 0 + privVal.Info.LastRound = 0 + privVal.Info.LastStep = 0 + privVal.Info.LastSignature = crypto.Signature{} + privVal.Info.LastSignBytes = nil privVal.Save() } -func (privVal *PrivValidator) GetAddress() []byte { - return privVal.Address +func (privVal *DefaultPrivValidator) GetAddress() []byte { + return privVal.Address() } -func (privVal *PrivValidator) SignVote(chainID string, vote *Vote) error { +func (privVal *DefaultPrivValidator) SignVote(chainID string, vote *Vote) error { privVal.mtx.Lock() defer privVal.mtx.Unlock() signature, err := privVal.signBytesHRS(vote.Height, vote.Round, voteToStep(vote), SignBytes(chainID, vote)) @@ -206,7 +225,7 @@ func (privVal *PrivValidator) SignVote(chainID string, vote *Vote) error { return nil } -func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) error { +func (privVal *DefaultPrivValidator) SignProposal(chainID string, proposal *Proposal) error { privVal.mtx.Lock() defer privVal.mtx.Unlock() signature, err := privVal.signBytesHRS(proposal.Height, proposal.Round, stepPropose, SignBytes(chainID, proposal)) @@ -218,33 +237,34 @@ func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) e } // check if there's a regression. Else sign and write the hrs+signature to disk -func (privVal *PrivValidator) signBytesHRS(height, round int, step int8, signBytes []byte) (crypto.Signature, error) { +func (privVal *DefaultPrivValidator) signBytesHRS(height, round int, step int8, signBytes []byte) (crypto.Signature, error) { sig := crypto.Signature{} + info := privVal.Info // If height regression, err - if privVal.LastHeight > height { + if info.LastHeight > height { return sig, errors.New("Height regression") } // More cases for when the height matches - if privVal.LastHeight == height { + if info.LastHeight == height { // If round regression, err - if privVal.LastRound > round { + if info.LastRound > round { return sig, errors.New("Round regression") } // If step regression, err - if privVal.LastRound == round { - if privVal.LastStep > step { + if info.LastRound == round { + if info.LastStep > step { return sig, errors.New("Step regression") - } else if privVal.LastStep == step { - if privVal.LastSignBytes != nil { - if privVal.LastSignature.Empty() { + } else if info.LastStep == step { + if info.LastSignBytes != nil { + if info.LastSignature.Empty() { PanicSanity("privVal: LastSignature is nil but LastSignBytes is not!") } // so we dont sign a conflicting vote or proposal // NOTE: proposals are non-deterministic (include time), // so we can actually lose them, but will still never sign conflicting ones - if bytes.Equal(privVal.LastSignBytes, signBytes) { - // log.Notice("Using privVal.LastSignature", "sig", privVal.LastSignature) - return privVal.LastSignature, nil + if bytes.Equal(info.LastSignBytes, signBytes) { + // log.Notice("Using info.LastSignature", "sig", info.LastSignature) + return info.LastSignature, nil } } return sig, errors.New("Step regression") @@ -253,45 +273,46 @@ func (privVal *PrivValidator) signBytesHRS(height, round int, step int8, signByt } // Sign - sig, err := privVal.Sign(signBytes) + sig, err := privVal.Signer.Sign(signBytes) if err != nil { return sig, err } // Persist height/round/step - privVal.LastHeight = height - privVal.LastRound = round - privVal.LastStep = step - privVal.LastSignature = sig - privVal.LastSignBytes = signBytes + privVal.Info.LastHeight = height + privVal.Info.LastRound = round + privVal.Info.LastStep = step + privVal.Info.LastSignature = sig + privVal.Info.LastSignBytes = signBytes privVal.save() return sig, nil } -func (privVal *PrivValidator) SignHeartbeat(chainID string, heartbeat *Heartbeat) error { +func (privVal *DefaultPrivValidator) SignHeartbeat(chainID string, heartbeat *Heartbeat) error { privVal.mtx.Lock() defer privVal.mtx.Unlock() var err error - heartbeat.Signature, err = privVal.Sign(SignBytes(chainID, heartbeat)) + heartbeat.Signature, err = privVal.Signer.Sign(SignBytes(chainID, heartbeat)) return err } -func (privVal *PrivValidator) String() string { - return fmt.Sprintf("PrivValidator{%v LH:%v, LR:%v, LS:%v}", privVal.Address, privVal.LastHeight, privVal.LastRound, privVal.LastStep) +func (privVal *DefaultPrivValidator) String() string { + info := privVal.Info + return fmt.Sprintf("PrivValidator{%v LH:%v, LR:%v, LS:%v}", info.Address, info.LastHeight, info.LastRound, info.LastStep) } //------------------------------------- -type PrivValidatorsByAddress []*PrivValidator +type PrivValidatorsByAddress []*DefaultPrivValidator func (pvs PrivValidatorsByAddress) Len() int { return len(pvs) } func (pvs PrivValidatorsByAddress) Less(i, j int) bool { - return bytes.Compare(pvs[i].Address, pvs[j].Address) == -1 + return bytes.Compare(pvs[i].Info.Address, pvs[j].Info.Address) == -1 } func (pvs PrivValidatorsByAddress) Swap(i, j int) { diff --git a/types/priv_validator_test.go b/types/priv_validator_test.go index 1eb0b57d..d0fcfd18 100644 --- a/types/priv_validator_test.go +++ b/types/priv_validator_test.go @@ -29,29 +29,34 @@ func TestLoadValidator(t *testing.T) { require.Nil(err, "%+v", err) serialized := fmt.Sprintf(`{ - "address": "%s", - "pub_key": { - "type": "ed25519", - "data": "%s" + "info": { + "address": "%s", + "pub_key": { + "type": "ed25519", + "data": "%s" + }, + "last_height": 0, + "last_round": 0, + "last_step": 0, + "last_signature": null }, - "priv_key": { - "type": "ed25519", - "data": "%s" - }, - "last_height": 0, - "last_round": 0, - "last_step": 0, - "last_signature": null + "signer": { + "priv_key": { + "type": "ed25519", + "data": "%s" + } + } }`, addrStr, pubStr, privStr) - val := PrivValidator{} + val := DefaultPrivValidator{} err = json.Unmarshal([]byte(serialized), &val) require.Nil(err, "%+v", err) // make sure the values match - assert.EqualValues(addrBytes, val.Address) - assert.EqualValues(pubKey, val.PubKey) - assert.EqualValues(privKey, val.PrivKey) + assert.EqualValues(addrBytes, val.Address()) + assert.EqualValues(pubKey, val.PubKey()) + valPrivKey := val.Signer.PrivKey + assert.EqualValues(privKey, valPrivKey) // export it and make sure it is the same out, err := json.Marshal(val) diff --git a/types/proposal_test.go b/types/proposal_test.go index 6f618959..ce1bbc8d 100644 --- a/types/proposal_test.go +++ b/types/proposal_test.go @@ -30,15 +30,15 @@ func BenchmarkProposalWriteSignBytes(b *testing.B) { func BenchmarkProposalSign(b *testing.B) { privVal := GenPrivValidator() for i := 0; i < b.N; i++ { - privVal.Sign(SignBytes("test_chain_id", testProposal)) + privVal.Signer.Sign(SignBytes("test_chain_id", testProposal)) } } func BenchmarkProposalVerifySignature(b *testing.B) { signBytes := SignBytes("test_chain_id", testProposal) privVal := GenPrivValidator() - signature, _ := privVal.Sign(signBytes) - pubKey := privVal.PubKey + signature, _ := privVal.Signer.Sign(signBytes) + pubKey := privVal.PubKey() for i := 0; i < b.N; i++ { pubKey.VerifyBytes(SignBytes("test_chain_id", testProposal), signature) diff --git a/types/validator.go b/types/validator.go index 24f8974f..29cbfea2 100644 --- a/types/validator.go +++ b/types/validator.go @@ -106,7 +106,7 @@ func (vc validatorCodec) Compare(o1 interface{}, o2 interface{}) int { //-------------------------------------------------------------------------------- // For testing... -func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidator) { +func RandValidator(randPower bool, minPower int64) (*Validator, *DefaultPrivValidator) { privVal := GenPrivValidator() _, tempFilePath := cmn.Tempfile("priv_validator_") privVal.SetFile(tempFilePath) @@ -114,6 +114,6 @@ func RandValidator(randPower bool, minPower int64) (*Validator, *PrivValidator) if randPower { votePower += int64(cmn.RandUint32()) } - val := NewValidator(privVal.PubKey, votePower) + val := NewValidator(privVal.PubKey(), votePower) return val, privVal } diff --git a/types/validator_set.go b/types/validator_set.go index e334ed9f..5531f4af 100644 --- a/types/validator_set.go +++ b/types/validator_set.go @@ -369,9 +369,9 @@ func (ac accumComparable) Less(o interface{}) bool { // For testing // NOTE: PrivValidator are in order. -func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []*PrivValidator) { +func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []*DefaultPrivValidator) { vals := make([]*Validator, numValidators) - privValidators := make([]*PrivValidator, numValidators) + privValidators := make([]*DefaultPrivValidator, numValidators) for i := 0; i < numValidators; i++ { val, privValidator := RandValidator(false, votingPower) vals[i] = val diff --git a/types/vote_set_test.go b/types/vote_set_test.go index ddc05548..716becf5 100644 --- a/types/vote_set_test.go +++ b/types/vote_set_test.go @@ -11,7 +11,7 @@ import ( ) // NOTE: privValidators are in order -func randVoteSet(height int, round int, type_ byte, numValidators int, votingPower int64) (*VoteSet, *ValidatorSet, []*PrivValidator) { +func randVoteSet(height int, round int, type_ byte, numValidators int, votingPower int64) (*VoteSet, *ValidatorSet, []*DefaultPrivValidator) { valSet, privValidators := RandValidatorSet(numValidators, votingPower) return NewVoteSet("test_chain_id", height, round, type_, valSet), valSet, privValidators } @@ -59,9 +59,9 @@ func withBlockPartsHeader(vote *Vote, blockPartsHeader PartSetHeader) *Vote { return vote } -func signAddVote(privVal *PrivValidator, vote *Vote, voteSet *VoteSet) (bool, error) { +func signAddVote(privVal *DefaultPrivValidator, vote *Vote, voteSet *VoteSet) (bool, error) { var err error - vote.Signature, err = privVal.Sign(SignBytes(voteSet.ChainID(), vote)) + vote.Signature, err = privVal.Signer.Sign(SignBytes(voteSet.ChainID(), vote)) if err != nil { return false, err } @@ -76,7 +76,7 @@ func TestAddVote(t *testing.T) { // t.Logf(">> %v", voteSet) - if voteSet.GetByAddress(val0.Address) != nil { + if voteSet.GetByAddress(val0.Address()) != nil { t.Errorf("Expected GetByAddress(val0.Address) to be nil") } if voteSet.BitArray().GetIndex(0) { @@ -88,7 +88,7 @@ func TestAddVote(t *testing.T) { } vote := &Vote{ - ValidatorAddress: val0.Address, + ValidatorAddress: val0.Address(), ValidatorIndex: 0, // since privValidators are in order Height: height, Round: round, @@ -100,7 +100,7 @@ func TestAddVote(t *testing.T) { t.Error(err) } - if voteSet.GetByAddress(val0.Address) == nil { + if voteSet.GetByAddress(val0.Address()) == nil { t.Errorf("Expected GetByAddress(val0.Address) to be present") } if !voteSet.BitArray().GetIndex(0) { @@ -126,7 +126,7 @@ func Test2_3Majority(t *testing.T) { } // 6 out of 10 voted for nil. for i := 0; i < 6; i++ { - vote := withValidator(voteProto, privValidators[i].Address, i) + vote := withValidator(voteProto, privValidators[i].Address(), i) signAddVote(privValidators[i], vote, voteSet) } blockID, ok := voteSet.TwoThirdsMajority() @@ -136,7 +136,7 @@ func Test2_3Majority(t *testing.T) { // 7th validator voted for some blockhash { - vote := withValidator(voteProto, privValidators[6].Address, 6) + vote := withValidator(voteProto, privValidators[6].Address(), 6) signAddVote(privValidators[6], withBlockHash(vote, RandBytes(32)), voteSet) blockID, ok = voteSet.TwoThirdsMajority() if ok || !blockID.IsZero() { @@ -146,7 +146,7 @@ func Test2_3Majority(t *testing.T) { // 8th validator voted for nil. { - vote := withValidator(voteProto, privValidators[7].Address, 7) + vote := withValidator(voteProto, privValidators[7].Address(), 7) signAddVote(privValidators[7], vote, voteSet) blockID, ok = voteSet.TwoThirdsMajority() if !ok || !blockID.IsZero() { @@ -174,7 +174,7 @@ func Test2_3MajorityRedux(t *testing.T) { // 66 out of 100 voted for nil. for i := 0; i < 66; i++ { - vote := withValidator(voteProto, privValidators[i].Address, i) + vote := withValidator(voteProto, privValidators[i].Address(), i) signAddVote(privValidators[i], vote, voteSet) } blockID, ok := voteSet.TwoThirdsMajority() @@ -184,7 +184,7 @@ func Test2_3MajorityRedux(t *testing.T) { // 67th validator voted for nil { - vote := withValidator(voteProto, privValidators[66].Address, 66) + vote := withValidator(voteProto, privValidators[66].Address(), 66) signAddVote(privValidators[66], withBlockHash(vote, nil), voteSet) blockID, ok = voteSet.TwoThirdsMajority() if ok || !blockID.IsZero() { @@ -194,7 +194,7 @@ func Test2_3MajorityRedux(t *testing.T) { // 68th validator voted for a different BlockParts PartSetHeader { - vote := withValidator(voteProto, privValidators[67].Address, 67) + vote := withValidator(voteProto, privValidators[67].Address(), 67) blockPartsHeader := PartSetHeader{blockPartsTotal, crypto.CRandBytes(32)} signAddVote(privValidators[67], withBlockPartsHeader(vote, blockPartsHeader), voteSet) blockID, ok = voteSet.TwoThirdsMajority() @@ -205,7 +205,7 @@ func Test2_3MajorityRedux(t *testing.T) { // 69th validator voted for different BlockParts Total { - vote := withValidator(voteProto, privValidators[68].Address, 68) + vote := withValidator(voteProto, privValidators[68].Address(), 68) blockPartsHeader := PartSetHeader{blockPartsTotal + 1, blockPartsHeader.Hash} signAddVote(privValidators[68], withBlockPartsHeader(vote, blockPartsHeader), voteSet) blockID, ok = voteSet.TwoThirdsMajority() @@ -216,7 +216,7 @@ func Test2_3MajorityRedux(t *testing.T) { // 70th validator voted for different BlockHash { - vote := withValidator(voteProto, privValidators[69].Address, 69) + vote := withValidator(voteProto, privValidators[69].Address(), 69) signAddVote(privValidators[69], withBlockHash(vote, RandBytes(32)), voteSet) blockID, ok = voteSet.TwoThirdsMajority() if ok || !blockID.IsZero() { @@ -226,7 +226,7 @@ func Test2_3MajorityRedux(t *testing.T) { // 71st validator voted for the right BlockHash & BlockPartsHeader { - vote := withValidator(voteProto, privValidators[70].Address, 70) + vote := withValidator(voteProto, privValidators[70].Address(), 70) signAddVote(privValidators[70], vote, voteSet) blockID, ok = voteSet.TwoThirdsMajority() if !ok || !blockID.Equals(BlockID{blockHash, blockPartsHeader}) { @@ -250,7 +250,7 @@ func TestBadVotes(t *testing.T) { // val0 votes for nil. { - vote := withValidator(voteProto, privValidators[0].Address, 0) + vote := withValidator(voteProto, privValidators[0].Address(), 0) added, err := signAddVote(privValidators[0], vote, voteSet) if !added || err != nil { t.Errorf("Expected VoteSet.Add to succeed") @@ -259,7 +259,7 @@ func TestBadVotes(t *testing.T) { // val0 votes again for some block. { - vote := withValidator(voteProto, privValidators[0].Address, 0) + vote := withValidator(voteProto, privValidators[0].Address(), 0) added, err := signAddVote(privValidators[0], withBlockHash(vote, RandBytes(32)), voteSet) if added || err == nil { t.Errorf("Expected VoteSet.Add to fail, conflicting vote.") @@ -268,7 +268,7 @@ func TestBadVotes(t *testing.T) { // val1 votes on another height { - vote := withValidator(voteProto, privValidators[1].Address, 1) + vote := withValidator(voteProto, privValidators[1].Address(), 1) added, err := signAddVote(privValidators[1], withHeight(vote, height+1), voteSet) if added || err == nil { t.Errorf("Expected VoteSet.Add to fail, wrong height") @@ -277,7 +277,7 @@ func TestBadVotes(t *testing.T) { // val2 votes on another round { - vote := withValidator(voteProto, privValidators[2].Address, 2) + vote := withValidator(voteProto, privValidators[2].Address(), 2) added, err := signAddVote(privValidators[2], withRound(vote, round+1), voteSet) if added || err == nil { t.Errorf("Expected VoteSet.Add to fail, wrong round") @@ -286,7 +286,7 @@ func TestBadVotes(t *testing.T) { // val3 votes of another type. { - vote := withValidator(voteProto, privValidators[3].Address, 3) + vote := withValidator(voteProto, privValidators[3].Address(), 3) added, err := signAddVote(privValidators[3], withType(vote, VoteTypePrecommit), voteSet) if added || err == nil { t.Errorf("Expected VoteSet.Add to fail, wrong type") @@ -311,7 +311,7 @@ func TestConflicts(t *testing.T) { // val0 votes for nil. { - vote := withValidator(voteProto, privValidators[0].Address, 0) + vote := withValidator(voteProto, privValidators[0].Address(), 0) added, err := signAddVote(privValidators[0], vote, voteSet) if !added || err != nil { t.Errorf("Expected VoteSet.Add to succeed") @@ -320,7 +320,7 @@ func TestConflicts(t *testing.T) { // val0 votes again for blockHash1. { - vote := withValidator(voteProto, privValidators[0].Address, 0) + vote := withValidator(voteProto, privValidators[0].Address(), 0) added, err := signAddVote(privValidators[0], withBlockHash(vote, blockHash1), voteSet) if added { t.Errorf("Expected VoteSet.Add to fail, conflicting vote.") @@ -335,7 +335,7 @@ func TestConflicts(t *testing.T) { // val0 votes again for blockHash1. { - vote := withValidator(voteProto, privValidators[0].Address, 0) + vote := withValidator(voteProto, privValidators[0].Address(), 0) added, err := signAddVote(privValidators[0], withBlockHash(vote, blockHash1), voteSet) if !added { t.Errorf("Expected VoteSet.Add to succeed, called SetPeerMaj23().") @@ -350,7 +350,7 @@ func TestConflicts(t *testing.T) { // val0 votes again for blockHash1. { - vote := withValidator(voteProto, privValidators[0].Address, 0) + vote := withValidator(voteProto, privValidators[0].Address(), 0) added, err := signAddVote(privValidators[0], withBlockHash(vote, blockHash2), voteSet) if added { t.Errorf("Expected VoteSet.Add to fail, duplicate SetPeerMaj23() from peerA") @@ -362,7 +362,7 @@ func TestConflicts(t *testing.T) { // val1 votes for blockHash1. { - vote := withValidator(voteProto, privValidators[1].Address, 1) + vote := withValidator(voteProto, privValidators[1].Address(), 1) added, err := signAddVote(privValidators[1], withBlockHash(vote, blockHash1), voteSet) if !added || err != nil { t.Errorf("Expected VoteSet.Add to succeed") @@ -379,7 +379,7 @@ func TestConflicts(t *testing.T) { // val2 votes for blockHash2. { - vote := withValidator(voteProto, privValidators[2].Address, 2) + vote := withValidator(voteProto, privValidators[2].Address(), 2) added, err := signAddVote(privValidators[2], withBlockHash(vote, blockHash2), voteSet) if !added || err != nil { t.Errorf("Expected VoteSet.Add to succeed") @@ -399,7 +399,7 @@ func TestConflicts(t *testing.T) { // val2 votes for blockHash1. { - vote := withValidator(voteProto, privValidators[2].Address, 2) + vote := withValidator(voteProto, privValidators[2].Address(), 2) added, err := signAddVote(privValidators[2], withBlockHash(vote, blockHash1), voteSet) if !added { t.Errorf("Expected VoteSet.Add to succeed") @@ -439,7 +439,7 @@ func TestMakeCommit(t *testing.T) { // 6 out of 10 voted for some block. for i := 0; i < 6; i++ { - vote := withValidator(voteProto, privValidators[i].Address, i) + vote := withValidator(voteProto, privValidators[i].Address(), i) signAddVote(privValidators[i], vote, voteSet) } @@ -448,7 +448,7 @@ func TestMakeCommit(t *testing.T) { // 7th voted for some other block. { - vote := withValidator(voteProto, privValidators[6].Address, 6) + vote := withValidator(voteProto, privValidators[6].Address(), 6) vote = withBlockHash(vote, RandBytes(32)) vote = withBlockPartsHeader(vote, PartSetHeader{123, RandBytes(32)}) signAddVote(privValidators[6], vote, voteSet) @@ -456,7 +456,7 @@ func TestMakeCommit(t *testing.T) { // The 8th voted like everyone else. { - vote := withValidator(voteProto, privValidators[7].Address, 7) + vote := withValidator(voteProto, privValidators[7].Address(), 7) signAddVote(privValidators[7], vote, voteSet) }