Introducing Axyl. The Rayls Public Chain Consensus Algorithm.

Axyl orders and finalises transactions on the Rayls Public Chain. This page explains how it works, starting from the basics.

What a consensus algorithm has to do

A blockchain is a shared list of transactions. Every node on the network needs to end up with exactly the same list, in exactly the same order, even though transactions arrive over the internet from many different places at slightly different times and even though some of the machines running the network might be slow, broken, or actively hostile.

The piece of software that solves this problem is called a consensus algorithm. Its job is to take the messy reality of a distributed network — partial failures, network delays, conflicting submissions — and produce a single agreed-upon order that every honest participant can compute independently and arrive at the same answer.

BFT: tolerating bad actors

Different consensus algorithms make different assumptions about how nodes can fail. The strongest assumption — and the one Axyl uses — is Byzantine fault tolerance, or BFT.

A node is said to be Byzantine if it can do anything: crash, go offline, send different messages to different peers, sign conflicting things, lie about what it has seen, or coordinate with other malicious nodes to attack the network. BFT algorithms keep working correctly even when some fraction of the participants behave this way. The classical result, going back to the 1980s, is that a BFT system can tolerate up to one-third of its participants being Byzantine and still agree on a consistent order. If N is the total number of participants and f is the number of Byzantine ones, the system stays safe as long as N ≥ 3f + 1.

In practice this gives rise to two thresholds that come up everywhere in BFT:

  • 2f+1 — a supermajority. Any two groups of size 2f+1 must overlap in at least one honest node, which is what lets the protocol commit decisions without ambiguity.
  • f+1 — a validity threshold. Any group of size f+1 must contain at least one honest node, which is enough to be confident that a piece of data isn't entirely fabricated.

These two numbers will appear repeatedly below. They are not arbitrary — they are the smallest sets that give the safety properties BFT requires.

DAG: how the data is organised

Most blockchains structure their consensus around a chain of blocks. Each block contains some transactions, references the previous block by its hash, and is produced by a single chosen leader for that round. Bitcoin, Ethereum, Solana, and most older proof-of-stake systems work this way.

Axyl uses a different structure: a DAG, short for directed acyclic graph. Instead of one block per round produced by one leader, every validator produces its own piece of data each round, and each piece references multiple pieces from the previous round rather than just one. The result looks like a graph that grows upward in layers: many nodes at each layer, each pointing back to several nodes in the layer below.

   round 4    [ ]   [ ]   [ ]   [ ]
                \  / \   / \   / \
   round 3    [ ]   [ ]   [ ]   [ ]
                \  / \   / \   / \
   round 2    [ ]   [ ]   [ ]   [ ]
                \  / \   / \   / \
   round 1    [ ]   [ ]   [ ]   [ ]

It's directed because the references only point one way (newer to older). It's acyclic because you can't follow references in a cycle — you always end up further back in time.

The advantage is parallelism. In a chain-based protocol, only one validator is producing data at a time and everyone else waits. In a DAG, every validator is producing data simultaneously, so the network's total throughput scales with the combined bandwidth of the whole committee instead of being capped by whichever single machine is the current leader.

The catch is that a DAG by itself doesn't give you a single order — it gives you a graph with many possible orderings. So a DAG-based consensus algorithm has two jobs: build the graph, and then deterministically pick one order out of it. Axyl handles these as two separate layers, Narwhal for building the graph and Bullshark for ordering it.

Narwhal and Bullshark

Axyl's two layers come from a pair of academic papers. Narwhal (Danezis et al., 2021) describes how to build the DAG: how validators package transactions, how they share them, and how the graph stays well-connected even when some validators are slow. Bullshark (Spiegelman et al., 2022) describes how to read a Narwhal DAG and produce a single deterministic order out of it.

