Skip to content
Merged
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
64 changes: 9 additions & 55 deletions crates/miden-lib/src/transaction/inputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use miden_objects::transaction::{AccountInputs, InputNote, PartialBlockchain, Tr
use miden_objects::vm::AdviceInputs;
use miden_objects::{EMPTY_WORD, Felt, FieldElement, Word, ZERO};
use miden_processor::AdviceMutation;
use thiserror::Error;

use super::TransactionKernel;

Expand All @@ -25,13 +24,13 @@ impl TransactionAdviceInputs {
///
/// The created advice inputs will be populated with the data required for executing a
/// transaction with the specified transaction inputs.
pub fn new(tx_inputs: &TransactionInputs) -> Result<Self, TransactionAdviceMapMismatch> {
pub fn new(tx_inputs: &TransactionInputs) -> Self {
let mut inputs = TransactionAdviceInputs(tx_inputs.advice_inputs().clone());

inputs.build_stack(tx_inputs);
inputs.add_kernel_commitment();
inputs.add_partial_blockchain(tx_inputs.blockchain());
inputs.add_input_notes(tx_inputs)?;
inputs.add_input_notes(tx_inputs);

// Add the script's MAST forest's advice inputs.
if let Some(tx_script) = tx_inputs.tx_args().tx_script() {
Expand All @@ -46,7 +45,7 @@ impl TransactionAdviceInputs {

// Inject native account.
let partial_native_acc = tx_inputs.account();
inputs.add_account(partial_native_acc)?;
inputs.add_account(partial_native_acc);

// If a seed was provided, extend the map appropriately.
if let Some(seed) = tx_inputs.account().seed() {
Expand All @@ -71,7 +70,7 @@ impl TransactionAdviceInputs {
// Extend with extra user-supplied advice.
inputs.extend(tx_inputs.tx_args().advice_inputs().clone());

Ok(inputs)
inputs
}

/// Returns a reference to the underlying advice inputs.
Expand Down Expand Up @@ -108,9 +107,9 @@ impl TransactionAdviceInputs {
pub fn add_foreign_accounts<'inputs>(
&mut self,
foreign_account_inputs: impl IntoIterator<Item = &'inputs AccountInputs>,
) -> Result<(), TransactionAdviceMapMismatch> {
) {
for foreign_acc in foreign_account_inputs {
self.add_account(foreign_acc.account())?;
self.add_account(foreign_acc.account());
self.add_account_witness(foreign_acc.witness());

// for foreign accounts, we need to insert the id to state mapping
Expand All @@ -121,8 +120,6 @@ impl TransactionAdviceInputs {
// ACCOUNT_ID |-> [ID_AND_NONCE, VAULT_ROOT, STORAGE_COMMITMENT, CODE_COMMITMENT]
self.add_map_entry(account_id_key, header.as_elements());
}

Ok(())
}

/// Extend the advice stack with the transaction inputs.
Expand Down Expand Up @@ -253,28 +250,13 @@ impl TransactionAdviceInputs {
/// - The account code commitment |-> procedures vector.
/// - The leaf hash |-> (key, value), for all leaves of the partial vault.
/// - If present, the Merkle leaves associated with the account storage maps.
fn add_account(
&mut self,
account: &PartialAccount,
) -> Result<(), TransactionAdviceMapMismatch> {
fn add_account(&mut self, account: &PartialAccount) {
// --- account code -------------------------------------------------------

// CODE_COMMITMENT -> [[ACCOUNT_PROCEDURE_DATA]]
let code = account.code();
self.add_map_entry(code.commitment(), code.as_elements());

// Extend the advice map with the account code's advice inputs.
// This ensures that the advice map is available during the note script execution when it
// calls the account's code that relies on the it's advice map data (data segments) loaded
// into the advice provider
self.0.map.merge(account.code().mast().advice_map()).map_err(
|((key, existing_val), incoming_val)| TransactionAdviceMapMismatch {
key,
existing_val: existing_val.to_vec(),
incoming_val: incoming_val.to_vec(),
},
)?;

// --- account storage ----------------------------------------------------

// STORAGE_COMMITMENT |-> [[STORAGE_SLOT_DATA]]
Expand All @@ -290,8 +272,6 @@ impl TransactionAdviceInputs {
// populate Merkle store and advice map with nodes info needed to access vault assets
self.extend_merkle_store(account.vault().inner_nodes());
self.extend_map(account.vault().leaves().map(|leaf| (leaf.hash(), leaf.to_elements())));

Ok(())
}

/// Adds an account witness to the advice inputs.
Expand Down Expand Up @@ -328,12 +308,9 @@ impl TransactionAdviceInputs {
/// - The note's position in the note tree
///
/// The data above is processed by `prologue::process_input_notes_data`.
fn add_input_notes(
&mut self,
tx_inputs: &TransactionInputs,
) -> Result<(), TransactionAdviceMapMismatch> {
fn add_input_notes(&mut self, tx_inputs: &TransactionInputs) {
if tx_inputs.input_notes().is_empty() {
return Ok(());
return;
}

let mut note_data = Vec::new();
Expand Down Expand Up @@ -387,19 +364,9 @@ impl TransactionAdviceInputs {
note_data.push(Felt::ZERO)
},
}

self.0.map.merge(note.script().mast().advice_map()).map_err(
|((key, existing_val), incoming_val)| TransactionAdviceMapMismatch {
key,
existing_val: existing_val.to_vec(),
incoming_val: incoming_val.to_vec(),
},
)?;
}

self.add_map_entry(tx_inputs.input_notes().commitment(), note_data);

Ok(())
}

// HELPER METHODS
Expand Down Expand Up @@ -447,16 +414,3 @@ impl From<AdviceInputs> for TransactionAdviceInputs {
Self(inner)
}
}

// CONFLICT ERROR
// ================================================================================================

#[derive(Debug, Error)]
#[error(
"conflicting map entry for key {key}: existing={existing_val:?}, incoming={incoming_val:?}"
)]
pub struct TransactionAdviceMapMismatch {
pub key: Word,
pub existing_val: Vec<Felt>,
pub incoming_val: Vec<Felt>,
}
10 changes: 4 additions & 6 deletions crates/miden-lib/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod events;
pub use events::{EventId, TransactionEvent};

mod inputs;
pub use inputs::{TransactionAdviceInputs, TransactionAdviceMapMismatch};
pub use inputs::TransactionAdviceInputs;

mod outputs;
pub use outputs::{
Expand Down Expand Up @@ -121,9 +121,7 @@ impl TransactionKernel {

/// Transforms the provided [`TransactionInputs`] into stack and advice
/// inputs needed to execute a transaction kernel for a specific transaction.
pub fn prepare_inputs(
tx_inputs: &TransactionInputs,
) -> Result<(StackInputs, TransactionAdviceInputs), TransactionAdviceMapMismatch> {
pub fn prepare_inputs(tx_inputs: &TransactionInputs) -> (StackInputs, TransactionAdviceInputs) {
let account = tx_inputs.account();

let stack_inputs = TransactionKernel::build_input_stack(
Expand All @@ -134,9 +132,9 @@ impl TransactionKernel {
tx_inputs.block_header().block_num(),
);

let tx_advice_inputs = TransactionAdviceInputs::new(tx_inputs)?;
let tx_advice_inputs = TransactionAdviceInputs::new(tx_inputs);

Ok((stack_inputs, tx_advice_inputs))
(stack_inputs, tx_advice_inputs)
}

// ASSEMBLER CONSTRUCTOR
Expand Down
4 changes: 2 additions & 2 deletions crates/miden-testing/src/kernel_tests/tx/test_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -715,13 +715,13 @@ async fn inputs_created_correctly() -> anyhow::Result<()> {
adv_map.A([1,2,3,4])=[5,6,7,8]

begin
call.{assert_adv_map_proc_root}

# test account code advice map
push.[6,7,8,9]
adv.push_mapval adv_loadw
push.[10,11,12,13]
assert_eqw.err="account code adv map not found"

call.{assert_adv_map_proc_root}
end
"#,
assert_adv_map_proc_root =
Expand Down
3 changes: 1 addition & 2 deletions crates/miden-testing/src/tx_context/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ impl TransactionContext {
///
/// - If the provided `code` is not a valid program.
pub async fn execute_code(&self, code: &str) -> Result<ExecutionOutput, ExecutionError> {
let (stack_inputs, advice_inputs) = TransactionKernel::prepare_inputs(&self.tx_inputs)
.expect("error initializing transaction inputs");
let (stack_inputs, advice_inputs) = TransactionKernel::prepare_inputs(&self.tx_inputs);

// Virtual file name should be unique.
let virtual_source_file = self.source_manager.load(
Expand Down
5 changes: 0 additions & 5 deletions crates/miden-tx/src/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use alloc::string::String;
use alloc::vec::Vec;
use core::error::Error;

use miden_lib::transaction::TransactionAdviceMapMismatch;
use miden_objects::account::AccountId;
use miden_objects::account::auth::PublicKeyCommitment;
use miden_objects::assembly::diagnostics::reporting::PrintDiagnostic;
Expand Down Expand Up @@ -74,8 +73,6 @@ impl From<TransactionCheckerError> for TransactionExecutorError {

#[derive(Debug, Error)]
pub enum TransactionExecutorError {
#[error("the advice map contains conflicting map entries")]
ConflictingAdviceMapEntry(#[source] TransactionAdviceMapMismatch),
#[error("failed to fetch transaction inputs from the data store")]
FetchTransactionInputsFailed(#[source] DataStoreError),
#[error("foreign account inputs for ID {0} are not anchored on reference block")]
Expand Down Expand Up @@ -149,8 +146,6 @@ pub enum TransactionProverError {
TransactionOutputConstructionFailed(#[source] TransactionOutputError),
#[error("failed to build proven transaction")]
ProvenTransactionBuildFailed(#[source] ProvenTransactionError),
#[error("the advice map contains conflicting map entries")]
ConflictingAdviceMapEntry(#[source] TransactionAdviceMapMismatch),
// Print the diagnostic directly instead of returning the source error. In the source error
// case, the diagnostic is lost if the execution error is not explicitly unwrapped.
#[error("failed to execute transaction kernel program:\n{}", PrintDiagnostic::new(.0))]
Expand Down
12 changes: 1 addition & 11 deletions crates/miden-tx/src/executor/exec_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,7 @@ where
})?;

let mut tx_advice_inputs = TransactionAdviceInputs::default();
tx_advice_inputs
.add_foreign_accounts([&foreign_account_inputs])
.map_err(|err| {
TransactionKernelError::other_with_source(
format!(
"failed to construct advice inputs for foreign account {}",
foreign_account_inputs.id()
),
err,
)
})?;
tx_advice_inputs.add_foreign_accounts([&foreign_account_inputs]);

self.base_host
.load_foreign_account_code(foreign_account_inputs.code())
Expand Down
3 changes: 1 addition & 2 deletions crates/miden-tx/src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,7 @@ where
(TransactionExecutorHost<'store, 'auth, STORE, AUTH>, StackInputs, AdviceInputs),
TransactionExecutorError,
> {
let (stack_inputs, tx_advice_inputs) = TransactionKernel::prepare_inputs(tx_inputs)
.map_err(TransactionExecutorError::ConflictingAdviceMapEntry)?;
let (stack_inputs, tx_advice_inputs) = TransactionKernel::prepare_inputs(tx_inputs);

// This reverses the stack inputs (even though it doesn't look like it does) because the
// fast processor expects the reverse order.
Expand Down
3 changes: 1 addition & 2 deletions crates/miden-tx/src/prover/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ impl LocalTransactionProver {
tx_inputs: impl Into<TransactionInputs>,
) -> Result<ProvenTransaction, TransactionProverError> {
let tx_inputs = tx_inputs.into();
let (stack_inputs, advice_inputs) = TransactionKernel::prepare_inputs(&tx_inputs)
.map_err(TransactionProverError::ConflictingAdviceMapEntry)?;
let (stack_inputs, advice_inputs) = TransactionKernel::prepare_inputs(&tx_inputs);

self.mast_store.load_account_code(tx_inputs.account().code());
for account_code in tx_inputs.foreign_account_code() {
Expand Down
Loading