Skip to main content

Nethereum.AppChain.Sync

NuGet: Nethereum.AppChain.Sync | Source: src/Nethereum.AppChain.Sync/

Nethereum.AppChain.Sync

PREVIEW — This package is in preview. APIs may change between releases.

Synchronisation services for Nethereum AppChain follower nodes — enabling anyone to independently sync, verify, and read AppChain state.

Overview​

A core promise of the AppChain model is that state is synchronisable by anyone. This package delivers on that promise: follower nodes catch up with the sequencer and maintain a verified copy of the chain state, with every block re-executed and every state root validated.

It implements a two-phase sync strategy: batch-based historical import from L1-anchored checkpoints followed by live block polling from peers. The package includes multi-peer management with automatic failover, state reconstruction through block re-execution, finality tracking (soft vs L1-finalized blocks), and coordinated sync that transitions seamlessly between batch and live phases.

Key Features​

  • Two-Phase Sync: Batch import for historical data, live polling for chain head
  • Multi-Peer Failover: Health-checked peer pool with automatic best-peer selection
  • State Reconstruction: Optional block re-execution to build and validate state
  • Finality Tracking: Distinguishes soft (peer-synced) from finalized (L1-anchored) blocks
  • Coordinated Sync: Orchestrates batch → live transitions automatically
  • Batch Management: File-based batch storage with compression and verification

Installation​

dotnet add package Nethereum.AppChain.Sync

Dependencies​

  • Nethereum.CoreChain - TransactionProcessor, IncrementalStateRootCalculator, storage interfaces
  • Nethereum.AppChain - Core chain abstraction
  • Nethereum.Model - Block headers, transactions, receipts
  • Nethereum.Util - Keccak hashing and byte utilities
  • Microsoft.Extensions.Logging.Abstractions - Structured logging

Key Concepts​

Two-Phase Synchronization​

Phase 1 (Batch Sync): Import pre-packaged block batches from anchored history. Batches are downloaded from the sequencer or mirror URLs, verified against their hash, and imported into local storage. This provides fast, finalized catch-up.

Phase 2 (Live Sync): Poll peers for new blocks as they are produced. MultiPeerSyncService follows the chain head with configurable poll intervals and automatic peer switching on failures.

Finality Tiers​

Blocks have two finality levels:

  • Soft: Recently synced from peers, may be subject to reorgs
  • Finalized: Anchored to L1, cryptographically immutable

The IFinalityTracker manages these states, enabling dApps to choose their safety guarantees.

Block Re-Execution​

BlockReExecutor optionally re-executes transactions during sync to reconstruct state locally. This validates that block state roots match headers and allows followers to serve state queries:

var reExecutor = new BlockReExecutor(
transactionProcessor, stateStore, chainConfig, stateRootCalculator);

Peer Management​

PeerManager maintains a health-checked pool of sync peers with automatic selection of the best peer by block height and latency:

var peerManager = new PeerManager(config, clientFactory);
peerManager.AddPeer("http://sequencer:8546");
await peerManager.StartHealthCheckAsync();
var bestClient = await peerManager.GetHealthyClientAsync();

Quick Start​

using Nethereum.AppChain.Sync;

var peerManager = new PeerManager(new PeerManagerConfig());
peerManager.AddPeer("http://sequencer:8546");

var syncConfig = new MultiPeerSyncConfig
{
PollIntervalMs = 100,
AutoFollow = true,
RejectOnStateRootMismatch = true
};

var syncService = new MultiPeerSyncService(syncConfig,
blockStore, txStore, receiptStore, logStore,
finalityTracker, peerManager, blockReExecutor);

await syncService.StartAsync();

Usage Examples​

Example 1: Live Block Sync with State Validation​

using Nethereum.AppChain.Sync;

var syncService = new MultiPeerSyncService(
new MultiPeerSyncConfig { PollIntervalMs = 100, AutoFollow = true },
blockStore, txStore, receiptStore, logStore,
finalityTracker, peerManager, blockReExecutor);

syncService.BlockImported += (sender, args) =>
{
Console.WriteLine($"Block {args.Header.BlockNumber} imported");
};

