]> Untitled Git - bdk/commitdiff
refactor(test): move tx test utils to testenv
authorVihiga Tyonum <withtvpeter@gmail.com>
Sat, 14 Sep 2024 20:52:50 +0000 (21:52 +0100)
committerVihiga Tyonum <withtvpeter@gmail.com>
Thu, 3 Oct 2024 12:12:32 +0000 (13:12 +0100)
- add `utils` mod to testenv crate to keep all
utilities moved from `crates/chain/test/common`
- replace all test tx macros in `chain` crate with
import from `testenv` crate
    - tests/test_indexed_tx_graph
    - tests/test_keychain_txout_index
    - tests/test_local_chain
    - tests/test_tx_graph
    - tests/test_tx_graph_conflicts
- deleted all moved macros and functions in
`crates/chain/test/common/mod`
- replace `bitcoin` external crate with
`bd_chain::bitcoin`
- move `DESCRIPTORS` sample array to `utils` for
other crates to use
- rename h! macro to hash! for clarity
- rename localchain! macro parameter from
'block_hash' to 'hash'

[Ticket: #1602]

13 files changed:
crates/chain/Cargo.toml
crates/chain/tests/common/mod.rs
crates/chain/tests/common/tx_template.rs
crates/chain/tests/test_indexed_tx_graph.rs
crates/chain/tests/test_keychain_txout_index.rs
crates/chain/tests/test_local_chain.rs
crates/chain/tests/test_tx_graph.rs
crates/chain/tests/test_tx_graph_conflicts.rs
crates/core/Cargo.toml
crates/core/tests/common.rs [deleted file]
crates/core/tests/test_checkpoint.rs
crates/testenv/src/lib.rs
crates/testenv/src/utils.rs [new file with mode: 0644]

index 9085b5ec88827aa3619b47f98fb63cc815e9105e..cfdaa1cab8f1a5c6dbd8dc66ec01daf0aba4390d 100644 (file)
@@ -28,6 +28,8 @@ serde_json = { version = "1", optional = true }
 [dev-dependencies]
 rand = "0.8"
 proptest = "1.2.0"
+bdk_testenv = { path = "../testenv", default-features = false }
+
 
 [features]
 default = ["std", "miniscript"]
index 3fad37f93ce8843450ce3fa61473cc9b823b565c..cb3ee66f37a0e6b36b8fb9599e3b175c34432d4c 100644 (file)
@@ -3,87 +3,3 @@
 mod tx_template;
 #[allow(unused_imports)]
 pub use tx_template::*;
-
-#[allow(unused_macros)]
-macro_rules! block_id {
-    ($height:expr, $hash:literal) => {{
-        bdk_chain::BlockId {
-            height: $height,
-            hash: bitcoin::hashes::Hash::hash($hash.as_bytes()),
-        }
-    }};
-}
-
-#[allow(unused_macros)]
-macro_rules! h {
-    ($index:literal) => {{
-        bitcoin::hashes::Hash::hash($index.as_bytes())
-    }};
-}
-
-#[allow(unused_macros)]
-macro_rules! local_chain {
-    [ $(($height:expr, $block_hash:expr)), * ] => {{
-        #[allow(unused_mut)]
-        bdk_chain::local_chain::LocalChain::from_blocks([$(($height, $block_hash).into()),*].into_iter().collect())
-            .expect("chain must have genesis block")
-    }};
-}
-
-#[allow(unused_macros)]
-macro_rules! chain_update {
-    [ $(($height:expr, $hash:expr)), * ] => {{
-        #[allow(unused_mut)]
-        bdk_chain::local_chain::LocalChain::from_blocks([$(($height, $hash).into()),*].into_iter().collect())
-            .expect("chain must have genesis block")
-            .tip()
-    }};
-}
-
-#[allow(unused_macros)]
-macro_rules! changeset {
-    (checkpoints: $($tail:tt)*) => { changeset!(index: TxHeight, checkpoints: $($tail)*) };
-    (
-        index: $ind:ty,
-        checkpoints: [ $(( $height:expr, $cp_to:expr )),* ]
-        $(,txids: [ $(( $txid:expr, $tx_to:expr )),* ])?
-    ) => {{
-        use bdk_chain::collections::BTreeMap;
-
-        #[allow(unused_mut)]
-        bdk_chain::sparse_chain::ChangeSet::<$ind> {
-            checkpoints: {
-                let mut changes = BTreeMap::default();
-                $(changes.insert($height, $cp_to);)*
-                changes
-            },
-            txids: {
-                let mut changes = BTreeMap::default();
-                $($(changes.insert($txid, $tx_to.map(|h: TxHeight| h.into()));)*)?
-                changes
-            }
-        }
-    }};
-}
-
-#[allow(unused)]
-pub fn new_tx(lt: u32) -> bitcoin::Transaction {
-    bitcoin::Transaction {
-        version: bitcoin::transaction::Version::non_standard(0x00),
-        lock_time: bitcoin::absolute::LockTime::from_consensus(lt),
-        input: vec![],
-        output: vec![],
-    }
-}
-
-#[allow(unused)]
-pub const DESCRIPTORS: [&str; 7] = [
-    "tr([73c5da0a/86'/0'/0']xprv9xgqHN7yz9MwCkxsBPN5qetuNdQSUttZNKw1dcYTV4mkaAFiBVGQziHs3NRSWMkCzvgjEe3n9xV8oYywvM8at9yRqyaZVz6TYYhX98VjsUk/0/*)",
-    "tr([73c5da0a/86'/0'/0']xprv9xgqHN7yz9MwCkxsBPN5qetuNdQSUttZNKw1dcYTV4mkaAFiBVGQziHs3NRSWMkCzvgjEe3n9xV8oYywvM8at9yRqyaZVz6TYYhX98VjsUk/1/*)",
-    "wpkh([73c5da0a/86'/0'/0']xprv9xgqHN7yz9MwCkxsBPN5qetuNdQSUttZNKw1dcYTV4mkaAFiBVGQziHs3NRSWMkCzvgjEe3n9xV8oYywvM8at9yRqyaZVz6TYYhX98VjsUk/1/0/*)",
-    "tr(tprv8ZgxMBicQKsPd3krDUsBAmtnRsK3rb8u5yi1zhQgMhF1tR8MW7xfE4rnrbbsrbPR52e7rKapu6ztw1jXveJSCGHEriUGZV7mCe88duLp5pj/86'/1'/0'/0/*)",
-    "tr(tprv8ZgxMBicQKsPd3krDUsBAmtnRsK3rb8u5yi1zhQgMhF1tR8MW7xfE4rnrbbsrbPR52e7rKapu6ztw1jXveJSCGHEriUGZV7mCe88duLp5pj/86'/1'/0'/1/*)",
-    "wpkh(xprv9s21ZrQH143K4EXURwMHuLS469fFzZyXk7UUpdKfQwhoHcAiYTakpe8pMU2RiEdvrU9McyuE7YDoKcXkoAwEGoK53WBDnKKv2zZbb9BzttX/1/0/*)",
-    // non-wildcard
-    "wpkh([73c5da0a/86'/0'/0']xprv9xgqHN7yz9MwCkxsBPN5qetuNdQSUttZNKw1dcYTV4mkaAFiBVGQziHs3NRSWMkCzvgjEe3n9xV8oYywvM8at9yRqyaZVz6TYYhX98VjsUk/1/0)",
-];
index c7ce392e584c8b310e88d035b775b6a84b630d10..6ece64cbb9697de5ebca362fa82f58271c3a9f3e 100644 (file)
@@ -1,5 +1,6 @@
 #![cfg(feature = "miniscript")]
 
+use bdk_testenv::utils::DESCRIPTORS;
 use rand::distributions::{Alphanumeric, DistString};
 use std::collections::HashMap;
 
@@ -55,7 +56,7 @@ pub fn init_graph<'a, A: Anchor + Clone + 'a>(
     tx_templates: impl IntoIterator<Item = &'a TxTemplate<'a, A>>,
 ) -> (TxGraph<A>, SpkTxOutIndex<u32>, HashMap<&'a str, Txid>) {
     let (descriptor, _) =
-        Descriptor::parse_descriptor(&Secp256k1::signing_only(), super::DESCRIPTORS[2]).unwrap();
+        Descriptor::parse_descriptor(&Secp256k1::signing_only(), DESCRIPTORS[2]).unwrap();
     let mut graph = TxGraph::<A>::default();
     let mut spk_index = SpkTxOutIndex::default();
     (0..10).for_each(|index| {
index 1fbbcd0df56ec7565625095bf92a40f57cb4358e..a8d17ca91094daf26ae6cc7214e2e46b2678e170 100644 (file)
@@ -5,13 +5,16 @@ mod common;
 
 use std::{collections::BTreeSet, sync::Arc};
 
-use crate::common::DESCRIPTORS;
 use bdk_chain::{
     indexed_tx_graph::{self, IndexedTxGraph},
     indexer::keychain_txout::KeychainTxOutIndex,
     local_chain::LocalChain,
     tx_graph, Balance, ChainPosition, ConfirmationBlockTime, DescriptorExt,
 };
+use bdk_testenv::{
+    block_id, hash,
+    utils::{new_tx, DESCRIPTORS},
+};
 use bitcoin::{secp256k1::Secp256k1, Amount, OutPoint, ScriptBuf, Transaction, TxIn, TxOut};
 use miniscript::Descriptor;
 
@@ -49,7 +52,7 @@ fn insert_relevant_txs() {
                 script_pubkey: spk_1,
             },
         ],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     let tx_b = Transaction {
@@ -57,7 +60,7 @@ fn insert_relevant_txs() {
             previous_output: OutPoint::new(tx_a.compute_txid(), 0),
             ..Default::default()
         }],
-        ..common::new_tx(1)
+        ..new_tx(1)
     };
 
     let tx_c = Transaction {
@@ -65,7 +68,7 @@ fn insert_relevant_txs() {
             previous_output: OutPoint::new(tx_a.compute_txid(), 1),
             ..Default::default()
         }],
-        ..common::new_tx(2)
+        ..new_tx(2)
     };
 
     let txs = [tx_c, tx_b, tx_a];
@@ -126,15 +129,16 @@ fn insert_relevant_txs() {
 #[test]
 fn test_list_owned_txouts() {
     // Create Local chains
-    let local_chain = LocalChain::from_blocks((0..150).map(|i| (i as u32, h!("random"))).collect())
-        .expect("must have genesis hash");
+    let local_chain =
+        LocalChain::from_blocks((0..150).map(|i| (i as u32, hash!("random"))).collect())
+            .expect("must have genesis hash");
 
     // Initiate IndexedTxGraph
 
     let (desc_1, _) =
-        Descriptor::parse_descriptor(&Secp256k1::signing_only(), common::DESCRIPTORS[2]).unwrap();
+        Descriptor::parse_descriptor(&Secp256k1::signing_only(), DESCRIPTORS[2]).unwrap();
     let (desc_2, _) =
-        Descriptor::parse_descriptor(&Secp256k1::signing_only(), common::DESCRIPTORS[3]).unwrap();
+        Descriptor::parse_descriptor(&Secp256k1::signing_only(), DESCRIPTORS[3]).unwrap();
 
     let mut graph = IndexedTxGraph::<ConfirmationBlockTime, KeychainTxOutIndex<String>>::new(
         KeychainTxOutIndex::new(10),
@@ -187,7 +191,7 @@ fn test_list_owned_txouts() {
             value: Amount::from_sat(70000),
             script_pubkey: trusted_spks[0].to_owned(),
         }],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx2 is an incoming transaction received at untrusted keychain at block 1.
@@ -196,7 +200,7 @@ fn test_list_owned_txouts() {
             value: Amount::from_sat(30000),
             script_pubkey: untrusted_spks[0].to_owned(),
         }],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx3 spends tx2 and gives a change back in trusted keychain. Confirmed at Block 2.
@@ -209,7 +213,7 @@ fn test_list_owned_txouts() {
             value: Amount::from_sat(10000),
             script_pubkey: trusted_spks[1].to_owned(),
         }],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx4 is an external transaction receiving at untrusted keychain, unconfirmed.
@@ -218,7 +222,7 @@ fn test_list_owned_txouts() {
             value: Amount::from_sat(20000),
             script_pubkey: untrusted_spks[1].to_owned(),
         }],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx5 is an external transaction receiving at trusted keychain, unconfirmed.
