Browse Source

priv validator returns last sign bytes if h/r/s matches

since now we have time in the msgs and we might crash between writing
the priv val and writing to wal.

Refs #984
pull/993/head
Anton Kaliaev 7 years ago
parent
commit
a1cc9ac642
No known key found for this signature in database GPG Key ID: 7B6881D965918214
2 changed files with 17 additions and 25 deletions
  1. +17
    -21
      types/priv_validator.go
  2. +0
    -4
      types/priv_validator_test.go

+ 17
- 21
types/priv_validator.go View File

@ -193,8 +193,8 @@ func (privVal *PrivValidatorFS) Reset() {
privVal.Save()
}
// SignVote signs a canonical representation of the vote, along with the chainID.
// Implements PrivValidator.
// SignVote signs a canonical representation of the vote, along with the
// chainID. Implements PrivValidator.
func (privVal *PrivValidatorFS) SignVote(chainID string, vote *Vote) error {
privVal.mtx.Lock()
defer privVal.mtx.Unlock()
@ -206,8 +206,8 @@ func (privVal *PrivValidatorFS) SignVote(chainID string, vote *Vote) error {
return nil
}
// SignProposal signs a canonical representation of the proposal, along with the chainID.
// Implements PrivValidator.
// SignProposal signs a canonical representation of the proposal, along with
// the chainID. Implements PrivValidator.
func (privVal *PrivValidatorFS) SignProposal(chainID string, proposal *Proposal) error {
privVal.mtx.Lock()
defer privVal.mtx.Unlock()
@ -219,40 +219,36 @@ func (privVal *PrivValidatorFS) SignProposal(chainID string, proposal *Proposal)
return nil
}
// signBytesHRS signs the given signBytes if the height/round/step (HRS)
// are greater than the latest state. If the HRS are equal,
// it returns the privValidator.LastSignature.
// signBytesHRS signs the given signBytes if the height/round/step (HRS) are
// greater than the latest state. If the HRS are equal, it returns the
// privValidator.LastSignature.
func (privVal *PrivValidatorFS) signBytesHRS(height int64, round int, step int8, signBytes []byte) (crypto.Signature, error) {
sig := crypto.Signature{}
// If height regression, err
if privVal.LastHeight > height {
return sig, errors.New("Height regression")
}
// More cases for when the height matches
if privVal.LastHeight == height {
// If round regression, err
if privVal.LastRound > round {
return sig, errors.New("Round regression")
}
// If step regression, err
if privVal.LastRound == round {
if privVal.LastStep > step {
return sig, errors.New("Step regression")
} else if privVal.LastStep == step {
if privVal.LastSignBytes != nil {
if privVal.LastSignature.Empty() {
cmn.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
panic("privVal: LastSignature is nil but LastSignBytes is not!")
}
// NOTE: we might crash between writing the priv val and writing to
// wal. since we have time in votes and proposals, signBytes can be
// different from LastSignBytes. we might be signing conflicting
// bytes here.
return privVal.LastSignature, nil
}
return sig, errors.New("Step regression")
return sig, errors.New("No LastSignature found")
}
}
}


+ 0
- 4
types/priv_validator_test.go View File

@ -99,7 +99,6 @@ func TestSignVote(t *testing.T) {
privVal := GenPrivValidatorFS(tempFilePath)
block1 := BlockID{[]byte{1, 2, 3}, PartSetHeader{}}
block2 := BlockID{[]byte{3, 2, 1}, PartSetHeader{}}
height, round := int64(10), 1
voteType := VoteTypePrevote
@ -117,7 +116,6 @@ func TestSignVote(t *testing.T) {
newVote(privVal.Address, 0, height, round-1, voteType, block1), // round regression
newVote(privVal.Address, 0, height-1, round, voteType, block1), // height regression
newVote(privVal.Address, 0, height-2, round+4, voteType, block1), // height regression and different round
newVote(privVal.Address, 0, height, round, voteType, block2), // different block
}
for _, c := range cases {
@ -133,7 +131,6 @@ func TestSignProposal(t *testing.T) {
privVal := GenPrivValidatorFS(tempFilePath)
block1 := PartSetHeader{5, []byte{1, 2, 3}}
block2 := PartSetHeader{10, []byte{3, 2, 1}}
height, round := int64(10), 1
// sign a proposal for first time
@ -150,7 +147,6 @@ func TestSignProposal(t *testing.T) {
newProposal(height, round-1, block1), // round regression
newProposal(height-1, round, block1), // height regression
newProposal(height-2, round+4, block1), // height regression and different round
newProposal(height, round, block2), // different block
}
for _, c := range cases {


Loading…
Cancel
Save