From 09b66ea8c49a4e05239e704e656b60b2e1264c2c Mon Sep 17 00:00:00 2001 From: Daniel Liu <139250065@qq.com> Date: Mon, 3 Nov 2025 15:25:57 +0800 Subject: [PATCH] engine_v2: check overflow first, close XFN-20 (#1659) --- consensus/XDPoS/engines/engine_v2/engine.go | 14 +++++++------- consensus/XDPoS/engines/engine_v2/snapshot.go | 7 ++++--- consensus/XDPoS/engines/engine_v2/timeout.go | 14 ++++++++------ consensus/XDPoS/engines/engine_v2/vote.go | 7 ++++--- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index 32a9951c90..260fdd19ff 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -228,10 +228,9 @@ func (x *XDPoS_v2) initial(chain consensus.ChainReader, header *types.Header) er } // Initial first v2 snapshot - lastGapNum := x.config.V2.SwitchBlock.Uint64() - x.config.Gap - // prevent overflow - if x.config.V2.SwitchBlock.Uint64() < x.config.Gap { - lastGapNum = 0 + lastGapNum := uint64(0) + if x.config.V2.SwitchBlock.Uint64() > x.config.Gap { + lastGapNum = x.config.V2.SwitchBlock.Uint64() - x.config.Gap } lastGapHeader := chain.GetHeaderByNumber(lastGapNum) @@ -782,9 +781,10 @@ func (x *XDPoS_v2) verifyQC(blockChainReader consensus.ChainReader, quorumCert * return <-sigErrChan } epochSwitchNumber := epochInfo.EpochSwitchBlockInfo.Number.Uint64() - gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch - x.config.Gap - // prevent overflow - if epochSwitchNumber-epochSwitchNumber%x.config.Epoch < x.config.Gap { + gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch + if gapNumber > x.config.Gap { + gapNumber -= x.config.Gap + } else { gapNumber = 0 } if gapNumber != quorumCert.GapNumber { diff --git a/consensus/XDPoS/engines/engine_v2/snapshot.go b/consensus/XDPoS/engines/engine_v2/snapshot.go index 65a431dd14..b98e935b26 100644 --- a/consensus/XDPoS/engines/engine_v2/snapshot.go +++ b/consensus/XDPoS/engines/engine_v2/snapshot.go @@ -79,9 +79,10 @@ func (x *XDPoS_v2) getSnapshot(chain consensus.ChainReader, number uint64, isGap if isGapNumber { gapBlockNum = number } else { - gapBlockNum = number - number%x.config.Epoch - x.config.Gap - //prevent overflow - if number-number%x.config.Epoch < x.config.Gap { + gapBlockNum = number - number%x.config.Epoch + if gapBlockNum > x.config.Gap { + gapBlockNum -= x.config.Gap + } else { gapBlockNum = 0 } } diff --git a/consensus/XDPoS/engines/engine_v2/timeout.go b/consensus/XDPoS/engines/engine_v2/timeout.go index f73d65faa2..0a57de31a4 100644 --- a/consensus/XDPoS/engines/engine_v2/timeout.go +++ b/consensus/XDPoS/engines/engine_v2/timeout.go @@ -255,9 +255,10 @@ func (x *XDPoS_v2) sendTimeout(chain consensus.ChainReader) error { if isEpochSwitch { // Notice this +1 is because we expect a block whos is the child of currentHeader currentNumber := currentBlockHeader.Number.Uint64() + 1 - gapNumber = currentNumber - currentNumber%x.config.Epoch - x.config.Gap - // prevent overflow - if currentNumber-currentNumber%x.config.Epoch < x.config.Gap { + gapNumber = currentNumber - currentNumber%x.config.Epoch + if gapNumber > x.config.Gap { + gapNumber -= x.config.Gap + } else { gapNumber = 0 } log.Debug("[sendTimeout] is epoch switch when sending out timeout message", "currentNumber", currentNumber, "gapNumber", gapNumber) @@ -267,9 +268,10 @@ func (x *XDPoS_v2) sendTimeout(chain consensus.ChainReader) error { log.Error("[sendTimeout] Error when trying to get current epoch switch info for a non-epoch block", "currentRound", x.currentRound, "currentBlockNum", currentBlockHeader.Number, "currentBlockHash", currentBlockHeader.Hash(), "epochNum", epochNum) return err } - gapNumber = epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64() - epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()%x.config.Epoch - x.config.Gap - // prevent overflow - if epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()-epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()%x.config.Epoch < x.config.Gap { + gapNumber = epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64() - epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64()%x.config.Epoch + if gapNumber > x.config.Gap { + gapNumber -= x.config.Gap + } else { gapNumber = 0 } log.Debug("[sendTimeout] non-epoch-switch block found its epoch block and calculated the gapNumber", "epochSwitchInfo.EpochSwitchBlockInfo.Number", epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64(), "gapNumber", gapNumber) diff --git a/consensus/XDPoS/engines/engine_v2/vote.go b/consensus/XDPoS/engines/engine_v2/vote.go index 181c680ae7..a622b91fff 100644 --- a/consensus/XDPoS/engines/engine_v2/vote.go +++ b/consensus/XDPoS/engines/engine_v2/vote.go @@ -63,9 +63,10 @@ func (x *XDPoS_v2) sendVote(chainReader consensus.ChainReader, blockInfo *types. return err } epochSwitchNumber := epochSwitchInfo.EpochSwitchBlockInfo.Number.Uint64() - gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch - x.config.Gap - // prevent overflow - if epochSwitchNumber-epochSwitchNumber%x.config.Epoch < x.config.Gap { + gapNumber := epochSwitchNumber - epochSwitchNumber%x.config.Epoch + if gapNumber > x.config.Gap { + gapNumber -= x.config.Gap + } else { gapNumber = 0 } signedHash, err := x.signSignature(types.VoteSigHash(&types.VoteForSign{