@@ -227,11 +231,11 @@ fn test_list_owned_txouts() {
             value: Amount::from_sat(15000),
             script_pubkey: trusted_spks[2].to_owned(),
         }],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx6 is an unrelated transaction confirmed at 3.
-    let tx6 = common::new_tx(0);
+    let tx6 = new_tx(0);
 
     // Insert transactions into graph with respective anchors
     // Insert unconfirmed txs with a last_seen timestamp
@@ -597,7 +601,7 @@ fn test_get_chain_position() {
                     value: Amount::ONE_BTC,
                     script_pubkey: spk.clone(),
                 }],
-                ..common::new_tx(0)
+                ..new_tx(0)
             },
             anchor: None,
             last_seen: None,
@@ -610,7 +614,7 @@ fn test_get_chain_position() {
                     value: Amount::ONE_BTC,
                     script_pubkey: spk.clone(),
                 }],
-                ..common::new_tx(1)
+                ..new_tx(1)
             },
             anchor: None,
             last_seen: Some(2),
@@ -623,7 +627,7 @@ fn test_get_chain_position() {
                     value: Amount::ONE_BTC,
                     script_pubkey: spk.clone(),
                 }],
-                ..common::new_tx(2)
+                ..new_tx(2)
             },
             anchor: Some(blocks[1]),
             last_seen: None,
@@ -636,7 +640,7 @@ fn test_get_chain_position() {
                     value: Amount::ONE_BTC,
                     script_pubkey: spk.clone(),
                 }],
-                ..common::new_tx(3)
+                ..new_tx(3)
             },
             anchor: Some(block_id!(2, "B'")),
             last_seen: Some(2),
@@ -649,7 +653,7 @@ fn test_get_chain_position() {
                     value: Amount::ONE_BTC,
                     script_pubkey: spk.clone(),
                 }],
-                ..common::new_tx(4)
+                ..new_tx(4)
             },
             anchor: Some(block_id!(2, "B'")),
             last_seen: None,
index 267ee2e9969817fbc32bd81dc224a3448d2791f5..9d80d54604f5325f9ad0ccbe2fd2ec8ea2a159ce 100644 (file)
@@ -1,18 +1,17 @@
 #![cfg(feature = "miniscript")]
 
-#[macro_use]
-mod common;
 use bdk_chain::{
     collections::BTreeMap,
     indexer::keychain_txout::{ChangeSet, KeychainTxOutIndex},
     DescriptorExt, DescriptorId, Indexer, Merge,
 };
-
+use bdk_testenv::{
+    hash,
+    utils::{new_tx, DESCRIPTORS},
+};
 use bitcoin::{secp256k1::Secp256k1, Amount, OutPoint, ScriptBuf, Transaction, TxOut};
 use miniscript::{Descriptor, DescriptorPublicKey};
 
-use crate::common::DESCRIPTORS;
-
 #[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
 enum TestKeychain {
     External,
@@ -253,7 +252,7 @@ fn test_lookahead() {
                     value: Amount::from_sat(10_000),
                 },
             ],
