On XDPoS v2, a block is final when the 3-chain commit rule commits it: a quorum certificate (QC) certifies a block whose parent and grandparent come from the two rounds just before it, and then the grandparent is committed. xOneRS exposes that point in two ways: the finalized block tag, which returns the latest committed block, and eth_getBlockFinalityByNumber, which returns 100 for a committed block. An exchange or a bridge should wait for one of these, not for a fixed number of blocks, because a timeout round delays the commit.
For what a QC and a timeout are, see QC, TC and timeouts. For what happens to transactions when a branch is dropped, see reorgs and the transaction pool.
When is an XDPoS v2 block final?
The commit rule in spec/consensus/v2-commit.md, from geth-XDC engine_v2/utils.go:530-598:
- A QC certifies block
B. Pis the parent ofBandGits grandparent.round(P)must beround(B) - 1andround(G)must beround(B) - 2.- If they are, and nothing at or above
Gis committed already,Gis committed and becomes the highest committed block.
Three blocks of three consecutive rounds are needed. A timeout between them breaks the chain, and the rule waits for the next three consecutive rounds. Blocks up to two after the V2 switch block commit nothing.
How do I read finality from xOne?
| Method | What it returns | Source |
|---|---|---|
finalized block tag (for example eth_getBlockByNumber("finalized", false)) |
the latest QC-committed V2 block; an error finalized block not found before the first commit; never the head |
types.rs resolve_tag |
safe block tag |
an error safe block not found: XDPoS never sets a safe block |
same |
eth_getBlockFinalityByNumber / ByHash |
100 for a canonical V2 block at or below the committed block; otherwise the signer share len(signers) * 100 / len(masternodes) (integer division); 0 for an unknown block |
xdc-eth-extensions.md |
The finalized tag follows geth-XDC: its commit hook sets the finalized block to the latest V2 committed block (eth/backend.go:433-436). Before PR #353 (merged 2026-11-14), xOneRS answered finalized with the head, which could overstate finality; the v0.1.0 release has that older behaviour.
The XDPoS_* methods are different: their block parameters accept finalized but treat it as the head (xdpos-namespace.md). Do not use an XDPoS_* call to read finality.
How many confirmations should an exchange wait for?
Wait until the deposit block is at or below the finalized block, or until eth_getBlockFinalityByNumber returns 100 for it. The spec defines finality by the commit rule, not by a block count: when no round times out, the committed block is two blocks below the certified block, and each timeout round adds a wait for the next three consecutive rounds. On net2040, 379 of 933 epochs had at least one round that made no block (epoch lengths), so timeouts are common enough to matter.
What can still change below the head?
Blocks above the committed block can be replaced. A one-block reorg is normal on XDPoS v2 when a round times out (the reorg post-mortem). xOneRS refuses to reorg below the committed block: the test deep_reorg_below_the_committed_block_is_refused in crates/xone-sync/tests/chain.rs checks it.
The collected competitor articles state no claim about XDPoS finality, so this post has no comparison table.
Frequently asked questions
Which RPC call tells me a block on XDC is final?
eth_getBlockByNumber("finalized", false) returns the latest committed block, and eth_getBlockFinalityByNumber(n) returns 100 when block n is committed. Both are served by xOneRS on main.
Is a fixed number of confirmations safe on XDC?
The commit rule does not use a fixed count: it needs three blocks of consecutive rounds, and a timeout round delays it. Read the finalized block instead of counting.
Why does safe return an error?
XDPoS never sets a safe block. geth-XDC answers safe block not found, and xOneRS does the same.
Can a finalized block be reverted?
xOneRS refuses a reorg below the committed block, and a test covers that rule.
Sources
This article describes the source and evidence at its review date. Check the linked repository for current implementation and qualification status.
Explore the engineering evidenceEdit this page on GitHub opens the Markdown source (content/blog/xdc-finality-xone/index.md). GitHub may ask you to sign in. Report a correction opens a prefilled GitHub issue for this page.