From 11299c6cc1d9614fa082939877e5a730be9eb47f Mon Sep 17 00:00:00 2001 From: Mantre Date: Sat, 21 Oct 2023 02:24:00 +0800 Subject: [PATCH] fix(consensus): not increase the voting power on duplicated binary votes (#762) --- consensus/voteset/binary_voteset.go | 6 +-- consensus/voteset/voteset_test.go | 59 ++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/consensus/voteset/binary_voteset.go b/consensus/voteset/binary_voteset.go index 310cc2da0..08c1590da 100644 --- a/consensus/voteset/binary_voteset.go +++ b/consensus/voteset/binary_voteset.go @@ -27,10 +27,9 @@ func newRoundVotes() *roundVotes { } } -func (bs *roundVotes) addVote(v *vote.Vote, power int64) { - vb := bs.voteBoxes[v.CPValue()] +func (rv *roundVotes) addVote(v *vote.Vote, power int64) { + vb := rv.voteBoxes[v.CPValue()] vb.addVote(v, power) - bs.votedPower += power } type BinaryVoteSet struct { @@ -97,6 +96,7 @@ func (vs *BinaryVoteSet) AddVote(v *vote.Vote) (bool, error) { } } else { roundVotes.allVotes[v.Signer()] = v + roundVotes.votedPower += power } roundVotes.addVote(v, power) diff --git a/consensus/voteset/voteset_test.go b/consensus/voteset/voteset_test.go index 26778a084..d3180573e 100644 --- a/consensus/voteset/voteset_test.go +++ b/consensus/voteset/voteset_test.go @@ -118,39 +118,80 @@ func TestAddBinaryVote(t *testing.T) { assert.True(t, added) } -func TestDuplicateVote(t *testing.T) { +func TestDuplicateBlockVote(t *testing.T) { ts := testsuite.NewTestSuite(t) - valsMap, valKeys, totalPower := setupCommittee(ts, 1000, 1500, 2500, 2000) + valsMap, valKeys, totalPower := setupCommittee(ts, 1, 1, 1, 1) h1 := ts.RandHash() h2 := ts.RandHash() + h3 := ts.RandHash() addr := valKeys[0].Address() vs := NewPrepareVoteSet(0, totalPower, valsMap) correctVote := vote.NewPrepareVote(h1, 1, 0, addr) - duplicatedVote := vote.NewPrepareVote(h2, 1, 0, addr) + duplicatedVote1 := vote.NewPrepareVote(h2, 1, 0, addr) + duplicatedVote2 := vote.NewPrepareVote(h3, 1, 0, addr) // sign the votes ts.HelperSignVote(valKeys[0], correctVote) - ts.HelperSignVote(valKeys[0], duplicatedVote) + ts.HelperSignVote(valKeys[0], duplicatedVote1) + ts.HelperSignVote(valKeys[0], duplicatedVote2) added, err := vs.AddVote(correctVote) assert.NoError(t, err) assert.True(t, added) - added, err = vs.AddVote(duplicatedVote) + added, err = vs.AddVote(duplicatedVote1) assert.Equal(t, errors.Code(err), errors.ErrDuplicateVote) assert.True(t, added) - added, err = vs.AddVote(correctVote) - assert.NoError(t, err) // added before - assert.False(t, added) + added, err = vs.AddVote(duplicatedVote2) + assert.Equal(t, errors.Code(err), errors.ErrDuplicateVote) + assert.True(t, added) bv1 := vs.BlockVotes(h1) bv2 := vs.BlockVotes(h2) + bv3 := vs.BlockVotes(h3) assert.Equal(t, bv1[addr], correctVote) - assert.Equal(t, bv2[addr], duplicatedVote) + assert.Equal(t, bv2[addr], duplicatedVote1) + assert.Equal(t, bv3[addr], duplicatedVote2) + assert.False(t, vs.HasQuorumHash()) +} + +func TestDuplicateBinaryVote(t *testing.T) { + ts := testsuite.NewTestSuite(t) + + valsMap, valKeys, totalPower := setupCommittee(ts, 1, 1, 1, 1) + + h1 := ts.RandHash() + h2 := ts.RandHash() + h3 := ts.RandHash() + addr := valKeys[0].Address() + vs := NewCPPreVoteVoteSet(0, totalPower, valsMap) + + correctVote := vote.NewCPPreVote(h1, 1, 0, 0, vote.CPValueOne, &vote.JustInitOne{}, addr) + duplicatedVote1 := vote.NewCPPreVote(h2, 1, 0, 0, vote.CPValueOne, &vote.JustInitOne{}, addr) + duplicatedVote2 := vote.NewCPPreVote(h3, 1, 0, 0, vote.CPValueOne, &vote.JustInitOne{}, addr) + + // sign the votes + ts.HelperSignVote(valKeys[0], correctVote) + ts.HelperSignVote(valKeys[0], duplicatedVote1) + ts.HelperSignVote(valKeys[0], duplicatedVote2) + + added, err := vs.AddVote(correctVote) + assert.NoError(t, err) + assert.True(t, added) + + added, err = vs.AddVote(duplicatedVote1) + assert.Equal(t, errors.Code(err), errors.ErrDuplicateVote) + assert.True(t, added) + + added, err = vs.AddVote(duplicatedVote2) + assert.Equal(t, errors.Code(err), errors.ErrDuplicateVote) + assert.True(t, added) + + assert.False(t, vs.HasOneThirdOfTotalPower(0)) } func TestQuorum(t *testing.T) {