-            ..common::new_tx(external_index)
+            ..new_tx(external_index)
         };
         assert_eq!(txout_index.index_tx(&tx), ChangeSet::default());
         assert_eq!(
@@ -305,7 +304,7 @@ fn test_scan_with_lookahead() {
         .collect();
 
     for (&spk_i, spk) in &spks {
-        let op = OutPoint::new(h!("fake tx"), spk_i);
+        let op = OutPoint::new(hash!("fake tx"), spk_i);
         let txout = TxOut {
             script_pubkey: spk.clone(),
             value: Amount::ZERO,
@@ -331,7 +330,7 @@ fn test_scan_with_lookahead() {
         .at_derivation_index(41)
         .unwrap()
         .script_pubkey();
-    let op = OutPoint::new(h!("fake tx"), 41);
+    let op = OutPoint::new(hash!("fake tx"), 41);
     let txout = TxOut {
         script_pubkey: spk_41,
         value: Amount::ZERO,
@@ -656,7 +655,7 @@ fn reassigning_keychain_to_a_new_descriptor_should_error() {
 #[test]
 fn when_querying_over_a_range_of_keychains_the_utxos_should_show_up() {
     let mut indexer = KeychainTxOutIndex::<usize>::new(0);
-    let mut tx = common::new_tx(0);
+    let mut tx = new_tx(0);
 
     for (i, descriptor) in DESCRIPTORS.iter().enumerate() {
         let descriptor = parse_descriptor(descriptor);
index 29686564db29fbd41eae420f2a2f4be28ff986d5..e8515c868738c98372e20c5a1c186462606352f9 100644 (file)
@@ -9,12 +9,10 @@ use bdk_chain::{
     },
     BlockId,
 };
+use bdk_testenv::{chain_update, hash, local_chain};
 use bitcoin::{block::Header, hashes::Hash, BlockHash};
 use proptest::prelude::*;
 
-#[macro_use]
-mod common;
-
 #[derive(Debug)]
 struct TestLocalChain<'a> {
     name: &'static str,
@@ -78,45 +76,45 @@ fn update_local_chain() {
     [
         TestLocalChain {
             name: "add first tip",
-            chain: local_chain![(0, h!("A"))],
-            update: chain_update![(0, h!("A"))],
+            chain: local_chain![(0, hash!("A"))],
+            update: chain_update![(0, hash!("A"))],
             exp: ExpectedResult::Ok {
                 changeset: &[],
-                init_changeset: &[(0, Some(h!("A")))],
+                init_changeset: &[(0, Some(hash!("A")))],
             },
         },
         TestLocalChain {
             name: "add second tip",
-            chain: local_chain![(0, h!("A"))],
-            update: chain_update![(0, h!("A")), (1, h!("B"))],
+            chain: local_chain![(0, hash!("A"))],
+            update: chain_update![(0, hash!("A")), (1, hash!("B"))],
             exp: ExpectedResult::Ok {
-                changeset: &[(1, Some(h!("B")))],
-                init_changeset: &[(0, Some(h!("A"))), (1, Some(h!("B")))],
+                changeset: &[(1, Some(hash!("B")))],
+                init_changeset: &[(0, Some(hash!("A"))), (1, Some(hash!("B")))],
             },
         },
         TestLocalChain {
             name: "two disjoint chains cannot merge",
-            chain: local_chain![(0, h!("_")), (1, h!("A"))],
-            update: chain_update![(0, h!("_")), (2, h!("B"))],
+            chain: local_chain![(0, hash!("_")), (1, hash!("A"))],
+            update: chain_update![(0, hash!("_")), (2, hash!("B"))],
             exp: ExpectedResult::Err(CannotConnectError {
                 try_include_height: 1,
             }),
         },
         TestLocalChain {
             name: "two disjoint chains cannot merge (existing chain longer)",
-            chain: local_chain![(0, h!("_")), (2, h!("A"))],
-            update: chain_update![(0, h!("_")), (1, h!("B"))],
+            chain: local_chain![(0, hash!("_")), (2, hash!("A"))],
+            update: chain_update![(0, hash!("_")), (1, hash!("B"))],
             exp: ExpectedResult::Err(CannotConnectError {
                 try_include_height: 2,
             }),
         },
         TestLocalChain {
             name: "duplicate chains should merge",
-            chain: local_chain![(0, h!("A"))],
-            update: chain_update![(0, h!("A"))],
+            chain: local_chain![(0, hash!("A"))],
+            update: chain_update![(0, hash!("A"))],
             exp: ExpectedResult::Ok {
                 changeset: &[],
-                init_changeset: &[(0, Some(h!("A")))],
+                init_changeset: &[(0, Some(hash!("A")))],
             },
         },
         // Introduce an older checkpoint (B)
@@ -125,11 +123,11 @@ fn update_local_chain() {
         // update | _   B   C
         TestLocalChain {
             name: "can introduce older checkpoint",
-            chain: local_chain![(0, h!("_")), (2, h!("C")), (3, h!("D"))],
-            update: chain_update![(0, h!("_")), (1, h!("B")), (2, h!("C"))],
+            chain: local_chain![(0, hash!("_")), (2, hash!("C")), (3, hash!("D"))],
+            update: chain_update![(0, hash!("_")), (1, hash!("B")), (2, hash!("C"))],
             exp: ExpectedResult::Ok {
-                changeset: &[(1, Some(h!("B")))],
-                init_changeset: &[(0, Some(h!("_"))), (1, Some(h!("B"))), (2, Some(h!("C"))), (3, Some(h!("D")))],
+                changeset: &[(1, Some(hash!("B")))],
+                init_changeset: &[(0, Some(hash!("_"))), (1, Some(hash!("B"))), (2, Some(hash!("C"))), (3, Some(hash!("D")))],
             },
         },
         // Introduce an older checkpoint (A) that is not directly behind PoA
@@ -138,11 +136,11 @@ fn update_local_chain() {
         // update | _   A       C
         TestLocalChain {
             name: "can introduce older checkpoint 2",
-            chain: local_chain![(0, h!("_")), (3, h!("B")), (4, h!("C"))],
-            update: chain_update![(0, h!("_")), (2, h!("A")), (4, h!("C"))],
+            chain: local_chain![(0, hash!("_")), (3, hash!("B")), (4, hash!("C"))],
+            update: chain_update![(0, hash!("_")), (2, hash!("A")), (4, hash!("C"))],
             exp: ExpectedResult::Ok {
-                changeset: &[(2, Some(h!("A")))],
-                init_changeset: &[(0, Some(h!("_"))), (2, Some(h!("A"))), (3, Some(h!("B"))), (4, Some(h!("C")))],
+                changeset: &[(2, Some(hash!("A")))],
+                init_changeset: &[(0, Some(hash!("_"))), (2, Some(hash!("A"))), (3, Some(hash!("B"))), (4, Some(hash!("C")))],
             }
         },
         // Introduce an older checkpoint (B) that is not the oldest checkpoint
@@ -151,11 +149,11 @@ fn update_local_chain() {
         // update | _       B   C
         TestLocalChain {
             name: "can introduce older checkpoint 3",
-            chain: local_chain![(0, h!("_")), (1, h!("A")), (3, h!("C"))],
-            update: chain_update![(0, h!("_")), (2, h!("B")), (3, h!("C"))],
+            chain: local_chain![(0, hash!("_")), (1, hash!("A")), (3, hash!("C"))],
+            update: chain_update![(0, hash!("_")), (2, hash!("B")), (3, hash!("C"))],
             exp: ExpectedResult::Ok {
-                changeset: &[(2, Some(h!("B")))],
-                init_changeset: &[(0, Some(h!("_"))), (1, Some(h!("A"))), (2, Some(h!("B"))), (3, Some(h!("C")))],
+                changeset: &[(2, Some(hash!("B")))],
+                init_changeset: &[(0, Some(hash!("_"))), (1, Some(hash!("A"))), (2, Some(hash!("B"))), (3, Some(hash!("C")))],
             }
         },
         // Introduce two older checkpoints below the PoA
@@ -164,20 +162,20 @@ fn update_local_chain() {
         // update | _   A   B   C
         TestLocalChain {
             name: "introduce two older checkpoints below PoA",
-            chain: local_chain![(0, h!("_")), (3, h!("C"))],
-            update: chain_update![(0, h!("_")), (1, h!("A")), (2, h!("B")), (3, h!("C"))],
+            chain: local_chain![(0, hash!("_")), (3, hash!("C"))],
+            update: chain_update![(0, hash!("_")), (1, hash!("A")), (2, hash!("B")), (3, hash!("C"))],
             exp: ExpectedResult::Ok {
-                changeset: &[(1, Some(h!("A"))), (2, Some(h!("B")))],
-                init_changeset: &[(0, Some(h!("_"))), (1, Some(h!("A"))), (2, Some(h!("B"))), (3, Some(h!("C")))],
+                changeset: &[(1, Some(hash!("A"))), (2, Some(hash!("B")))],
+                init_changeset: &[(0, Some(hash!("_"))), (1, Some(hash!("A"))), (2, Some(hash!("B"))), (3, Some(hash!("C")))],
             },
         },
         TestLocalChain {
             name: "fix blockhash before agreement point",
-            chain: local_chain![(0, h!("im-wrong")), (1, h!("we-agree"))],
-            update: chain_update![(0, h!("fix")), (1, h!("we-agree"))],
+            chain: local_chain![(0, hash!("im-wrong")), (1, hash!("we-agree"))],
+            update: chain_update![(0, hash!("fix")), (1, hash!("we-agree"))],
             exp: ExpectedResult::Ok {
-                changeset: &[(0, Some(h!("fix")))],
-                init_changeset: &[(0, Some(h!("fix"))), (1, Some(h!("we-agree")))],
+                changeset: &[(0, Some(hash!("fix")))],
+                init_changeset: &[(0, Some(hash!("fix"))), (1, Some(hash!("we-agree")))],
             },
         },
         // B and C are in both chain and update
@@ -187,16 +185,16 @@ fn update_local_chain() {
         // This should succeed with the point of agreement being C and A should be added in addition.
         TestLocalChain {
             name: "two points of agreement",
-            chain: local_chain![(0, h!("_")), (2, h!("B")), (3, h!("C"))],
-            update: chain_update![(0, h!("_")), (1, h!("A")), (2, h!("B")), (3, h!("C")), (4, h!("D"))],
+            chain: local_chain![(0, hash!("_")), (2, hash!("B")), (3, hash!("C"))],
+            update: chain_update![(0, hash!("_")), (1, hash!("A")), (2, hash!("B")), (3, hash!("C")), (4, hash!("D"))],
             exp: ExpectedResult::Ok {
-                changeset: &[(1, Some(h!("A"))), (4, Some(h!("D")))],
+                changeset: &[(1, Some(hash!("A"))), (4, Some(hash!("D")))],
                 init_changeset: &[
-                    (0, Some(h!("_"))),
-                    (1, Some(h!("A"))),
-                    (2, Some(h!("B"))),
-                    (3, Some(h!("C"))),
-                    (4, Some(h!("D"))),
+                    (0, Some(hash!("_"))),
+                    (1, Some(hash!("A"))),
+                    (2, Some(hash!("B"))),
+                    (3, Some(hash!("C"))),
+                    (4, Some(hash!("D"))),
                 ],
             },
         },
@@ -207,8 +205,8 @@ fn update_local_chain() {
         // This should fail as we cannot figure out whether C & D are on the same chain
         TestLocalChain {
             name: "update and chain does not connect",
-            chain: local_chain![(0, h!("_")), (2, h!("B")), (3, h!("C"))],
-            update: chain_update![(0, h!("_")), (1, h!("A")), (2, h!("B")), (4, h!("D"))],
+            chain: local_chain![(0, hash!("_")), (2, hash!("B")), (3, hash!("C"))],
+            update: chain_update![(0, hash!("_")), (1, hash!("A")), (2, hash!("B")), (4, hash!("D"))],
             exp: ExpectedResult::Err(CannotConnectError {
                 try_include_height: 3,
             }),
@@ -220,20 +218,20 @@ fn update_local_chain() {
         // This should succeed and invalidate B,C and E with point of agreement being A.
         TestLocalChain {
             name: "transitive invalidation applies to checkpoints higher than invalidation",
-            chain: local_chain![(0, h!("_")), (2, h!("B")), (3, h!("C")), (5, h!("E"))],
-            update: chain_update![(0, h!("_")), (2, h!("B'")), (3, h!("C'")), (4, h!("D"))],
+            chain: local_chain![(0, hash!("_")), (2, hash!("B")), (3, hash!("C")), (5, hash!("E"))],
+            update: chain_update![(0, hash!("_")), (2, hash!("B'")), (3, hash!("C'")), (4, hash!("D"))],
             exp: ExpectedResult::Ok {
                 changeset: &[
-                    (2, Some(h!("B'"))),
-                    (3, Some(h!("C'"))),
-                    (4, Some(h!("D"))),
+                    (2, Some(hash!("B'"))),
+                    (3, Some(hash!("C'"))),
+                    (4, Some(hash!("D"))),
                     (5, None),
                 ],
                 init_changeset: &[
-                    (0, Some(h!("_"))),
-                    (2, Some(h!("B'"))),
-                    (3, Some(h!("C'"))),
-                    (4, Some(h!("D"))),
+                    (0, Some(hash!("_"))),
+                    (2, Some(hash!("B'"))),
+                    (3, Some(hash!("C'"))),
+                    (4, Some(hash!("D"))),
                 ],
             },
         },
@@ -244,20 +242,20 @@ fn update_local_chain() {
         // This should succeed and invalidate B, C and E with no point of agreement
         TestLocalChain {
             name: "transitive invalidation applies to checkpoints higher than invalidation no point of agreement",
-            chain: local_chain![(0, h!("_")), (1, h!("B")), (2, h!("C")), (4, h!("E"))],
-            update: chain_update![(0, h!("_")), (1, h!("B'")), (2, h!("C'")), (3, h!("D"))],
+            chain: local_chain![(0, hash!("_")), (1, hash!("B")), (2, hash!("C")), (4, hash!("E"))],
+            update: chain_update![(0, hash!("_")), (1, hash!("B'")), (2, hash!("C'")), (3, hash!("D"))],
             exp: ExpectedResult::Ok {
                 changeset: &[
-                    (1, Some(h!("B'"))),
-                    (2, Some(h!("C'"))),
-                    (3, Some(h!("D"))),
+                    (1, Some(hash!("B'"))),
+                    (2, Some(hash!("C'"))),
+                    (3, Some(hash!("D"))),
                     (4, None)
                 ],
                 init_changeset: &[
-                    (0, Some(h!("_"))),
-                    (1, Some(h!("B'"))),
-                    (2, Some(h!("C'"))),
-                    (3, Some(h!("D"))),
+                    (0, Some(hash!("_"))),
+                    (1, Some(hash!("B'"))),
+                    (2, Some(hash!("C'"))),
+                    (3, Some(hash!("D"))),
                 ],
             },
         },
@@ -269,8 +267,8 @@ fn update_local_chain() {
         // A was invalid.
         TestLocalChain {
             name: "invalidation but no connection",
-            chain: local_chain![(0, h!("_")), (1, h!("A")), (2, h!("B")), (3, h!("C")), (5, h!("E"))],
-            update: chain_update![(0, h!("_")), (2, h!("B'")), (3, h!("C'")), (4, h!("D"))],
+            chain: local_chain![(0, hash!("_")), (1, hash!("A")), (2, hash!("B")), (3, hash!("C")), (5, hash!("E"))],
+            update: chain_update![(0, hash!("_")), (2, hash!("B'")), (3, hash!("C'")), (4, hash!("D"))],
             exp: ExpectedResult::Err(CannotConnectError { try_include_height: 1 }),
         },
         // Introduce blocks between two points of agreement
@@ -279,20 +277,20 @@ fn update_local_chain() {
         // update | A       C       E   F
         TestLocalChain {
             name: "introduce blocks between two points of agreement",
-            chain: local_chain![(0, h!("A")), (1, h!("B")), (3, h!("D")), (4, h!("E"))],
-            update: chain_update![(0, h!("A")), (2, h!("C")), (4, h!("E")), (5, h!("F"))],
+            chain: local_chain![(0, hash!("A")), (1, hash!("B")), (3, hash!("D")), (4, hash!("E"))],
+            update: chain_update![(0, hash!("A")), (2, hash!("C")), (4, hash!("E")), (5, hash!("F"))],
             exp: ExpectedResult::Ok {
                 changeset: &[
-                    (2, Some(h!("C"))),
-                    (5, Some(h!("F"))),
+                    (2, Some(hash!("C"))),
+                    (5, Some(hash!("F"))),
                 ],
                 init_changeset: &[
-                    (0, Some(h!("A"))),
-                    (1, Some(h!("B"))),
-                    (2, Some(h!("C"))),
-                    (3, Some(h!("D"))),
-                    (4, Some(h!("E"))),
-                    (5, Some(h!("F"))),
+                    (0, Some(hash!("A"))),
+                    (1, Some(hash!("B"))),
+                    (2, Some(hash!("C"))),
+                    (3, Some(hash!("D"))),
+                    (4, Some(hash!("E"))),
+                    (5, Some(hash!("F"))),
                 ],
             },
         },
@@ -302,18 +300,18 @@ fn update_local_chain() {
         // update | A       C   D'
         TestLocalChain {
             name: "allow update that is shorter than original chain",
-            chain: local_chain![(0, h!("_")), (2, h!("C")), (3, h!("D")), (4, h!("E")), (5, h!("F"))],
-            update: chain_update![(0, h!("_")), (2, h!("C")), (3, h!("D'"))],
+            chain: local_chain![(0, hash!("_")), (2, hash!("C")), (3, hash!("D")), (4, hash!("E")), (5, hash!("F"))],
+            update: chain_update![(0, hash!("_")), (2, hash!("C")), (3, hash!("D'"))],
             exp: ExpectedResult::Ok {
                 changeset: &[
-                    (3, Some(h!("D'"))),
+                    (3, Some(hash!("D'"))),
                     (4, None),
                     (5, None),
                 ],
                 init_changeset: &[
-                    (0, Some(h!("_"))),
-                    (2, Some(h!("C"))),
-                    (3, Some(h!("D'"))),
+                    (0, Some(hash!("_"))),
+                    (2, Some(hash!("C"))),
+                    (3, Some(hash!("D'"))),
                 ],
             },
         },
@@ -333,38 +331,38 @@ fn local_chain_insert_block() {
 
     let test_cases = [
         TestCase {
-            original: local_chain![(0, h!("_"))],
-            insert: (5, h!("block5")),
-            expected_result: Ok([(5, Some(h!("block5")))].into()),
-            expected_final: local_chain![(0, h!("_")), (5, h!("block5"))],
+            original: local_chain![(0, hash!("_"))],
+            insert: (5, hash!("block5")),
+            expected_result: Ok([(5, Some(hash!("block5")))].into()),
+            expected_final: local_chain![(0, hash!("_")), (5, hash!("block5"))],
         },
         TestCase {
-            original: local_chain![(0, h!("_")), (3, h!("A"))],
-            insert: (4, h!("B")),
-            expected_result: Ok([(4, Some(h!("B")))].into()),
-            expected_final: local_chain![(0, h!("_")), (3, h!("A")), (4, h!("B"))],
+            original: local_chain![(0, hash!("_")), (3, hash!("A"))],
+            insert: (4, hash!("B")),
+            expected_result: Ok([(4, Some(hash!("B")))].into()),
+            expected_final: local_chain![(0, hash!("_")), (3, hash!("A")), (4, hash!("B"))],
         },
         TestCase {
-            original: local_chain![(0, h!("_")), (4, h!("B"))],
-            insert: (3, h!("A")),
-            expected_result: Ok([(3, Some(h!("A")))].into()),
-            expected_final: local_chain![(0, h!("_")), (3, h!("A")), (4, h!("B"))],
+            original: local_chain![(0, hash!("_")), (4, hash!("B"))],
+            insert: (3, hash!("A")),
+            expected_result: Ok([(3, Some(hash!("A")))].into()),
+            expected_final: local_chain![(0, hash!("_")), (3, hash!("A")), (4, hash!("B"))],
         },
         TestCase {
-            original: local_chain![(0, h!("_")), (2, h!("K"))],
-            insert: (2, h!("K")),
+            original: local_chain![(0, hash!("_")), (2, hash!("K"))],
+            insert: (2, hash!("K")),
             expected_result: Ok([].into()),
-            expected_final: local_chain![(0, h!("_")), (2, h!("K"))],
+            expected_final: local_chain![(0, hash!("_")), (2, hash!("K"))],
         },
         TestCase {
-            original: local_chain![(0, h!("_")), (2, h!("K"))],
-            insert: (2, h!("J")),
+            original: local_chain![(0, hash!("_")), (2, hash!("K"))],
+            insert: (2, hash!("J")),
             expected_result: Err(AlterCheckPointError {
                 height: 2,
-                original_hash: h!("K"),
-                update_hash: Some(h!("J")),
+                original_hash: hash!("K"),
+                update_hash: Some(hash!("J")),
             }),
-            expected_final: local_chain![(0, h!("_")), (2, h!("K"))],
+            expected_final: local_chain![(0, hash!("_")), (2, hash!("K"))],
         },
     ];
 
@@ -393,45 +391,50 @@ fn local_chain_disconnect_from() {
     let test_cases = [
         TestCase {
             name: "try_replace_genesis_should_fail",
-            original: local_chain![(0, h!("_"))],
-            disconnect_from: (0, h!("_")),
+            original: local_chain![(0, hash!("_"))],
+            disconnect_from: (0, hash!("_")),
             exp_result: Err(MissingGenesisError),
-            exp_final: local_chain![(0, h!("_"))],
+            exp_final: local_chain![(0, hash!("_"))],
         },
         TestCase {
             name: "try_replace_genesis_should_fail_2",
-            original: local_chain![(0, h!("_")), (2, h!("B")), (3, h!("C"))],
-            disconnect_from: (0, h!("_")),
+            original: local_chain![(0, hash!("_")), (2, hash!("B")), (3, hash!("C"))],
+            disconnect_from: (0, hash!("_")),
             exp_result: Err(MissingGenesisError),
-            exp_final: local_chain![(0, h!("_")), (2, h!("B")), (3, h!("C"))],
+            exp_final: local_chain![(0, hash!("_")), (2, hash!("B")), (3, hash!("C"))],
         },
         TestCase {
             name: "from_does_not_exist",
-            original: local_chain![(0, h!("_")), (3, h!("C"))],
-            disconnect_from: (2, h!("B")),
+            original: local_chain![(0, hash!("_")), (3, hash!("C"))],
+            disconnect_from: (2, hash!("B")),
             exp_result: Ok(ChangeSet::default()),
-            exp_final: local_chain![(0, h!("_")), (3, h!("C"))],
+            exp_final: local_chain![(0, hash!("_")), (3, hash!("C"))],
         },
         TestCase {
             name: "from_has_different_blockhash",
-            original: local_chain![(0, h!("_")), (2, h!("B"))],
-            disconnect_from: (2, h!("not_B")),
+            original: local_chain![(0, hash!("_")), (2, hash!("B"))],
+            disconnect_from: (2, hash!("not_B")),
             exp_result: Ok(ChangeSet::default()),
-            exp_final: local_chain![(0, h!("_")), (2, h!("B"))],
+            exp_final: local_chain![(0, hash!("_")), (2, hash!("B"))],
         },
         TestCase {
             name: "disconnect_one",
-            original: local_chain![(0, h!("_")), (2, h!("B"))],
-            disconnect_from: (2, h!("B")),
+            original: local_chain![(0, hash!("_")), (2, hash!("B"))],
+            disconnect_from: (2, hash!("B")),
             exp_result: Ok(ChangeSet::from_iter([(2, None)])),
-            exp_final: local_chain![(0, h!("_"))],
+            exp_final: local_chain![(0, hash!("_"))],
         },
         TestCase {
             name: "disconnect_three",
-            original: local_chain![(0, h!("_")), (2, h!("B")), (3, h!("C")), (4, h!("D"))],
-            disconnect_from: (2, h!("B")),
+            original: local_chain![
+                (0, hash!("_")),
+                (2, hash!("B")),
+                (3, hash!("C")),
+                (4, hash!("D"))
+            ],
+            disconnect_from: (2, hash!("B")),
             exp_result: Ok(ChangeSet::from_iter([(2, None), (3, None), (4, None)])),
-            exp_final: local_chain![(0, h!("_"))],
+            exp_final: local_chain![(0, hash!("_"))],
         },
     ];
 
@@ -462,18 +465,18 @@ fn checkpoint_from_block_ids() {
     let test_cases = [
         TestCase {
             name: "in_order",
-            blocks: &[(0, h!("A")), (1, h!("B")), (3, h!("D"))],
+            blocks: &[(0, hash!("A")), (1, hash!("B")), (3, hash!("D"))],
             exp_result: Ok(()),
         },
         TestCase {
             name: "with_duplicates",
-            blocks: &[(1, h!("B")), (2, h!("C")), (2, h!("C'"))],
-            exp_result: Err(Some((2, h!("C")))),
+            blocks: &[(1, hash!("B")), (2, hash!("C")), (2, hash!("C'"))],
+            exp_result: Err(Some((2, hash!("C")))),
         },
         TestCase {
             name: "not_in_order",
-            blocks: &[(1, h!("B")), (3, h!("D")), (2, h!("C"))],
-            exp_result: Err(Some((3, h!("D")))),
+            blocks: &[(1, hash!("B")), (3, hash!("D")), (2, hash!("C"))],
+            exp_result: Err(Some((3, hash!("D")))),
         },
         TestCase {
             name: "empty",
@@ -482,7 +485,7 @@ fn checkpoint_from_block_ids() {
         },
         TestCase {
             name: "single",
-            blocks: &[(21, h!("million"))],
+            blocks: &[(21, hash!("million"))],
             exp_result: Ok(()),
         },
     ];
@@ -543,11 +546,11 @@ fn checkpoint_query() {
 
     let test_cases = [
         TestCase {
-            chain: local_chain![(0, h!("_")), (1, h!("A"))],
+            chain: local_chain![(0, hash!("_")), (1, hash!("A"))],
             query_range: (0, 2),
         },
         TestCase {
-            chain: local_chain![(0, h!("_")), (2, h!("B")), (3, h!("C"))],
+            chain: local_chain![(0, hash!("_")), (2, hash!("B")), (3, hash!("C"))],
             query_range: (0, 3),
         },
     ];
@@ -592,38 +595,48 @@ fn checkpoint_insert() {
     let test_cases = [
         TestCase {
             name: "insert_above_tip",
-            chain: &[(1, h!("a")), (2, h!("b"))],
-            to_insert: (4, h!("d")),
-            exp_final_chain: &[(1, h!("a")), (2, h!("b")), (4, h!("d"))],
+            chain: &[(1, hash!("a")), (2, hash!("b"))],
+            to_insert: (4, hash!("d")),
+            exp_final_chain: &[(1, hash!("a")), (2, hash!("b")), (4, hash!("d"))],
         },
         TestCase {
             name: "insert_already_exists_expect_no_change",
-            chain: &[(1, h!("a")), (2, h!("b")), (3, h!("c"))],
-            to_insert: (2, h!("b")),
-            exp_final_chain: &[(1, h!("a")), (2, h!("b")), (3, h!("c"))],
+            chain: &[(1, hash!("a")), (2, hash!("b")), (3, hash!("c"))],
+            to_insert: (2, hash!("b")),
+            exp_final_chain: &[(1, hash!("a")), (2, hash!("b")), (3, hash!("c"))],
         },
         TestCase {
             name: "insert_in_middle",
-            chain: &[(2, h!("b")), (4, h!("d")), (5, h!("e"))],
-            to_insert: (3, h!("c")),
-            exp_final_chain: &[(2, h!("b")), (3, h!("c")), (4, h!("d")), (5, h!("e"))],
+            chain: &[(2, hash!("b")), (4, hash!("d")), (5, hash!("e"))],
+            to_insert: (3, hash!("c")),
+            exp_final_chain: &[
+                (2, hash!("b")),
+                (3, hash!("c")),
+                (4, hash!("d")),
+                (5, hash!("e")),
+            ],
         },
         TestCase {
             name: "replace_one",
-            chain: &[(3, h!("c")), (4, h!("d")), (5, h!("e"))],
-            to_insert: (5, h!("E")),
-            exp_final_chain: &[(3, h!("c")), (4, h!("d")), (5, h!("E"))],
+            chain: &[(3, hash!("c")), (4, hash!("d")), (5, hash!("e"))],
+            to_insert: (5, hash!("E")),
+            exp_final_chain: &[(3, hash!("c")), (4, hash!("d")), (5, hash!("E"))],
         },
         TestCase {
             name: "insert_conflict_should_evict",
-            chain: &[(3, h!("c")), (4, h!("d")), (5, h!("e")), (6, h!("f"))],
-            to_insert: (4, h!("D")),
-            exp_final_chain: &[(3, h!("c")), (4, h!("D"))],
+            chain: &[
+                (3, hash!("c")),
+                (4, hash!("d")),
+                (5, hash!("e")),
+                (6, hash!("f")),
+            ],
+            to_insert: (4, hash!("D")),
+            exp_final_chain: &[(3, hash!("c")), (4, hash!("D"))],
         },
     ];
 
     fn genesis_block() -> impl Iterator<Item = BlockId> {
-        core::iter::once((0, h!("_"))).map(BlockId::from)
+        core::iter::once((0, hash!("_"))).map(BlockId::from)
     }
 
     for t in test_cases.into_iter() {
@@ -669,13 +682,13 @@ fn local_chain_apply_header_connected_to() {
 
     let test_cases = [
         {
-            let header = header_from_prev_blockhash(h!("_"));
+            let header = header_from_prev_blockhash(hash!("_"));
             let hash = header.block_hash();
             let height = 1;
             let connected_to = BlockId { height, hash };
             TestCase {
                 name: "connected_to_self_header_applied_to_self",
-                chain: local_chain![(0, h!("_")), (height, hash)],
+                chain: local_chain![(0, hash!("_")), (height, hash)],
                 header,
                 height,
                 connected_to,
@@ -683,7 +696,7 @@ fn local_chain_apply_header_connected_to() {
             }
         },
         {
-            let prev_hash = h!("A");
+            let prev_hash = hash!("A");
             let prev_height = 1;
             let header = header_from_prev_blockhash(prev_hash);
             let hash = header.block_hash();
@@ -694,7 +707,7 @@ fn local_chain_apply_header_connected_to() {
             };
             TestCase {
                 name: "connected_to_prev_header_applied_to_self",
-                chain: local_chain![(0, h!("_")), (prev_height, prev_hash)],
+                chain: local_chain![(0, hash!("_")), (prev_height, prev_hash)],
                 header,
                 height,
                 connected_to,
@@ -716,34 +729,34 @@ fn local_chain_apply_header_connected_to() {
             }
         },
         {
-            let header = header_from_prev_blockhash(h!("Z"));
+            let header = header_from_prev_blockhash(hash!("Z"));
             let height = 10;
             let hash = header.block_hash();
             let prev_height = height - 1;
             let prev_hash = header.prev_blockhash;
             TestCase {
                 name: "connect_at_connected_to",
-                chain: local_chain![(0, h!("_")), (2, h!("B")), (3, h!("C"))],
+                chain: local_chain![(0, hash!("_")), (2, hash!("B")), (3, hash!("C"))],
                 header,
                 height: 10,
                 connected_to: BlockId {
                     height: 3,
-                    hash: h!("C"),
+                    hash: hash!("C"),
                 },
                 exp_result: Ok(vec![(prev_height, Some(prev_hash)), (height, Some(hash))]),
             }
         },
         {
-            let prev_hash = h!("A");
+            let prev_hash = hash!("A");
             let prev_height = 1;
             let header = header_from_prev_blockhash(prev_hash);
             let connected_to = BlockId {
                 height: prev_height,
-                hash: h!("not_prev_hash"),
+                hash: hash!("not_prev_hash"),
             };
             TestCase {
                 name: "inconsistent_prev_hash",
-                chain: local_chain![(0, h!("_")), (prev_height, h!("not_prev_hash"))],
+                chain: local_chain![(0, hash!("_")), (prev_height, hash!("not_prev_hash"))],
                 header,
                 height: prev_height + 1,
                 connected_to,
@@ -751,17 +764,17 @@ fn local_chain_apply_header_connected_to() {
             }
         },
         {
-            let prev_hash = h!("A");
+            let prev_hash = hash!("A");
             let prev_height = 1;
             let header = header_from_prev_blockhash(prev_hash);
             let height = prev_height + 1;
             let connected_to = BlockId {
                 height,
-                hash: h!("not_current_hash"),
+                hash: hash!("not_current_hash"),
             };
             TestCase {
                 name: "inconsistent_current_block",
-                chain: local_chain![(0, h!("_")), (height, h!("not_current_hash"))],
+                chain: local_chain![(0, hash!("_")), (height, hash!("not_current_hash"))],
                 header,
                 height,
                 connected_to,
@@ -769,15 +782,15 @@ fn local_chain_apply_header_connected_to() {
             }
         },
         {
-            let header = header_from_prev_blockhash(h!("B"));
+            let header = header_from_prev_blockhash(hash!("B"));
             let height = 3;
             let connected_to = BlockId {
                 height: 4,
-                hash: h!("D"),
+                hash: hash!("D"),
             };
             TestCase {
                 name: "connected_to_is_greater",
-                chain: local_chain![(0, h!("_")), (2, h!("B"))],
+                chain: local_chain![(0, hash!("_")), (2, hash!("B"))],
                 header,
                 height,
                 connected_to,
index a49c9e5f5d30c4cbd1bcd50259b3bf0fea09804c..08be91c7ab0a9147661a107bfb1e8cd8d59170cc 100644 (file)
@@ -9,6 +9,7 @@ use bdk_chain::{
     tx_graph::{ChangeSet, TxGraph},
     Anchor, ChainOracle, ChainPosition, Merge,
 };
+use bdk_testenv::{block_id, hash, utils::new_tx};
 use bitcoin::{
     absolute, hashes::Hash, transaction, Amount, BlockHash, OutPoint, ScriptBuf, SignedAmount,
     Transaction, TxIn, TxOut, Txid,
@@ -24,14 +25,14 @@ fn insert_txouts() {
     // 2 (Outpoint, TxOut) tuples that denotes original data in the graph, as partial transactions.
     let original_ops = [
         (
-            OutPoint::new(h!("tx1"), 1),
+            OutPoint::new(hash!("tx1"), 1),
             TxOut {
                 value: Amount::from_sat(10_000),
                 script_pubkey: ScriptBuf::new(),
             },
         ),
         (
-            OutPoint::new(h!("tx1"), 2),
+            OutPoint::new(hash!("tx1"), 2),
             TxOut {
                 value: Amount::from_sat(20_000),
                 script_pubkey: ScriptBuf::new(),
@@ -41,7 +42,7 @@ fn insert_txouts() {
 
     // Another (OutPoint, TxOut) tuple to be used as update as partial transaction.
     let update_ops = [(
-        OutPoint::new(h!("tx2"), 0),
+        OutPoint::new(hash!("tx2"), 0),
         TxOut {
             value: Amount::from_sat(20_000),
             script_pubkey: ScriptBuf::new(),
@@ -65,7 +66,7 @@ fn insert_txouts() {
     // Conf anchor used to mark the full transaction as confirmed.
     let conf_anchor = BlockId {
         height: 100,
-        hash: h!("random blockhash"),
+        hash: hash!("random blockhash"),
     };
 
     // Unconfirmed seen_at timestamp to mark the partial transactions as unconfirmed.
@@ -114,7 +115,7 @@ fn insert_txouts() {
             txs: [Arc::new(update_tx.clone())].into(),
             txouts: update_ops.clone().into(),
             anchors: [(conf_anchor, update_tx.compute_txid()),].into(),
-            last_seen: [(h!("tx2"), 1000000)].into()
+            last_seen: [(hash!("tx2"), 1000000)].into()
         }
     );
 
@@ -126,7 +127,7 @@ fn insert_txouts() {
 
     // Check TxOuts are fetched correctly from the graph.
     assert_eq!(
-        graph.tx_outputs(h!("tx1")).expect("should exists"),
+        graph.tx_outputs(hash!("tx1")).expect("should exists"),
         [
             (
                 1u32,
@@ -167,7 +168,7 @@ fn insert_txouts() {
             txs: [Arc::new(update_tx.clone())].into(),
             txouts: update_ops.into_iter().chain(original_ops).collect(),
             anchors: [(conf_anchor, update_tx.compute_txid()),].into(),
-            last_seen: [(h!("tx2"), 1000000)].into()
+            last_seen: [(hash!("tx2"), 1000000)].into()
         }
     );
 }
@@ -361,7 +362,7 @@ fn test_calculate_fee() {
 
     let intxout1 = (
         OutPoint {
-            txid: h!("dangling output"),
+            txid: hash!("dangling output"),
             vout: 0,
         },
         TxOut {
@@ -415,7 +416,7 @@ fn test_calculate_fee() {
 
     // If we have an unknown outpoint, fee should return CalculateFeeError::MissingTxOut.
     let outpoint = OutPoint {
-        txid: h!("unknown_txid"),
+        txid: hash!("unknown_txid"),
         vout: 0,
     };
     tx.input.push(TxIn {
@@ -470,11 +471,11 @@ fn test_walk_ancestors() {
 
     let tx_a0 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(h!("op0"), 0),
+            previous_output: OutPoint::new(hash!("op0"), 0),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL, TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx_b0 spends tx_a0
@@ -484,7 +485,7 @@ fn test_walk_ancestors() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL, TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx_b1 spends tx_a0
@@ -494,16 +495,16 @@ fn test_walk_ancestors() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     let tx_b2 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(h!("op1"), 0),
+            previous_output: OutPoint::new(hash!("op1"), 0),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx_c0 spends tx_b0
@@ -513,7 +514,7 @@ fn test_walk_ancestors() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx_c1 spends tx_b0
@@ -523,7 +524,7 @@ fn test_walk_ancestors() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx_c2 spends tx_b1 and tx_b2
@@ -539,16 +540,16 @@ fn test_walk_ancestors() {
             },
         ],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     let tx_c3 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(h!("op2"), 0),
+            previous_output: OutPoint::new(hash!("op2"), 0),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx_d0 spends tx_c1
@@ -558,7 +559,7 @@ fn test_walk_ancestors() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx_d1 spends tx_c2 and tx_c3
@@ -574,7 +575,7 @@ fn test_walk_ancestors() {
             },
         ],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx_e0 spends tx_d1
@@ -584,7 +585,7 @@ fn test_walk_ancestors() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     let mut graph = TxGraph::<BlockId>::new([
@@ -658,7 +659,7 @@ fn test_walk_ancestors() {
 
 #[test]
 fn test_conflicting_descendants() {
-    let previous_output = OutPoint::new(h!("op"), 2);
+    let previous_output = OutPoint::new(hash!("op"), 2);
 
     // tx_a spends previous_output
     let tx_a = Transaction {
@@ -667,7 +668,7 @@ fn test_conflicting_descendants() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // tx_a2 spends previous_output and conflicts with tx_a
@@ -677,7 +678,7 @@ fn test_conflicting_descendants() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL, TxOut::NULL],
-        ..common::new_tx(1)
+        ..new_tx(1)
     };
 
     // tx_b spends tx_a
@@ -687,7 +688,7 @@ fn test_conflicting_descendants() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(2)
+        ..new_tx(2)
     };
 
     let txid_a = tx_a.compute_txid();
@@ -709,7 +710,7 @@ fn test_conflicting_descendants() {
 fn test_descendants_no_repeat() {
     let tx_a = Transaction {
         output: vec![TxOut::NULL, TxOut::NULL, TxOut::NULL],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     let txs_b = (0..3)
@@ -719,7 +720,7 @@ fn test_descendants_no_repeat() {
                 ..TxIn::default()
             }],
             output: vec![TxOut::NULL],
-            ..common::new_tx(1)
+            ..new_tx(1)
         })
         .collect::<Vec<_>>();
 
@@ -730,7 +731,7 @@ fn test_descendants_no_repeat() {
                 ..TxIn::default()
             }],
             output: vec![TxOut::NULL],
-            ..common::new_tx(2)
+            ..new_tx(2)
         })
         .collect::<Vec<_>>();
 
@@ -746,7 +747,7 @@ fn test_descendants_no_repeat() {
             },
         ],
         output: vec![TxOut::NULL],
-        ..common::new_tx(3)
+        ..new_tx(3)
     };
 
     let tx_e = Transaction {
@@ -755,17 +756,17 @@ fn test_descendants_no_repeat() {
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
-        ..common::new_tx(4)
+        ..new_tx(4)
     };
 
     let txs_not_connected = (10..20)
         .map(|v| Transaction {
             input: vec![TxIn {
-                previous_output: OutPoint::new(h!("tx_does_not_exist"), v),
+                previous_output: OutPoint::new(hash!("tx_does_not_exist"), v),
                 ..TxIn::default()
             }],
             output: vec![TxOut::NULL],
-            ..common::new_tx(v)
+            ..new_tx(v)
         })
         .collect::<Vec<_>>();
 
@@ -819,7 +820,7 @@ fn test_chain_spends() {
                 script_pubkey: ScriptBuf::new(),
             },
         ],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // The first confirmed transaction spends vout: 0. And is confirmed at block 98.
@@ -838,7 +839,7 @@ fn test_chain_spends() {
                 script_pubkey: ScriptBuf::new(),
             },
         ],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // The second transactions spends vout:1, and is unconfirmed.
@@ -857,7 +858,7 @@ fn test_chain_spends() {
                 script_pubkey: ScriptBuf::new(),
             },
         ],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     let mut graph = TxGraph::<ConfirmationBlockTime>::default();
@@ -929,7 +930,7 @@ fn test_chain_spends() {
             previous_output: OutPoint::new(tx_0.compute_txid(), 0),
             ..Default::default()
         }],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
     let _ = graph.insert_tx(tx_1_conflict.clone());
 
@@ -944,7 +945,7 @@ fn test_chain_spends() {
             previous_output: OutPoint::new(tx_0.compute_txid(), 1),
             ..Default::default()
         }],
-        ..common::new_tx(0)
+        ..new_tx(0)
     };
 
     // Insert in graph and mark it as seen.
@@ -983,7 +984,7 @@ fn test_chain_spends() {
 /// Ensure that `last_seen` values only increase during [`Merge::merge`].
 #[test]
 fn test_changeset_last_seen_merge() {
-    let txid: Txid = h!("test txid");
+    let txid: Txid = hash!("test txid");
 
     let test_cases: &[(Option<u64>, Option<u64>)] = &[
         (Some(5), Some(6)),
@@ -1026,7 +1027,7 @@ fn transactions_inserted_into_tx_graph_are_not_canonical_until_they_have_an_anch
     assert_eq!(unseen_txs.len(), 2);
 
     // chain
-    let blocks: BTreeMap<u32, BlockHash> = [(0, h!("g")), (1, h!("A")), (2, h!("B"))]
+    let blocks: BTreeMap<u32, BlockHash> = [(0, hash!("g")), (1, hash!("A")), (2, hash!("B"))]
         .into_iter()
         .collect();
     let chain = LocalChain::from_blocks(blocks).unwrap();
@@ -1181,9 +1182,9 @@ fn tx_graph_update_conversion() {
             TxUpdate {
                 txs: vec![make_tx(0).into(), make_tx(1).into()],
                 txouts: [
-                    (OutPoint::new(h!("a"), 0), make_txout(0)),
-                    (OutPoint::new(h!("a"), 1), make_txout(1)),
-                    (OutPoint::new(h!("b"), 0), make_txout(2)),
+                    (OutPoint::new(hash!("a"), 0), make_txout(0)),
+                    (OutPoint::new(hash!("a"), 1), make_txout(1)),
+                    (OutPoint::new(hash!("b"), 0), make_txout(2)),
                 ]
                 .into(),
                 ..Default::default()
@@ -1194,14 +1195,14 @@ fn tx_graph_update_conversion() {
             TxUpdate {
                 txs: vec![make_tx(0).into(), make_tx(1).into()],
                 txouts: [
-                    (OutPoint::new(h!("a"), 0), make_txout(0)),
-                    (OutPoint::new(h!("a"), 1), make_txout(1)),
-                    (OutPoint::new(h!("b"), 0), make_txout(2)),
+                    (OutPoint::new(hash!("a"), 0), make_txout(0)),
+                    (OutPoint::new(hash!("a"), 1), make_txout(1)),
+                    (OutPoint::new(hash!("b"), 0), make_txout(2)),
                 ]
                 .into(),
                 anchors: [
-                    (ConfirmationBlockTime::default(), h!("a")),
-                    (ConfirmationBlockTime::default(), h!("b")),
+                    (ConfirmationBlockTime::default(), hash!("a")),
+                    (ConfirmationBlockTime::default(), hash!("b")),
                 ]
                 .into(),
                 ..Default::default()
@@ -1212,17 +1213,17 @@ fn tx_graph_update_conversion() {
             TxUpdate {
                 txs: vec![make_tx(0).into(), make_tx(1).into()],
                 txouts: [
-                    (OutPoint::new(h!("a"), 0), make_txout(0)),
-                    (OutPoint::new(h!("a"), 1), make_txout(1)),
-                    (OutPoint::new(h!("d"), 0), make_txout(2)),
+                    (OutPoint::new(hash!("a"), 0), make_txout(0)),
+                    (OutPoint::new(hash!("a"), 1), make_txout(1)),
+                    (OutPoint::new(hash!("d"), 0), make_txout(2)),
                 ]
                 .into(),
                 anchors: [
-                    (ConfirmationBlockTime::default(), h!("a")),
-                    (ConfirmationBlockTime::default(), h!("b")),
+                    (ConfirmationBlockTime::default(), hash!("a")),
+                    (ConfirmationBlockTime::default(), hash!("b")),
                 ]
                 .into(),
-                seen_ats: [(h!("c"), 12346)].into_iter().collect(),
+                seen_ats: [(hash!("c"), 12346)].into_iter().collect(),
             },
         ),
     ];
index 45370b676370cfc0d01f331cbcb75bae7cbf3275..1f54c4b82ecf48c5b9cf62e9db7e48fcc3369839 100644 (file)
@@ -3,11 +3,11 @@
 #[macro_use]
 mod common;
 
-use std::collections::{BTreeSet, HashSet};
-
 use bdk_chain::{Balance, BlockId};
+use bdk_testenv::{block_id, hash, local_chain};
 use bitcoin::{Amount, OutPoint, ScriptBuf};
 use common::*;
+use std::collections::{BTreeSet, HashSet};
 
 #[allow(dead_code)]
 struct Scenario<'a> {
@@ -33,13 +33,13 @@ struct Scenario<'a> {
 fn test_tx_conflict_handling() {
     // Create Local chains
     let local_chain = local_chain!(
-        (0, h!("A")),
-        (1, h!("B")),
-        (2, h!("C")),
-        (3, h!("D")),
-        (4, h!("E")),
-        (5, h!("F")),
-        (6, h!("G"))
+        (0, hash!("A")),
+        (1, hash!("B")),
+        (2, hash!("C")),
+        (3, hash!("D")),
+        (4, hash!("E")),
+        (5, hash!("F")),
+        (6, hash!("G"))
     );
     let chain_tip = local_chain.tip().block_id();
 
index c218bf164c1ab99bb0f8338caab13c7897616021..50417f4a9d1db8d3b18bc1b9ddad51d7f5e19f28 100644 (file)
@@ -22,3 +22,4 @@ serde = ["dep:serde", "bitcoin/serde", "hashbrown?/serde"]
 
 [dev-dependencies]
 bdk_chain = { path = "../chain" }
+bdk_testenv = { path = "../testenv", default-features = false }
diff --git a/crates/core/tests/common.rs b/crates/core/tests/common.rs
deleted file mode 100644 (file)
index 347a90b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#[allow(unused_macros)]
-macro_rules! block_id {
-    ($height:expr, $hash:literal) => {{
-        bdk_chain::BlockId {
-            height: $height,
-            hash: bitcoin::hashes::Hash::hash($hash.as_bytes()),
-        }
-    }};
-}
index 705f1c4746f84c1144cd290faeb7ce9443f29280..2ec96c1530a4205644d23363be1caa9a8c2f4d22 100644 (file)
@@ -1,7 +1,5 @@
-#[macro_use]
-mod common;
-
 use bdk_core::CheckPoint;
+use bdk_testenv::block_id;
 
 /// Inserting a block that already exists in the checkpoint chain must always succeed.
 #[test]
index 6d169bdce3d4193e8d37558fff5050d6a656d41d..abf4cac4396bf7d9443a6fcc604c10554b566201 100644 (file)
@@ -1,3 +1,5 @@
+pub mod utils;
+
 use bdk_chain::{
     bitcoin::{
         address::NetworkChecked, block::Header, hash_types::TxMerkleNode, hashes::Hash,
diff --git a/crates/testenv/src/utils.rs b/crates/testenv/src/utils.rs
new file mode 100644 (file)
index 0000000..93ca1f2
--- /dev/null
@@ -0,0 +1,90 @@
+use bdk_chain::bitcoin;
+
+#[allow(unused_macros)]
+#[macro_export]
+macro_rules! block_id {
+    ($height:expr, $hash:literal) => {{
+        bdk_chain::BlockId {
+            height: $height,
+            hash: bitcoin::hashes::Hash::hash($hash.as_bytes()),
+        }
+    }};
+}
+
+#[allow(unused_macros)]
+#[macro_export]
+macro_rules! hash {
+    ($index:literal) => {{
+        bitcoin::hashes::Hash::hash($index.as_bytes())
+    }};
+}
+
+#[allow(unused_macros)]
+#[macro_export]
+macro_rules! local_chain {
+    [ $(($height:expr, $hash:expr)), * ] => {{
+        #[allow(unused_mut)]
+        bdk_chain::local_chain::LocalChain::from_blocks([$(($height, $hash).into()),*].into_iter().collect())
+            .expect("chain must have genesis block")
+    }};
+}
+
+#[allow(unused_macros)]
+#[macro_export]
+macro_rules! chain_update {
+    [ $(($height:expr, $hash:expr)), * ] => {{
+        #[allow(unused_mut)]
+        bdk_chain::local_chain::LocalChain::from_blocks([$(($height, $hash).into()),*].into_iter().collect())
+            .expect("chain must have genesis block")
+            .tip()
+    }};
+}
+
+#[allow(unused_macros)]
+#[macro_export]
+macro_rules! changeset {
+    (checkpoints: $($tail:tt)*) => { changeset!(index: TxHeight, checkpoints: $($tail)*) };
+    (
+        index: $ind:ty,
+        checkpoints: [ $(( $height:expr, $cp_to:expr )),* ]
+        $(,txids: [ $(( $txid:expr, $tx_to:expr )),* ])?
+    ) => {{
+        use bdk_chain::collections::BTreeMap;
+
+        #[allow(unused_mut)]
+        bdk_chain::sparse_chain::ChangeSet::<$ind> {
+            checkpoints: {
+                let mut changes = BTreeMap::default();
+                $(changes.insert($height, $cp_to);)*
+                changes
+            },
+            txids: {
+                let mut changes = BTreeMap::default();
+                $($(changes.insert($txid, $tx_to.map(|h: TxHeight| h.into()));)*)?
+                changes
+            }
+        }
+    }};
+}
+
+#[allow(unused)]
+pub fn new_tx(lt: u32) -> bitcoin::Transaction {
+    bitcoin::Transaction {
+        version: bitcoin::transaction::Version::non_standard(0x00),
+        lock_time: bitcoin::absolute::LockTime::from_consensus(lt),
+        input: vec![],
+        output: vec![],
+    }
+}
+
+#[allow(unused)]
+pub const DESCRIPTORS: [&str; 7] = [
+    "tr([73c5da0a/86'/0'/0']xprv9xgqHN7yz9MwCkxsBPN5qetuNdQSUttZNKw1dcYTV4mkaAFiBVGQziHs3NRSWMkCzvgjEe3n9xV8oYywvM8at9yRqyaZVz6TYYhX98VjsUk/0/*)",
+    "tr([73c5da0a/86'/0'/0']xprv9xgqHN7yz9MwCkxsBPN5qetuNdQSUttZNKw1dcYTV4mkaAFiBVGQziHs3NRSWMkCzvgjEe3n9xV8oYywvM8at9yRqyaZVz6TYYhX98VjsUk/1/*)",
+    "wpkh([73c5da0a/86'/0'/0']xprv9xgqHN7yz9MwCkxsBPN5qetuNdQSUttZNKw1dcYTV4mkaAFiBVGQziHs3NRSWMkCzvgjEe3n9xV8oYywvM8at9yRqyaZVz6TYYhX98VjsUk/1/0/*)",
+    "tr(tprv8ZgxMBicQKsPd3krDUsBAmtnRsK3rb8u5yi1zhQgMhF1tR8MW7xfE4rnrbbsrbPR52e7rKapu6ztw1jXveJSCGHEriUGZV7mCe88duLp5pj/86'/1'/0'/0/*)",
+    "tr(tprv8ZgxMBicQKsPd3krDUsBAmtnRsK3rb8u5yi1zhQgMhF1tR8MW7xfE4rnrbbsrbPR52e7rKapu6ztw1jXveJSCGHEriUGZV7mCe88duLp5pj/86'/1'/0'/1/*)",
+    "wpkh(xprv9s21ZrQH143K4EXURwMHuLS469fFzZyXk7UUpdKfQwhoHcAiYTakpe8pMU2RiEdvrU9McyuE7YDoKcXkoAwEGoK53WBDnKKv2zZbb9BzttX/1/0/*)",
+    // non-wildcard
+    "wpkh([73c5da0a/86'/0'/0']xprv9xgqHN7yz9MwCkxsBPN5qetuNdQSUttZNKw1dcYTV4mkaAFiBVGQziHs3NRSWMkCzvgjEe3n9xV8oYywvM8at9yRqyaZVz6TYYhX98VjsUk/1/0)",
+];