syncService.Error += (sender, args) =>
{
Console.WriteLine($"Sync error: {args.Message}");
};

await syncService.StartAsync();

Example 2: Coordinated Two-Phase Sync​

using Nethereum.AppChain.Sync;

var coordinated = new CoordinatedSyncService(
new CoordinatedSyncConfig { AutoStart = true },
batchSyncService, liveSyncService,
finalityTracker, anchorService, batchStore);

coordinated.SyncProgressChanged += (sender, args) =>
{
Console.WriteLine($"Phase: {args.Phase}, Block: {args.BlockNumber}");
};

coordinated.BatchFinalized += (sender, args) =>
{
Console.WriteLine($"Batch finalized up to block {args.ToBlock}");
};

await coordinated.StartAsync();

Example 3: Batch Import​

using Nethereum.AppChain.Sync;

var importer = new BatchImporter(blockStore, txStore, receiptStore, logStore);
var result = await importer.ImportBatchFromFileAsync(
filePath: "chain-420420-blocks-0-100.gz",
expectedHash: batchHash,
verificationMode: BatchVerificationMode.Full,
compressed: true);

Console.WriteLine($"Imported {result.BlockCount} blocks, {result.TransactionCount} transactions");

Example 4: Peer Management​

using Nethereum.AppChain.Sync;

var peerManager = new PeerManager(new PeerManagerConfig
{
HealthCheckIntervalMs = 5000,
HealthCheckTimeoutMs = 3000,
MaxFailuresBeforeRemoval = 5
});

peerManager.AddPeer("http://node1:8546");
peerManager.AddPeer("http://node2:8546");
peerManager.AddPeer("http://node3:8546");

peerManager.PeerStatusChanged += (sender, args) =>
{
Console.WriteLine($"Peer {args.Url}: healthy={args.IsHealthy}");
};

await peerManager.StartHealthCheckAsync();
var best = peerManager.GetBestPeer();

API Reference​

MultiPeerSyncService​

Real-time block following with multi-peer failover.

public class MultiPeerSyncService : ILiveBlockSync
{
public long LocalTip { get; }
public long RemoteTip { get; }
public LiveSyncState State { get; }

public Task StartAsync(CancellationToken ct = default);
public Task StopAsync();
public Task SyncToLatestAsync();
public Task SyncToBlockAsync(long blockNumber);

public event EventHandler<BlockImportedEventArgs>? BlockImported;
public event EventHandler<SyncErrorEventArgs>? Error;
}

CoordinatedSyncService​

Two-phase sync orchestration (batch then live).

public class CoordinatedSyncService
{
public Task StartAsync(CancellationToken ct = default);
public Task StopAsync();

public event EventHandler<SyncProgressEventArgs>? SyncProgressChanged;
public event EventHandler<BatchFinalizedEventArgs>? BatchFinalized;
}

PeerManager​

Peer pool with health checking and best-peer selection.

public class PeerManager : IPeerManager
{
public void AddPeer(string url);
public void RemovePeer(string url);
public SyncPeer? GetBestPeer();
public Task<ISequencerRpcClient?> GetHealthyClientAsync();
public Task StartHealthCheckAsync(CancellationToken ct = default);
}

IFinalityTracker​

Block finality state management.

public interface IFinalityTracker
{
Task<bool> IsFinalizedAsync(long blockNumber);
Task<bool> IsSoftAsync(long blockNumber);
Task MarkAsFinalizedAsync(long blockNumber);
Task MarkRangeAsFinalizedAsync(long fromBlock, long toBlock);
Task<long> GetLatestFinalizedBlockAsync();
}

BatchInfo​

Batch metadata structure.

Key properties:

  • FromBlock / ToBlock - Block range
  • BatchHash - Content hash for verification
  • Status - Pending, Created, Written, Anchored, Verified, Imported, Failed
  • ToBlockStateRoot / ToBlockTxRoot / ToBlockReceiptRoot - Root hashes

Used By (Consumers)​

Dependencies​

Additional Resources​