Shuffle,
/// Unchanged
Untouched,
- /// BIP69 / Lexicographic
- Bip69Lexicographic,
/// Provide custom comparison functions for sorting
Custom {
/// Transaction inputs sort function
match self {
TxOrdering::Shuffle => write!(f, "Shuffle"),
TxOrdering::Untouched => write!(f, "Untouched"),
- TxOrdering::Bip69Lexicographic => write!(f, "Bip69Lexicographic"),
TxOrdering::Custom { .. } => write!(f, "Custom"),
}
}
shuffle_slice(&mut tx.input, rng);
shuffle_slice(&mut tx.output, rng);
}
- TxOrdering::Bip69Lexicographic => {
- tx.input.sort_unstable_by_key(|txin| {
- (txin.previous_output.txid, txin.previous_output.vout)
- });
- tx.output
- .sort_unstable_by_key(|txout| (txout.value, txout.script_pubkey.clone()));
- }
TxOrdering::Custom {
input_sort,
output_sort,
.expect("it should have moved the outputs at least once");
}
- #[test]
- fn test_output_ordering_bip69() {
- use core::str::FromStr;
-
- let original_tx = ordering_test_tx!();
- let mut tx = original_tx;
-
- TxOrdering::Bip69Lexicographic.sort_tx(&mut tx);
-
- assert_eq!(
- tx.input[0].previous_output,
- bitcoin::OutPoint::from_str(
- "0e53ec5dfb2cb8a71fec32dc9a634a35b7e24799295ddd5278217822e0b31f57:5"
- )
- .unwrap()
- );
- assert_eq!(
- tx.input[1].previous_output,
- bitcoin::OutPoint::from_str(
- "0f60fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2:0"
- )
- .unwrap()
- );
- assert_eq!(
- tx.input[2].previous_output,
- bitcoin::OutPoint::from_str(
- "0f60fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2:1"
- )
- .unwrap()
- );
-
- assert_eq!(tx.output[0].value.to_sat(), 800);
- assert_eq!(tx.output[1].script_pubkey, ScriptBuf::from(vec![0xAA]));
- assert_eq!(
- tx.output[2].script_pubkey,
- ScriptBuf::from(vec![0xAA, 0xEE])
- );
- }
-
#[test]
fn test_output_ordering_custom_but_bip69() {
use core::str::FromStr;
+extern crate alloc;
+
use std::path::Path;
use std::str::FromStr;
#[test]
fn test_create_tx_ordering_respected() {
+ use alloc::sync::Arc;
+
let (mut wallet, _) = get_funded_wallet_wpkh();
let addr = wallet.next_unused_address(KeychainKind::External);
+
+ let bip69_txin_cmp = |tx_a: &TxIn, tx_b: &TxIn| {
+ let project_outpoint = |t: &TxIn| (t.previous_output.txid, t.previous_output.vout);
+ project_outpoint(tx_a).cmp(&project_outpoint(tx_b))
+ };
+
+ let bip69_txout_cmp = |tx_a: &TxOut, tx_b: &TxOut| {
+ let project_utxo = |t: &TxOut| (t.value, t.script_pubkey.clone());
+ project_utxo(tx_a).cmp(&project_utxo(tx_b))
+ };
+
+ let custom_bip69_ordering = bdk_wallet::wallet::tx_builder::TxOrdering::Custom {
+ input_sort: Arc::new(bip69_txin_cmp),
+ output_sort: Arc::new(bip69_txout_cmp),
+ };
+
let mut builder = wallet.build_tx();
builder
.add_recipient(addr.script_pubkey(), Amount::from_sat(30_000))
.add_recipient(addr.script_pubkey(), Amount::from_sat(10_000))
- .ordering(bdk_wallet::wallet::tx_builder::TxOrdering::Bip69Lexicographic);
+ .ordering(custom_bip69_ordering);
+
let psbt = builder.finish().unwrap();
let fee = check_fee!(wallet, psbt);