3) Make it distributed
Now we make one node become a network.
Peer discovery
- Start from static bootnodes.
- Enable optional mDNS for local development clusters.
Data propagation and sync
- Use pubsub gossip for tx and block announcements.
- On startup, request missing blocks using request/response.
Fork choice (simple by design)
For this capstone keep fork choice simple: highest height / longest chain.
That is enough to demonstrate distributed behavior, while also being honest that consensus is much deeper than this chapter.
Observability
Instrument key spans:
block_validatemempool_insertblock_importsync_requestsync_apply
#![allow(unused)]
fn main() {
use tracing::{info_span, Instrument};
let span = info_span!("block_import", height = block.header.height);
async move {
import_block(block).await
}
.instrument(span)
.await?;
}
Try it: 3 local nodes
cargo run -p blockchain_node -- --id n1 --port 7001 --bootnodes ""
cargo run -p blockchain_node -- --id n2 --port 7002 --bootnodes "/ip4/127.0.0.1/tcp/7001"
cargo run -p blockchain_node -- --id n3 --port 7003 --bootnodes "/ip4/127.0.0.1/tcp/7001"
Then submit one tx to n2 and verify n1/n3 logs show propagation and block import.
Deliverable
A local 3-node demo where a block observed on one node is imported by the other two.