Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions docs/phase-2/CIP-urgency-signalling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ flowchart LR

This CIP introduces a transaction-level urgency signal with two lanes: standard and urgent. Urgent transactions pay a different, dynamic fee quote and are eligible for inclusion in both Ranking Blocks and Endorser Blocks. Standard transactions are eligible only for Endorser Blocks. The ledger enforces that Ranking Blocks contain only urgent-paying transactions. The dynamic fee is controlled by the EIP-1559 algorithm.

We specify that Ranking Blocks can only contain urgent transactions to prevent bribery of block producers. If bribery is allowed, a block producer has the incentive to accept a bribe over a legitimate urgent transaction, because it means they'll get to keep the entire bribe. If, instead, they chose to include a legitimate urgent transaction, the excess fees would go to the treasury. As such, preventing that incentive is necessary.
We specify that Ranking Blocks can only contain urgent transactions to prevent bribery of block producers. If bribery is allowed, a block producer has the incentive to accept a bribe over a legitimate urgent transaction, because it means they'll get to keep the entire bribe. If, instead, they chose to include a legitimate urgent transaction, the excess fees would be donated to the treasury (see Incentives). As such, preventing that incentive is necessary.

Additionally, in order to solve a problem that arises under low-ish load circumstances (RB fill somewhere between the fill target, 0.5 in the default case, and the RB max fill), we specify a modification: we prevent EB announcement unless the announced EB is larger than a given percentage of the RB's capacity. This modification is to defend against the case where, under the load scenario described above, some standard transactions are mixed in with urgent transactions in a steady flow. Without the modification, an EB is announced at every possible occasion, meaning there are frequent EB certificates included in RBs. This results in a self-sabotaging outcome, where standard transactions have to wait longer because they're not allowed in a non-full RB, and urgent transactions have to wait longer for the same reason, because RBs frequently contain certificates, excluding urgent transactions. The modification restores urgent transactions to parity with the flat-fee baseline at this load; in exchange, standard transactions queue until an EB is worth its certificate, a small additional wait we accept.
Additionally, in order to solve a problem that arises under low-ish load circumstances (RB fill somewhere between the fill target, 0.5 in the default case, and the RB max fill), we specify a modification: we prevent EB announcement unless the announced EB is larger than a given percentage of the RB's capacity. This modification is to defend against the case where, under the load scenario described above, some standard transactions are mixed in with urgent transactions in a steady flow. Without the modification, an EB is announced at every possible occasion, meaning there are frequent EB certificates included in RBs. This results in a self-sabotaging outcome, where standard transactions have to wait longer because they're not allowed in a non-full RB, and urgent transactions have to wait longer for the same reason, because RBs frequently contain certificates, excluding urgent transactions. The modification restores urgent transactions to parity with the flat-fee baseline at this load; in exchange, standard transactions queue until the selected EB payload reaches the specified byte threshold, or until the K = 10 age escape opens, a small additional wait we accept.

<details>
<summary>Show glossary of terms</summary>
Expand Down Expand Up @@ -268,7 +268,7 @@ and what policy applies to them.

#### Tipping

