From 3d925d29a737d6c2ac25b77f465dd02e4c4ee19f Mon Sep 17 00:00:00 2001 From: sara Date: Fri, 29 Aug 2025 16:26:09 -0300 Subject: [PATCH] sorting inputs and testing --- crates/tx3-cardano/src/compile/mod.rs | 8 +++- crates/tx3-cardano/src/tests.rs | 65 +++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/crates/tx3-cardano/src/compile/mod.rs b/crates/tx3-cardano/src/compile/mod.rs index 5ed41cd6..d2e0d260 100644 --- a/crates/tx3-cardano/src/compile/mod.rs +++ b/crates/tx3-cardano/src/compile/mod.rs @@ -211,7 +211,7 @@ fn compile_mint_block(tx: &ir::Tx) -> Result, Error> { } fn compile_inputs(tx: &ir::Tx) -> Result, Error> { - let refs = tx + let mut refs: Vec = tx .inputs .iter() .flat_map(|x| coercion::expr_into_utxo_refs(&x.utxos)) @@ -222,6 +222,12 @@ fn compile_inputs(tx: &ir::Tx) -> Result, Erro }) .collect(); + refs.sort_by(|a, b| { + a.transaction_id + .cmp(&b.transaction_id) + .then(a.index.cmp(&b.index)) + }); + Ok(refs) } diff --git a/crates/tx3-cardano/src/tests.rs b/crates/tx3-cardano/src/tests.rs index fc07e628..b9cee5d4 100644 --- a/crates/tx3-cardano/src/tests.rs +++ b/crates/tx3-cardano/src/tests.rs @@ -508,3 +508,68 @@ async fn min_utxo_compiler_op_test() { assert!(!assets.is_empty()); } } + +fn make_input(hash: &str, index: u32) -> ir::Input { + ir::Input { + name: "".to_string(), + utxos: ir::Expression::UtxoSet(HashSet::from([Utxo { + r#ref: UtxoRef { + txid: hex::decode(hash).unwrap(), + index, + }, + address: pallas::ledger::addresses::Address::from_bech32("addr1qx0rs5qrvx9qkndwu0w88t0xghgy3f53ha76kpx8uf496m9rn2ursdm3r0fgf5pmm4lpufshl8lquk5yykg4pd00hp6quf2hh2").unwrap().to_vec(), + datum: Some(tx3_lang::ir::Expression::None), + assets: tx3_lang::CanonicalAssets::from_naked_amount(500_000_000), + script: None, + }])), + redeemer: ir::Expression::None, + } +} + +#[pollster::test] +async fn inputs_sorted_lexicographically() { + let pparams = PParams { + network: crate::Network::Testnet, + min_fee_coefficient: 1, + min_fee_constant: 2, + coins_per_utxo_byte: 1, + cost_models: HashMap::from([ + (0, COST_MODEL_PLUTUS_V1.to_vec()), + (1, COST_MODEL_PLUTUS_V2.to_vec()), + (2, COST_MODEL_PLUTUS_V2.to_vec()), + ]), + }; + let input1 = make_input( + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + 1, + ); + let input2 = make_input( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + 1, + ); + let input3 = make_input( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + 0, + ); + let input4 = make_input( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + 3, + ); + let tx = ir::Tx { + inputs: vec![input1, input2, input3, input4], + adhoc: vec![], + burns: vec![], + collateral: vec![], + fees: ir::Expression::Number(1234), + metadata: vec![], + mints: vec![], + outputs: vec![], + references: vec![], + signers: None, + validity: None, + }; + + let compiled_tx = compile::entry_point(&tx, &pparams); + let inputs = &compiled_tx.unwrap().transaction_body.inputs; + assert_eq!(inputs.is_sorted(), true); +}