Blockchain 6 min read

Decoding Ethereum’s eth.syncing API: A Complete Source‑Code Walkthrough

This article dissects the Go implementation of Ethereum’s eth.syncing API, explaining the Syncing method, the SyncProgress struct, how block synchronization statistics are gathered, and how different sync modes affect the returned values, all illustrated with real source code excerpts.

Senior Brother's Insights
Senior Brother's Insights
Senior Brother's Insights
Decoding Ethereum’s eth.syncing API: A Complete Source‑Code Walkthrough

Introduction

When monitoring an Ethereum node’s synchronization status, developers often call eth.syncing. This article examines the Go source code behind the Syncing RPC method, clarifying what each returned field represents and how the values are computed.

Syncing Method Source Code

// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not
// yet received the latest block headers from its peers. In case it is synchronizing:
// - startingBlock: block number this node started to synchronise from
// - currentBlock:  block number this node is currently importing
// - highestBlock:  block number of the highest block header this node has received from peers
// - pulledStates:  number of state entries processed until now
// - knownStates:   number of known state entries that still need to be pulled
func (s *PublicEthereumAPI) Syncing() (interface{}, error) {
    progress := s.b.Downloader().Progress()
    if progress.CurrentBlock >= progress.HighestBlock {
        return false, nil
    }
    // Otherwise gather the block sync stats
    return map[string]interface{}{
        "startingBlock": hexutil.Uint64(progress.StartingBlock),
        "currentBlock":  hexutil.Uint64(progress.CurrentBlock),
        "highestBlock":  hexutil.Uint64(progress.HighestBlock),
        "pulledStates":  hexutil.Uint64(progress.PulledStates),
        "knownStates":   hexutil.Uint64(progress.KnownStates),
    }, nil
}

The method returns false when the node is fully synced (i.e., CurrentBlock is greater than or equal to HighestBlock). Otherwise it builds a map containing synchronization statistics.

Corresponding Data Structure

// SyncProgress gives progress indications when the node is synchronising with the Ethereum network.
type SyncProgress struct {
    StartingBlock uint64 // Block number where sync began
    CurrentBlock  uint64 // Current block number where sync is at
    HighestBlock  uint64 // Highest alleged block number in the chain
    PulledStates uint64 // Number of state trie entries already downloaded
    KnownStates  uint64 // Total number of state trie entries known about
}

This struct mirrors the fields returned by the RPC call, providing a clear mapping between the internal progress tracker and the JSON response.

How the Progress Values Are Obtained

func (d *Downloader) Progress() ethereum.SyncProgress {
    d.syncStatsLock.RLock()
    defer d.syncStatsLock.RUnlock()
    var current uint64
    switch d.mode {
    case FullSync:
        current = d.blockchain.CurrentBlock().NumberU64()
    case FastSync:
        current = d.blockchain.CurrentFastBlock().NumberU64()
    case LightSync:
        current = d.lightchain.CurrentHeader().Number.Uint64()
    }
    return ethereum.SyncProgress{
        StartingBlock: d.syncStatsChainOrigin,
        CurrentBlock:  current,
        HighestBlock:  d.syncStatsChainHeight,
        PulledStates: d.syncStatsState.processed,
        KnownStates:   d.syncStatsState.processed + d.syncStatsState.pending,
    }
}

The Progress method locks the sync statistics, determines the current block based on the node’s sync mode ( FullSync, FastSync, or LightSync), and then assembles a SyncProgress value.

Sync Mode Differences

Full mode : CurrentBlock reflects the height of the fully validated block.

Fast mode : CurrentBlock reflects the height of the fast‑sync block.

Light mode : CurrentBlock reflects the number of the current header.

KnownStates is calculated as PulledStates + pending, representing total known state entries.

Conclusion

By tracing the implementation of eth.syncing, we see that the RPC response directly reflects the internal SyncProgress struct, with fields populated from the downloader’s progress tracker. Understanding these details helps developers interpret synchronization status accurately and debug node behavior.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

GoAPIBlockchainEthereumeth.syncingSyncing
Senior Brother's Insights
Written by

Senior Brother's Insights

A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.