]> Untitled Git - bdk/commitdiff
deps(bdk): bump `bitcoin` to `0.32.0`, miniscript to `12.0.0`
authorLeonardo Lima <oleonardolima@users.noreply.github.com>
Wed, 22 May 2024 21:34:30 +0000 (18:34 -0300)
committerLeonardo Lima <oleonardolima@users.noreply.github.com>
Wed, 12 Jun 2024 13:31:50 +0000 (10:31 -0300)
deps(chain): bump `bitcoin` to `0.32.0`, miniscript to `12.0.0`

fix(chain): use `minimal_non_dust()` instead of `dust_value()`

fix(chain): use `compute_txid()` instead of `txid`

deps(testenv): bump `electrsd` to `0.28.0`

deps(electrum): bump `electrum-client` to `0.20.0`

fix(electrum): use `compute_txid()` instead of `txid`

deps(esplora): bump `esplora-client` to `0.8.0`

deps(bitcoind_rpc): bump `bitcoin` to `0.32.0`, `bitcoincore-rpc` to
`0.19.0`

fix(bitcoind_rpc): use `compute_txid()` instead of `txid`

fix(nursery/tmp_plan): use proper `sighash` errors, and fix the expected
`Signature` fields

fix(sqlite): use `compute_txid()` instead of `txid`

deps(hwi): bump `hwi` to `0.9.0`

deps(wallet): bump `bitcoin` to `0.32.0`, miniscript to `12.0.0`

fix(wallet): use `compute_txid()` and `minimal_non_dust()`

- update to use `compute_txid()` instead of deprecated `txid()`
- update to use `minimal_non_dust()` instead of `dust_value()`
- remove unused `bitcoin::hex::FromHex`.

fix(wallet): uses `.into` conversion on `Network` for `NetworkKind`

- uses `.into()` when appropriate, otherwise use the explicit
  `NetworkKind`, and it's `.is_mainnet()` method.

fix(wallet): add P2wpkh, Taproot, InputsIndex errors to `SignerError`

fix(wallet): fields on taproot, and ecdsa `Signature` structure

fix(wallet/wallet): convert `Weight` to `usize` for now

- converts the `bitcoin-units::Weight` type to `usize` with help of
  `to_wu()` method.
- it should be updated/refactored in the future to handle the `Weight`
  type throughout the code instead of current `usize`, only converting
  it for now.
- allows the usage of deprecated `is_provably_unspendable()`, needs
  further discussion if suggested `is_op_return` is suitable.
- update the expect field to `signature`, as it was renamed from `sig`.

fix(wallet/wallet): use `is_op_return` instead of
`is_provably_unspendable`

fix(wallet/wallet): use `relative::Locktime` instead of `Sequence`

fix(wallet/descriptor): use `ParsePublicKeyError`

fix(wallet/descriptor): use `.into()` to convert from `AbsLockTime` and
`RelLockTime` to `absolute::LockTime` and `relative::LockTime`

fix(wallet/wallet): use `Message::from_digest()` instead of relying on
deprecated `ThirtyTwoByteHash` trait.

fix(wallet/descriptor+wallet): expect `Threshold` type, and handle it
internally

fix(wallet/wallet): remove `0x` prefix from expected `TxId` display

fix(examples): use `compute_txid()` instead of `txid`

fix(ci): remove usage of `bitcoin/no-std` feature

- remove comment: `# The `no-std` feature it's implied when the `std` feature is disabled.`

41 files changed:
.github/workflows/cont_integration.yml
crates/bitcoind_rpc/Cargo.toml
crates/bitcoind_rpc/tests/test_emitter.rs
crates/chain/Cargo.toml
crates/chain/src/descriptor_ext.rs
crates/chain/src/indexed_tx_graph.rs
crates/chain/src/keychain/txout_index.rs
crates/chain/src/spk_txout_index.rs
crates/chain/src/tx_data_traits.rs
crates/chain/src/tx_graph.rs
crates/chain/tests/common/tx_template.rs
crates/chain/tests/test_indexed_tx_graph.rs
crates/chain/tests/test_spk_txout_index.rs
crates/chain/tests/test_tx_graph.rs
crates/electrum/Cargo.toml
crates/electrum/src/bdk_electrum_client.rs
crates/esplora/Cargo.toml
crates/hwi/Cargo.toml
crates/sqlite/src/store.rs
crates/testenv/Cargo.toml
crates/wallet/Cargo.toml
crates/wallet/src/descriptor/dsl.rs
crates/wallet/src/descriptor/error.rs
crates/wallet/src/descriptor/mod.rs
crates/wallet/src/descriptor/policy.rs
crates/wallet/src/descriptor/template.rs
crates/wallet/src/keys/mod.rs
crates/wallet/src/wallet/coin_selection.rs
crates/wallet/src/wallet/export.rs
crates/wallet/src/wallet/mod.rs
crates/wallet/src/wallet/signer.rs
crates/wallet/src/wallet/tx_builder.rs
crates/wallet/src/wallet/utils.rs
crates/wallet/tests/common.rs
crates/wallet/tests/wallet.rs
example-crates/example_cli/src/lib.rs
example-crates/wallet_electrum/src/main.rs
example-crates/wallet_esplora_async/src/main.rs
example-crates/wallet_esplora_blocking/src/main.rs
nursery/tmp_plan/src/plan_impls.rs
nursery/tmp_plan/src/requirements.rs

index 0b853b8de93cf020424c7ac00daba1a9ec649db2..510af1dbfa7a629fd15f98fdfdeea214815741b2 100644 (file)
@@ -58,15 +58,15 @@ jobs:
       - name: Check bdk_chain
         working-directory: ./crates/chain
         # TODO "--target thumbv6m-none-eabi" should work but currently does not
-        run: cargo check --no-default-features --features bitcoin/no-std,miniscript/no-std,hashbrown
+        run: cargo check --no-default-features --features miniscript/no-std,hashbrown
       - name: Check bdk wallet
         working-directory: ./crates/wallet
         # TODO "--target thumbv6m-none-eabi" should work but currently does not
-        run: cargo check --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown
+        run: cargo check --no-default-features --features miniscript/no-std,bdk_chain/hashbrown
       - name: Check esplora
         working-directory: ./crates/esplora
         # TODO "--target thumbv6m-none-eabi" should work but currently does not
-        run: cargo check --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown
+        run: cargo check --no-default-features --features miniscript/no-std,bdk_chain/hashbrown
 
   check-wasm:
     name: Check WASM
@@ -92,10 +92,10 @@ jobs:
         uses: Swatinem/rust-cache@v2.2.1
       - name: Check bdk wallet
         working-directory: ./crates/wallet
-        run: cargo check --target wasm32-unknown-unknown --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown,dev-getrandom-wasm
+        run: cargo check --target wasm32-unknown-unknown --no-default-features --features miniscript/no-std,bdk_chain/hashbrown,dev-getrandom-wasm
       - name: Check esplora
         working-directory: ./crates/esplora
-        run: cargo check --target wasm32-unknown-unknown --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown,async
+        run: cargo check --target wasm32-unknown-unknown --no-default-features --features miniscript/no-std,bdk_chain/hashbrown,async
 
   fmt:
     name: Rust fmt
index ac2abb97c892077a0832bdcd4c619b021dc86b64..1652f1f83cd375265bb0b17e7e39f651ca573195 100644 (file)
@@ -13,9 +13,8 @@ readme = "README.md"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-# For no-std, remember to enable the bitcoin/no-std feature
-bitcoin = { version = "0.31", default-features = false }
-bitcoincore-rpc = { version = "0.18" }
+bitcoin = { version = "0.32.0", default-features = false }
+bitcoincore-rpc = { version = "0.19.0" }
 bdk_chain = { path = "../chain", version = "0.15", default-features = false }
 
 [dev-dependencies]
