0xMiden / 0xMiden/miden-vm

Wrong masm file shown on certain kinds of errors (missing import, possibly other)

Đang mở
#2,762 3 bình luận 1 reaction 1 người được giao Được @bitwalker nhận Xem trên GitHub
assembly
Ngôn ngữ chính
Rust
Star
772
Fork
352
Merge trung bình
1 ngày 7 giờ
Pull request đã merge (30 ngày)
84

Mô tả

### Packages versions

miden-assembly: 0.20.6

### Bug description

Issue: When compiling library code with missing imports, MASM file name and contents will be replaced with `account_id.masm` and it's contents respectively.

Example: Code missing `miden::protocol::active_account` import while calling `exec.active_account::get_item` will yield:
```
Error: Failed to compile lp_local library: x undefined symbol reference
,-[/Users/mieszkomanijak/Documents/repos/miden/c-prod_pools/target/release/build/miden-protocol-f93a66620a2cffdd/out/asm/shared_modules/account_id.masm:68:11]
67 | #! Inputs: [acct_id_prefix]
68 | #! Outputs: [is_non_fungible_faucet]
: ^^^^^^^^^^^^|^^^^^^^^^^^
: `-- this symbol path could not be resolved
69 | #!
`----
help: maybe you are missing an import?
```

### How can this be reproduced?

Offending code from `asm/accounts/lp_local.masm` trying to call `exec.active_account::get_item` in l 88

