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
This commit is contained in:
parent
67c3af3bf8
commit
a1cc9ac642
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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…
Reference in New Issue