Aevum Native Transport
A small, known set of validators doesn't need a generalized p2p mesh. It needs fast, reliable TCP between peers it already knows about. Here's what replaced libp2p, and why.
TL;DR. ANT is the transport Aevum validators use for consensus traffic — persistent TCP per peer, length-prefixed framing, a per-peer state machine, and dedup at the receive path, running in its own worker thread so consensus traffic can never starve keep-alives.
ANT is the transport layer Aevum validators use for consensus traffic: a persistent TCP connection per peer, length-prefixed framing, a per-peer finite state machine, and content-fingerprint dedup at the receive path. It runs in its own Node.js worker thread so a consensus storm can never starve the keep-alive loop. Block sync, RPC, and everything client-facing keeps using plain HTTP over the same JSON-RPC port.
Why we built it
The first attempt used libp2p, and it didn't hold up. Cross-datacenter mesh connections between validators would drop within seconds under sustained consensus load. The gossipsub keep-alive loop shared an event loop with the BFT engine, so a burst of votes would starve the keep-alives — peers would decide each other were dead, prune the mesh, and vote propagation would stall.
After three weeks chasing it, the conclusion was that a generalized peer-to-peer mesh was the wrong abstraction for this problem. Aevum validators are a small, known set with stable addresses and high mutual trust — what the network actually needs is fast, reliable TCP between N pre-known peers, not dynamic peer discovery and DHT routing.
ANT shipped in late June 2026 and replaced libp2p within a day. Zero disconnects since.
How it works
- Persistent TCP connections — one per peer. Both sides dial; the lower address wins and the other side disconnects, which avoids reconnect storms.
- Length-prefixed framing — a uint32 length followed by an SSZ-encoded payload. Simple, deterministic, and easy to debug with tcpdump.
- Per-peer finite state machine — CONNECTING → HANDSHAKING → READY → DRAINING → CLOSED, with logging at every transition for ops visibility.
- Content-fingerprint dedup — the full-mesh topology means the same vote arrives from multiple peers. Deduping it before signature re-verification dropped load averages from 4.0 to 0.07.
- Worker-thread isolation — ANT runs in its own Node worker, so the BFT engine's event loop can never block ANT's keep-alive timers, or vice versa.
The handshake currently uses TLS for transport security. A post-quantum, ML-DSA-signed peer-identity handshake is queued for before mainnet.
When HTTP is still used
ANT only carries consensus traffic. Three other things stay on plain HTTP:
- Block sync — catchup nodes pull-poll
/block-raw/:non peers in 32-block batches; pull-based and NAT-friendly. - JSON-RPC — wallets, dapps, indexers, and every other client-facing service.
- Pull-mode vote relay — validators behind restrictive NATs poll a bootnode's
/consensus/round-snapshotendpoint instead of joining the ANT mesh directly, trading a little latency for working behind aggressive corporate firewalls.
ANT solves the tight-mesh problem. HTTP solves the work-everywhere problem.
Source and design notes
ANT lives in the AevumChain repository under packages/node/src/net/ant/ — about 700 lines of TypeScript, 15 tests. The decision to isolate it in a worker thread, and the reasoning behind dropping libp2p, are both documented in the dev log for anyone who wants the full trail. See Architecture for how ANT fits into the rest of the stack.