Skip to content
Merged
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
41 changes: 24 additions & 17 deletions crates/miden-testing/src/kernel_tests/batch/proposed_batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,19 +519,24 @@ fn multiple_transactions_against_same_account() -> anyhow::Result<()> {

/// Tests that the input and outputs notes commitment is correctly computed.
/// - Notes created and consumed in the same batch are erased from these commitments.
/// - The input note commitment is sorted by the order in which the notes appeared in the batch.
/// - The input note commitment is sorted by [`Nullifier`].
/// - The output note commitment is sorted by [`NoteId`].
#[test]
fn input_and_output_notes_commitment() -> anyhow::Result<()> {
let TestSetup { chain, account1, account2, .. } = setup_chain();
let block1 = chain.block_header(1);

let note0 = mock_output_note(50);
let note1 = mock_note(60);
let note2 = mock_output_note(70);
let note3 = mock_output_note(80);
let note4 = mock_note(90);
let note5 = mock_note(100);
// Randomize the note IDs and nullifiers on each test run to make sure the sorting property
// is tested with various inputs.
let mut rng = rand::rng();

let note0 = mock_output_note(rng.random());
let note1 = mock_note(rng.random());
let note2 = mock_output_note(rng.random());
let note3 = mock_output_note(rng.random());
let note4 = mock_note(rng.random());
let note5 = mock_note(rng.random());
let note6 = mock_note(rng.random());

let tx1 =
MockProvenTxBuilder::with_account(account1.id(), Word::empty(), account1.to_commitment())
Expand All @@ -542,7 +547,7 @@ fn input_and_output_notes_commitment() -> anyhow::Result<()> {
let tx2 =
MockProvenTxBuilder::with_account(account2.id(), Word::empty(), account2.to_commitment())
.ref_block_commitment(block1.commitment())
.unauthenticated_notes(vec![note4.clone()])
.unauthenticated_notes(vec![note4.clone(), note6.clone()])
.output_notes(vec![OutputNote::Full(note1.clone()), note2.clone(), note3.clone()])
.build()?;

Expand All @@ -556,21 +561,23 @@ fn input_and_output_notes_commitment() -> anyhow::Result<()> {
// We expect note1 to be erased from the input/output notes as it is created and consumed
// in the batch.
let mut expected_output_notes = [note0, note2, note3];
// We expect a vector sorted by NoteId.
// We expect a vector sorted by NoteId (since InputOutputNoteTracker is set up that way).
expected_output_notes.sort_unstable_by_key(OutputNote::id);

assert_eq!(batch.output_notes().len(), 3);
assert_eq!(batch.output_notes(), expected_output_notes);

let mut expected_input_notes = [
InputNoteCommitment::from(&InputNote::unauthenticated(note4)),
InputNoteCommitment::from(&InputNote::unauthenticated(note5)),
InputNoteCommitment::from(&InputNote::unauthenticated(note6)),
];
// We expect a vector sorted by Nullifier (since InputOutputNoteTracker is set up that way).
expected_input_notes.sort_unstable_by_key(InputNoteCommitment::nullifier);

// Input notes are sorted by the order in which they appeared in the batch.
assert_eq!(batch.input_notes().num_notes(), 2);
assert_eq!(
batch.input_notes().clone().into_vec(),
&[
InputNoteCommitment::from(&InputNote::unauthenticated(note5)),
InputNoteCommitment::from(&InputNote::unauthenticated(note4)),
]
);
assert_eq!(batch.input_notes().num_notes(), 3);
assert_eq!(batch.input_notes().clone().into_vec(), &expected_input_notes);

Ok(())
}
Expand Down