Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
- 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)).
- Added `TransactionScript::from_package()` method to create `TransactionScript` from `miden-mast-package::Package` ([#2779](https://github.com/0xMiden/protocol/pull/2779)).


## 0.14.3 (2026-04-07)

Expand Down
4 changes: 4 additions & 0 deletions crates/miden-protocol/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,10 @@ impl PartialBlockchainError {
pub enum TransactionScriptError {
#[error("failed to assemble transaction script:\n{}", PrintDiagnostic::new(.0))]
AssemblyError(Report),
#[error("failed to convert package to transaction script:\n{}", PrintDiagnostic::new(.0))]
PackageNotProgram(Report),
#[error("failed to convert package to transaction script:\n{}", PrintDiagnostic::new(.0))]
PackageNotTransactionScript(Report),
}

// TRANSACTION INPUT ERROR
Expand Down
26 changes: 26 additions & 0 deletions crates/miden-protocol/src/transaction/tx_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ use alloc::collections::BTreeMap;
use alloc::sync::Arc;
use alloc::vec::Vec;

use miden_assembly::Report;
use miden_core::mast::MastNodeExt;
use miden_crypto::merkle::InnerNodeInfo;
use miden_mast_package::{Package, TargetType};

use super::{Felt, Hasher, Word};
use crate::account::auth::{PublicKeyCommitment, Signature};
use crate::errors::TransactionScriptError;
use crate::note::{NoteId, NoteRecipient};
use crate::utils::serde::{
ByteReader,
Expand Down Expand Up @@ -308,6 +311,29 @@ impl TransactionScript {
Self { mast, entrypoint }
}

/// Creates a [TransactionScript] from a [`Package`].
///
/// The package must be an executable (i.e., its target type must be
/// [`TargetType::TransactionScript`](miden_mast_package::TargetType::TransactionScript)).
///
/// # Errors
/// Returns an error if the package cannot be converted to an executable program.
pub fn from_package(package: &Package) -> Result<Self, TransactionScriptError> {
Comment thread
bobbinth marked this conversation as resolved.
let package_kind = package.kind;
if !matches!(package_kind, TargetType::TransactionScript) {
let err_report = Report::msg(format!(
"package's kind is {}, expected TransactionScript",
package_kind
));
return Err(TransactionScriptError::PackageNotTransactionScript(err_report));
};

let program =
package.try_into_program().map_err(TransactionScriptError::PackageNotProgram)?;
Comment on lines +323 to +332
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this will currently fail because Package::try_into_program() will return an error if package_kind is not TargetType::Executable.

This brings up a question of how can we identify the program entrypoint for TransactionScript packages. For notes, we have the @note_script attribute. Should we add something similar for transaction scripts? cc @bitwalker and @greenhat

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we not use TargetType::TransactionScript here?
(...)
I believe this will currently fail because Package::try_into_program() will return an error if package_kind is not TargetType::Executable.

For context, I originally went with try_into_program directly because, while working on 0xMiden/faucet#204, the Package containing the compiled TransactionScript had Executable as its kind and not TransactionScript (the project was compiled with cargo-miden 0.8.0).

If I'm not mistaken, this behavior changed inside the compiler. Until version 0.8.0 (the one we were using), Packages were tagged as either Executable or Library (I believe this was done here). However, on the next branch, this is no longer the case: TargetType is used directly (Done here I believe).

However, after compiling (using the latest changes) the mint-tx project from 0xMiden/faucet#204, the resuling package is still tagged as Executable.

I'm not quite sure where this discrepancy stems from.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this will currently fail because Package::try_into_program() will return an error if package_kind is not TargetType::Executable.

We still compile transaction scripts as an executable. Only the note script and authentication component are compiled as a library with exports marked with @note_script and @auth_script.

This brings up a question of how can we identify the program entrypoint for TransactionScript packages. For notes, we have the @note_script attribute. Should we add something similar for transaction scripts? cc @bitwalker and @greenhat

I agree. The transaction script is the only rollup target that is not compiled as a library. It makes sense to compile it as a library and mark an entrypoint with an attribute.


Ok(TransactionScript::new(program))
}

// PUBLIC ACCESSORS
// --------------------------------------------------------------------------------------------

Expand Down
Loading