A validator that authors a perfect block has achieved nothing until every other validator has it. Propagation is where a chain's theoretical throughput meets the physics of the network. This post describes how EmpoorioChain moves blocks and transactions between nodes, and how it measures whether that is going well.
The base layer: libp2p
EmpoorioChain nodes are Substrate nodes, and they inherit Substrate's networking: peer discovery through Kademlia, block announcement and request/response protocols, and gossip for consensus messages (GRANDPA votes travel on their own gossip topic). Blocks are announced by header and fetched by body, so a node only downloads a block once regardless of how many peers announce it.
This stack is battle-tested across many Substrate networks. EmpoorioChain does not reinvent it; it configures it and adds one thing on top.
The addition: DAG-aware transaction gossip
Before a transaction is in a block, it is in the transaction pool, and pools gossip. EmpoorioChain's pool is a DAG mempool: transactions are vertices, and edges express dependencies — the nonce ordering of one sender, and read/write conflicts on storage between different senders. The gossip layer (runtime/src/mempool/gossip.rs) knows about this structure and can propagate:
- individual DAG vertices (a transaction with its dependency hints), and
- DAG batches — groups of independent transactions already partitioned for parallel execution.
Why does it matter? Because the block author downstream wants to execute independent transactions in parallel. If the batches arrive already partitioned, the author does less planning work per block. And if a node receives a transaction whose dependencies it has not seen, it knows to wait rather than to reject.
The pool also enforces deterministic ordering (fee priority, then nonce, then id), rejects duplicates and detects dependency cycles. Determinism is not optional: two honest nodes given the same set of transactions must produce the same ordering, or the author's block will look wrong to everyone else.
Measuring it
The node exposes propagation and pool metrics to Prometheus:
emp_txpool_pending_txs— how many transactions are waitingemp_txpool_dag_widthandemp_txpool_dag_depth— the shape of the dependency graphemp_txpool_duplicate_txs— how much of the gossip is wastedemp_txpool_propagation_delay_ms_p95— how long a transaction takes to reach this node after it was first seen elsewhere
A growing depth with a shrinking width means senders are queuing behind their own nonces; a growing width means a lot of independent load — good news for parallel execution. A rising p95 propagation delay is the early warning that the network layer, not the runtime, is becoming the bottleneck.
What is deliberately not done yet
The engineering docs are explicit that full DAG-based consensus (Bullshark-style) is not active. Switching to it would require replacing the block authorship pipeline itself, not just the queue in front of it. Turning on DAG ordering while Aura still authors linear blocks would create the illusion of a DAG with none of its properties. So the production choice is stated plainly: Aura and GRANDPA for consensus, an improved DAG mempool in front, measure under load, and only then decide whether to move authorship.
The criteria for that move are written down — a proposer integrated with the pool, identical state roots against Aura/GRANDPA under the same load, Zombienet tests with 4 and 10 validators under artificial latency, adversarial spam and fork tests, and a rollback plan. Until every box is ticked, the gossip layer is an optimisation of what exists, not a new consensus.
Based on MEMPOOL_DAG_ORDERING.md and CONSENSUS_STATUS.md.