index 5e0622f2761442ce75201bc08d99ef82cead2f89..7eefbc049e81d62edcb02da2cb124d75abc54910 100644 (file)
@@ -197,7 +197,7 @@ fn test_into_tx_graph() -> anyhow::Result<()> {
                 .graph
                 .txs
                 .iter()
-                .map(|tx| tx.txid())
+                .map(|tx| tx.compute_txid())
                 .collect::<BTreeSet<Txid>>(),
             exp_txids,
             "changeset should have the 3 mempool transactions",
@@ -440,7 +440,7 @@ fn mempool_avoids_re_emission() -> anyhow::Result<()> {
     let emitted_txids = emitter
         .mempool()?
         .into_iter()
-        .map(|(tx, _)| tx.txid())
+        .map(|(tx, _)| tx.compute_txid())
         .collect::<BTreeSet<Txid>>();
     assert_eq!(
         emitted_txids, exp_txids,
@@ -509,7 +509,7 @@ fn mempool_re_emits_if_tx_introduction_height_not_reached() -> anyhow::Result<()
         emitter
             .mempool()?
             .into_iter()
-            .map(|(tx, _)| tx.txid())
+            .map(|(tx, _)| tx.compute_txid())
             .collect::<BTreeSet<_>>(),
         tx_introductions.iter().map(|&(_, txid)| txid).collect(),
         "first mempool emission should include all txs",
@@ -518,7 +518,7 @@ fn mempool_re_emits_if_tx_introduction_height_not_reached() -> anyhow::Result<()
         emitter
             .mempool()?
             .into_iter()
-            .map(|(tx, _)| tx.txid())
+            .map(|(tx, _)| tx.compute_txid())
             .collect::<BTreeSet<_>>(),
         tx_introductions.iter().map(|&(_, txid)| txid).collect(),
         "second mempool emission should still include all txs",
@@ -538,7 +538,7 @@ fn mempool_re_emits_if_tx_introduction_height_not_reached() -> anyhow::Result<()
             let emitted_txids = emitter
                 .mempool()?
                 .into_iter()
-                .map(|(tx, _)| tx.txid())
+                .map(|(tx, _)| tx.compute_txid())
                 .collect::<BTreeSet<_>>();
             assert_eq!(
                 emitted_txids, exp_txids,
@@ -596,7 +596,7 @@ fn mempool_during_reorg() -> anyhow::Result<()> {
         emitter
             .mempool()?
             .into_iter()
-            .map(|(tx, _)| tx.txid())
+            .map(|(tx, _)| tx.compute_txid())
             .collect::<BTreeSet<_>>(),
         env.rpc_client()
             .get_raw_mempool()?
@@ -633,7 +633,7 @@ fn mempool_during_reorg() -> anyhow::Result<()> {
             let mempool = emitter
                 .mempool()?
                 .into_iter()
-                .map(|(tx, _)| tx.txid())
+                .map(|(tx, _)| tx.compute_txid())
                 .collect::<BTreeSet<_>>();
             let exp_mempool = tx_introductions
                 .iter()
@@ -648,7 +648,7 @@ fn mempool_during_reorg() -> anyhow::Result<()> {
             let mempool = emitter
                 .mempool()?
                 .into_iter()
-                .map(|(tx, _)| tx.txid())
+                .map(|(tx, _)| tx.compute_txid())
                 .collect::<BTreeSet<_>>();
             let exp_mempool = tx_introductions
                 .iter()
index 57113218ba546a58031536131880158f0164883c..8b4a3c3286b72739f0b868332abf1337651f4659 100644 (file)
@@ -13,13 +13,12 @@ readme = "README.md"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-# For no-std, remember to enable the bitcoin/no-std feature
-bitcoin = { version = "0.31.0", default-features = false }
+bitcoin = { version = "0.32.0", default-features = false }
 serde_crate = { package = "serde", version = "1", optional = true, features = ["derive", "rc"] }
 
 # Use hashbrown as a feature flag to have HashSet and HashMap from it.
 hashbrown = { version = "0.9.1", optional = true, features = ["serde"] }
-miniscript = { version = "11.0.0", optional = true, default-features = false }
+miniscript = { version = "12.0.0", optional = true, default-features = false }
 
 [dev-dependencies]
 rand = "0.8"
index af7175525769063d6c0dde7573f42bb42a86c075..e42d291bb737acf29cb82fa6126a2eead2810cd5 100644 (file)
@@ -31,7 +31,7 @@ impl DescriptorExt for Descriptor<DescriptorPublicKey> {
         self.at_derivation_index(0)
             .expect("descriptor can't have hardened derivation")
             .script_pubkey()
-            .dust_value()
+            .minimal_non_dust()
             .to_sat()
     }
 
index ff6686332a4d471c48fe02e708b474e91d2fea37..3848ba64b1715b9b683fd83b9acbed7708d6a906 100644 (file)
@@ -143,7 +143,7 @@ where
         let mut graph = tx_graph::ChangeSet::default();
         for (tx, anchors) in txs {
             if self.index.is_tx_relevant(tx) {
-                let txid = tx.txid();
+                let txid = tx.compute_txid();
                 graph.append(self.graph.insert_tx(tx.clone()));
                 for anchor in anchors {
                     graph.append(self.graph.insert_anchor(txid, anchor));
@@ -234,7 +234,7 @@ where
         for (tx_pos, tx) in block.txdata.iter().enumerate() {
             changeset.indexer.append(self.index.index_tx(tx));
             if self.index.is_tx_relevant(tx) {
-                let txid = tx.txid();
+                let txid = tx.compute_txid();
                 let anchor = A::from_block_position(block, block_id, tx_pos);
                 changeset.graph.append(self.graph.insert_tx(tx.clone()));
                 changeset
@@ -261,7 +261,7 @@ where
         let mut graph = tx_graph::ChangeSet::default();
         for (tx_pos, tx) in block.txdata.iter().enumerate() {
             let anchor = A::from_block_position(&block, block_id, tx_pos);
-            graph.append(self.graph.insert_anchor(tx.txid(), anchor));
+            graph.append(self.graph.insert_anchor(tx.compute_txid(), anchor));
             graph.append(self.graph.insert_tx(tx.clone()));
         }
         let indexer = self.index_tx_graph_changeset(&graph);
index 994553b3f51d6b2ed64fefc86df13cdaa71bffdb..18690a7a2e35d2a9f0f1f93e9f1ceb3dd15a6c49 100644 (file)
@@ -251,7 +251,7 @@ impl<K: Clone + Ord + Debug> Indexer for KeychainTxOutIndex<K> {
     fn index_tx(&mut self, tx: &bitcoin::Transaction) -> Self::ChangeSet {
         let mut changeset = super::ChangeSet::<K>::default();
         for (op, txout) in tx.output.iter().enumerate() {
-            changeset.append(self.index_txout(OutPoint::new(tx.txid(), op as u32), txout));
+            changeset.append(self.index_txout(OutPoint::new(tx.compute_txid(), op as u32), txout));
         }
         changeset
     }
index 3ee423772e8e186b97e06f19a6214db20d36c6b3..a724ccdbc990451c76bd73bd436f61750ecdd846 100644 (file)
@@ -86,7 +86,7 @@ impl<I: Clone + Ord> SpkTxOutIndex<I> {
     /// 2. When getting new data from the chain, you usually scan it before incorporating it into your chain state.
     pub fn scan(&mut self, tx: &Transaction) -> BTreeSet<I> {
         let mut scanned_indices = BTreeSet::new();
-        let txid = tx.txid();
+        let txid = tx.compute_txid();
         for (i, txout) in tx.output.iter().enumerate() {
             let op = OutPoint::new(txid, i as u32);
             if let Some(spk_i) = self.scan_txout(op, txout) {
index 8fa17ff90449af5f2bda2c5adb69b8661832748f..b3ab3515ef96c8e2692f0b01e00b4fcc4eee43a0 100644 (file)
@@ -43,7 +43,7 @@ use alloc::vec::Vec;
 /// let mut graph_a = TxGraph::<BlockId>::default();
 /// let _ = graph_a.insert_tx(tx.clone());
 /// graph_a.insert_anchor(
-///     tx.txid(),
+///     tx.compute_txid(),
 ///     BlockId {
 ///         height: 1,
 ///         hash: Hash::hash("first".as_bytes()),
@@ -58,7 +58,7 @@ use alloc::vec::Vec;
 /// let mut graph_b = TxGraph::<ConfirmationHeightAnchor>::default();
 /// let _ = graph_b.insert_tx(tx.clone());
 /// graph_b.insert_anchor(
-///     tx.txid(),
+///     tx.compute_txid(),
 ///     ConfirmationHeightAnchor {
 ///         anchor_block: BlockId {
 ///             height: 2,
@@ -76,7 +76,7 @@ use alloc::vec::Vec;
 /// let mut graph_c = TxGraph::<ConfirmationTimeHeightAnchor>::default();
 /// let _ = graph_c.insert_tx(tx.clone());
 /// graph_c.insert_anchor(
-///     tx.txid(),
+///     tx.compute_txid(),
 ///     ConfirmationTimeHeightAnchor {
 ///         anchor_block: BlockId {
 ///             height: 2,
index eb119e3c9022de1c549c13c14a8254e1abdce1ba..13eefd66bef8e615815a630fd17651cfec25514d 100644 (file)
@@ -445,7 +445,7 @@ impl<A> TxGraph<A> {
         &'g self,
         tx: &'g Transaction,
     ) -> impl Iterator<Item = (usize, Txid)> + '_ {
-        let txid = tx.txid();
+        let txid = tx.compute_txid();
         tx.input
             .iter()
             .enumerate()
@@ -516,9 +516,10 @@ impl<A: Clone + Ord> TxGraph<A> {
     pub fn insert_tx<T: Into<Arc<Transaction>>>(&mut self, tx: T) -> ChangeSet<A> {
         let tx = tx.into();
         let mut update = Self::default();
-        update
-            .txs
-            .insert(tx.txid(), (TxNodeInternal::Whole(tx), BTreeSet::new(), 0));
+        update.txs.insert(
+            tx.compute_txid(),
+            (TxNodeInternal::Whole(tx), BTreeSet::new(), 0),
+        );
         self.apply_update(update)
     }
 
@@ -533,7 +534,7 @@ impl<A: Clone + Ord> TxGraph<A> {
     ) -> ChangeSet<A> {
         let mut changeset = ChangeSet::<A>::default();
         for (tx, seen_at) in txs {
-            changeset.append(self.insert_seen_at(tx.txid(), seen_at));
+            changeset.append(self.insert_seen_at(tx.compute_txid(), seen_at));
             changeset.append(self.insert_tx(tx));
         }
         changeset
@@ -642,7 +643,7 @@ impl<A: Clone + Ord> TxGraph<A> {
     pub fn apply_changeset(&mut self, changeset: ChangeSet<A>) {
         for wrapped_tx in changeset.txs {
             let tx = wrapped_tx.as_ref();
-            let txid = tx.txid();
+            let txid = tx.compute_txid();
 
             tx.input
                 .iter()
@@ -660,7 +661,7 @@ impl<A: Clone + Ord> TxGraph<A> {
                 }
                 Some((TxNodeInternal::Whole(tx), _, _)) => {
                     debug_assert_eq!(
-                        tx.as_ref().txid(),
+                        tx.as_ref().compute_txid(),
                         txid,
                         "tx should produce txid that is same as key"
                     );
@@ -825,7 +826,7 @@ impl<A: Anchor> TxGraph<A> {
         // resulting array will also include `tx`
         let unconfirmed_ancestor_txs =
             TxAncestors::new_include_root(self, tx.clone(), |_, ancestor_tx: Arc<Transaction>| {
-                let tx_node = self.get_tx_node(ancestor_tx.as_ref().txid())?;
+                let tx_node = self.get_tx_node(ancestor_tx.as_ref().compute_txid())?;
                 // We're filtering the ancestors to keep only the unconfirmed ones (= no anchors in
                 // the best chain)
                 for block in tx_node.anchors {
@@ -843,7 +844,7 @@ impl<A: Anchor> TxGraph<A> {
         // and our unconf descendants' last seen.
         let unconfirmed_descendants_txs = TxDescendants::new_include_root(
             self,
-            tx.as_ref().txid(),
+            tx.as_ref().compute_txid(),
             |_, descendant_txid: Txid| {
                 let tx_node = self.get_tx_node(descendant_txid)?;
                 // We're filtering the ancestors to keep only the unconfirmed ones (= no anchors in
@@ -884,7 +885,7 @@ impl<A: Anchor> TxGraph<A> {
                     return Ok(None);
                 }
                 if conflicting_tx.last_seen_unconfirmed == *last_seen
-                    && conflicting_tx.as_ref().txid() > tx.as_ref().txid()
+                    && conflicting_tx.as_ref().compute_txid() > tx.as_ref().compute_txid()
                 {
                     // Conflicting tx has priority if txid of conflicting tx > txid of original tx
                     return Ok(None);
@@ -1255,7 +1256,7 @@ impl<A> ChangeSet<A> {
                 tx.output
                     .iter()
                     .enumerate()
-                    .map(move |(vout, txout)| (OutPoint::new(tx.txid(), vout as _), txout))
+                    .map(move |(vout, txout)| (OutPoint::new(tx.compute_txid(), vout as _), txout))
             })
             .chain(self.txouts.iter().map(|(op, txout)| (*op, txout)))
     }
index 42bc0f79ff98150a444f682d09ed39201dfb8e7a..13bce01baffca4879f355ff18503e9fe3d1e5742 100644 (file)
@@ -125,14 +125,14 @@ pub fn init_graph<'a, A: Anchor + Clone + 'a>(
                 .collect(),
         };
 
-        tx_ids.insert(tx_tmp.tx_name, tx.txid());
+        tx_ids.insert(tx_tmp.tx_name, tx.compute_txid());
         spk_index.scan(&tx);
         let _ = graph.insert_tx(tx.clone());
         for anchor in tx_tmp.anchors.iter() {
-            let _ = graph.insert_anchor(tx.txid(), anchor.clone());
+            let _ = graph.insert_anchor(tx.compute_txid(), anchor.clone());
         }
         if let Some(seen_at) = tx_tmp.last_seen {
-            let _ = graph.insert_seen_at(tx.txid(), seen_at);
+            let _ = graph.insert_seen_at(tx.compute_txid(), seen_at);
         }
     }
     (graph, spk_index, tx_ids)
index 328163379bfd44c8999dd0a7acbb66da50d00848..43085cc21997648049699fab2d9902546efd41de 100644 (file)
@@ -52,7 +52,7 @@ fn insert_relevant_txs() {
 
     let tx_b = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_a.txid(), 0),
+            previous_output: OutPoint::new(tx_a.compute_txid(), 0),
             ..Default::default()
         }],
         ..common::new_tx(1)
@@ -60,7 +60,7 @@ fn insert_relevant_txs() {
 
     let tx_c = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_a.txid(), 1),
+            previous_output: OutPoint::new(tx_a.compute_txid(), 1),
             ..Default::default()
         }],
         ..common::new_tx(2)
@@ -196,7 +196,7 @@ fn test_list_owned_txouts() {
     // tx3 spends tx2 and gives a change back in trusted keychain. Confirmed at Block 2.
     let tx3 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx2.txid(), 0),
+            previous_output: OutPoint::new(tx2.compute_txid(), 0),
             ..Default::default()
         }],
         output: vec![TxOut {
@@ -340,16 +340,22 @@ fn test_list_owned_txouts() {
             balance,
         ) = fetch(0, &graph);
 
-        assert_eq!(confirmed_txouts_txid, [tx1.txid()].into());
+        assert_eq!(confirmed_txouts_txid, [tx1.compute_txid()].into());
         assert_eq!(
             unconfirmed_txouts_txid,
-            [tx2.txid(), tx3.txid(), tx4.txid(), tx5.txid()].into()
+            [
+                tx2.compute_txid(),
+                tx3.compute_txid(),
+                tx4.compute_txid(),
+                tx5.compute_txid()
+            ]
+            .into()
         );
 
-        assert_eq!(confirmed_utxos_txid, [tx1.txid()].into());
+        assert_eq!(confirmed_utxos_txid, [tx1.compute_txid()].into());
         assert_eq!(
             unconfirmed_utxos_txid,
-            [tx3.txid(), tx4.txid(), tx5.txid()].into()
+            [tx3.compute_txid(), tx4.compute_txid(), tx5.compute_txid()].into()
         );
 
         assert_eq!(
@@ -374,17 +380,20 @@ fn test_list_owned_txouts() {
         ) = fetch(1, &graph);
 
         // tx2 gets into confirmed txout set
-        assert_eq!(confirmed_txouts_txid, [tx1.txid(), tx2.txid()].into());
+        assert_eq!(
+            confirmed_txouts_txid,
+            [tx1.compute_txid(), tx2.compute_txid()].into()
+        );
         assert_eq!(
             unconfirmed_txouts_txid,
-            [tx3.txid(), tx4.txid(), tx5.txid()].into()
+            [tx3.compute_txid(), tx4.compute_txid(), tx5.compute_txid()].into()
         );
 
         // tx2 doesn't get into confirmed utxos set
-        assert_eq!(confirmed_utxos_txid, [tx1.txid()].into());
+        assert_eq!(confirmed_utxos_txid, [tx1.compute_txid()].into());
         assert_eq!(
             unconfirmed_utxos_txid,
-            [tx3.txid(), tx4.txid(), tx5.txid()].into()
+            [tx3.compute_txid(), tx4.compute_txid(), tx5.compute_txid()].into()
         );
 
         assert_eq!(
@@ -411,13 +420,22 @@ fn test_list_owned_txouts() {
         // tx3 now gets into the confirmed txout set
         assert_eq!(
             confirmed_txouts_txid,
-            [tx1.txid(), tx2.txid(), tx3.txid()].into()
+            [tx1.compute_txid(), tx2.compute_txid(), tx3.compute_txid()].into()
+        );
+        assert_eq!(
+            unconfirmed_txouts_txid,
+            [tx4.compute_txid(), tx5.compute_txid()].into()
         );
-        assert_eq!(unconfirmed_txouts_txid, [tx4.txid(), tx5.txid()].into());
 
         // tx3 also gets into confirmed utxo set
-        assert_eq!(confirmed_utxos_txid, [tx1.txid(), tx3.txid()].into());
-        assert_eq!(unconfirmed_utxos_txid, [tx4.txid(), tx5.txid()].into());
+        assert_eq!(
+            confirmed_utxos_txid,
+            [tx1.compute_txid(), tx3.compute_txid()].into()
+        );
+        assert_eq!(
+            unconfirmed_utxos_txid,
+            [tx4.compute_txid(), tx5.compute_txid()].into()
+        );
 
         assert_eq!(
             balance,
@@ -442,12 +460,21 @@ fn test_list_owned_txouts() {
 
         assert_eq!(
             confirmed_txouts_txid,
-            [tx1.txid(), tx2.txid(), tx3.txid()].into()
+            [tx1.compute_txid(), tx2.compute_txid(), tx3.compute_txid()].into()
+        );
+        assert_eq!(
+            unconfirmed_txouts_txid,
+            [tx4.compute_txid(), tx5.compute_txid()].into()
         );
-        assert_eq!(unconfirmed_txouts_txid, [tx4.txid(), tx5.txid()].into());
 
-        assert_eq!(confirmed_utxos_txid, [tx1.txid(), tx3.txid()].into());
-        assert_eq!(unconfirmed_utxos_txid, [tx4.txid(), tx5.txid()].into());
+        assert_eq!(
+            confirmed_utxos_txid,
+            [tx1.compute_txid(), tx3.compute_txid()].into()
+        );
+        assert_eq!(
+            unconfirmed_utxos_txid,
+            [tx4.compute_txid(), tx5.compute_txid()].into()
+        );
 
         // Coinbase is still immature
         assert_eq!(
index 2317b0a7d8f5f28bbf966ad48a30b82833649b24..8be252703c0011f8d663aed45720e4123a99806b 100644 (file)
@@ -47,7 +47,7 @@ fn spk_txout_sent_and_received() {
         lock_time: absolute::LockTime::ZERO,
         input: vec![TxIn {
             previous_output: OutPoint {
-                txid: tx1.txid(),
+                txid: tx1.compute_txid(),
                 vout: 0,
             },
             ..Default::default()
index 6377588623b93d51c3b98c44d4a967c95fd4e5b0..21b955d21236fa50bd2da550beb17e6c926e158a 100644 (file)
@@ -130,11 +130,11 @@ fn insert_txouts() {
 
         // Mark it as confirmed.
         assert_eq!(
-            graph.insert_anchor(update_txs.txid(), conf_anchor),
+            graph.insert_anchor(update_txs.compute_txid(), conf_anchor),
             ChangeSet {
                 txs: [].into(),
                 txouts: [].into(),
-                anchors: [(conf_anchor, update_txs.txid())].into(),
+                anchors: [(conf_anchor, update_txs.compute_txid())].into(),
                 last_seen: [].into()
             }
         );
@@ -149,7 +149,11 @@ fn insert_txouts() {
         ChangeSet {
             txs: [Arc::new(update_txs.clone())].into(),
             txouts: update_ops.clone().into(),
-            anchors: [(conf_anchor, update_txs.txid()), (unconf_anchor, h!("tx2"))].into(),
+            anchors: [
+                (conf_anchor, update_txs.compute_txid()),
+                (unconf_anchor, h!("tx2"))
+            ]
+            .into(),
             last_seen: [(h!("tx2"), 1000000)].into()
         }
     );
@@ -183,7 +187,9 @@ fn insert_txouts() {
     );
 
     assert_eq!(
-        graph.tx_outputs(update_txs.txid()).expect("should exists"),
+        graph
+            .tx_outputs(update_txs.compute_txid())
+            .expect("should exists"),
         [(
             0u32,
             &TxOut {
@@ -200,7 +206,11 @@ fn insert_txouts() {
         ChangeSet {
             txs: [Arc::new(update_txs.clone())].into(),
             txouts: update_ops.into_iter().chain(original_ops).collect(),
-            anchors: [(conf_anchor, update_txs.txid()), (unconf_anchor, h!("tx2"))].into(),
+            anchors: [
+                (conf_anchor, update_txs.compute_txid()),
+                (unconf_anchor, h!("tx2"))
+            ]
+            .into(),
             last_seen: [(h!("tx2"), 1000000)].into()
         }
     );
@@ -235,7 +245,7 @@ fn insert_tx_graph_keeps_track_of_spend() {
     };
 
     let op = OutPoint {
-        txid: tx1.txid(),
+        txid: tx1.compute_txid(),
         vout: 0,
     };
 
@@ -261,7 +271,7 @@ fn insert_tx_graph_keeps_track_of_spend() {
 
     assert_eq!(
         graph1.outspends(op),
-        &iter::once(tx2.txid()).collect::<HashSet<_>>()
+        &iter::once(tx2.compute_txid()).collect::<HashSet<_>>()
     );
     assert_eq!(graph2.outspends(op), graph1.outspends(op));
 }
@@ -281,7 +291,9 @@ fn insert_tx_can_retrieve_full_tx_from_graph() {
     let mut graph = TxGraph::<()>::default();
     let _ = graph.insert_tx(tx.clone());
     assert_eq!(
-        graph.get_tx(tx.txid()).map(|tx| tx.as_ref().clone()),
+        graph
+            .get_tx(tx.compute_txid())
+            .map(|tx| tx.as_ref().clone()),
         Some(tx)
     );
 }
@@ -301,7 +313,7 @@ fn insert_tx_displaces_txouts() {
 
     let changeset = tx_graph.insert_txout(
         OutPoint {
-            txid: tx.txid(),
+            txid: tx.compute_txid(),
             vout: 0,
         },
         TxOut {
@@ -314,7 +326,7 @@ fn insert_tx_displaces_txouts() {
 
     let _ = tx_graph.insert_txout(
         OutPoint {
-            txid: tx.txid(),
+            txid: tx.compute_txid(),
             vout: 0,
         },
         TxOut {
@@ -328,7 +340,7 @@ fn insert_tx_displaces_txouts() {
     assert_eq!(
         tx_graph
             .get_txout(OutPoint {
-                txid: tx.txid(),
+                txid: tx.compute_txid(),
                 vout: 0
             })
             .unwrap()
@@ -337,7 +349,7 @@ fn insert_tx_displaces_txouts() {
     );
     assert_eq!(
         tx_graph.get_txout(OutPoint {
-            txid: tx.txid(),
+            txid: tx.compute_txid(),
             vout: 1
         }),
         None
@@ -361,7 +373,7 @@ fn insert_txout_does_not_displace_tx() {
 
     let _ = tx_graph.insert_txout(
         OutPoint {
-            txid: tx.txid(),
+            txid: tx.compute_txid(),
             vout: 0,
         },
         TxOut {
@@ -372,7 +384,7 @@ fn insert_txout_does_not_displace_tx() {
 
     let _ = tx_graph.insert_txout(
         OutPoint {
-            txid: tx.txid(),
+            txid: tx.compute_txid(),
             vout: 0,
         },
         TxOut {
@@ -384,7 +396,7 @@ fn insert_txout_does_not_displace_tx() {
     assert_eq!(
         tx_graph
             .get_txout(OutPoint {
-                txid: tx.txid(),
+                txid: tx.compute_txid(),
                 vout: 0
             })
             .unwrap()
@@ -393,7 +405,7 @@ fn insert_txout_does_not_displace_tx() {
     );
     assert_eq!(
         tx_graph.get_txout(OutPoint {
-            txid: tx.txid(),
+            txid: tx.compute_txid(),
             vout: 1
         }),
         None
@@ -443,14 +455,14 @@ fn test_calculate_fee() {
         input: vec![
             TxIn {
                 previous_output: OutPoint {
-                    txid: intx1.txid(),
+                    txid: intx1.compute_txid(),
                     vout: 0,
                 },
                 ..Default::default()
             },
             TxIn {
                 previous_output: OutPoint {
-                    txid: intx2.txid(),
+                    txid: intx2.compute_txid(),
                     vout: 0,
                 },
                 ..Default::default()
@@ -543,7 +555,7 @@ fn test_walk_ancestors() {
     // tx_b0 spends tx_a0
     let tx_b0 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_a0.txid(), 0),
+            previous_output: OutPoint::new(tx_a0.compute_txid(), 0),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL, TxOut::NULL],
@@ -553,7 +565,7 @@ fn test_walk_ancestors() {
     // tx_b1 spends tx_a0
     let tx_b1 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_a0.txid(), 1),
+            previous_output: OutPoint::new(tx_a0.compute_txid(), 1),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
@@ -572,7 +584,7 @@ fn test_walk_ancestors() {
     // tx_c0 spends tx_b0
     let tx_c0 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_b0.txid(), 0),
+            previous_output: OutPoint::new(tx_b0.compute_txid(), 0),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
@@ -582,7 +594,7 @@ fn test_walk_ancestors() {
     // tx_c1 spends tx_b0
     let tx_c1 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_b0.txid(), 1),
+            previous_output: OutPoint::new(tx_b0.compute_txid(), 1),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
@@ -593,11 +605,11 @@ fn test_walk_ancestors() {
     let tx_c2 = Transaction {
         input: vec![
             TxIn {
-                previous_output: OutPoint::new(tx_b1.txid(), 0),
+                previous_output: OutPoint::new(tx_b1.compute_txid(), 0),
                 ..TxIn::default()
             },
             TxIn {
-                previous_output: OutPoint::new(tx_b2.txid(), 0),
+                previous_output: OutPoint::new(tx_b2.compute_txid(), 0),
                 ..TxIn::default()
             },
         ],
@@ -617,7 +629,7 @@ fn test_walk_ancestors() {
     // tx_d0 spends tx_c1
     let tx_d0 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_c1.txid(), 0),
+            previous_output: OutPoint::new(tx_c1.compute_txid(), 0),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
@@ -628,11 +640,11 @@ fn test_walk_ancestors() {
     let tx_d1 = Transaction {
         input: vec![
             TxIn {
-                previous_output: OutPoint::new(tx_c2.txid(), 0),
+                previous_output: OutPoint::new(tx_c2.compute_txid(), 0),
                 ..TxIn::default()
             },
             TxIn {
-                previous_output: OutPoint::new(tx_c3.txid(), 0),
+                previous_output: OutPoint::new(tx_c3.compute_txid(), 0),
                 ..TxIn::default()
             },
         ],
@@ -643,7 +655,7 @@ fn test_walk_ancestors() {
     // tx_e0 spends tx_d1
     let tx_e0 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_d1.txid(), 0),
+            previous_output: OutPoint::new(tx_d1.compute_txid(), 0),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
@@ -665,7 +677,7 @@ fn test_walk_ancestors() {
     ]);
 
     [&tx_a0, &tx_b1].iter().for_each(|&tx| {
-        let changeset = graph.insert_anchor(tx.txid(), tip.block_id());
+        let changeset = graph.insert_anchor(tx.compute_txid(), tip.block_id());
         assert!(!changeset.is_empty());
     });
 
@@ -682,7 +694,7 @@ fn test_walk_ancestors() {
         // Only traverse unconfirmed ancestors of tx_e0 this time
         graph
             .walk_ancestors(tx_e0.clone(), |depth, tx| {
-                let tx_node = graph.get_tx_node(tx.txid())?;
+                let tx_node = graph.get_tx_node(tx.compute_txid())?;
                 for block in tx_node.anchors {
                     match local_chain.is_block_in_chain(block.anchor_block(), tip.block_id()) {
                         Ok(Some(true)) => return None,
@@ -746,15 +758,15 @@ fn test_conflicting_descendants() {
     // tx_b spends tx_a
     let tx_b = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_a.txid(), 0),
+            previous_output: OutPoint::new(tx_a.compute_txid(), 0),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
         ..common::new_tx(2)
     };
 
-    let txid_a = tx_a.txid();
-    let txid_b = tx_b.txid();
+    let txid_a = tx_a.compute_txid();
+    let txid_b = tx_b.compute_txid();
 
     let mut graph = TxGraph::<()>::default();
     let _ = graph.insert_tx(tx_a);
@@ -778,7 +790,7 @@ fn test_descendants_no_repeat() {
     let txs_b = (0..3)
         .map(|vout| Transaction {
             input: vec![TxIn {
-                previous_output: OutPoint::new(tx_a.txid(), vout),
+                previous_output: OutPoint::new(tx_a.compute_txid(), vout),
                 ..TxIn::default()
             }],
             output: vec![TxOut::NULL],
@@ -789,7 +801,7 @@ fn test_descendants_no_repeat() {
     let txs_c = (0..2)
         .map(|vout| Transaction {
             input: vec![TxIn {
-                previous_output: OutPoint::new(txs_b[vout as usize].txid(), vout),
+                previous_output: OutPoint::new(txs_b[vout as usize].compute_txid(), vout),
                 ..TxIn::default()
             }],
             output: vec![TxOut::NULL],
@@ -800,11 +812,11 @@ fn test_descendants_no_repeat() {
     let tx_d = Transaction {
         input: vec![
             TxIn {
-                previous_output: OutPoint::new(txs_c[0].txid(), 0),
+                previous_output: OutPoint::new(txs_c[0].compute_txid(), 0),
                 ..TxIn::default()
             },
             TxIn {
-                previous_output: OutPoint::new(txs_c[1].txid(), 0),
+                previous_output: OutPoint::new(txs_c[1].compute_txid(), 0),
                 ..TxIn::default()
             },
         ],
@@ -814,7 +826,7 @@ fn test_descendants_no_repeat() {
 
     let tx_e = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_d.txid(), 0),
+            previous_output: OutPoint::new(tx_d.compute_txid(), 0),
             ..TxIn::default()
         }],
         output: vec![TxOut::NULL],
@@ -848,11 +860,11 @@ fn test_descendants_no_repeat() {
         .chain(core::iter::once(&tx_e))
     {
         let _ = graph.insert_tx(tx.clone());
-        expected_txids.push(tx.txid());
+        expected_txids.push(tx.compute_txid());
     }
 
     let descendants = graph
-        .walk_descendants(tx_a.txid(), |_, txid| Some(txid))
+        .walk_descendants(tx_a.compute_txid(), |_, txid| Some(txid))
         .collect::<Vec<_>>();
 
     assert_eq!(descendants, expected_txids);
@@ -888,7 +900,7 @@ fn test_chain_spends() {
     // The first confirmed transaction spends vout: 0. And is confirmed at block 98.
     let tx_1 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_0.txid(), 0),
+            previous_output: OutPoint::new(tx_0.compute_txid(), 0),
             ..TxIn::default()
         }],
         output: vec![
@@ -907,7 +919,7 @@ fn test_chain_spends() {
     // The second transactions spends vout:1, and is unconfirmed.
     let tx_2 = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_0.txid(), 1),
+            previous_output: OutPoint::new(tx_0.compute_txid(), 1),
             ..TxIn::default()
         }],
         output: vec![
@@ -931,7 +943,7 @@ fn test_chain_spends() {
 
     for (ht, tx) in [(95, &tx_0), (98, &tx_1)] {
         let _ = graph.insert_anchor(
-            tx.txid(),
+            tx.compute_txid(),
             ConfirmationHeightAnchor {
                 anchor_block: tip.block_id(),
                 confirmation_height: ht,
@@ -941,19 +953,23 @@ fn test_chain_spends() {
 
     // Assert that confirmed spends are returned correctly.
     assert_eq!(
-        graph.get_chain_spend(&local_chain, tip.block_id(), OutPoint::new(tx_0.txid(), 0)),
+        graph.get_chain_spend(
+            &local_chain,
+            tip.block_id(),
+            OutPoint::new(tx_0.compute_txid(), 0)
+        ),
         Some((
             ChainPosition::Confirmed(&ConfirmationHeightAnchor {
                 anchor_block: tip.block_id(),
                 confirmation_height: 98
             }),
-            tx_1.txid(),
+            tx_1.compute_txid(),
         )),
     );
 
     // Check if chain position is returned correctly.
     assert_eq!(
-        graph.get_chain_position(&local_chain, tip.block_id(), tx_0.txid()),
+        graph.get_chain_position(&local_chain, tip.block_id(), tx_0.compute_txid()),
         // Some(ObservedAs::Confirmed(&local_chain.get_block(95).expect("block expected"))),
         Some(ChainPosition::Confirmed(&ConfirmationHeightAnchor {
             anchor_block: tip.block_id(),
@@ -963,25 +979,33 @@ fn test_chain_spends() {
 
     // Even if unconfirmed tx has a last_seen of 0, it can still be part of a chain spend.
     assert_eq!(
-        graph.get_chain_spend(&local_chain, tip.block_id(), OutPoint::new(tx_0.txid(), 1)),
-        Some((ChainPosition::Unconfirmed(0), tx_2.txid())),
+        graph.get_chain_spend(
+            &local_chain,
+            tip.block_id(),
+            OutPoint::new(tx_0.compute_txid(), 1)
+        ),
+        Some((ChainPosition::Unconfirmed(0), tx_2.compute_txid())),
     );
 
     // Mark the unconfirmed as seen and check correct ObservedAs status is returned.
-    let _ = graph.insert_seen_at(tx_2.txid(), 1234567);
+    let _ = graph.insert_seen_at(tx_2.compute_txid(), 1234567);
 
     // Check chain spend returned correctly.
     assert_eq!(
         graph
-            .get_chain_spend(&local_chain, tip.block_id(), OutPoint::new(tx_0.txid(), 1))
+            .get_chain_spend(
+                &local_chain,
+                tip.block_id(),
+                OutPoint::new(tx_0.compute_txid(), 1)
+            )
             .unwrap(),
-        (ChainPosition::Unconfirmed(1234567), tx_2.txid())
+        (ChainPosition::Unconfirmed(1234567), tx_2.compute_txid())
     );
 
     // A conflicting transaction that conflicts with tx_1.
     let tx_1_conflict = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_0.txid(), 0),
+            previous_output: OutPoint::new(tx_0.compute_txid(), 0),
             ..Default::default()
         }],
         ..common::new_tx(0)
@@ -990,13 +1014,13 @@ fn test_chain_spends() {
 
     // Because this tx conflicts with an already confirmed transaction, chain position should return none.
     assert!(graph
-        .get_chain_position(&local_chain, tip.block_id(), tx_1_conflict.txid())
+        .get_chain_position(&local_chain, tip.block_id(), tx_1_conflict.compute_txid())
         .is_none());
 
     // Another conflicting tx that conflicts with tx_2.
     let tx_2_conflict = Transaction {
         input: vec![TxIn {
-            previous_output: OutPoint::new(tx_0.txid(), 1),
+            previous_output: OutPoint::new(tx_0.compute_txid(), 1),
             ..Default::default()
         }],
         ..common::new_tx(0)
@@ -1004,12 +1028,12 @@ fn test_chain_spends() {
 
     // Insert in graph and mark it as seen.
     let _ = graph.insert_tx(tx_2_conflict.clone());
-    let _ = graph.insert_seen_at(tx_2_conflict.txid(), 1234568);
+    let _ = graph.insert_seen_at(tx_2_conflict.compute_txid(), 1234568);
 
     // This should return a valid observation with correct last seen.
     assert_eq!(
         graph
-            .get_chain_position(&local_chain, tip.block_id(), tx_2_conflict.txid())
+            .get_chain_position(&local_chain, tip.block_id(), tx_2_conflict.compute_txid())
             .expect("position expected"),
         ChainPosition::Unconfirmed(1234568)
     );
@@ -1017,14 +1041,21 @@ fn test_chain_spends() {
     // Chain_spend now catches the new transaction as the spend.
     assert_eq!(
         graph
-            .get_chain_spend(&local_chain, tip.block_id(), OutPoint::new(tx_0.txid(), 1))
+            .get_chain_spend(
+                &local_chain,
+                tip.block_id(),
+                OutPoint::new(tx_0.compute_txid(), 1)
+            )
             .expect("expect observation"),
-        (ChainPosition::Unconfirmed(1234568), tx_2_conflict.txid())
+        (
+            ChainPosition::Unconfirmed(1234568),
+            tx_2_conflict.compute_txid()
+        )
     );
 
     // Chain position of the `tx_2` is now none, as it is older than `tx_2_conflict`
     assert!(graph
-        .get_chain_position(&local_chain, tip.block_id(), tx_2.txid())
+        .get_chain_position(&local_chain, tip.block_id(), tx_2.compute_txid())
         .is_none());
 }
 
@@ -1065,7 +1096,7 @@ fn test_changeset_last_seen_append() {
 fn update_last_seen_unconfirmed() {
     let mut graph = TxGraph::<()>::default();
     let tx = new_tx(0);
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
 
     // insert a new tx
     // initially we have a last_seen of 0, and no anchors
index 6ee822ec02902acf31eb964e1a349ca82f100cff..a7b72847b536450649db866eca68df7a56e55b1e 100644 (file)
@@ -13,8 +13,8 @@ readme = "README.md"
 
 [dependencies]
 bdk_chain = { path = "../chain", version = "0.15.0" }
-electrum-client = { version = "0.19" }
+electrum-client = { version = "0.20" }
 #rustls = { version = "=0.21.1", optional = true, features = ["dangerous_configuration"] }
 
 [dev-dependencies]
-bdk_testenv = { path = "../testenv", default-features = false }
\ No newline at end of file
+bdk_testenv = { path = "../testenv", default-features = false }
index 5f7d59b22ac1269cff8cd03811ce4debf6438170..32be258863b43ed74245677ba6ba9b5fb2a831d3 100644 (file)
@@ -310,7 +310,7 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
                 Some(txout) => txout,
                 None => continue,
             };
-            debug_assert_eq!(op_tx.txid(), op_txid);
+            debug_assert_eq!(op_tx.compute_txid(), op_txid);
 
             // attempt to find the following transactions (alongside their chain positions), and
             // add to our sparsechain `update`:
index 471e3c7638d532d8e80250f8db9b2fb75716cec9..69339e891591c39eeb57b944893d0ec48c505e91 100644 (file)
@@ -13,13 +13,12 @@ readme = "README.md"
 
 [dependencies]
 bdk_chain = { path = "../chain", version = "0.15.0", default-features = false }
-esplora-client = { version = "0.7.0", default-features = false }
+esplora-client = { version = "0.8.0", default-features = false }
 async-trait = { version = "0.1.66", optional = true }
 futures = { version = "0.3.26", optional = true }
 
-# use these dependencies if you need to enable their /no-std features
-bitcoin = { version = "0.31.0", optional = true, default-features = false }
-miniscript = { version = "11.0.0", optional = true, default-features = false }
+bitcoin = { version = "0.32.0", optional = true, default-features = false }
+miniscript = { version = "12.0.0", optional = true, default-features = false }
 
 [dev-dependencies]
 bdk_testenv = { path = "../testenv", default-features = false }
@@ -27,7 +26,7 @@ tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
 
 [features]
 default = ["std", "async-https", "blocking-https-rustls"]
-std = ["bdk_chain/std"]
+std = ["bdk_chain/std", "miniscript?/std"]
 async = ["async-trait", "futures", "esplora-client/async"]
 async-https = ["async", "esplora-client/async-https"]
 async-https-rustls = ["async", "esplora-client/async-https-rustls"]
index 6aad8e54d0f89058b4f3ecd9482dc0682f7f84d7..d73646320984c3bb7cdc0cc94eabc184febb09b9 100644 (file)
@@ -10,4 +10,4 @@ readme = "README.md"
 
 [dependencies]
 bdk_wallet = { path = "../wallet", version = "1.0.0-alpha.12" }
-hwi = { version = "0.8.0", features = [ "miniscript"] }
+hwi = { version = "0.9.0", features = [ "miniscript"] }
index beeb9e0aa9d896288dec105d19945e5d8acad3f7..fe4572dbd70d2824a6e872da77372cb87bf73daf 100644 (file)
@@ -303,7 +303,7 @@ impl<K, A> Store<K, A> {
             let insert_tx_stmt = &mut db_transaction
                 .prepare_cached("INSERT INTO tx (txid, whole_tx) VALUES (:txid, :whole_tx) ON CONFLICT (txid) DO UPDATE SET whole_tx = :whole_tx WHERE txid = :txid")
                 .expect("insert or update tx whole_tx statement");
-            let txid = tx.txid().to_string();
+            let txid = tx.compute_txid().to_string();
             let whole_tx = serialize(&tx);
             insert_tx_stmt
                 .execute(named_params! {":txid": txid, ":whole_tx": whole_tx })
@@ -685,9 +685,9 @@ mod test {
         let tx2_hex = Vec::<u8>::from_hex("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0432e7494d010e062f503253482fffffffff0100f2052a010000002321038a7f6ef1c8ca0c588aa53fa860128077c9e6c11e6830f4d7ee4e763a56b7718fac00000000").unwrap();
         let tx2: Arc<Transaction> = Arc::new(deserialize(tx2_hex.as_slice()).unwrap());
 
-        let outpoint0_0 = OutPoint::new(tx0.txid(), 0);
+        let outpoint0_0 = OutPoint::new(tx0.compute_txid(), 0);
         let txout0_0 = tx0.output.first().unwrap().clone();
-        let outpoint1_0 = OutPoint::new(tx1.txid(), 0);
+        let outpoint1_0 = OutPoint::new(tx1.compute_txid(), 0);
         let txout1_0 = tx1.output.first().unwrap().clone();
 
         let anchor1 = anchor_fn(1, 1296667328, block_hash_1);
@@ -696,11 +696,11 @@ mod test {
         let tx_graph_changeset = tx_graph::ChangeSet::<A> {
             txs: [tx0.clone(), tx1.clone()].into(),
             txouts: [(outpoint0_0, txout0_0), (outpoint1_0, txout1_0)].into(),
-            anchors: [(anchor1, tx0.txid()), (anchor1, tx1.txid())].into(),
+            anchors: [(anchor1, tx0.compute_txid()), (anchor1, tx1.compute_txid())].into(),
             last_seen: [
-                (tx0.txid(), 1598918400),
-                (tx1.txid(), 1598919121),
-                (tx2.txid(), 1608919121),
+                (tx0.compute_txid(), 1598918400),
+                (tx1.compute_txid(), 1598919121),
+                (tx2.compute_txid(), 1608919121),
             ]
             .into(),
         };
@@ -730,7 +730,7 @@ mod test {
             txs: [tx2.clone()].into(),
             txouts: BTreeMap::default(),
             anchors: BTreeSet::default(),
-            last_seen: [(tx2.txid(), 1708919121)].into(),
+            last_seen: [(tx2.compute_txid(), 1708919121)].into(),
         };
 
         let graph_changeset2: indexed_tx_graph::ChangeSet<A, keychain::ChangeSet<Keychain>> =
@@ -749,7 +749,7 @@ mod test {
         let tx_graph_changeset3 = tx_graph::ChangeSet::<A> {
             txs: BTreeSet::default(),
             txouts: BTreeMap::default(),
-            anchors: [(anchor2, tx0.txid()), (anchor2, tx1.txid())].into(),
+            anchors: [(anchor2, tx0.compute_txid()), (anchor2, tx1.compute_txid())].into(),
             last_seen: BTreeMap::default(),
         };
 
index 7f46d9cf2b18ce1da96e795e2d1bbf16859dd83a..384d899df23635c13e2ddb434aa4edf556fb3286 100644 (file)
@@ -14,7 +14,7 @@ readme = "README.md"
 
 [dependencies]
 bdk_chain = { path = "../chain", version = "0.15", default-features = false }
-electrsd = { version= "0.27.1", features = ["bitcoind_25_0", "esplora_a33e97e1", "legacy"] }
+electrsd = { version = "0.28.0", features = ["bitcoind_25_0", "esplora_a33e97e1", "legacy"] }
 
 [features]
 default = ["std"]
index 2a129e9595229e4b70f079105aead99edee8b2ee..8b72af47c336d768d6f35aac4dd9d521204d5ef3 100644 (file)
@@ -15,8 +15,8 @@ rust-version = "1.63"
 [dependencies]
 anyhow = { version = "1", default-features = false }
 rand = "^0.8"
-miniscript = { version = "11.0.0", features = ["serde"], default-features = false }
-bitcoin = { version = "0.31.0", features = ["serde", "base64", "rand-std"], default-features = false }
+miniscript = { version = "12.0.0", features = ["serde"], default-features = false }
+bitcoin = { version = "0.32.0", features = ["serde", "base64", "rand-std"], default-features = false }
 serde = { version = "^1.0", features = ["derive"] }
 serde_json = { version = "^1.0" }
 bdk_chain = { path = "../chain", version = "0.15.0", features = ["miniscript", "serde"], default-features = false }
index 0d7e7c8e9c367f97dc177adb406e6623a4d2fa57..e975971760af5b6e98e719dbaf38e8c4ce247bbd 100644 (file)
@@ -703,10 +703,10 @@ macro_rules! fragment {
         $crate::keys::make_pkh($key, &secp)
     });
     ( after ( $value:expr ) ) => ({
-        $crate::impl_leaf_opcode_value!(After, $crate::miniscript::AbsLockTime::from_consensus($value))
+        $crate::impl_leaf_opcode_value!(After, $crate::miniscript::AbsLockTime::from_consensus($value).expect("valid `AbsLockTime`"))
     });
     ( older ( $value:expr ) ) => ({
-        $crate::impl_leaf_opcode_value!(Older, $crate::bitcoin::Sequence($value)) // TODO!!
+        $crate::impl_leaf_opcode_value!(Older, $crate::miniscript::RelLockTime::from_consensus($value).expect("valid `RelLockTime`")) // TODO!!
     });
     ( sha256 ( $hash:expr ) ) => ({
         $crate::impl_leaf_opcode_value!(Sha256, $hash)
@@ -757,7 +757,8 @@ macro_rules! fragment {
             (keys_acc, net_acc)
         });
 
-        $crate::impl_leaf_opcode_value_two!(Thresh, $thresh, items)
+        let thresh = $crate::miniscript::Threshold::new($thresh, items).expect("valid threshold and pks collection");
+        $crate::impl_leaf_opcode_value!(Thresh, thresh)
             .map(|(minisc, _, _)| (minisc, key_maps, valid_networks))
     });
     ( thresh ( $thresh:expr, $( $inner:tt )* ) ) => ({
@@ -769,7 +770,12 @@ macro_rules! fragment {
     ( multi_vec ( $thresh:expr, $keys:expr ) ) => ({
         let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
 
-        $crate::keys::make_multi($thresh, $crate::miniscript::Terminal::Multi, $keys, &secp)
+        let fun = |k, pks| {
+            let thresh = $crate::miniscript::Threshold::new(k, pks).expect("valid threshold and pks collection");
+            $crate::miniscript::Terminal::Multi(thresh)
+        };
+
+        $crate::keys::make_multi($thresh, fun, $keys, &secp)
     });
     ( multi ( $thresh:expr $(, $key:expr )+ ) ) => ({
         $crate::group_multi_keys!( $( $key ),* )
@@ -778,7 +784,12 @@ macro_rules! fragment {
     ( multi_a_vec ( $thresh:expr, $keys:expr ) ) => ({
         let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
 
-        $crate::keys::make_multi($thresh, $crate::miniscript::Terminal::MultiA, $keys, &secp)
+        let fun = |k, pks| {
+            let thresh = $crate::miniscript::Threshold::new(k, pks).expect("valid threshold and pks collection");
+            $crate::miniscript::Terminal::MultiA(thresh)
+        };
+
+        $crate::keys::make_multi($thresh, fun, $keys, &secp)
     });
     ( multi_a ( $thresh:expr $(, $key:expr )+ ) ) => ({
         $crate::group_multi_keys!( $( $key ),* )
index 4d15e3602148d0ab4aa52cb36bbe2fa77c2bd3b1..48d0091ddf9745009f8a67b863aad15a4251b59a 100644 (file)
@@ -37,7 +37,7 @@ pub enum Error {
     /// Error during base58 decoding
     Base58(bitcoin::base58::Error),
     /// Key-related error
-    Pk(bitcoin::key::Error),
+    Pk(bitcoin::key::ParsePublicKeyError),
     /// Miniscript error
     Miniscript(miniscript::Error),
     /// Hex decoding error
@@ -103,8 +103,8 @@ impl From<bitcoin::base58::Error> for Error {
     }
 }
 
-impl From<bitcoin::key::Error> for Error {
-    fn from(err: bitcoin::key::Error) -> Self {
+impl From<bitcoin::key::ParsePublicKeyError> for Error {
+    fn from(err: bitcoin::key::ParsePublicKeyError) -> Self {
         Error::Pk(err)
     }
 }
index 4b1135feb77a9697df935cfab235cf3f571b956c..0d39481042194f7900add1beb58f810e8f975153 100644 (file)
@@ -229,7 +229,7 @@ impl IntoWalletDescriptor for DescriptorTemplateOut {
                 let pk = match pk {
                     DescriptorPublicKey::XPub(ref xpub) => {
                         let mut xpub = xpub.clone();
-                        xpub.xkey.network = self.network;
+                        xpub.xkey.network = self.network.into();
 
                         DescriptorPublicKey::XPub(xpub)
                     }
@@ -264,11 +264,11 @@ impl IntoWalletDescriptor for DescriptorTemplateOut {
             .map(|(mut k, mut v)| {
                 match (&mut k, &mut v) {
                     (DescriptorPublicKey::XPub(xpub), DescriptorSecretKey::XPrv(xprv)) => {
-                        xpub.xkey.network = network;
-                        xprv.xkey.network = network;
+                        xpub.xkey.network = network.into();
+                        xprv.xkey.network = network.into();
                     }
                     (_, DescriptorSecretKey::Single(key)) => {
-                        key.key.network = network;
+                        key.key.network = network.into();
                     }
                     _ => {}
                 }
@@ -606,8 +606,8 @@ mod test {
     use assert_matches::assert_matches;
     use bitcoin::hex::FromHex;
     use bitcoin::secp256k1::Secp256k1;
-    use bitcoin::ScriptBuf;
     use bitcoin::{bip32, Psbt};
+    use bitcoin::{NetworkKind, ScriptBuf};
 
     use super::*;
     use crate::psbt::PsbtUtils;
@@ -743,7 +743,7 @@ mod test {
             .unwrap();
 
         let mut xprv_testnet = xprv;
-        xprv_testnet.network = Network::Testnet;
+        xprv_testnet.network = NetworkKind::Test;
 
         let xpub_testnet = bip32::Xpub::from_priv(&secp, &xprv_testnet);
         let desc_pubkey = DescriptorPublicKey::XPub(DescriptorXKey {
index bf8a661ea4a50e8d7c8d7246e6fae08b24a0f361..efb7ac7ca316efab2af38c5bbdbe3012794df08a 100644 (file)
@@ -40,6 +40,7 @@ use crate::collections::{BTreeMap, HashSet, VecDeque};
 use alloc::string::String;
 use alloc::vec::Vec;
 use core::cmp::max;
+use miniscript::miniscript::limits::{MAX_PUBKEYS_IN_CHECKSIGADD, MAX_PUBKEYS_PER_MULTISIG};
 
 use core::fmt;
 
@@ -48,12 +49,12 @@ use serde::{Serialize, Serializer};
 
 use bitcoin::bip32::Fingerprint;
 use bitcoin::hashes::{hash160, ripemd160, sha256};
-use bitcoin::{absolute, key::XOnlyPublicKey, PublicKey, Sequence};
+use bitcoin::{absolute, key::XOnlyPublicKey, relative, PublicKey, Sequence};
 
 use miniscript::descriptor::{
     DescriptorPublicKey, ShInner, SinglePub, SinglePubKey, SortedMultiVec, WshInner,
 };
-use miniscript::hash256;
+use miniscript::{hash256, Threshold};
 use miniscript::{
     Descriptor, Miniscript, Satisfier, ScriptContext, SigType, Terminal, ToPublicKey,
 };
@@ -137,7 +138,7 @@ pub enum SatisfiableItem {
     /// Relative timelock locktime
     RelativeTimelock {
         /// The timelock value
-        value: Sequence,
+        value: relative::LockTime,
     },
     /// Multi-signature public keys with threshold count
     Multisig {
@@ -586,30 +587,25 @@ impl Policy {
         Ok(Some(policy))
     }
 
-    fn make_multisig<Ctx: ScriptContext + 'static>(
-        keys: &[DescriptorPublicKey],
+    fn make_multi<Ctx: ScriptContext + 'static>(
+        threshold: &Threshold<DescriptorPublicKey, MAX_PUBKEYS_PER_MULTISIG>,
         signers: &SignersContainer,
         build_sat: BuildSatisfaction,
-        threshold: usize,
         sorted: bool,
         secp: &SecpCtx,
     ) -> Result<Option<Policy>, PolicyError> {
-        if threshold == 0 {
-            return Ok(None);
-        }
-
-        let parsed_keys = keys.iter().map(|k| PkOrF::from_key(k, secp)).collect();
+        let parsed_keys = threshold.iter().map(|k| PkOrF::from_key(k, secp)).collect();
 
         let mut contribution = Satisfaction::Partial {
-            n: keys.len(),
-            m: threshold,
+            n: threshold.n(),
+            m: threshold.k(),
             items: vec![],
             conditions: Default::default(),
             sorted: Some(sorted),
         };
         let mut satisfaction = contribution.clone();
 
-        for (index, key) in keys.iter().enumerate() {
+        for (index, key) in threshold.iter().enumerate() {
             if signers.find(signer_id(key, secp)).is_some() {
                 contribution.add(
                     &Satisfaction::Complete {
@@ -635,7 +631,7 @@ impl Policy {
 
         let mut policy: Policy = SatisfiableItem::Multisig {
             keys: parsed_keys,
-            threshold,
+            threshold: threshold.k(),
         }
         .into();
         policy.contribution = contribution;
@@ -644,6 +640,57 @@ impl Policy {
         Ok(Some(policy))
     }
 
+    fn make_multi_a<Ctx: ScriptContext + 'static>(
+        threshold: &Threshold<DescriptorPublicKey, MAX_PUBKEYS_IN_CHECKSIGADD>,
+        signers: &SignersContainer,
+        build_sat: BuildSatisfaction,
+        sorted: bool,
+        secp: &SecpCtx,
+    ) -> Result<Option<Policy>, PolicyError> {
+        let parsed_keys = threshold.iter().map(|k| PkOrF::from_key(k, secp)).collect();
+
+        let mut contribution = Satisfaction::Partial {
+            n: threshold.n(),
+            m: threshold.k(),
+            items: vec![],
+            conditions: Default::default(),
+            sorted: Some(sorted),
+        };
+        let mut satisfaction = contribution.clone();
+
+        for (index, key) in threshold.iter().enumerate() {
+            if signers.find(signer_id(key, secp)).is_some() {
+                contribution.add(
+                    &Satisfaction::Complete {
+                        condition: Default::default(),
+                    },
+                    index,
+                )?;
+            }
+            if let Some(psbt) = build_sat.psbt() {
+                if Ctx::find_signature(psbt, key, secp) {
+                    satisfaction.add(
+                        &Satisfaction::Complete {
+                            condition: Default::default(),
+                        },
+                        index,
+                    )?;
+                }
+            }
+        }
+        satisfaction.finalize();
+        contribution.finalize();
+
+        let mut policy: Policy = SatisfiableItem::Multisig {
+            keys: parsed_keys,
+            threshold: threshold.k(),
+        }
+        .into();
+        policy.contribution = contribution;
+        policy.satisfaction = satisfaction;
+        Ok(Some(policy))
+    }
+
     /// Return whether or not a specific path in the policy tree is required to unambiguously
     /// create a transaction
     ///
@@ -725,7 +772,7 @@ impl Policy {
                 timelock: Some(*value),
             }),
             SatisfiableItem::RelativeTimelock { value } => Ok(Condition {
-                csv: Some(*value),
+                csv: Some((*value).into()),
                 timelock: None,
             }),
             _ => Ok(Condition::default()),
@@ -952,11 +999,14 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
                 Some(policy)
             }
             Terminal::Older(value) => {
-                let mut policy: Policy = SatisfiableItem::RelativeTimelock { value: *value }.into();
+                let mut policy: Policy = SatisfiableItem::RelativeTimelock {
+                    value: (*value).into(),
+                }
+                .into();
                 policy.contribution = Satisfaction::Complete {
                     condition: Condition {
                         timelock: None,
-                        csv: Some(*value),
+                        csv: Some((*value).into()),
                     },
                 };
                 if let BuildSatisfaction::PsbtTimelocks {
@@ -966,9 +1016,11 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
                 } = build_sat
                 {
                     let older = Older::new(Some(current_height), Some(input_max_height), false);
-                    let older_sat = Satisfier::<bitcoin::PublicKey>::check_older(&older, *value);
-                    let inputs_sat = psbt_inputs_sat(psbt)
-                        .all(|sat| Satisfier::<bitcoin::PublicKey>::check_older(&sat, *value));
+                    let older_sat =
+                        Satisfier::<bitcoin::PublicKey>::check_older(&older, (*value).into());
+                    let inputs_sat = psbt_inputs_sat(psbt).all(|sat| {
+                        Satisfier::<bitcoin::PublicKey>::check_older(&sat, (*value).into())
+                    });
                     if older_sat && inputs_sat {
                         policy.satisfaction = policy.contribution.clone();
                     }
@@ -986,8 +1038,11 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
             Terminal::Hash160(hash) => {
                 Some(SatisfiableItem::Hash160Preimage { hash: *hash }.into())
             }
-            Terminal::Multi(k, pks) | Terminal::MultiA(k, pks) => {
-                Policy::make_multisig::<Ctx>(pks, signers, build_sat, *k, false, secp)?
+            Terminal::Multi(threshold) => {
+                Policy::make_multi::<Ctx>(threshold, signers, build_sat, false, secp)?
+            }
+            Terminal::MultiA(threshold) => {
+                Policy::make_multi_a::<Ctx>(threshold, signers, build_sat, false, secp)?
             }
             // Identities
             Terminal::Alt(inner)
@@ -1016,8 +1071,9 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
                 a.extract_policy(signers, build_sat, secp)?,
                 b.extract_policy(signers, build_sat, secp)?,
             )?,
-            Terminal::Thresh(k, nodes) => {
-                let mut threshold = *k;
+            Terminal::Thresh(threshold) => {
+                let mut k = threshold.k();
+                let nodes = threshold.data();
                 let mapped: Vec<_> = nodes
                     .iter()
                     .map(|n| n.extract_policy(signers, build_sat, secp))
@@ -1027,13 +1083,13 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
                     .collect();
 
                 if mapped.len() < nodes.len() {
-                    threshold = match threshold.checked_sub(nodes.len() - mapped.len()) {
+                    k = match k.checked_sub(nodes.len() - mapped.len()) {
                         None => return Ok(None),
                         Some(x) => x,
                     };
                 }
 
-                Policy::make_thresh(mapped, threshold)?
+                Policy::make_thresh(mapped, k)?
             }
 
             // Unsupported
@@ -1087,13 +1143,10 @@ impl ExtractPolicy for Descriptor<DescriptorPublicKey> {
             build_sat: BuildSatisfaction,
             secp: &SecpCtx,
         ) -> Result<Option<Policy>, Error> {
-            Ok(Policy::make_multisig::<Ctx>(
-                keys.pks.as_ref(),
-                signers,
-                build_sat,
-                keys.k,
-                true,
-                secp,
+            let threshold = Threshold::new(keys.k(), keys.pks().to_vec())
+                .expect("valid threshold and pks collection");
+            Ok(Policy::make_multi::<Ctx>(
+                &threshold, signers, build_sat, true, secp,
             )?)
         }
 
index 61d6165b9449c343aaaae2f2f7d7395fa3dd9fb3..9eb375169b4c9ab3b7008106f78b6c9fac10e6c7 100644 (file)
@@ -583,7 +583,7 @@ mod test {
         use bitcoin::bip32::ChildNumber::{self, Hardened};
 
         let xprvkey = bitcoin::bip32::Xpriv::from_str("xprv9s21ZrQH143K2fpbqApQL69a4oKdGVnVN52R82Ft7d1pSqgKmajF62acJo3aMszZb6qQ22QsVECSFxvf9uyxFUvFYQMq3QbtwtRSMjLAhMf").unwrap();
-        assert_eq!(Network::Bitcoin, xprvkey.network);
+        assert!(xprvkey.network.is_mainnet());
         let xdesc = Bip44(xprvkey, KeychainKind::Internal)
             .build(Network::Bitcoin)
             .unwrap();
@@ -597,7 +597,7 @@ mod test {
         }
 
         let tprvkey = bitcoin::bip32::Xpriv::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
-        assert_eq!(Network::Testnet, tprvkey.network);
+        assert!(!tprvkey.network.is_mainnet());
         let tdesc = Bip44(tprvkey, KeychainKind::Internal)
             .build(Network::Testnet)
             .unwrap();
index 5f6b54cd169683207b012478a1009d42f06e0722..10827034886443583f6f1c4e39b628575f88c423 100644 (file)
@@ -336,7 +336,7 @@ impl<Ctx: ScriptContext> ExtendedKey<Ctx> {
     pub fn into_xprv(self, network: Network) -> Option<bip32::Xpriv> {
         match self {
             ExtendedKey::Private((mut xprv, _)) => {
-                xprv.network = network;
+                xprv.network = network.into();
                 Some(xprv)
             }
             ExtendedKey::Public(_) => None,
@@ -355,7 +355,7 @@ impl<Ctx: ScriptContext> ExtendedKey<Ctx> {
             ExtendedKey::Public((xpub, _)) => xpub,
         };
 
-        xpub.network = network;
+        xpub.network = network.into();
         xpub
     }
 }
@@ -402,7 +402,7 @@ impl<Ctx: ScriptContext> From<bip32::Xpriv> for ExtendedKey<Ctx> {
 /// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
 ///     fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
 ///         let xprv = bip32::Xpriv {
-///             network: self.network,
+///             network: self.network.into(),
 ///             depth: 0,
 ///             parent_fingerprint: bip32::Fingerprint::default(),
 ///             private_key: self.key_data.inner,
@@ -434,7 +434,7 @@ impl<Ctx: ScriptContext> From<bip32::Xpriv> for ExtendedKey<Ctx> {
 /// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
 ///     fn into_extended_key(self) -> Result<ExtendedKey<Ctx>, KeyError> {
 ///         let xprv = bip32::Xpriv {
-///             network: bitcoin::Network::Bitcoin, // pick an arbitrary network here
+///             network: bitcoin::Network::Bitcoin.into(), // pick an arbitrary network here
 ///             depth: 0,
 ///             parent_fingerprint: bip32::Fingerprint::default(),
 ///             private_key: self.key_data.inner,
@@ -717,7 +717,7 @@ impl<Ctx: ScriptContext> GeneratableKey<Ctx> for PrivateKey {
         let inner = secp256k1::SecretKey::from_slice(&entropy)?;
         let private_key = PrivateKey {
             compressed: options.compressed,
-            network: Network::Bitcoin,
+            network: Network::Bitcoin.into(),
             inner,
         };
 
@@ -847,9 +847,7 @@ impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey {
     fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
         let networks = match self {
             DescriptorPublicKey::Single(_) => any_network(),
-            DescriptorPublicKey::XPub(DescriptorXKey { xkey, .. })
-                if xkey.network == Network::Bitcoin =>
-            {
+            DescriptorPublicKey::XPub(DescriptorXKey { xkey, .. }) if xkey.network.is_mainnet() => {
                 mainnet_network()
             }
             _ => test_networks(),
@@ -882,12 +880,8 @@ impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for XOnlyPublicKey {
 impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey {
     fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
         let networks = match &self {
-            DescriptorSecretKey::Single(sk) if sk.key.network == Network::Bitcoin => {
-                mainnet_network()
-            }
-            DescriptorSecretKey::XPrv(DescriptorXKey { xkey, .. })
-                if xkey.network == Network::Bitcoin =>
-            {
+            DescriptorSecretKey::Single(sk) if sk.key.network.is_mainnet() => mainnet_network(),
+            DescriptorSecretKey::XPrv(DescriptorXKey { xkey, .. }) if xkey.network.is_mainnet() => {
                 mainnet_network()
             }
             _ => test_networks(),
@@ -1003,6 +997,6 @@ pub mod test {
         .unwrap();
         let xprv = xkey.into_xprv(Network::Testnet).unwrap();
 
-        assert_eq!(xprv.network, Network::Testnet);
+        assert_eq!(xprv.network, Network::Testnet.into());
     }
 }
index 5df64796a5f250b1ca8960ffa3c1986670eb0c05..7bffb91d959ece8165c82cedb8b3a7dfc56be48f 100644 (file)
@@ -316,7 +316,7 @@ pub fn decide_change(remaining_amount: u64, fee_rate: FeeRate, drain_script: &Sc
     let drain_val = remaining_amount.saturating_sub(change_fee);
 
     if drain_val.is_dust(drain_script) {
-        let dust_threshold = drain_script.dust_value().to_sat();
+        let dust_threshold = drain_script.minimal_non_dust().to_sat();
         Excess::NoChange {
             dust_threshold,
             change_fee,
index 3697f91ddd068911f048bf83cb66f4c0eb9b70c8..41f463a461a5677b7ff3900f656d9fddea155742 100644 (file)
@@ -164,7 +164,7 @@ impl FullyNodedExport {
         fn check_ms<Ctx: ScriptContext>(
             terminal: &Terminal<String, Ctx>,
         ) -> Result<(), &'static str> {
-            if let Terminal::Multi(_, _) = terminal {
+            if let Terminal::Multi(_) = terminal {
                 Ok(())
             } else {
                 Err("The descriptor contains operators not supported by Bitcoin Core")
index 0d661727dd59cb5aa441605d6875be37ef79e6ef..64d9cfa9ccf6fdd385e7d79840f43d09f75d72ef 100644 (file)
@@ -1177,7 +1177,7 @@ impl Wallet {
         };
 
         let mut changeset = ChangeSet::default();
-        let txid = tx.txid();
+        let txid = tx.compute_txid();
         changeset.append(self.indexed_graph.insert_tx(tx).into());
         if let Some(anchor) = anchor {
             changeset.append(self.indexed_graph.insert_anchor(txid, anchor).into());
@@ -1478,10 +1478,7 @@ impl Wallet {
         let recipients = params.recipients.iter().map(|(r, v)| (r, *v));
 
         for (index, (script_pubkey, value)) in recipients.enumerate() {
-            if !params.allow_dust
-                && value.is_dust(script_pubkey)
-                && !script_pubkey.is_provably_unspendable()
-            {
+            if !params.allow_dust && value.is_dust(script_pubkey) && !script_pubkey.is_op_return() {
                 return Err(CreateTxError::OutputBelowDustLimit(index));
             }
 
@@ -1635,7 +1632,7 @@ impl Wallet {
     /// let tx = psbt.clone().extract_tx().expect("tx");
     /// // broadcast tx but it's taking too long to confirm so we want to bump the fee
     /// let mut psbt =  {
-    ///     let mut builder = wallet.build_fee_bump(tx.txid())?;
+    ///     let mut builder = wallet.build_fee_bump(tx.compute_txid())?;
     ///     builder
     ///         .fee_rate(FeeRate::from_sat_per_vb(5).expect("valid feerate"));
     ///     builder.finish()?
@@ -1673,7 +1670,9 @@ impl Wallet {
             .iter()
             .any(|txin| txin.sequence.to_consensus_u32() <= 0xFFFFFFFD)
         {
-            return Err(BuildFeeBumpError::IrreplaceableTransaction(tx.txid()));
+            return Err(BuildFeeBumpError::IrreplaceableTransaction(
+                tx.compute_txid(),
+            ));
         }
 
         let fee = self
@@ -1704,7 +1703,8 @@ impl Wallet {
                         let satisfaction_weight = self
                             .get_descriptor_for_keychain(keychain)
                             .max_weight_to_satisfy()
-                            .unwrap();
+                            .unwrap()
+                            .to_wu() as usize;
                         WeightedUtxo {
                             utxo: Utxo::Local(LocalOutput {
                                 outpoint: txin.previous_output,
@@ -2037,6 +2037,7 @@ impl Wallet {
                     self.get_descriptor_for_keychain(keychain)
                         .max_weight_to_satisfy()
                         .unwrap()
+                        .to_wu() as usize
                 })
             })
             .collect()
index 280e7066f4bb2070212e11db5a8dde4458617d8e..c8c523ab02639b43956f5f76054ad4009456eb63 100644 (file)
@@ -91,7 +91,7 @@ use bitcoin::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpriv};
 use bitcoin::hashes::hash160;
 use bitcoin::secp256k1::Message;
 use bitcoin::sighash::{EcdsaSighashType, TapSighash, TapSighashType};
-use bitcoin::{ecdsa, psbt, sighash, taproot};
+use bitcoin::{ecdsa, psbt, sighash, taproot, transaction};
 use bitcoin::{key::TapTweak, key::XOnlyPublicKey, secp256k1};
 use bitcoin::{PrivateKey, Psbt, PublicKey};
 
@@ -159,8 +159,12 @@ pub enum SignerError {
     NonStandardSighash,
     /// Invalid SIGHASH for the signing context in use
     InvalidSighash,
-    /// Error while computing the hash to sign
-    SighashError(sighash::Error),
+    /// Error while computing the hash to sign a P2WPKH input.
+    SighashP2wpkh(sighash::P2wpkhError),
+    /// Error while computing the hash to sign a Taproot input.
+    SighashTaproot(sighash::TaprootError),
+    /// Error while computing the hash, out of bounds access on the transaction inputs.
+    TxInputsIndexError(transaction::InputsIndexError),
     /// Miniscript PSBT error
     MiniscriptPsbt(MiniscriptPsbtError),
     /// To be used only by external libraries implementing [`InputSigner`] or
@@ -169,9 +173,21 @@ pub enum SignerError {
     External(String),
 }
 
-impl From<sighash::Error> for SignerError {
-    fn from(e: sighash::Error) -> Self {
-        SignerError::SighashError(e)
+impl From<transaction::InputsIndexError> for SignerError {
+    fn from(v: transaction::InputsIndexError) -> Self {
+        Self::TxInputsIndexError(v)
+    }
+}
+
+impl From<sighash::P2wpkhError> for SignerError {
+    fn from(e: sighash::P2wpkhError) -> Self {
+        Self::SighashP2wpkh(e)
+    }
+}
+
+impl From<sighash::TaprootError> for SignerError {
+    fn from(e: sighash::TaprootError) -> Self {
+        Self::SighashTaproot(e)
     }
 }
 
@@ -189,7 +205,9 @@ impl fmt::Display for SignerError {
             Self::MissingHdKeypath => write!(f, "Missing fingerprint and derivation path"),
             Self::NonStandardSighash => write!(f, "The psbt contains a non standard sighash"),
             Self::InvalidSighash => write!(f, "Invalid SIGHASH for the signing context in use"),
-            Self::SighashError(err) => write!(f, "Error while computing the hash to sign: {}", err),
+            Self::SighashP2wpkh(err) => write!(f, "Error while computing the hash to sign a P2WPKH input: {}", err),
+            Self::SighashTaproot(err) => write!(f, "Error while computing the hash to sign a Taproot input: {}", err),
+            Self::TxInputsIndexError(err) => write!(f, "Error while computing the hash, out of bounds access on the transaction inputs: {}", err),
             Self::MiniscriptPsbt(err) => write!(f, "Miniscript PSBT error: {}", err),
             Self::External(err) => write!(f, "{}", err),
         }
@@ -549,21 +567,24 @@ fn sign_psbt_ecdsa(
     secret_key: &secp256k1::SecretKey,
     pubkey: PublicKey,
     psbt_input: &mut psbt::Input,
-    hash: impl bitcoin::hashes::Hash + bitcoin::secp256k1::ThirtyTwoByteHash,
-    hash_ty: EcdsaSighashType,
+    hash: impl bitcoin::hashes::Hash<Bytes = [u8; 32]>,
+    sighash_type: EcdsaSighashType,
     secp: &SecpCtx,
     allow_grinding: bool,
 ) {
-    let msg = &Message::from(hash);
-    let sig = if allow_grinding {
+    let msg = &Message::from_digest(hash.to_byte_array());
+    let signature = if allow_grinding {
         secp.sign_ecdsa_low_r(msg, secret_key)
     } else {
         secp.sign_ecdsa(msg, secret_key)
     };
-    secp.verify_ecdsa(msg, &sig, &pubkey.inner)
+    secp.verify_ecdsa(msg, &signature, &pubkey.inner)
         .expect("invalid or corrupted ecdsa signature");
 
-    let final_signature = ecdsa::Signature { sig, hash_ty };
+    let final_signature = ecdsa::Signature {
+        signature,
+        sighash_type,
+    };
     psbt_input.partial_sigs.insert(pubkey, final_signature);
 }
 
@@ -574,7 +595,7 @@ fn sign_psbt_schnorr(
     leaf_hash: Option<taproot::TapLeafHash>,
     psbt_input: &mut psbt::Input,
     hash: TapSighash,
-    hash_ty: TapSighashType,
+    sighash_type: TapSighashType,
     secp: &SecpCtx,
 ) {
     let keypair = secp256k1::Keypair::from_seckey_slice(secp, secret_key.as_ref()).unwrap();
@@ -586,11 +607,14 @@ fn sign_psbt_schnorr(
     };
 
     let msg = &Message::from(hash);
-    let sig = secp.sign_schnorr(msg, &keypair);
-    secp.verify_schnorr(&sig, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
+    let signature = secp.sign_schnorr(msg, &keypair);
+    secp.verify_schnorr(&signature, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
         .expect("invalid or corrupted schnorr signature");
 
-    let final_signature = taproot::Signature { sig, hash_ty };
+    let final_signature = taproot::Signature {
+        signature,
+        sighash_type,
+    };
 
     if let Some(lh) = leaf_hash {
         psbt_input
@@ -933,7 +957,7 @@ impl ComputeSighash for Segwitv0 {
         // Always try first with the non-witness utxo
         let utxo = if let Some(prev_tx) = &psbt_input.non_witness_utxo {
             // Check the provided prev-tx
-            if prev_tx.txid() != tx_input.previous_output.txid {
+            if prev_tx.compute_txid() != tx_input.previous_output.txid {
                 return Err(SignerError::InvalidNonWitnessUtxo);
             }
 
index fbe5081f71052ba2bf6abe45be87ac847a398d8e..7b02248d9470b64c901a62afc3342141f8f8281f 100644 (file)
@@ -295,7 +295,9 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
 
             for utxo in utxos {
                 let descriptor = wallet.get_descriptor_for_keychain(utxo.keychain);
-                let satisfaction_weight = descriptor.max_weight_to_satisfy().unwrap();
+
+                let satisfaction_weight =
+                    descriptor.max_weight_to_satisfy().unwrap().to_wu() as usize;
                 self.params.utxos.push(WeightedUtxo {
                     satisfaction_weight,
                     utxo: Utxo::Local(utxo),
@@ -385,9 +387,9 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
         if psbt_input.witness_utxo.is_none() {
             match psbt_input.non_witness_utxo.as_ref() {
                 Some(tx) => {
-                    if tx.txid() != outpoint.txid {
+                    if tx.compute_txid() != outpoint.txid {
                         return Err(AddForeignUtxoError::InvalidTxid {
-                            input_txid: tx.txid(),
+                            input_txid: tx.compute_txid(),
                             foreign_utxo: outpoint,
                         });
                     }
index 208a88dfe176c3aef69906af4b8e057d2826b727..402361134bdafac1baae56cf967ec47ab206a30b 100644 (file)
@@ -10,7 +10,7 @@
 // licenses.
 
 use bitcoin::secp256k1::{All, Secp256k1};
-use bitcoin::{absolute, Script, Sequence};
+use bitcoin::{absolute, relative, Script, Sequence};
 
 use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
 
@@ -26,7 +26,7 @@ pub trait IsDust {
 
 impl IsDust for u64 {
     fn is_dust(&self, script: &Script) -> bool {
-        *self < script.dust_value().to_sat()
+        *self < script.minimal_non_dust().to_sat()
     }
 }
 
@@ -95,7 +95,7 @@ impl Older {
 }
 
 impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for Older {
-    fn check_older(&self, n: Sequence) -> bool {
+    fn check_older(&self, n: relative::LockTime) -> bool {
         if let Some(current_height) = self.current_height {
             // TODO: test >= / >
             current_height
index d77147f4d8388eb0fbd0dd9d85c1704bbb021d53..0acdc5ea1aed285476ff49b426cdeae6f4516892 100644 (file)
@@ -46,7 +46,7 @@ pub fn get_funded_wallet_with_change(descriptor: &str, change: &str) -> (Wallet,
         lock_time: bitcoin::absolute::LockTime::ZERO,
         input: vec![TxIn {
             previous_output: OutPoint {
-                txid: tx0.txid(),
+                txid: tx0.compute_txid(),
                 vout: 0,
             },
             script_sig: Default::default(),
@@ -96,7 +96,7 @@ pub fn get_funded_wallet_with_change(descriptor: &str, change: &str) -> (Wallet,
         )
         .unwrap();
 
-    (wallet, tx1.txid())
+    (wallet, tx1.compute_txid())
 }
 
 /// Return a fake wallet that appears to be funded for testing.
index dff699a6ff341bf4d1e728bb9949a5a835090a4f..17dbabc856366e13b82d24fcb67e41445261a8ce 100644 (file)
@@ -45,7 +45,7 @@ fn receive_output(wallet: &mut Wallet, value: u64, height: ConfirmationTime) ->
     wallet.insert_tx(tx.clone(), height).unwrap();
 
     OutPoint {
-        txid: tx.txid(),
+        txid: tx.compute_txid(),
         vout: 0,
     }
 }
@@ -1151,7 +1151,7 @@ fn test_create_tx_add_utxo() {
     builder
         .add_recipient(addr.script_pubkey(), Amount::from_sat(30_000))
         .add_utxo(OutPoint {
-            txid: small_output_tx.txid(),
+            txid: small_output_tx.compute_txid(),
             vout: 0,
         })
         .unwrap();
@@ -1202,7 +1202,7 @@ fn test_create_tx_manually_selected_insufficient() {
     builder
         .add_recipient(addr.script_pubkey(), Amount::from_sat(30_000))
         .add_utxo(OutPoint {
-            txid: small_output_tx.txid(),
+            txid: small_output_tx.compute_txid(),
             vout: 0,
         })
         .unwrap()
@@ -1306,8 +1306,6 @@ fn test_create_tx_policy_path_ignored_subtree_with_csv() {
 #[test]
 fn test_create_tx_global_xpubs_with_origin() {
     use bitcoin::bip32;
-    use bitcoin::hex::FromHex;
-
     let (mut wallet, _) = get_funded_wallet("wpkh([73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
     let addr = wallet.next_unused_address(KeychainKind::External).unwrap();
     let mut builder = wallet.build_tx();
@@ -1348,7 +1346,11 @@ fn test_add_foreign_utxo() {
     builder
         .add_recipient(addr.script_pubkey(), Amount::from_sat(60_000))
         .only_witness_utxo()
-        .add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
+        .add_foreign_utxo(
+            utxo.outpoint,
+            psbt_input,
+            foreign_utxo_satisfaction.to_wu() as usize,
+        )
         .unwrap();
     let mut psbt = builder.finish().unwrap();
     wallet1.insert_txout(utxo.outpoint, utxo.txout);
@@ -1399,7 +1401,7 @@ fn test_add_foreign_utxo() {
 
 #[test]
 #[should_panic(
-    expected = "MissingTxOut([OutPoint { txid: 0x21d7fb1bceda00ab4069fc52d06baa13470803e9050edd16f5736e5d8c4925fd, vout: 0 }])"
+    expected = "MissingTxOut([OutPoint { txid: 21d7fb1bceda00ab4069fc52d06baa13470803e9050edd16f5736e5d8c4925fd, vout: 0 }])"
 )]
 fn test_calculate_fee_with_missing_foreign_utxo() {
     let (mut wallet1, _) = get_funded_wallet_wpkh();
@@ -1424,7 +1426,11 @@ fn test_calculate_fee_with_missing_foreign_utxo() {
     builder
         .add_recipient(addr.script_pubkey(), Amount::from_sat(60_000))
         .only_witness_utxo()
-        .add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
+        .add_foreign_utxo(
+            utxo.outpoint,
+            psbt_input,
+            foreign_utxo_satisfaction.to_wu() as usize,
+        )
         .unwrap();
     let psbt = builder.finish().unwrap();
     let tx = psbt.extract_tx().expect("failed to extract tx");
@@ -1441,8 +1447,11 @@ fn test_add_foreign_utxo_invalid_psbt_input() {
         .unwrap();
 
     let mut builder = wallet.build_tx();
-    let result =
-        builder.add_foreign_utxo(outpoint, psbt::Input::default(), foreign_utxo_satisfaction);
+    let result = builder.add_foreign_utxo(
+        outpoint,
+        psbt::Input::default(),
+        foreign_utxo_satisfaction.to_wu() as usize,
+    );
     assert!(matches!(result, Err(AddForeignUtxoError::MissingUtxo)));
 }
 
@@ -1470,7 +1479,7 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
                     non_witness_utxo: Some(tx1.as_ref().clone()),
                     ..Default::default()
                 },
-                satisfaction_weight
+                satisfaction_weight.to_wu() as usize
             )
             .is_err(),
         "should fail when outpoint doesn't match psbt_input"
@@ -1483,7 +1492,7 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
                     non_witness_utxo: Some(tx2.as_ref().clone()),
                     ..Default::default()
                 },
-                satisfaction_weight
+                satisfaction_weight.to_wu() as usize
             )
             .is_ok(),
         "should be ok when outpoint does match psbt_input"
@@ -1515,7 +1524,11 @@ fn test_add_foreign_utxo_only_witness_utxo() {
             ..Default::default()
         };
         builder
-            .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
+            .add_foreign_utxo(
+                utxo2.outpoint,
+                psbt_input,
+                satisfaction_weight.to_wu() as usize,
+            )
             .unwrap();
         assert!(
             builder.finish().is_err(),
@@ -1531,7 +1544,11 @@ fn test_add_foreign_utxo_only_witness_utxo() {
         };
         builder
             .only_witness_utxo()
-            .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
+            .add_foreign_utxo(
+                utxo2.outpoint,
+                psbt_input,
+                satisfaction_weight.to_wu() as usize,
+            )
             .unwrap();
         assert!(
             builder.finish().is_ok(),
@@ -1547,7 +1564,11 @@ fn test_add_foreign_utxo_only_witness_utxo() {
             ..Default::default()
         };
         builder
-            .add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
+            .add_foreign_utxo(
+                utxo2.outpoint,
+                psbt_input,
+                satisfaction_weight.to_wu() as usize,
+            )
             .unwrap();
         assert!(
             builder.finish().is_ok(),
@@ -1583,8 +1604,6 @@ fn test_create_tx_global_xpubs_origin_missing() {
 #[test]
 fn test_create_tx_global_xpubs_master_without_origin() {
     use bitcoin::bip32;
-    use bitcoin::hex::FromHex;
-
     let (mut wallet, _) = get_funded_wallet("wpkh(tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL/0/*)");
     let addr = wallet.next_unused_address(KeychainKind::External).unwrap();
     let mut builder = wallet.build_tx();
@@ -1613,7 +1632,7 @@ fn test_bump_fee_irreplaceable_tx() {
     let psbt = builder.finish().unwrap();
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -1630,7 +1649,7 @@ fn test_bump_fee_confirmed_tx() {
     let psbt = builder.finish().unwrap();
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
 
     wallet
         .insert_tx(
@@ -1657,7 +1676,7 @@ fn test_bump_fee_low_fee_rate() {
     let feerate = psbt.fee_rate().unwrap();
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
 
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
@@ -1690,7 +1709,7 @@ fn test_bump_fee_low_abs() {
     let psbt = builder.finish().unwrap();
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
 
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
@@ -1713,7 +1732,7 @@ fn test_bump_fee_zero_abs() {
     let psbt = builder.finish().unwrap();
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -1739,7 +1758,7 @@ fn test_bump_fee_reduce_change() {
     let original_fee = check_fee!(wallet, psbt);
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -1837,7 +1856,7 @@ fn test_bump_fee_reduce_single_recipient() {
     let tx = psbt.clone().extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
     let original_fee = check_fee!(wallet, psbt);
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -1885,7 +1904,7 @@ fn test_bump_fee_absolute_reduce_single_recipient() {
     let original_fee = check_fee!(wallet, psbt);
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -1949,7 +1968,7 @@ fn test_bump_fee_drain_wallet() {
     builder
         .drain_to(addr.script_pubkey())
         .add_utxo(OutPoint {
-            txid: tx.txid(),
+            txid: tx.compute_txid(),
             vout: 0,
         })
         .unwrap()
@@ -1959,7 +1978,7 @@ fn test_bump_fee_drain_wallet() {
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
 
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -2011,7 +2030,7 @@ fn test_bump_fee_remove_output_manually_selected_only() {
         )
         .unwrap();
     let outpoint = OutPoint {
-        txid: init_tx.txid(),
+        txid: init_tx.compute_txid(),
         vout: 0,
     };
     let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
@@ -2027,7 +2046,7 @@ fn test_bump_fee_remove_output_manually_selected_only() {
     let psbt = builder.finish().unwrap();
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -2074,7 +2093,7 @@ fn test_bump_fee_add_input() {
     let psbt = builder.finish().unwrap();
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let original_details = wallet.sent_and_received(&tx);
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -2131,7 +2150,7 @@ fn test_bump_fee_absolute_add_input() {
     let psbt = builder.finish().unwrap();
     let tx = psbt.extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -2197,7 +2216,7 @@ fn test_bump_fee_no_change_add_input_and_change() {
     let original_fee = check_fee!(wallet, psbt);
 
     let tx = psbt.extract_tx().expect("failed to extract tx");
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -2267,7 +2286,7 @@ fn test_bump_fee_add_input_change_dust() {
     let original_tx_weight = tx.weight();
     assert_eq!(tx.input.len(), 1);
     assert_eq!(tx.output.len(), 2);
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     wallet
         .insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
         .unwrap();
@@ -2335,7 +2354,7 @@ fn test_bump_fee_force_add_input() {
     let psbt = builder.finish().unwrap();
     let mut tx = psbt.extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     for txin in &mut tx.input {
         txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
     }
@@ -2401,7 +2420,7 @@ fn test_bump_fee_absolute_force_add_input() {
     let psbt = builder.finish().unwrap();
     let mut tx = psbt.extract_tx().expect("failed to extract tx");
     let original_sent_received = wallet.sent_and_received(&tx);
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     // skip saving the new utxos, we know they can't be used anyways
     for txin in &mut tx.input {
         txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
@@ -2481,7 +2500,7 @@ fn test_bump_fee_unconfirmed_inputs_only() {
         ConfirmationTime::Unconfirmed { last_seen: 0 },
     );
     let mut tx = psbt.extract_tx().expect("failed to extract tx");
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     for txin in &mut tx.input {
         txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
     }
@@ -2514,7 +2533,7 @@ fn test_bump_fee_unconfirmed_input() {
         .enable_rbf();
     let psbt = builder.finish().unwrap();
     let mut tx = psbt.extract_tx().expect("failed to extract tx");
-    let txid = tx.txid();
+    let txid = tx.compute_txid();
     for txin in &mut tx.input {
         txin.witness.push([0x00; P2WPKH_FAKE_WITNESS_SIZE]); // fake signature
     }
@@ -3386,7 +3405,11 @@ fn test_taproot_foreign_utxo() {
     let mut builder = wallet1.build_tx();
     builder
         .add_recipient(addr.script_pubkey(), Amount::from_sat(60_000))
-        .add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
+        .add_foreign_utxo(
+            utxo.outpoint,
+            psbt_input,
+            foreign_utxo_satisfaction.to_wu() as usize,
+        )
         .unwrap();
     let psbt = builder.finish().unwrap();
     let sent_received =
@@ -3890,7 +3913,10 @@ fn test_fee_rate_sign_no_grinding_high_r() {
             .unwrap();
         // We only have one key in the partial_sigs map, this is a trick to retrieve it
         let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
-        sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
+        sig_len = psbt.inputs[0].partial_sigs[key]
+            .signature
+            .serialize_der()
+            .len();
     }
     // Actually finalizing the transaction...
     wallet
@@ -3936,7 +3962,10 @@ fn test_fee_rate_sign_grinding_low_r() {
         .unwrap();
 
     let key = psbt.inputs[0].partial_sigs.keys().next().unwrap();
-    let sig_len = psbt.inputs[0].partial_sigs[key].sig.serialize_der().len();
+    let sig_len = psbt.inputs[0].partial_sigs[key]
+        .signature
+        .serialize_der()
+        .len();
     assert_eq!(sig_len, 70);
     assert_fee_rate!(psbt, fee.unwrap_or(Amount::ZERO), fee_rate);
 }
index 319c23805f0794124d8cdc54e5628ee33e6d3ff1..256c4bdf64977265aa47ed269bf16292b7ec7fd4 100644 (file)
@@ -643,7 +643,7 @@ where
 
             match (broadcast)(chain_specific, &transaction) {
                 Ok(_) => {
-                    println!("Broadcasted Tx : {}", transaction.txid());
+                    println!("Broadcasted Tx : {}", transaction.compute_txid());
 
                     let keychain_changeset = graph.lock().unwrap().insert_tx(transaction);
 
index e6c01c20be15cbec7d0f3ca613bfa9836423de44..d8dbc458f7440c003e9f11e21f3c1db13db8e113 100644 (file)
@@ -94,7 +94,7 @@ fn main() -> Result<(), anyhow::Error> {
 
     let tx = psbt.extract_tx()?;
     client.transaction_broadcast(&tx)?;
-    println!("Tx broadcasted! Txid: {}", tx.txid());
+    println!("Tx broadcasted! Txid: {}", tx.compute_txid());
 
     Ok(())
 }
index f46779b3c1ec73564837fe34c8a0e9a1e2c7aa12..6510c5660e5551876d2b0bd5176553486332ccb8 100644 (file)
@@ -103,7 +103,7 @@ async fn main() -> Result<(), anyhow::Error> {
 
     let tx = psbt.extract_tx()?;
     client.broadcast(&tx).await?;
-    println!("Tx broadcasted! Txid: {}", tx.txid());
+    println!("Tx broadcasted! Txid: {}", tx.compute_txid());
 
     Ok(())
 }
index 92caca2c9b43890fae56886f6fcda6f6aea5158a..5ade6804e0ffede6229a644a21286327ab861e5e 100644 (file)
@@ -80,7 +80,7 @@ fn main() -> Result<(), anyhow::Error> {
 
     let tx = psbt.extract_tx()?;
     client.broadcast(&tx)?;
-    println!("Tx broadcasted! Txid: {}", tx.txid());
+    println!("Tx broadcasted! Txid: {}", tx.compute_txid());
 
     Ok(())
 }
index 6b4da3c9045b117eb5e7a0153b19facd4e75bb8f..8bbcb5ee91a333c724c0cb63b2b70bc66b2ea934 100644 (file)
@@ -240,7 +240,7 @@ fn plan_steps<Ak: Clone + CanDerive, Ctx: ScriptContext>(
             if max_sequence.is_height_locked() == older.is_height_locked() {
                 if max_sequence.to_consensus_u32() >= older.to_consensus_u32() {
                     Some(TermPlan {
-                        min_sequence: Some(*older),
+                        min_sequence: Some((*older).into()),
                         ..Default::default()
                     })
                 } else {
@@ -318,8 +318,8 @@ fn plan_steps<Ak: Clone + CanDerive, Ctx: ScriptContext>(
                 (lplan, rplan) => lplan.or(rplan),
             }
         }
-        Terminal::Thresh(_, _) => todo!(),
-        Terminal::Multi(_, _) => todo!(),
-        Terminal::MultiA(_, _) => todo!(),
+        Terminal::Thresh(_) => todo!(),
+        Terminal::Multi(_) => todo!(),
+        Terminal::MultiA(_) => todo!(),
     }
 }
index 520290c0ead53bdafa418264b3aa613e8e1eb2cb..0d0097dbf46caa3b2ca0f132b9db8ef659983a50 100644 (file)
@@ -87,20 +87,28 @@ pub enum RequiredSignatures<Ak> {
 
 #[derive(Clone, Debug)]
 pub enum SigningError {
-    SigHashError(sighash::Error),
+    SigHashP2wpkh(sighash::P2wpkhError),
+    SigHashTaproot(sighash::TaprootError),
     DerivationError(bip32::Error),
 }
 
-impl From<sighash::Error> for SigningError {
-    fn from(e: sighash::Error) -> Self {
-        Self::SigHashError(e)
+impl From<sighash::TaprootError> for SigningError {
+    fn from(v: sighash::TaprootError) -> Self {
+        Self::SigHashTaproot(v)
+    }
+}
+
+impl From<sighash::P2wpkhError> for SigningError {
+    fn from(v: sighash::P2wpkhError) -> Self {
+        Self::SigHashP2wpkh(v)
     }
 }
 
 impl core::fmt::Display for SigningError {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         match self {
-            SigningError::SigHashError(e) => e.fmt(f),
+            SigningError::SigHashP2wpkh(e) => e.fmt(f),
+            SigningError::SigHashTaproot(e) => e.fmt(f),
             SigningError::DerivationError(e) => e.fmt(f),
         }
     }
@@ -170,8 +178,8 @@ impl RequiredSignatures<DescriptorPublicKey> {
                 let sig = secp.sign_schnorr_no_aux_rand(&msg, &keypair);
 
                 let bitcoin_sig = taproot::Signature {
-                    sig,
-                    hash_ty: schnorr_sighashty,
+                    signature: sig,
+                    sighash_type: schnorr_sighashty,
                 };
 
                 auth_data
@@ -210,10 +218,10 @@ impl RequiredSignatures<DescriptorPublicKey> {
                         };
                         let keypair = Keypair::from_secret_key(&secp, &secret_key.clone());
                         let msg = Message::from_digest(sighash.to_byte_array());
-                        let sig = secp.sign_schnorr_no_aux_rand(&msg, &keypair);
+                        let signature = secp.sign_schnorr_no_aux_rand(&msg, &keypair);
                         let bitcoin_sig = taproot::Signature {
-                            sig,
-                            hash_ty: sighash_type,
+                            signature,
+                            sighash_type,
                         };
 
                         auth_data