From 403d24a4b24461cfbd72aaec5be09160f82a4dec Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Mon, 22 Dec 2014 18:49:37 -0800 Subject: [PATCH] generated privValidator for testing uses tmp files PrivValidator.Sign*() and .Save() lock on a mutex --- consensus/pol_test.go | 14 +++++++------- consensus/state_test.go | 8 ++++---- consensus/test.go | 18 +++++++++--------- consensus/vote_set_test.go | 12 ++++++------ state/priv_validator.go | 20 +++++++++++++++++--- 5 files changed, 43 insertions(+), 29 deletions(-) diff --git a/consensus/pol_test.go b/consensus/pol_test.go index 5f125a467..6c0f48178 100644 --- a/consensus/pol_test.go +++ b/consensus/pol_test.go @@ -23,7 +23,7 @@ func signAddPOLVoteSignature(val *state.PrivValidator, valSet *state.ValidatorSe func TestVerifyVotes(t *testing.T) { height, round := uint(1), uint(0) - _, valSet, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + _, valSet, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // Make a POL with -2/3 votes. blockHash := RandBytes(32) @@ -54,7 +54,7 @@ func TestVerifyVotes(t *testing.T) { func TestVerifyInvalidVote(t *testing.T) { height, round := uint(1), uint(0) - _, valSet, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + _, valSet, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // Make a POL with +2/3 votes with the wrong signature. blockHash := RandBytes(32) @@ -78,7 +78,7 @@ func TestVerifyInvalidVote(t *testing.T) { func TestVerifyCommits(t *testing.T) { height, round := uint(1), uint(2) - _, valSet, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + _, valSet, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // Make a POL with +2/3 votes. blockHash := RandBytes(32) @@ -101,7 +101,7 @@ func TestVerifyCommits(t *testing.T) { func TestVerifyInvalidCommits(t *testing.T) { height, round := uint(1), uint(2) - _, valSet, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + _, valSet, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // Make a POL with +2/3 votes with the wrong signature. blockHash := RandBytes(32) @@ -125,7 +125,7 @@ func TestVerifyInvalidCommits(t *testing.T) { func TestVerifyInvalidCommitRounds(t *testing.T) { height, round := uint(1), uint(2) - _, valSet, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + _, valSet, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // Make a POL with +2/3 commits for the current round. blockHash := RandBytes(32) @@ -148,7 +148,7 @@ func TestVerifyInvalidCommitRounds(t *testing.T) { func TestVerifyInvalidCommitRounds2(t *testing.T) { height, round := uint(1), uint(2) - _, valSet, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + _, valSet, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // Make a POL with +2/3 commits for future round. blockHash := RandBytes(32) @@ -172,7 +172,7 @@ func TestVerifyInvalidCommitRounds2(t *testing.T) { func TestReadWrite(t *testing.T) { height, round := uint(1), uint(2) - _, valSet, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + _, valSet, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // Make a POL with +2/3 votes. blockHash := RandBytes(32) diff --git a/consensus/state_test.go b/consensus/state_test.go index 8ad631646..f7a333bc7 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -8,7 +8,7 @@ import ( ) func TestSetupRound(t *testing.T) { - cs, privValidators := makeConsensusState() + cs, privValidators := randConsensusState() val0 := privValidators[0] // Add a vote, precommit, and commit by val0. @@ -50,7 +50,7 @@ func TestSetupRound(t *testing.T) { } func TestRunActionProposeNoPrivValidator(t *testing.T) { - cs, _ := makeConsensusState() + cs, _ := randConsensusState() cs.RunActionPropose(1, 0) rs := cs.GetRoundState() if rs.Proposal != nil { @@ -59,7 +59,7 @@ func TestRunActionProposeNoPrivValidator(t *testing.T) { } func TestRunActionPropose(t *testing.T) { - cs, privValidators := makeConsensusState() + cs, privValidators := randConsensusState() val0 := privValidators[0] cs.SetPrivValidator(val0) @@ -92,7 +92,7 @@ func checkRoundState(t *testing.T, rs *RoundState, } func TestRunActionPrecommitCommitFinalize(t *testing.T) { - cs, privValidators := makeConsensusState() + cs, privValidators := randConsensusState() val0 := privValidators[0] cs.SetPrivValidator(val0) diff --git a/consensus/test.go b/consensus/test.go index 77f1da8ed..fe09aa3a9 100644 --- a/consensus/test.go +++ b/consensus/test.go @@ -11,24 +11,24 @@ import ( // Common test methods -func makeValidator(votingPower uint64) (*state.Validator, *state.PrivValidator) { - privValidator := state.GenPrivValidator() +func makeValidator(valInfo *state.ValidatorInfo) *state.Validator { return &state.Validator{ - Address: privValidator.Address, - PubKey: privValidator.PubKey, + Address: valInfo.Address, + PubKey: valInfo.PubKey, BondHeight: 0, UnbondHeight: 0, LastCommitHeight: 0, - VotingPower: votingPower, + VotingPower: valInfo.FirstBondAmount, Accum: 0, - }, privValidator + } } -func makeVoteSet(height uint, round uint, type_ byte, numValidators int, votingPower uint64) (*VoteSet, *state.ValidatorSet, []*state.PrivValidator) { +func randVoteSet(height uint, round uint, type_ byte, numValidators int, votingPower uint64) (*VoteSet, *state.ValidatorSet, []*state.PrivValidator) { vals := make([]*state.Validator, numValidators) privValidators := make([]*state.PrivValidator, numValidators) for i := 0; i < numValidators; i++ { - val, privValidator := makeValidator(votingPower) + valInfo, privValidator := state.RandValidator(false, votingPower) + val := makeValidator(valInfo) vals[i] = val privValidators[i] = privValidator } @@ -37,7 +37,7 @@ func makeVoteSet(height uint, round uint, type_ byte, numValidators int, votingP return NewVoteSet(height, round, type_, valSet), valSet, privValidators } -func makeConsensusState() (*ConsensusState, []*state.PrivValidator) { +func randConsensusState() (*ConsensusState, []*state.PrivValidator) { state, _, privValidators := state.RandGenesisState(20, false, 1000, 10, false, 1000) blockStore := NewBlockStore(db_.NewMemDB()) mempool := mempool_.NewMempool(state) diff --git a/consensus/vote_set_test.go b/consensus/vote_set_test.go index c34ada917..4653b1e84 100644 --- a/consensus/vote_set_test.go +++ b/consensus/vote_set_test.go @@ -14,7 +14,7 @@ import ( func TestAddVote(t *testing.T) { height, round := uint(1), uint(0) - voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) val0 := privValidators[0] // t.Logf(">> %v", voteSet) @@ -48,7 +48,7 @@ func TestAddVote(t *testing.T) { func Test2_3Majority(t *testing.T) { height, round := uint(1), uint(0) - voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // 6 out of 10 voted for nil. voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} @@ -89,7 +89,7 @@ func Test2_3Majority(t *testing.T) { func Test2_3MajorityRedux(t *testing.T) { height, round := uint(1), uint(0) - voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 100, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 100, 1) blockHash := CRandBytes(32) blockPartsTotal := uint(123) @@ -165,7 +165,7 @@ func Test2_3MajorityRedux(t *testing.T) { func TestBadVotes(t *testing.T) { height, round := uint(1), uint(0) - voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // val0 votes for nil. vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} @@ -210,7 +210,7 @@ func TestBadVotes(t *testing.T) { func TestAddCommitsToPrevoteVotes(t *testing.T) { height, round := uint(2), uint(5) - voteSet, _, privValidators := makeVoteSet(height, round, VoteTypePrevote, 10, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // val0, val1, val2, val3, val4, val5 vote for nil. voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} @@ -274,7 +274,7 @@ func TestAddCommitsToPrevoteVotes(t *testing.T) { func TestMakeValidation(t *testing.T) { height, round := uint(1), uint(0) - voteSet, _, privValidators := makeVoteSet(height, round, VoteTypeCommit, 10, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypeCommit, 10, 1) blockHash, blockParts := CRandBytes(32), PartSetHeader{123, CRandBytes(32)} // 6 out of 10 voted for some block. diff --git a/state/priv_validator.go b/state/priv_validator.go index 5c9b6908b..4ab3f1d11 100644 --- a/state/priv_validator.go +++ b/state/priv_validator.go @@ -9,6 +9,7 @@ import ( "fmt" "io/ioutil" "math" + "sync" . "github.com/tendermint/tendermint/account" . "github.com/tendermint/tendermint/binary" @@ -52,6 +53,7 @@ type PrivValidator struct { // For persistence. // Overloaded for testing. filename string + mtx sync.Mutex } // Generates a new validator with private key. @@ -118,6 +120,12 @@ func LoadPrivValidator() *PrivValidator { } func (privVal *PrivValidator) Save() { + privVal.mtx.Lock() + defer privVal.mtx.Unlock() + privVal.save() +} + +func (privVal *PrivValidator) save() { privValJSON := PrivValidatorJSON{ Address: base64.StdEncoding.EncodeToString(privVal.Address), PubKey: base64.StdEncoding.EncodeToString(BinaryBytes(privVal.PubKey)), @@ -138,6 +146,8 @@ func (privVal *PrivValidator) Save() { // TODO: test func (privVal *PrivValidator) SignVote(vote *Vote) SignatureEd25519 { + privVal.mtx.Lock() + defer privVal.mtx.Unlock() // If height regression, panic if privVal.LastHeight > vote.Height { @@ -163,7 +173,7 @@ func (privVal *PrivValidator) SignVote(vote *Vote) SignatureEd25519 { privVal.LastHeight = vote.Height privVal.LastRound = vote.Round privVal.LastStep = voteToStep(vote) - privVal.Save() + privVal.save() // Sign return privVal.SignVoteUnsafe(vote) @@ -174,6 +184,8 @@ func (privVal *PrivValidator) SignVoteUnsafe(vote *Vote) SignatureEd25519 { } func (privVal *PrivValidator) SignProposal(proposal *Proposal) SignatureEd25519 { + privVal.mtx.Lock() + defer privVal.mtx.Unlock() if privVal.LastHeight < proposal.Height || privVal.LastHeight == proposal.Height && privVal.LastRound < proposal.Round || privVal.LastHeight == 0 && privVal.LastRound == 0 && privVal.LastStep == stepNone { @@ -182,7 +194,7 @@ func (privVal *PrivValidator) SignProposal(proposal *Proposal) SignatureEd25519 privVal.LastHeight = proposal.Height privVal.LastRound = proposal.Round privVal.LastStep = stepPropose - privVal.Save() + privVal.save() // Sign return privVal.PrivKey.Sign(SignBytes(proposal)).(SignatureEd25519) @@ -192,13 +204,15 @@ func (privVal *PrivValidator) SignProposal(proposal *Proposal) SignatureEd25519 } func (privVal *PrivValidator) SignRebondTx(rebondTx *RebondTx) SignatureEd25519 { + privVal.mtx.Lock() + defer privVal.mtx.Unlock() if privVal.LastHeight < rebondTx.Height { // Persist height/round/step privVal.LastHeight = rebondTx.Height privVal.LastRound = math.MaxUint64 // We can't do anything else for this rebondTx.Height. privVal.LastStep = math.MaxUint8 - privVal.Save() + privVal.save() // Sign return privVal.PrivKey.Sign(SignBytes(rebondTx)).(SignatureEd25519)