Skip to main content
With the upgrade to Heimdall v2, deterministic finality is now achieved in 2 to 5 seconds, thanks to 1 to 2 second block times in Heimdall. Milestones are voted on and finalized much faster than the previous checkpoint-only model.

Types of finality

There are two main types of finality in blockchains: probabilistic and deterministic. Probabilistic finality means there is a chance of a reorganization where a different chain might become the canonical chain. Bitcoin is a well-known example. Deterministic finality means there is no chance of a reorganization once a block is finalized. Ethereum uses deterministic finality via its Casper FFG mechanism. Polygon PoS uses deterministic finality via its milestone mechanism.

How finality works on Polygon PoS

Polygon PoS achieves finality through two distinct mechanisms that serve different purposes:

Milestones

Milestones provide fast deterministic finality on the Polygon chain itself, without waiting for a checkpoint to be submitted to Ethereum. At every Heimdall height, each validator proposes the Bor block hashes they have seen since the last finalized milestone, using vote extensions in the CometBFT consensus. When finalizing Heimdall height H+1, Heimdall looks for the longest common sequence of block hashes from all validators that have 2/3 or more agreement. That sequence is finalized as the new milestone. This means finality is deterministic even before a checkpoint reaches Ethereum. Milestones typically finalize a transaction within 2 to 5 seconds.

Checkpoints

Checkpoints still occur every 256 blocks (minimum) and are submitted to Ethereum mainnet. They:
  • Provide proof of burn for asset withdrawals from Polygon to Ethereum.
  • Anchor Polygon state to Ethereum for additional security.
Checkpoints are separate from milestones. A transaction is finalized on Polygon by a milestone well before the next checkpoint is submitted.

Querying finality

Use the standard eth_getBlockByNumber JSON-RPC method with the "finalized" block tag to retrieve the most recently finalized block on Polygon PoS. Finalized blocks are considered irreversible.
{
  "method": "eth_getBlockByNumber",
  "params": ["finalized", true],
  "id": 1,
  "jsonrpc": "2.0"
}
To check whether a specific transaction has reached finality, compare its block number to the latest finalized block number:
async function milestones_checkFinality(client: any, txHash: string): Promise<boolean> {
  const tx = await client.getTransaction({ hash: `0x${txHash}` })
  if (!tx || !tx.blockNumber) return false
  const latestBlock: Block = await client.getBlock({ blockTag: 'finalized' })

  console.log(`Latest finalized block: ${latestBlock.number}`)
  console.log(`Your transaction block: ${tx.blockNumber}`)

  // Returns true if the finalized block has passed the transaction's block number.
  return (latestBlock.number !== null && latestBlock.number > tx.blockNumber)
}
Finality is achieved after a consensus period among validators, approximately 2 to 5 seconds.