Skip to content
Closed
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## 0.12.3 (2025-11-14)

- Added `ecdsa_k256_keccak::PublicKey` as a valid template type ([#2097](https://github.com/0xMiden/miden-base/pull/2097)).
- [BREAKING] Fix advice inputs in transaction inputs not being propagated through ([#2094](https://github.com/0xMiden/miden-base/pull/2094)).

## 0.12.2 (2025-11-12)

Expand Down
5 changes: 3 additions & 2 deletions crates/miden-lib/src/transaction/inputs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ 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> {
let mut inputs = TransactionAdviceInputs(tx_inputs.advice_inputs().clone());
// Start with empty advice inputs so the advice stack is correctly build.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Start with empty advice inputs so the advice stack is correctly build.
// Start with empty advice inputs so the advice stack is correctly built.

let mut inputs = TransactionAdviceInputs(AdviceInputs::default());

inputs.build_stack(tx_inputs);
inputs.add_kernel_commitment();
Expand Down Expand Up @@ -69,7 +70,7 @@ impl TransactionAdviceInputs {
}

// Extend with extra user-supplied advice.
inputs.extend(tx_inputs.tx_args().advice_inputs().clone());
inputs.extend(tx_inputs.advice_inputs().clone());

Ok(inputs)
}
Expand Down
11 changes: 3 additions & 8 deletions crates/miden-objects/src/transaction/inputs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ pub struct TransactionInputs {
blockchain: PartialBlockchain,
input_notes: InputNotes<InputNote>,
tx_args: TransactionArgs,
advice_inputs: AdviceInputs,
foreign_account_code: Vec<AccountCode>,
}

Expand Down Expand Up @@ -83,7 +82,6 @@ impl TransactionInputs {
blockchain,
input_notes,
tx_args: TransactionArgs::default(),
advice_inputs: AdviceInputs::default(),
foreign_account_code: Vec::new(),
})
}
Expand All @@ -102,7 +100,7 @@ impl TransactionInputs {

/// Replaces the transaction inputs and assigns the given advice inputs.
pub fn with_advice_inputs(mut self, advice_inputs: AdviceInputs) -> Self {
self.advice_inputs = advice_inputs;
self.tx_args.extend_advice_inputs(advice_inputs);
Comment on lines 102 to +103
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the first iteration of the PR this overwrote the advice inputs. I now changed it to extend it, which makes the test_nested_fpi_cyclic_invocation test pass now (and I removed the ignore).

The test was failing during the LocalTransactionProver::prove call, because the custom advice stack inputs the test was setting on the advice inputs got overwritten after the tx execution by the call to with_advice_inputs in build_executed_transaction. So the custom advice stack inputs were no longer there at the time of proving. Thanks @Fumuran for the hint!

self
}

Expand All @@ -116,7 +114,7 @@ impl TransactionInputs {

/// Replaces the advice inputs for the transaction.
pub fn set_advice_inputs(&mut self, new_advice_inputs: AdviceInputs) {
self.advice_inputs = new_advice_inputs;
self.tx_args.set_advice_inputs(new_advice_inputs);
}

/// Updates the transaction arguments of the inputs.
Expand Down Expand Up @@ -166,7 +164,7 @@ impl TransactionInputs {

/// Returns the advice inputs to be consumed in the transaction.
pub fn advice_inputs(&self) -> &AdviceInputs {
&self.advice_inputs
self.tx_args().advice_inputs()
}

/// Returns the transaction arguments to be consumed in the transaction.
Expand Down Expand Up @@ -198,7 +196,6 @@ impl Serializable for TransactionInputs {
self.blockchain.write_into(target);
self.input_notes.write_into(target);
self.tx_args.write_into(target);
self.advice_inputs.write_into(target);
self.foreign_account_code.write_into(target);
}
}
Expand All @@ -212,7 +209,6 @@ impl Deserializable for TransactionInputs {
let blockchain = PartialBlockchain::read_from(source)?;
let input_notes = InputNotes::read_from(source)?;
let tx_args = TransactionArgs::read_from(source)?;
let advice_inputs = AdviceInputs::read_from(source)?;
let foreign_account_code = Vec::<AccountCode>::read_from(source)?;

Ok(TransactionInputs {
Expand All @@ -221,7 +217,6 @@ impl Deserializable for TransactionInputs {
blockchain,
input_notes,
tx_args,
advice_inputs,
foreign_account_code,
})
}
Expand Down
5 changes: 5 additions & 0 deletions crates/miden-objects/src/transaction/tx_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ impl TransactionArgs {
}
}

/// Replaces the advice inputs for the transaction args.
pub(crate) fn set_advice_inputs(&mut self, new_advice_inputs: AdviceInputs) {
self.advice_inputs = new_advice_inputs;
}

/// Extends the internal advice inputs' map with the provided key-value pairs.
pub fn extend_advice_map<T: IntoIterator<Item = (Word, Vec<Felt>)>>(&mut self, iter: T) {
self.advice_inputs.map.extend(iter);
Expand Down
34 changes: 34 additions & 0 deletions crates/miden-testing/src/kernel_tests/tx/test_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use miden_objects::testing::account_id::{
ACCOUNT_ID_PUBLIC_FUNGIBLE_FAUCET_2,
ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE,
ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE,
ACCOUNT_ID_SENDER,
};
use miden_objects::testing::constants::{FUNGIBLE_ASSET_AMOUNT, NON_FUNGIBLE_ASSET_DATA};
use miden_objects::testing::note::DEFAULT_NOTE_CODE;
Expand Down Expand Up @@ -821,3 +822,36 @@ async fn inputs_created_correctly() -> anyhow::Result<()> {

Ok(())
}

/// Test that reexecuting a transaction with no authenticator and the tx inputs from a first
/// successful execution is possible. This ensures that the signature generated in the first
/// execution is present during re-execution.
#[tokio::test]
async fn tx_can_be_reexecuted() -> anyhow::Result<()> {
let mut builder = MockChain::builder();
// Use basic auth so the tx requires a signature for successful execution.
let account = builder.add_existing_mock_account(Auth::BasicAuth)?;
let note = builder.add_p2id_note(
ACCOUNT_ID_SENDER.try_into()?,
account.id(),
&[FungibleAsset::mock(3)],
NoteType::Public,
)?;
let chain = builder.build()?;

let tx = chain
.build_tx_context(account.id(), &[note.id()], &[])?
.build()?
.execute()
.await?;

let _reexecuted_tx = chain
.build_tx_context(account.id(), &[note.id()], &[])?
.authenticator(None)
.tx_inputs(tx.tx_inputs().clone())
.build()?
.execute()
.await?;

Ok(())
}
9 changes: 2 additions & 7 deletions crates/miden-testing/src/tx_context/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@ use miden_objects::block::AccountWitness;
use miden_objects::note::{Note, NoteId, NoteScript};
use miden_objects::testing::account_id::ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE;
use miden_objects::testing::noop_auth_component::NoopAuthComponent;
use miden_objects::transaction::{
OutputNote,
TransactionArgs,
TransactionInputs,
TransactionScript,
};
use miden_objects::transaction::{OutputNote, TransactionInputs, TransactionScript};
use miden_processor::{AdviceInputs, Felt, Word};
use miden_tx::TransactionMastStore;
use miden_tx::auth::BasicAuthenticator;
Expand Down Expand Up @@ -290,7 +285,7 @@ impl TransactionContextBuilder {
},
};

let mut tx_args = TransactionArgs::default().with_note_args(self.note_args);
let mut tx_args = tx_inputs.tx_args().clone().with_note_args(self.note_args);

tx_args = if let Some(tx_script) = self.tx_script {
tx_args.with_tx_script_and_args(tx_script, self.tx_script_args)
Expand Down
Loading