use bitcoin::blockdata::transaction::{TxIn, TxOut};
+use bitcoin_hashes::sha256d::Hash as Sha256dHash;
use std::cmp::Ordering;
-pub fn sort_outputs<T>(outputs: &mut Vec<(TxOut, T)>) {
+pub fn sort_outputs<T, C : Fn(&T, &T) -> Ordering>(outputs: &mut Vec<(TxOut, T)>, tie_breaker: C) {
outputs.sort_unstable_by(|a, b| {
- if a.0.value < b.0.value {
- Ordering::Less
- } else if b.0.value < a.0.value {
- Ordering::Greater
- } else if a.0.script_pubkey[..] < b.0.script_pubkey[..] {
- Ordering::Less
- } else if b.0.script_pubkey[..] < a.0.script_pubkey[..] {
- Ordering::Greater
- } else {
- Ordering::Equal
- }
+ a.0.value.cmp(&b.0.value).then_with(|| {
+ a.0.script_pubkey[..].cmp(&b.0.script_pubkey[..]).then_with(|| {
+ tie_breaker(&a.1, &b.1)
+ })
+ })
});
}
+fn cmp(a: &Sha256dHash, b: &Sha256dHash) -> Ordering {
+ use bitcoin_hashes::Hash;
+
+ let av = a.into_inner();
+ let bv = b.into_inner();
+ for i in (0..32).rev() {
+ let cmp = av[i].cmp(&bv[i]);
+ if cmp != Ordering::Equal {
+ return cmp;
+ }
+ }
+ Ordering::Equal
+}
+
pub fn sort_inputs<T>(inputs: &mut Vec<(TxIn, T)>) {
inputs.sort_unstable_by(|a, b| {
- if a.0.previous_output.txid.into_le() < b.0.previous_output.txid.into_le() {
- Ordering::Less
- } else if b.0.previous_output.txid.into_le() < a.0.previous_output.txid.into_le() {
- Ordering::Greater
- } else if a.0.previous_output.vout < b.0.previous_output.vout {
- Ordering::Less
- } else if b.0.previous_output.vout < a.0.previous_output.vout {
- Ordering::Greater
- } else {
- Ordering::Equal
- }
+ cmp( &a.0.previous_output.txid, &b.0.previous_output.txid).then(
+ a.0.previous_output.vout.cmp(&b.0.previous_output.vout))
});
}
use bitcoin::blockdata::script::{Script, Builder};
use bitcoin::blockdata::transaction::{TxOut, OutPoint};
- use bitcoin::util::hash::Sha256dHash;
+ use bitcoin_hashes::sha256d::Hash as Sha256dHash;
+ use bitcoin_hashes::hex::FromHex;
use hex::decode;
let txout2_ = txout2.clone();
let mut outputs = vec![(txout1, "ignore"), (txout2, "ignore")];
- sort_outputs(&mut outputs);
+ sort_outputs(&mut outputs, |_, _| { unreachable!(); });
assert_eq!(
&outputs,
let txout2_ = txout2.clone();
let mut outputs = vec![(txout1, "ignore"), (txout2, "ignore")];
- sort_outputs(&mut outputs);
+ sort_outputs(&mut outputs, |_, _| { unreachable!(); });
assert_eq!(
&outputs,
let txout2_ = txout2.clone();
let mut outputs = vec![(txout1, "ignore"), (txout2, "ignore")];
- sort_outputs(&mut outputs);
+ sort_outputs(&mut outputs, |_, _| { unreachable!(); });
assert_eq!(&outputs, &vec![(txout1_, "ignore"), (txout2_, "ignore")]);
}
outputs.reverse(); // prep it
// actually do the work!
- sort_outputs(&mut outputs);
+ sort_outputs(&mut outputs, |_, _| { unreachable!(); });
assert_eq!(outputs, expected);
}