Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8c59e66
refactor: Change way of providing code and inputs to executor
igamigo Mar 19, 2025
0a576c0
test: Fix 3 tests
igamigo Mar 19, 2025
f0888df
chore: Merge next
igamigo Mar 19, 2025
4052596
chore: Merge next
igamigo Mar 31, 2025
017d8fd
Checkpoint
igamigo Apr 2, 2025
7df20d7
feat: Add ForeignTransactionInputs
igamigo Apr 7, 2025
1edbfe7
chore: Merge next
igamigo Apr 7, 2025
0ac3111
chore: Remove TODO
igamigo Apr 7, 2025
d88556f
chore: CHANGELOG
igamigo Apr 7, 2025
327fc3f
reviews: Address comment
igamigo Apr 10, 2025
4040442
Revert change
igamigo Apr 10, 2025
fc60697
refactor: Remove unused DataStore error variant
igamigo Apr 10, 2025
a34b940
chore: Clippy
igamigo Apr 10, 2025
2f7e499
refactor: TransactionArgs mutators
igamigo Apr 11, 2025
20c9d25
chore: Clippy
igamigo Apr 11, 2025
32a5296
refactor: MAST store
igamigo Apr 11, 2025
5965b5c
refactor: FPI inputs
igamigo Apr 11, 2025
0a680cf
reviews: propagate errors, add validations and tests
igamigo Apr 14, 2025
75e1fdc
test: Fix assembles
igamigo Apr 14, 2025
96c28ef
reviews: Move mast_store.rs
igamigo Apr 14, 2025
eee32d8
Merge branch 'next' into igamigo-refactor-executor
igamigo Apr 14, 2025
853ca80
fix: Remove accidentall std addition
igamigo Apr 14, 2025
26ae3a5
chore: Merge
igamigo Apr 14, 2025
124d03f
chore: Lints
igamigo Apr 14, 2025
e7a88e2
test: Fix doc test build
igamigo Apr 14, 2025
beb71f1
reviews: Change name, add execute_code variant and make function private
igamigo Apr 15, 2025
b4b2e1c
reviews: Box string in error
igamigo Apr 15, 2025
cd15d1f
reviews: Typo
igamigo Apr 15, 2025
9e3b4e9
chore: Merge next
igamigo Apr 21, 2025
635cf7f
chore: Merge conflicts
igamigo Apr 21, 2025
7b959d1
tests: refactor test to work around the new validations
igamigo Apr 21, 2025
bf97884
feat: Add is_valid()
igamigo Apr 21, 2025
f352972
chore: Clippy
igamigo Apr 21, 2025
5757967
style: CHANGELOG extra newline
igamigo Apr 21, 2025
6503c8b
chore: Renames and imports
igamigo Apr 21, 2025
65ea187
reviews: Remove unnecessary (crate) and add note
igamigo Apr 22, 2025
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: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- Add `AccountTree` and `PartialAccountTree` wrappers and enforce ID prefix uniqueness (#1254).
- Added a retry strategy for worker's health check (#1255).
- Added pretty print for `AccountCode` (#1273).

- [BREAKING] Refactored how foreign account inputs are passed to `TransactionExecutor`, and upgraded Rust version to 1.86 (#1229).

## 0.8.1 (2025-03-26) - `miden-objects` and `miden-tx` crates only.

Expand Down
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ members = [

[workspace.package]
edition = "2024"
rust-version = "1.85"
rust-version = "1.86"
license = "MIT"
authors = ["Miden contributors"]
homepage = "https://polygon.technology/polygon-miden"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/0xPolygonMiden/miden-base/blob/main/LICENSE)
[![test](https://github.com/0xPolygonMiden/miden-base/actions/workflows/test.yml/badge.svg)](https://github.com/0xPolygonMiden/miden-base/actions/workflows/test.yml)
[![build](https://github.com/0xPolygonMiden/miden-base/actions/workflows/build.yml/badge.svg)](https://github.com/0xPolygonMiden/miden-base/actions/workflows/build.yml)
[![RUST_VERSION](https://img.shields.io/badge/rustc-1.85+-lightgray.svg)](https://www.rust-lang.org/tools/install)
[![RUST_VERSION](https://img.shields.io/badge/rustc-1.86+-lightgray.svg)](https://www.rust-lang.org/tools/install)
[![GitHub Release](https://img.shields.io/github/release/0xPolygonMiden/miden-base)](https://github.com/0xPolygonMiden/miden-base/releases/)

Description and core structures for the Miden Rollup protocol.
Expand Down
31 changes: 11 additions & 20 deletions bin/bench-tx/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{
fs::{File, read_to_string, write},
io::Write,
path::Path,
sync::Arc,
};

use miden_lib::{note::create_p2id_note, transaction::TransactionKernel};
Expand Down Expand Up @@ -67,17 +68,12 @@ pub fn benchmark_default_tx() -> Result<TransactionMeasurements, String> {
let account_id = tx_context.account().id();

let block_ref = tx_context.tx_inputs().block_header().block_num();
let note_ids = tx_context
.tx_inputs()
.input_notes()
.iter()
.map(|note| note.id())
.collect::<Vec<_>>();

let tx_args = tx_context.tx_args().clone();
let notes = tx_context.tx_inputs().input_notes().clone();
let executor: TransactionExecutor =
TransactionExecutor::new(tx_context.get_data_store(), None).with_tracing();
TransactionExecutor::new(Arc::new(tx_context), None).with_tracing();
let executed_transaction = executor
.execute_transaction(account_id, block_ref, &note_ids, tx_context.tx_args().clone())
.execute_transaction(account_id, block_ref, notes, tx_args)
.map_err(|e| e.to_string())?;

Ok(executed_transaction.into())
Expand Down Expand Up @@ -116,26 +112,21 @@ pub fn benchmark_p2id() -> Result<TransactionMeasurements, String> {
let tx_context = TransactionContextBuilder::new(target_account.clone())
.input_notes(vec![note.clone()])
.build();
let block_ref = tx_context.tx_inputs().block_header().block_num();

let executor = TransactionExecutor::new(tx_context.get_data_store(), Some(falcon_auth.clone()))
.with_tracing();
let notes = tx_context.tx_inputs().input_notes().clone();

let block_ref = tx_context.tx_inputs().block_header().block_num();
let note_ids = tx_context
.tx_inputs()
.input_notes()
.iter()
.map(|note| note.id())
.collect::<Vec<_>>();
let executor =
TransactionExecutor::new(Arc::new(tx_context), Some(falcon_auth.clone())).with_tracing();

let tx_script_target =
TransactionScript::compile(DEFAULT_AUTH_SCRIPT, [], TransactionKernel::assembler())
.unwrap();
let tx_args_target = TransactionArgs::with_tx_script(tx_script_target);
let tx_args_target = TransactionArgs::default().with_tx_script(tx_script_target);

// execute transaction
let executed_transaction = executor
.execute_transaction(target_account.id(), block_ref, &note_ids, tx_args_target)
.execute_transaction(target_account.id(), block_ref, notes, tx_args_target)
.unwrap();

Ok(executed_transaction.into())
Expand Down
23 changes: 17 additions & 6 deletions crates/miden-lib/src/transaction/inputs.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::vec::Vec;

use miden_objects::{
Digest, EMPTY_WORD, Felt, FieldElement, WORD_SIZE, Word, ZERO,
Digest, EMPTY_WORD, Felt, FieldElement, TransactionInputError, WORD_SIZE, Word, ZERO,
account::{Account, StorageSlot},
transaction::{ChainMmr, InputNote, TransactionArgs, TransactionInputs, TransactionScript},
vm::AdviceInputs,
Expand All @@ -22,7 +22,7 @@ pub(super) fn extend_advice_inputs(
tx_inputs: &TransactionInputs,
tx_args: &TransactionArgs,
advice_inputs: &mut AdviceInputs,
) {
) -> Result<(), TransactionInputError> {
// TODO: remove this value and use a user input instead
let kernel_version = 0;

Expand All @@ -32,8 +32,13 @@ pub(super) fn extend_advice_inputs(
add_kernel_commitments_to_advice_inputs(advice_inputs, kernel_version);
add_chain_mmr_to_advice_inputs(tx_inputs.block_chain(), advice_inputs);
add_account_to_advice_inputs(tx_inputs.account(), tx_inputs.account_seed(), advice_inputs);
add_input_notes_to_advice_inputs(tx_inputs, tx_args, advice_inputs);
add_input_notes_to_advice_inputs(tx_inputs, tx_args, advice_inputs)?;
for foreign_account in tx_args.foreign_accounts() {
TransactionKernel::extend_advice_inputs_for_account(advice_inputs, foreign_account)?;
}

advice_inputs.extend(tx_args.advice_inputs().clone());
Ok(())
}

// ADVICE STACK BUILDER
Expand Down Expand Up @@ -223,10 +228,10 @@ fn add_input_notes_to_advice_inputs(
tx_inputs: &TransactionInputs,
tx_args: &TransactionArgs,
inputs: &mut AdviceInputs,
) {
) -> Result<(), TransactionInputError> {
// if there are no input notes, nothing is added to the advice inputs
if tx_inputs.input_notes().is_empty() {
return;
return Ok(());
}

let mut note_data = Vec::new();
Expand Down Expand Up @@ -283,7 +288,12 @@ fn add_input_notes_to_advice_inputs(
proof.location().node_index_in_block().into(),
note.commitment(),
)
.unwrap(),
.map_err(|err| {
TransactionInputError::InvalidMerklePath(
format!("input note ID {}", note.id()).into(),
err,
)
})?,
);
note_data.push(proof.location().block_num().into());
note_data.extend(note_block_header.sub_commitment());
Expand All @@ -300,6 +310,7 @@ fn add_input_notes_to_advice_inputs(

// NOTE: keep map in sync with the `prologue::process_input_notes_data` kernel procedure
inputs.extend_map([(tx_inputs.input_notes().commitment(), note_data)]);
Ok(())
}

// KERNEL COMMITMENTS INJECTOR
Expand Down
80 changes: 50 additions & 30 deletions crates/miden-lib/src/transaction/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use alloc::{string::ToString, sync::Arc, vec::Vec};

use miden_objects::{
Digest, EMPTY_WORD, Felt, TransactionOutputError, ZERO,
account::{AccountCode, AccountHeader, AccountId, AccountStorageHeader},
Digest, EMPTY_WORD, Felt, TransactionInputError, TransactionOutputError, ZERO,
account::{AccountCode, AccountId},
assembly::{Assembler, DefaultSourceManager, KernelLibrary},
block::{AccountWitness, BlockNumber},
crypto::merkle::MerkleError,
block::BlockNumber,
transaction::{
OutputNote, OutputNotes, TransactionArgs, TransactionInputs, TransactionOutputs,
ForeignAccountInputs, OutputNote, OutputNotes, TransactionArgs, TransactionInputs,
TransactionOutputs,
},
utils::{serde::Deserializable, sync::LazyLock},
vm::{AdviceInputs, AdviceMap, Program, ProgramInfo, StackInputs, StackOutputs},
Expand Down Expand Up @@ -114,7 +114,7 @@ impl TransactionKernel {
tx_inputs: &TransactionInputs,
tx_args: &TransactionArgs,
init_advice_inputs: Option<AdviceInputs>,
) -> (StackInputs, AdviceInputs) {
) -> Result<(StackInputs, AdviceInputs), TransactionInputError> {
let account = tx_inputs.account();

let stack_inputs = TransactionKernel::build_input_stack(
Expand All @@ -126,9 +126,9 @@ impl TransactionKernel {
);

let mut advice_inputs = init_advice_inputs.unwrap_or_default();
inputs::extend_advice_inputs(tx_inputs, tx_args, &mut advice_inputs);
inputs::extend_advice_inputs(tx_inputs, tx_args, &mut advice_inputs)?;

(stack_inputs, advice_inputs)
Ok((stack_inputs, advice_inputs))
}

// ASSEMBLER CONSTRUCTOR
Expand Down Expand Up @@ -189,36 +189,30 @@ impl TransactionKernel {
.expect("Invalid stack input")
}

/// Extends the advice inputs with account data and Merkle proofs.
///
/// Where:
/// - account_header is the header of the account which data will be used for the extension.
/// - account_code is the code of the account which will be used for the extension.
/// - storage_header is the header of the storage which data will be used for the extension.
/// - merkle_path is the authentication path from the account root of the block header to the
/// account.
/// Extends the advice inputs with the account-specific inputs.
pub fn extend_advice_inputs_for_account(
advice_inputs: &mut AdviceInputs,
account_header: &AccountHeader,
account_code: &AccountCode,
storage_header: &AccountStorageHeader,
account_witness: &AccountWitness,
) -> Result<(), MerkleError> {
foreign_account_inputs: &ForeignAccountInputs,
) -> Result<(), TransactionInputError> {
let account_header = foreign_account_inputs.account_header();
let storage_header = foreign_account_inputs.storage_header();
let account_code = foreign_account_inputs.account_code();
let account_witness = foreign_account_inputs.witness();
let storage_proofs = foreign_account_inputs.storage_map_proofs();
let account_id = account_header.id();
let storage_root = account_header.storage_commitment();
let code_root = account_header.code_commitment();

// Note: keep in sync with the start_foreign_context kernel procedure
let account_key =
let account_key: Digest =
Digest::from([account_id.suffix(), account_id.prefix().as_felt(), ZERO, ZERO]);

// Extend the advice inputs with the new data
advice_inputs.extend_map([
// ACCOUNT_ID -> [ID_AND_NONCE, VAULT_ROOT, STORAGE_ROOT, CODE_ROOT]
// ACCOUNT_ID -> [ID_AND_NONCE, VAULT_ROOT, STORAGE_COMMITMENT, CODE_COMMITMENT]
(account_key, account_header.as_elements()),
// STORAGE_ROOT -> [STORAGE_SLOT_DATA]
(storage_root, storage_header.as_elements()),
// CODE_ROOT -> [ACCOUNT_CODE_DATA]
(code_root, account_code.as_elements()),
// STORAGE_COMMITMENT -> [STORAGE_SLOT_DATA]
(account_header.storage_commitment(), storage_header.as_elements()),
// CODE_COMMITMENT -> [ACCOUNT_CODE_DATA]
(account_header.code_commitment(), account_code.as_elements()),
]);

let account_leaf = account_witness.leaf();
Expand All @@ -228,11 +222,37 @@ impl TransactionKernel {
advice_inputs.extend_merkle_store(
account_witness
.path()
.inner_nodes(account_id.prefix().as_u64(), account_leaf_hash)?,
.inner_nodes(account_id.prefix().as_u64(), account_leaf_hash)
.map_err(|err| {
TransactionInputError::InvalidMerklePath(
format!("foreign account ID {}", account_id).into(),
err,
)
})?,
);

// populate advice map with the account's leaf
advice_inputs.extend_map([(account_leaf_hash, account_leaf.to_elements())]);

// Load merkle nodes for storage maps
for proof in storage_proofs {
// Extend the merkle store and map with the storage maps
advice_inputs.extend_merkle_store(
proof
.path()
.inner_nodes(proof.leaf().index().value(), proof.leaf().hash())
.map_err(|err| {
TransactionInputError::InvalidMerklePath(
format!("foreign account ID {} storage proof", account_id).into(),
err,
)
})?,
);
// Populate advice map with Sparse Merkle Tree leaf nodes
advice_inputs
.extend_map(core::iter::once((proof.leaf().hash(), proof.leaf().to_elements())));
}

Ok(())
}

Expand Down
10 changes: 9 additions & 1 deletion crates/miden-objects/src/account/storage/header.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use alloc::vec::Vec;

use super::{AccountStorage, Felt, StorageSlot, StorageSlotType, Word};
use vm_processor::Digest;

use super::{AccountStorage, Felt, Hasher, StorageSlot, StorageSlotType, Word};
use crate::{
AccountError, ZERO,
utils::serde::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
Expand Down Expand Up @@ -90,6 +92,12 @@ impl AccountStorageHeader {
})
}

// NOTE: The way of computing the commitment should be kept in sync with `AccountStorage`
/// Computes the account storage header commitment.
pub fn compute_commitment(&self) -> Digest {
Hasher::hash_elements(&self.as_elements())
}

/// Converts storage slots of this account storage header into a vector of field elements.
///
/// This is done by first converting each storage slot into exactly 8 elements as follows:
Expand Down
2 changes: 1 addition & 1 deletion crates/miden-objects/src/account/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ fn slots_as_elements(slots: &[StorageSlot]) -> Vec<Felt> {
}

/// Computes the commitment to the given slots
fn build_slots_commitment(slots: &[StorageSlot]) -> Digest {
pub fn build_slots_commitment(slots: &[StorageSlot]) -> Digest {
let elements = slots_as_elements(slots);
Hasher::hash_elements(&elements)
}
Expand Down
6 changes: 5 additions & 1 deletion crates/miden-objects/src/batch/account_update.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use alloc::boxed::Box;

use crate::{
Digest,
account::{AccountId, delta::AccountUpdateDetails},
Expand Down Expand Up @@ -106,7 +108,9 @@ impl BatchAccountUpdate {
}

self.details = self.details.clone().merge(tx.account_update().details().clone()).map_err(
|source_err| BatchAccountUpdateError::TransactionUpdateMergeError(tx.id(), source_err),
|source_err| {
BatchAccountUpdateError::TransactionUpdateMergeError(tx.id(), Box::new(source_err))
},
)?;
self.final_state_commitment = tx.account_update().final_state_commitment();

Expand Down
3 changes: 2 additions & 1 deletion crates/miden-objects/src/block/proposed_block.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use alloc::{
boxed::Box,
collections::{BTreeMap, BTreeSet},
vec::Vec,
};
Expand Down Expand Up @@ -681,7 +682,7 @@ impl AccountUpdateAggregator {
details = Some(match details {
None => update_details,
Some(details) => details.merge(update_details).map_err(|source| {
ProposedBlockError::AccountUpdateError { account_id, source }
ProposedBlockError::AccountUpdateError { account_id, source: Box::new(source) }
})?,
});
}
Expand Down
Loading