The Narwhal layer is responsible for data availability — making sure every validator has every piece of data, and being able to prove it. The Bullshark layer is responsible for ordering — turning the graph into the canonical sequence of transactions that the EVM (the Ethereum Virtual Machine, the runtime that actually executes smart contracts and produces the chain's state) executes.

Keeping them separate is what makes the system fast. Narwhal runs continuously in the background, gossiping batches of transactions and building the DAG round after round, regardless of whether any particular round will commit anything. Bullshark sits on top and periodically reads the DAG to identify which parts can now be safely ordered and committed. Because the data is already everywhere by the time Bullshark runs, ordering is essentially free — just a deterministic walk over a graph everyone already has.

The committee

Every epoch (a 24-hour time window) the Rayls Public Chain runs with a fixed committee of validators registered through the on-chain ConsensusRegistry contract. The committee is the same for the full 24 hours; it can only change at an epoch boundary.

Each validator has a BLS public key (BLS is a signature scheme whose useful property is that many individual signatures on the same message can be combined into one short aggregate signature, which keeps certificates compact even when hundreds of validators have signed them) and an associated voting power. At launch every validator has a voting power of 1 and the validator set is operated by the Rayls Foundation. Both of these will change over time in line with the published decentralisation roadmap — voting power will eventually reflect stake, and validator selection will move to a permissionless process.

Axyl uses two thresholds, both expressed as a sum of voting power across the committee:

ThresholdFormulaMeaning
Quorum (2f+1)⌊2·N/3⌋ + 1A supermajority — sufficient to commit
Validity (f+1)⌈N/3⌉At least one honest validator — sufficient to advance

Where N is total voting power and f is the maximum tolerated Byzantine voting power. The protocol provides safety as long as Byzantine voting power stays below f, and liveness as long as honest voting power above 2f+1 is reachable.

Workers, primaries, and batches

Each validator runs two roles:

A worker is responsible for data availability. Workers pull transactions from the local Reth (the Ethereum execution-layer client that the Rayls Public Chain is built on, written in Rust) transaction pool, select the highest-fee transactions that extend the canonical tip, seal them into a batch, and broadcast that batch to the workers on every other validator. Worker peers verify the batch is well-formed (size limits, gas limits, transactions decode and pass basic checks) and acknowledge it. Once a worker has collected acknowledgements representing 2f+1 voting power — a process handled by the QuorumWaiter — the batch is considered available across the committee and its 32-byte digest is forwarded to the local primary. The transactions themselves stay in the pool until the batch is actually committed; this is what guarantees that no transaction is lost if the batch fails to make it into the DAG.

A primary is responsible for building the DAG. The primary takes batch digests from its workers, combines them with parent certificates from the previous round, and proposes a header. It broadcasts the header to peer primaries and collects votes. Once it has votes representing 2f+1 voting power, it aggregates them into a certificate and gossips that certificate. Certificates are the nodes of the DAG.

Critically, transactions are not validated on the path into a batch and are not gossiped individually. Each validator's transaction pool is private — there is no public mempool (the shared pool of pending transactions that public chains like Ethereum maintain, which lets anyone watch transactions before they are included in a block). This eliminates a class of front-running and sandwich attacks that depend on observing pending transactions. The trade-off is that two validators may independently include the same transaction in different batches, in which case the duplicate is detected and skipped at execution time. This is treated as an acceptable inefficiency.

The DAG, round by round

The primary advances in rounds. Each round produces at most one certificate per validator. A header in round r+1 must reference a 2f+1 voting-power quorum of certificates from round r as its parents, which is what makes the structure a DAG and what makes the DAG well-connected.

Rounds alternate in role:

  • Even rounds elect a leader. There is exactly one leader per even round, picked deterministically by the leader schedule. The leader's certificate is the candidate to anchor a commit.
  • Odd rounds are voting rounds. A certificate in round r+1 (odd, when r is even) implicitly votes for the round-r leader by including its certificate digest in its parents.

A leader is committed when it accumulates f+1 voting power of support from the round above it — that is, when at least f+1 voting power of round-r+1 certificates list the leader as a parent. The threshold is f+1 rather than 2f+1 because the Bullshark safety argument only requires that at least one honest validator observed the leader before voting, and f+1 voting power guarantees that.

Committing a leader

When process_certificate inserts a new certificate at round r+1, Bullshark checks whether the leader at round r-1 (two rounds back, since headers reference parents from the previous round) has accumulated enough support. If it has, the leader's entire causal history — every certificate it transitively points to that has not been committed yet — is flattened into a linear sequence by a depth-first walk. This sequence is the committed sub-DAG.

                 round r+2 (current)
            inserting certificate ─┐
                                    ▼
   round r+1   [c]   [c]   [c]   [c]      ← votes for leader
                  \   |   /   /
                   \  |  /   /              f+1 voting power supports L?
                    \ | /   /                yes → commit L
   round r      [c]   [L]   [c]   [c]      ← leader at this round
                  \    |   /   /
                   \   |  /   /
   round r-1    [c]   [c]   [c]   [c]

If the leader doesn't yet have f+1 support, no commit happens — the DAG keeps growing and Bullshark will check again when more certificates arrive. This is what makes the protocol resilient to slow validators: a missing validator delays a single round but doesn't block the chain.

When a leader does commit, Bullshark walks backward through past unconnected leaders and commits any of them that are reachable in the DAG from the new leader. This is how the protocol catches up after a period of weak commits — one strong leader can "rescue" several earlier ones in the same step.

Producing the same order on every node

For the chain to work, every validator has to execute the same transactions in the same order. If two validators ended up with even slightly different orderings, they would compute different account balances and the chain would split.

The committed sub-DAG handles this. Once Bullshark decides to commit a leader, the order is no longer a matter of local opinion: every validator runs the same fixed procedure on the same graph, so they all produce the same list. The procedure is to start at the leader and walk through the certificates it depends on, then their dependencies, and so on, always visiting things in the same order. When two certificates are equally valid candidates to visit next, the tie is broken by comparing their digests — a number that every validator computes identically.

The output of this walk is a flat list of certificates. Each certificate points to one or more batches, and each batch is itself an ordered list of transactions. Reading the list of certificates, then the batches each one references, then the transactions inside each batch, gives the final transaction order for the round.

Reth then takes that order and executes it, producing one EVM block per batch. If a transaction turns out to be invalid at execution time — a bad signature, a sender without enough balance, a nonce that doesn't line up, or a duplicate that was already executed in an earlier batch — it is silently skipped. No fee is charged and no revert is recorded. This is safe because the batch already passed basic well-formedness checks during consensus, and it means the consensus layer doesn't have to know anything about EVM rules.

There is one developer-experience consequence to be aware of. Because invalid transactions are dropped before they ever land in a block, there is no on-chain receipt to look up afterwards — and the Rayls Public Chain does not expose a public mempool, so the standard "pending transactions" API that wallets and tools normally rely on isn't available either. The practical effect is that if a user sends a transaction with a bad signature, a wrong nonce, or insufficient balance, MetaMask and similar wallets will show it stuck pending forever with no way to find out what went wrong. dApps building on the Rayls Public Chain are expected to track their own submissions: keep the transaction hash after sending, poll for a receipt, and after a reasonable timeout (a few epochs) treat the absence of a receipt as a drop rather than a pending state. A status endpoint for looking up submission outcomes is on the roadmap.

Leader election

The leader for each even round is picked by simple rotation. Every validator takes a turn, in order, and the round number determines whose turn it is. With voting power of 1 across the committee at launch, this is a straight round-robin.

Sitting on top of this rotation is a safety mechanism called the leader swap table. Its job is to skip over validators that have stopped doing their job properly — for example, a validator whose machine has gone offline, lost its network connection, or fallen far behind the rest of the committee. Rather than let the chain stall every time the rotation lands on a broken validator, the swap table quietly substitutes a working one in their place.

The swap table is built from a reputation score that Bullshark keeps for every validator. Each time a leader is committed, validators that helped commit it (by referencing it in their own certificates the next round) get a point. Validators that consistently miss the leader, propose late, or go offline don't accumulate points and fall behind their peers.

Periodically the chain looks at the accumulated scores and rebuilds the swap table:

  • Validators with scores far below the average are tagged as struggling.
  • Validators with scores well above the average are tagged as healthy.
  • Whenever the rotation is about to make a struggling validator the leader, the swap table redirects to a healthy validator instead. The choice is seeded by the round number so every validator picks the same replacement.

One subtlety here, worth flagging openly. Because the seed is derived only from the round number, and the pool of healthy candidates is derived from reputation scores that are visible on-chain, an outside observer who notices that a validator has gone quiet can predict in advance exactly which validator will be promoted to replace it on every future round. With the launch committee — foundation-operated, well-provisioned infrastructure, all validators on the same operational baseline — this isn't a real concern. Once the validator set opens up under the decentralisation roadmap, however, an attacker could in principle pre-target the predicted replacement with a denial-of-service attack to stall progress. The fix is straightforward: mix in some chain-derived randomness alongside the round number. The same approach is already used for the committee shuffle via the extra_data field, and the same source can be used here. This will be hardened before the validator set opens up; at launch it is a known trade-off in exchange for a simple, deterministic schedule.

A struggling validator is not removed from the committee — it can still propose batches, vote on headers, and earn its way back. It just stops being given a turn as leader until its scores recover. Scores reset periodically so a temporarily-broken validator that has come back online has a chance to be promoted again.

At launch, with all validators operated by the foundation and running on well-provisioned infrastructure, the swap table will rarely fire. Its main purpose is to keep the chain healthy as the validator set grows and diversifies under the decentralisation roadmap.

Headers, votes, and certificates

This section spells out exactly what a primary signs and what a certificate contains. It can be skipped on a first read.

A header is a primary's proposal for a single round. It contains:

  • The primary's identity and signature.
  • The round number.
  • A list of parent certificates from the previous round, together representing at least 2f+1 voting power.
  • A list of batch digests pointing to worker batches that have already reached worker quorum.
  • A timestamp.

A vote is what a peer primary returns after checking that a header is valid. The peer verifies that the header is well-formed, that every batch it references is one the peer has already seen, and that the parent set really does add up to 2f+1 voting power. If everything checks out, the peer signs the header with its BLS key and returns the signature.

A certificate is a header plus a single aggregate signature that represents 2f+1 voting power of votes. Because BLS signatures combine, the certificate stays compact — one signature, one verification — even if many primaries have signed.

Certificates are the nodes of the DAG. Once a certificate exists, it is permanent: it has a fixed digest, it can be gossiped between nodes, and any honest validator can verify it without trusting whoever sent it.

All of this state — certificates, votes, the index of which validator produced which round's header — is stored in MDBX (the embedded key-value database that Reth uses for on-disk storage) so a node that restarts can rebuild its in-memory DAG without re-downloading the history. Old certificates that sit below a configured depth are eventually deleted, because once a sub-DAG has been committed there's no reason to keep its ancestors around except for serving them to nodes that are still catching up.

Epochs and committee rotation

Time on the Rayls Public Chain is divided into epochs of 24 hours each. The active committee is fixed for the duration of an epoch. At an epoch boundary:

  • The on-chain ConsensusRegistry runs concludeEpoch as an EVM system call, which crystallises stake changes, applies incentives, and finalises the next committee.
  • Each validator from the outgoing committee signs an EpochRecord summarising the epoch — the active committee, the next committee, the last execution block, and the last consensus header. Signatures are aggregated into an EpochCertificate representing 2f+1 voting power.
  • Worker batch builders shut down at the boundary and restart against the new committee.
  • Bullshark's reputation scores reset and the leader schedule is rebuilt against the new committee.
  • The EIP-1559 parameters are recomputed. The base fee itself tracks demand per block under the standard EIP-1559 rule (it goes up when blocks are full, down when they're empty); only the parameters of that rule — the target gas usage and the adjustment speed — are recalibrated at epoch boundaries.

The chain of EpochRecords is what allows trustless light-sync: a node that knows only the genesis committee can request each epoch record and certificate from any peer, verify the BLS aggregate signature against the previous epoch's committee, and walk forward to the present without trusting any single source. This metadata chain is independent of the execution chain and can be verified without running the EVM.

Why this is safe

The safety argument for Bullshark is straightforward in two parts.

First, two honest validators that both commit something at round r commit the same thing. The leader at round r is deterministic from the schedule and the swap table, both of which are derived from past committed state. The commit rule requires f+1 voting power of support, and any two f+1 voting power sets must overlap on at least one honest validator, who would not sign two conflicting headers in the same round.

Second, the recursive commit rule — when leader L_r commits, scan backward and commit any reachable L_{r-2}, L_{r-4}, … — is consistent across validators because reachability in the DAG is defined by the certificates themselves, which every honest validator has agreed on via the certificate quorum. There is no ambiguity about whether L_r reaches L_{r-2}; either the path exists in the certificates, or it doesn't.

Liveness rests on the proposer continuing to advance rounds whenever a quorum of parents is available, and on the leader schedule eventually picking an honest leader. The reputation-based swap table accelerates this by shifting bad leaders out of the rotation rather than waiting for them to time out repeatedly.

What lives where

For developers reading the code, the consensus algorithm is implemented in:

  • crates/consensus/worker/ — batch building, validation, gossip, and the quorum waiter.
  • crates/consensus/primary/proposer/ — round advancement, header construction, and timing.
  • crates/consensus/primary/certifier.rs — header broadcast, vote collection, certificate aggregation.
  • crates/consensus/primary/consensus/bullshark.rs — the commit rule and sub-DAG ordering.
  • crates/consensus/primary/consensus/leader_schedule.rs — round-robin leader election and the reputation-based swap table.
  • crates/consensus/state-sync/ — catching up missing certificates and batches from peers.
  • crates/middleware/orchestrator/epoch_manager/ — epoch boundary handling and committee rotation.

The Axyl implementation derives from the Sui codebase under Apache 2.0 and adapts it to a closed, foundation-operated validator set with per-validator voting power, BLS aggregate signatures, EVM execution via Reth, and a deterministic leader-swap mechanism driven by on-chain reputation. The original Narwhal and Bullshark papers linked at the top cover the formal protocol descriptions and proofs.