Skip to content

refactor(standards): split fee estimation out of pay_fee - #3796

Open
mmagician wants to merge 12 commits into
nextfrom
mmagician-claude/port-fee-estimate-split
Open

refactor(standards): split fee estimation out of pay_fee#3796
mmagician wants to merge 12 commits into
nextfrom
mmagician-claude/port-fee-estimate-split

Conversation

@mmagician

@mmagician mmagician commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Port of #3784 from release/v0.16.0-rc to next.

Changes w.r.t. #3784

  • Adapted to next: tx::get_fee_faucet_id became tx::get_fee_asset_id (#3741), which returns the asset ID directly, so the rc pay_network_note_sponsorships wrapper collapsed to a single call and was dropped as suggested in the rc review. fungible_asset::to_amount_unchecked follows the next rename.
  • On refactor(standards): split fee estimation out of pay_fee #3784, fee asset ID was read twice. pay_fee called estimate_fee, which read tx::get_fee_faucet_id to run the estimate, and then called pay_network_note_sponsorships, which read it again to run the creation. On next, the port now reads tx::get_fee_asset_id once in pay_fee, duplicates the word on the stack, and passes one copy to estimate/create respectively.

Notes

The two follow-ups originally listed here (zero-priced network notes budgeted at the 512-cycle walk margin while the payment pass still priced them via FPI after compute_fee, and the double pricing pass adding about 3950 core rows to network-note transactions) are addressed by b0e0179: the estimate records each network note's price in pay_fee's local memory and the payment reads it back, so every network note is priced once and the payment tail no longer contains a foreign procedure call. "consume CLAIM note (L2 to Miden)" is back to 4378 rows under its 65536 bracket.

Comment thread crates/miden-standards/asm/standards/fee/mod.masm Outdated
Comment thread crates/miden-standards/asm/standards/fee/mod.masm Outdated
Comment thread crates/miden-standards/asm/standards/fee/mod.masm Outdated
Comment thread CHANGELOG.md Outdated
@mmagician
mmagician force-pushed the mmagician-claude/port-fee-estimate-split branch from ccad489 to 05ccca0 Compare September 3, 2026 10:45
Comment thread crates/miden-standards/asm/standards/fees/mod.masm Outdated
Comment thread crates/miden-standards/asm/standards/fees/mod.masm Outdated
Comment thread crates/miden-standards/asm/standards/fees/mod.masm Outdated
@mmagician
mmagician requested a review from bobbinth September 3, 2026 12:15
@mmagician mmagician changed the title refactor(standards): split fee estimation out of pay_fee refactor(standards): split fee estimation out of pay_fee Sep 3, 2026
@mmagician
mmagician marked this pull request as draft September 3, 2026 12:21
@mmagician
mmagician marked this pull request as ready for review September 3, 2026 14:03
WiktorStarczewski and others added 11 commits September 3, 2026 14:08
Port of #3784 from release/v0.16.0-rc to next. `fee::estimate_fee` owns
everything up to the single `tx::compute_fee`, pricing the sponsorship
notes through the new `fees::estimate_network_note_sponsorships`;
`pay_fee` composes it with `fees::create_network_note_sponsorships` and
the unchanged payment tail.

Adapted to next: `tx::get_fee_asset_id` replaces `get_fee_faucet_id`,
which made the `pay_network_note_sponsorships` wrapper a single call, so
it was dropped as suggested in the rc review; `to_amount_unchecked`
follows the next rename.

Unlike rc, `pay_fee` reads the fee asset ID once for both passes and the
margin math reuses the output-note count the walk already read: the rc
shape added two kernel calls per fee payment, which pushed the
"consume two P2ID notes with ECDSA signing" bench scenario past the
16384-row padding bracket pinned by the trace-contract guard.

Cost tables regenerated on next.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkQzFtRjyDwQ7iVtRbsHsn
…he apply_cycle_margins change

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkQzFtRjyDwQ7iVtRbsHsn
Drops the wrapper that only read the asset ID: `fee::estimate_fee` now
takes FEE_ASSET_ID as its first input, and `pay_fee` reads it once for
the estimate and the sponsorship payment. Cost tables regenerated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkQzFtRjyDwQ7iVtRbsHsn
The procedure gained the sponsorship-note count as well as the
output-note count.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkQzFtRjyDwQ7iVtRbsHsn
Co-authored-by: Marti <marcin.gorny.94@protonmail.com>
The estimate pass records every network output note's price in a
caller-provided table indexed by output note index, and the creation
pass funds the sponsorship notes from that table instead of repeating
the FPI call into each target's fee policy. `pay_fee` keeps the table
in its locals; `estimate_fee` and both `fees` walks take its address.

This removes the second pricing pass from the payment tail, so the
cycle margins after `compute_fee` no longer stand in for foreign
procedure calls, and network-note transactions shrink by about 3500
core rows. Cost tables regenerated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkQzFtRjyDwQ7iVtRbsHsn
Covers the price table with two network notes priced differently, so a
sponsorship funded from the wrong entry would fail. Also names the
table size on estimate_fee's doc and the changelog, and drops a stale
comment about a pricing call in the payment tail.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkQzFtRjyDwQ7iVtRbsHsn
The price table holds the fee asset value word each target returned,
one per output note, so the payment reads back exactly what was priced
instead of rebuilding the value from an amount. Cost tables regenerated.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkQzFtRjyDwQ7iVtRbsHsn
With the pricing call gone from the payment tail, a sponsorship note
costs about 4300 cycles to create and each walked output note about
400, measured by diffing the auth procedure cycles of transactions with
one to three plain, zero-priced and sponsored network notes.
SPONSORSHIP_NOTE_CYCLES drops from 16384 to 8192; the walk margin stays.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkQzFtRjyDwQ7iVtRbsHsn
@mmagician
mmagician force-pushed the mmagician-claude/port-fee-estimate-split branch from 470a84a to 92e00db Compare September 3, 2026 14:12
Asserts the measured creation cost of one sponsorship note stays within
SPONSORSHIP_NOTE_CYCLES and the cost of walking one more output note
through both passes within twice the per-note walk margin, mirroring
the constants next to the other fee-flow mirrors.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkQzFtRjyDwQ7iVtRbsHsn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants