igneum/docs/analysis/base-fee-floor.md
igneum-labs f503f491e9 Prover mirrors the fee switch: both tables and fees_v1_activation_daa in the shard input, guest re-pinned, devnet runbook for H = 210,000
igneum-prove-core carries the node's fees.rs (PgasTable, FeeParams PROTOTYPE and CALIBRATED_V1,
FeeSchedule::at); the shard input and every fixture carry the schedule and the block's DAA score; the executor
reads the set at that score, raises the base fees to its floors and meters with its intrinsic, B_p and modexp
entry, as the node's execute_segment does. The 328-byte statement is unchanged: the node's native veto pins the
schedule (a new layout would be a consensus change for every node). Exporter: schedule and daaScore from the
dump (gen.mjs writes them), per-segment switch on replay, S_p from the set. Fixtures from one simnet chain across
the switch at DAA 800: fees-switch-prototype (block 51), fees-v1-shards2 (351), fees-v1-shards3 (355); 358
segments replayed, every state root the node's. Host tests on both sides. Guest re-pinned: shard
0x2b1a81cb..., aggregator 0x474678f3...; pinned-guests-check passes.

Node fork 2b6d23ef unchanged (igneum-exec tests 11 passed). Digest for the override with
fees_v1_activation_daa 210000: ab8847da538dead1dc10e046dfaadab3c1c35928e3748810c4e050d4a886087a.
Runbook docs/plans/fee-switch-devnet.md; infra/devnet/restart-hand-nodes.sh and restart-seed.sh take the
override object (the hand nodes and the seed run 20139145 today and must move to 2b6d23ef first). One line on
the live page, spec 5.11, the testnet README, the floor analysis, the bench log and the journey.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 16:24:35 +00:00

11 KiB

Base-fee floors and the prover-gas table: the model (ADOPTED 5 October 2026)

Status: every number below was proposed on the night of 4 October 2026 and ADOPTED by the owner on 5 October 2026, as proposed (sign-off recorded in docs/plans/release-0.3.6.md). The parameters live in the node fork (consensus/core/src/fees.rs, FeeParams::CALIBRATED_V1; written on branch testnet-params, merged into release-0.3.6 on 5 October 2026). Which network runs them: the testnet and the mainnet from genesis (Params.fees = v1, fees_v1_activation_daa = 0); the devnet and the simnet keep FeeParams::PROTOTYPE until the override file carries a fees object or the fees_v1_activation_daa height switch (section 4, "the devnet rollout"), so the live devnet does not change rules between the 0.3.5 and 0.3.6 node builds. Spec 05 section 5.11 carries the summary. Nothing is deployed.

Inputs the model takes from the repository, with their status:

