Conversation
* refactor: address remaining #3204 comments (standards module moves) Carries the #3204 follow-up cleanup on top of the unified authenticator: - [BREAKING] move the `note_tag` MASM module to `miden::standards::note::note_tag` - [BREAKING] move the `note_creator` component to the `utils` namespace and the Rust `NoteCreator` type to `account::note_creator` - re-export `create_note` from the basic-wallet interface - standardize the panic-condition wording in the kernel/protocol MASM doc comments and update the affected import sites and docs The authenticator doc comments in api.masm / native_account.masm and the CHANGELOG entry are kept consistent with the flag-based tracking design from the parent commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: small comment fixes * chore: re-trigger CI --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ency switch (#3520) * test(standards): pin the freeze-only actor asymmetry under RBAC * docs(standards): document the freeze-only actor pattern on Authority * changelog
* refactor: remove asset value from callback outputs * test: preserve callback value regression coverage * test: restore account callback value regression * Apply suggestions from code review * refactor: make callback wrappers consume inputs * docs: preserve callback changelog history --------- Co-authored-by: Philipp Gackstatter <18741416+PhilippGackstatter@users.noreply.github.com>
Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
Co-authored-by: UfukNode <208284577+UfukNode@users.noreply.github.com>
…dings (#3463) The security/code-reviewer agents sometimes clear a section with prose like "None. I specifically tried and failed to break the following:" followed by bullets documenting what was ruled out. `_count_blocking_findings` only recognized an exact `- None.` bullet as an absence marker, so those diligence bullets were counted as real findings, producing a false "N blocking finding(s)" verdict even though the reviewer intended CLEAN. Require a blocking section's first content line to open with "None"/"N/A" (bare, bolded, or with a period-terminated explanation on the same line, but not a real finding like "None of the callers..." - there's no "." or end-of-line right after "None" there); once matched, the rest of the section is ignored. A stray absence marker anywhere else only skips itself, so a real finding followed by a later "- None." isn't double-counted. This is fail-open for the narrow case of a "None." opener genuinely followed by real findings. Both prompts already require the response to open with a `BLOCK:`/`CLEAN:`/`APPROVE:` token (tolerant of markdown bold around it, and found by searching the preamble before the review body starts rather than strictly at byte 0 - a model occasionally writes a sentence or two before the token line even when told to lead with it, which happened for real during this change's own review); use it as a simple backstop - missing it is malformed output (blocks), and a self-reported BLOCK overrides a structured count of 0. A structured count still always wins over a self-reported CLEAN, so the agent can't talk its way past a real finding. Update both reviewer prompts: put the leading token directly into the Output Format template (as a placeholder, not a literal example that could get echoed as a real verdict) so it isn't just a trailing instruction the agent might drift from, align code-reviewer's verdict vocabulary with the token vocabulary (APPROVE/BLOCK instead of APPROVE/REQUEST CHANGES), and state the Empty Sections rule as one unambiguous sentence in both directions in both files. Co-authored-by: Claude (Opus) <noreply@anthropic.com>
…ezing role management (#3476) * fix(standards): prevent role delegation to a dead admin role from freezing role management * changelog * fix comment * remove redundant comments * apply suggestions
…es (#3501) * refactor(protocol): move shared input note helpers into private modules * chore: update changelog PR link * chore: address review comments * Apply suggestions from code review Co-authored-by: Marti <marcin.gorny.94@protonmail.com> --------- Co-authored-by: Marti <marti@miden.team> Co-authored-by: Marti <marcin.gorny.94@protonmail.com>
…oc to indexed-note path (#3542) The Panics doc for remove_asset_raw and remove_all_assets_raw stated unconditionally that calling outside the native account's context panics. That only holds for the indexed-note path (is_active_note is false); the active-note path used by active_note::remove_asset / remove_all_assets is exempt, per the kernel's own doc for the underlying procs (api.masm input_note_remove_asset / input_note_remove_all_assets). Co-authored-by: Claude (Opus) <noreply@anthropic.com>
* feat: track generic assets in `AccountVaultDelta` * chore: add changelog * chore: address review comments * chore: move changelog entry to 0.17
* feat(agglayer): configure priced fee policies at deployment * docs: document AggLayer constant fee policies * refactor(agglayer): add fee policy account builders * refactor(agglayer): streamline fee policy builders * test(agglayer): clarify fee manager names * refactor(agglayer): simplify testing helper imports * test(agglayer): cover bridge flows with fees enabled * refactor(tests): unify AggLayer fee policy setup * fix: address fee policy deployment review Make the fee policy manager a required argument of the AggLayer account builders instead of an optional setter whose absence panicked in `build()`, and expose the faucet's asset callback flag on the builder. The bridge-in claim-to-P2ID test regained the callback-enabled faucet it lost when it moved to the priced helper, and the bridge-out test keeps pinning all 32 bundled Solidity MTF vectors. * feat(agglayer): make deployed fee schedules repricable Both AggLayer network accounts install the ConstantFeeManager and allowlist CONSTANT_FEE_POLICY_CONFIG notes, so their ADMIN role can reprice a schedule that was otherwise frozen at deployment. The bridge sizes the sponsorship of every MINT and BURN note it creates from the faucet's schedule, so leaving the faucet frozen would stall bridging once the chain's verification base fee moved. The faucet moves from Authority::OwnerControlled to RbacControlled to make that reachable at all: with the bridge as its Ownable2Step owner, every authority-gated procedure was gated on a sender nothing can produce. Minting and burning are unaffected, since MintOwnerOnly and BurnOwnerOnly check the owner slot directly rather than going through Authority. The config note is scheduled free rather than at its benchmarked cost. Consuming one is the only route to set_note_fee, so pricing it would let the schedule put the note that repairs it out of reach. * docs(agglayer): specify fee schedule administration Documents what the fee policy work changed: the deployed schedules and how they are repriced, the faucet's move to RBAC and the resulting split between owner-gated minting and ADMIN-gated configuration, and the CONSTANT_FEE_POLICY_CONFIG note. Also records the operational consequence of a priced schedule that was previously undocumented: a note with a non-zero schedule entry can only be consumed alongside FEE_SPONSORSHIP notes covering it, regardless of the chain's own base fee, so every management note needs a sponsorship funded with it. Pins the faucet allowlist the way the bridge's already was, and covers repricing a paused bridge. * docs(agglayer): reword the SPEC term flagged by the spellchecker * chore: condense the AggLayer fee policy changelog entries * refactor(tests): deduplicate AggLayer fee-enabled test plumbing Adds a find_output_note helper for the six copies of the output-note-by-script-root predicate, returns Option<Note> from add_fee_sponsorship so the fee axis stops being threaded through if/else blocks, and uses the existing authenticated_input_notes iterator overload to restore the builder chains. The priced-account pin test now reuses build_managed_account instead of rebuilding the same two fixtures verbatim. * Update CHANGELOG.md Co-authored-by: zeapoz <zeapo@pm.me> * refactor(agglayer): return AccountBuilder from the account builder helpers Address review feedback on the deployment builder API: - drop the AggLayerBridgeAccountBuilder and AggLayerFaucetAccountBuilder wrappers; AggLayerBridge::account_builder and AggLayerFaucet::account_builder now return the underlying AccountBuilder directly - move the test-only helpers (zero_fee_policy_manager, faucet_account_builder, create_existing_agglayer_faucet) into miden_agglayer::testing * refactor(agglayer): rename the note-set accessors Address review feedback on the note-set naming: the former fee_policy_notes returned the full set of notes the account actually accepts, so it becomes allowed_notes, and the component-specific subsets become bridge_notes and faucet_notes. Record the rename in the changelog and move this PR's entries back under the unreleased v0.17.0 section, where the released v0.16.0 section had absorbed them during the merge from next. * refactor(agglayer): collapse the note-set accessors into allowed_notes AuthNetworkAccount::new already extends any allowlist it is given with the default network-account notes, so passing the full set to the builder is idempotent and the bridge_notes/faucet_notes split served no purpose. * refactor(agglayer): inline the account builders and drop the one-shot constructors AggLayerBridge::account_builder and AggLayerFaucet::account_builder now hold the building logic directly; the faucet builder takes the initial supply so test fixtures no longer need a separate pass-through, and the unused create_bridge_account / create_agglayer_faucet wrappers are gone. * docs(agglayer): explain the zero-priced fee config note and flag #2724 The zero schedule entry only forgoes enforced reimbursement: a voluntary sponsorship still funds a repricing transaction, and the pricer still computes the config note's real cost. Also document the price-then-allowlist ordering for new roots and mark the faucet ownership-rotation question as tracked by #2724. * test(agglayer): prove a sponsored repricing note reimburses the bridge * docs(agglayer): correct the faucet ownership claim - transfer is owner-gated The SPEC and builder docs claimed the faucet ADMIN can retarget the Ownable2Step owner. It cannot: transfer_ownership asserts the note sender is the current owner (the bridge), never consulting Authority, and the bridge has no flow that authors such a note. Rotation stays unreachable; #2724 tracks removing the dead procedures. * docs(agglayer): simplify the fee policy wording * docs(agglayer): note that a priced-in margin delays repricing * docs(agglayer): quantify the default pricing margin The default NetworkNotePricer margin is one extra verification cycle, roughly 6% of the fee, so a schedule built with it is not far from needing a reprice when the base fee rises. * docs(agglayer): document the bridge-faucet schedule coupling The bridge funds MINT/BURN sponsorships sized by the faucet's schedule and is reimbursed via its own CLAIM/B2AGG prices, so faucet repricing must be matched on the bridge. Nothing enforces this; it is an operator rule. * docs(agglayer): correct the schedule-coupling consequence A faucet entry repriced past the bridge's own CLAIM/B2AGG entry does not merely drain the vault: the AtMostCollectedFees assertion aborts every claim and bridge-out. Also document the bridge-first repricing order and that the bridge's CLAIM/B2AGG entries must never be zeroed. * docs(agglayer): state the schedule-coupling invariant instead of one order Bridge-first repricing is only safe upward; the invariant is that the bridge's CLAIM/B2AGG entries never sit below the faucet's MINT/BURN entries, so raise the bridge first and lower the faucet first. Zeroing the bridge entries halts claims outright rather than draining. * docs(agglayer): state the full schedule-coupling rule The solvency rule includes the bridge's own consumption fee, which is what NetworkNotePricer deploys, applies to every registered faucet, and holds during registration as well as repricing. Also note that raising an entry strands in-flight notes until a top-up sponsorship is added. * docs(agglayer): trim fee administration spec * fix(fees): price config notes without losing recovery * docs(fees): correct the repricing recovery story Drop the zero-reset claim and state the real sender-side constraint: standard auth components size a config note's sponsorship from the target's pre-transaction estimate (fee::pay_fee), so recovering from an excessively high entry requires fronting the previous fee, and an entry no sender can fund freezes fee administration. Also generalize the charged-the-new-value rule to every note of a repriced root and note that raising a fee leaves already-created notes under-sponsored until an extra FEE_SPONSORSHIP tops them up. * fix(agglayer): drop the unused allow_all burn policy from the faucet Registering BurnAllowAll as an allowed policy let the ADMIN role open burns in two steps under Authority::RbacControlled: widen the note allowlist with FAUCET_POLICY_CONFIG, then activate the registered policy. No AggLayer flow opens burns - bridge-out burns through the owner-gated receive_and_burn - so remove the registration and the redundant explicit component instead of documenting the escalation. The faucet code commitment changes. * chore: condense the AggLayer changelog, state the faucet ADMIN rotation limit One changelog entry for the whole PR. The SPEC trust model and the faucet builder docs now state that the faucet does not allowlist RBAC_CONFIG: its ADMIN cannot be rotated directly, and losing the key freezes the faucet's authority-gated configuration. * chore(agglayer): tidy the fee test fixtures and docs Use the mock chain's native fee faucet in the zero-fee fixture, record why the priced fixtures cannot move next to the zero-fee ones, drop a stale doc reference to a deleted scenario, and add the missing section header in fee_policy.rs. * test(agglayer): pin the output-note counts in the fee-enabled E2E cases find_output_note returns the first match by script root, so nothing pinned the total note count after the assertions were relaxed. Assert the exact per-case counts (feature note alone fee-free; plus the FEE_SPONSORSHIP and TX_FEE notes fee-enabled) so a stray extra note fails loudly. * docs(agglayer): note the inert FEE_SPONSORSHIP schedule entry Fee collection prices sponsorship notes at zero without consulting the policy, so the scheduled FEE_SPONSORSHIP entry is never read; it exists only to keep the schedule covering the whole allowlist. * docs(agglayer): tighten the fee administration and faucet ADMIN caveats The full mechanics live in the CONSTANT_FEE_POLICY_CONFIG note rustdoc; the SPEC states the outcomes and points there. * docs(fees): compress the config-note operational notes * docs(agglayer): rewrap the faucet allowlist doc paragraph * Update crates/miden-agglayer/src/lib.rs Co-authored-by: Marti <marti@miden.team> * Update crates/miden-agglayer/src/lib.rs Co-authored-by: Marti <marti@miden.team> * fix(fees): drop the sponsorship note from constant fee schedules A fee schedule maps a note script root to the price charged for consuming it. A FEE_SPONSORSHIP note funds those prices rather than carrying one, and fee collection never consults the policy for it: collect_sponsored_fees records a required fee of zero for a sponsorship input, and is_network_note keys off the NetworkAccountTarget attachment, which a sponsorship note never carries. Unifying the AggLayer note-set accessors pulled the root into the schedule as a side effect. Express the rule once as FeeSponsorshipNote::feature_notes and price only those. * docs(agglayer): disambiguate ADMIN and trim SPEC change narration Each faucet installs its own role set, so both accounts have a built-in ADMIN. State that once in the administration section and qualify the ambiguous uses. Drop the config-note text that narrated how pricing changed during review in favour of what the design does now. * docs(agglayer): restore the AuthNetworkAccount link definition The applied review suggestion removed the link-reference definition along with the paragraph above it, breaking cargo doc under -D warnings. * chore: trim the AggLayer changelog entry * docs(agglayer): say the bridge accepts three other standard notes * docs(agglayer): plainer wording in the allowlist and builder docs Say the bridge accepts three other standard notes rather than opting into standards notes, and allowed rather than sanctioned input notes. Reword the faucet's sponsorship-sizing note into two plain sentences. Drop the prose and inline comments restating that AuthNetworkAccount adds its own defaults, and the orphaned link definitions they leave behind. * docs(fees): simplify the config note's operational notes Drop the redundant RBAC comment in build.rs, which the component-order comment below it already covers. * docs(agglayer): drop the duplicate issue link from the trust model table * docs(agglayer): name the components the faucet shares with the bridge * chore: move the AggLayer entry to the v0.16.0 changelog section * refactor(tx): drop the AggLayer fee policy helpers from NetworkNotePricer Callers pass the account's allowed_notes to basic_constant_fee_policy_manager directly, keeping the pricer agnostic about account types. * refactor(agglayer): clean up bridge note pricing --------- Co-authored-by: zeapoz <zeapo@pm.me> Co-authored-by: Marti <marti@miden.team>
…3581) * feat(agglayer): configure priced fee policies at deployment * docs: document AggLayer constant fee policies * refactor(agglayer): add fee policy account builders * refactor(agglayer): streamline fee policy builders * test(agglayer): clarify fee manager names * refactor(agglayer): simplify testing helper imports * test(agglayer): cover bridge flows with fees enabled * refactor(tests): unify AggLayer fee policy setup * fix: address fee policy deployment review Make the fee policy manager a required argument of the AggLayer account builders instead of an optional setter whose absence panicked in `build()`, and expose the faucet's asset callback flag on the builder. The bridge-in claim-to-P2ID test regained the callback-enabled faucet it lost when it moved to the priced helper, and the bridge-out test keeps pinning all 32 bundled Solidity MTF vectors. * feat(agglayer): make deployed fee schedules repricable Both AggLayer network accounts install the ConstantFeeManager and allowlist CONSTANT_FEE_POLICY_CONFIG notes, so their ADMIN role can reprice a schedule that was otherwise frozen at deployment. The bridge sizes the sponsorship of every MINT and BURN note it creates from the faucet's schedule, so leaving the faucet frozen would stall bridging once the chain's verification base fee moved. The faucet moves from Authority::OwnerControlled to RbacControlled to make that reachable at all: with the bridge as its Ownable2Step owner, every authority-gated procedure was gated on a sender nothing can produce. Minting and burning are unaffected, since MintOwnerOnly and BurnOwnerOnly check the owner slot directly rather than going through Authority. The config note is scheduled free rather than at its benchmarked cost. Consuming one is the only route to set_note_fee, so pricing it would let the schedule put the note that repairs it out of reach. * docs(agglayer): specify fee schedule administration Documents what the fee policy work changed: the deployed schedules and how they are repriced, the faucet's move to RBAC and the resulting split between owner-gated minting and ADMIN-gated configuration, and the CONSTANT_FEE_POLICY_CONFIG note. Also records the operational consequence of a priced schedule that was previously undocumented: a note with a non-zero schedule entry can only be consumed alongside FEE_SPONSORSHIP notes covering it, regardless of the chain's own base fee, so every management note needs a sponsorship funded with it. Pins the faucet allowlist the way the bridge's already was, and covers repricing a paused bridge. * docs(agglayer): reword the SPEC term flagged by the spellchecker * chore: condense the AggLayer fee policy changelog entries * refactor(tests): deduplicate AggLayer fee-enabled test plumbing Adds a find_output_note helper for the six copies of the output-note-by-script-root predicate, returns Option<Note> from add_fee_sponsorship so the fee axis stops being threaded through if/else blocks, and uses the existing authenticated_input_notes iterator overload to restore the builder chains. The priced-account pin test now reuses build_managed_account instead of rebuilding the same two fixtures verbatim. * Update CHANGELOG.md * refactor(agglayer): return AccountBuilder from the account builder helpers Address review feedback on the deployment builder API: - drop the AggLayerBridgeAccountBuilder and AggLayerFaucetAccountBuilder wrappers; AggLayerBridge::account_builder and AggLayerFaucet::account_builder now return the underlying AccountBuilder directly - move the test-only helpers (zero_fee_policy_manager, faucet_account_builder, create_existing_agglayer_faucet) into miden_agglayer::testing * refactor(agglayer): rename the note-set accessors Address review feedback on the note-set naming: the former fee_policy_notes returned the full set of notes the account actually accepts, so it becomes allowed_notes, and the component-specific subsets become bridge_notes and faucet_notes. Record the rename in the changelog and move this PR's entries back under the unreleased v0.17.0 section, where the released v0.16.0 section had absorbed them during the merge from next. * refactor(agglayer): collapse the note-set accessors into allowed_notes AuthNetworkAccount::new already extends any allowlist it is given with the default network-account notes, so passing the full set to the builder is idempotent and the bridge_notes/faucet_notes split served no purpose. * refactor(agglayer): inline the account builders and drop the one-shot constructors AggLayerBridge::account_builder and AggLayerFaucet::account_builder now hold the building logic directly; the faucet builder takes the initial supply so test fixtures no longer need a separate pass-through, and the unused create_bridge_account / create_agglayer_faucet wrappers are gone. * docs(agglayer): explain the zero-priced fee config note and flag #2724 The zero schedule entry only forgoes enforced reimbursement: a voluntary sponsorship still funds a repricing transaction, and the pricer still computes the config note's real cost. Also document the price-then-allowlist ordering for new roots and mark the faucet ownership-rotation question as tracked by #2724. * test(agglayer): prove a sponsored repricing note reimburses the bridge * docs(agglayer): correct the faucet ownership claim - transfer is owner-gated The SPEC and builder docs claimed the faucet ADMIN can retarget the Ownable2Step owner. It cannot: transfer_ownership asserts the note sender is the current owner (the bridge), never consulting Authority, and the bridge has no flow that authors such a note. Rotation stays unreachable; #2724 tracks removing the dead procedures. * docs(agglayer): simplify the fee policy wording * docs(agglayer): note that a priced-in margin delays repricing * docs(agglayer): quantify the default pricing margin The default NetworkNotePricer margin is one extra verification cycle, roughly 6% of the fee, so a schedule built with it is not far from needing a reprice when the base fee rises. * docs(agglayer): document the bridge-faucet schedule coupling The bridge funds MINT/BURN sponsorships sized by the faucet's schedule and is reimbursed via its own CLAIM/B2AGG prices, so faucet repricing must be matched on the bridge. Nothing enforces this; it is an operator rule. * docs(agglayer): correct the schedule-coupling consequence A faucet entry repriced past the bridge's own CLAIM/B2AGG entry does not merely drain the vault: the AtMostCollectedFees assertion aborts every claim and bridge-out. Also document the bridge-first repricing order and that the bridge's CLAIM/B2AGG entries must never be zeroed. * docs(agglayer): state the schedule-coupling invariant instead of one order Bridge-first repricing is only safe upward; the invariant is that the bridge's CLAIM/B2AGG entries never sit below the faucet's MINT/BURN entries, so raise the bridge first and lower the faucet first. Zeroing the bridge entries halts claims outright rather than draining. * docs(agglayer): state the full schedule-coupling rule The solvency rule includes the bridge's own consumption fee, which is what NetworkNotePricer deploys, applies to every registered faucet, and holds during registration as well as repricing. Also note that raising an entry strands in-flight notes until a top-up sponsorship is added. * docs(agglayer): trim fee administration spec * fix(fees): price config notes without losing recovery * docs(fees): correct the repricing recovery story Drop the zero-reset claim and state the real sender-side constraint: standard auth components size a config note's sponsorship from the target's pre-transaction estimate (fee::pay_fee), so recovering from an excessively high entry requires fronting the previous fee, and an entry no sender can fund freezes fee administration. Also generalize the charged-the-new-value rule to every note of a repriced root and note that raising a fee leaves already-created notes under-sponsored until an extra FEE_SPONSORSHIP tops them up. * fix(agglayer): drop the unused allow_all burn policy from the faucet Registering BurnAllowAll as an allowed policy let the ADMIN role open burns in two steps under Authority::RbacControlled: widen the note allowlist with FAUCET_POLICY_CONFIG, then activate the registered policy. No AggLayer flow opens burns - bridge-out burns through the owner-gated receive_and_burn - so remove the registration and the redundant explicit component instead of documenting the escalation. The faucet code commitment changes. * chore: condense the AggLayer changelog, state the faucet ADMIN rotation limit One changelog entry for the whole PR. The SPEC trust model and the faucet builder docs now state that the faucet does not allowlist RBAC_CONFIG: its ADMIN cannot be rotated directly, and losing the key freezes the faucet's authority-gated configuration. * chore(agglayer): tidy the fee test fixtures and docs Use the mock chain's native fee faucet in the zero-fee fixture, record why the priced fixtures cannot move next to the zero-fee ones, drop a stale doc reference to a deleted scenario, and add the missing section header in fee_policy.rs. * test(agglayer): pin the output-note counts in the fee-enabled E2E cases find_output_note returns the first match by script root, so nothing pinned the total note count after the assertions were relaxed. Assert the exact per-case counts (feature note alone fee-free; plus the FEE_SPONSORSHIP and TX_FEE notes fee-enabled) so a stray extra note fails loudly. * docs(agglayer): note the inert FEE_SPONSORSHIP schedule entry Fee collection prices sponsorship notes at zero without consulting the policy, so the scheduled FEE_SPONSORSHIP entry is never read; it exists only to keep the schedule covering the whole allowlist. * docs(agglayer): tighten the fee administration and faucet ADMIN caveats The full mechanics live in the CONSTANT_FEE_POLICY_CONFIG note rustdoc; the SPEC states the outcomes and points there. * docs(fees): compress the config-note operational notes * docs(agglayer): rewrap the faucet allowlist doc paragraph * Update crates/miden-agglayer/src/lib.rs * Update crates/miden-agglayer/src/lib.rs * fix(fees): drop the sponsorship note from constant fee schedules A fee schedule maps a note script root to the price charged for consuming it. A FEE_SPONSORSHIP note funds those prices rather than carrying one, and fee collection never consults the policy for it: collect_sponsored_fees records a required fee of zero for a sponsorship input, and is_network_note keys off the NetworkAccountTarget attachment, which a sponsorship note never carries. Unifying the AggLayer note-set accessors pulled the root into the schedule as a side effect. Express the rule once as FeeSponsorshipNote::feature_notes and price only those. * docs(agglayer): disambiguate ADMIN and trim SPEC change narration Each faucet installs its own role set, so both accounts have a built-in ADMIN. State that once in the administration section and qualify the ambiguous uses. Drop the config-note text that narrated how pricing changed during review in favour of what the design does now. * docs(agglayer): restore the AuthNetworkAccount link definition The applied review suggestion removed the link-reference definition along with the paragraph above it, breaking cargo doc under -D warnings. * chore: trim the AggLayer changelog entry * docs(agglayer): say the bridge accepts three other standard notes * docs(agglayer): plainer wording in the allowlist and builder docs Say the bridge accepts three other standard notes rather than opting into standards notes, and allowed rather than sanctioned input notes. Reword the faucet's sponsorship-sizing note into two plain sentences. Drop the prose and inline comments restating that AuthNetworkAccount adds its own defaults, and the orphaned link definitions they leave behind. * docs(fees): simplify the config note's operational notes Drop the redundant RBAC comment in build.rs, which the component-order comment below it already covers. * docs(agglayer): drop the duplicate issue link from the trust model table * docs(agglayer): name the components the faucet shares with the bridge * chore: move the AggLayer entry to the v0.16.0 changelog section * refactor(tx): drop the AggLayer fee policy helpers from NetworkNotePricer Callers pass the account's allowed_notes to basic_constant_fee_policy_manager directly, keeping the pricer agnostic about account types. * refactor(agglayer): clean up bridge note pricing --------- Co-authored-by: Alexander John Lee <77119221+partylikeits1983@users.noreply.github.com> Co-authored-by: zeapoz <zeapo@pm.me>
…3576) * chore: rename value_into_amount API for consistency * chore: add changelog * chore: structure the changelog
* fix(protocol): validate private note attachments * test(protocol): clarify attachment mismatch assertions * test(protocol): simplify mismatch assertions
* refactor(agglayer): construct fee policy managers internally * chore: link AggLayer changelog to follow-up PR * refactor(agglayer): inline fee policy manager construction
…a single constructor (#3548) * refactor(protocol): consolidate `MastForestScript` instantation into a single constructor * chore: update builder methods to use `mut self` --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
* fix: assert procedure belongs to foreign account * chore: add changelog * Apply suggestions from code review Co-authored-by: Alexander John Lee <77119221+partylikeits1983@users.noreply.github.com> --------- Co-authored-by: Marti <marti@miden.team> Co-authored-by: Alexander John Lee <77119221+partylikeits1983@users.noreply.github.com>
…es (#3500) * document AuthControlled in authority-gated config notes * changelog * apply suggestions --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
* feat: sort account procedures at construction * chore: add changelog * chore: address review comments * chore: bring back proc count validation in proc builder
…3567) * feat: validate proc uniqueness and sorting in tx kernel * chore: add changelog * chore: address review comments
* feat(miden-tx): let NetworkNotePricer take supplied note costs The pricer's cost lookup was hard-wired to the standard and agglayer tables, so an account with note families outside those tables — or with table-known script roots that measure differently on its own code — had to re-implement the pricing formula. The builder now accepts note_costs, a map consulted before the built-in tables, and the private test-only lookup hook is folded into it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: changelog entry for the pricer note-cost map Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(changelog): deduplicate the v0.16.0 section The changelog commit had inserted a second `## v0.16.0` header along with entries belonging to other PRs, splitting the release notes into two v0.16.0 sections. Keep the single existing section and add only this PR's `note_costs` entry to its Features list. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(miden-tx): let note costs be supplied individually or as an iterator Switch `note_costs` to a `#[builder(field)]` and expose `note_cost` (single entry) and `note_costs` (iterator) builder extensions, following the SwapNote builder pattern, so callers can set costs one at a time as well as in bulk. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com>
Bump the workspace version 0.16.0-rc.4 -> 0.16.0-rc.5 (workspace.package and the path-dependency pins), refresh Cargo.lock, and date the v0.16.0 changelog section. Co-authored-by: Claude (Opus) <noreply@anthropic.com>
…ture (#3617) * feat(agglayer): expose bridge storage readers outside the testing feature Production callers need these accessors to inspect GER registration, LET state, and hash chains without enabling the testing feature. Co-authored-by: Cursor <cursoragent@cursor.com> * chore: link the changelog entry to the pull request Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
* chore: remove stale doc references, rename procedure * chore: consistent field and getter name * chore: correct stale note version 0 ref
* feat: enforce max delta ops in vault delta * feat: enforce max num added assets in kernel * chore: add changelog * chore: address review comments * chore: simplify vault delta * chore: address review comments --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
* fix(protocol): reject empty asset id in input_note::remove_asset * chore: add changelog entry * chore: re-trigger CI * Update crates/miden-protocol/asm/kernels/transaction-core/src/input_note.masm Co-authored-by: zeapoz <zeapo@pm.me> * chore: fix build --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com> Co-authored-by: zeapoz <zeapo@pm.me> Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com> Co-authored-by: Bobbin Threadbare <bobbinth@protonmail.com>
…der (#3606) * fix(protocol): clear input-note slot on empty fungible removal remainder * chore: add changelog entry * chore: re-trigger CI * Apply suggestions from code review Co-authored-by: Marti <marcin.gorny.94@protonmail.com> * test(protocol): add regression test for non-canonical fungible remove_asset Adds a scenario to test_remove_asset_fails covering audit finding L-03 (#3591): removing a fungible asset with a value whose amount limb matches the stored amount but whose upper limbs are non-zero must now fail with ERR_FUNGIBLE_ASSET_VALUE_MOST_SIGNIFICANT_ELEMENTS_MUST_BE_ZERO instead of leaving a dangling (ASSET_ID, EMPTY_WORD) slot behind. Verified the scenario fails against the pre-fix kernel and passes with the fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Update crates/miden-testing/src/kernel_tests/tx/test_input_note.rs * Apply suggestion from @mmagician --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com> Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
* fix(standards): bind the non-fungible MINT note to its faucet * changelog * address review comments on non-fungible MINT note * refactor(standards): bind the non-fungible MINT note via its stored ASSET_ID * chore: regenerate the note consumption cost tables * refactor(standards): use asset::load in the non-fungible MINT note --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
* fix(protocol): verify faucet callback root against account code * chore: add changelog entry * chore: re-trigger CI * Update CHANGELOG.md Co-authored-by: zeapoz <zeapo@pm.me> * test(protocol): import generated faucet callback error constant Replace the locally redefined ERR_FAUCET_CALLBACK_PROC_ROOT_NOT_PART_OF_ACCOUNT_CODE MasmError with the constant generated from callbacks.masm by the build script, so the test and kernel share a single source of truth for the error string. ERR_ACCOUNT_BLOCKED stays defined locally: it mirrors the test-only BLOCK_LIST_MASM component, not a kernel error, so it is not build-generated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore: refresh cost tables --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com> Co-authored-by: zeapoz <zeapo@pm.me> Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com> Co-authored-by: Bobbin Threadbare <bobbinth@protonmail.com>
…dures (#3610) * refactor(protocol): use native accessors in native-only account procedures * Update crates/miden-protocol/asm/kernels/transaction-core/src/account.masm * Apply suggestion from @mmagician * fix(protocol): move num_storage_slots instead of duplicating it in find_storage_slot Addresses review feedback on the end-pointer construction in find_storage_slot: swap the slot count to the top and consume it directly via mul, instead of duplicating it with dup.1 and dropping the leftover copy afterwards. Same public interface, fewer cycles. * Apply suggestion from @mmagician --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com>
…icy (#3547) * fix(standards): enable asset callbacks on faucets with a transfer policy * changelog and remove comments * merge * test(standards): share the faucet policy-manager fixtures --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
* feat(standards): enforce FPI expiration limits * refactor(standards): drop the @fpi attribute pending defined semantics * refactor(standards): remove expiration deltas from the policy manager Expiration deltas are policy-owned per review feedback on #3512: the dispatchers deliberately set none, and each transfer policy applies its own. Documented the contract - including that the dispatcher's own policy-root and pause-flag reads are unbounded when the active policy sets no delta, pending the protocol-wide backstop discussed in #3504 - on the dispatchers and on TransferPolicy::custom. Narrowed the CHANGELOG entry to the procedures actually covered and moved it from the released v0.16.0 section into v0.17.0, where this lands. * refactor(standards): replace expiration helper with fpi::apply_default_expiration_delta Per review feedback on #3512: the nonzero check duplicated the kernel's own validation in tx::update_expiration_block_delta, so the helper is now a parameterless one-liner that call sites invoke without pushing the delta themselves. Documented the expiration side effect on the four procedures that apply it and added the module to the changelog. * feat(standards): apply default expiration delta in remaining standard policies Per review feedback on #3512: min_burn_amount reads the mutable minimum burn amount and the owner-only mint/burn policies read the mutable Ownable2Step owner slot, so their check_policy procedures now apply the default expiration delta like the allowlist/blocklist policies do. The allow-all policies read no state and stay unbounded. * refactor(standards): align expiration docs and deduplicate test assertions Review polish: document the policy-owned expiration contract (including the unbounded dispatcher reads and the #3504 backstop pointer) on the mint/burn dispatchers, the Mint/BurnPolicy types, and their custom constructors to match the transfer path; mark the unbounded config getters (get_fee_policy, get_min_burn_amount) as deliberate pending #3504; correct the get_fee_asset_id rationale (the fee asset slot has no setter); add the missing stack trackers after the new call sites; and replace eight copy-pasted test assertions with a shared track_caller helper that mirrors DEFAULT_EXPIRATION_BLOCK_DELTA. * docs(standards): remove stale expiration references * refactor(standards): rename FPI expiration helper * refactor(standards): narrow FPI expiration scope * docs: consolidate FPI expiration changelog entry * docs: simplify FPI expiration changelog entry * refactor(testing): import expiration assertion helper * refactor(testing): simplify expiration assertion helper * docs(standards): trim transfer expiration rationale
…depth (#3645) * fix(standards): return get_schema_commitment at the required stack depth * chore: fix changelog PR reference --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
…cetPolicyConfig scripts (#3563) * feat(protocol): bound note storage loading in the OwnerConfig and FaucetPolicyConfig scripts * changelog * remove redundant comments * fix: address review comments on active_note storage procedures * fix: use get_bounded_storage in note scripts with a bounded storage layout --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
…el_proc` (#3646) * chore: make only exec_kernel_proc syscall invokable * chore: add changelog * chore: entrypoint -> dispatcher * chore: update stale entrypoint refs
…3641) * fix(protocol): verify input-note storage item count in the prologue * refactor(protocol): name the note storage preimage local offset Addresses review: promote the magic 0 in locaddr.0 to the PROCESS_NOTE_STORAGE_PREIMAGE_LOC constant. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(protocol): reword "advised" item count to count from the advice map Addresses review: "advised" is not used as an adjective in this codebase; refer to the item count from the advice map instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(protocol): add stack state comment before pipe_elements_preimage_to_memory Addresses review: document the operand stack state right before the call to pipe_elements_preimage_to_memory. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(protocol): refer to procedure locals instead of scratch memory Addresses review: "scratch buffer"/"scratch memory" is not used in this codebase; refer to memory locals / the preimage buffer instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Apply suggestions from code review Co-authored-by: Marti <marcin.gorny.94@protonmail.com> * docs(protocol): note that push_mapvaln also pushes the element count --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com> Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
… in `mint_and_send` (#3660) * refactor(standards): drop redundant dupw/dropw around loc_storew_le in mint_and_send * changelog * Update CHANGELOG.md --------- Co-authored-by: Philipp Gackstatter <PhilippGackstatter@users.noreply.github.com>
…3666) * fix(standards): reject zero-amount mints in fungible mint_and_send * changelog * drop redundant comments
* fix(protocol): validate storage slot type at account creation * chore: add changelog entry * chore: re-trigger CI * Update crates/miden-protocol/asm/kernels/transaction-core/src/account.masm Co-authored-by: zeapoz <zeapo@pm.me> * refactor(protocol): validate slot types inside the storage validation loop Merge the separate validate_storage_slot_types pass into the main validate_storage loop so storage is validated in a single pass over the slots, per review feedback. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(protocol): read only native account state in validate_storage validate_storage mixed the two accessor families: the slot count and the slot IDs resolved through the active account, while the slot type was read from the native account. Only the native account's storage is validated this way, so take every read from the native account. get_native_slot_id already existed and is identical to get_slot_id apart from the accessor, and validate_storage was get_slot_id's only caller, so drop the duplicate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Apply suggestion from @mmagician --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com> Co-authored-by: zeapoz <zeapo@pm.me> Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com> Co-authored-by: Bobbin Threadbare <bobbinth@protonmail.com>
…ation (#3609) * fix(protocol): assert reserved account state elements are zero at creation * chore: add changelog entry * test: collapse header reserved-element assertion into assert_matches if-guard Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test: collapse storage-slot reserved-element assertion into assert_matches if-guard Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(protocol): read the new reserved-element accessors from the native account Both accessors introduced here resolve through the active account, but their only callers validate a new native account: validate_new_account for the account header word and validate_storage for the slot records. Read them from the native account instead, so neither can be pointed at a foreign account. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com>
…ccount` (#3657) * refactor(protocol): read only native account state in validate_new_account validate_new_account read the account ID, nonce and vault root through the active account, even though it only ever validates the native account. The native variants of all three already exist, so switch to them and leave the active accessors for the procedures that genuinely serve foreign accounts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Update crates/miden-protocol/asm/kernels/transaction-core/src/prologue.masm --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com>
… assets (#3650) * docs(standards): document that note scripts claim only remaining note assets Standard note scripts move the assets remaining in a note at consumption time and do not compare them against the note's initial assets info. Per the discussion in #3601 this is intentional (it enables authorized deductions such as fees), so document the behavior where notes claim their assets. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(standards): drop PSWAP-specific warnings, deferred to follow-up fix The PSWAP offered-amount drain is being fixed directly in a follow-up PR rather than documented as accepted behavior, so remove the PSWAP hazard warnings from this docs change. The neutral remaining-vs-initial wording is kept consistent with the rest of the standards pass, and the SWAP note (whose loss is consumer-side and not being changed) stays documented here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Apply suggestions from code review Co-authored-by: Marti <marcin.gorny.94@protonmail.com> * Update CHANGELOG.md Co-authored-by: zeapoz <zeapo@pm.me> --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com> Co-authored-by: zeapoz <zeapo@pm.me>
…asset (#3652) * fix(standards): price PSWAP fills against the note's initial offered asset The PSWAP note script priced a fill against the offered asset *remaining* in the note at consumption time rather than the amount the creator funded. A consumer whose own account exposes an indexed-removal procedure could, via an earlier helper note in the same transaction, drain most of the offered asset out of the PSWAP note into their own vault before the PSWAP script ran; the single-asset assert still passed on the partially-removed slot, so the fill was priced against the residue and the creator's remainder note absorbed the loss. Bind the offered amount to the note's initial assets, which the prologue records at note creation and which removals never affect. `load_offered_asset` now fetches the note's initial assets, asserts exactly one, and asserts the single remaining offered asset equals the single initial one word-for-word (asset ID and value), aborting with the new ERR_PSWAP_OFFERED_ASSET_ALTERED otherwise. Any pre-removal from a PSWAP note thus aborts the whole transaction. Both the fill (execute_pswap) and reclaim (handle_reclaim) paths go through this procedure. This changes the compiled PSWAP note-script MAST root and therefore PSWAP note recipients/IDs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(standards): trim pswap fix comments Reduce the inline comments added with the offered-asset binding to match the surrounding file, and drop the counterfactual/pre-fix narration from the doc comments and the regression test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Apply suggestions from code review Co-authored-by: Marti <marcin.gorny.94@protonmail.com> * refactor(standards): name load_offered_asset local offsets Replace the bare locaddr.0 / locaddr.8 in load_offered_asset with named OFFERED_REMAINING_ASSET_PTR / OFFERED_INITIAL_ASSET_PTR constants, matching the per-proc local-offset convention used elsewhere in the file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Apply suggestion from @mmagician * Apply suggestions from code review Co-authored-by: zeapoz <zeapo@pm.me> Co-authored-by: Philipp Gackstatter <PhilippGackstatter@users.noreply.github.com> * fix(standards): use helper_note_id instead of the moved helper_note in PSWAP drain test --------- Co-authored-by: Claude (Opus) <noreply@anthropic.com> Co-authored-by: zeapoz <zeapo@pm.me> Co-authored-by: Philipp Gackstatter <PhilippGackstatter@users.noreply.github.com>
* chore: make exec_kernel_proc reusable across kernels * chore: add changelog * fix: memory.rs table --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
* fix(agglayer): make faucet roles rotatable * test(agglayer): cover faucet role rotation * test(agglayer): focus faucet RBAC integration coverage
* feat(agglayer): add fee manager roles * test(agglayer): avoid panic paths in fee role tests * test(agglayer): cover fee manager role rotation * refactor(agglayer): clarify fee role fixtures
Export standalone Poseidon2 permutation rows alongside the existing transaction trace measurements and validate the complete generated scenario set. Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
…tack padding (#3668) * fix(standards): stop the MINT note scripts assuming caller-provided stack padding * changelog --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com>
* feat(agglayer): add pauser role * refactor(agglayer): clarify pauser fixtures
* chore: remove account_id::validate re-export * feat: add version to asset ID * chore: add changelog * Update docs/src/asset.md Co-authored-by: zeapoz <zeapo@pm.me> * chore: optimize composition extraction --------- Co-authored-by: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com> Co-authored-by: zeapoz <zeapo@pm.me>
* feat: add version to `Account` * chore: add changelog * chore: move version offset to the top * chore: remove stale panic reference, add header test * chore: add version field to header, serialize version * chore: make format * Revert "chore: add version field to header, serialize version" This reverts commit f2829d9.
…3696) * feat: expand note version to 6 bits * feat: reduce block header version to 8 bits, remove param * chore: add changelog
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a tracking PR for v0.17.0 release.