Network Synchronization
Synchronizing blockchain state across network nodes.
Advanced⏱️ 55 min📚 Prerequisites: 1
Network Synchronization
Network sync ensures all nodes have the same blockchain state. New nodes need to download and verify the entire blockchain.
Sync Process
- Initial Handshake: Connect to peers
- Get Best Block: Find highest block height
- Request Blocks: Download blocks in batches
- Validate Blocks: Verify each block
- Update State: Apply blocks to local state
- Catch Up: Continue until synced
Sync Strategies
Full Sync
Download and validate every block:
RUSTfn full_sync(node: &mut Node, target_height: u64) { let mut current_height = node.blockchain.height(); while current_height < target_height { let blocks = request_blocks(current_height, 100); for block in blocks { if validate_block(&block) { node.blockchain.add_block(block); current_height += 1; } } } }
Fast Sync
Download block headers first, then bodies:
- Faster initial sync
- Verify headers first
- Download bodies in parallel
Light Sync
Only download block headers:
- For light clients
- Verify headers only
- Request full blocks when needed
State Sync
RUSTstruct SyncState { current_height: u64, target_height: u64, is_syncing: bool, blocks_downloaded: u64, } impl SyncState { fn progress(&self) -> f64 { if self.target_height == 0 { return 0.0; } (self.current_height as f64 / self.target_height as f64) * 100.0 } }
Fork Resolution During Sync
- Multiple chains: Request from multiple peers
- Compare: Find common ancestor
- Choose: Select longest valid chain
- Reorganize: Switch to better chain if found
Optimization
- Parallel downloads: Download from multiple peers
- Batch requests: Request multiple blocks at once
- Caching: Cache verified blocks
- Checkpointing: Trust checkpoints for faster sync
Code Examples
Sync State
Tracking synchronization progress
RUST
struct SyncState {
current_height: u64,
target_height: u64,
is_syncing: bool,
}
impl SyncState {
fn new() -> Self {
SyncState {
current_height: 0,
target_height: 0,
is_syncing: false,
}
}
fn start_sync(&mut self, target: u64) {
self.target_height = target;
self.is_syncing = true;
println!("Starting sync to height {}", target);
}
fn update_progress(&mut self, new_height: u64) {
self.current_height = new_height;
if self.current_height >= self.target_height {
self.is_syncing = false;
println!("Sync complete!");
} else {
let progress = (self.current_height as f64 / self.target_height as f64) * 100.0;
println!("Sync progress: {:.1}% ({}/{})",
progress, self.current_height, self.target_height);
}
}
fn is_complete(&self) -> bool {
!self.is_syncing && self.current_height >= self.target_height
}
}
fn main() {
let mut sync = SyncState::new();
sync.start_sync(1000);
sync.update_progress(250);
sync.update_progress(500);
sync.update_progress(750);
sync.update_progress(1000);
println!("Sync complete: {}", sync.is_complete());
}Explanation:
Sync state tracks the synchronization progress. It monitors current height, target height, and calculates progress percentage.
Block Request
Requesting blocks from peers
RUST
struct BlockRequest {
from_height: u64,
count: u64,
}
struct SyncManager {
current_height: u64,
target_height: u64,
}
impl SyncManager {
fn new() -> Self {
SyncManager {
current_height: 0,
target_height: 0,
}
}
fn request_blocks(&self, batch_size: u64) -> BlockRequest {
let remaining = self.target_height - self.current_height;
let count = remaining.min(batch_size);
BlockRequest {
from_height: self.current_height + 1,
count,
}
}
fn process_blocks(&mut self, blocks_received: u64) {
self.current_height += blocks_received;
println!("Processed {} blocks. Current height: {}",
blocks_received, self.current_height);
}
}
fn main() {
let mut manager = SyncManager {
current_height: 100,
target_height: 1000,
};
let request = manager.request_blocks(100);
println!("Requesting {} blocks from height {}",
request.count, request.from_height);
manager.process_blocks(100);
}Explanation:
Block requests are made in batches for efficiency. The sync manager tracks what blocks are needed and requests them from peers.
Exercises
Sync Progress
Create a sync manager that tracks progress!
Starter Code:
RUST
struct SyncManager {
current: u64,
target: u64,
}
fn main() {
let mut sync = SyncManager::new();
sync.target = 1000;
sync.update_progress(500);
println!("Progress: {}%", sync.get_progress_percentage());
}