feat: implement asset callbacks#2571
Conversation
cdb8e5f to
7588e08
Compare
bobbinth
left a comment
There was a problem hiding this comment.
Looks good! Thank you! Not a full review yet, but I left some comments inline.
| "auth_procedure": 62667, | ||
| "after_tx_cycles_obtained": 574 | ||
| "total": 71195, | ||
| "auth_procedure": 69694, |
There was a problem hiding this comment.
Auth procedure cycle count went up quite a bit - but I'm guessing this may be because of some prior changes rather than because of this PR, right?
There was a problem hiding this comment.
Checked a few key PRs:
before auth component consolidation: 9cfb4f2a
"auth_procedure": 62641
before asset refactor: a09027b6
"auth_procedure": 63170
before VM migration: e8570061
"auth_procedure": 63169
after VM migration: 0897aae6
"auth_procedure": 69686
So auth component consolidation added ~500 cycles but the VM migration was the main reason for the large increase in cycles.
There was a problem hiding this comment.
Since most of the auth procedure is Falcon signature verification - I wonder if most of the delta is because Falcon signature verification got a bit less efficient.
@Al-Kindi-0 - could you check how many cycles Falcon signature takes now? (maybe some stack re-orientation work made it less efficient?)
crates/miden-protocol/asm/kernels/transaction/lib/callbacks.masm
Outdated
Show resolved
Hide resolved
bobbinth
left a comment
There was a problem hiding this comment.
Looks good! Thank you! I left one small comment inline.
mmagician
left a comment
There was a problem hiding this comment.
Do not allow callbacks to mint anything; keep them read-only in general. For now this is the case and that may be the best option until we have thought about this more thoroughly.
Is this true that right now this is the case? Looking at the procedure signature:
#! Inputs: [ASSET_KEY, ASSET_VALUE]
#! Outputs: [PROCESSED_ASSET_VALUE]
#!
#! Where:
#! - ASSET_KEY is the vault key of the asset being added.
#! - ASSET_VALUE is the value of the asset being added.
#! - PROCESSED_ASSET_VALUE is the asset value returned by the callback, or the original
#! ASSET_VALUE if callbacks are disabled.
pub proc on_before_asset_added_to_account
It looks like PROCESSED_ASSET_VALUE could mint new tokens
The signature is setup so that we could allow this in the future. At the moment, foreign accounts have read-only access to the transaction, so they effectively cannot mint/burn tokens. If/Once we allow that, the callback would be able to mint/burn tokens as well. |
* chore: refactor tx kernel from `ASSET` to `ASSET_KEY` and `ASSET_VALUE` (#2396) * chore: refactor `miden::protocol` from `ASSET` to `ASSET_KEY` and `ASSET_VALUE` (#2410) * feat: adapt the layout of `Asset`s to the double word representation (#2437) * feat: migrate to miden VM 0.21 and miden crypto 0.22 (#2508) * feat: optimize layouts and procedures for little-endian (#2512) * chore: use `get_balance` helper in account_delta * chore: Add `TryFrom<Word> for AssetVaultKey` * feat: refactor `asset.masm` * feat: add `fungible_asset.masm` * feat: refactor `asset_vault.masm` * feat: refactor `faucet.masm` * feat: refactor `account.masm` * feat: refactor `account_delta.masm` * feat: refactor `epilogue.masm` * feat: refactor `output_note.masm` * feat: refactor `prologue.masm` * chore: increase `NOTE_MEM_SIZE` to 3072 * chore: adapt `NoteAssets` commitment * feat: refactor `note.masm` * chore: refactor `api.masm` * chore: regenerate kernel proc hashes * chore: add changelog * fix: faucet::mint output docs * chore: update memory.rs input/output note memory layouts * fix: duplicate num assets in memory.rs table * feat: move `build_asset_vault_key` to shared utils * feat: refactor `faucet::mint` * feat: refactor `faucet::burn` * chore: refactor `create_non_fungible_asset` for uniformity * feat: refactor `native_account::remove_asset` * chore: move `mock::util` lib to miden-standards * feat: refactor `move_asset_to_note` * feat: add asset key to SWAP storage * feat: refactor `native_account::add_asset` * chore: refactor `receive_asset` * feat: refactor `output_note::add_asset` * chore: deduplicate epilogue asset preservation test * chore: remove re-export of vault key builder procedures * chore: regenerate kernel procedure hashes * chore: add changelog * fix: doc link to mock util lib * chore: improve send_note_body impl and test * fix: replace leftover `ASSET`s with `ASSET_VALUE` * chore: update protocol library docs * fix: rename leftover `ASSET` to `ASSET_VALUE` * chore: remove unused error * chore: regenerate tx kernel errors * chore: improve note assets commitment computation * fix: input notes memory assertions * chore: add renamed procedures to changelog * fix: incorrect stack and doc comment * fix: p2id::new test * feat: validate new asset layouts * chore: update asset procedure calls in faucet * feat: add create_fungible_asset_unchecked * chore: change has_non_fungible_asset to take asset key * feat: include full faucet ID limbs in asset delta * chore: remove into `Word` conversions for assets * feat: Implement strongly typed asset vault key * chore: temporarily remove asset vault key hash * chore: remove asset from word conversion * feat: update `Asset` docs * chore: remove unused (non-)fungible asset builders * feat: refactor asset serialization and tests * chore: add validation in get_asset and get_initial_asset * chore: adapt miden-standards to changed asset def * chore: adapt miden-tx to changed asset def * feat: return native asset ID and fee amount as tx output * chore: update create_non_fungible_asset faucet/asset APIs * chore: adapt tests to new asset layouts * feat: validate asset ID prefix in non-fungible assets * chore: drop trailing "asset" from `asset::validate_asset` * chore: rewrite asset validation tests * chore: merge validate_value in `fungible_asset` * chore: remove unused build_asset_vault_key procedures * chore: remove `LexicographicWord` wrapper in non-fungible asset delta * chore: update asset::create_non_fungible_asset signature in docs * fix: test name, vault key display impl, remove unused errors * fix: intra doc links * chore: add changelog * Initial plan * Address review nits: add load_asset_key_and_value utility, use explicit ASSET_PTR constants, rename variables, add test Co-authored-by: mmagician <[email protected]> * Fix load_asset_key_and_value procedure and usages in prologue and epilogue Co-authored-by: mmagician <[email protected]> * Run cargo fmt to fix formatting issues Co-authored-by: mmagician <[email protected]> * Rename asset_value back to asset in tx_event.rs Co-authored-by: mmagician <[email protected]> * Run cargo fmt to fix formatting after variable rename Co-authored-by: mmagician <[email protected]> * chore: simplify fungible_asset merge and add split * chore: remove outdated edge case handling in vault * chore: convert u64s from BE to LE * feat: migrate rpo256 -> poseidon2 * chore: upgrade miden VM & crypto in Cargo.toml * chore: refactor memory.masm from BE to LE * chore: update broken imports in `miden-protocol` * chore: introduce `FromNum` and `TryFromNum` traits * chore: FieldElement import, as_int, and read_many_iter in `protocol` * chore: replace imports in miden-protocol-macros * chore: update imports in miden-standards * chore: update imports in miden-tx * chore: deactivate agglayer in workspace and miden-testing * chore: update imports in miden-testing * chore: migrate account ID and asset-related MASM modules to LE * chore: migrate account, delta and note-related MASM modules to LE * chore: migrate prologue & epilogue to LE * chore: update empty SMT root * chore: migrate tx and api.masm modules to LE * chore: reverse tx stack inputs and outputs * chore: migrate miden::protocol from BE to LE * chore: swap order of link map operands on adv stack * chore: swap prefix/suffix in asset vault test * chore: use more resilient way to write test_transaction_epilogue * chore: migrate tests in miden-testing from BE to LE * chore: update schema type IDs for falcon512_poseidon2::pub_key * chore: migrate miden::standards::{access, auth} from BE to LE * chore: migrate miden::standards::faucets from BE to LE * chore: migrate miden::standards::data_structures from BE to LE * chore: migrate miden::standards::notes from BE to LE * chore: migrate miden::standards::{wallets, attachments} from BE to LE * fix: mmr authentication path for latest block * chore: use falcon512_poseidon2::encode_signature for sig prep * chore: update protocol library docs * chore: remove @BigEndian from type defs * fix: avoid using undeclared stack * feat: reexport asset::mem_load * chore: migrate singlesig_acl from be to le * fix: multisig stack layouts after migration * chore: update Cargo.lock and regenerate kernel proc hashes * chore: cargo update to latest crypto and VM patch releases * fix: unused imports after miden-field upgrade * chore: use `Felt::{from, try_from}` and remove `(Try)FromNum` * chore: remove temp mmr fix and adapt find_half_key_value call * chore: regenerate kernel proc hashes * chore: make toml * chore: add changelog entry * fix: outdated doc links * fix: make format * chore: deactivate miden-agglayer in check-features.sh * chore: allow bincode in deny.toml * fix: deny.toml entries and upgrade toml to 1.0 * fix: transaction context builder doc test * feat: Add `Asset::as_elements` * chore: use `asset::mem_load` in swap note * fix: update agglayer::bridge::bridge_out to new asset layout * chore: remove `Ord for Asset` impl * chore: re-add error when asset-to-be-removed is not present * chore: remove whitespace in docs * chore: `cargo update` * chore: use seed digest 2 and 3 as account ID suffix and prefix * chore: remove `AccountId::try_from<[Felt; 2]>`; add `try_from_elements` * chore: consistently use `RATE0, RATE1, CAPACITY` for hasher state * chore: optimize account_id::validate for little-endian order * chore: optimize account ID seed validation * chore: reverse tx summary stack layout * feat: optimize `account::is_slot_id_lt` for little-endian layout * chore: regenerate kernel proc hashes * chore: add changelog * chore: rename `Falcon512Rpo` to `Falcon512Poseidon2` * chore: rename `_ADDRESS` to `_PTR` in swap * chore: rename `asset::{mem_store, mem_load}` to store/load * chore: use imports instead of absolute paths * chore: reword non-fungible asset key collision resistance * chore: add `AssetId::is_empty` * chore: remove unnecessary imports in `AssetVault` * chore: spell out asset key layout in has_non_fungible_asset * chore: validate account ID type in AssetVaultKey::new * fix: typo in Asset docs * chore: prefix `get/into_faucet_id` with `key` * chore: prefix `get/into_asset_id` with `key` * chore: suffix `is_(non_)fungible_asset` with `key` * chore: address review comments * chore: update outdated tx kernel input/output docs * chore: LE layout for upcoming fpi account ID; fix stack comments * chore: replace `type Word` with built-in `word` * fix: asset::mem_store using `_be` instructions * chore: update `add_input_notes` docs * chore: Add `fungible_asset::to_amount` * chore: replace `swap.3` with `movdn.3` * chore: rename `get_balance_from_fungible_asset` to `value_into_amount` * chore: use more explicit `poseidon2::copy_digest` * chore: ensure asset vault key validity for fungible keys --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: mmagician <[email protected]> Co-authored-by: Bobbin Threadbare <[email protected]> * fix: remove unused MASM imports (#2543) * feat: Enable warnings_as_errors in assembler * fix: remove unused imports in miden-protocol * fix: remove unused imports in miden-standards * fix: enable `miden-crypto/std` in `testing` feature to fix MSRV check (#2544) The migration to miden-crypto 0.22 replaced `winter_rand_utils::rand_value` with `miden_crypto::rand::test_utils::rand_value`, which is gated behind `#[cfg(any(test, feature = "std"))]`. Since the workspace dependency uses `default-features = false`, crates depending on `miden-protocol/testing` without `std` failed to compile, breaking the release-dry-run MSRV check. Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> * chore: enable CI on merge queue trigger (#2540) * chore: enable CI on merge queue trigger * Update .github/workflows/build-docs.yml Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]> * feat: enable warning as errors for `CodeBuilder` (#2558) * refactor: enforce defining supported types on metadata (#2554) * feat: enforce maximum serialized size for output notes (#2205) * feat: introduce `AccountIdKey` (#2495) * Introducing a dedicated AccountIdKey type to unify and centralize all AccountId * changelog for introduce AccountIdKey type * refactor: clean up comments and improve code readability in AccountIdKey and tests * refactor: update AccountIdKey conversion method and clean up imports * refactor: reorganize AccountIdKey indices and clean up related code * Apply suggestions from code review * Update crates/miden-protocol/src/block/account_tree/account_id_key.rs * Update crates/miden-protocol/src/block/account_tree/account_id_key.rs * feat: validate account ID in `AccountTree::new` --------- Co-authored-by: Bobbin Threadbare <[email protected]> Co-authored-by: Philipp Gackstatter <[email protected]> * fix: make format and remove unused import (#2564) * feat: make `NoteMetadataHeader` public (#2561) * chore: ProvenBlock constructor with validation (#2553) * refactor: include fee in TransactionId computation * refactor: remove `Ord` and `PartialOrd` from `StorageSlot` (#2549) * chore: Replace SMT leaf conversion function (#2271) * feat: add ability to submit user batches for the MockChain (#2565) * chore: Explicitly use `get_native_account_active_storage_slots_ptr` in `account::set_item` and `account::set_map_item` * chore: fix typos * feat: integrate PSM contracts to AuthMultisig (#2527) * chore: remove `ProvenTransactionBuilder` in favor of `ProvenTransaction::new` (#2567) * feat: implement `Ownable2Step` (#2292) * feat: implement two-step ownership management for account components - Add `ownable2step.masm` to provide two-step ownership functionality, requiring explicit acceptance of ownership transfers. - Create Rust module for `Ownable2Step` struct to manage ownership state and storage layout. - Introduce error handling for ownership operations in `standards.rs`. - Develop comprehensive tests for ownership transfer, acceptance, and renouncement scenarios in `ownable2step.rs`. * feat: add Ownable2Step account component for two-step ownership transfer * fix: correct ownership word layout and update transfer ownership logic in ownable2step * Refactor ownership management to use Ownable2Step pattern - Updated the access control mechanism to implement a two-step ownership transfer pattern in the ownable2step module. - Modified the storage layout to accommodate the new ownership structure, reversing the order of owner and nominated owner fields. - Refactored the network fungible faucet to utilize the new Ownable2Step for ownership management. - Adjusted related tests to validate the new ownership transfer logic and ensure correct behavior when transferring and accepting ownership. - Updated error handling to reflect changes in ownership management, including new error messages for ownership transfer scenarios. * refactor: update ownership word layout and adjust related logic in Ownable2Step * refactor: rename owner and nominated_owner to get_owner and get_nominated_owner for consistency * refactor: streamline ownership management in tests by utilizing Ownable2Step according to philip * fix: `make format` --------- Co-authored-by: Bobbin Threadbare <[email protected]> Co-authored-by: Philipp Gackstatter <[email protected]> * feat: prefix account components with miden::standards namespace (#2400) * refactor: rename output note structs (#2569) * feat: add `create_fungible_key` proc for fungible asset vault keys (#2575) * feat(asm): add create_fungible_key proc for fungible asset vault keys * chore: re-export create_fungible_key from `protocol::asset` * chore: add changelog --------- Co-authored-by: Philipp Gackstatter <[email protected]> * feat: migrate miden-agglayer to VM 0.21 and crypto 0.22 (#2546) * feat: migrate miden-agglayer to VM 0.21 and crypto 0.22 Re-enable the miden-agglayer crate in the workspace and apply all necessary API and convention changes from the VM 0.21 migration: Rust changes: - Remove FieldElement trait imports (removed from miden-core) - Felt::as_int() -> Felt::as_canonical_u64() - Program import moved to miden_core::program::Program - bytes_to_packed_u32_felts -> bytes_to_packed_u32_elements (miden_core::utils) - AccountId::try_from([Felt;2]) -> AccountId::try_from_elements(suffix, prefix) - Serializable/Deserializable from miden_assembly::serde (was ::utils) MASM changes: - rpo256 -> poseidon2 (hash function migration) - asset::mem_store/mem_load -> asset::store/load (procedure renames) - u64::overflowing_mul -> u64::widening_mul - u128_sub_no_underflow rewritten for LE convention (u64 procedures now use [lo, hi] input/output order) - verify_u128_to_native_amount_conversion updated for LE result order Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix: migrate agglayer tests and fix LE convention issues Re-enable agglayer tests in miden-testing and fix all compilation and runtime errors from the VM 0.21 migration: Test compilation fixes: - FieldElement import removal, as_int -> as_canonical_u64 - AuthScheme::Falcon512Rpo -> Falcon512Poseidon2 - AdviceInputs path: miden_processor::advice::AdviceInputs - FastProcessor::new_debug -> new().with_advice().with_debugging() - StackInputs::new(vec![]) -> new(&[]) - bytes_to_packed_u32_felts -> bytes_to_packed_u32_elements - AccountId::try_from -> try_from_elements MASM runtime fixes: - eth_address.masm: fix u32split LE output order in build_felt verification (movup.4 -> movup.3 for lo/hi comparison) - bridge_out.masm: fix create_burn_note note_idx corruption - loc_loadw_be overwrites top 4 stack elements including both copies from dup; save note_idx to local instead (pre-existing bug that only manifested with multiple output notes) - bridge_out.masm: fix num_leaves storage LE ordering - push new_leaf_count to stack top for Word[0] storage, use mem_storew_le instead of mem_storew_be for loading - bridge_config.masm: update GER hash from Rpo256 to Poseidon2 - canonical_zeros: remove .rev() from build.rs generation, swap push order for LE memory layout - Word element ordering fixes for bridge admin, GER manager, faucet registry keys, and conversion metadata Test expectation fixes: - Rpo256 -> Poseidon2 for GER hash computation - Removed word reversal in root/proof reading (LE convention) - Fixed expected storage value ordering - mem_storew_be -> mem_storew_le in test MASM code All 39 agglayer tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * style: apply rustfmt formatting Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * refactor: address PR review comments - Extract `create_id_key(id: AccountId) -> Word` helper and reuse for bridge_admin, ger_manager, bridge_account_id, and faucet_registry_key - Replace `felts_to_bytes` with re-export of `packed_u32_elements_to_bytes` from miden-core (identical implementation) - Remove stale comment in config_note.rs - Use `Felt::ONE` instead of `Felt::new(1)` in config_bridge test - Add TODO comments referencing issue #2548 for getter helpers - Simplify note_idx handling: use `padw` before `loc_loadw_le` instead of saving to a local variable; revert @Locals(15) to @Locals(14) - Switch `loc_storew_be`/`loc_loadw_be` to `_le` variants in create_burn_note - Add stack state comments before third overflowing_sub in u128_sub_no_underflow Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * chore: padding is 15 * remove utils re-export, faucet_registry_key * chore: drop 4 words * fix: pad before call invoc.; explicit stack comments * fix: unnecesary dup and incorrect movup * style: codify multi-element naming convention for MASM stack comments Add convention to masm_doc_comment_fmt.md: - `value` = single felt - `value(N)` = N felts (non-word) - `VALUE` = word (4 felts, no (4) suffix needed) Apply throughout agglayer MASM: drop redundant (4) from ASSET_KEY, ASSET_VALUE, SERIAL_NUM, SCRIPT_ROOT, RECIPIENT, NOTE_ATTACHMENT, PROC_MAST_ROOT, OLD_VALUE, VALUE, U256_LO, U256_HI. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * chore: update comments on poseidon inputs * Update crates/miden-protocol/masm_doc_comment_fmt.md Co-authored-by: Philipp Gackstatter <[email protected]> * chore: test for high x3 * fix: correctly rearrange lo/hi for sub * chore: more explicit sub comments * chore: revert changes to faucet config slot * chore: revert prefix<>suffix storage ordering * fix: store flag values at word[0] for LE convention Change GER_KNOWN_FLAG and IS_FAUCET_REGISTERED_FLAG to be stored at word[0] instead of word[3]. Under LE, `push.0.0.0.FLAG` puts FLAG at stack top = word[0], matching the documented layout [1, 0, 0, 0]. Previously `push.FLAG.0.0.0` placed FLAG at stack bottom = word[3], resulting in Word([0, 0, 0, 1]) which contradicted the docs. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * chore: use felts directly instead of extracting u64 * chore: fix build * Apply suggestion from @PhilippGackstatter Co-authored-by: Philipp Gackstatter <[email protected]> * chore: use AccountIdKey * refactor: push explicit zeros, dont assume padding is 0 * refactor: simplify assert_faucet_registered by asserting first * chore: re-add miden-agglayer to feature checks Now that miden-agglayer has been migrated, add it back to the check-features.sh loop. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * refactor: explicit pointers for storing prefix/suffix * refactor: swap to_account_id output to LE convention [suffix, prefix] All other bridge/faucet MASM procedures use [suffix, prefix] (suffix on top) for account IDs on the stack. Align to_account_id with this convention by adding a swap at the end, and update all callers: - faucet/mod.masm: update get_destination_account_id_data, claim, and build_p2id_output_note to handle the new stack order - solidity_miden_address_conversion test: swap stack index expectations Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> --------- Co-authored-by: Claude (Opus) <[email protected]> Co-authored-by: Bobbin Threadbare <[email protected]> Co-authored-by: Philipp Gackstatter <[email protected]> Co-authored-by: Bobbin Threadbare <[email protected]> * feat: make `Ownable2Step` an `AccountComponent` (#2572) * feat: add `from_parts_unchecked()` method for `InputNoteCommitment` (#2588) * feat: support bool types on schemas (#2591) * fix: move recompute logic to `OutputNoteBuilder::add_asset` to avoid repeated hashing (#2577) * fix: move recompute logic to OutputNoteBuilder::add_asset to avoid rehashing * changelog and lint * chore: add `NoteAssets::into_vec` --------- Co-authored-by: Bobbin Threadbare <[email protected]> Co-authored-by: Philipp Gackstatter <[email protected]> * feat: expose `AccountComponentMetadata` through public method (#2596) * fix: `TokenSymbol::try_from(Felt)` underflow (#2568) * feat: implement asset callback support in tx kernel (#2571) * feat: implement `on_before_asset_added_to_note` callback (#2595) * feat: add support for callbacks in non-fungible assets * chore: add test for block list note callback * feat: implement `on_before_asset_added_to_note` callback * chore: add test to make sure inputs are received correctly * chore: deduplicate test setup code * chore: add changelog * fix: non-fungible asset delta not including asset metadata * chore: deduplicate callback invocation procedures * chore: deduplicate blocked account test * chore: deduplicate note callback test * chore: test empty callback proc root slot * chore: Introduce `end_foreign_callback_context` * feat: validate asset metadata (#2609) * feat: flexible Minting Policies for Token Standards (#2559) * refactor: move storage schema component into a separate file (#2603) * feat: add `Package` support in `MockChainBuilder` & `NoteScript` (#2502) * feat: introduce `SwapNoteStorage` (#2592) * feat: add callback docs (#2604) * feat: add hooks to enable TX debugging (#2574) * Migrate to Miden VM `v0.22.0-alpha.1` (#2625) * refactor: update RandomCoin, use position of LeafIndex * chore: update deny file * chore: use version from crates.io, update deny file * fix: swap FAUCET_ID_SUFFIX/PREFIX constants in CONFIG_AGG_BRIDGE The constants FAUCET_ID_SUFFIX and FAUCET_ID_PREFIX were swapped relative to the actual storage layout in config_note.rs (suffix at index 5, prefix at index 6). This caused register_faucet to store with a mismatched key, so lookups returned empty. Also fix the misleading doc comment in config_note.rs. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * lint * fix: use Ownable2Step and OwnerControlled components for agglayer faucet The NetworkFungibleFaucet's mint_and_send now requires Ownable2Step for ownership verification and OwnerControlled for mint policy management. Migrate the agglayer faucet from a custom owner_config storage slot to these standard components: - Remove bridge_account_id from AggLayerFaucet (ownership is now handled by the Ownable2Step component) - Add Ownable2Step and OwnerControlled as companion components in the faucet account builder - Use Ownable2Step::try_from_storage to extract the owner in bridge_account_id() helper Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix: include Ownable2Step and OwnerControlled in faucet code commitment The build.rs computes the faucet code commitment for validation checks. After adding Ownable2Step and OwnerControlled as companion components, the code commitment must include their procedures. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix: use mem_storew_le for MINT note storage in bridge_in The MINT note script reads storage with mem_loadw_le (LE convention), so the bridge must store the P2ID script root, serial number, and attachment data using mem_storew_le to match. Using mem_storew_be caused the P2ID script root hash to be stored with reversed elements, making it unresolvable by the kernel. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * fix: bridge_in endianness + clippy warnings - Use mem_storew_le for MINT note storage in bridge_in.masm to match the MINT note script's mem_loadw_le reads (VM 0.21 byte-endianness). - Add MintNote::script() to bridge_in TX3 context. - Fix clippy useless_conversion warnings in bridge.rs. - Formatting fix in faucet.rs. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]> * feat: add `FixedWidthString<N>` utility (#2633) * Update crates/miden-agglayer/src/bridge.rs * chore: fix padding comments * chore: add owner controlled slot names to faucet --------- Co-authored-by: Philipp Gackstatter <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Bobbin Threadbare <[email protected]> Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: igamigo <[email protected]> Co-authored-by: Forostovec <[email protected]> Co-authored-by: Nikhil Patil <[email protected]> Co-authored-by: Bobbin Threadbare <[email protected]> Co-authored-by: Santiago Pittella <[email protected]> Co-authored-by: Serge Radinovich <[email protected]> Co-authored-by: Percy Dikec <[email protected]> Co-authored-by: onurinanc <[email protected]> Co-authored-by: Himess <[email protected]> Co-authored-by: Arthur Abeilice <[email protected]> Co-authored-by: Poulav <[email protected]> Co-authored-by: juan518munoz <[email protected]> Co-authored-by: Tomas Fabrizio Orsi <[email protected]> Co-authored-by: djole <[email protected]> Co-authored-by: Andrey Khmuro <[email protected]>
Implements the
on_before_asset_added_to_accountcallback in the tx kernel.The PR is deliberately "minimal" and does not:
on_before_asset_added_to_notecallback.Both of these will be done in a separate PR based on feedback to this PR.
Design Decisions
Allow missing callback slots
Since the callback flag is part of the asset key, the callback flag must be set whenever an asset is created, e.g. in
miden::protocol::asset::create_fungible_asset. So, this and similar procedures now takeenable_callbacksas an input.To avoid parameterizing implementations like
miden::standards::faucets::distributeover this flag, a helper is added that checks whether the active account defines any callbacks:miden::protocol::active_account::has_callbacks. This procedure is called in distribute and passes the returned flag on to the to-be-minted asset.Decisions
has_callbacksreturns 1 if the slot exists and contains a non-empty word, 0 otherwise. This is to avoid having to add the callback slots to all faucet accounts (and in the future all accounts).miden::protocol.The 2nd decision was made by considering the following (post-mainnet) scenario:
has_callbacksis a library-only implementation.BasicFungibleFaucetuses the flag returned by this procedure to create it assets.has_callbackscannot be updated, it is deprecated and ahas_callbacks_v2is added that implements the existence check for the new callback.BasicFungibleFaucetcode still uses the MAST root of the originalhas_callbacksprocedure and now consequently determines that it does not have callbacks, even though the new one is actually used.When the
has_callbacksproc is implemented in the kernel, due to dynamic invocation, it can be upgraded to take into account newly added callbacks without breaking MAST roots.In theory I would prefer the library-only implementation, but I'm not sure how to properly address such issues otherwise.
Worth noting: A similar problem exists for
miden::standards::auth::signature::verify_signature_by_scheme- adding new schemes in the future will change the MAST root and we can't apply the kernel procedure workaround there.Multiple Procedures Per Callback
This PR assumes the need to assign multiple procedures to the same callback is unlikely to come up. If it would come up anyway, account components would have to manually merge multiple procedures into a single one and then provide that one as the callback procedure.
The approach here is that account components that implement callbacks need to add the callback storage slot themselves, with the help of
AssetCallbacks.Callback Inputs
on_before_asset_added_to_accountdoes not pass the native account ID to the callback to keep the signature simpler. It is easy to retrieve the ID withnative_account::get_id. The main idea is:Applying this consistency rule from the account to the note callback would mean that the note callback would become a bit messy if it were to provide
[note_idx, native_account_id_suffix, native_account_id_prefix, ASSET_KEY, ASSET_VALUE], and so it makes sense to me to not pass the native ID to any of them.Callback Security
I'm also wondering about the security of callback procedures in an account's public interface. If the callback is a public part of the interface, it can be called by anyone. But if it turns out that callbacks will be able to mint assets, then this could probably be exploited:
ASSET_VALUEof the faucet's asset and invoke the callback from a tx script.PROCESSED_ASSET_VALUE.PROCESSED_ASSET_VALUE - ASSET_VALUEis a valid asset that can be sent to some other account.Mitigations
authenticate_account_origin, if the called procedure is a callback, check whether the kernel is in a "callback context". Not yet sure if this protects against all possible ways this could be called.FungibleAssetDelta
The
FungibleAssetDeltaneeded an update since the (Rust) delta only included the faucet ID, but the callback flag also needs to be included to differentiate assets with and without callbacks. This means including the faucet ID and the asset metadata (= currently callback flag).This will become much nicer when we generalize the asset delta, so I did not spend time on optimizing the code in that type.