diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index fc2866835e..bfaea96f3c 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -371,16 +371,16 @@ func (x *XDPoS_v2) verifyVotingRule(header *types.Header) error { } // Once Hot stuff voting rule has verified, this node can then send vote -func (x *XDPoS_v2) sendVote(blockInfo utils.BlockInfo) error { +func (x *XDPoS_v2) sendVote(blockInfo *utils.BlockInfo) error { // First step: Generate the signature by using node's private key(The signature is the blockInfo signature) // Second step: Construct the vote struct with the above signature & blockinfo struct // Third step: Send the vote to broadcast channel - signedHash, err := x.signSignature(utils.VoteSigHash(&blockInfo)) + signedHash, err := x.signSignature(utils.VoteSigHash(blockInfo)) if err != nil { return err } voteMsg := &utils.Vote{ - ProposedBlockInfo: blockInfo, + ProposedBlockInfo: *blockInfo, Signature: signedHash, } x.broadcastToBftChannel(voteMsg) diff --git a/consensus/XDPoS/utils/pool_test.go b/consensus/XDPoS/utils/pool_test.go index 208cbbff14..55ab8adde8 100644 --- a/consensus/XDPoS/utils/pool_test.go +++ b/consensus/XDPoS/utils/pool_test.go @@ -28,22 +28,36 @@ func TestPoolWithTimeout(t *testing.T) { timeout1 := Timeout{Round: 1, Signature: []byte{1}} timeout2 := Timeout{Round: 1, Signature: []byte{2}} timeout3 := Timeout{Round: 1, Signature: []byte{3}} - assert.Nil(pool.Add(&timeout1)) - assert.Nil(pool.Add(&timeout1)) - assert.Equal(ret, 0) - assert.Nil(pool.Add(&timeout2)) - assert.Equal(ret, 2) - assert.Nil(pool.Add(&timeout3)) - assert.Equal(ret, 2) + _, numOfItems, err := pool.Add(&timeout1) + assert.Nil(err) + assert.Equal(1, numOfItems) + _, numOfItems, err = pool.Add(&timeout1) + assert.Nil(err) + // Duplicates should not be added + assert.Equal(1, numOfItems) + assert.Equal(0, ret) + _, numOfItems, err = pool.Add(&timeout2) + assert.Nil(err) + assert.Equal(2, ret) + + _, numOfItems, err = pool.Add(&timeout3) + assert.Nil(err) + assert.Equal(2, ret) pool = NewPool(3) // 3 is the cert size ret = 0 pool.SetOnThresholdFn(onThresholdFn) - assert.Nil(pool.Add(&timeout1)) - assert.Nil(pool.Add(&timeout2)) + _, numOfItems, err = pool.Add(&timeout1) + assert.Nil(err) + assert.Equal(1, numOfItems) + _, numOfItems, err = pool.Add(&timeout2) + assert.Nil(err) + assert.Equal(2, numOfItems) assert.Equal(ret, 0) pool.Clear() - assert.Nil(pool.Add(&timeout3)) - assert.Equal(ret, 0) + _, numOfItems, err = pool.Add(&timeout3) + assert.Nil(err) + assert.Equal(1, numOfItems) + assert.Equal(0, ret) } func TestPoolWithVote(t *testing.T) { @@ -68,29 +82,63 @@ func TestPoolWithVote(t *testing.T) { vote1 := Vote{ProposedBlockInfo: blockInfo1, Signature: []byte{1}} vote2 := Vote{ProposedBlockInfo: blockInfo2, Signature: []byte{2}} vote3 := Vote{ProposedBlockInfo: blockInfo1, Signature: []byte{3}} - assert.Nil(pool.Add(&vote1)) - assert.Nil(pool.Add(&vote1)) + _, numOfItems, err := pool.Add(&vote1) + assert.Nil(err) + assert.Equal(1, numOfItems) + // Duplicates should not be added + _, numOfItems, err = pool.Add(&vote1) + assert.Nil(err) + assert.Equal(1, numOfItems) assert.Equal(ret, 0) - assert.Nil(pool.Add(&vote2)) - assert.Equal(ret, 0) - assert.Nil(pool.Add(&vote3)) - assert.Equal(ret, 2) + + _, numOfItems, err = pool.Add(&vote2) + assert.Nil(err) + // vote2 is on a different blockInfo to vote1 + assert.Equal(1, numOfItems) + assert.Equal(0, ret) + + _, numOfItems, err = pool.Add(&vote3) + assert.Nil(err) + assert.Equal(2, numOfItems) + + assert.Equal(2, ret) pool = NewPool(3) // 3 is the cert size ret = 0 pool.SetOnThresholdFn(onThresholdFn) - assert.Nil(pool.Add(&vote1)) - assert.Nil(pool.Add(&vote2)) - assert.Nil(pool.Add(&vote3)) - assert.Equal(ret, 0) + + _, numOfItems, err = pool.Add(&vote1) + assert.Nil(err) + assert.Equal(1, numOfItems) + + // vote2 is on a different blockInfo to vote1 + _, numOfItems, err = pool.Add(&vote2) + assert.Nil(err) + assert.Equal(1, numOfItems) + + _, numOfItems, err = pool.Add(&vote3) + assert.Nil(err) + assert.Equal(2, numOfItems) + + assert.Equal(0, ret) pool.Clear() assert.Empty(pool.objList) pool = NewPool(2) // 2 is the cert size ret = 0 pool.SetOnThresholdFn(onThresholdFn) - assert.Nil(pool.Add(&vote1)) - assert.Nil(pool.Add(&vote2)) - assert.Nil(pool.Add(&vote3)) - assert.Equal(len(pool.objList), 1) //vote for one hash is cleared, but another remains + + _, numOfItems, err = pool.Add(&vote1) + assert.Nil(err) + assert.Equal(1, numOfItems) + + // vote2 is on a different blockInfo to vote1 + _, numOfItems, err = pool.Add(&vote2) + assert.Nil(err) + assert.Equal(1, numOfItems) + + _, numOfItems, err = pool.Add(&vote3) + assert.Nil(err) + assert.Equal(2, numOfItems) + assert.Equal(1, len(pool.objList)) //vote for one hash is cleared, but another remains pool.Clear() assert.Empty(pool.objList) } diff --git a/tests/consensus/v2_test.go b/tests/consensus/v2_test.go index 206f2725eb..59b53b4c73 100644 --- a/tests/consensus/v2_test.go +++ b/tests/consensus/v2_test.go @@ -100,7 +100,7 @@ func TestThrowErrorIfTimeoutMsgRoundLessThanCurrentRound(t *testing.T) { } // VoteHandler -func TestVoteMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) { +func TestVoteMessageHandlerSuccessfullyGeneratedQC(t *testing.T) { blockchain, _, _, _ := PrepareXDCTestBlockChain(t, 11, params.TestXDPoSMockChainConfigWithV2Engine) engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 @@ -129,7 +129,7 @@ func TestVoteMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) { assert.Nil(t, err) assert.Equal(t, utils.Round(1), engineV2.GetCurrentRound()) - // Create a vote message that should trigger vite pool hook + // Create a vote message that should trigger vote pool hook voteMsg = &utils.Vote{ ProposedBlockInfo: *blockInfo, Signature: []byte{3}, @@ -202,7 +202,7 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) { assert.Nil(t, err) assert.Equal(t, utils.Round(1), engineV2.GetCurrentRound()) - // Create a vote message that should trigger vite pool hook + // Create a vote message that should trigger vote pool hook voteMsg = &utils.Vote{ ProposedBlockInfo: *blockInfo, Signature: []byte{3},