Browse Source

state/privval: vote timestamp fix (#6748)

pull/6786/head
JayT106 3 years ago
committed by GitHub
parent
commit
9a2a7d4307
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 1 deletions
  1. +28
    -1
      internal/consensus/common_test.go
  2. +1
    -0
      internal/consensus/state.go
  3. +24
    -0
      internal/consensus/state_test.go

+ 28
- 1
internal/consensus/common_test.go View File

@ -88,6 +88,7 @@ type validatorStub struct {
Round int32 Round int32
types.PrivValidator types.PrivValidator
VotingPower int64 VotingPower int64
lastVote *types.Vote
} }
const testMinPower int64 = 10 const testMinPower int64 = 10
@ -121,8 +122,18 @@ func (vs *validatorStub) signVote(
BlockID: types.BlockID{Hash: hash, PartSetHeader: header}, BlockID: types.BlockID{Hash: hash, PartSetHeader: header},
} }
v := vote.ToProto() v := vote.ToProto()
err = vs.PrivValidator.SignVote(context.Background(), config.ChainID(), v)
if err := vs.PrivValidator.SignVote(context.Background(), config.ChainID(), v); err != nil {
return nil, fmt.Errorf("sign vote failed: %w", err)
}
// ref: signVote in FilePV, the vote should use the privious vote info when the sign data is the same.
if signDataIsEqual(vs.lastVote, v) {
v.Signature = vs.lastVote.Signature
v.Timestamp = vs.lastVote.Timestamp
}
vote.Signature = v.Signature vote.Signature = v.Signature
vote.Timestamp = v.Timestamp
return vote, err return vote, err
} }
@ -139,6 +150,9 @@ func signVote(
if err != nil { if err != nil {
panic(fmt.Errorf("failed to sign vote: %v", err)) panic(fmt.Errorf("failed to sign vote: %v", err))
} }
vs.lastVote = v
return v return v
} }
@ -876,3 +890,16 @@ func newKVStore() abci.Application {
func newPersistentKVStoreWithPath(dbDir string) abci.Application { func newPersistentKVStoreWithPath(dbDir string) abci.Application {
return kvstore.NewPersistentKVStoreApplication(dbDir) return kvstore.NewPersistentKVStoreApplication(dbDir)
} }
func signDataIsEqual(v1 *types.Vote, v2 *tmproto.Vote) bool {
if v1 == nil || v2 == nil {
return false
}
return v1.Type == v2.Type &&
bytes.Equal(v1.BlockID.Hash, v2.BlockID.GetHash()) &&
v1.Height == v2.GetHeight() &&
v1.Round == v2.Round &&
bytes.Equal(v1.ValidatorAddress.Bytes(), v2.GetValidatorAddress()) &&
v1.ValidatorIndex == v2.GetValidatorIndex()
}

+ 1
- 0
internal/consensus/state.go View File

@ -2218,6 +2218,7 @@ func (cs *State) signVote(
err := cs.privValidator.SignVote(ctx, cs.state.ChainID, v) err := cs.privValidator.SignVote(ctx, cs.state.ChainID, v)
vote.Signature = v.Signature vote.Signature = v.Signature
vote.Timestamp = v.Timestamp
return vote, err return vote, err
} }


+ 24
- 0
internal/consensus/state_test.go View File

@ -1939,6 +1939,30 @@ func TestStateOutputVoteStats(t *testing.T) {
} }
func TestSignSameVoteTwice(t *testing.T) {
config := configSetup(t)
_, vss := randState(config, 2)
randBytes := tmrand.Bytes(tmhash.Size)
vote := signVote(vss[1],
config,
tmproto.PrecommitType,
randBytes,
types.PartSetHeader{Total: 10, Hash: randBytes},
)
vote2 := signVote(vss[1],
config,
tmproto.PrecommitType,
randBytes,
types.PartSetHeader{Total: 10, Hash: randBytes},
)
require.Equal(t, vote, vote2)
}
// subscribe subscribes test client to the given query and returns a channel with cap = 1. // subscribe subscribes test client to the given query and returns a channel with cap = 1.
func subscribe(eventBus *types.EventBus, q tmpubsub.Query) <-chan tmpubsub.Message { func subscribe(eventBus *types.EventBus, q tmpubsub.Query) <-chan tmpubsub.Message {
sub, err := eventBus.Subscribe(context.Background(), testSubscriber, q) sub, err := eventBus.Subscribe(context.Background(), testSubscriber, q)


Loading…
Cancel
Save