Skip to content

Commit

Permalink
fix only timeout round exists in next epoch
Browse files Browse the repository at this point in the history
  • Loading branch information
liam.lai committed Dec 24, 2024
1 parent b2a41af commit d318e20
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
12 changes: 12 additions & 0 deletions consensus/XDPoS/engines/engine_v2/timeout.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,19 @@ func (x *XDPoS_v2) verifyTC(chain consensus.ChainReader, timeoutCert *types.Time
log.Warn("[verifyQC] duplicated signature in QC", "duplicate", common.Bytes2Hex(d))
}
}
latestBlockRound, err := x.GetRoundNumber(chain.CurrentHeader())
if err != nil {
log.Error("[verifyTC] Error when getting current header round", "error", err)
return fmt.Errorf("fail on verifyTC due to error when getting current header round, %s", err)
}

tcEpoch := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(timeoutCert.Round)/x.config.Epoch

//tcEpoch maybe not existed if there is no QC round in this epoch, there is no epoch switch block generated, so it needs to use currentRound to find epochBlockInfo
if latestBlockRound < timeoutCert.Round {
tcEpoch = x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(latestBlockRound)/x.config.Epoch
}

epochBlockInfo, err := x.GetBlockByEpochNumber(chain, tcEpoch)
if err != nil {
log.Error("[verifyTC] Error when getting epoch block info by tc round", "error", err)
Expand Down
49 changes: 49 additions & 0 deletions consensus/tests/engine_v2_tests/sync_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,55 @@ func TestSkipVerifySyncInfoIfBothQcTcNotQualified(t *testing.T) {
assert.Nil(t, err)
}

func TestVerifySyncInfoIfTCRoundIsAtNextEpoch(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2

// Make the Highest QC in syncInfo point to an old block to simulate it's no longer qualified
parentBlock := blockchain.GetBlockByNumber(903)
var extraField types.ExtraFields_v2
err := utils.DecodeBytesExtraFields(parentBlock.Extra(), &extraField)
if err != nil {
t.Fatal("Fail to decode extra data", err)
}

highestTC := &types.TimeoutCert{
Round: types.Round(899),
Signatures: []types.Signature{},
}

timeoutForSign := &types.TimeoutForSign{
Round: types.Round(900),
GapNumber: 450,
}

// Sign from acc 1, 2, 3 and voter
acc1SignedHash := SignHashByPK(acc1Key, types.TimeoutSigHash(timeoutForSign).Bytes())
acc2SignedHash := SignHashByPK(acc2Key, types.TimeoutSigHash(timeoutForSign).Bytes())
acc3SignedHash := SignHashByPK(acc3Key, types.TimeoutSigHash(timeoutForSign).Bytes())
voterSignedHash := SignHashByPK(voterKey, types.TimeoutSigHash(timeoutForSign).Bytes())

var signatures []types.Signature
signatures = append(signatures, acc1SignedHash, acc2SignedHash, acc3SignedHash, voterSignedHash)

syncInfoTC := &types.TimeoutCert{
Round: timeoutForSign.Round,
Signatures: signatures,
GapNumber: timeoutForSign.GapNumber,
}

syncInfoMsg := &types.SyncInfo{
HighestQuorumCert: extraField.QuorumCert,
HighestTimeoutCert: syncInfoTC,
}

engineV2.SetPropertiesFaker(syncInfoMsg.HighestQuorumCert, highestTC)

verified, err := engineV2.VerifySyncInfoMessage(blockchain, syncInfoMsg)
assert.True(t, verified)
assert.Nil(t, err)
}

func TestVerifySyncInfoIfTcUseDifferentEpoch(t *testing.T) {
config := params.TestXDPoSMockChainConfig
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 1349, config, nil)
Expand Down

0 comments on commit d318e20

Please sign in to comment.