In times of congestion, the ability to separate transactions by urgency becomes impossible. In this case, users can use [nested transactions](https://github.com/cardano-foundation/CIPs/pull/862) to offer the block producer a tip in order to buy into RB space.
When the urgent lane is saturated, paying the urgent quote makes a transaction eligible for RB inclusion but cannot distinguish it from every other eligible transaction. In that case, a user can use [nested transactions](https://github.com/cardano-foundation/CIPs/pull/862) to offer the block producer a tip for selecting it into the scarce RB space. This does not bypass the ledger rule: the transaction must still cover the urgent quote.

POLINA TODO: explain how this should be done

Expand Down Expand Up @@ -378,11 +378,19 @@ The instability that excludes denominator 4 is visible directly in the price tra

![Per-lane price coefficient under severe congestion at max-change denominator 16: both coefficients track demand smoothly](images/d16.png)

TODO: fold the standard-lane batching cost into the Incentives fairness discussion: the wait is now bounded at K Ranking Block intervals by the age escape, and at typical light load costs p95 roughly four slots over plain reservation. Urgent transactions included via EB are refunded down to the standard quote; reference the fee change return mechanism CIP when drafted.

### Incentives

NICOLAS TODO
Settlement splits every posted bid three ways: the ordinary min-fee component, the premium above it, and the refunded excess (see Block production and node policy). Each destination is chosen for its incentive effect.

The premium is donated to the treasury. It does not go to the block producer: a producer who keeps the premium is no longer indifferent between a legitimate urgent transaction and a side-payment, which recreates the bribery incentive the reservation rule exists to remove. Burning it would be equally neutral for producers; donation is preferred because it keeps congestion revenue inside the protocol's existing funding mechanism.

Protocol fee revenue for producers is unchanged by this proposal. The min-fee component of every included transaction enters the fee pot exactly as fees do today, regardless of lane. The default node policy selects FIFO in both lanes, so the pricing mechanism does not introduce a fee-ordering auction. FIFO is not ledger-enforced, however. Once the urgent lane is saturated, a user may offer a producer tip through nested transactions, as described above. Reservation prevents a producer from selling RB inclusion below the urgent quote; it does not claim to prevent competition among transactions that already cover that quote.

An urgent user pays only for the service received. The premium is scoped to the Ranking Block: an urgent transaction included via an Endorser Block is charged the standard quote. The refund returns everything above the applicable quote, so the posted max fee is a genuine ceiling, and headroom against quote drift costs nothing at settlement. A transaction whose max fee is insufficient is rejected (`BidBelowQuote`) or evicted; both outcomes are visible to the submitter, and neither leaves the transaction queued while its value decays. Eligibility for the urgent lane requires only paying the posted quote, never a prior arrangement with a producer. That is an access guarantee, not a guarantee of inclusion priority once the lane is full.

A standard user is insulated from urgent demand. The standard quote responds only to standard-lane utilisation; it starts at the ordinary min fee, and the absolute coefficient floor prevents it from ever falling below that. An uncontended standard transaction therefore pays what it pays today. The cost this design does impose on the standard lane is batching: standard transactions pool until the selected Endorser Block payload reaches the announcement byte threshold, or until the K = 10 age escape opens. The escape bounds that wait at K Ranking Block intervals, and at typical light load it costs p95 roughly four slots over plain reservation.

Settlement is conservative: base plus premium plus refund equals the posted bid for every transaction, and each component is checkable from on-chain data alone. Fee handling neither mints nor destroys value.

## Rationale: how does this CIP achieve its goals?

Expand Down Expand Up @@ -429,6 +437,31 @@ After separating the simulator's fresh-demand, ranking-block-production, and ret

Full details, including method, configs, per-load tables, paired seed deltas, and figures: [preliminary experiment report](https://github.com/input-output-hk/tiered-pricing/blob/main/docs/phase-2/preliminary-experiment-report.md).

### Prototype
Comment thread
nhenin marked this conversation as resolved.

https://github.com/user-attachments/assets/6a4ef69a-516f-4517-bfbd-d7b8a97b09cf

The two lanes live on the devnet (8 min 50 s): a walkthrough of the mechanism and live system, followed by sustained demand, a price squeeze with real evictions, certification pressure and recovery, and the return to an idle network. Captions included.

The mechanism has also been implemented end to end. The prototype patches the Linear Leios prototype node directly: the ledger rules, the consensus mempool, the node's transaction submission path, and the trace pipeline. It runs a three-node Dijkstra devnet with a live dashboard and a generated crowd of senders choosing lanes against the live quotes. Full details live in the [prototype repository](https://github.com/nhenin/dynamic-pricing): the code and a one-command launcher, the per-repository change sets, the design documents, and a section mapping the prototype's vocabulary and calibration to this CIP.

The prototype exercises the transaction lifecycle specified above on a real network rather than a simulator:

- The Ranking Block rule is a ledger rule. A transaction whose max fee does not cover the urgent quote fails with `BidBelowQuote`.
- Both quotes are repriced inside block application. A certified Endorser Block enters the price signals exactly once, at certification.
- Settlement is measured from ledger state, block by block. The min-fee component accumulates in the fee pot, the premium in the treasury, and the excess returns to a refund account named in the transaction body. The three pots sum exactly to what senders paid.
- The mempool admits one worst-case controller step ahead and re-validates under moving prices. A rising quote evicts the transactions whose max fee it overtakes.
- Endorser Block announcement is gated by the byte threshold (45,056 bytes at the default target) and the K = 10 age escape: below the threshold the standard lane pools, and a trickle can be released after ten Ranking Blocks.
- Linear Leios pool votes are cast and traced by all three nodes. Quorum produces the certificate, and the certified Endorser Block is applied by the running protocol. The certification-miss scenario withholds those votes at source rather than fabricating a certificate or ledger outcome.

The prototype runs the recommended controller and fee construction: target utilisation 0.5, max-change denominator 16, the 5-sample and 20-block signal windows (bytes and execution units, larger ratio), no cross-lane floor, the urgent lane's 2× initial coefficient, admission one worst-case controller step ahead, the announcement byte threshold, the K = 10 announcement age escape, and settlement by delivery. An urgent transaction delivered through a certified Endorser Block is charged the standard quote, the excess is refunded, and every urgent fee-cap check uses the maximum of the two current quotes. The Endorser Block is a FIFO merge of standard transactions and urgent overflow; an urgent rider contributes at most one Ranking Block reservation to each certified urgent signal sample.

The prototype deliberately diverges from the recommended construction at two integration points. First, the recommendation merges the entire urgent remainder into the Endorser Block, whereas the prototype holds one Ranking Block's worth of the newest urgent backlog out of that merge. This express reserve keeps the next Ranking Block non-empty while urgent demand is waiting. It is a node-policy experiment, not a ledger rule, and should be evaluated against the unreserved FIFO merge before production. Second, the prototype permits a certificate-carrying Ranking Block to apply its own urgent payload immediately before the certified Endorser Block cargo; the current CIP model treats that Ranking Block as payload-free. This integration choice preserves transaction dependency order in the prototype, but it must either be reconciled with the Linear Leios block-body construction or removed from a production implementation.

The implementation required coordinated changes across four boundaries: ledger validation and settlement, consensus mempool selection and revalidation, the node submission path, and the Linear Leios announcement, voting, certification, and trace pipeline. The most difficult part was maintaining one transaction lifecycle while an Endorser Block is in flight. Announced transactions must leave the selectable mempool to prevent duplicate inclusion, superseded uncertified cargo must be readmitted without violating first-come dependencies, and certified cargo must be applied in dependency order. These are consensus-safety concerns rather than dashboard concerns, and the prototype includes targeted tests and live traces for them.

Making the work production-grade would require replacing prototype constants with governed protocol parameters and era-versioned serialization, completing the formal reordering and dependency treatment (including governance actions), specifying adversarial mempool and DoS limits, integrating wallet fee-cap and refund construction, and testing restart, rollback, reannouncement, and fork convergence across heterogeneous nodes. The two prototype divergences above also need a single normative resolution, followed by conformance tests shared by the formal model, simulator, ledger, consensus, and wallet implementations. The prototype demonstrates implementability; it does not remove those integration and assurance steps.

## Path to Active

### Acceptance Criteria
Expand Down