Skip to content

Commit 006fcbd

Browse files
Fumuranbobbinth
andauthored
Fix note script compilation: use libraries instead of programs (#2822)
* refactor: make all notes be libs, update CodeBuilder::compile_note_script * refactor: compile and store note script libs instead of scripts themselves * chore: fix comment format * chore: increment crate versions to v0.14.5 --------- Co-authored-by: Bobbin Threadbare <bobbinth@protonmail.com>
1 parent 1c99e41 commit 006fcbd

29 files changed

Lines changed: 170 additions & 120 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.14.5 (2026-04-23)
4+
5+
- Fixed note script compilation: all note scripts are now compiled as libraries ([#2822](https://github.com/0xMiden/protocol/pull/2822)).
6+
37
## 0.14.4 (2026-04-09)
48

59
- Fixed AggLayer `write_mint_note_storage` stack padding before loading the mint serial number ([#2749](https://github.com/0xMiden/protocol/pull/2749)).

Cargo.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ homepage = "https://miden.xyz"
2121
license = "MIT"
2222
repository = "https://github.com/0xMiden/protocol"
2323
rust-version = "1.90"
24-
version = "0.14.4"
24+
version = "0.14.5"
2525

2626
[profile.release]
2727
codegen-units = 1

bin/bench-note-checker/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub fn setup_mixed_notes_benchmark(config: MixedNotesConfig) -> anyhow::Result<M
8585
seed[0] = i as u8;
8686
let mut rng = RandomCoin::new([i as u32, 0, 0, 0].into());
8787
let failing_note = NoteBuilder::new(sender, &mut rng)
88-
.code("begin push.0 div end") // Division by zero - will fail.
88+
.code("@note_script pub proc main push.0 div end") // Division by zero - will fail.
8989
.build()?;
9090
failing_notes.push(failing_note);
9191
}

crates/miden-agglayer/SPEC.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ Keccak preimage format directly — the felt value does **not** equal the numeri
402402
| Field | Value |
403403
|-------|-------|
404404
| `serial_num` | Random (`rng.draw_word()`) |
405-
| `script` | `B2AGG.masb` |
405+
| `script` | `B2AGG.masl` |
406406
| `storage` | 6 felts -- see layout below |
407407

408408
**Storage layout (6 felts):**
@@ -461,7 +461,7 @@ token registry, and creates a MINT note targeting the faucet.
461461
| Field | Value |
462462
|-------|-------|
463463
| `serial_num` | Random (`rng.draw_word()`) |
464-
| `script` | `CLAIM.masb` |
464+
| `script` | `CLAIM.masl` |
465465
| `storage` | 569 felts -- see layout below |
466466

467467
**Storage layout (569 felts):**
@@ -530,7 +530,7 @@ The storage is divided into three logical regions: proof data (felts 0-535), lea
530530
| Field | Value |
531531
|-------|-------|
532532
| `serial_num` | Random (`rng.draw_word()`) |
533-
| `script` | `CONFIG_AGG_BRIDGE.masb` |
533+
| `script` | `CONFIG_AGG_BRIDGE.masl` |
534534
| `storage` | 7 felts -- see layout below |
535535

536536
**Storage layout (7 felts):**
@@ -577,7 +577,7 @@ CLAIM notes can be verified against it.
577577
| Field | Value |
578578
|-------|-------|
579579
| `serial_num` | Random (`rng.draw_word()`) |
580-
| `script` | `UPDATE_GER.masb` |
580+
| `script` | `UPDATE_GER.masl` |
581581
| `storage` | 8 felts -- see layout below |
582582

583583
**Storage layout (8 felts):**

crates/miden-agglayer/asm/note_scripts/B2AGG.masm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ const ERR_B2AGG_TARGET_ACCOUNT_MISMATCH="B2AGG note attachment target account do
5050
#! - The note does not contain exactly 6 storage items.
5151
#! - The note does not contain exactly 1 asset.
5252
#! - The note attachment does not target the consuming account.
53-
begin
53+
@note_script
54+
pub proc main
5455
dropw
5556
# => [pad(16)]
5657

crates/miden-agglayer/asm/note_scripts/CLAIM.masm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ const ERR_CLAIM_TARGET_ACCT_MISMATCH = "CLAIM note attachment target account doe
7575
#! Panics if:
7676
#! - account does not expose claim procedure.
7777
#! - note attachment target account does not match the consuming account.
78-
begin
78+
@note_script
79+
pub proc main
7980
dropw
8081
# => [pad(16)]
8182

crates/miden-agglayer/asm/note_scripts/CONFIG_AGG_BRIDGE.masm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ const ERR_CONFIG_AGG_BRIDGE_TARGET_ACCOUNT_MISMATCH = "CONFIG_AGG_BRIDGE note at
4747
#! - The note attachment target account does not match the consuming bridge account.
4848
#! - The note does not contain exactly 7 storage items.
4949
#! - The account does not expose the register_faucet procedure.
50-
begin
50+
@note_script
51+
pub proc main
5152
dropw
5253
# => [pad(16)]
5354

crates/miden-agglayer/asm/note_scripts/UPDATE_GER.masm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ const ERR_UPDATE_GER_TARGET_ACCOUNT_MISMATCH = "UPDATE_GER note attachment targe
3939
#! - account does not expose update_ger procedure.
4040
#! - target account ID does not match the consuming account ID.
4141
#! - number of note storage items is not exactly 8.
42-
begin
42+
@note_script
43+
pub proc main
4344
dropw
4445
# => [pad(16)]
4546

crates/miden-agglayer/build.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use std::sync::Arc;
55

66
use fs_err as fs;
77
use miden_assembly::diagnostics::{IntoDiagnostic, NamedSource, Result, WrapErr};
8-
use miden_assembly::serde::Serializable;
98
use miden_assembly::{Assembler, Library, Report};
109
use miden_crypto::hash::keccak::{Keccak256, Keccak256Digest};
1110
use miden_protocol::account::{
@@ -43,7 +42,7 @@ const AGGLAYER_GLOBAL_CONSTANTS_FILE_NAME: &str = "agglayer_constants.rs";
4342
/// Read and parse the contents from `./asm`.
4443
/// - Compiles the contents of asm/agglayer directory into a single agglayer.masl library.
4544
/// - Compiles the contents of asm/components directory into individual per-component .masl files.
46-
/// - Compiles the contents of asm/note_scripts directory into individual .masb files.
45+
/// - Compiles the contents of asm/note_scripts directory into individual `.masl` libraries.
4746
fn main() -> Result<()> {
4847
// re-build when the MASM code changes
4948
println!("cargo::rerun-if-changed={ASM_DIR}/");
@@ -124,39 +123,38 @@ fn compile_agglayer_lib(
124123
// COMPILE EXECUTABLE MODULES
125124
// ================================================================================================
126125

127-
/// Reads all MASM files from the "{source_dir}", complies each file individually into a MASB
128-
/// file, and stores the compiled files into the "{target_dir}".
129-
///
130-
/// The source files are expected to contain executable programs.
126+
/// Reads all MASM files from `{source_dir}`, compiles each file as a note script library with
127+
/// [`Assembler::assemble_library`], and writes the serialized library as `.masl` via
128+
/// [`Library::write_to_file`].
131129
fn compile_note_scripts(
132130
source_dir: &Path,
133-
target_dir: &Path,
131+
note_scripts_target_dir: &Path,
134132
mut assembler: Assembler,
135133
) -> Result<()> {
136-
fs::create_dir_all(target_dir)
134+
fs::create_dir_all(note_scripts_target_dir)
137135
.into_diagnostic()
138136
.wrap_err("failed to create note_scripts directory")?;
139137

140138
// Add the miden-standards library to the assembler so note scripts can use it
141139
let standards_lib = miden_standards::StandardsLib::default();
142140
assembler.link_static_library(standards_lib)?;
143141

144-
for masm_file_path in shared::get_masm_files(source_dir).unwrap() {
145-
// read the MASM file, parse it, and serialize the parsed AST to bytes
146-
let code = assembler.clone().assemble_program(masm_file_path.clone())?;
147-
148-
let bytes = code.to_bytes();
142+
for note_file_path in shared::get_masm_files(source_dir).unwrap() {
143+
// compile the note script library from the provided MASM file
144+
let note_library = assembler.clone().assemble_library([note_file_path.clone()])?;
149145

150-
let masm_file_name = masm_file_path
146+
let note_file_name = note_file_path
151147
.file_name()
152148
.expect("file name should exist")
153149
.to_str()
154150
.ok_or_else(|| Report::msg("failed to convert file name to &str"))?;
155-
let mut masb_file_path = target_dir.join(masm_file_name);
151+
let mut masl_file_path = note_scripts_target_dir.join(note_file_name);
152+
masl_file_path.set_extension(Library::LIBRARY_EXTENSION);
156153

157-
// write the binary MASB to the output dir
158-
masb_file_path.set_extension("masb");
159-
fs::write(masb_file_path, bytes).unwrap();
154+
// write the note script library to the output dir
155+
note_library
156+
.write_to_file(&masl_file_path)
157+
.map_err(|e| Report::msg(format!("{e:#}")))?;
160158
}
161159
Ok(())
162160
}

0 commit comments

Comments
 (0)