From 7d6687451a5b49c7d779b9441cc88a138d104fea Mon Sep 17 00:00:00 2001 From: Riccardo Casatta Date: Fri, 9 Aug 2019 17:03:12 +0200 Subject: [PATCH] use BTreeMap instead of HashMap to always serialize the same (#310) * use BTreeMap instead of HashMap to always serialize the same * fix rust 1.22 error * psbt fuzz roundtrip * psbt fuzz roundtrip on our ser --- a | 0 fuzz/fuzz_targets/deserialize_psbt.rs | 11 ++++++++++- src/util/psbt/map/global.rs | 6 +++--- src/util/psbt/map/input.rs | 8 ++++---- src/util/psbt/map/output.rs | 6 +++--- src/util/psbt/mod.rs | 19 +++++++++++++------ src/util/psbt/raw.rs | 2 +- 7 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 a diff --git a/a b/a new file mode 100644 index 00000000..e69de29b diff --git a/fuzz/fuzz_targets/deserialize_psbt.rs b/fuzz/fuzz_targets/deserialize_psbt.rs index 9021fc3b..d19563b1 100644 --- a/fuzz/fuzz_targets/deserialize_psbt.rs +++ b/fuzz/fuzz_targets/deserialize_psbt.rs @@ -1,7 +1,16 @@ extern crate bitcoin; fn do_test(data: &[u8]) { - let _: Result = bitcoin::consensus::encode::deserialize(data); + let psbt: Result = bitcoin::consensus::encode::deserialize(data); + match psbt { + Err(_) => {}, + Ok(psbt) => { + let ser = bitcoin::consensus::encode::serialize(&psbt); + let deser: bitcoin::util::psbt::PartiallySignedTransaction = bitcoin::consensus::encode::deserialize(&ser).unwrap(); + // Since the fuzz data could order psbt fields differently, we compare to our deser/ser instead of data + assert_eq!(ser, bitcoin::consensus::encode::serialize(&deser)); + } + } } #[cfg(feature = "afl")] diff --git a/src/util/psbt/map/global.rs b/src/util/psbt/map/global.rs index 81fc3f57..b34b4114 100644 --- a/src/util/psbt/map/global.rs +++ b/src/util/psbt/map/global.rs @@ -12,7 +12,7 @@ // If not, see . // -use std::collections::HashMap; +use std::collections::BTreeMap; use std::io::{self, Cursor}; use blockdata::transaction::Transaction; @@ -29,7 +29,7 @@ pub struct Global { /// empty. pub unsigned_tx: Transaction, /// Unknown global key-value pairs. - pub unknown: HashMap>, + pub unknown: BTreeMap>, } impl Global { @@ -124,7 +124,7 @@ impl Decodable for Global { fn consensus_decode(mut d: D) -> Result { let mut tx: Option = None; - let mut unknowns: HashMap> = Default::default(); + let mut unknowns: BTreeMap> = Default::default(); loop { match raw::Pair::consensus_decode(&mut d) { diff --git a/src/util/psbt/map/input.rs b/src/util/psbt/map/input.rs index b685ff73..32f19bc5 100644 --- a/src/util/psbt/map/input.rs +++ b/src/util/psbt/map/input.rs @@ -12,7 +12,7 @@ // If not, see . // -use std::collections::HashMap; +use std::collections::BTreeMap; use blockdata::script::Script; use blockdata::transaction::{SigHashType, Transaction, TxOut}; @@ -38,7 +38,7 @@ pub struct Input { pub witness_utxo: Option, /// A map from public keys to their corresponding signature as would be /// pushed to the stack from a scriptSig or witness. - pub partial_sigs: HashMap>, + pub partial_sigs: BTreeMap>, /// The sighash type to be used for this input. Signatures for this input /// must use the sighash type. pub sighash_type: Option, @@ -48,7 +48,7 @@ pub struct Input { pub witness_script: Option