Lux Proposals
← All proposals
LP-0219Draft

Status

Draft. No backwards compatibility. No flag day.

Activated at the genesis of the new final Lux network: **2025-12-25

16:20 Pacific (unix 1766708400)**. The pre-Quasar Edition Lux network

(2020–2025) had no rollup-to-rollup atomic primitive and is a separate

network out of scope.

Abstract

LP-218 deploys ZAP-native PQ rollups as Tier-3 chains on Z-Chain. Each

rollup has a sequencer that batches transactions, Pulsar-signs the

batch, and submits a RollupBatchTx to Z-Chain; Z-Chain verifies the

Pulsar signature via the P3Q precompile at slot 0x012205 and the

batch inherits Z-Chain's QuasarCert finality.

§"Cross-rollup atomicity" in LP-218 observes that two rollups on the

same Z-Chain trivially commit atomically when their RollupBatchTxes

land in the same Z-Chain block — they share the same QuasarCert. But

"share the same block" is not a guarantee a coordinator can construct;

it depends on Z-Chain's wave admission ordering. LP-218 §"Future work"

item 1 calls for a formal protocol.

LP-219 supplies that protocol. The mechanism is **the LP-211

cross-shard 2PC pattern, applied at the rollup tier**. Where LP-211's

"shards" are LP-204 Tier-2 chain-VMs and the "parent L1" is the L1

hosting them, LP-219's "shards" are LP-218 Tier-3 rollups and the

"parent L1" is Z-Chain. The 2PC pattern is identical at the wire

level — same schemas, same prepare-ack collection, same atomic

commit/abort cert anchored at the parent's QuasarCert.

Architectural decision: LP-219 reuses LP-211 schemas, not new ones.

The cross-shard 2PC pattern is independent of tier. The schema IDs

