Reorgs
Chapter 43: Chain Reorganizations Handling
Section titled “Chapter 43: Chain Reorganizations Handling”Overview
Section titled “Overview”Chain reorganizations (reorgs) are fundamental to how blockchains function. They occur when the network discovers a new chain that is longer or more valid than the current chain, causing nodes to revert to a previous state and follow the new fork. Understanding and properly handling reorgs is essential for building robust blockchain applications.
43.1 What is a Chain Reorganization?
Section titled “43.1 What is a Chain Reorganization?”A chain reorganization (reorg) occurs when a blockchain node must switch to a different chain because the network has reached consensus on a new chain that differs from what the node previously accepted.
┌─────────────────────────────────────────────────────────────────────────────┐│ CHAIN REORGANIZATION EXAMPLE │├─────────────────────────────────────────────────────────────────────────────┤│ ││ BEFORE REORG: ││ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ││ │Genesis│───▶│ B1 │───▶│ B2 │───▶│ B3 │ (current head) ││ └─────┘ └─────┘ └─────┘ └─────┘ ││ ││ NEW BLOCK ARRIVES: ││ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ││ │Genesis│───▶│ B1 │───▶│ B2 │───▶│ B3 │───▶ B4 ││ └─────┘ └─────┘ └─────┘ └─────┘ ││ │ ││ ▼ ││ CONFLICT! Another B4' arrives ││ with different transactions ││ ││ AFTER REORG: ││ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ││ │Genesis│───▶│ B1 │───▶│ B2 │───▶│ B3' │───▶ B4' ││ └─────┘ └─────┘ └─────┘ └─────┘ ││ │ ││ └───── B3 and B4 are now discarded (uncle blocks) ││ │└─────────────────────────────────────────────────────────────────────────────┘Types of Reorgs
Section titled “Types of Reorgs”| Type | Depth | Cause | Frequency |
|---|---|---|---|
| Minor | 1-2 blocks | Network latency, block propagation | Common |
| Medium | 3-10 blocks | Validator issues, network partitions | Occasional |
| Deep | 10+ blocks | Consensus bugs, majority misbehavior | Rare |
| Finality | N/A | Protocol-level finalization | Never (for finalized blocks) |
43.2 How Different Consensus Mechanisms Handle Reorgs
Section titled “43.2 How Different Consensus Mechanisms Handle Reorgs”Proof of Work (PoW)
Section titled “Proof of Work (PoW)”In PoW networks like Bitcoin and Ethereum Classic, reorgs can occur frequently due to mining competition.
┌─────────────────────────────────────────────────────────────────┐│ POX REORG CHARACTERISTICS │├─────────────────────────────────────────────────────────────────┤│ ││ PROBABILITY OF REORG: ││ ━━━━━━━━━━━━━━━━━━━━━━━ ││ ││ Block Depth (n) ≈ Probability of Reorg ││ ┌─────────────┬─────────────────────┐ ││ │ 1 block │ ~50% (natural) │ ││ │ 2 blocks │ ~25% │ ││ │ 3 blocks │ ~12.5% │ ││ │ 6 blocks │ ~1.5% │ ││ │ 12 blocks │ ~0.02% │ ││ └─────────────┴─────────────────────┘ ││ ││ Recommendation: Wait for 6 confirmations for significant ││ transactions ││ │└─────────────────────────────────────────────────────────────────┘Proof of Stake (PoS)
Section titled “Proof of Stake (PoS)”In PoS networks like Ethereum 2.0, reorgs are much less frequent due to finality.
┌─────────────────────────────────────────────────────────────────┐│ PROOF OF STAKE FINALITY │├─────────────────────────────────────────────────────────────────┤│ ││ SLOT (12 seconds) ──▶ EPOCH (32 slots = 6.4 minutes) ││ │ │ ││ ▼ ▼ ││ ┌─────────┐ ┌─────────────┐ ││ │ Proposed │ │ Checkpoint │ ││ │ Block │ │ Finalized │ ││ └─────────┘ └─────────────┘ ││ ││ FINALITY: ││ ━━━━━━━━━ ││ After 2 epochs (2/3 validators agree): ││ - Block is finalized ││ - Cannot be reverted ││ - Probability of reorg ≈ 0 ││ ││ UNFINALIZED BLOCKS: ││ ━━━━━━━━━━━━━━━━ ││ - Can experience reorgs up to 2 epochs ││ - Reorg depth typically 1-12 blocks ││ │└─────────────────────────────────────────────────────────────────┘Tendermint/BFT
Section titled “Tendermint/BFT”In Tendermint consensus (Cosmos), blocks are finalized immediately upon receiving 2/3+ pre-commits.
┌─────────────────────────────────────────────────────────────────┐│ TENDERMINT IMMEDIATE FINALITY │├─────────────────────────────────────────────────────────────────┤│ ││ Each block is finalized as soon as 2/3+ validators ││ pre-commit: ││ ││ ┌─────────┐ ││ │ Block N │ ──▶ 2/3+ Pre-commits ──▶ FINALIZED ││ └─────────┘ ││ ││ Key Points: ││ ━━━━━━━━━━━━━━ ││ - No probabilistic finality ││ - Reorgs only possible during same height ││ - Rare "soft reorg" scenarios (same block height) ││ │└─────────────────────────────────────────────────────────────────┘43.3 Handling Reorgs in Applications
Section titled “43.3 Handling Reorgs in Applications”Detecting Reorgs
Section titled “Detecting Reorgs”// JavaScript/TypeScript - Detecting reorgsclass ReorgDetector { constructor() { this.lastBlockNumber = null; this.lastBlockHash = null; }
async checkBlock(block) { // Block number decreased = reorg occurred if (this.lastBlockNumber && block.number < this.lastBlockNumber) { console.log(`Reorg detected! Block ${block.number} < ${this.lastBlockNumber}`); await this.handleReorg(block.number); return; }
// Block number same but hash different = same-height reorg if (this.lastBlockNumber === block.number && block.hash !== this.lastBlockHash) { console.log(`Same-height reorg detected for block ${block.number}`); await this.handleReorg(block.number); return; }
this.lastBlockNumber = block.number; this.lastBlockHash = block.hash; }
async handleReorg(newHeadNumber) { // Rollback database to new head await this.rollbackDatabase(newHeadNumber);
// Clear cached data after new head await this.clearCache(newHeadNumber);
// Re-fetch blocks from new head await this.refetchBlocks(newHeadNumber); }}Python Reorg Handler
Section titled “Python Reorg Handler”# Python - Handling reorgsclass ReorgHandler: def __init__(self, db): self.db = db self.last_block = None
async def on_new_block(self, block): # Check for reorg if self.last_block: if block['number'] < self.last_block['number']: # Reorg detected - rollback await self.handle_reorg(block['number']) elif (block['number'] == self.last_block['number'] and block['hash'] != self.last_block['hash']): # Same-height reorg await self.handle_reorg(block['number'])
self.last_block = block await self.process_block(block)
async def handle_reorg(self, new_head): # Remove blocks after new head await self.db.rollback_to_block(new_head)
# Clear mempool await self.mempool.clear()
# Re-sync from new head await self.sync_from(new_head)43.4 Reorg Edge Cases
Section titled “43.4 Reorg Edge Cases”Uncle Blocks
Section titled “Uncle Blocks”In PoW, blocks that are replaced become “uncle” blocks but still get rewards.
┌─────────────────────────────────────────────────────────────────┐│ UNCLE BLOCKS │├─────────────────────────────────────────────────────────────────┤│ ││ Main Chain: ││ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ││ │ A │──▶│ B │──▶│ C │──▶│ D │ ││ └────┘ └────┘ └────┘ └────┘ ││ │ ││ └──▶ ┌────┐ (Uncle - got orphaned) ││ │ B' │ ││ └────┘ ││ ││ Uncle rewards: ││ ━━━━━━━━━━━━━━ ││ - Uncle block gets ~87.5% of block reward ││ - Including uncle increases main block reward ││ │└─────────────────────────────────────────────────────────────────┘Same-Height Reorgs
Section titled “Same-Height Reorgs”# Handling same-height reorgs (rare in PoS)async def handle_same_height_reorg(block_hash_1, block_hash_2): """ When two different blocks at same height are proposed. This can happen due to: - Proposer misbehavior - Network partition - Timing issues """ # Compare block timestamps block_1 = await get_block(block_hash_1) block_2 = await get_block(block_hash_2)
# Keep the one that arrived first or has more attestations if block_1.timestamp < block_2.timestamp: return block_hash_1 else: return block_hash_243.5 Best Practices for Applications
Section titled “43.5 Best Practices for Applications”Transaction Confirmation
Section titled “Transaction Confirmation”// Best practices for transaction confirmationsconst CONFIRMATION_BLOCKS = { ethereum: { regular: 12, // ~3 minutes for regular transactions defi: 64, // ~16 minutes for DeFi transactions high_value: 128, // ~32 minutes for high-value transactions }, polygon: { regular: 128, // ~4 minutes defi: 512, // ~17 minutes }};
async function confirmTransaction(txHash, value) { const network = 'ethereum'; const confirmations = value > 1000000 ? 'high_value' : 'regular'; const required = CONFIRMATION_BLOCKS[network][confirmations];
return await waitForConfirmations(txHash, required);}Database Transaction Handling
Section titled “Database Transaction Handling”-- Use database transactions to handle reorgs safelyBEGIN TRANSACTION;
-- Check current stateSELECT block_number FROM chain_state WHERE id = 1;
-- If reorg detected, rollbackDELETE FROM transactions WHERE block_number > :new_head;DELETE FROM logs WHERE block_number > :new_head;DELETE FROM receipts WHERE block_number > :new_head;
-- Update chain stateUPDATE chain_state SET block_number = :new_head WHERE id = 1;
COMMIT;43.6 Interview Questions
Section titled “43.6 Interview Questions”| Question | Answer |
|---|---|
| What is a chain reorg? | When a node switches to a different chain due to network consensus |
| How does Ethereum handle reorgs? | Uses checkpoint finality - after 2 epochs, blocks are finalized |
| How deep can reorgs be in PoS? | Typically 1-12 blocks before finality |
| How do you detect a reorg? | Monitor block number/header changes - decrease indicates reorg |
| What are uncle blocks? | Valid blocks that were orphaned due to reorg |
Summary
Section titled “Summary”- Reorgs are normal blockchain behavior
- Different consensus mechanisms have different reorg characteristics
- PoS has finality, making deep reorgs impossible
- Applications must handle reorgs by monitoring block changes
- Database transactions should be used for safe rollback
Next Chapter
Section titled “Next Chapter”In Chapter 44: Snapshot Management, we’ll explore blockchain snapshots.
Last Updated: 2026-02-20