Input Value Status, source
Block rate 1 block per second Designed (spec 02; BlockrateParams::new::<1>())
Execution gas per block B_e 30,000,000 Implemented, devnet v3 value (consensus/core/src/evm.rs, BLOCK_EXECUTION_GAS_LIMIT)
Plain transfer, execution gas 21,000 Ethereum's rule
Year-one block subsidy 31.69 IGN (3,168,808,781 sompi per second) Implemented (consensus/core/src/igneum.rs)
SP1 cycles per EVM gas, modexp-heavy shard 44 Measured (bench-log, "shard proving on the RTX 5090", run-20261004-173115)
SP1 cycles per prototype pgas, same shard 9 Measured (same)
SP1 cycles per prototype pgas, plain-transfer shard 1,400 to 1,600 Measured (bench-log, 4 October, "proving: devnet v4 shards")
Compressed proof of a 60 M-cycle shard, one RTX 5090 10.9 s Measured (same run)
Aggregation of a block's shards 2.2 to 2.5 s Measured (same run)
Token price $0.10 per IGN ASSUMPTION for the arithmetic only; sensitivities at $0.01, $1 and $2 below. Not a forecast, not a claim
Electricity $0.15 per kWh; RTX 5090 at 575 W while proving Approximate (the economy analysis used $0.02 to $0.40; 575 W is the card's rated draw, not measured here)

1. The prover-gas table, calibrated v1

The unit is unchanged: 1 pgas stands for 1,000 reference SP1 cycles. The prototype table of 3 October charged every opcode and precompile by shape with magnitudes nobody had measured. Two of its entries are now measured.

Entry Prototype (3 October) Measurement Calibrated v1
modexp (0x05) 1,000 + 10 per input byte the modexp-dominated shard ran 60.76 M cycles for 6.75 M prototype pgas: 9 cycles per pgas against the unit's 1,000, so the entry is about 111x its cost 10 + 1 per 10 input bytes (the prototype over 100)
Intrinsic per transaction 200 the plain-transfer shard ran 1,400 to 1,600 cycles per prototype pgas: 200 x 1,500 = 300,000 cycles per transaction, which includes the shard's fixed witness check and root computations, so it is an upper bound 300
Every other opcode and precompile prototype shape not measured prototype shape, unchanged, table version 1

What the two constants say about a transaction: the modexp shard metered 1,390,773 EVM gas for 60.76 M cycles, 44 cycles per gas, which is 0.044 pgas per gas at the unit; a plain transfer is 300 pgas for 21,000 gas, 0.014 pgas per gas. The design expected a pgas / gas band of 0.1 to 10 (execution-layer design 4.3); the measured band is 0.01 to 0.05, so proving gas is cheaper per gas than the design guessed, by 10x, on the two workloads measured. The remaining entries (ecrecover 3,000 pgas, ecpairing 45,000 per pair, the storage opcodes) are the next calibration; each is one SP1 run of a fixture that isolates it.

2. The shard and block budgets

Quantity Value Arithmetic
Shard budget S_p 30,000 pgas 30 M cycles: half the measured 60 M-cycle shard. One RTX 5090 compresses it in about 5.5 s (linear in cycles from 10.9 s, approximate); a 12 GB card in about 20 s (approximate: the economy simulation's shard shares put a 3060 at 3.7x the 5090's time; unmeasured, the phase 2 gate)
Block budget B_p 120,000 pgas 4 x S_p, the prototype's ratio (spec 7.4)
Transfers per block at B_p 400 120,000 / 300
Execution gas those use 8,400,000 400 x 21,000, 28% of B_e: the proving dimension binds first for transfers
Block proof time, four RTX 5090s about 8 s 5.5 s per shard in parallel plus 2.5 s aggregation (approximate), inside the 20 to 60 s launch target
Block proof time, four 12 GB cards about 23 s 20 + 2.5 s (approximate)
Cards to keep pace at full blocks 22 RTX 5090s, or about 80 12 GB cards 4 shards x 5.5 s = 22 card-seconds per second; x 3.7 for the 12 GB class (approximate)

The prototype B_p of 30,000,000 pgas was "equal to B_e" and never a throughput number: at 9 cycles per prototype pgas a full prototype block is 270 M cycles, 49 s on one 5090, and at the plain-transfer rate it is 45 G cycles. The calibrated B_p is a throughput number: one block per second provable by a fleet the economy simulation already models. Raising it is a parameter the genesis rules leave to miners (60% signalling, spec 5.5), and the economy analysis of 4 October recommends tying it to the live proving fleet on the testnet.

3. The base-fee floors

Both base fees are burned in full (spec 5.1) and adjusted by EIP-1559 toward half the limit with a denominator of 8 (1/8 per block at the extremes). The floor is the lowest value either fee can reach. It has three jobs: keep a plain transfer cheap, make a full block cost real money from the first block, and price proving above the electricity it burns so spam cannot be cheaper than the work it imposes.

Floor Value In IGN
Execution base fee f_e 100 gwei per gas 0.0000001 IGN per gas
Proving base fee f_p 10,000 gwei per pgas 0.00001 IGN per pgas
Initial base fees at genesis the floors

A plain transfer at the floor

Term Arithmetic IGN
Execution 21,000 x 100 gwei 0.0021
Proving 300 x 10,000 gwei 0.0030
Total (tip excluded) 0.0051
Token price (assumption) $0.01 $0.10 $1 $2
Transfer at the floor $0.000051 $0.00051 $0.0051 $0.0102

The target "under $0.01 per simple transfer" holds up to $1.96 per IGN. Under load the fee leaves the floor: after n consecutive full blocks the base fee is the floor times 1.125^n, which is 3.2x after 10 blocks, 34x after 30 and about 1,170x after 60 blocks (one minute). The floor prices the quiet chain; the controller prices the busy one.

A full block at the floor, which is what spam costs

Case Arithmetic IGN per block Per day (86,400 blocks) At $0.10 per day
Execution dimension full (30 M gas of cheap-to-prove calls) 30,000,000 x 100 gwei 3.0 259,200 $25,920
Proving dimension full with transfers (400 transfers) 120,000 x 10,000 gwei + 8,400,000 x 100 gwei 1.2 + 0.84 = 2.04 176,256 $17,626
Both dimensions full (the worst mix) up to 4.2 362,880 $36,288

A self-paying spam loop (a miner filling its own blocks, or a contract that calls itself until the gas is gone) pays the same: the base fee is burned, the tip returns to the miner and nets to zero, so a miner that fills its own block burns 3.0 IGN against a subsidy of 31.69 IGN, 9.5% of its own reward per filled block, for nothing. And only at the floor: after one minute of full blocks the controller has multiplied every number above by about 1,170.

Proving priced above its electricity

Quantity Arithmetic Value
Cycles per second, one RTX 5090 60 M cycles / 10.9 s 5.5 M
Energy per pgas (1,000 cycles) 575 W x 1,000 / 5.5 M 0.105 J = 2.9 x 10^-8 kWh
Electricity per pgas at $0.15 per kWh $4.4 x 10^-9
Floor per pgas at $0.10 per IGN 0.00001 IGN $1.0 x 10^-6
Floor over electricity 230x at $0.10; 23x at $0.01; 1x at $0.00044

The floor covers the physical cost of the proving it buys down to a token price of about $0.0004, which is where this anchor would bind before the spam anchor does. The execution dimension has no such anchor: native execution of a full block costs tens of milliseconds of CPU; its floor is set by the spam arithmetic alone, as Ethereum's is.

4. What the table and the floors do not settle

Item State
The other opcode and precompile entries prototype shapes; calibrate per entry in SP1 with three input sizes (design R1)
The intrinsic 300 an upper bound that includes the per-shard fixed cost; a shard with many transfers will show the marginal number
The 12 GB card time for S_p approximate, from the simulation's share ratios; the phase 2 gate measures it
The prover's mirror of the table Done 5 October 2026 (docs/plans/fee-switch-devnet.md): proving/igneum-prove/core/src/config.rs mirrors the node's fees.rs (both tables, FeeSchedule::at), the shard input carries the schedule and the block's DAA score, the guest was re-pinned. The prototype fixtures stay valid (no fees field = prototype, never); v1 fixtures were cut from a simnet run across the switch
The devnet rollout done as a height switch (5 October 2026): Params.fees_v1_activation_daa (override file, default never on devnet and simnet, 0 on testnet and mainnet, in the consensus digest). Chain blocks at or above the switch meter with v1 (every metering site in igneum/exec takes the block's DAA score, fees::fee_params_at); the first such block raises both base fees to the v1 floors. The live devnet keeps its history and its prototype rules until the switch is published with the 0.3.6 update (docs/plans/release-0.3.6.md, section 5). A fresh chain can instead carry fees in the override file (the fast-time profile does)
The price assumption $0.10 is an arithmetic assumption. The floor is a parameter the genesis rules leave to miners (60% signalling) and can be moved by them

5. Where the numbers live

What Where
The parameter set and its tests vendor/igneum-node-testnet/consensus/core/src/fees.rs (branch testnet-params)
Per network consensus/core/src/config/params.rs, Params.fees and Params.fees_v1_activation_daa (FeeParams::TESTNET and MAINNET = CALIBRATED_V1 with the switch at 0; FeeParams::DEVNET and SIMNET = PROTOTYPE with the switch never, both movable through the override file)
The execution layer's readers igneum/exec/src/config.rs (block_proving_gas_limit(daa), intrinsic_pgas_per_tx(daa), the floor and initial readers, every one at a DAA score), pgas.rs (the inspector carries the block's table; the modexp entry reads it), executor.rs (execute_segment picks the set by the block's DAA score and raises the carried base fees to its floors; next_base_fee takes the floor and the denominator)
Installed at start kaspad/src/daemon.rs (install_fee_params: the base set and the switch, printed after the PoW schedule)
The specification docs/spec/05-fees-and-economics.md section 5.11