From a4fbf6a18c1b1c0730e80edbe62b9195d673c7db Mon Sep 17 00:00:00 2001 From: Marti Date: Wed, 8 Apr 2026 13:13:43 +0000 Subject: [PATCH 1/3] chore: read token add and network in one go --- .../asm/agglayer/faucet/mod.masm | 51 +++++-------------- crates/miden-agglayer/src/faucet.rs | 14 ++--- 2 files changed, 21 insertions(+), 44 deletions(-) diff --git a/crates/miden-agglayer/asm/agglayer/faucet/mod.masm b/crates/miden-agglayer/asm/agglayer/faucet/mod.masm index 408c0e93e1..f442a646e6 100644 --- a/crates/miden-agglayer/asm/agglayer/faucet/mod.masm +++ b/crates/miden-agglayer/asm/agglayer/faucet/mod.masm @@ -1,5 +1,4 @@ use miden::core::sys -use agglayer::common::utils use agglayer::common::asset_conversion use miden::protocol::active_account @@ -20,42 +19,27 @@ const METADATA_HASH_HI_SLOT = word("agglayer::faucet::metadata_hash_hi") # PUBLIC INTERFACE # ================================================================================================= -#! Returns the origin token address (5 felts) from faucet conversion storage. +#! Returns the origin token address (5 felts) and origin network identifier from faucet conversion +#! storage. #! -#! Reads conversion_info_1 (first 4 felts of address) and conversion_info_2 (5th felt) from storage. +#! Reads conversion_info_1 (first 4 felts of address) and conversion_info_2 (5th felt + origin +#! network) from storage in a single pass. #! #! Inputs: [] -#! Outputs: [addr0, addr1, addr2, addr3, addr4] +#! Outputs: [addr0, addr1, addr2, addr3, addr4, origin_network] #! #! Invocation: exec -pub proc get_origin_token_address +proc get_origin_token_address_and_network push.CONVERSION_INFO_1_SLOT[0..2] exec.active_account::get_item # => [addr0, addr1, addr2, addr3] - # Read slot 2: [addr4, origin_network, scale, 0] push.CONVERSION_INFO_2_SLOT[0..2] exec.active_account::get_item # => [addr4, origin_network, scale, 0, addr0, addr1, addr2, addr3] - # Keep only addr4, drop origin_network, scale, 0 - movdn.7 drop drop drop - # => [addr0, addr1, addr2, addr3, addr4] -end - -#! Returns the origin network identifier from faucet conversion storage. -#! -#! Inputs: [] -#! Outputs: [origin_network] -#! -#! Invocation: exec -pub proc get_origin_network - push.CONVERSION_INFO_2_SLOT[0..2] - exec.active_account::get_item - # => [addr4, origin_network, scale, 0] - - drop movdn.2 drop drop - # => [origin_network] + movdn.7 movdn.7 drop drop + # => [addr0, addr1, addr2, addr3, addr4, origin_network] end #! Returns the scale factor from faucet conversion storage. @@ -145,21 +129,12 @@ pub proc asset_to_origin_asset exec.asset_conversion::reverse_limbs_and_change_byte_endianness # => [U256_LO, U256_HI, pad(15)] - # Step 3: Get origin token address - exec.get_origin_token_address - # => [addr0, addr1, addr2, addr3, addr4, U256_LO, U256_HI, pad(15)] - - # Move address below the U256 amount - repeat.5 movdn.12 end - # => [U256_LO, U256_HI, addr0, addr1, addr2, addr3, addr4, pad(15)] - - # Step 4: Get origin network - exec.get_origin_network - exec.utils::swap_u32_bytes - # => [origin_network, U256_LO, U256_HI, addr0..addr4, pad(15)] + # Step 3: Get origin token address and network + exec.get_origin_token_address_and_network + # => [addr0, addr1, addr2, addr3, addr4, origin_network, U256_LO, U256_HI, pad(15)] - # Move origin_network after the address fields - movdn.13 + # Move address + network below the U256 amount + repeat.6 movdn.13 end # => [U256_LO, U256_HI, addr0, addr1, addr2, addr3, addr4, origin_network, pad(15)] exec.sys::truncate_stack diff --git a/crates/miden-agglayer/src/faucet.rs b/crates/miden-agglayer/src/faucet.rs index 306a8acc99..0432ea58d0 100644 --- a/crates/miden-agglayer/src/faucet.rs +++ b/crates/miden-agglayer/src/faucet.rs @@ -3,6 +3,7 @@ extern crate alloc; use alloc::vec; use alloc::vec::Vec; +use miden_core::utils::bytes_to_packed_u32_elements; use miden_core::{Felt, Word}; use miden_protocol::account::component::AccountComponentMetadata; use miden_protocol::account::{ @@ -264,10 +265,9 @@ impl AggLayerFaucet { .get_item(&CONVERSION_INFO_2_SLOT_NAME) .expect("should be able to read the second conversion info slot"); - Ok(conversion_info_2[1] - .as_canonical_u64() - .try_into() - .expect("origin network ID should fit into u32")) + let le_packed = u32::try_from(conversion_info_2[1].as_canonical_u64()) + .expect("origin network ID should fit into u32"); + Ok(u32::from_be_bytes(le_packed.to_le_bytes())) } /// Extracts the scaling factor in form of the u8 from the corresponding storage slot of the @@ -436,7 +436,7 @@ pub enum AgglayerFaucetError { /// - Slot 1 (`agglayer::faucet::conversion_info_1`): `[addr0, addr1, addr2, addr3]` — first 4 felts /// of the origin token address (5 × u32 limbs). /// - Slot 2 (`agglayer::faucet::conversion_info_2`): `[addr4, origin_network, scale, 0]` — -/// remaining address felt + origin network + scale factor. +/// remaining address felt + origin network (LE-packed) + scale factor. /// /// # Parameters /// - `origin_token_address`: The EVM token address in Ethereum format @@ -454,8 +454,10 @@ fn agglayer_faucet_conversion_slots( let slot1 = Word::new([addr_elements[0], addr_elements[1], addr_elements[2], addr_elements[3]]); + let origin_network_packed = bytes_to_packed_u32_elements(&origin_network.to_be_bytes()); + assert_eq!(origin_network_packed.len(), 1, "origin_network should pack into exactly one Felt"); let slot2 = - Word::new([addr_elements[4], Felt::from(origin_network), Felt::from(scale), Felt::ZERO]); + Word::new([addr_elements[4], origin_network_packed[0], Felt::from(scale), Felt::ZERO]); (slot1, slot2) } From 9d3cf8d03cdd26cd12ee67791de06bcd8a5fa183 Mon Sep 17 00:00:00 2001 From: Marti Date: Wed, 8 Apr 2026 13:20:48 +0000 Subject: [PATCH 2/3] chore: lint --- crates/miden-agglayer/src/faucet.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/miden-agglayer/src/faucet.rs b/crates/miden-agglayer/src/faucet.rs index 0432ea58d0..16f09b3a1b 100644 --- a/crates/miden-agglayer/src/faucet.rs +++ b/crates/miden-agglayer/src/faucet.rs @@ -455,7 +455,11 @@ fn agglayer_faucet_conversion_slots( let slot1 = Word::new([addr_elements[0], addr_elements[1], addr_elements[2], addr_elements[3]]); let origin_network_packed = bytes_to_packed_u32_elements(&origin_network.to_be_bytes()); - assert_eq!(origin_network_packed.len(), 1, "origin_network should pack into exactly one Felt"); + assert_eq!( + origin_network_packed.len(), + 1, + "origin_network should pack into exactly one Felt" + ); let slot2 = Word::new([addr_elements[4], origin_network_packed[0], Felt::from(scale), Felt::ZERO]); From 8b11252c1ed258616f8ad3dd5a73fafe7f725b53 Mon Sep 17 00:00:00 2001 From: Marti Date: Wed, 8 Apr 2026 13:21:45 +0000 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d6c7bf585..c6bbf6925d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Added shared `ProcedurePolicy` for AuthMultisig ([#2670](https://github.com/0xMiden/protocol/pull/2670)). - [BREAKING] Changed `NoteType` encoding from 2 bits to 1 and makes `NoteType::Private` the default ([#2691](https://github.com/0xMiden/miden-base/issues/2691)). - Added `BlockNumber::saturating_sub()` ([#2660](https://github.com/0xMiden/protocol/issues/2660)). +- [BREAKING] Stored `origin_network` in LE-packed format in AggLayer faucet storage ([#2745](https://github.com/0xMiden/protocol/pull/2745)). ## 0.14.3 (2026-04-07)