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
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 ([#2099](https://github.com/0xMiden/miden-base/pull/2099)).

## 0.12.2 (2025-11-12)

Expand Down
24 changes: 20 additions & 4 deletions crates/miden-objects/src/transaction/inputs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,13 @@ impl TransactionInputs {

/// Replaces the transaction inputs and assigns the given transaction arguments.
pub fn with_tx_args(mut self, tx_args: TransactionArgs) -> Self {
self.tx_args = tx_args;
self.set_tx_args_inner(tx_args);
self
}

/// 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.set_advice_inputs(advice_inputs);
self
}

Expand All @@ -115,14 +115,18 @@ impl TransactionInputs {
}

/// Replaces the advice inputs for the transaction.
///
/// Note: the advice stack from the provided advice inputs is discarded.
pub fn set_advice_inputs(&mut self, new_advice_inputs: AdviceInputs) {
self.advice_inputs = new_advice_inputs;
let AdviceInputs { map, store, .. } = new_advice_inputs;
self.advice_inputs = AdviceInputs { stack: Default::default(), map, store };
self.tx_args.extend_advice_inputs(self.advice_inputs.clone());
}

/// Updates the transaction arguments of the inputs.
#[cfg(feature = "testing")]
pub fn set_tx_args(&mut self, tx_args: TransactionArgs) {
self.tx_args = tx_args;
self.set_tx_args_inner(tx_args);
}

// PUBLIC ACCESSORS
Expand Down Expand Up @@ -189,6 +193,18 @@ impl TransactionInputs {
) {
(self.account, self.block_header, self.blockchain, self.input_notes, self.tx_args)
}

// HELPER METHODS
// --------------------------------------------------------------------------------------------

/// Replaces the current tx_args with the provided value.
///
/// This also appends advice inputs from these transaction inputs to the advice inputs of the
/// tx args.
fn set_tx_args_inner(&mut self, tx_args: TransactionArgs) {
self.tx_args = tx_args;
self.tx_args.extend_advice_inputs(self.advice_inputs.clone());
}
}

impl Serializable for TransactionInputs {
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(())
}
Loading