0xE2..0xE7 (LP-211's allocation) carry the same semantics whether

the "shards" are chain-VMs or rollups. A CrossShardPrepareAck at

Tier-2 and a "cross-rollup prepare-ack" at Tier-3 are the same wire

shape; the tier is determined by which parent the cert anchors at,

not by a schema discriminator. This honors LP-200 "one and only one

way to do everything" — there is one cross-X 2PC protocol, parameterized

by parent.

Atomicity guarantees, failure modes, and performance are inherited

from LP-211. The latency at PQ-strict Z-Chain is the LP-218 batch

finality (~10-50 ms) plus the cross-rollup coordinator round-trips

(~10-100 ms LAN). End-to-end cross-rollup atomic commit: ~50-150 ms

LAN at PQ-strict; ~200-500 ms WAN.

The pattern — 7 steps

A cross-rollup tx group T = {T_1, ..., T_K} spans K rollups

deployed on the same Z-Chain. Each T_j is the per-rollup portion

targeting rollup R_j. The protocol commits all K portions atomically

or aborts all K.

Step 0 — coordinator selection

The coordinator is a Z-Chain validator, selected deterministically

per cross-rollup tx group:


coordinator(T) = zchain.validators[ hash(T.id) mod N ]

where T.id = sha256(canonical_bytes(T)) and N is Z-Chain's

validator count. Selection is a pure function of T; every rollup

sequencer agrees on the coordinator without coordination.

Step 1 — atomic group spans 2+ rollups

The client (a user wallet, a relayer, or a cross-rollup application)

constructs T as a list of (rollup_id, tx_bytes) pairs. The wire

shape is LP-211 schema 0xE2 CrossShardTxGroup (reused; "shard" in

the schema name is the LP-211-naming carryover — at Tier-3 the

"chain_id" field carries the rollup_id):


CrossShardTxGroup (0xE2)
    group_id   [32]byte    sha256 of canonical bytes
    parts      []CrossShardPart
      each part = (chain_id uint32, tx_bytes []byte)
                  // chain_id at Tier-3 = rollup_id

The client gossips T to the coordinator's Z-Chain validator via

LP-201 DHT.

Step 2 — each rollup's sequencer prepares its portion

The coordinator dispatches each T_j to rollup R_j's sequencer

(LP-211 schema 0xE3 CrossShardDispatch). Rollup R_j's sequencer:

1. Admits T_j into the rollup's mempool.

2. Closes a rollup batch that includes T_j.

3. Computes the new rollup state root (per LP-218 §"Rollup VM

execution" stage 2).

4. Pulsar-signs the tuple `(prev_root, new_root, batch_hash, T.id,

"prepare") — the "prepare"` tag distinguishes this from a

standard batch commit.

5. Does NOT yet submit a RollupBatchTx. Instead, the sequencer

gossips a prepare-ack to the coordinator.

The rollup's state diff is staged — held in the sequencer's

runtime, not yet committed to the rollup's ZapDB. This is the

LP-202 atomic-unwind contract applied at the rollup tier; the

staged overlay is content-addressed by the prepare-ack hash and

can be reclaimed in O(1) on abort.

Step 3 — cross-rollup coordinator collects prepare-acks

Each sequencer emits a prepare-ack: LP-211 schema 0xE4

CrossShardPrepareAck (reused; field chain_id carries rollup_id):


CrossShardPrepareAck (0xE4)
    group_id          [32]byte
    chain_id          uint32       // = rollup_id at Tier-3
    state_diff_hash   [32]byte     // hash of staged overlay
    wave_cert         []byte       // sequencer's Pulsar sig over the prepare tuple

The wave_cert for a rollup is a Pulsar threshold signature from

the rollup's sequencer group (1-of-1 single-sequencer, or t-of-n

threshold-sequencer per LP-218 §"Two rollup modes"). The signature

proves the sequencer committed to executing T_j and produced the

staged overlay.

The coordinator subscribes to prepare-acks on LP-201 gossip. It

collects until:

prepare_timeout_ms defaults to 5× the slowest rollup's batch

cadence (typical: 100 ms for fast rollups, 500 ms for slow ones).

Step 4 — single rollup-batch-tx aggregating both prepares

The coordinator submits a single tx to Z-Chain that aggregates

the K rollup batches. The tx body is a RollupAggregateBatchTx

a new tx-kind in LP-218's rollup-VM tx-kind registry, but **NOT a

new wire schema**. It reuses LP-218 schema 0xE8 RollupBatchTx

with TxCount representing the K member-batches and the body

carrying the K Pulsar prepare signatures concatenated.

The Z-Chain validates the tx by:

1. Verifying each of the K Pulsar prepare signatures via the P3Q

precompile (LP-218 §"P3Q precompile interface").

2. If any P3Q verify fails, the entire tx is rejected — the

aggregated batch is atomic at the verify layer.

3. If all K P3Q verifies pass, the tx is admitted to Z-Chain's

mempool.

4. Z-Chain's next LP-209 wave includes the aggregated tx.

Performance: K P3Q verifies at ~50 μs each on Blackwell sm_120; for

K=4 the verify cost is ~200 μs on the Z-Chain validator. Well within

the wave budget.

Step 5 — Z-Chain validates both Pulsar threshold sigs via P3Q

This step is internal to the Z-Chain wave: each validator runs the

K P3Q verifies as part of normal tx validation. P3Q verify is

constant-time, stateless, and deterministic — every Z-Chain

validator reaches the same accept/reject decision on the aggregated

tx.

The order of P3Q verifies does not matter — they are independent.

On GPU-equipped validators, the K verifies batch together via the

LP-203 batched-verify kernel (LP-218 §"Performance characteristics"

row "P3Q precompile verify, batched (N=64): ~5 ms aggregate"). For

K ≤ 64, the batched verify completes in <5 ms.

Step 6 — PQ-heavy cert at parent L1 commits the cross-rollup batch

Z-Chain's wave commit closes with a QuasarCert at Z-Chain's

configured LP-217 mode (typically PQ-strict for value-bearing

rollup commits). Once the QuasarCert finalizes:

1. Each rollup sequencer observes Z-Chain's cert via LP-201 gossip

(LP-211 schema 0xE6 CrossShardCommitNotify carrying the

Z-Chain cert).

2. Each rollup sequencer verifies the cert covers T.id and meets

the rollup's CertModeFloor (LP-218 §"Inherited cert mode").

3. Each rollup sequencer applies its staged overlay via LP-202

atomic commit to the rollup's ZapDB. Done.

Step 7 — each rollup's local ZapDB commits per LP-211 atomic-unwind contract

The rollup-side application of the staged overlay is the LP-202

txn.Commit() call on the staged ZapDB transaction. O(1) cost —

the overlay was already content-addressed at Step 2.

If Step 4' (abort) ran instead, each rollup calls

txn.Discard() — also O(1). The cross-rollup tx group is dropped;

the client may re-submit with a new group_id.

Atomicity guarantees

Theorem. For any cross-rollup tx group T after the Z-Chain

QuasarCert decisively covers either CrossShardCommit(T.id) or

CrossShardAbort(T.id), every rollup R_j ∈ T's rollups has either

committed T_j or unwound T_j, and these outcomes match.

Argument (mirrors LP-211 §"Atomicity proof sketch"):

1. Each rollup's staged overlay is local — exists only in the

rollup sequencer's runtime, content-addressed by the prepare-ack

hash.

2. The rollup's Pulsar prepare-sig (Step 2) commits the rollup to

executing T_j at the rollup's per-batch finality. A sequencer

that later refuses to apply the staged overlay on Step 6

commit-notify is byzantine and slashable on Z-Chain (Step 6

commit-notify is the cryptographic instruction; refusal

contradicts the sequencer's own Pulsar prepare-sig).

3. The Z-Chain QuasarCert is either commit or abort, never both —

wave ordering at Z-Chain is total (LP-209), so the aggregated

tx commits at exactly one Z-Chain wave height with a single

QuasarCert.

4. Therefore: the Z-Chain QuasarCert is the unique decision

oracle. Every rollup's local outcome is a deterministic function

of the Z-Chain cert (commit → apply staged overlay; abort

LP-202 unwind). A sequencer that diverges is byzantine and

slashable.

The atomicity is eventually-cryptographic: there is a transient

window between Step 2 prepare and Step 6 commit during which a

rollup's staged overlay exists but is not yet committed. During

that window, the rollup's external API MUST NOT expose the staged

state — queries return pre-T_j state. This is the standard 2PC

invisibility property; the LP-202 staged overlay contract

guarantees it.

Failure modes

| Failure | Trigger | Effect | Recovery |
|---|---|---|---|
| Coordinator offline | crash, partition | prepare-acks accumulate but no aggregated tx submitted | rollups' staged overlays time out via local prepare_timeout_ms × 2 watchdog; LP-202 txn.Discard() unwinds; tx group is dropped; client re-submits |
| One sequencer refuses prepare | tx validity failure, byzantine | coordinator receives CrossShardRefuseAck; submits Step 4' abort | every prepared rollup unwinds; tx group dropped |
| Coordinator equivocates (submits both commit and abort) | byzantine coordinator | Z-Chain's LP-209 wave ordering admits only one (first-seen); LP-208 equivocation gate suppresses the second at Z-Chain mempool; coordinator slashed | atomicity preserved by Z-Chain wave ordering |
| Z-Chain partitions before committing the aggregated tx | infrastructure | rollups' staged overlays time out; LP-202 unwind; client re-submits when Z-Chain heals | partition recovery is LP-204's concern; LP-219 inherits |
| Sequencer is too slow to produce prepare-ack | rollup overloaded | coordinator timeout; abort path | rollup operator scales; tx group dropped; client re-submits later |
| One P3Q verify fails inside Z-Chain wave | invalid Pulsar sig (sequencer bug or replay attempt) | Z-Chain rejects the aggregated tx; all K rollups' prepares are stranded | rollups time out and unwind; coordinator may re-issue with corrected sigs |
| Aggregated tx larger than Z-Chain wave capacity | K >> 64 cross-rollup parts | tx admission fails | client splits T into smaller groups; aggregation is not designed for K > 64 |
| One rollup's CertModeFloor not met by Z-Chain's cert tier | misconfigured rollup | rollup waits for higher tier; effective cross-rollup latency = slowest rollup's floor | operator aligns rollup floors with Z-Chain's typical operating tier |

Performance

LAN, PQ-strict mode at every layer, 40-validator Z-Chain with 4-rollup

fan-out (K=4):

| Event | Time (cumulative) | Source |
|---|---|---|
| Cross-rollup tx submitted to coordinator | 0 ms | client |
| Coordinator dispatches to K rollups via DHT | ~10 ms | LP-201 DHT lookup + gossip |
| Per-rollup mempool admit | ~15 ms | LP-218 §1 NIC-bound |
| Per-rollup sequencer closes batch with staged overlay | ~25 ms | LP-218 batch finalization at PQ-fast |
| Prepare-acks arrive at coordinator | ~35 ms | + 10 ms gossip |
| Coordinator submits aggregated tx to Z-Chain | ~36 ms | one mempool insert |
| Z-Chain validators K P3Q-verify (K=4) | ~37 ms | ~200 μs verify cost; batched-kernel on GPU |
| Z-Chain wave commits aggregated tx | ~52 ms | + LP-218 batch finalization at PQ-strict (15 ms) |
| Rollups observe commit-notify and apply staged overlay | ~62 ms | + 10 ms gossip + LP-202 O(1) commit |

End-to-end cross-rollup atomic commit at PQ-strict LAN: ~62 ms for

K=4.

For K=64 (the upper bound for batched P3Q verify):

| Event | Time (cumulative) |
|---|---|
| Per-rollup prepare-ack collection | ~50 ms (cap on slow rollups) |
| K P3Q verify (batched, N=64) | ~5 ms |
| Z-Chain wave commit | ~70 ms |
| End-to-end | ~85 ms |

Z-Chain wave commit at PQ-strict is the bottleneck. The cross-rollup

coordinator round-trips and the per-rollup prepare costs are dominated

by the Z-Chain commit at K ≤ 64.

WAN, PQ-strict mode: ~200-500 ms (RTT-dominated; LP-209 wave latency

triples under WAN).

PQ-heavy mode: add ~150 ms to each cert step (LP-217 PQ-heavy floor

latency); total ~200 ms LAN, ~700 ms WAN.

Cross-rollup atomic throughput

The aggregated RollupAggregateBatchTx is one tx per cross-rollup

group. Z-Chain's tx throughput at PQ-strict is ~10 waves/sec × ~100

txs/wave = 1000 txs/sec floor. Each cross-rollup group consumes one

tx slot. Aggregate cross-rollup atomic throughput: ~1000 groups/sec

at LAN PQ-strict.

For workloads where cross-rollup atomicity is the bottleneck (e.g.

cross-rollup DEX bridging, cross-rollup oracle commitments), the

operator should target PQ-fast on Z-Chain (~3-5 ms wave commit) for

~10,000 cross-rollup groups/sec at the cost of PQ posture.

Wire schemas

Architectural decision: LP-219 reuses LP-211 schema IDs. No new

schema family. The justification:

1. The cross-X 2PC pattern is independent of tier. LP-211

schemas 0xE2..0xE7 carry `(group_id, chain_id, state_diff_hash,

wave_cert). At Tier-2 the chain_id` is an LP-186 chain-VM ID

(0xC0..0xCB); at Tier-3 it is a rollup_id.

2. The TxKind discriminator inside the wave_cert distinguishes

"cross-shard at parent L1" from "cross-rollup at Z-Chain" via

the wave_cert's chain_id field — the cert is at the parent

layer, not the shard layer.

3. One schema, two deployment contexts. Honors LP-200 "one and

only one way to do everything."

Schemas used (all inherited from LP-211)

| Schema | Hex | Used by LP-219 |
|---|---|---|
| CrossShardTxGroup | 0xE2 | tx group bytes; parts[].chain_id = rollup_id at Tier-3 |
| CrossShardDispatch | 0xE3 | coordinator → rollup sequencers via Z-Chain DHT |
| CrossShardPrepareAck | 0xE4 | rollup sequencer → coordinator |
| CrossShardRefuseAck | 0xE5 | rollup sequencer refusal |
| CrossShardCommitNotify | 0xE6 | Z-Chain → rollup sequencers (commit) |
| CrossShardAbortNotify | 0xE7 | Z-Chain → rollup sequencers (abort) |

Aggregated tx (reuses LP-218 schema 0xE8)

The RollupAggregateBatchTx is not a new schema. It is the same

LP-218 RollupBatchTx (schema 0xE8, Kind 0x40) with:

Adding 0x44 to LP-218's TxKind registry is the only registry change

LP-219 introduces. No new schema ID is allocated. The wire is

backward-compatible at the schema-ID layer; only the TxKind byte

inside the LP-218 envelope is new.

Schema-ID allocation (per LP-300 master schema registry)

| Range | Owner | LP |
|---|---|---|
| 0xC0..0xCB | chains-VM wire (12 VMs) | LP-186 |
| 0xD0..0xDF | ZAP P2P transport | LP-201 |
| 0xE0..0xE1 | DAG mempool | LP-208 |
| 0xE2..0xE7 | cross-X 2PC (LP-211 + LP-219 reuse — see below) | LP-211 (canonical owner; LP-219 reuses) |
| 0xE8..0xEF | rollup-VM envelopes (incl. LP-219 new TxKind 0x44) | LP-218 (+ LP-219 TxKind extension) |
| 0xF0..0xF2 | light client wire | LP-214 |
| 0xF3..0xFF | reserved future | — |

LP-300 is normative; this table is informative. No byte collision:

LP-218 envelopes live in 0xE8..0xEF, LP-211 cross-X 2PC schemas

live in 0xE2..0xE7. The previous draft of LP-218 claimed 0xE0..0xEF

which overlapped LP-211; that has been corrected — LP-218 now

occupies 0xE8..0xEF per LP-300.

LP-219 reuses LP-211 schemas 0xE2..0xE7 verbatim — it does not allocate

its own schema IDs. The only registry change LP-219 introduces is a

new TxKind byte 0x44 (RollupAggregateBatch) inside the LP-218

schema 0xE8 envelope.

Composition with LP-211

LP-219 IS LP-211, parameterized by tier:

| Concern | LP-211 | LP-219 |
|---|---|---|
| "Shard" | LP-204 Tier-2 chain-VM | LP-218 Tier-3 rollup |
| "Parent L1" | the L1 hosting the chain-VMs | Z-Chain (Lux primary's L1) |
| Coordinator | parent L1 validator | Z-Chain validator |
| Prepare wave | per-shard LP-209 wave | per-rollup LP-218 batch |
| Commit anchor | parent L1 LP-209 wave's QuasarCert | Z-Chain LP-209 wave's QuasarCert |
| Cert mode | LP-217 mode on the parent L1 | LP-217 mode on Z-Chain |
| Atomic-unwind contract | LP-202 txn.Discard() | LP-202 txn.Discard() (same) |
| Wire schemas | 0xE2..0xE7 | 0xE2..0xE7 (reused) |

The duplication is intentional. Lifting LP-219 into a separate spec

makes the cross-rollup pattern discoverable and named — operators

deploying rollups on Z-Chain look up "rollup-to-rollup atomic" by

name, not by tracing LP-211's parameterization. The cost is one

extra LP document; the benefit is the entrypoint is named.

Composition with LP-218 cert-mode floors

A cross-rollup group spans K rollups, each with its own

CertModeFloor (LP-218 §"Inherited cert mode"). The cross-rollup

commit is observable at each rollup at the time **Z-Chain's cert

reaches that rollup's floor**. Per LP-202 monotonic upgrade, the

Z-Chain cert observability is monotonic; different rollups in the

group commit at different wall-clock times as Z-Chain's cert tier

progresses.

Worked example: rollup A CertModeFloor = PQ-fast, rollup B

CertModeFloor = PQ-strict, Z-Chain operating at PQ-strict.

| t (ms) | Event | Z-Chain cert observable at | Rollup A acts? | Rollup B acts? |
|---|---|---|---|---|
| 0 | Coordinator submits aggregated tx | n/a | no | no |
| 50 | Z-Chain BLS leg aggregates | PQ-off | no (A wants ≥ PQ-fast) | no |
| 55 | Z-Chain Corona leg aggregates | PQ-fast | yes — A commits | no |
| 65 | Z-Chain Pulsar leg aggregates | PQ-strict | (already committed at 55) | yes — B commits |

The atomicity holds: the Z-Chain cert is the unique decision oracle,

and both rollups observe the SAME cert (just at different observability

tiers). Either both commit (Z-Chain cert is commit) or both unwind

(Z-Chain cert is abort). The wall-clock disparity is acceptable —

the LP-202 monotonic-upgrade invariant guarantees the cert at PQ-fast

is a strict subset of the cert at PQ-strict.

Activation marker


activates: 2025-12-25T16:20:00-08:00
activates-unix: 1766708400

Cross-rollup atomic commits via the LP-219 protocol are accepted by

Z-Chain from the genesis block of the new final Lux network onward.

The new TxKind RollupAggregateBatch = 0x44 is admitted by Z-Chain

validators from height 0.

Cross-references