Skip to main content

Purpose and Scope

Chain synchronization is the process of downloading and validating blockchain data (blocks, headers, receipts, and state) from network peers in order to bring a node up to the latest chain head.
This document explains the synchronization architecture and internal workflow used in StableNet.
Core components:
  • downloader.Downloader – Main synchronization engine
  • chainSyncer – Orchestrates synchronization tasks
  • queue – Schedules parallel downloads and caches results
  • peerSet – Manages peers participating in synchronization
This document covers synchronization modes, common ancestor discovery, parallel download of headers/bodies/receipts, Snap-based state synchronization, queue limits, and peer management flows. For peer discovery, see Discovery Mechanisms.
For block insertion and chain management logic, see Blockchain Management.

Synchronization Modes

StableNet supports three SyncMode values.
ModeValueBehavior
FullSync0Download all blocks and execute all transactions
SnapSync1Download headers and a recent state snapshot, then backfill history
LightSync2Download headers only, minimal validation
The current mode is stored atomically in Downloader.mode.

Mode Selection Logic

chainSyncer.modeAndLocalHead() determines the synchronization mode using the following rules:
  • If the SnapSync flag is enabled, select SnapSync
  • If there is no local head state, force SnapSync
  • If the chain has rewound below the SnapSync pivot, re-enable SnapSync
  • Otherwise, use FullSync

Downloader Architecture

Downloader is the central component of the synchronization pipeline.
FieldTypePurpose
modeatomic.Uint32Current synchronization mode
queue*queueDownload task scheduler
peers*peerSetPeer tracking and selection
blockchainBlockChainTarget for FullSync
lightchainLightChainTarget for LightSync
SnapSyncer*snap.SyncerState snapshot synchronization
skeleton*skeletonBeacon header backfill
cancelChchan struct{}Cancellation signal
Downloader is created by the eth protocol handler and controlled by chainSyncer.

Synchronization Orchestration

chainSyncer Control Loop

chainSyncer.loop() operates as a state machine and repeatedly performs the following:
  • Evaluate the current local head and remote peer states
  • Decide the next synchronization action
  • Execute synchronization and process results
  • Retry or switch modes on errors

Synchronization Execution

doSync() executes one of the following based on the selected mode:
  • FullSync – Full header, body, and receipt download
  • SnapSync – State snapshot download followed by history backfill

Finding the Common Ancestor

Synchronization begins by finding the common ancestor between the local chain and the remote chain.
  1. Span Search
    Request headers at intervals to quickly narrow down the fork range.
  2. Binary Search
    Perform a binary search within the candidate range to find the exact common ancestor.

Fork Protection

To prevent deep chain reorganizations, a protective floor is applied, limiting ancestor searches below a certain depth.

Header Synchronization

Headers are synchronized before bodies and receipts.

Header Fetch Modes

  • Legacy mode – Request headers directly from network peers

Header Processing

Downloaded headers are verified and ordered in parallel across multiple goroutines, while reorganization protection constants ensure chain stability.

Downloading Bodies and Receipts

Once headers are ready, bodies and receipts are downloaded in parallel via the queue.
  • Bodies and receipts maintain independent task queues and pending pools
  • Tasks are dynamically assigned based on peer capacity
  • Peers that fail validation are penalized or dropped

State Synchronization (Snap Sync)

Snap synchronization accelerates initial sync by skipping full transaction execution and downloading a state snapshot.

Snap Sync Stages

  1. Select a pivot block
  2. Download the state snapshot
  3. Fill missing trie nodes and code
  4. Commit the pivot
  5. Process subsequent blocks using FullSync

Pivot Block

The pivot block serves as the state root reference point.
  • Legacy mode – Request the latest head from peers
The pivot number is persisted in the database.

SnapSyncer Responsibilities

SnapSyncer downloads the following data:
  • Account trie segments
  • Contract storage data
  • Contract bytecode
  • Missing trie nodes

Ancient Store Handling

During SnapSync, older blocks may be moved directly into the ancient store.
  • Threshold is finalized blocks or head - 90000
  • Blocks below the threshold are immediately frozen
  • Recent blocks remain in the active database

Queue Task Scheduling

queue controls parallel downloads and caches results.
FieldPurpose
blockTaskPoolPending body tasks
blockTaskQueuePriority queue for body tasks
blockPendPoolIn-progress body requests
receiptTaskPoolPending receipt tasks
receiptTaskQueuePriority queue for receipt tasks
resultCacheCompleted result cache

Cache Limits

The result cache is throttled when any of the following conditions are exceeded:
  • Item count limit
  • Total memory usage limit
In this case, fetchers wait until processors consume cached results.

Peer Management

peerConnection

Each peer tracks throughput and response latency.
  • Capacity estimates for headers, bodies, and receipts
  • Performance estimation based on exponential moving averages

peerSet

peerSet manages the set of peers eligible for synchronization.

Peer Registration

New peers are registered via RegisterPeer() after completing the synchronization handshake.

Error Handling and Dropping

  • Missing data is marked via MarkLacking()
  • Repeated errors, timeouts, or invalid responses result in peer drops
  • In legacy sync paths, errors may cause immediate drops

Synchronization Workflow Summary

  1. Select peers and determine synchronization mode
  2. Find the common ancestor
  3. Download and validate headers
  4. Download bodies and receipts in parallel
  5. Perform SnapSync state synchronization if required
  6. Commit the pivot and switch to FullSync
  7. Reach the chain head and enter normal operation
This workflow represents the full synchronization lifecycle from the moment a node joins the network until it reaches the latest chain state.