```
use miden::core::math::u64
use miden::protocol::native_account
#use miden::protocol::active_account
use miden::core::sys

use zoro::math
use zoro::storage_utils

const MINIMUM_LIQUIDITY = 100

### MEMORY LOCATIONS
const DYNAMIC_PROC_ADDR = 4

const USER_ACCOUNT_ID_WORD = 20
const USER_ACCOUNT_ID_PREFIX = 20
const USER_ACCOUNT_ID_SUFFIX = 21

### ERROR CODES
const ERR_ZERO_ADDRESS = "Zero address"

### STORAGE SLOTS
const USER_DEPOSITS_MAPPING_SLOT = word("zoro::lp_local::user_deposits_mapping")
const RESERVE_SLOT = word("zoro::lp_local::reserve")
const TOTAL_SUPPLY_SLOT = word("zoro::lp_local::total_supply")
#################
#! Computes the LP amount out for a deposit of amount_0 and amount_1.
#! For initial deposit (the total supply is 0), it subracts the minimum liquidity.
#! Inputs: [total_supply, amount_0, amount_1, reserve_0, reserve_1]
#! Outputs: [lp_amount_out]
@locals(5)
pub proc get_lp_amount_out(total_supply: felt, amount_0: felt, amount_1: felt, reserve_0: felt, reserve_1: felt) -> felt
# loc.0: total_supply
# loc.1: amount_0
# loc.2: amount_1
# loc.3: reserve_0
# loc.4: reserve_1
loc_store.0 loc_store.1 loc_store.2 loc_store.3 loc_store.4
# => []
### if total_supply == 0
loc_load.0 eq.0
if.true
### initial deposit: - MINIMUM_LIQUIDITY
loc_load.1 loc_load.2 mul exec.math::sqrt
# => [lp_amount]
push.MINIMUM_LIQUIDITY exec.math::safe_sub
# => [lp_amount_out]
### return lp_amount_out
else
### subsequent deposits: min(lp_amount_0, lp_amount_1)
### lp_amount_0 = amount_0 * total_supply / reserve_0
loc_load.1 u32split loc_load.0 u32split exec.u64::wrapping_mul loc_load.3 u32split exec.u64::div
# => [lp_amount_0_high, lp_amount_0_low]
loc_load.2 u32split loc_load.0 u32split exec.u64::wrapping_mul loc_load.4 u32split exec.u64::div
# => [lp_amount_1_high, lp_amount_1_low, lp_amount_0_high, lp_amount_0_low]
exec.u64::min
# => [lp_amount_out_high, lp_amount_out_low]
exec.math::safe_cast_u64_into_felt
# => [lp_amount_out]
### return lp_amount_out
end

exec.sys::truncate_stack
end

proc assert_non_zero_address#(suffix: felt, prefix: felt)
neq.0 swap.1 neq.0
# => [is_suffix_non_zero, is_prefix_non_zero]
or assert.err=ERR_ZERO_ADDRESS
end
proc get_current_user_deposit_key#() -> Word
mem_load.USER_ACCOUNT_ID_SUFFIX mem_load.USER_ACCOUNT_ID_PREFIX
exec.assert_non_zero_address
mem_load.USER_ACCOUNT_ID_SUFFIX mem_load.USER_ACCOUNT_ID_PREFIX
# => [USER_DEPOSIT_KEY]
exec.get_user_deposit_key
exec.sys::truncate_stack
end

proc get_user_deposit_key#(prefix: felt, suffix: felt) -> Word
push.0.0 movup.3 movup.2
# => [prefix, suffix, 0 , 0 ] == [KEY]
end

pub proc total_supply#() -> felt
push.TOTAL_SUPPLY_SLOT[0..2] exec.active_account::get_item
end

pub proc get_reserve#() -> (felt, felt)
push.RESERVE_SLOT[0..2] exec.active_account::get_item
end

proc set_reserve#(reserve_0: felt, reserve_1: felt)
### amount validation vs vault
push.RESERVE_SLOT[0..2] exec.native_account::set_item
dropw
end

@locals(2)
proc add_to_reserve#(amount_0: felt, amount_1: felt)
# loc.0: amount_0
# loc.1: amount_1
loc_store.0 loc_store.1
# => []
exec.get_reserve
# => [reserve_0, reserve_1]
loc_load.0 exec.math::safe_add
# => [new_reserve_0, reserve_1]
swap
loc_load.1 exec.math::safe_add
# => [new_reserve_1, new_reserve_0]
swap
# => [new_reserve_0, new_reserve_1]
exec.set_reserve
end

@locals(2)
proc sub_from_reserve#(amount_0: felt, amount_1: felt)
# loc.0: amount_0
# loc.1: amount_1
loc_store.0 loc_store.1
# => []
exec.get_reserve
# => [reserve_0, reserve_1]
loc_load.0 exec.math::safe_sub
# => [new_reserve_0, reserve_1]
swap
loc_load.1 exec.math::safe_sub
# => [new_reserve_1, new_reserve_0]
swap
# => [new_reserve_0, new_reserve_1]
exec.set_reserve
end

@locals(3)
proc mint#(amount: felt, beneficiary_prefix: felt, beneficiary_suffix: felt)
# loc.0: amount
# loc.1: beneficiary_prefix
# loc.2: beneficiary_suffix
loc_store.0 loc_store.1 loc_store.2
# => []
### add to mapping USER_DEPOSITS_MAPPING_SLOT
loc_load.0
loc_load.2 loc_load.1 exec.get_user_deposit_key
# => [USER_DEPOSIT_KEY, amount]
push.USER_DEPOSITS_MAPPING_SLOT[0..2]
# => [slot_id_prefix, slot_id_suffix, USER_DEPOSIT_KEY, amount]
exec.storage_utils::add_to_map_item
drop
### updating total supply
loc_load.0 push.TOTAL_SUPPLY_SLOT[0..2] exec.storage_utils::add_to_storage_item
drop
end

#! add new deposit: receive asset, update deposit mapping
#!
#! Inputs: [ASSET0, ASSET1, user_id_prefix, user_id_suffix]
#! Outputs: [share_amount_out]
#!
@locals(9)
pub proc deposit
# loc.0: ASSET0
# loc.4: ASSET1
# loc.5: lp_amount_out
loc_storew_be.0 dropw loc_storew_be.4 dropw mem_store.USER_ACCOUNT_ID_PREFIX mem_store.USER_ACCOUNT_ID_SUFFIX

### get_lp_amount_out (total_supply: felt, amount_0: felt, amount_1: felt, reserve_0: felt, reserve_1: felt)
exec.get_reserve
# => [reserve_0, reserve_1]
loc_load.7 loc_load.3
# => [amount_0, amount_1, reserve_0, reserve_1]
exec.total_supply
# => [total_supply, amount_0, amount_1, reserve_0, reserve_1]

exec.get_lp_amount_out
# => [lp_amount_out]
loc_store.5
### check if initial deposit
exec.total_supply eq.0
if.true
### burn minimum liquidity
push.0.0 push.MINIMUM_LIQUIDITY
exec.mint
end

### mint to user
loc_load.5
mem_load.USER_ACCOUNT_ID_SUFFIX mem_load.USER_ACCOUNT_ID_PREFIX
# => [user_id_prefix, user_id_suffix, lp_amount_out]
exec.mint

### receive assets
### reserve needs to be updated
#padw padw padw loc_loadw_be.0 exec.receive_asset
#padw padw padw loc_loadw_be.4 exec.receive_asset
padw loc_loadw_be.0 exec.native_account::add_asset dropw
padw loc_loadw_be.4 exec.native_account::add_asset dropw
## make sure asset order correct
loc_load.7 loc_load.3
# => [amount_0, amount_1]
exec.add_to_reserve

end
```
Compiled with
```
pub fn get_lp_local_library() -> Result {
let math_library = get_math_library()?;
let storage_utils_library = get_storage_utils_library()?;
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let path: PathBuf = [manifest_dir, "asm", "accounts", "lp_local.masm"]
.iter()
.collect();
let source = fs::read_to_string(&path)?;
let assembler = TransactionKernel::assembler()
.with_warnings_as_errors(true)
.with_static_library(math_library)
.map_err(|e| anyhow!("Failed to add math library to assembler: {e:?}"))?
.with_static_library(storage_utils_library)
.map_err(|e| anyhow!("Failed to add storage_utils library to assembler: {e:?}"))?;
create_library(assembler, "zoro::lp_local", &source)
.map_err(|e| anyhow!("Failed to compile lp_local library: {e:?}"))
}

pub fn get_math_library() -> Result {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let path: PathBuf = [manifest_dir, "asm", "accounts", "math.masm"]
.iter()
.collect();
let source = fs::read_to_string(&path)?;
let assembler = TransactionKernel::assembler().with_warnings_as_errors(true);
create_library(assembler, "zoro::math", &source)
.map_err(|e| anyhow!("Failed to compile math library: {e:?}"))
}

pub fn get_storage_utils_library() -> Result {
let math_library = get_math_library()?;
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let path: PathBuf = [manifest_dir, "asm", "accounts", "storage_utils.masm"]
.iter()
.collect();
let source = fs::read_to_string(&path)?;
let assembler = TransactionKernel::assembler()
.with_warnings_as_errors(true)
.with_static_library(math_library)
.unwrap_or_else(|e| panic!("Failed to add math library to assembler: {e:?}"));
create_library(assembler, "zoro::storage_utils", &source)
.map_err(|e| anyhow!("Failed to compile storage_utils library: {e:?}"))
}

pub fn create_library(
assembler: Assembler,
library_path: &str,
source_code: &str,
) -> Result> {
let source_manager = Arc::new(DefaultSourceManager::default());
// println!("parsing library: {:?}", library_path);
let module = Module::parser(ModuleKind::Library).parse_str(
AssemblyPath::new(library_path),
source_code,
source_manager.clone(),
)?;
// println!("Module: {:?}", module);
let library = assembler.clone().assemble_library([module])?;
Ok(library)
}

```

### Relevant log output

```shell
Error: Failed to compile lp_local library: x undefined symbol reference
,-[/Users/mieszkomanijak/Documents/repos/miden/c-prod_pools/target/release/build/miden-protocol-f93a66620a2cffdd/out/asm/shared_modules/account_id.masm:68:11]
67 | #! Inputs: [acct_id_prefix]
68 | #! Outputs: [is_non_fungible_faucet]
: ^^^^^^^^^^^^|^^^^^^^^^^^
: `-- this symbol path could not be resolved
69 | #!
`----
help: maybe you are missing an import?
```

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Lỗi xảy ra trong assembler khi một import bị thiếu khiến tệp không đúng được hiển thị trong thông báo lỗi. Hãy xem mã báo cáo lỗi trong mô-đun assembler, nhiều khả năng nằm trong crate miden-assembly. Tìm nơi tên tệp được phân giải và thay thế. Trường hợp kiểm thử nằm trong phần nội dung của issue: biên dịch một thư viện có import bị thiếu (chẳng hạn active_account) và xem đường dẫn lỗi được tạo ra như thế nào. Bản sửa lỗi phải bảo đảm tên tệp nguồn chính xác được hiển thị.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
rust
Lĩnh vực
compilers
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.