]> Untitled Git - bdk/commitdiff
build!: Update bdk to rust-bitcoin 0.30.0
authorDaniela Brozzoni <danielabrozzoni@protonmail.com>
Wed, 9 Aug 2023 13:36:45 +0000 (15:36 +0200)
committerDaniela Brozzoni <danielabrozzoni@protonmail.com>
Wed, 16 Aug 2023 13:02:51 +0000 (15:02 +0200)
42 files changed:
Cargo.toml
README.md
examples/electrum_backend.rs
examples/esplora_backend_asynchronous.rs
examples/esplora_backend_synchronous.rs
examples/hardware_signer.rs
examples/mnemonic_to_descriptors.rs
examples/psbt_signer.rs
examples/rpcwallet.rs
examples/utils/mod.rs
src/blockchain/compact_filters/mod.rs
src/blockchain/compact_filters/peer.rs
src/blockchain/compact_filters/store.rs
src/blockchain/compact_filters/sync.rs
src/blockchain/electrum.rs
src/blockchain/esplora/blocking.rs
src/blockchain/rpc.rs
src/blockchain/script_sync.rs
src/database/any.rs
src/database/keyvalue.rs
src/database/memory.rs
src/database/mod.rs
src/database/sqlite.rs
src/descriptor/dsl.rs
src/descriptor/error.rs
src/descriptor/mod.rs
src/descriptor/policy.rs
src/descriptor/template.rs
src/error.rs
src/keys/bip39.rs
src/keys/mod.rs
src/lib.rs
src/psbt/mod.rs
src/testutils/blockchain_tests.rs
src/testutils/mod.rs
src/types.rs
src/wallet/coin_selection.rs
src/wallet/hardwaresigner.rs
src/wallet/mod.rs
src/wallet/signer.rs
src/wallet/tx_builder.rs
src/wallet/utils.rs

index d46913da9e81e81f3d2fa15038a2a0c8acd992de..d90974fb225654d814da8d63e0ed96d5fd68941f 100644 (file)
@@ -14,16 +14,16 @@ license = "MIT OR Apache-2.0"
 [dependencies]
 bdk-macros = "^0.6"
 log = "0.4"
-miniscript = { version = "9.0", default-features = false, features = ["serde"] }
-bitcoin = { version = "0.29.2", default-features = false, features = ["serde", "base64", "rand"] }
+miniscript = { version = "10.0", default-features = false, features = ["serde"] }
+bitcoin = { version = "0.30", default-features = false, features = ["serde", "base64", "rand-std"] }
 serde = { version = "^1.0", features = ["derive"] }
 serde_json = { version = "^1.0" }
 rand = "^0.8"
 
 # Optional dependencies
 sled = { version = "0.34", optional = true }
-electrum-client = { version = "0.12", optional = true }
-esplora-client = { version = "0.4", default-features = false, optional = true }
+electrum-client = { version = "0.18", optional = true }
+esplora-client = { version = "0.6", default-features = false, optional = true }
 rusqlite = { version = "0.28.0", optional = true }
 ahash = { version = "0.7.6", optional = true }
 futures = { version = "0.3", optional = true }
@@ -31,13 +31,13 @@ async-trait = { version = "0.1", optional = true }
 rocksdb = { version = "0.14", default-features = false, features = ["snappy"], optional = true }
 cc = { version = ">=1.0.64", optional = true }
 socks = { version = "0.3", optional = true }
-hwi = { version = "0.5", optional = true, features = ["use-miniscript"] }
+hwi = { version = "0.7", optional = true, features = ["miniscript"] }
 
 bip39 = { version = "2.0.0", optional = true }
 bitcoinconsensus = { version = "0.19.0-3", optional = true }
 
 # Needed by bdk_blockchain_tests macro and the `rpc` feature
-bitcoincore-rpc = { version = "0.16", optional = true }
+bitcoincore-rpc = { package="core-rpc", version = "0.17", optional = true }
 
 # Platform-specific dependencies
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
@@ -107,13 +107,11 @@ test-hardware-signer = ["hardware-signer"]
 dev-getrandom-wasm = ["getrandom/js"]
 
 [dev-dependencies]
-miniscript = { version = "9.0", features = ["std"] }
-bitcoin = { version = "0.29.2", features = ["std"] }
+miniscript = { version = "10.0", features = ["std"] }
+bitcoin = { version = "0.30", features = ["std"] }
 lazy_static = "1.4"
 env_logger = { version = "0.7", default-features = false }
-electrsd = "0.22"
-# Remove after upgrade to rust-bitcoin ^0.30 where base64 is re-exported
-base64 = "^0.13"
+electrsd = "0.24"
 assert_matches = "1.5.0"
 
 [[example]]
index a8a3fa2b9b2eaff96bdee48f26a236071d365bba..039c754880af9c5fa6432fefe9bdf392657b3116 100644 (file)
--- a/README.md
+++ b/README.md
@@ -96,7 +96,7 @@ use bdk::blockchain::ElectrumBlockchain;
 use bdk::electrum_client::Client;
 use bdk::wallet::AddressIndex::New;
 
-use base64;
+use bitcoin::base64;
 use bdk::bitcoin::consensus::serialize;
 use bdk::bitcoin::Network;
 
@@ -123,7 +123,7 @@ fn main() -> Result<(), bdk::Error> {
     };
 
     println!("Transaction details: {:#?}", details);
-    println!("Unsigned PSBT: {}", base64::encode(&serialize(&psbt)));
+    println!("Unsigned PSBT: {}", base64::encode(psbt.serialize()));
 
     Ok(())
 }
@@ -134,9 +134,9 @@ fn main() -> Result<(), bdk::Error> {
 ```rust,no_run
 use bdk::{Wallet, SignOptions, database::MemoryDatabase};
 
-use base64;
+use bitcoin::base64;
 use bdk::bitcoin::consensus::deserialize;
-use bdk::bitcoin::Network;
+use bdk::bitcoin::{psbt::Psbt, Network};
 
 fn main() -> Result<(), bdk::Error> {
     let wallet = Wallet::new(
@@ -147,7 +147,7 @@ fn main() -> Result<(), bdk::Error> {
     )?;
 
     let psbt = "...";
-    let mut psbt = deserialize(&base64::decode(psbt).unwrap())?;
+    let mut psbt = Psbt::deserialize(&base64::decode(psbt).unwrap())?;
 
     let _finalized = wallet.sign(&mut psbt, SignOptions::default())?;
 
index 5259865f38170b1b906a18925f910273a0a75eb3..af81eb18e39bd976f1de3fcfacfca6f2eabd250d 100644 (file)
@@ -1,6 +1,6 @@
 use std::str::FromStr;
 
-use bdk::bitcoin::util::bip32::ExtendedPrivKey;
+use bdk::bitcoin::bip32::ExtendedPrivKey;
 use bdk::bitcoin::Network;
 use bdk::blockchain::{Blockchain, ElectrumBlockchain};
 use bdk::database::MemoryDatabase;
@@ -10,7 +10,7 @@ use bdk::{KeychainKind, SyncOptions, Wallet};
 
 use bdk::electrum_client::Client;
 use bdk::wallet::AddressIndex;
-use bitcoin::util::bip32;
+use bitcoin::bip32;
 
 pub mod utils;
 
index 4aa149ba35cae3d098a75a25e2814aba423501f1..f8b8588c7e336deb364971472305adec4cbbf087 100644 (file)
@@ -9,7 +9,7 @@ use bdk::{
     KeychainKind, SyncOptions, Wallet,
 };
 use bitcoin::{
-    util::bip32::{self, ExtendedPrivKey},
+    bip32::{self, ExtendedPrivKey},
     Network,
 };
 
index 31907f83608c7550b34c10ac53742f84b5e2ccb0..4d2ef68c8301bb000ed104638bdd20af5267fe8f 100644 (file)
@@ -9,7 +9,7 @@ use bdk::{
     KeychainKind, SyncOptions, Wallet,
 };
 use bitcoin::{
-    util::bip32::{self, ExtendedPrivKey},
+    bip32::{self, ExtendedPrivKey},
     Network,
 };
 
index d1c25f1ab89d8a69aa805adb3c2d04a76edde846..9773a7f0ab9c33cdd69bedf93a73336498069c6b 100644 (file)
@@ -1,7 +1,7 @@
 use bdk::bitcoin::{Address, Network};
 use bdk::blockchain::{Blockchain, ElectrumBlockchain};
 use bdk::database::MemoryDatabase;
-use bdk::hwi::{types::HWIChain, HWIClient};
+use bdk::hwi::HWIClient;
 use bdk::miniscript::{Descriptor, DescriptorPublicKey};
 use bdk::signer::SignerOrdering;
 use bdk::wallet::{hardwaresigner::HWISigner, AddressIndex};
@@ -30,7 +30,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     }
     let first_device = devices.remove(0)?;
     // ...and creating a client out of the first one
-    let client = HWIClient::get_client(&first_device, true, HWIChain::Test)?;
+    let client = HWIClient::get_client(&first_device, true, Network::Testnet.into())?;
     println!("Look what I found, a {}!", first_device.model);
 
     // Getting the HW's public descriptors
@@ -41,7 +41,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     );
 
     // Creating a custom signer from the device
-    let custom_signer = HWISigner::from_device(&first_device, HWIChain::Test)?;
+    let custom_signer = HWISigner::from_device(&first_device, Network::Testnet.into())?;
     let mut wallet = Wallet::new(
         descriptors.receive[0].clone(),
         Some(descriptors.internal[0].clone()),
@@ -77,7 +77,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
         return Ok(());
     }
 
-    let return_address = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?;
+    let return_address = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?
+        .require_network(Network::Testnet)?;
     let (mut psbt, _details) = {
         let mut builder = wallet.build_tx();
         builder
index 0a560a528d4449ec376cf25688cfd9b7fbdd2a7a..7d2dd6013ffba96c769e2c4167603c301c6e9937 100644 (file)
@@ -6,8 +6,8 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
+use bdk::bitcoin::bip32::DerivationPath;
 use bdk::bitcoin::secp256k1::Secp256k1;
-use bdk::bitcoin::util::bip32::DerivationPath;
 use bdk::bitcoin::Network;
 use bdk::descriptor;
 use bdk::descriptor::IntoWalletDescriptor;
index 35c539dad511a69a023780fc56ab8f779a40de2a..1a7eb34f3a408b304c867959cb7de549085f6fe5 100644 (file)
@@ -92,7 +92,8 @@ fn main() -> Result<(), Box<dyn Error>> {
         }
     } else {
         println!("Creating a PSBT sending 9800 SATs plus fee to the u01.net testnet faucet return address 'tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt'.");
-        let return_address = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?;
+        let return_address = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")?
+            .require_network(Network::Testnet)?;
         let mut builder = watch_only_wallet.build_tx();
         builder
             .add_recipient(return_address.script_pubkey(), 9_800)
index 24a55591033601a0c9d8b4fd954e2b4f90a98f3c..7e1dcb9bca865190b9704e330b78e9d5cf51f08d 100644 (file)
@@ -62,7 +62,10 @@ fn main() -> Result<(), Box<dyn Error>> {
     };
 
     // Get a new core address
-    let core_address = bitcoind.client.get_new_address(None, None)?;
+    let core_address = bitcoind
+        .client
+        .get_new_address(None, None)?
+        .require_network(Network::Regtest)?;
 
     // Generate 101 blocks and use the above address as coinbase
     bitcoind.client.generate_to_address(101, &core_address)?;
index 25249fa7e31af6cde33caa8c4e5ad868ec9e4737..76aa49d59d47886b51d149580aef2dda84cc5741 100644 (file)
@@ -13,7 +13,10 @@ pub(crate) mod tx {
         // Create a transaction builder
         let mut tx_builder = wallet.build_tx();
 
-        let to_address = Address::from_str(recipient_address).unwrap();
+        let to_address = Address::from_str(recipient_address)
+            .unwrap()
+            .require_network(wallet.network())
+            .unwrap();
 
         // Set recipient of the transaction
         tx_builder.set_recipients(vec![(to_address.script_pubkey(), amount)]);
index 7845d513d1b2fb97d799dc18c072cb7409b82bd4..0c13d75fd3309f1d6d9f8a667a47354e420fc8b6 100644 (file)
@@ -355,7 +355,7 @@ impl WalletSync for CompactFiltersBlockchain {
                     peer,
                     |block_hash, filter| {
                         if !filter
-                            .match_any(block_hash, &mut all_scripts.iter().map(AsRef::as_ref))?
+                            .match_any(block_hash, all_scripts.iter().map(|s| s.as_slice()))?
                         {
                             return Ok(false);
                         }
@@ -570,7 +570,7 @@ pub enum CompactFiltersError {
     /// Internal I/O error
     Io(std::io::Error),
     /// Invalid BIP158 filter
-    Bip158(bitcoin::util::bip158::Error),
+    Bip158(bitcoin::bip158::Error),
     /// Internal system time error
     Time(std::time::SystemTimeError),
 
@@ -608,7 +608,7 @@ impl std::error::Error for CompactFiltersError {}
 
 impl_error!(rocksdb::Error, Db, CompactFiltersError);
 impl_error!(std::io::Error, Io, CompactFiltersError);
-impl_error!(bitcoin::util::bip158::Error, Bip158, CompactFiltersError);
+impl_error!(bitcoin::bip158::Error, Bip158, CompactFiltersError);
 impl_error!(std::time::SystemTimeError, Time, CompactFiltersError);
 
 impl From<crate::error::Error> for CompactFiltersError {
index 665a033d4be951253a6e3e6026e2ebe56bcfe89a..670472aba5c0e08b3b43c47b783046ea800d0102 100644 (file)
@@ -27,7 +27,7 @@ use bitcoin::network::message::{NetworkMessage, RawNetworkMessage};
 use bitcoin::network::message_blockdata::*;
 use bitcoin::network::message_filter::*;
 use bitcoin::network::message_network::VersionMessage;
-use bitcoin::network::Address;
+use bitcoin::network::{Address, Magic};
 use bitcoin::{Block, Network, Transaction, Txid, Wtxid};
 
 use super::CompactFiltersError;
@@ -242,7 +242,7 @@ impl Peer {
     /// Send a Bitcoin network message
     fn _send(
         writer: &mut TcpStream,
-        magic: u32,
+        magic: Magic,
         payload: NetworkMessage,
     ) -> Result<(), CompactFiltersError> {
         log::trace!("==> {:?}", payload);
index 6b8d4943bd45b51da77588b8edbba647fcfc9552..373d3573a4e5794e0d55368d9ad95e8a1ca8600e 100644 (file)
@@ -21,16 +21,17 @@ use rand::{thread_rng, Rng};
 
 use rocksdb::{Direction, IteratorMode, ReadOptions, WriteBatch, DB};
 
+use bitcoin::bip158::BlockFilter;
+use bitcoin::block::Header;
 use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::consensus::{deserialize, encode::VarInt, serialize, Decodable, Encodable};
 use bitcoin::hash_types::{FilterHash, FilterHeader};
 use bitcoin::hashes::Hash;
-use bitcoin::util::bip158::BlockFilter;
-use bitcoin::util::uint::Uint256;
+use bitcoin::pow::Work;
 use bitcoin::Block;
 use bitcoin::BlockHash;
-use bitcoin::BlockHeader;
 use bitcoin::Network;
+use bitcoin::ScriptBuf;
 
 use super::CompactFiltersError;
 
@@ -69,7 +70,7 @@ impl StoreEntry {
             }
             StoreEntry::Block(Some(height)) => prefix.extend_from_slice(&height.to_be_bytes()),
             StoreEntry::BlockHeaderIndex(Some(hash)) => {
-                prefix.extend_from_slice(&hash.into_inner())
+                prefix.extend_from_slice(hash.to_raw_hash().as_ref())
             }
             StoreEntry::CFilterTable((filter_type, bundle_index)) => {
                 prefix.push(*filter_type);
@@ -228,7 +229,7 @@ impl ChainStore<Full> {
             batch.put_cf(
                 cf_handle,
                 genesis_key,
-                (genesis.header, genesis.header.work()).serialize(),
+                (genesis.header, genesis.header.work().to_be_bytes()).serialize(),
             );
             batch.put_cf(
                 cf_handle,
@@ -260,7 +261,7 @@ impl ChainStore<Full> {
                 step *= 2;
             }
 
-            let (header, _): (BlockHeader, Uint256) = SerializeDb::deserialize(
+            let (header, _): (Header, [u8; 32]) = SerializeDb::deserialize(
                 &store_read
                     .get_pinned_cf(cf_handle, StoreEntry::BlockHeader(Some(index)).get_key())?
                     .unwrap(),
@@ -292,11 +293,12 @@ impl ChainStore<Full> {
         let cf_handle = write_store.cf_handle(&self.cf_name).unwrap();
         let new_cf_handle = write_store.cf_handle(&new_cf_name).unwrap();
 
-        let (header, work): (BlockHeader, Uint256) = SerializeDb::deserialize(
+        let (header, work): (Header, [u8; 32]) = SerializeDb::deserialize(
             &write_store
                 .get_pinned_cf(cf_handle, StoreEntry::BlockHeader(Some(from)).get_key())?
                 .ok_or(CompactFiltersError::DataCorruption)?,
         )?;
+        let work = Work::from_be_bytes(work);
 
         let mut batch = WriteBatch::default();
         batch.put_cf(
@@ -307,7 +309,7 @@ impl ChainStore<Full> {
         batch.put_cf(
             new_cf_handle,
             StoreEntry::BlockHeader(Some(from)).get_key(),
-            (header, work).serialize(),
+            (header, work.to_be_bytes()).serialize(),
         );
         write_store.write(batch)?;
 
@@ -381,7 +383,7 @@ impl ChainStore<Full> {
             opts,
             IteratorMode::From(&from_key, Direction::Forward),
         ) {
-            let (header, _): (BlockHeader, Uint256) = SerializeDb::deserialize(&v)?;
+            let (header, _): (Header, [u8; 32]) = SerializeDb::deserialize(&v)?;
 
             batch.delete_cf(
                 cf_handle,
@@ -433,7 +435,7 @@ impl ChainStore<Full> {
         let key = StoreEntry::BlockHeader(Some(height)).get_key();
         let data = read_store.get_pinned_cf(cf_handle, key)?;
         data.map(|data| {
-            let (header, _): (BlockHeader, Uint256) =
+            let (header, _): (Header, [u8; 32]) =
                 deserialize(&data).map_err(|_| CompactFiltersError::DataCorruption)?;
             Ok::<_, CompactFiltersError>(header.block_hash())
         })
@@ -496,7 +498,7 @@ impl ChainStore<Full> {
 }
 
 impl<T: StoreType> ChainStore<T> {
-    pub fn work(&self) -> Result<Uint256, CompactFiltersError> {
+    pub fn work(&self) -> Result<Work, CompactFiltersError> {
         let read_store = self.store.read().unwrap();
         let cf_handle = read_store.cf_handle(&self.cf_name).unwrap();
 
@@ -506,12 +508,13 @@ impl<T: StoreType> ChainStore<T> {
         Ok(iterator
             .last()
             .map(|(_, v)| -> Result<_, CompactFiltersError> {
-                let (_, work): (BlockHeader, Uint256) = SerializeDb::deserialize(&v)?;
+                let (_, work): (Header, [u8; 32]) = SerializeDb::deserialize(&v)?;
+                let work = Work::from_be_bytes(work);
 
                 Ok(work)
             })
             .transpose()?
-            .unwrap_or_default())
+            .unwrap_or_else(|| Work::from_be_bytes([0; 32])))
     }
 
     pub fn get_height(&self) -> Result<usize, CompactFiltersError> {
@@ -546,7 +549,7 @@ impl<T: StoreType> ChainStore<T> {
         iterator
             .last()
             .map(|(_, v)| -> Result<_, CompactFiltersError> {
-                let (header, _): (BlockHeader, Uint256) = SerializeDb::deserialize(&v)?;
+                let (header, _): (Header, [u8; 32]) = SerializeDb::deserialize(&v)?;
 
                 Ok(header.block_hash())
             })
@@ -556,7 +559,7 @@ impl<T: StoreType> ChainStore<T> {
     pub fn apply(
         &mut self,
         from: usize,
-        headers: Vec<BlockHeader>,
+        headers: Vec<Header>,
     ) -> Result<BlockHash, CompactFiltersError> {
         let mut batch = WriteBatch::default();
 
@@ -566,7 +569,8 @@ impl<T: StoreType> ChainStore<T> {
         let (mut last_hash, mut accumulated_work) = read_store
             .get_pinned_cf(cf_handle, StoreEntry::BlockHeader(Some(from)).get_key())?
             .map(|result| {
-                let (header, work): (BlockHeader, Uint256) = SerializeDb::deserialize(&result)?;
+                let (header, work): (Header, [u8; 32]) = SerializeDb::deserialize(&result)?;
+                let work = Work::from_be_bytes(work);
                 Ok::<_, CompactFiltersError>((header.block_hash(), work))
             })
             .transpose()?
@@ -589,7 +593,7 @@ impl<T: StoreType> ChainStore<T> {
             batch.put_cf(
                 cf_handle,
                 StoreEntry::BlockHeader(Some(height)).get_key(),
-                (header, accumulated_work).serialize(),
+                (header, accumulated_work.to_be_bytes()).serialize(),
             );
         }
 
@@ -641,7 +645,7 @@ impl CfStore {
         let genesis = genesis_block(headers_store.network);
 
         let filter = BlockFilter::new_script_filter(&genesis, |utxo| {
-            Err(bitcoin::util::bip158::Error::UtxoMissing(*utxo))
+            Err::<ScriptBuf, _>(bitcoin::bip158::Error::UtxoMissing(*utxo))
         })?;
         let first_key = StoreEntry::CFilterTable((filter_type, Some(0))).get_key();
 
@@ -653,7 +657,7 @@ impl CfStore {
                     &first_key,
                     (
                         BundleStatus::Init,
-                        filter.filter_header(&FilterHeader::from_hash(Hash::all_zeros())),
+                        filter.filter_header(&FilterHeader::from_raw_hash(Hash::all_zeros())),
                     )
                         .serialize(),
                 )?;
index ba4e004564677714114307df3bef79644d807824..1e4e36fbe96cd6709e7c78163fd3b0e9302cd87b 100644 (file)
@@ -13,11 +13,11 @@ use std::collections::{BTreeMap, HashMap, VecDeque};
 use std::sync::{Arc, Mutex};
 use std::time::Duration;
 
+use bitcoin::bip158::BlockFilter;
 use bitcoin::hash_types::{BlockHash, FilterHeader};
 use bitcoin::hashes::Hash;
 use bitcoin::network::message::NetworkMessage;
 use bitcoin::network::message_blockdata::GetHeadersMessage;
-use bitcoin::util::bip158::BlockFilter;
 
 use super::peer::*;
 use super::store::*;
index 845bb64b5b8ab73e0b048d056823f6a6c9bbed08..ad7c9a534f05eb8b4e2620773d8b36f888a293ea 100644 (file)
@@ -325,8 +325,8 @@ impl ConfigurableBlockchain for ElectrumBlockchain {
         let socks5 = config.socks5.as_ref().map(Socks5Config::new);
         let electrum_config = ConfigBuilder::new()
             .retry(config.retry)
-            .timeout(config.timeout)?
-            .socks5(socks5)?
+            .timeout(config.timeout)
+            .socks5(socks5)
             .validate_domain(config.validate_domain)
             .build();
 
index e75e5456c92c20f70bc1b02044e1a5b7d8ed3ece..cfd83f2cf06fbfbb46564269aacaacad9b8100c8 100644 (file)
@@ -132,7 +132,7 @@ impl WalletSync for EsploraBlockchain {
                     let scripts = script_req
                         .request()
                         .take(self.concurrency as usize)
-                        .cloned();
+                        .map(bitcoin::ScriptBuf::from);
 
                     let mut handles = vec![];
                     for script in scripts {
index da19e20c67b88ceb50f73bf57d337cd87a58e608..65456579ea828645df84f64c98842f1fedc83a30 100644 (file)
 //! let blockchain = RpcBlockchain::from_config(&config);
 //! ```
 
-use crate::bitcoin::hashes::hex::ToHex;
 use crate::bitcoin::{Network, OutPoint, Transaction, TxOut, Txid};
 use crate::blockchain::*;
 use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
 use crate::descriptor::calc_checksum;
 use crate::error::MissingCachedScripts;
 use crate::{BlockTime, Error, FeeRate, KeychainKind, LocalUtxo, TransactionDetails};
-use bitcoin::Script;
+use bitcoin::{Script, ScriptBuf};
 use bitcoincore_rpc::json::{
     GetTransactionResultDetailCategory, ImportMultiOptions, ImportMultiRequest,
-    ImportMultiRequestScriptPubkey, ImportMultiRescanSince, ListTransactionResult,
-    ListUnspentResultEntry, ScanningDetails,
+    ImportMultiRequestScriptPubkey, ListTransactionResult, ListUnspentResultEntry, ScanningDetails,
+    Timestamp,
 };
 use bitcoincore_rpc::jsonrpc::serde_json::{json, Value};
 use bitcoincore_rpc::Auth as RpcAuth;
@@ -302,8 +301,8 @@ struct DbState<'a, D> {
     params: &'a RpcSyncParams,
     prog: &'a dyn Progress,
 
-    ext_spks: Vec<Script>,
-    int_spks: Vec<Script>,
+    ext_spks: Vec<ScriptBuf>,
+    int_spks: Vec<ScriptBuf>,
     txs: HashMap<Txid, TransactionDetails>,
     utxos: HashSet<LocalUtxo>,
     last_indexes: HashMap<KeychainKind, u32>,
@@ -668,7 +667,7 @@ fn import_descriptors<'a, S>(
     scripts_iter: S,
 ) -> Result<(), Error>
 where
-    S: Iterator<Item = &'a Script>,
+    S: Iterator<Item = &'a ScriptBuf>,
 {
     let requests = Value::Array(
         scripts_iter
@@ -696,11 +695,11 @@ where
 
 fn import_multi<'a, S>(client: &Client, start_epoch: u64, scripts_iter: S) -> Result<(), Error>
 where
-    S: Iterator<Item = &'a Script>,
+    S: Iterator<Item = &'a ScriptBuf>,
 {
     let requests = scripts_iter
         .map(|script| ImportMultiRequest {
-            timestamp: ImportMultiRescanSince::Timestamp(start_epoch),
+            timestamp: Timestamp::Time(start_epoch),
             script_pubkey: Some(ImportMultiRequestScriptPubkey::Script(script)),
             watchonly: Some(true),
             ..Default::default()
@@ -808,7 +807,7 @@ fn is_wallet_descriptor(client: &Client) -> Result<bool, Error> {
 }
 
 fn descriptor_from_script_pubkey(script: &Script) -> String {
-    let desc = format!("raw({})", script.to_hex());
+    let desc = format!("raw({})", script.to_hex_string());
     format!("{}#{}", desc, calc_checksum(&desc).unwrap())
 }
 
@@ -964,7 +963,7 @@ mod test {
 
         // generate scripts (1 tx per script)
         let scripts = (0..TX_COUNT)
-            .map(|index| desc.at_derivation_index(index).script_pubkey())
+            .map(|index| desc.at_derivation_index(index).unwrap().script_pubkey())
             .collect::<Vec<_>>();
 
         // import scripts and wait
index 2c4b26cef9a12a8c2360ce44ca55d0b35d858803..9aeec7a4a99d4c65ca1af17256e6fa83e73605f5 100644 (file)
@@ -9,7 +9,7 @@ use crate::{
     wallet::time::Instant,
     BlockTime, Error, KeychainKind, LocalUtxo, TransactionDetails,
 };
-use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid};
+use bitcoin::{OutPoint, Script, ScriptBuf, Transaction, TxOut, Txid};
 use log::*;
 use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
 
@@ -53,7 +53,7 @@ pub struct ScriptReq<'a, D: BatchDatabase> {
     state: State<'a, D>,
     script_index: usize,
     initial_scripts_needed: usize, // if this is 1, we assume the descriptor is not derivable
-    scripts_needed: VecDeque<Script>,
+    scripts_needed: VecDeque<ScriptBuf>,
     stop_gap: usize,
     keychain: KeychainKind,
     next_keychains: Vec<KeychainKind>,
@@ -62,7 +62,7 @@ pub struct ScriptReq<'a, D: BatchDatabase> {
 /// The sync starts by returning script pubkeys we are interested in.
 impl<'a, D: BatchDatabase> ScriptReq<'a, D> {
     pub fn request(&self) -> impl Iterator<Item = &Script> + Clone {
-        self.scripts_needed.iter()
+        self.scripts_needed.iter().map(|s| s.as_script())
     }
 
     pub fn satisfy(
index bbd9d41a50342e56736d6b8cc9e81be70a431205..e8458111aee82018dcea96f3ab870bbdb1480a27 100644 (file)
@@ -153,7 +153,7 @@ impl BatchOperations for AnyDatabase {
         &mut self,
         keychain: KeychainKind,
         child: u32,
-    ) -> Result<Option<Script>, Error> {
+    ) -> Result<Option<ScriptBuf>, Error> {
         impl_inner_method!(
             AnyDatabase,
             self,
@@ -204,7 +204,7 @@ impl Database for AnyDatabase {
         )
     }
 
-    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
+    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<ScriptBuf>, Error> {
         impl_inner_method!(AnyDatabase, self, iter_script_pubkeys, keychain)
     }
     fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error> {
@@ -221,7 +221,7 @@ impl Database for AnyDatabase {
         &self,
         keychain: KeychainKind,
         child: u32,
-    ) -> Result<Option<Script>, Error> {
+    ) -> Result<Option<ScriptBuf>, Error> {
         impl_inner_method!(
             AnyDatabase,
             self,
@@ -286,7 +286,7 @@ impl BatchOperations for AnyBatch {
         &mut self,
         keychain: KeychainKind,
         child: u32,
-    ) -> Result<Option<Script>, Error> {
+    ) -> Result<Option<ScriptBuf>, Error> {
         impl_inner_method!(AnyBatch, self, del_script_pubkey_from_path, keychain, child)
     }
     fn del_path_from_script_pubkey(
index f586ebeba820eaad612e3a76596bce7b4f7e72f5..7c20b219441bed200673fcabff6bc425cf1fbcaa 100644 (file)
@@ -15,7 +15,7 @@ use sled::{Batch, Tree};
 
 use bitcoin::consensus::encode::{deserialize, serialize};
 use bitcoin::hash_types::Txid;
-use bitcoin::{OutPoint, Script, Transaction};
+use bitcoin::{OutPoint, Script, ScriptBuf, Transaction};
 
 use crate::database::memory::MapKey;
 use crate::database::{BatchDatabase, BatchOperations, Database, SyncTime};
@@ -90,7 +90,7 @@ macro_rules! impl_batch_operations {
             Ok(())
         }
 
-        fn del_script_pubkey_from_path(&mut self, keychain: KeychainKind, path: u32) -> Result<Option<Script>, Error> {
+        fn del_script_pubkey_from_path(&mut self, keychain: KeychainKind, path: u32) -> Result<Option<ScriptBuf>, Error> {
             let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
             let res = self.remove(key);
             let res = $process_delete!(res);
@@ -221,7 +221,7 @@ impl Database for Tree {
         }
     }
 
-    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
+    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<ScriptBuf>, Error> {
         let key = MapKey::Path((keychain, None)).as_map_key();
         self.scan_prefix(key)
             .map(|x| -> Result<_, Error> {
@@ -286,7 +286,7 @@ impl Database for Tree {
         &self,
         keychain: KeychainKind,
         path: u32,
-    ) -> Result<Option<Script>, Error> {
+    ) -> Result<Option<ScriptBuf>, Error> {
         let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
         Ok(self.get(key)?.map(|b| deserialize(&b)).transpose()?)
     }
index 6cfca6fc9b538ee77226c1f6a86baecad565e6d0..4373280f34e8f5676bd4bc0ece2ed3b349e6be65 100644 (file)
@@ -20,7 +20,7 @@ use std::ops::Bound::{Excluded, Included};
 
 use bitcoin::consensus::encode::{deserialize, serialize};
 use bitcoin::hash_types::Txid;
-use bitcoin::{OutPoint, Script, Transaction};
+use bitcoin::{OutPoint, Script, ScriptBuf, Transaction};
 
 use crate::database::{BatchDatabase, BatchOperations, ConfigurableDatabase, Database, SyncTime};
 use crate::error::Error;
@@ -136,7 +136,7 @@ impl BatchOperations for MemoryDatabase {
         path: u32,
     ) -> Result<(), Error> {
         let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
-        self.map.insert(key, Box::new(script.clone()));
+        self.map.insert(key, Box::new(ScriptBuf::from(script)));
 
         let key = MapKey::Script(Some(script)).as_map_key();
         let value = json!({
@@ -196,7 +196,7 @@ impl BatchOperations for MemoryDatabase {
         &mut self,
         keychain: KeychainKind,
         path: u32,
-    ) -> Result<Option<Script>, Error> {
+    ) -> Result<Option<ScriptBuf>, Error> {
         let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
         let res = self.map.remove(&key);
         self.deleted_keys.push(key);
@@ -315,7 +315,7 @@ impl Database for MemoryDatabase {
         }
     }
 
-    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
+    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<ScriptBuf>, Error> {
         let key = MapKey::Path((keychain, None)).as_map_key();
         self.map
             .range::<Vec<u8>, _>((Included(&key), Excluded(&after(&key))))
@@ -368,7 +368,7 @@ impl Database for MemoryDatabase {
         &self,
         keychain: KeychainKind,
         path: u32,
-    ) -> Result<Option<Script>, Error> {
+    ) -> Result<Option<ScriptBuf>, Error> {
         let key = MapKey::Path((Some(keychain), Some(path))).as_map_key();
         Ok(self
             .map
@@ -485,7 +485,6 @@ macro_rules! populate_test_db {
         $crate::populate_test_db!($db, $tx_meta, $current_height, (@coinbase false))
     }};
     ($db:expr, $tx_meta:expr, $current_height:expr, (@coinbase $is_coinbase:expr)$(,)?) => {{
-        use std::str::FromStr;
         use $crate::database::SyncTime;
         use $crate::database::{BatchOperations, Database};
         let mut db = $db;
@@ -497,7 +496,7 @@ macro_rules! populate_test_db {
         }
         let tx = $crate::bitcoin::Transaction {
             version: 1,
-            lock_time: bitcoin::PackedLockTime(0),
+            lock_time: bitcoin::absolute::LockTime::ZERO,
             input,
             output: tx_meta
                 .output
@@ -506,6 +505,7 @@ macro_rules! populate_test_db {
                     value: out_meta.value,
                     script_pubkey: $crate::bitcoin::Address::from_str(&out_meta.to_address)
                         .unwrap()
+                        .assume_checked()
                         .script_pubkey(),
                 })
                 .collect(),
index 7f26a1320420971d6d5ac018fe1ecb9acbb59fbd..fd835300de62bbc3dade53a0aa64bc2a581560ea 100644 (file)
@@ -27,7 +27,7 @@
 use serde::{Deserialize, Serialize};
 
 use bitcoin::hash_types::Txid;
-use bitcoin::{OutPoint, Script, Transaction, TxOut};
+use bitcoin::{OutPoint, Script, ScriptBuf, Transaction, TxOut};
 
 use crate::error::Error;
 use crate::types::*;
@@ -83,7 +83,7 @@ pub trait BatchOperations {
         &mut self,
         keychain: KeychainKind,
         child: u32,
-    ) -> Result<Option<Script>, Error>;
+    ) -> Result<Option<ScriptBuf>, Error>;
     /// Delete the data related to a specific script_pubkey, meaning the keychain and the child
     /// number.
     fn del_path_from_script_pubkey(
@@ -124,7 +124,7 @@ pub trait Database: BatchOperations {
     ) -> Result<(), Error>;
 
     /// Return the list of script_pubkeys
-    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error>;
+    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<ScriptBuf>, Error>;
     /// Return the list of [`LocalUtxo`]s
     fn iter_utxos(&self) -> Result<Vec<LocalUtxo>, Error>;
     /// Return the list of raw transactions
@@ -137,7 +137,7 @@ pub trait Database: BatchOperations {
         &self,
         keychain: KeychainKind,
         child: u32,
-    ) -> Result<Option<Script>, Error>;
+    ) -> Result<Option<ScriptBuf>, Error>;
     /// Fetch the keychain and child number of a given script_pubkey
     fn get_path_from_script_pubkey(
         &self,
@@ -214,17 +214,17 @@ impl<T: Database> DatabaseUtils for T {}
 
 #[cfg(test)]
 pub mod test {
-    use std::str::FromStr;
-
     use bitcoin::consensus::encode::deserialize;
     use bitcoin::consensus::serialize;
     use bitcoin::hashes::hex::*;
+    use bitcoin::Witness;
     use bitcoin::*;
+    use std::str::FromStr;
 
     use super::*;
 
     pub fn test_script_pubkey<D: Database>(mut db: D) {
-        let script = Script::from(
+        let script = ScriptBuf::from(
             Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
         );
         let path = 42;
@@ -245,7 +245,7 @@ pub mod test {
     pub fn test_batch_script_pubkey<D: BatchDatabase>(mut db: D) {
         let mut batch = db.begin_batch();
 
-        let script = Script::from(
+        let script = ScriptBuf::from(
             Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
         );
         let path = 42;
@@ -272,7 +272,7 @@ pub mod test {
     }
 
     pub fn test_iter_script_pubkey<D: Database>(mut db: D) {
-        let script = Script::from(
+        let script = ScriptBuf::from(
             Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
         );
         let path = 42;
@@ -284,7 +284,7 @@ pub mod test {
     }
 
     pub fn test_del_script_pubkey<D: Database>(mut db: D) {
-        let script = Script::from(
+        let script = ScriptBuf::from(
             Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
         );
         let path = 42;
@@ -302,7 +302,7 @@ pub mod test {
             "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:0",
         )
         .unwrap();
-        let script = Script::from(
+        let script = ScriptBuf::from(
             Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
         );
         let txout = TxOut {
@@ -478,7 +478,7 @@ pub mod test {
     pub fn test_del_path_from_script_pubkey<D: Database>(mut db: D) {
         let keychain = KeychainKind::External;
 
-        let script = Script::from(
+        let script = ScriptBuf::from(
             Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
         );
         let path = 42;
@@ -502,14 +502,14 @@ pub mod test {
         let scripts = db.iter_script_pubkeys(Some(keychain)).unwrap();
         assert!(scripts.is_empty());
 
-        let first_script = Script::from(
+        let first_script = ScriptBuf::from(
             Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
         );
         let path = 42;
 
         db.set_script_pubkey(&first_script, keychain, path).unwrap();
 
-        let second_script = Script::from(
+        let second_script = ScriptBuf::from(
             Vec::<u8>::from_hex("00145c9a1816d38db5cbdd4b067b689dc19eb7d930e2").unwrap(),
         );
         let path = 57;
@@ -528,7 +528,7 @@ pub mod test {
             "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:0",
         )
         .unwrap();
-        let script = Script::from(
+        let script = ScriptBuf::from(
             Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
         );
         let txout = TxOut {
index fc71508566cd38918862f060ae7f1ae8e8f86783..59ce898529dcf6e2bddca8a17b6b2640c61ae15e 100644 (file)
@@ -13,7 +13,7 @@ use std::path::PathBuf;
 
 use bitcoin::consensus::encode::{deserialize, serialize};
 use bitcoin::hash_types::Txid;
-use bitcoin::{OutPoint, Script, Transaction, TxOut};
+use bitcoin::{OutPoint, Script, ScriptBuf, Transaction, TxOut};
 
 use crate::database::{BatchDatabase, BatchOperations, Database, SyncTime};
 use crate::error::Error;
@@ -162,7 +162,7 @@ impl SqliteDatabase {
             None => (None, None),
         };
 
-        let txid: &[u8] = &transaction.txid;
+        let txid: &[u8] = transaction.txid.as_ref();
 
         let mut statement = self.connection.prepare_cached("INSERT INTO transaction_details (txid, timestamp, received, sent, fee, height) VALUES (:txid, :timestamp, :received, :sent, :fee, :height)")?;
 
@@ -187,7 +187,7 @@ impl SqliteDatabase {
             None => (None, None),
         };
 
-        let txid: &[u8] = &transaction.txid;
+        let txid: &[u8] = transaction.txid.as_ref();
 
         let mut statement = self.connection.prepare_cached("UPDATE transaction_details SET timestamp=:timestamp, received=:received, sent=:sent, fee=:fee, height=:height WHERE txid=:txid")?;
 
@@ -254,11 +254,11 @@ impl SqliteDatabase {
         Ok(self.connection.last_insert_rowid())
     }
 
-    fn select_script_pubkeys(&self) -> Result<Vec<Script>, Error> {
+    fn select_script_pubkeys(&self) -> Result<Vec<ScriptBuf>, Error> {
         let mut statement = self
             .connection
             .prepare_cached("SELECT script FROM script_pubkeys")?;
-        let mut scripts: Vec<Script> = vec![];
+        let mut scripts: Vec<ScriptBuf> = vec![];
         let mut rows = statement.query([])?;
         while let Some(row) = rows.next()? {
             let raw_script: Vec<u8> = row.get(0)?;
@@ -268,11 +268,11 @@ impl SqliteDatabase {
         Ok(scripts)
     }
 
-    fn select_script_pubkeys_by_keychain(&self, keychain: String) -> Result<Vec<Script>, Error> {
+    fn select_script_pubkeys_by_keychain(&self, keychain: String) -> Result<Vec<ScriptBuf>, Error> {
         let mut statement = self
             .connection
             .prepare_cached("SELECT script FROM script_pubkeys WHERE keychain=:keychain")?;
-        let mut scripts: Vec<Script> = vec![];
+        let mut scripts: Vec<ScriptBuf> = vec![];
         let mut rows = statement.query(named_params! {":keychain": keychain})?;
         while let Some(row) = rows.next()? {
             let raw_script: Vec<u8> = row.get(0)?;
@@ -286,7 +286,7 @@ impl SqliteDatabase {
         &self,
         keychain: String,
         child: u32,
-    ) -> Result<Option<Script>, Error> {
+    ) -> Result<Option<ScriptBuf>, Error> {
         let mut statement = self.connection.prepare_cached(
             "SELECT script FROM script_pubkeys WHERE keychain=:keychain AND child=:child",
         )?;
@@ -295,7 +295,7 @@ impl SqliteDatabase {
         match rows.next()? {
             Some(row) => {
                 let script: Vec<u8> = row.get(0)?;
-                let script: Script = script.into();
+                let script: ScriptBuf = script.into();
                 Ok(Some(script))
             }
             None => Ok(None),
@@ -362,7 +362,7 @@ impl SqliteDatabase {
                 let keychain: String = row.get(1)?;
                 let keychain: KeychainKind = serde_json::from_str(&keychain)?;
                 let script: Vec<u8> = row.get(2)?;
-                let script_pubkey: Script = script.into();
+                let script_pubkey: ScriptBuf = script.into();
                 let is_spent: bool = row.get(3)?;
 
                 Ok(Some(LocalUtxo {
@@ -658,7 +658,7 @@ impl BatchOperations for SqliteDatabase {
             utxo.txout.value,
             serde_json::to_string(&utxo.keychain)?,
             utxo.outpoint.vout,
-            &utxo.outpoint.txid,
+            utxo.outpoint.txid.as_ref(),
             utxo.txout.script_pubkey.as_bytes(),
             utxo.is_spent,
         )?;
@@ -666,19 +666,19 @@ impl BatchOperations for SqliteDatabase {
     }
 
     fn set_raw_tx(&mut self, transaction: &Transaction) -> Result<(), Error> {
-        match self.select_transaction_by_txid(&transaction.txid())? {
+        match self.select_transaction_by_txid(transaction.txid().as_ref())? {
             Some(_) => {
-                self.update_transaction(&transaction.txid(), &serialize(transaction))?;
+                self.update_transaction(transaction.txid().as_ref(), &serialize(transaction))?;
             }
             None => {
-                self.insert_transaction(&transaction.txid(), &serialize(transaction))?;
+                self.insert_transaction(transaction.txid().as_ref(), &serialize(transaction))?;
             }
         }
         Ok(())
     }
 
     fn set_tx(&mut self, transaction: &TransactionDetails) -> Result<(), Error> {
-        match self.select_transaction_details_by_txid(&transaction.txid)? {
+        match self.select_transaction_details_by_txid(transaction.txid.as_ref())? {
             Some(_) => {
                 self.update_transaction_details(transaction)?;
             }
@@ -708,7 +708,7 @@ impl BatchOperations for SqliteDatabase {
         &mut self,
         keychain: KeychainKind,
         child: u32,
-    ) -> Result<Option<Script>, Error> {
+    ) -> Result<Option<ScriptBuf>, Error> {
         let keychain = serde_json::to_string(&keychain)?;
         let script = self.select_script_pubkey_by_path(keychain.clone(), child)?;
         match script {
@@ -734,9 +734,9 @@ impl BatchOperations for SqliteDatabase {
     }
 
     fn del_utxo(&mut self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
-        match self.select_utxo_by_outpoint(&outpoint.txid, outpoint.vout)? {
+        match self.select_utxo_by_outpoint(outpoint.txid.as_ref(), outpoint.vout)? {
             Some(local_utxo) => {
-                self.delete_utxo_by_outpoint(&outpoint.txid, outpoint.vout)?;
+                self.delete_utxo_by_outpoint(outpoint.txid.as_ref(), outpoint.vout)?;
                 Ok(Some(local_utxo))
             }
             None => Ok(None),
@@ -744,9 +744,9 @@ impl BatchOperations for SqliteDatabase {
     }
 
     fn del_raw_tx(&mut self, txid: &Txid) -> Result<Option<Transaction>, Error> {
-        match self.select_transaction_by_txid(txid)? {
+        match self.select_transaction_by_txid(txid.as_ref())? {
             Some(tx) => {
-                self.delete_transaction_by_txid(txid)?;
+                self.delete_transaction_by_txid(txid.as_ref())?;
                 Ok(Some(tx))
             }
             None => Ok(None),
@@ -758,12 +758,12 @@ impl BatchOperations for SqliteDatabase {
         txid: &Txid,
         include_raw: bool,
     ) -> Result<Option<TransactionDetails>, Error> {
-        match self.select_transaction_details_by_txid(txid)? {
+        match self.select_transaction_details_by_txid(txid.as_ref())? {
             Some(mut transaction_details) => {
-                self.delete_transaction_details_by_txid(txid)?;
+                self.delete_transaction_details_by_txid(txid.as_ref())?;
 
                 if include_raw {
-                    self.delete_transaction_by_txid(txid)?;
+                    self.delete_transaction_by_txid(txid.as_ref())?;
                 } else {
                     transaction_details.transaction = None;
                 }
@@ -820,7 +820,7 @@ impl Database for SqliteDatabase {
         }
     }
 
-    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<Script>, Error> {
+    fn iter_script_pubkeys(&self, keychain: Option<KeychainKind>) -> Result<Vec<ScriptBuf>, Error> {
         match keychain {
             Some(keychain) => {
                 let keychain = serde_json::to_string(&keychain)?;
@@ -849,7 +849,7 @@ impl Database for SqliteDatabase {
         &self,
         keychain: KeychainKind,
         child: u32,
-    ) -> Result<Option<Script>, Error> {
+    ) -> Result<Option<ScriptBuf>, Error> {
         let keychain = serde_json::to_string(&keychain)?;
         match self.select_script_pubkey_by_path(keychain, child)? {
             Some(script) => Ok(Some(script)),
@@ -868,18 +868,18 @@ impl Database for SqliteDatabase {
     }
 
     fn get_utxo(&self, outpoint: &OutPoint) -> Result<Option<LocalUtxo>, Error> {
-        self.select_utxo_by_outpoint(&outpoint.txid, outpoint.vout)
+        self.select_utxo_by_outpoint(outpoint.txid.as_ref(), outpoint.vout)
     }
 
     fn get_raw_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error> {
-        match self.select_transaction_by_txid(txid)? {
+        match self.select_transaction_by_txid(txid.as_ref())? {
             Some(tx) => Ok(Some(tx)),
             None => Ok(None),
         }
     }
 
     fn get_tx(&self, txid: &Txid, include_raw: bool) -> Result<Option<TransactionDetails>, Error> {
-        match self.select_transaction_details_by_txid(txid)? {
+        match self.select_transaction_details_by_txid(txid.as_ref())? {
             Some(mut transaction_details) => {
                 if !include_raw {
                     transaction_details.transaction = None;
@@ -1115,7 +1115,7 @@ pub mod test {
 
         let mut db = get_database();
 
-        let script = Script::from(
+        let script = ScriptBuf::from(
             Vec::<u8>::from_hex("76a91402306a7c23f3e8010de41e9e591348bb83f11daa88ac").unwrap(),
         );
         let path = 42;
index 67ef67057ffee7cbdf48e18030b7fbf72828b867..9fa6e2081d5ade046eac673f3a42beabf6014379 100644 (file)
@@ -514,13 +514,14 @@ macro_rules! descriptor {
         use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
 
         $crate::impl_top_level_pk!(Pkh, $crate::miniscript::Legacy, $key)
+            .and_then(|(a, b, c)| Ok((a.map_err(|e| miniscript::Error::from(e))?, b, c)))
             .map(|(a, b, c)| (Descriptor::<DescriptorPublicKey>::Pkh(a), b, c))
     });
     ( wpkh ( $key:expr ) ) => ({
         use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey};
 
         $crate::impl_top_level_pk!(Wpkh, $crate::miniscript::Segwitv0, $key)
-            .and_then(|(a, b, c)| Ok((a?, b, c)))
+            .and_then(|(a, b, c)| Ok((a.map_err(|e| miniscript::Error::from(e))?, b, c)))
             .map(|(a, b, c)| (Descriptor::<DescriptorPublicKey>::Wpkh(a), b, c))
     });
     ( sh ( wpkh ( $key:expr ) ) ) => ({
@@ -530,7 +531,7 @@ macro_rules! descriptor {
         use $crate::miniscript::descriptor::{Descriptor, DescriptorPublicKey, Sh};
 
         $crate::impl_top_level_pk!(Wpkh, $crate::miniscript::Segwitv0, $key)
-            .and_then(|(a, b, c)| Ok((a?, b, c)))
+            .and_then(|(a, b, c)| Ok((a.map_err(|e| miniscript::Error::from(e))?, b, c)))
             .and_then(|(a, b, c)| Ok((Descriptor::<DescriptorPublicKey>::Sh(Sh::new_wpkh(a.into_inner())?), b, c)))
     });
     ( sh ( $( $minisc:tt )* ) ) => ({
@@ -700,7 +701,7 @@ macro_rules! fragment {
         $crate::keys::make_pkh($key, &secp)
     });
     ( after ( $value:expr ) ) => ({
-        $crate::impl_leaf_opcode_value!(After, $crate::bitcoin::PackedLockTime($value)) // TODO!! https://github.com/rust-bitcoin/rust-bitcoin/issues/1302
+        $crate::impl_leaf_opcode_value!(After, $crate::miniscript::AbsLockTime::from_consensus($value))
     });
     ( older ( $value:expr ) ) => ({
         $crate::impl_leaf_opcode_value!(Older, $crate::bitcoin::Sequence($value)) // TODO!!
@@ -793,7 +794,6 @@ macro_rules! fragment {
 
 #[cfg(test)]
 mod test {
-    use bitcoin::hashes::hex::ToHex;
     use bitcoin::secp256k1::Secp256k1;
     use miniscript::descriptor::{DescriptorPublicKey, KeyMap};
     use miniscript::{Descriptor, Legacy, Segwitv0};
@@ -802,8 +802,8 @@ mod test {
 
     use crate::descriptor::{DescriptorError, DescriptorMeta};
     use crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks};
+    use bitcoin::bip32;
     use bitcoin::network::constants::Network::{Bitcoin, Regtest, Signet, Testnet};
-    use bitcoin::util::bip32;
     use bitcoin::PrivateKey;
 
     // test the descriptor!() macro
@@ -819,18 +819,15 @@ mod test {
         assert_eq!(desc.is_witness(), is_witness);
         assert_eq!(!desc.has_wildcard(), is_fixed);
         for i in 0..expected.len() {
-            let index = i as u32;
-            let child_desc = if !desc.has_wildcard() {
-                desc.at_derivation_index(0)
-            } else {
-                desc.at_derivation_index(index)
-            };
+            let child_desc = desc
+                .at_derivation_index(i as u32)
+                .expect("i is not hardened");
             let address = child_desc.address(Regtest);
             if let Ok(address) = address {
                 assert_eq!(address.to_string(), *expected.get(i).unwrap());
             } else {
                 let script = child_desc.script_pubkey();
-                assert_eq!(script.to_hex().as_str(), *expected.get(i).unwrap());
+                assert_eq!(script.to_hex_string(), *expected.get(i).unwrap());
             }
         }
     }
@@ -1175,9 +1172,7 @@ mod test {
     }
 
     #[test]
-    #[should_panic(
-        expected = "Miniscript(ContextError(CompressedOnly(\"04b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a87378ec38ff91d43e8c2092ebda601780485263da089465619e0358a5c1be7ac91f4\")))"
-    )]
+    #[should_panic(expected = "Miniscript(ContextError(UncompressedKeysNotAllowed))")]
     fn test_dsl_miniscript_checks() {
         let mut uncompressed_pk =
             PrivateKey::from_wif("L5EZftvrYaSudiozVRzTqLcHLNDoVn7H5HSfM9BAN6tMJX8oTWz6").unwrap();
index d558c926c19e20946b53abce312fa0f544edb8d6..417a43dd3eced4109ef43e7b4a479598b9a15646 100644 (file)
@@ -30,11 +30,11 @@ pub enum Error {
     InvalidDescriptorCharacter(u8),
 
     /// BIP32 error
-    Bip32(bitcoin::util::bip32::Error),
+    Bip32(bitcoin::bip32::Error),
     /// Error during base58 decoding
-    Base58(bitcoin::util::base58::Error),
+    Base58(bitcoin::base58::Error),
     /// Key-related error
-    Pk(bitcoin::util::key::Error),
+    Pk(bitcoin::key::Error),
     /// Miniscript error
     Miniscript(miniscript::Error),
     /// Hex decoding error
@@ -78,9 +78,9 @@ impl std::fmt::Display for Error {
 
 impl std::error::Error for Error {}
 
-impl_error!(bitcoin::util::bip32::Error, Bip32);
-impl_error!(bitcoin::util::base58::Error, Base58);
-impl_error!(bitcoin::util::key::Error, Pk);
+impl_error!(bitcoin::bip32::Error, Bip32);
+impl_error!(bitcoin::base58::Error, Base58);
+impl_error!(bitcoin::key::Error, Pk);
 impl_error!(miniscript::Error, Miniscript);
 impl_error!(bitcoin::hashes::hex::Error, Hex);
 impl_error!(crate::descriptor::policy::PolicyError, Policy);
index b307bbf1c6d0667cea436bf47441216b252f3762..5b97a3ed90af53fa24e9c57fa25ed3283d224692 100644 (file)
 
 use std::collections::BTreeMap;
 
-use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint, KeySource};
-use bitcoin::util::{psbt, taproot};
-use bitcoin::{secp256k1, PublicKey, XOnlyPublicKey};
+use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint, KeySource};
+use bitcoin::{key::XOnlyPublicKey, secp256k1, PublicKey};
+use bitcoin::{psbt, taproot};
 use bitcoin::{Network, TxOut};
 
 use miniscript::descriptor::{
-    DefiniteDescriptorKey, DescriptorSecretKey, DescriptorType, InnerXKey, SinglePubKey,
+    DefiniteDescriptorKey, DescriptorMultiXKey, DescriptorSecretKey, DescriptorType,
+    DescriptorXKey, InnerXKey, KeyMap, SinglePubKey, Wildcard,
 };
 pub use miniscript::{
-    descriptor::DescriptorXKey, descriptor::KeyMap, descriptor::Wildcard, Descriptor,
-    DescriptorPublicKey, Legacy, Miniscript, ScriptContext, Segwitv0,
+    Descriptor, DescriptorPublicKey, Legacy, Miniscript, ScriptContext, Segwitv0,
 };
 use miniscript::{ForEachKey, MiniscriptKey, TranslatePk};
 
@@ -57,16 +57,16 @@ pub type DerivedDescriptor = Descriptor<DefiniteDescriptorKey>;
 /// Alias for the type of maps that represent derivation paths in a [`psbt::Input`] or
 /// [`psbt::Output`]
 ///
-/// [`psbt::Input`]: bitcoin::util::psbt::Input
-/// [`psbt::Output`]: bitcoin::util::psbt::Output
+/// [`psbt::Input`]: bitcoin::psbt::Input
+/// [`psbt::Output`]: bitcoin::psbt::Output
 pub type HdKeyPaths = BTreeMap<secp256k1::PublicKey, KeySource>;
 
 /// Alias for the type of maps that represent taproot key origins in a [`psbt::Input`] or
 /// [`psbt::Output`]
 ///
-/// [`psbt::Input`]: bitcoin::util::psbt::Input
-/// [`psbt::Output`]: bitcoin::util::psbt::Output
-pub type TapKeyOrigins = BTreeMap<bitcoin::XOnlyPublicKey, (Vec<taproot::TapLeafHash>, KeySource)>;
+/// [`psbt::Input`]: bitcoin::psbt::Input
+/// [`psbt::Output`]: bitcoin::psbt::Output
+pub type TapKeyOrigins = BTreeMap<XOnlyPublicKey, (Vec<taproot::TapLeafHash>, KeySource)>;
 
 /// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`]
 pub trait IntoWalletDescriptor {
@@ -134,14 +134,10 @@ impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
             network: Network,
         }
 
-        impl<'s, 'd>
-            miniscript::Translator<DescriptorPublicKey, miniscript::DummyKey, DescriptorError>
+        impl<'s, 'd> miniscript::Translator<DescriptorPublicKey, String, DescriptorError>
             for Translator<'s, 'd>
         {
-            fn pk(
-                &mut self,
-                pk: &DescriptorPublicKey,
-            ) -> Result<miniscript::DummyKey, DescriptorError> {
+            fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<String, DescriptorError> {
                 let secp = &self.secp;
 
                 let (_, _, networks) = if self.descriptor.is_taproot() {
@@ -159,7 +155,7 @@ impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
                 };
 
                 if networks.contains(&self.network) {
-                    Ok(miniscript::DummyKey)
+                    Ok(Default::default())
                 } else {
                     Err(DescriptorError::Key(KeyError::InvalidNetwork))
                 }
@@ -167,35 +163,40 @@ impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
             fn sha256(
                 &mut self,
                 _sha256: &<DescriptorPublicKey as MiniscriptKey>::Sha256,
-            ) -> Result<miniscript::DummySha256Hash, DescriptorError> {
+            ) -> Result<String, DescriptorError> {
                 Ok(Default::default())
             }
             fn hash256(
                 &mut self,
                 _hash256: &<DescriptorPublicKey as MiniscriptKey>::Hash256,
-            ) -> Result<miniscript::DummyHash256Hash, DescriptorError> {
+            ) -> Result<String, DescriptorError> {
                 Ok(Default::default())
             }
             fn ripemd160(
                 &mut self,
                 _ripemd160: &<DescriptorPublicKey as MiniscriptKey>::Ripemd160,
-            ) -> Result<miniscript::DummyRipemd160Hash, DescriptorError> {
+            ) -> Result<String, DescriptorError> {
                 Ok(Default::default())
             }
             fn hash160(
                 &mut self,
                 _hash160: &<DescriptorPublicKey as MiniscriptKey>::Hash160,
-            ) -> Result<miniscript::DummyHash160Hash, DescriptorError> {
+            ) -> Result<String, DescriptorError> {
                 Ok(Default::default())
             }
         }
 
         // check the network for the keys
-        self.0.translate_pk(&mut Translator {
+        use miniscript::TranslateErr;
+        match self.0.translate_pk(&mut Translator {
             secp,
             network,
             descriptor: &self.0,
-        })?;
+        }) {
+            Ok(_) => {}
+            Err(TranslateErr::TranslatorErr(e)) => return Err(e),
+            Err(TranslateErr::OuterError(e)) => return Err(e.into()),
+        }
 
         Ok(self)
     }
@@ -249,7 +250,12 @@ impl IntoWalletDescriptor for DescriptorTemplateOut {
         }
 
         // fixup the network for keys that need it in the descriptor
-        let translated = desc.translate_pk(&mut Translator { network })?;
+        use miniscript::TranslateErr;
+        let translated = match desc.translate_pk(&mut Translator { network }) {
+            Ok(descriptor) => descriptor,
+            Err(TranslateErr::TranslatorErr(e)) => return Err(e),
+            Err(TranslateErr::OuterError(e)) => return Err(e.into()),
+        };
         // ...and in the key map
         let fixed_keymap = keymap
             .into_iter()
@@ -338,6 +344,18 @@ pub(crate) trait XKeyUtils {
     fn root_fingerprint(&self, secp: &SecpCtx) -> Fingerprint;
 }
 
+impl<T> XKeyUtils for DescriptorMultiXKey<T>
+where
+    T: InnerXKey,
+{
+    fn root_fingerprint(&self, secp: &SecpCtx) -> Fingerprint {
+        match self.origin {
+            Some((fingerprint, _)) => fingerprint,
+            None => self.xkey.xkey_fingerprint(secp),
+        }
+    }
+}
+
 impl<T> XKeyUtils for DescriptorXKey<T>
 where
     T: InnerXKey,
@@ -492,7 +510,10 @@ impl DescriptorMeta for ExtendedDescriptor {
             false
         });
 
-        path_found.map(|path| self.at_derivation_index(path))
+        path_found.map(|path| {
+            self.at_derivation_index(path)
+                .expect("We ignore hardened wildcards")
+        })
     }
 
     fn derive_from_hd_keypaths<'s>(
@@ -543,7 +564,7 @@ impl DescriptorMeta for ExtendedDescriptor {
             return None;
         }
 
-        let descriptor = self.at_derivation_index(0);
+        let descriptor = self.at_derivation_index(0).expect("0 is not hardened");
         match descriptor.desc_type() {
             // TODO: add pk() here
             DescriptorType::Pkh
@@ -582,11 +603,10 @@ mod test {
     use std::str::FromStr;
 
     use assert_matches::assert_matches;
-    use bitcoin::consensus::encode::deserialize;
     use bitcoin::hashes::hex::FromHex;
     use bitcoin::secp256k1::Secp256k1;
-    use bitcoin::util::{bip32, psbt};
-    use bitcoin::Script;
+    use bitcoin::ScriptBuf;
+    use bitcoin::{bip32, psbt::Psbt};
 
     use super::*;
     use crate::psbt::PsbtUtils;
@@ -597,7 +617,7 @@ mod test {
             "wpkh(02b4632d08485ff1df2db55b9dafd23347d1c47a457072a1e87be26896549a8737)",
         )
         .unwrap();
-        let psbt: psbt::PartiallySignedTransaction = deserialize(
+        let psbt = Psbt::deserialize(
             &Vec::<u8>::from_hex(
                 "70736274ff010052010000000162307be8e431fbaff807cdf9cdc3fde44d7402\
                  11bc8342c31ffd6ec11fe35bcc0100000000ffffffff01328601000000000016\
@@ -620,7 +640,7 @@ mod test {
             "pkh([0f056943/44h/0h/0h]tpubDDpWvmUrPZrhSPmUzCMBHffvC3HyMAPnWDSAQNBTnj1iZeJa7BZQEttFiP4DS4GCcXQHezdXhn86Hj6LHX5EDstXPWrMaSneRWM8yUf6NFd/10/*)",
         )
         .unwrap();
-        let psbt: psbt::PartiallySignedTransaction = deserialize(
+        let psbt = Psbt::deserialize(
             &Vec::<u8>::from_hex(
                 "70736274ff010053010000000145843b86be54a3cd8c9e38444e1162676c00df\
                  e7964122a70df491ea12fd67090100000000ffffffff01c19598000000000017\
@@ -651,7 +671,7 @@ mod test {
             "wsh(and_v(v:pk(03b6633fef2397a0a9de9d7b6f23aef8368a6e362b0581f0f0af70d5ecfd254b14),older(6)))",
         )
         .unwrap();
-        let psbt: psbt::PartiallySignedTransaction = deserialize(
+        let psbt = Psbt::deserialize(
             &Vec::<u8>::from_hex(
                 "70736274ff01005302000000011c8116eea34408ab6529223c9a176606742207\
                  67a1ff1d46a6e3c4a88243ea6e01000000000600000001109698000000000017\
@@ -675,7 +695,7 @@ mod test {
             "sh(and_v(v:pk(021403881a5587297818fcaf17d239cefca22fce84a45b3b1d23e836c4af671dbb),after(630000)))",
         )
         .unwrap();
-        let psbt: psbt::PartiallySignedTransaction = deserialize(
+        let psbt = Psbt::deserialize(
             &Vec::<u8>::from_hex(
                 "70736274ff0100530100000001bc8c13df445dfadcc42afa6dc841f85d22b01d\
                  a6270ebf981740f4b7b1d800390000000000feffffff01ba9598000000000017\
@@ -858,9 +878,9 @@ mod test {
         let (descriptor, _) =
             into_wallet_descriptor_checked(descriptor, &secp, Network::Testnet).unwrap();
 
-        let descriptor = descriptor.at_derivation_index(0);
+        let descriptor = descriptor.at_derivation_index(0).unwrap();
 
-        let script = Script::from_str("5321022f533b667e2ea3b36e21961c9fe9dca340fbe0af5210173a83ae0337ab20a57621026bb53a98e810bd0ee61a0ed1164ba6c024786d76554e793e202dc6ce9c78c4ea2102d5b8a7d66a41ffdb6f4c53d61994022e886b4f45001fb158b95c9164d45f8ca3210324b75eead2c1f9c60e8adeb5e7009fec7a29afcdb30d829d82d09562fe8bae8521032d34f8932200833487bd294aa219dcbe000b9f9b3d824799541430009f0fa55121037468f8ea99b6c64788398b5ad25480cad08f4b0d65be54ce3a55fd206b5ae4722103f72d3d96663b0ea99b0aeb0d7f273cab11a8de37885f1dddc8d9112adb87169357ae").unwrap();
+        let script = ScriptBuf::from_hex("5321022f533b667e2ea3b36e21961c9fe9dca340fbe0af5210173a83ae0337ab20a57621026bb53a98e810bd0ee61a0ed1164ba6c024786d76554e793e202dc6ce9c78c4ea2102d5b8a7d66a41ffdb6f4c53d61994022e886b4f45001fb158b95c9164d45f8ca3210324b75eead2c1f9c60e8adeb5e7009fec7a29afcdb30d829d82d09562fe8bae8521032d34f8932200833487bd294aa219dcbe000b9f9b3d824799541430009f0fa55121037468f8ea99b6c64788398b5ad25480cad08f4b0d65be54ce3a55fd206b5ae4722103f72d3d96663b0ea99b0aeb0d7f273cab11a8de37885f1dddc8d9112adb87169357ae").unwrap();
 
         let mut psbt_input = psbt::Input::default();
         psbt_input
index 2063aeb777d15cdcb532c01cf58c65332186cfc0..c38b3387d5dc9d652bfa18ed5396e4443bf56528 100644 (file)
@@ -43,9 +43,9 @@ use std::fmt;
 use serde::ser::SerializeMap;
 use serde::{Serialize, Serializer};
 
+use bitcoin::bip32::Fingerprint;
 use bitcoin::hashes::{hash160, ripemd160, sha256};
-use bitcoin::util::bip32::Fingerprint;
-use bitcoin::{LockTime, PublicKey, Sequence, XOnlyPublicKey};
+use bitcoin::{absolute, key::XOnlyPublicKey, PublicKey, Sequence};
 
 use miniscript::descriptor::{
     DescriptorPublicKey, ShInner, SinglePub, SinglePubKey, SortedMultiVec, WshInner,
@@ -66,7 +66,7 @@ use crate::wallet::utils::{After, Older, SecpCtx};
 use super::checksum::calc_checksum;
 use super::error::Error;
 use super::XKeyUtils;
-use bitcoin::util::psbt::{Input as PsbtInput, PartiallySignedTransaction as Psbt};
+use bitcoin::psbt::{self, Psbt};
 use miniscript::psbt::PsbtInputSatisfier;
 
 /// A unique identifier for a key
@@ -93,6 +93,9 @@ impl PkOrF {
                 ..
             }) => PkOrF::XOnlyPubkey(*pk),
             DescriptorPublicKey::XPub(xpub) => PkOrF::Fingerprint(xpub.root_fingerprint(secp)),
+            DescriptorPublicKey::MultiXPub(multi) => {
+                PkOrF::Fingerprint(multi.root_fingerprint(secp))
+            }
         }
     }
 }
@@ -129,7 +132,7 @@ pub enum SatisfiableItem {
     /// Absolute timeclock timestamp
     AbsoluteTimelock {
         /// The timelock value
-        value: LockTime,
+        value: absolute::LockTime,
     },
     /// Relative timelock locktime
     RelativeTimelock {
@@ -449,11 +452,14 @@ pub struct Condition {
     pub csv: Option<Sequence>,
     /// Optional timelock condition
     #[serde(skip_serializing_if = "Option::is_none")]
-    pub timelock: Option<LockTime>,
+    pub timelock: Option<absolute::LockTime>,
 }
 
 impl Condition {
-    fn merge_nlocktime(a: LockTime, b: LockTime) -> Result<LockTime, PolicyError> {
+    fn merge_nlocktime(
+        a: absolute::LockTime,
+        b: absolute::LockTime,
+    ) -> Result<absolute::LockTime, PolicyError> {
         if !a.is_same_unit(b) {
             Err(PolicyError::MixedTimelockUnits)
         } else if a > b {
@@ -746,6 +752,7 @@ fn signer_id(key: &DescriptorPublicKey, secp: &SecpCtx) -> SignerId {
             ..
         }) => pk.to_pubkeyhash(SigType::Ecdsa).into(),
         DescriptorPublicKey::XPub(xpub) => xpub.root_fingerprint(secp).into(),
+        DescriptorPublicKey::MultiXPub(xpub) => xpub.root_fingerprint(secp).into(),
     }
 }
 
@@ -783,9 +790,9 @@ fn make_generic_signature<M: Fn() -> SatisfiableItem, F: Fn(&Psbt) -> bool>(
 fn generic_sig_in_psbt<
     // C is for "check", it's a closure we use to *check* if a psbt input contains the signature
     // for a specific key
-    C: Fn(&PsbtInput, &SinglePubKey) -> bool,
+    C: Fn(&psbt::Input, &SinglePubKey) -> bool,
     // E is for "extract", it extracts a key from the bip32 derivations found in the psbt input
-    E: Fn(&PsbtInput, Fingerprint) -> Option<SinglePubKey>,
+    E: Fn(&psbt::Input, Fingerprint) -> Option<SinglePubKey>,
 >(
     psbt: &Psbt,
     key: &DescriptorPublicKey,
@@ -803,6 +810,13 @@ fn generic_sig_in_psbt<
                 None => false,
             }
         }
+        DescriptorPublicKey::MultiXPub(xpub) => {
+            //TODO check actual derivation matches
+            match extract(input, xpub.root_fingerprint(secp)) {
+                Some(pubkey) => check(input, &pubkey),
+                None => false,
+            }
+        }
     })
 }
 
@@ -908,12 +922,12 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
             }
             Terminal::After(value) => {
                 let mut policy: Policy = SatisfiableItem::AbsoluteTimelock {
-                    value: value.into(),
+                    value: (*value).into(),
                 }
                 .into();
                 policy.contribution = Satisfaction::Complete {
                     condition: Condition {
-                        timelock: Some(value.into()),
+                        timelock: Some((*value).into()),
                         csv: None,
                     },
                 };
@@ -925,9 +939,9 @@ impl<Ctx: ScriptContext + 'static> ExtractPolicy for Miniscript<DescriptorPublic
                 {
                     let after = After::new(Some(current_height), false);
                     let after_sat =
-                        Satisfier::<bitcoin::PublicKey>::check_after(&after, value.into());
+                        Satisfier::<bitcoin::PublicKey>::check_after(&after, (*value).into());
                     let inputs_sat = psbt_inputs_sat(psbt).all(|sat| {
-                        Satisfier::<bitcoin::PublicKey>::check_after(&sat, value.into())
+                        Satisfier::<bitcoin::PublicKey>::check_after(&sat, (*value).into())
                     });
                     if after_sat && inputs_sat {
                         policy.satisfaction = policy.contribution.clone();
@@ -1152,8 +1166,8 @@ mod test {
     use crate::keys::{DescriptorKey, IntoDescriptorKey};
     use crate::wallet::signer::SignersContainer;
     use assert_matches::assert_matches;
+    use bitcoin::bip32;
     use bitcoin::secp256k1::Secp256k1;
-    use bitcoin::util::bip32;
     use bitcoin::Network;
     use std::str::FromStr;
     use std::sync::Arc;
@@ -1572,6 +1586,7 @@ mod test {
 
         let addr = wallet_desc
             .at_derivation_index(0)
+            .unwrap()
             .address(Network::Testnet)
             .unwrap();
         assert_eq!(
@@ -1638,6 +1653,7 @@ mod test {
 
         let addr = wallet_desc
             .at_derivation_index(0)
+            .unwrap()
             .address(Network::Testnet)
             .unwrap();
         assert_eq!(
index f8af7a95365ff809897ad977ff11219e0530951d..338af696add6ca56e98e70b45efd697d64695bad 100644 (file)
@@ -14,7 +14,7 @@
 //! This module contains the definition of various common script templates that are ready to be
 //! used. See the documentation of each template for an example.
 
-use bitcoin::util::bip32;
+use bitcoin::bip32;
 use bitcoin::Network;
 
 use miniscript::{Legacy, Segwitv0, Tap};
@@ -215,7 +215,7 @@ impl<K: IntoDescriptorKey<Tap>> DescriptorTemplate for P2TR<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip44;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
+/// let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
 /// let wallet = Wallet::new(
 ///     Bip44(key.clone(), KeychainKind::External),
 ///     Some(Bip44(key, KeychainKind::Internal)),
@@ -254,8 +254,8 @@ impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip44Public;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
-/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
+/// let key = bitcoin::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU")?;
+/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
 /// let wallet = Wallet::new(
 ///     Bip44Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip44Public(key, fingerprint, KeychainKind::Internal)),
@@ -294,7 +294,7 @@ impl<K: DerivableKey<Legacy>> DescriptorTemplate for Bip44Public<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip49;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
+/// let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
 /// let wallet = Wallet::new(
 ///     Bip49(key.clone(), KeychainKind::External),
 ///     Some(Bip49(key, KeychainKind::Internal)),
@@ -333,8 +333,8 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip49Public;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
-/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
+/// let key = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L")?;
+/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
 /// let wallet = Wallet::new(
 ///     Bip49Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip49Public(key, fingerprint, KeychainKind::Internal)),
@@ -373,7 +373,7 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip49Public<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip84;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
+/// let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
 /// let wallet = Wallet::new(
 ///     Bip84(key.clone(), KeychainKind::External),
 ///     Some(Bip84(key, KeychainKind::Internal)),
@@ -412,8 +412,8 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip84Public;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
-/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
+/// let key = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
+/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
 /// let wallet = Wallet::new(
 ///     Bip84Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip84Public(key, fingerprint, KeychainKind::Internal)),
@@ -452,7 +452,7 @@ impl<K: DerivableKey<Segwitv0>> DescriptorTemplate for Bip84Public<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip86;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
+/// let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPeZRHk4rTG6orPS2CRNFX3njhUXx5vj9qGog5ZMH4uGReDWN5kCkY3jmWEtWause41CDvBRXD1shKknAMKxT99o9qUTRVC6m")?;
 /// let mut wallet = Wallet::new(
 ///     Bip86(key.clone(), KeychainKind::External),
 ///     Some(Bip86(key, KeychainKind::Internal)),
@@ -491,8 +491,8 @@ impl<K: DerivableKey<Tap>> DescriptorTemplate for Bip86<K> {
 /// # use bdk::wallet::AddressIndex::New;
 /// use bdk::template::Bip86Public;
 ///
-/// let key = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
-/// let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f")?;
+/// let key = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q")?;
+/// let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f")?;
 /// let mut wallet = Wallet::new(
 ///     Bip86Public(key.clone(), fingerprint, KeychainKind::External),
 ///     Some(Bip86Public(key, fingerprint, KeychainKind::Internal)),
@@ -599,30 +599,30 @@ mod test {
     // BIP44 `pkh(key/44'/{0,1}'/0'/{0,1}/*)`
     #[test]
     fn test_bip44_template_cointype() {
-        use bitcoin::util::bip32::ChildNumber::{self, Hardened};
+        use bitcoin::bip32::ChildNumber::{self, Hardened};
 
-        let xprvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K2fpbqApQL69a4oKdGVnVN52R82Ft7d1pSqgKmajF62acJo3aMszZb6qQ22QsVECSFxvf9uyxFUvFYQMq3QbtwtRSMjLAhMf").unwrap();
+        let xprvkey = bitcoin::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K2fpbqApQL69a4oKdGVnVN52R82Ft7d1pSqgKmajF62acJo3aMszZb6qQ22QsVECSFxvf9uyxFUvFYQMq3QbtwtRSMjLAhMf").unwrap();
         assert_eq!(Network::Bitcoin, xprvkey.network);
         let xdesc = Bip44(xprvkey, KeychainKind::Internal)
             .build(Network::Bitcoin)
             .unwrap();
 
         if let ExtendedDescriptor::Pkh(pkh) = xdesc.0 {
-            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().into();
+            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().unwrap().into();
             let purpose = path.get(0).unwrap();
             assert_matches!(purpose, Hardened { index: 44 });
             let coin_type = path.get(1).unwrap();
             assert_matches!(coin_type, Hardened { index: 0 });
         }
 
-        let tprvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let tprvkey = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         assert_eq!(Network::Testnet, tprvkey.network);
         let tdesc = Bip44(tprvkey, KeychainKind::Internal)
             .build(Network::Testnet)
             .unwrap();
 
         if let ExtendedDescriptor::Pkh(pkh) = tdesc.0 {
-            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().into();
+            let path: Vec<ChildNumber> = pkh.into_inner().full_derivation_path().unwrap().into();
             let purpose = path.get(0).unwrap();
             assert_matches!(purpose, Hardened { index: 44 });
             let coin_type = path.get(1).unwrap();
@@ -646,9 +646,9 @@ mod test {
         for i in 0..expected.len() {
             let index = i as u32;
             let child_desc = if !desc.has_wildcard() {
-                desc.at_derivation_index(0)
+                desc.at_derivation_index(0).unwrap()
             } else {
-                desc.at_derivation_index(index)
+                desc.at_derivation_index(index).unwrap()
             };
             let address = child_desc.address(network).unwrap();
             assert_eq!(address.to_string(), *expected.get(i).unwrap());
@@ -774,7 +774,7 @@ mod test {
     // BIP44 `pkh(key/44'/0'/0'/{0,1}/*)`
     #[test]
     fn test_bip44_template() {
-        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let prvkey = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         check(
             Bip44(prvkey, KeychainKind::External).build(Network::Bitcoin),
             false,
@@ -804,8 +804,8 @@ mod test {
     // BIP44 public `pkh(key/{0,1}/*)`
     #[test]
     fn test_bip44_public_template() {
-        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU").unwrap();
-        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
+        let pubkey = bitcoin::bip32::ExtendedPubKey::from_str("tpubDDDzQ31JkZB7VxUr9bjvBivDdqoFLrDPyLWtLapArAi51ftfmCb2DPxwLQzX65iNcXz1DGaVvyvo6JQ6rTU73r2gqdEo8uov9QKRb7nKCSU").unwrap();
+        let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f").unwrap();
         check(
             Bip44Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
             false,
@@ -835,7 +835,7 @@ mod test {
     // BIP49 `sh(wpkh(key/49'/0'/0'/{0,1}/*))`
     #[test]
     fn test_bip49_template() {
-        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let prvkey = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         check(
             Bip49(prvkey, KeychainKind::External).build(Network::Bitcoin),
             true,
@@ -865,8 +865,8 @@ mod test {
     // BIP49 public `sh(wpkh(key/{0,1}/*))`
     #[test]
     fn test_bip49_public_template() {
-        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L").unwrap();
-        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
+        let pubkey = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC49r947KGK52X5rBWS4BLs5m9SRY3pYHnvRrm7HcybZ3BfdEsGFyzCMzayi1u58eT82ZeyFZwH7DD6Q83E3fM9CpfMtmnTygnLfP59jL9L").unwrap();
+        let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f").unwrap();
         check(
             Bip49Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
             true,
@@ -896,7 +896,7 @@ mod test {
     // BIP84 `wpkh(key/84'/0'/0'/{0,1}/*)`
     #[test]
     fn test_bip84_template() {
-        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let prvkey = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         check(
             Bip84(prvkey, KeychainKind::External).build(Network::Bitcoin),
             true,
@@ -926,8 +926,8 @@ mod test {
     // BIP84 public `wpkh(key/{0,1}/*)`
     #[test]
     fn test_bip84_public_template() {
-        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q").unwrap();
-        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("c55b303f").unwrap();
+        let pubkey = bitcoin::bip32::ExtendedPubKey::from_str("tpubDC2Qwo2TFsaNC4ju8nrUJ9mqVT3eSgdmy1yPqhgkjwmke3PRXutNGRYAUo6RCHTcVQaDR3ohNU9we59brGHuEKPvH1ags2nevW5opEE9Z5Q").unwrap();
+        let fingerprint = bitcoin::bip32::Fingerprint::from_str("c55b303f").unwrap();
         check(
             Bip84Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
             true,
@@ -958,7 +958,7 @@ mod test {
     // Used addresses in test vector in https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki
     #[test]
     fn test_bip86_template() {
-        let prvkey = bitcoin::util::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu").unwrap();
+        let prvkey = bitcoin::bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3GJpoapnV8SFfukcVBSfeCficPSGfubmSFDxo1kuHnLisriDvSnRRuL2Qrg5ggqHKNVpxR86QEC8w35uxmGoggxtQTPvfUu").unwrap();
         check(
             Bip86(prvkey, KeychainKind::External).build(Network::Bitcoin),
             false,
@@ -989,8 +989,8 @@ mod test {
     // Used addresses in test vector in https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki
     #[test]
     fn test_bip86_public_template() {
-        let pubkey = bitcoin::util::bip32::ExtendedPubKey::from_str("xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ").unwrap();
-        let fingerprint = bitcoin::util::bip32::Fingerprint::from_str("73c5da0a").unwrap();
+        let pubkey = bitcoin::bip32::ExtendedPubKey::from_str("xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ").unwrap();
+        let fingerprint = bitcoin::bip32::Fingerprint::from_str("73c5da0a").unwrap();
         check(
             Bip86Public(pubkey, fingerprint, KeychainKind::External).build(Network::Bitcoin),
             false,
index fba0fd2d7c0673f8670d343170e9c7dab08a1d2e..29af11ebfa57c018075876ef0f4f1156e36f3094 100644 (file)
@@ -86,6 +86,8 @@ pub enum Error {
         /// found network, for example the network of the bitcoin node
         found: Network,
     },
+    /// The address requested comes from an hardened index
+    HardenedIndex,
     #[cfg(feature = "verify")]
     /// Transaction verification error
     Verification(crate::wallet::verify::VerifyError),
@@ -106,7 +108,7 @@ pub enum Error {
     /// Miniscript PSBT error
     MiniscriptPsbt(MiniscriptPsbtError),
     /// BIP32 error
-    Bip32(bitcoin::util::bip32::Error),
+    Bip32(bitcoin::bip32::Error),
     /// A secp256k1 error
     Secp256k1(bitcoin::secp256k1::Error),
     /// Error serializing or deserializing JSON data
@@ -114,9 +116,9 @@ pub enum Error {
     /// Hex decoding error
     Hex(bitcoin::hashes::hex::Error),
     /// Partially signed bitcoin transaction error
-    Psbt(bitcoin::util::psbt::Error),
+    Psbt(bitcoin::psbt::Error),
     /// Partially signed bitcoin transaction parse error
-    PsbtParse(bitcoin::util::psbt::PsbtParseError),
+    PsbtParse(bitcoin::psbt::PsbtParseError),
 
     //KeyMismatch(bitcoin::secp256k1::PublicKey, bitcoin::secp256k1::PublicKey),
     //MissingInputUTXO(usize),
@@ -228,6 +230,7 @@ impl fmt::Display for Error {
                 "Invalid network: requested {} but found {}",
                 requested, found
             ),
+            Self::HardenedIndex => write!(f, "Requested address from an hardened index"),
             #[cfg(feature = "verify")]
             Self::Verification(err) => write!(f, "Transaction verification error: {}", err),
             Self::InvalidProgressValue(progress) => {
@@ -304,12 +307,12 @@ impl From<crate::keys::KeyError> for Error {
 impl_error!(bitcoin::consensus::encode::Error, Encode);
 impl_error!(miniscript::Error, Miniscript);
 impl_error!(MiniscriptPsbtError, MiniscriptPsbt);
-impl_error!(bitcoin::util::bip32::Error, Bip32);
+impl_error!(bitcoin::bip32::Error, Bip32);
 impl_error!(bitcoin::secp256k1::Error, Secp256k1);
 impl_error!(serde_json::Error, Json);
 impl_error!(bitcoin::hashes::hex::Error, Hex);
-impl_error!(bitcoin::util::psbt::Error, Psbt);
-impl_error!(bitcoin::util::psbt::PsbtParseError, PsbtParse);
+impl_error!(bitcoin::psbt::Error, Psbt);
+impl_error!(bitcoin::psbt::PsbtParseError, PsbtParse);
 
 #[cfg(feature = "electrum")]
 impl_error!(electrum_client::Error, Electrum);
index c79683acf04d1bd810e383cf9120494ceff05cd3..3787490dfc6d0be2e3a13f3edf2e19b35a768ff1 100644 (file)
@@ -14,7 +14,7 @@
 // TODO: maybe write our own implementation of bip39? Seems stupid to have an extra dependency for
 // something that should be fairly simple to re-implement.
 
-use bitcoin::util::bip32;
+use bitcoin::bip32;
 use bitcoin::Network;
 
 use miniscript::ScriptContext;
@@ -141,7 +141,7 @@ impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Mnemonic {
         (word_count, language): Self::Options,
         entropy: Self::Entropy,
     ) -> Result<GeneratedKey<Self, Ctx>, Self::Error> {
-        let entropy = &entropy.as_ref()[..(word_count as usize / 8)];
+        let entropy = &entropy[..(word_count as usize / 8)];
         let mnemonic = Mnemonic::from_entropy_in(language, entropy)?;
 
         Ok(GeneratedKey::new(mnemonic, any_network()))
@@ -152,7 +152,7 @@ impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Mnemonic {
 mod test {
     use std::str::FromStr;
 
-    use bitcoin::util::bip32;
+    use bitcoin::bip32;
 
     use bip39::{Language, Mnemonic};
 
index 84c447fe07ebfee1a10745d02c0510130fe04665..d083f46710911799f167622341bdb77309f46fa0 100644 (file)
@@ -19,8 +19,8 @@ use std::str::FromStr;
 
 use bitcoin::secp256k1::{self, Secp256k1, Signing};
 
-use bitcoin::util::bip32;
-use bitcoin::{Network, PrivateKey, PublicKey, XOnlyPublicKey};
+use bitcoin::bip32;
+use bitcoin::{key::XOnlyPublicKey, Network, PrivateKey, PublicKey};
 
 use miniscript::descriptor::{Descriptor, DescriptorXKey, Wildcard};
 pub use miniscript::descriptor::{
@@ -385,12 +385,12 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
 ///
 /// ```
 /// use bdk::bitcoin;
-/// use bdk::bitcoin::util::bip32;
+/// use bdk::bitcoin::bip32;
 /// use bdk::keys::{DerivableKey, ExtendedKey, KeyError, ScriptContext};
 ///
 /// struct MyCustomKeyType {
 ///     key_data: bitcoin::PrivateKey,
-///     chain_code: Vec<u8>,
+///     chain_code: [u8; 32],
 ///     network: bitcoin::Network,
 /// }
 ///
@@ -401,7 +401,7 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
 ///             depth: 0,
 ///             parent_fingerprint: bip32::Fingerprint::default(),
 ///             private_key: self.key_data.inner,
-///             chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
+///             chain_code: bip32::ChainCode::from(&self.chain_code),
 ///             child_number: bip32::ChildNumber::Normal { index: 0 },
 ///         };
 ///
@@ -416,14 +416,14 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
 ///
 /// ```
 /// use bdk::bitcoin;
-/// use bdk::bitcoin::util::bip32;
+/// use bdk::bitcoin::bip32;
 /// use bdk::keys::{
 ///     any_network, DerivableKey, DescriptorKey, ExtendedKey, KeyError, ScriptContext,
 /// };
 ///
 /// struct MyCustomKeyType {
 ///     key_data: bitcoin::PrivateKey,
-///     chain_code: Vec<u8>,
+///     chain_code: [u8; 32],
 /// }
 ///
 /// impl<Ctx: ScriptContext> DerivableKey<Ctx> for MyCustomKeyType {
@@ -433,7 +433,7 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
 ///             depth: 0,
 ///             parent_fingerprint: bip32::Fingerprint::default(),
 ///             private_key: self.key_data.inner,
-///             chain_code: bip32::ChainCode::from(self.chain_code.as_ref()),
+///             chain_code: bip32::ChainCode::from(&self.chain_code),
 ///             child_number: bip32::ChildNumber::Normal { index: 0 },
 ///         };
 ///
@@ -925,13 +925,13 @@ pub enum KeyError {
     Message(String),
 
     /// BIP32 error
-    Bip32(bitcoin::util::bip32::Error),
+    Bip32(bitcoin::bip32::Error),
     /// Miniscript error
     Miniscript(miniscript::Error),
 }
 
 impl_error!(miniscript::Error, Miniscript, KeyError);
-impl_error!(bitcoin::util::bip32::Error, Bip32, KeyError);
+impl_error!(bitcoin::bip32::Error, Bip32, KeyError);
 
 impl std::fmt::Display for KeyError {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -950,7 +950,7 @@ impl std::error::Error for KeyError {}
 
 #[cfg(test)]
 pub mod test {
-    use bitcoin::util::bip32;
+    use bitcoin::bip32;
 
     use super::*;
 
index 0cdea4a529f70a5a2bbbf8f70b5682aad11bff3c..084314552f40a9b4031ad38a5f565b7918ecbd09 100644 (file)
@@ -149,7 +149,7 @@ fn main() -> Result<(), bdk::Error> {
 //! ```no_run
 //! use std::str::FromStr;
 //!
-//! use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
+//! use bitcoin::psbt::PartiallySignedTransaction as Psbt;
 //!
 //! use bdk::{Wallet, SignOptions};
 //! use bdk::database::MemoryDatabase;
index 04aa84160018f8ee96dd48e108daf13556d20182..471b49472927294e3b64eb43df3030fa0df635f1 100644 (file)
@@ -12,7 +12,7 @@
 //! Additional functions on the `rust-bitcoin` `PartiallySignedTransaction` structure.
 
 use crate::FeeRate;
-use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
+use bitcoin::psbt::PartiallySignedTransaction as Psbt;
 use bitcoin::TxOut;
 
 // TODO upstream the functions here to `rust-bitcoin`?
index a048802e0c5236d286564ede6930c95edc026949..510a2c5bbc20ba574f56cc86f0d6d4af56bbd6ab 100644 (file)
 
 use crate::testutils::TestIncomingTx;
 use bitcoin::consensus::encode::{deserialize, serialize};
-use bitcoin::hashes::hex::{FromHex, ToHex};
 use bitcoin::hashes::sha256d;
-use bitcoin::{Address, Amount, PackedLockTime, Script, Sequence, Transaction, Txid, Witness};
-pub use bitcoincore_rpc::bitcoincore_rpc_json::AddressType;
+use bitcoin::{absolute, Address, Amount, Script, ScriptBuf, Sequence, Transaction, Txid, Witness};
+pub use bitcoincore_rpc::json::AddressType;
 pub use bitcoincore_rpc::{Auth, Client as RpcClient, RpcApi};
 use core::str::FromStr;
 use electrsd::bitcoind::BitcoinD;
+use electrsd::electrum_client::ElectrumApi as _;
 use electrsd::{bitcoind, ElectrsD};
 pub use electrum_client::{Client as ElectrumClient, ElectrumApi};
 #[allow(unused_imports)]
@@ -45,7 +45,11 @@ impl TestClient {
 
         let electrsd = ElectrsD::with_conf(electrs_exe, &bitcoind, &conf).unwrap();
 
-        let node_address = bitcoind.client.get_new_address(None, None).unwrap();
+        let node_address = bitcoind
+            .client
+            .get_new_address(None, None)
+            .unwrap()
+            .assume_checked();
         bitcoind
             .client
             .generate_to_address(101, &node_address)
@@ -107,7 +111,7 @@ impl TestClient {
             .collect();
 
         if self.get_balance(None, None).unwrap() < Amount::from_sat(required_balance) {
-            panic!("Insufficient funds in bitcoind. Please generate a few blocks with: `bitcoin-cli generatetoaddress 10 {}`", self.get_new_address(None, None).unwrap());
+            panic!("Insufficient funds in bitcoind. Please generate a few blocks with: `bitcoin-cli generatetoaddress 10 {}`", self.get_new_address(None, None).unwrap().assume_checked());
         }
 
         // FIXME: core can't create a tx with two outputs to the same address
@@ -143,6 +147,7 @@ impl TestClient {
 
         let monitor_script = Address::from_str(&meta_tx.output[0].to_address)
             .unwrap()
+            .assume_checked()
             .script_pubkey();
         self.wait_for_tx(txid, &monitor_script);
 
@@ -161,7 +166,7 @@ impl TestClient {
 
         let bumped: serde_json::Value = self.call("bumpfee", &[txid.to_string().into()]).unwrap();
         let new_txid = Txid::from_str(&bumped["txid"].as_str().unwrap().to_string()).unwrap();
-        let monitor_script = Script::from_hex(&mut tx.vout[0].script_pub_key.hex.to_hex()).unwrap();
+        let monitor_script = ScriptBuf::from_bytes(tx.vout[0].script_pub_key.hex.clone());
         self.wait_for_tx(new_txid, &monitor_script);
 
         debug!("Bumped {}, new txid {}", txid, new_txid);
@@ -170,41 +175,44 @@ impl TestClient {
     }
 
     pub fn generate_manually(&mut self, txs: Vec<Transaction>) -> String {
-        use bitcoin::blockdata::block::{Block, BlockHeader};
+        use bitcoin::blockdata::block::{Block, Header, Version};
         use bitcoin::blockdata::script::Builder;
         use bitcoin::blockdata::transaction::{OutPoint, TxIn, TxOut};
         use bitcoin::hash_types::{BlockHash, TxMerkleNode};
         use bitcoin::hashes::Hash;
+        use bitcoin::pow::CompactTarget;
 
         let block_template: serde_json::Value = self
             .call("getblocktemplate", &[json!({"rules": ["segwit"]})])
             .unwrap();
         trace!("getblocktemplate: {:#?}", block_template);
 
-        let header = BlockHeader {
-            version: block_template["version"].as_i64().unwrap() as i32,
-            prev_blockhash: BlockHash::from_hex(
+        let header = Header {
+            version: Version::from_consensus(block_template["version"].as_i64().unwrap() as i32),
+            prev_blockhash: BlockHash::from_str(
                 block_template["previousblockhash"].as_str().unwrap(),
             )
             .unwrap(),
             merkle_root: TxMerkleNode::all_zeros(),
             time: block_template["curtime"].as_u64().unwrap() as u32,
-            bits: u32::from_str_radix(block_template["bits"].as_str().unwrap(), 16).unwrap(),
+            bits: CompactTarget::from_consensus(
+                u32::from_str_radix(block_template["bits"].as_str().unwrap(), 16).unwrap(),
+            ),
             nonce: 0,
         };
         debug!("header: {:#?}", header);
 
         let height = block_template["height"].as_u64().unwrap() as i64;
-        let witness_reserved_value: Vec<u8> = sha256d::Hash::all_zeros().as_ref().into();
+        let witness_reserved_value = sha256d::Hash::all_zeros().as_byte_array().to_vec();
         // burn block subsidy and fees, not a big deal
         let mut coinbase_tx = Transaction {
             version: 1,
-            lock_time: PackedLockTime(0),
+            lock_time: absolute::LockTime::ZERO,
             input: vec![TxIn {
                 previous_output: OutPoint::null(),
                 script_sig: Builder::new().push_int(height).into_script(),
                 sequence: Sequence(0xFFFFFFFF),
-                witness: Witness::from_vec(vec![witness_reserved_value]),
+                witness: Witness::from_slice(&vec![witness_reserved_value]),
             }],
             output: vec![],
         };
@@ -225,7 +233,7 @@ impl TestClient {
 
             // now update and replace the coinbase tx
             let mut coinbase_witness_commitment_script = vec![0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed];
-            coinbase_witness_commitment_script.extend_from_slice(&witness_commitment);
+            coinbase_witness_commitment_script.extend_from_slice(witness_commitment.as_ref());
 
             coinbase_tx.output.push(TxOut {
                 value: 0,
@@ -245,11 +253,11 @@ impl TestClient {
 
         // now do PoW :)
         let target = block.header.target();
-        while block.header.validate_pow(&target).is_err() {
+        while block.header.validate_pow(target).is_err() {
             block.header.nonce = block.header.nonce.checked_add(1).unwrap(); // panic if we run out of nonces
         }
 
-        let block_hex: String = serialize(&block).to_hex();
+        let block_hex: String = bitcoin::consensus::encode::serialize_hex(&block);
         debug!("generated block hex: {}", block_hex);
 
         self.electrsd.client.block_headers_subscribe().unwrap();
@@ -265,11 +273,12 @@ impl TestClient {
 
         self.wait_for_block(height as usize);
 
-        block.header.block_hash().to_hex()
+        block.header.block_hash().to_string()
     }
 
     pub fn generate(&mut self, num_blocks: u64, address: Option<Address>) {
-        let address = address.unwrap_or_else(|| self.get_new_address(None, None).unwrap());
+        let address =
+            address.unwrap_or_else(|| self.get_new_address(None, None).unwrap().assume_checked());
         let hashes = self.generate_to_address(num_blocks, &address).unwrap();
         let best_hash = hashes.last().unwrap();
         let height = self.get_block_info(best_hash).unwrap().height;
@@ -317,9 +326,11 @@ impl TestClient {
             &self
                 .get_new_address(None, address_type)
                 .unwrap()
+                .assume_checked()
                 .to_string(),
         )
         .unwrap()
+        .assume_checked()
     }
 }
 
@@ -378,7 +389,7 @@ macro_rules! bdk_blockchain_tests {
      fn $_fn_name:ident ( $( $test_client:ident : &TestClient )? $(,)? ) -> $blockchain:ty $block:block) => {
         #[cfg(test)]
         mod bdk_blockchain_tests {
-            use $crate::bitcoin::{Transaction, Network};
+            use $crate::bitcoin::{Transaction, Network, blockdata::script::PushBytesBuf};
             use $crate::testutils::blockchain_tests::TestClient;
             use $crate::blockchain::Blockchain;
             use $crate::database::MemoryDatabase;
@@ -386,6 +397,7 @@ macro_rules! bdk_blockchain_tests {
             use $crate::wallet::AddressIndex;
             use $crate::{Wallet, FeeRate, SyncOptions};
             use $crate::testutils;
+            use std::convert::TryFrom;
 
             use super::*;
 
@@ -1058,7 +1070,7 @@ macro_rules! bdk_blockchain_tests {
                 assert_eq!(wallet.get_balance().unwrap().untrusted_pending, 50_000, "incorrect balance");
 
                 let mut builder = wallet.build_tx();
-                let data = [42u8;80];
+                let data = PushBytesBuf::try_from(vec![42u8;80]).unwrap();
                 builder.add_data(&data);
                 let (mut psbt, details) = builder.finish().unwrap();
 
@@ -1066,7 +1078,7 @@ macro_rules! bdk_blockchain_tests {
                 assert!(finalized, "Cannot finalize transaction");
                 let tx = psbt.extract_tx();
                 let serialized_tx = bitcoin::consensus::encode::serialize(&tx);
-                assert!(serialized_tx.windows(data.len()).any(|e| e==data), "cannot find op_return data in transaction");
+                assert!(serialized_tx.windows(data.len()).any(|e| e==data.as_bytes()), "cannot find op_return data in transaction");
                 blockchain.broadcast(&tx).unwrap();
                 test_client.generate(1, Some(node_addr));
                 wallet.sync(&blockchain, SyncOptions::default()).unwrap();
@@ -1165,8 +1177,9 @@ macro_rules! bdk_blockchain_tests {
                 // 2. Get a new bech32m address from test bitcoind node taproot wallet
 
                 // TODO replace once rust-bitcoincore-rpc with PR 199 released
-                let node_addr: bitcoin::Address = taproot_wallet_client.call("getnewaddress", &["test address".into(), "bech32m".into()]).unwrap();
-                assert_eq!(node_addr, bitcoin::Address::from_str("bcrt1pj5y3f0fu4y7g98k4v63j9n0xvj3lmln0cpwhsjzknm6nt0hr0q7qnzwsy9").unwrap());
+                let node_addr: bitcoin::Address<bitcoin::address::NetworkUnchecked> = taproot_wallet_client.call("getnewaddress", &["test address".into(), "bech32m".into()]).unwrap();
+                let node_addr = node_addr.assume_checked();
+                assert_eq!(node_addr, bitcoin::Address::from_str("bcrt1pj5y3f0fu4y7g98k4v63j9n0xvj3lmln0cpwhsjzknm6nt0hr0q7qnzwsy9").unwrap().assume_checked());
 
                 // 3. Send 50_000 sats from test bitcoind node to test BDK wallet
 
@@ -1215,7 +1228,7 @@ macro_rules! bdk_blockchain_tests {
 
                 let (wallet, blockchain, _, mut test_client) = init_single_sig();
                 let bdk_address = wallet.get_address(AddressIndex::New).unwrap().address;
-                let core_address = test_client.get_new_address(None, None).unwrap();
+                let core_address = test_client.get_new_address(None, None).unwrap().assume_checked();
                 let tx = testutils! {
                     @tx ( (@addr bdk_address.clone()) => 50_000, (@addr core_address.clone()) => 40_000 )
                 };
@@ -1407,8 +1420,8 @@ macro_rules! bdk_blockchain_tests {
                     "label":"taproot key spend",
                 }]);
                 let _importdescriptors_result: Value = taproot_wallet_client.call("importdescriptors", &[import_descriptor_args]).expect("import wallet");
-                let generate_to_address: bitcoin::Address = taproot_wallet_client.call("getnewaddress", &["test address".into(), "bech32m".into()]).expect("new address");
-                let _generatetoaddress_result = taproot_wallet_client.generate_to_address(101, &generate_to_address).expect("generated to address");
+                let generate_to_address: bitcoin::Address<bitcoin::address::NetworkUnchecked> = taproot_wallet_client.call("getnewaddress", &["test address".into(), "bech32m".into()]).expect("new address");
+                let _generatetoaddress_result = taproot_wallet_client.generate_to_address(101, &generate_to_address.assume_checked()).expect("generated to address");
                 let send_to_address = wallet.get_address($crate::wallet::AddressIndex::New).unwrap().address.to_string();
                 let change_address = wallet.get_address($crate::wallet::AddressIndex::New).unwrap().address.to_string();
                 let send_addr_amounts = json!([{
@@ -1421,7 +1434,7 @@ macro_rules! bdk_blockchain_tests {
                 let send_result: Value = taproot_wallet_client.call("send", &[send_addr_amounts, Value::Null, "unset".into(), Value::Null, send_options]).expect("send psbt");
                 let core_psbt = send_result["psbt"].as_str().expect("core psbt str");
 
-                use bitcoin::util::psbt::PartiallySignedTransaction;
+                use bitcoin::psbt::PartiallySignedTransaction;
 
                 // Test parsing core created PSBT
                 let mut psbt = PartiallySignedTransaction::from_str(&core_psbt).expect("core taproot psbt");
index 32f3951c2094209dd8047896d3f6d62223681a11..730238e74416019775c86b62f5add6b320b5bd2e 100644 (file)
@@ -106,7 +106,7 @@ macro_rules! testutils {
         let secp = Secp256k1::new();
 
         let parsed = Descriptor::<DescriptorPublicKey>::parse_descriptor(&secp, &$descriptors.0).expect("Failed to parse descriptor in `testutils!(@external)`").0;
-        parsed.at_derivation_index($child).address(bitcoin::Network::Regtest).expect("No address form")
+        parsed.at_derivation_index($child).unwrap().address(bitcoin::Network::Regtest).expect("No address form")
     });
     ( @internal $descriptors:expr, $child:expr ) => ({
         use $crate::bitcoin::secp256k1::Secp256k1;
@@ -146,7 +146,7 @@ macro_rules! testutils {
         let mut seed = [0u8; 32];
         rand::thread_rng().fill(&mut seed[..]);
 
-        let key = $crate::bitcoin::util::bip32::ExtendedPrivKey::new_master(
+        let key = $crate::bitcoin::bip32::ExtendedPrivKey::new_master(
             $crate::bitcoin::Network::Testnet,
             &seed,
         );
index cd2ad5b36825b47195025ddb9653ef65861bede4..13e37b9fff53b9da7860137d6a2912aa7caae299 100644 (file)
@@ -13,7 +13,7 @@ use std::convert::AsRef;
 use std::ops::Sub;
 
 use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
-use bitcoin::{hash_types::Txid, util::psbt};
+use bitcoin::{hash_types::Txid, psbt, Weight};
 
 use serde::{Deserialize, Serialize};
 
@@ -97,8 +97,8 @@ impl FeeRate {
     }
 
     /// Calculate fee rate from `fee` and weight units (`wu`).
-    pub fn from_wu(fee: u64, wu: usize) -> FeeRate {
-        Self::from_vb(fee, wu.vbytes())
+    pub fn from_wu(fee: u64, wu: Weight) -> FeeRate {
+        Self::from_vb(fee, wu.to_vbytes_ceil() as usize)
     }
 
     /// Calculate fee rate from `fee` and `vbytes`.
@@ -113,8 +113,8 @@ impl FeeRate {
     }
 
     /// Calculate absolute fee in Satoshis using size in weight units.
-    pub fn fee_wu(&self, wu: usize) -> u64 {
-        self.fee_vb(wu.vbytes())
+    pub fn fee_wu(&self, wu: Weight) -> u64 {
+        self.fee_vb(wu.to_vbytes_ceil() as usize)
     }
 
     /// Calculate absolute fee in Satoshis using size in virtual bytes.
@@ -405,7 +405,7 @@ mod tests {
 
         let tx_details_a = TransactionDetails {
             transaction: None,
-            txid: Txid::from_inner([0; 32]),
+            txid: Txid::all_zeros(),
             received: 0,
             sent: 0,
             fee: None,
@@ -414,7 +414,7 @@ mod tests {
 
         let tx_details_b = TransactionDetails {
             transaction: None,
-            txid: Txid::from_inner([0; 32]),
+            txid: Txid::all_zeros(),
             received: 0,
             sent: 0,
             fee: None,
@@ -423,7 +423,7 @@ mod tests {
 
         let tx_details_c = TransactionDetails {
             transaction: None,
-            txid: Txid::from_inner([0; 32]),
+            txid: Txid::all_zeros(),
             received: 0,
             sent: 0,
             fee: None,
@@ -432,7 +432,7 @@ mod tests {
 
         let tx_details_d = TransactionDetails {
             transaction: None,
-            txid: Txid::from_inner([1; 32]),
+            txid: Txid::from_byte_array([1; Txid::LEN]),
             received: 0,
             sent: 0,
             fee: None,
index 8482f96a9de20fdc8d11f3d9b577750d1a6bdcaf..7ee259088cc39f64e1d915ddc3df7d970cab4379 100644 (file)
 //!         database: &D,
 //!         required_utxos: Vec<WeightedUtxo>,
 //!         optional_utxos: Vec<WeightedUtxo>,
-//!         fee_rate: FeeRate,
+//!         fee_rate: bdk::FeeRate,
 //!         target_amount: u64,
 //!         drain_script: &Script,
 //!     ) -> Result<CoinSelectionResult, bdk::Error> {
 //!         let mut selected_amount = 0;
-//!         let mut additional_weight = 0;
+//!         let mut additional_weight = Weight::ZERO;
 //!         let all_utxos_selected = required_utxos
 //!             .into_iter()
 //!             .chain(optional_utxos)
@@ -53,7 +53,9 @@
 //!                 (&mut selected_amount, &mut additional_weight),
 //!                 |(selected_amount, additional_weight), weighted_utxo| {
 //!                     **selected_amount += weighted_utxo.utxo.txout().value;
-//!                     **additional_weight += TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight;
+//!                     **additional_weight += Weight::from_wu(
+//!                         (TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight) as u64,
+//!                     );
 //!                     Some(weighted_utxo.utxo)
 //!                 },
 //!             )
 //! # let wallet = doctest_wallet!();
 //! // create wallet, sync, ...
 //!
-//! let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+//! let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
+//!     .unwrap()
+//!     .require_network(Network::Testnet)
+//!     .unwrap();
 //! let (psbt, details) = {
 //!     let mut builder = wallet.build_tx().coin_selection(AlwaysSpendEverything);
 //!     builder.add_recipient(to_address.script_pubkey(), 50_000);
@@ -100,7 +105,7 @@ use crate::{database::Database, WeightedUtxo};
 use crate::{error::Error, Utxo};
 
 use bitcoin::consensus::encode::serialize;
-use bitcoin::Script;
+use bitcoin::{Script, Weight};
 
 #[cfg(test)]
 use assert_matches::assert_matches;
@@ -337,8 +342,9 @@ fn select_sorted_utxos(
             (&mut selected_amount, &mut fee_amount),
             |(selected_amount, fee_amount), (must_use, weighted_utxo)| {
                 if must_use || **selected_amount < target_amount + **fee_amount {
-                    **fee_amount +=
-                        fee_rate.fee_wu(TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight);
+                    **fee_amount += fee_rate.fee_wu(Weight::from_wu(
+                        (TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight) as u64,
+                    ));
                     **selected_amount += weighted_utxo.utxo.txout().value;
 
                     log::debug!(
@@ -386,7 +392,9 @@ struct OutputGroup {
 
 impl OutputGroup {
     fn new(weighted_utxo: WeightedUtxo, fee_rate: FeeRate) -> Self {
-        let fee = fee_rate.fee_wu(TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight);
+        let fee = fee_rate.fee_wu(Weight::from_wu(
+            (TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight) as u64,
+        ));
         let effective_value = weighted_utxo.utxo.txout().value as i64 - fee as i64;
         OutputGroup {
             weighted_utxo,
@@ -724,7 +732,7 @@ impl BranchAndBoundCoinSelection {
 mod test {
     use std::str::FromStr;
 
-    use bitcoin::{OutPoint, Script, TxOut};
+    use bitcoin::{OutPoint, ScriptBuf, TxOut};
 
     use super::*;
     use crate::database::{BatchOperations, MemoryDatabase};
@@ -754,7 +762,7 @@ mod test {
                 outpoint,
                 txout: TxOut {
                     value,
-                    script_pubkey: Script::new(),
+                    script_pubkey: ScriptBuf::new(),
                 },
                 keychain: KeychainKind::External,
                 is_spent: false,
@@ -837,7 +845,7 @@ mod test {
                     .unwrap(),
                     txout: TxOut {
                         value: rng.gen_range(0..200000000),
-                        script_pubkey: Script::new(),
+                        script_pubkey: ScriptBuf::new(),
                     },
                     keychain: KeychainKind::External,
                     is_spent: false,
@@ -857,7 +865,7 @@ mod test {
                 .unwrap(),
                 txout: TxOut {
                     value: utxos_value,
-                    script_pubkey: Script::new(),
+                    script_pubkey: ScriptBuf::new(),
                 },
                 keychain: KeychainKind::External,
                 is_spent: false,
@@ -879,7 +887,7 @@ mod test {
     fn test_largest_first_coin_selection_success() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 250_000 + FEE_AMOUNT;
 
         let result = LargestFirstCoinSelection::default()
@@ -902,7 +910,7 @@ mod test {
     fn test_largest_first_coin_selection_use_all() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = LargestFirstCoinSelection::default()
@@ -925,7 +933,7 @@ mod test {
     fn test_largest_first_coin_selection_use_only_necessary() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = LargestFirstCoinSelection::default()
@@ -949,7 +957,7 @@ mod test {
     fn test_largest_first_coin_selection_insufficient_funds() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 500_000 + FEE_AMOUNT;
 
         LargestFirstCoinSelection::default()
@@ -969,7 +977,7 @@ mod test {
     fn test_largest_first_coin_selection_insufficient_funds_high_fees() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 250_000 + FEE_AMOUNT;
 
         LargestFirstCoinSelection::default()
@@ -988,7 +996,7 @@ mod test {
     fn test_oldest_first_coin_selection_success() {
         let mut database = MemoryDatabase::default();
         let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 180_000 + FEE_AMOUNT;
 
         let result = OldestFirstCoinSelection::default()
@@ -1013,7 +1021,7 @@ mod test {
         let utxo1 = utxo(120_000, 1);
         let utxo2 = utxo(80_000, 2);
         let utxo3 = utxo(300_000, 3);
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let mut database = MemoryDatabase::default();
 
@@ -1070,7 +1078,7 @@ mod test {
     fn test_oldest_first_coin_selection_use_all() {
         let mut database = MemoryDatabase::default();
         let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = OldestFirstCoinSelection::default()
@@ -1093,7 +1101,7 @@ mod test {
     fn test_oldest_first_coin_selection_use_only_necessary() {
         let mut database = MemoryDatabase::default();
         let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = OldestFirstCoinSelection::default()
@@ -1117,7 +1125,7 @@ mod test {
     fn test_oldest_first_coin_selection_insufficient_funds() {
         let mut database = MemoryDatabase::default();
         let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 600_000 + FEE_AMOUNT;
 
         OldestFirstCoinSelection::default()
@@ -1139,7 +1147,7 @@ mod test {
         let utxos = setup_database_and_get_oldest_first_test_utxos(&mut database);
 
         let target_amount: u64 = utxos.iter().map(|wu| wu.utxo.txout().value).sum::<u64>() - 50;
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         OldestFirstCoinSelection::default()
             .coin_select(
@@ -1160,7 +1168,7 @@ mod test {
         let utxos = generate_same_value_utxos(100_000, 20);
 
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let target_amount = 250_000 + FEE_AMOUNT;
 
@@ -1184,7 +1192,7 @@ mod test {
     fn test_bnb_coin_selection_required_are_enough() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let result = BranchAndBoundCoinSelection::default()
@@ -1207,7 +1215,7 @@ mod test {
     fn test_bnb_coin_selection_optional_are_enough() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 299756 + FEE_AMOUNT;
 
         let result = BranchAndBoundCoinSelection::default()
@@ -1241,7 +1249,7 @@ mod test {
         assert_eq!(amount, 100_000);
         let amount: u64 = optional.iter().map(|u| u.utxo.txout().value).sum();
         assert!(amount > 150_000);
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let target_amount = 150_000 + FEE_AMOUNT;
 
@@ -1266,7 +1274,7 @@ mod test {
     fn test_bnb_coin_selection_insufficient_funds() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 500_000 + FEE_AMOUNT;
 
         BranchAndBoundCoinSelection::default()
@@ -1286,7 +1294,7 @@ mod test {
     fn test_bnb_coin_selection_insufficient_funds_high_fees() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 250_000 + FEE_AMOUNT;
 
         BranchAndBoundCoinSelection::default()
@@ -1305,7 +1313,7 @@ mod test {
     fn test_bnb_coin_selection_check_fee_rate() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 99932; // first utxo's effective value
 
         let result = BranchAndBoundCoinSelection::new(0)
@@ -1335,7 +1343,7 @@ mod test {
         for _i in 0..200 {
             let mut optional_utxos = generate_random_utxos(&mut rng, 16);
             let target_amount = sum_random_utxos(&mut rng, &mut optional_utxos);
-            let drain_script = Script::default();
+            let drain_script = ScriptBuf::default();
             let result = BranchAndBoundCoinSelection::new(0)
                 .coin_select(
                     &database,
@@ -1364,7 +1372,7 @@ mod test {
         let size_of_change = 31;
         let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
 
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
         let target_amount = 20_000 + FEE_AMOUNT;
         BranchAndBoundCoinSelection::new(size_of_change)
             .bnb(
@@ -1395,7 +1403,7 @@ mod test {
         let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
         let target_amount = 20_000 + FEE_AMOUNT;
 
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         BranchAndBoundCoinSelection::new(size_of_change)
             .bnb(
@@ -1431,7 +1439,7 @@ mod test {
         // cost_of_change + 5.
         let target_amount = 2 * 50_000 - 2 * 67 - cost_of_change.ceil() as i64 + 5;
 
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let result = BranchAndBoundCoinSelection::new(size_of_change)
             .bnb(
@@ -1471,7 +1479,7 @@ mod test {
             let target_amount =
                 optional_utxos[3].effective_value + optional_utxos[23].effective_value;
 
-            let drain_script = Script::default();
+            let drain_script = ScriptBuf::default();
 
             let result = BranchAndBoundCoinSelection::new(0)
                 .bnb(
@@ -1502,7 +1510,7 @@ mod test {
             .map(|u| OutputGroup::new(u, fee_rate))
             .collect();
 
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let result = BranchAndBoundCoinSelection::default().single_random_draw(
             vec![],
@@ -1521,7 +1529,7 @@ mod test {
     fn test_bnb_exclude_negative_effective_value() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let selection = BranchAndBoundCoinSelection::default().coin_select(
             &database,
@@ -1545,7 +1553,7 @@ mod test {
     fn test_bnb_include_negative_effective_value_when_required() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let (required, optional) = utxos
             .into_iter()
@@ -1573,7 +1581,7 @@ mod test {
     fn test_bnb_sum_of_effective_value_negative() {
         let utxos = get_test_utxos();
         let database = MemoryDatabase::default();
-        let drain_script = Script::default();
+        let drain_script = ScriptBuf::default();
 
         let selection = BranchAndBoundCoinSelection::default().coin_select(
             &database,
index 230cd4cf0380c9def6d591aa55c2354c7bf0749a..02ba3a6b7387666d5935ccce26c2d5e21bd7925d 100644 (file)
@@ -20,7 +20,7 @@
 //! # use bdk::wallet::hardwaresigner::HWISigner;
 //! # use bdk::wallet::AddressIndex::New;
 //! # use bdk::{FeeRate, KeychainKind, SignOptions, SyncOptions, Wallet};
-//! # use hwi::{types::HWIChain, HWIClient};
+//! # use hwi::HWIClient;
 //! # use std::sync::Arc;
 //! #
 //! # fn main() -> Result<(), Box<dyn std::error::Error>> {
@@ -29,7 +29,7 @@
 //!     panic!("No devices found!");
 //! }
 //! let first_device = devices.remove(0)?;
-//! let custom_signer = HWISigner::from_device(&first_device, HWIChain::Test)?;
+//! let custom_signer = HWISigner::from_device(&first_device, Network::Testnet.into())?;
 //!
 //! # let mut wallet = Wallet::new(
 //! #     "",
@@ -49,9 +49,9 @@
 //! # }
 //! ```
 
+use bitcoin::bip32::Fingerprint;
 use bitcoin::psbt::PartiallySignedTransaction;
 use bitcoin::secp256k1::{All, Secp256k1};
-use bitcoin::util::bip32::Fingerprint;
 
 use hwi::error::Error;
 use hwi::types::{HWIChain, HWIDevice};
index 55a2ef223f4ecb6a6a96773d58828d9b7870ccc7..82feacecc87aee5e7b939bd043255cb23e3419cd 100644 (file)
@@ -24,10 +24,11 @@ use std::sync::Arc;
 use bitcoin::secp256k1::Secp256k1;
 
 use bitcoin::consensus::encode::serialize;
-use bitcoin::util::psbt;
+use bitcoin::psbt;
+use bitcoin::sighash::{EcdsaSighashType, TapSighashType};
 use bitcoin::{
-    Address, EcdsaSighashType, LockTime, Network, OutPoint, SchnorrSighashType, Script, Sequence,
-    Transaction, TxOut, Txid, Witness,
+    absolute, Address, Network, OutPoint, Script, ScriptBuf, Sequence, Transaction, TxOut, Txid,
+    Weight, Witness,
 };
 
 use miniscript::psbt::{PsbtExt, PsbtInputExt, PsbtInputSatisfier};
@@ -116,13 +117,15 @@ pub enum AddressIndex {
     /// web page.
     LastUnused,
     /// Return the address for a specific descriptor index. Does not change the current descriptor
-    /// index used by `AddressIndex::New` and `AddressIndex::LastUsed`.
+    /// index used by `AddressIndex::New` and `AddressIndex::LastUsed`. The index must be non-hardened,
+    /// i.e., < 2**31.
     ///
     /// Use with caution, if an index is given that is less than the current descriptor index
     /// then the returned address may have already been used.
     Peek(u32),
     /// Return the address for a specific descriptor index and reset the current descriptor index
-    /// used by `AddressIndex::New` and `AddressIndex::LastUsed` to this value.
+    /// used by `AddressIndex::New` and `AddressIndex::LastUsed` to this value. The index must be
+    /// non-hardened, i.e. < 2**31
     ///
     /// Use with caution, if an index is given that is less than the current descriptor index
     /// then the returned address and subsequent addresses returned by calls to `AddressIndex::New`
@@ -257,6 +260,7 @@ where
         let address_result = self
             .get_descriptor_for_keychain(keychain)
             .at_derivation_index(incremented_index)
+            .expect("can't be hardened")
             .address(self.network);
 
         address_result
@@ -275,7 +279,8 @@ where
 
         let derived_key = self
             .get_descriptor_for_keychain(keychain)
-            .at_derivation_index(current_index);
+            .at_derivation_index(current_index)
+            .expect("can't be hardened");
 
         let script_pubkey = derived_key.script_pubkey();
 
@@ -304,6 +309,7 @@ where
     fn peek_address(&self, index: u32, keychain: KeychainKind) -> Result<AddressInfo, Error> {
         self.get_descriptor_for_keychain(keychain)
             .at_derivation_index(index)
+            .map_err(|_| Error::HardenedIndex)?
             .address(self.network)
             .map(|address| AddressInfo {
                 index,
@@ -320,6 +326,7 @@ where
 
         self.get_descriptor_for_keychain(keychain)
             .at_derivation_index(index)
+            .map_err(|_| Error::HardenedIndex)?
             .address(self.network)
             .map(|address| AddressInfo {
                 index,
@@ -567,7 +574,7 @@ where
     /// # use bdk::database::*;
     /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
     /// # let wallet = doctest_wallet!();
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
     /// let (psbt, details) = {
     ///    let mut builder =  wallet.build_tx();
     ///    builder
@@ -669,7 +676,8 @@ where
         let current_height = match params.current_height {
             // If they didn't tell us the current height, we assume it's the latest sync height.
             None => self.database().get_sync_time()?.map(|sync_time| {
-                LockTime::from_height(sync_time.block_time.height).expect("Invalid height")
+                absolute::LockTime::from_height(sync_time.block_time.height)
+                    .expect("Invalid height")
             }),
             h => h,
         };
@@ -680,7 +688,7 @@ where
                 // Fee sniping can be partially prevented by setting the timelock
                 // to current_height. If we don't know the current_height,
                 // we default to 0.
-                let fee_sniping_height = current_height.unwrap_or(LockTime::ZERO);
+                let fee_sniping_height = current_height.unwrap_or(absolute::LockTime::ZERO);
 
                 // We choose the biggest between the required nlocktime and the fee sniping
                 // height
@@ -688,7 +696,7 @@ where
                     // No requirement, just use the fee_sniping_height
                     None => fee_sniping_height,
                     // There's a block-based requirement, but the value is lower than the fee_sniping_height
-                    Some(value @ LockTime::Blocks(_)) if value < fee_sniping_height => fee_sniping_height,
+                    Some(value @ absolute::LockTime::Blocks(_)) if value < fee_sniping_height => fee_sniping_height,
                     // There's a time-based requirement or a block-based requirement greater
                     // than the fee_sniping_height use that value
                     Some(value) => value,
@@ -704,7 +712,9 @@ where
 
         let n_sequence = match (params.rbf, requirements.csv) {
             // No RBF or CSV but there's an nLockTime, so the nSequence cannot be final
-            (None, None) if lock_time != LockTime::ZERO => Sequence::ENABLE_LOCKTIME_NO_RBF,
+            (None, None) if lock_time != absolute::LockTime::ZERO => {
+                Sequence::ENABLE_LOCKTIME_NO_RBF
+            }
             // No RBF, CSV or nLockTime, make the transaction final
             (None, None) => Sequence::MAX,
 
@@ -767,7 +777,7 @@ where
 
         let mut tx = Transaction {
             version,
-            lock_time: lock_time.into(),
+            lock_time,
             input: vec![],
             output: vec![],
         };
@@ -815,7 +825,7 @@ where
         // end up with a transaction with a slightly higher fee rate than the requested one.
         // If, instead, we undershoot, we may end up with a feerate lower than the requested one
         // - we might come up with non broadcastable txs!
-        fee_amount += fee_rate.fee_wu(2);
+        fee_amount += fee_rate.fee_wu(Weight::from_wu(2));
 
         if params.change_policy != tx_builder::ChangeSpendPolicy::ChangeAllowed
             && self.change_descriptor.is_none()
@@ -832,7 +842,7 @@ where
             params.drain_wallet,
             params.manually_selected_only,
             params.bumping_fee.is_some(), // we mandate confirmed transactions if we're bumping the fee
-            current_height.map(LockTime::to_consensus_u32),
+            current_height.map(absolute::LockTime::to_consensus_u32),
         )?;
 
         // get drain script
@@ -860,7 +870,7 @@ where
             .iter()
             .map(|u| bitcoin::TxIn {
                 previous_output: u.outpoint(),
-                script_sig: Script::default(),
+                script_sig: ScriptBuf::default(),
                 sequence: n_sequence,
                 witness: Witness::new(),
             })
@@ -949,7 +959,8 @@ where
     /// # use bdk::database::*;
     /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
     /// # let wallet = doctest_wallet!();
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address =
+    /// Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
     /// let (mut psbt, _) = {
     ///     let mut builder = wallet.build_tx();
     ///     builder
@@ -963,7 +974,7 @@ where
     /// let (mut psbt, _) =  {
     ///     let mut builder = wallet.build_fee_bump(tx.txid())?;
     ///     builder
-    ///         .fee_rate(FeeRate::from_sat_per_vb(5.0));
+    ///         .fee_rate(bdk::FeeRate::from_sat_per_vb(5.0));
     ///     builder.finish()?
     /// };
     ///
@@ -1010,6 +1021,7 @@ where
                     .borrow()
                     .get_path_from_script_pubkey(&txout.script_pubkey)?
                 {
+                    #[allow(deprecated)]
                     Some((keychain, _)) => (
                         self._get_descriptor_for_keychain(keychain)
                             .0
@@ -1100,7 +1112,7 @@ where
     /// # use bdk::database::*;
     /// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
     /// # let wallet = doctest_wallet!();
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
     /// let (mut psbt, _) = {
     ///     let mut builder = wallet.build_tx();
     ///     builder.add_recipient(to_address.script_pubkey(), 50_000);
@@ -1137,8 +1149,8 @@ where
             && !psbt.inputs.iter().all(|i| {
                 i.sighash_type.is_none()
                     || i.sighash_type == Some(EcdsaSighashType::All.into())
-                    || i.sighash_type == Some(SchnorrSighashType::All.into())
-                    || i.sighash_type == Some(SchnorrSighashType::Default.into())
+                    || i.sighash_type == Some(TapSighashType::All.into())
+                    || i.sighash_type == Some(TapSighashType::Default.into())
             })
         {
             return Err(Error::Signer(signer::SignerError::NonStandardSighash));
@@ -1323,7 +1335,10 @@ where
             .borrow()
             .get_path_from_script_pubkey(&txout.script_pubkey)?
             .map(|(keychain, child)| (self.get_descriptor_for_keychain(keychain), child))
-            .map(|(desc, child)| desc.at_derivation_index(child)))
+            .map(|(desc, child)| {
+                desc.at_derivation_index(child)
+                    .expect("child is not hardened")
+            }))
     }
 
     fn fetch_and_increment_index(&self, keychain: KeychainKind) -> Result<u32, Error> {
@@ -1384,7 +1399,10 @@ where
         let start_time = time::Instant::new();
         for i in from..(from + count) {
             address_batch.set_script_pubkey(
-                &descriptor.at_derivation_index(i).script_pubkey(),
+                &descriptor
+                    .at_derivation_index(i)
+                    .expect("i is not hardened")
+                    .script_pubkey(),
                 keychain,
                 i,
             )?;
@@ -1410,6 +1428,7 @@ where
                 let keychain = utxo.keychain;
                 (
                     utxo,
+                    #[allow(deprecated)]
                     self.get_descriptor_for_keychain(keychain)
                         .max_satisfaction_weight()
                         .unwrap(),
@@ -1614,7 +1633,9 @@ where
         };
 
         let desc = self.get_descriptor_for_keychain(keychain);
-        let derived_descriptor = desc.at_derivation_index(child);
+        let derived_descriptor = desc
+            .at_derivation_index(child)
+            .expect("child can't be hardened");
 
         psbt_input
             .update_with_descriptor_unchecked(&derived_descriptor)
@@ -1665,7 +1686,9 @@ where
                 );
 
                 let desc = self.get_descriptor_for_keychain(keychain);
-                let desc = desc.at_derivation_index(child);
+                let desc = desc
+                    .at_derivation_index(child)
+                    .expect("child can't be hardened");
 
                 if is_input {
                     psbt.update_input_with_descriptor(index, &desc)
@@ -1830,6 +1853,7 @@ pub fn get_funded_wallet(
         .set_script_pubkey(
             &bitcoin::Address::from_str(&tx_meta.output.get(0).unwrap().to_address)
                 .unwrap()
+                .assume_checked()
                 .script_pubkey(),
             KeychainKind::External,
             funding_address_kix,
@@ -1849,7 +1873,7 @@ pub fn get_funded_wallet(
 #[cfg(test)]
 pub(crate) mod test {
     use assert_matches::assert_matches;
-    use bitcoin::{util::psbt, Network, PackedLockTime, Sequence};
+    use bitcoin::{absolute, blockdata::script::PushBytes, psbt, Network, Sequence};
 
     use crate::database::Database;
     use crate::types::KeychainKind;
@@ -2185,7 +2209,7 @@ pub(crate) mod test {
 
         // Since we never synced the wallet we don't have a last_sync_height
         // we could use to try to prevent fee sniping. We default to 0.
-        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(0));
+        assert_eq!(psbt.unsigned_tx.lock_time, absolute::LockTime::ZERO);
     }
 
     #[test]
@@ -2210,7 +2234,10 @@ pub(crate) mod test {
         let (psbt, _) = builder.finish().unwrap();
 
         // current_height will override the last sync height
-        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(current_height));
+        assert_eq!(
+            psbt.unsigned_tx.lock_time,
+            absolute::LockTime::from_height(current_height).unwrap()
+        );
     }
 
     #[test]
@@ -2235,7 +2262,7 @@ pub(crate) mod test {
         // If there's no current_height we're left with using the last sync height
         assert_eq!(
             psbt.unsigned_tx.lock_time,
-            PackedLockTime(sync_time.block_time.height)
+            absolute::LockTime::from_height(sync_time.block_time.height).unwrap()
         );
     }
 
@@ -2247,7 +2274,10 @@ pub(crate) mod test {
         builder.add_recipient(addr.script_pubkey(), 25_000);
         let (psbt, _) = builder.finish().unwrap();
 
-        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(100_000));
+        assert_eq!(
+            psbt.unsigned_tx.lock_time,
+            absolute::LockTime::from_height(100_000).unwrap()
+        );
     }
 
     #[test]
@@ -2258,13 +2288,16 @@ pub(crate) mod test {
         builder
             .add_recipient(addr.script_pubkey(), 25_000)
             .current_height(630_001)
-            .nlocktime(LockTime::from_height(630_000).unwrap());
+            .nlocktime(absolute::LockTime::from_height(630_000).unwrap());
         let (psbt, _) = builder.finish().unwrap();
 
         // When we explicitly specify a nlocktime
         // we don't try any fee sniping prevention trick
         // (we ignore the current_height)
-        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(630_000));
+        assert_eq!(
+            psbt.unsigned_tx.lock_time,
+            absolute::LockTime::from_height(630_000).unwrap()
+        );
     }
 
     #[test]
@@ -2274,10 +2307,13 @@ pub(crate) mod test {
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 25_000)
-            .nlocktime(LockTime::from_height(630_000).unwrap());
+            .nlocktime(absolute::LockTime::from_height(630_000).unwrap());
         let (psbt, _) = builder.finish().unwrap();
 
-        assert_eq!(psbt.unsigned_tx.lock_time, PackedLockTime(630_000));
+        assert_eq!(
+            psbt.unsigned_tx.lock_time,
+            absolute::LockTime::from_height(630_000).unwrap()
+        );
     }
 
     #[test]
@@ -2290,7 +2326,7 @@ pub(crate) mod test {
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 25_000)
-            .nlocktime(LockTime::from_height(50000).unwrap());
+            .nlocktime(absolute::LockTime::from_height(50000).unwrap());
         builder.finish().unwrap();
     }
 
@@ -2428,7 +2464,9 @@ pub(crate) mod test {
     #[test]
     fn test_create_tx_drain_wallet_and_drain_to_and_with_recipient() {
         let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
-        let addr = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+        let addr = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
+            .unwrap()
+            .assume_checked();
         let drain_addr = wallet.get_address(New).unwrap();
         let mut builder = wallet.build_tx();
         builder
@@ -2645,19 +2683,18 @@ pub(crate) mod test {
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 30_000)
-            .sighash(bitcoin::EcdsaSighashType::Single.into());
+            .sighash(bitcoin::sighash::EcdsaSighashType::Single.into());
         let (psbt, _) = builder.finish().unwrap();
 
         assert_eq!(
             psbt.inputs[0].sighash_type,
-            Some(bitcoin::EcdsaSighashType::Single.into())
+            Some(bitcoin::sighash::EcdsaSighashType::Single.into())
         );
     }
 
     #[test]
     fn test_create_tx_input_hd_keypaths() {
-        use bitcoin::util::bip32::{DerivationPath, Fingerprint};
-        use std::str::FromStr;
+        use bitcoin::bip32::{DerivationPath, Fingerprint};
 
         let (wallet, _, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
         let addr = wallet.get_address(New).unwrap();
@@ -2677,8 +2714,7 @@ pub(crate) mod test {
 
     #[test]
     fn test_create_tx_output_hd_keypaths() {
-        use bitcoin::util::bip32::{DerivationPath, Fingerprint};
-        use std::str::FromStr;
+        use bitcoin::bip32::{DerivationPath, Fingerprint};
 
         let (wallet, descriptors, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
         // cache some addresses
@@ -2712,7 +2748,7 @@ pub(crate) mod test {
 
         assert_eq!(
             psbt.inputs[0].redeem_script,
-            Some(Script::from(
+            Some(ScriptBuf::from(
                 Vec::<u8>::from_hex(
                     "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
                 )
@@ -2736,7 +2772,7 @@ pub(crate) mod test {
         assert_eq!(psbt.inputs[0].redeem_script, None);
         assert_eq!(
             psbt.inputs[0].witness_script,
-            Some(Script::from(
+            Some(ScriptBuf::from(
                 Vec::<u8>::from_hex(
                     "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac"
                 )
@@ -2756,7 +2792,7 @@ pub(crate) mod test {
         builder.drain_to(addr.script_pubkey()).drain_wallet();
         let (psbt, _) = builder.finish().unwrap();
 
-        let script = Script::from(
+        let script = ScriptBuf::from(
             Vec::<u8>::from_hex(
                 "21032b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3ac",
             )
@@ -2830,7 +2866,9 @@ pub(crate) mod test {
             Some(100),
         );
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 30_000)
@@ -2859,7 +2897,9 @@ pub(crate) mod test {
             Some(100),
         );
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 30_000)
@@ -2877,7 +2917,9 @@ pub(crate) mod test {
     fn test_create_tx_policy_path_required() {
         let (wallet, _, _) = get_funded_wallet(get_test_a_or_b_plus_csv());
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder.add_recipient(addr.script_pubkey(), 30_000);
         builder.finish().unwrap();
@@ -2907,7 +2949,9 @@ pub(crate) mod test {
         // child #0 is just the key "A"
         let path = vec![(root_id, vec![0])].into_iter().collect();
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 30_000)
@@ -2926,7 +2970,9 @@ pub(crate) mod test {
         // child #1 is or(pk(B),older(144))
         let path = vec![(root_id, vec![1])].into_iter().collect();
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 30_000)
@@ -2945,7 +2991,9 @@ pub(crate) mod test {
         // child #0 is pk(cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu)
         let path = vec![(root_id, vec![0])].into_iter().collect();
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 30_000)
@@ -2957,8 +3005,8 @@ pub(crate) mod test {
 
     #[test]
     fn test_create_tx_global_xpubs_with_origin() {
+        use bitcoin::bip32;
         use bitcoin::hashes::hex::FromHex;
-        use bitcoin::util::bip32;
 
         let (wallet, _, _) = get_funded_wallet("wpkh([73756c7f/48'/0'/0'/2']tpubDCKxNyM3bLgbEX13Mcd8mYxbVg9ajDkWXMh29hMWBurKfVmBfWAM96QVP3zaUcN51HvkZ3ar4VwP82kC8JZhhux8vFQoJintSpVBwpFvyU3/0/*)");
         let addr = wallet.get_address(New).unwrap();
@@ -2982,8 +3030,11 @@ pub(crate) mod test {
         let (wallet2, _, _) =
             get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let utxo = wallet2.list_unspent().unwrap().remove(0);
+        #[allow(deprecated)]
         let foreign_utxo_satisfaction = wallet2
             .get_descriptor_for_keychain(KeychainKind::External)
             .max_satisfaction_weight()
@@ -3049,6 +3100,7 @@ pub(crate) mod test {
         let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
         let mut builder = wallet.build_tx();
         let outpoint = wallet.list_unspent().unwrap()[0].outpoint;
+        #[allow(deprecated)]
         let foreign_utxo_satisfaction = wallet
             .get_descriptor_for_keychain(KeychainKind::External)
             .max_satisfaction_weight()
@@ -3082,6 +3134,7 @@ pub(crate) mod test {
             .transaction
             .unwrap();
 
+        #[allow(deprecated)]
         let satisfaction_weight = wallet2
             .get_descriptor_for_keychain(KeychainKind::External)
             .max_satisfaction_weight()
@@ -3121,9 +3174,12 @@ pub(crate) mod test {
         let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
         let (wallet2, _, txid2) =
             get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)");
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let utxo2 = wallet2.list_unspent().unwrap().remove(0);
 
+        #[allow(deprecated)]
         let satisfaction_weight = wallet2
             .get_descriptor_for_keychain(KeychainKind::External)
             .max_satisfaction_weight()
@@ -3213,8 +3269,8 @@ pub(crate) mod test {
 
     #[test]
     fn test_create_tx_global_xpubs_master_without_origin() {
+        use bitcoin::bip32;
         use bitcoin::hashes::hex::FromHex;
-        use bitcoin::util::bip32;
 
         let (wallet, _, _) = get_funded_wallet("wpkh(tpubD6NzVbkrYhZ4Y55A58Gv9RSNF5hy84b5AJqYy7sCcjFrkcLpPre8kmgfit6kY1Zs3BLgeypTDBZJM222guPpdz7Cup5yzaMu62u7mYGbwFL/0/*)");
         let addr = wallet.get_address(New).unwrap();
@@ -3343,7 +3399,9 @@ pub(crate) mod test {
     #[test]
     fn test_bump_fee_reduce_change() {
         let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 25_000)
@@ -3403,7 +3461,9 @@ pub(crate) mod test {
     #[test]
     fn test_bump_fee_absolute_reduce_change() {
         let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 25_000)
@@ -3469,7 +3529,9 @@ pub(crate) mod test {
     #[test]
     fn test_bump_fee_reduce_single_recipient() {
         let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .drain_to(addr.script_pubkey())
@@ -3513,7 +3575,9 @@ pub(crate) mod test {
     #[test]
     fn test_bump_fee_absolute_reduce_single_recipient() {
         let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .drain_to(addr.script_pubkey())
@@ -3567,7 +3631,9 @@ pub(crate) mod test {
             txid: incoming_txid,
             vout: 0,
         };
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .drain_to(addr.script_pubkey())
@@ -3624,7 +3690,9 @@ pub(crate) mod test {
             txid: incoming_txid,
             vout: 0,
         };
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .drain_to(addr.script_pubkey())
@@ -3667,7 +3735,9 @@ pub(crate) mod test {
             Some(100),
         );
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 45_000)
@@ -3730,7 +3800,9 @@ pub(crate) mod test {
             Some(100),
         );
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 45_000)
@@ -3794,7 +3866,9 @@ pub(crate) mod test {
         );
 
         // initially make a tx without change by using `drain_to`
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .drain_to(addr.script_pubkey())
@@ -3870,7 +3944,9 @@ pub(crate) mod test {
             Some(100),
         );
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 45_000)
@@ -3907,7 +3983,7 @@ pub(crate) mod test {
         // + extra input weight: 160 WU = (32 (prevout) + 4 (vout) + 4 (nsequence)) * 4
         // + input satisfaction weight: 112 WU = 106 (witness) + 2 (witness len) + (1 (script len)) * 4
         // - change output weight: 124 WU = (8 (value) + 1 (script len) + 22 (script)) * 4
-        let new_tx_weight = original_tx_weight + 160 + 112 - 124;
+        let new_tx_weight = original_tx_weight + Weight::from_wu(160 + 112 - 124);
         // two inputs (50k, 25k) and one output (45k) - epsilon
         // We use epsilon here to avoid asking for a slightly too high feerate
         let fee_abs = 50_000 + 25_000 - 45_000 - 10;
@@ -3947,7 +4023,9 @@ pub(crate) mod test {
             Some(100),
         );
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 45_000)
@@ -4018,7 +4096,9 @@ pub(crate) mod test {
             Some(100),
         );
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 45_000)
@@ -4090,7 +4170,9 @@ pub(crate) mod test {
         // The replacement transaction may only include an unconfirmed input
         // if that input was included in one of the original transactions.
         let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .drain_wallet()
@@ -4134,7 +4216,9 @@ pub(crate) mod test {
         // always fee bump with an unconfirmed input if it was included in the
         // original transaction)
         let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         // We receive a tx with 0 confirmations, which will be used as an input
         // in the drain tx.
         crate::populate_test_db!(
@@ -4184,7 +4268,9 @@ pub(crate) mod test {
         // for a transaction.
         // See https://github.com/bitcoindevkit/bdk/issues/660
         let (wallet, descriptors, _) = get_funded_wallet(get_test_wpkh());
-        let send_to = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt").unwrap();
+        let send_to = Address::from_str("tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt")
+            .unwrap()
+            .assume_checked();
         let fee_rate = FeeRate::from_sat_per_vb(2.01);
         let incoming_txid = crate::populate_test_db!(
             wallet.database.borrow_mut(),
@@ -4302,7 +4388,9 @@ pub(crate) mod test {
     #[test]
     fn test_include_output_redeem_witness_script() {
         let (wallet, _, _) = get_funded_wallet("sh(wsh(multi(1,cVpPVruEDdmutPzisEsYvtST1usBR3ntr8pXSyt6D2YYqXRyPcFW,cRjo6jqfVNP33HhSS76UhXETZsGTZYx8FMFvR9kpbtCSV1PmdZdu)))");
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 45_000)
@@ -4319,7 +4407,9 @@ pub(crate) mod test {
     #[test]
     fn test_signing_only_one_of_multiple_inputs() {
         let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), 45_000)
@@ -4327,7 +4417,7 @@ pub(crate) mod test {
         let (mut psbt, _) = builder.finish().unwrap();
 
         // add another input to the psbt that is at least passable.
-        let dud_input = bitcoin::util::psbt::Input {
+        let dud_input = bitcoin::psbt::Input {
             witness_utxo: Some(TxOut {
                 value: 100_000,
                 script_pubkey: miniscript::Descriptor::<bitcoin::PublicKey>::from_str(
@@ -4619,7 +4709,9 @@ pub(crate) mod test {
             wallet.get_address(New).unwrap(),
             AddressInfo {
                 index: 0,
-                address: Address::from_str("tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a").unwrap(),
+                address: Address::from_str("tb1q6yn66vajcctph75pvylgkksgpp6nq04ppwct9a")
+                    .unwrap()
+                    .assume_checked(),
                 keychain: KeychainKind::External,
             }
         );
@@ -4629,7 +4721,9 @@ pub(crate) mod test {
             wallet.get_address(New).unwrap(),
             AddressInfo {
                 index: 1,
-                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7").unwrap(),
+                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7")
+                    .unwrap()
+                    .assume_checked(),
                 keychain: KeychainKind::External,
             }
         );
@@ -4639,7 +4733,9 @@ pub(crate) mod test {
             wallet.get_address(Peek(25)).unwrap(),
             AddressInfo {
                 index: 25,
-                address: Address::from_str("tb1qsp7qu0knx3sl6536dzs0703u2w2ag6ppl9d0c2").unwrap(),
+                address: Address::from_str("tb1qsp7qu0knx3sl6536dzs0703u2w2ag6ppl9d0c2")
+                    .unwrap()
+                    .assume_checked(),
                 keychain: KeychainKind::External,
             }
         );
@@ -4649,7 +4745,9 @@ pub(crate) mod test {
             wallet.get_address(New).unwrap(),
             AddressInfo {
                 index: 2,
-                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2").unwrap(),
+                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2")
+                    .unwrap()
+                    .assume_checked(),
                 keychain: KeychainKind::External,
             }
         );
@@ -4659,7 +4757,9 @@ pub(crate) mod test {
             wallet.get_address(Reset(1)).unwrap(),
             AddressInfo {
                 index: 1,
-                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7").unwrap(),
+                address: Address::from_str("tb1q4er7kxx6sssz3q7qp7zsqsdx4erceahhax77d7")
+                    .unwrap()
+                    .assume_checked(),
                 keychain: KeychainKind::External,
             }
         );
@@ -4669,7 +4769,9 @@ pub(crate) mod test {
             wallet.get_address(New).unwrap(),
             AddressInfo {
                 index: 2,
-                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2").unwrap(),
+                address: Address::from_str("tb1qzntf2mqex4ehwkjlfdyy3ewdlk08qkvkvrz7x2")
+                    .unwrap()
+                    .assume_checked(),
                 keychain: KeychainKind::External,
             }
         );
@@ -4680,7 +4782,8 @@ pub(crate) mod test {
         let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
         let addr =
             Address::from_str("tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c")
-                .unwrap();
+                .unwrap()
+                .assume_checked();
         let mut builder = wallet.build_tx();
         builder.add_recipient(addr.script_pubkey(), 45_000);
         builder.finish().unwrap();
@@ -4689,7 +4792,7 @@ pub(crate) mod test {
     #[test]
     fn test_get_address() {
         use crate::descriptor::template::Bip84;
-        let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         let wallet = Wallet::new(
             Bip84(key, KeychainKind::External),
             Some(Bip84(key, KeychainKind::Internal)),
@@ -4702,7 +4805,9 @@ pub(crate) mod test {
             wallet.get_address(AddressIndex::New).unwrap(),
             AddressInfo {
                 index: 0,
-                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
+                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w")
+                    .unwrap()
+                    .assume_checked(),
                 keychain: KeychainKind::External,
             }
         );
@@ -4711,7 +4816,9 @@ pub(crate) mod test {
             wallet.get_internal_address(AddressIndex::New).unwrap(),
             AddressInfo {
                 index: 0,
-                address: Address::from_str("bcrt1q0ue3s5y935tw7v3gmnh36c5zzsaw4n9c9smq79").unwrap(),
+                address: Address::from_str("bcrt1q0ue3s5y935tw7v3gmnh36c5zzsaw4n9c9smq79")
+                    .unwrap()
+                    .assume_checked(),
                 keychain: KeychainKind::Internal,
             }
         );
@@ -4728,7 +4835,9 @@ pub(crate) mod test {
             wallet.get_internal_address(AddressIndex::New).unwrap(),
             AddressInfo {
                 index: 0,
-                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w").unwrap(),
+                address: Address::from_str("bcrt1qrhgaqu0zvf5q2d0gwwz04w0dh0cuehhqvzpp4w")
+                    .unwrap()
+                    .assume_checked(),
                 keychain: KeychainKind::Internal,
             },
             "when there's no internal descriptor it should just use external"
@@ -4740,7 +4849,7 @@ pub(crate) mod test {
         use crate::descriptor::template::Bip84;
         use std::collections::HashSet;
 
-        let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
+        let key = bitcoin::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
         let wallet = Wallet::new(
             Bip84(key, KeychainKind::External),
             None,
@@ -4803,7 +4912,7 @@ pub(crate) mod test {
         let (wallet, _, _) = get_funded_wallet(get_test_tr_repeated_key());
         let addr = wallet.get_address(AddressIndex::New).unwrap();
 
-        let path = vec![("e5mmg3xh".to_string(), vec![0])]
+        let path = vec![("rn4nre9c".to_string(), vec![0])]
             .into_iter()
             .collect();
 
@@ -4823,13 +4932,6 @@ pub(crate) mod test {
         assert_eq!(
             input_key_origins,
             vec![
-                (
-                    from_str!("b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55"),
-                    (
-                        vec![],
-                        (FromStr::from_str("871fd295").unwrap(), vec![].into())
-                    )
-                ),
                 (
                     from_str!("2b0558078bec38694a84933d659303e2575dae7e91685911454115bfd64487e3"),
                     (
@@ -4843,7 +4945,14 @@ pub(crate) mod test {
                         ],
                         (FromStr::from_str("ece52657").unwrap(), vec![].into())
                     )
-                )
+                ),
+                (
+                    from_str!("b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55"),
+                    (
+                        vec![],
+                        (FromStr::from_str("871fd295").unwrap(), vec![].into())
+                    )
+                ),
             ],
             "Wrong input tap_key_origins"
         );
@@ -4863,10 +4972,8 @@ pub(crate) mod test {
 
     #[test]
     fn test_taproot_psbt_input_tap_tree() {
-        use crate::bitcoin::psbt::serialize::Deserialize;
-        use crate::bitcoin::psbt::TapTree;
         use bitcoin::hashes::hex::FromHex;
-        use bitcoin::util::taproot;
+        use bitcoin::taproot;
 
         let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree());
         let addr = wallet.get_address(AddressIndex::Peek(0)).unwrap();
@@ -4878,7 +4985,7 @@ pub(crate) mod test {
         assert_eq!(
             psbt.inputs[0].tap_merkle_root,
             Some(
-                FromHex::from_hex(
+                taproot::TapNodeHash::from_str(
                     "61f81509635053e52d9d1217545916167394490da2287aca4693606e43851986"
                 )
                 .unwrap()
@@ -4887,9 +4994,9 @@ pub(crate) mod test {
         assert_eq!(
             psbt.inputs[0].tap_scripts.clone().into_iter().collect::<Vec<_>>(),
             vec![
-                (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b7ef769a745e625ed4b9a4982a4dc08274c59187e73e6f07171108f455081cb2").unwrap()).unwrap(), (from_str!("208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac"), taproot::LeafVersion::TapScript)),
-                (taproot::ControlBlock::from_slice(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b9a515f7be31a70186e3c5937ee4a70cc4b4e1efe876c1d38e408222ffc64834").unwrap()).unwrap(), (from_str!("2051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac"), taproot::LeafVersion::TapScript)),
-            ],
+            (taproot::ControlBlock::decode(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b7ef769a745e625ed4b9a4982a4dc08274c59187e73e6f07171108f455081cb2").unwrap()).unwrap(), (ScriptBuf::from_hex("208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac").unwrap(), taproot::LeafVersion::TapScript)),
+            (taproot::ControlBlock::decode(&Vec::<u8>::from_hex("c0b511bd5771e47ee27558b1765e87b541668304ec567721c7b880edc0a010da55b9a515f7be31a70186e3c5937ee4a70cc4b4e1efe876c1d38e408222ffc64834").unwrap()).unwrap(), (ScriptBuf::from_hex("2051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac").unwrap(), taproot::LeafVersion::TapScript)),
+        ],
         );
         assert_eq!(
             psbt.inputs[0].tap_internal_key,
@@ -4905,10 +5012,8 @@ pub(crate) mod test {
             psbt.outputs[0].tap_internal_key
         );
 
-        assert_eq!(
-            psbt.outputs[0].tap_tree,
-            Some(TapTree::deserialize(&Vec::<u8>::from_hex("01c022208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac01c0222051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac",).unwrap()).unwrap())
-        );
+        let tap_tree: bitcoin::taproot::TapTree = serde_json::from_str(r#"[1,{"Script":["2051494dc22e24a32fe9dcfbd7e85faf345fa1df296fb49d156e859ef345201295ac",192]},1,{"Script":["208aee2b8120a5f157f1223f72b5e62b825831a27a9fdf427db7cc697494d4a642ac",192]}]"#).unwrap();
+        assert_eq!(psbt.outputs[0].tap_tree, Some(tap_tree));
     }
 
     #[test]
@@ -4979,9 +5084,12 @@ pub(crate) mod test {
         let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
         let (wallet2, _, _) = get_funded_wallet(get_test_tr_single_sig());
 
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let utxo = wallet2.list_unspent().unwrap().remove(0);
         let psbt_input = wallet2.get_psbt_input(utxo.clone(), None, false).unwrap();
+        #[allow(deprecated)]
         let foreign_utxo_satisfaction = wallet2
             .get_descriptor_for_keychain(KeychainKind::External)
             .max_satisfaction_weight()
@@ -5102,7 +5210,7 @@ pub(crate) mod test {
     #[test]
     fn test_taproot_script_spend_sign_include_some_leaves() {
         use crate::signer::TapLeavesOptions;
-        use bitcoin::util::taproot::TapLeafHash;
+        use bitcoin::taproot::TapLeafHash;
 
         let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
         let addr = wallet.get_address(AddressIndex::New).unwrap();
@@ -5144,7 +5252,7 @@ pub(crate) mod test {
     #[test]
     fn test_taproot_script_spend_sign_exclude_some_leaves() {
         use crate::signer::TapLeavesOptions;
-        use bitcoin::util::taproot::TapLeafHash;
+        use bitcoin::taproot::TapLeafHash;
 
         let (wallet, _, _) = get_funded_wallet(get_test_tr_with_taptree_both_priv());
         let addr = wallet.get_address(AddressIndex::New).unwrap();
@@ -5240,7 +5348,7 @@ pub(crate) mod test {
         let mut builder = wallet.build_tx();
         builder
             .drain_to(addr.script_pubkey())
-            .sighash(SchnorrSighashType::All.into())
+            .sighash(TapSighashType::All.into())
             .drain_wallet();
         let (mut psbt, _) = builder.finish().unwrap();
 
@@ -5253,7 +5361,7 @@ pub(crate) mod test {
 
     #[test]
     fn test_taproot_sign_non_default_sighash() {
-        let sighash = SchnorrSighashType::NonePlusAnyoneCanPay;
+        let sighash = TapSighashType::NonePlusAnyoneCanPay;
 
         let (wallet, _, _) = get_funded_wallet(get_test_tr_single_sig());
         let addr = wallet.get_address(New).unwrap();
@@ -5367,7 +5475,9 @@ pub(crate) mod test {
 
         // We try to create a transaction, only to notice that all
         // our funds are unspendable
-        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap();
+        let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX")
+            .unwrap()
+            .assume_checked();
         let mut builder = wallet.build_tx();
         builder
             .add_recipient(addr.script_pubkey(), balance.immature / 2)
@@ -5453,7 +5563,7 @@ pub(crate) mod test {
         let addr = wallet.get_address(New).unwrap();
         let fee_rate = FeeRate::from_sat_per_vb(1.0);
         let mut builder = wallet.build_tx();
-        let mut data = vec![0];
+        let data: &PushBytes = From::<&[u8; 1]>::from(&[0; 1]);
         builder
             .drain_to(addr.script_pubkey())
             .drain_wallet()
@@ -5473,8 +5583,8 @@ pub(crate) mod test {
         while sig_len < 71 {
             // Changing the OP_RETURN data will make the signature change (but not the fee, until
             // data[0] is small enough)
-            data[0] += 1;
-            psbt.unsigned_tx.output[op_return_vout].script_pubkey = Script::new_op_return(&data);
+            let data: &PushBytes = From::<&[u8; 1]>::from(&[1; 1]);
+            psbt.unsigned_tx.output[op_return_vout].script_pubkey = ScriptBuf::new_op_return(&data);
             // Clearing the previous signature
             psbt.inputs[0].partial_sigs.clear();
             // Signing
@@ -5545,7 +5655,6 @@ pub(crate) mod test {
     #[test]
     fn test_create_signer() {
         use crate::wallet::hardwaresigner::HWISigner;
-        use hwi::types::HWIChain;
         use hwi::HWIClient;
 
         let mut devices = HWIClient::enumerate().unwrap();
@@ -5553,9 +5662,9 @@ pub(crate) mod test {
             panic!("No devices found!");
         }
         let device = devices.remove(0).unwrap();
-        let client = HWIClient::get_client(&device, true, HWIChain::Regtest).unwrap();
+        let client = HWIClient::get_client(&device, true, Network::Regtest.into()).unwrap();
         let descriptors = client.get_descriptors::<String>(None).unwrap();
-        let custom_signer = HWISigner::from_device(&device, HWIChain::Regtest).unwrap();
+        let custom_signer = HWISigner::from_device(&device, Network::Regtest.into()).unwrap();
 
         let (mut wallet, _, _) = get_funded_wallet(&descriptors.internal[0]);
         wallet.add_signer(
index ff54cfa8a770f34b11ff0342fe39da4954716cae..6197040a245fe0aaa3d6365abebe277313487af9 100644 (file)
@@ -19,7 +19,7 @@
 //! # use std::str::FromStr;
 //! # use bitcoin::secp256k1::{Secp256k1, All};
 //! # use bitcoin::*;
-//! # use bitcoin::util::psbt;
+//! # use bitcoin::psbt;
 //! # use bdk::signer::*;
 //! # use bdk::database::*;
 //! # use bdk::*;
@@ -86,18 +86,17 @@ use std::fmt;
 use std::ops::{Bound::Included, Deref};
 use std::sync::Arc;
 
-use bitcoin::blockdata::opcodes;
-use bitcoin::blockdata::script::Builder as ScriptBuilder;
-use bitcoin::hashes::{hash160, Hash};
+use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, Fingerprint};
+use bitcoin::hashes::hash160;
 use bitcoin::secp256k1::Message;
-use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, Fingerprint};
-use bitcoin::util::{ecdsa, psbt, schnorr, sighash, taproot};
-use bitcoin::{secp256k1, XOnlyPublicKey};
-use bitcoin::{EcdsaSighashType, PrivateKey, PublicKey, SchnorrSighashType, Script};
+use bitcoin::sighash::{EcdsaSighashType, TapSighash, TapSighashType};
+use bitcoin::{ecdsa, psbt, sighash, taproot};
+use bitcoin::{key::TapTweak, key::XOnlyPublicKey, secp256k1};
+use bitcoin::{PrivateKey, PublicKey};
 
 use miniscript::descriptor::{
-    Descriptor, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, KeyMap, SinglePriv,
-    SinglePubKey,
+    Descriptor, DescriptorMultiXKey, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey,
+    InnerXKey, KeyMap, SinglePriv, SinglePubKey,
 };
 use miniscript::{Legacy, Segwitv0, SigType, Tap, ToPublicKey};
 
@@ -130,7 +129,7 @@ impl From<Fingerprint> for SignerId {
 }
 
 /// Signing error
-#[derive(Debug, PartialEq, Eq, Clone)]
+#[derive(Debug)]
 pub enum SignerError {
     /// The private key is missing for the required public key
     MissingKey,
@@ -382,6 +381,49 @@ impl InputSigner for SignerWrapper<DescriptorXKey<ExtendedPrivKey>> {
     }
 }
 
+fn multikey_to_xkeys<K: InnerXKey + Clone>(
+    multikey: DescriptorMultiXKey<K>,
+) -> Vec<DescriptorXKey<K>> {
+    multikey
+        .derivation_paths
+        .clone()
+        .into_paths()
+        .into_iter()
+        .map(|derivation_path| DescriptorXKey {
+            origin: multikey.origin.clone(),
+            xkey: multikey.xkey.clone(),
+            derivation_path,
+            wildcard: multikey.wildcard,
+        })
+        .collect()
+}
+
+impl SignerCommon for SignerWrapper<DescriptorMultiXKey<ExtendedPrivKey>> {
+    fn id(&self, secp: &SecpCtx) -> SignerId {
+        SignerId::from(self.root_fingerprint(secp))
+    }
+
+    fn descriptor_secret_key(&self) -> Option<DescriptorSecretKey> {
+        Some(DescriptorSecretKey::MultiXPrv(self.signer.clone()))
+    }
+}
+
+impl InputSigner for SignerWrapper<DescriptorMultiXKey<ExtendedPrivKey>> {
+    fn sign_input(
+        &self,
+        psbt: &mut psbt::PartiallySignedTransaction,
+        input_index: usize,
+        sign_options: &SignOptions,
+        secp: &SecpCtx,
+    ) -> Result<(), SignerError> {
+        let xkeys = multikey_to_xkeys(self.signer.clone());
+        for xkey in xkeys {
+            SignerWrapper::new(xkey, self.ctx).sign_input(psbt, input_index, sign_options, secp)?
+        }
+        Ok(())
+    }
+}
+
 impl SignerCommon for SignerWrapper<PrivateKey> {
     fn id(&self, secp: &SecpCtx) -> SignerId {
         SignerId::from(self.public_key(secp).to_pubkeyhash(SigType::Ecdsa))
@@ -476,8 +518,16 @@ impl InputSigner for SignerWrapper<PrivateKey> {
         }
 
         let (hash, hash_ty) = match self.ctx {
-            SignerContext::Segwitv0 => Segwitv0::sighash(psbt, input_index, ())?,
-            SignerContext::Legacy => Legacy::sighash(psbt, input_index, ())?,
+            SignerContext::Segwitv0 => {
+                let (h, t) = Segwitv0::sighash(psbt, input_index, ())?;
+                let h = h.to_raw_hash();
+                (h, t)
+            }
+            SignerContext::Legacy => {
+                let (h, t) = Legacy::sighash(psbt, input_index, ())?;
+                let h = h.to_raw_hash();
+                (h, t)
+            }
             _ => return Ok(()), // handled above
         };
         sign_psbt_ecdsa(
@@ -498,12 +548,12 @@ fn sign_psbt_ecdsa(
     secret_key: &secp256k1::SecretKey,
     pubkey: PublicKey,
     psbt_input: &mut psbt::Input,
-    hash: bitcoin::Sighash,
+    hash: impl bitcoin::hashes::Hash + bitcoin::secp256k1::ThirtyTwoByteHash,
     hash_ty: EcdsaSighashType,
     secp: &SecpCtx,
     allow_grinding: bool,
 ) {
-    let msg = &Message::from_slice(&hash.into_inner()[..]).unwrap();
+    let msg = &Message::from(hash);
     let sig = if allow_grinding {
         secp.sign_ecdsa_low_r(msg, secret_key)
     } else {
@@ -512,7 +562,7 @@ fn sign_psbt_ecdsa(
     secp.verify_ecdsa(msg, &sig, &pubkey.inner)
         .expect("invalid or corrupted ecdsa signature");
 
-    let final_signature = ecdsa::EcdsaSig { sig, hash_ty };
+    let final_signature = ecdsa::Signature { sig, hash_ty };
     psbt_input.partial_sigs.insert(pubkey, final_signature);
 }
 
@@ -522,12 +572,10 @@ fn sign_psbt_schnorr(
     pubkey: XOnlyPublicKey,
     leaf_hash: Option<taproot::TapLeafHash>,
     psbt_input: &mut psbt::Input,
-    hash: taproot::TapSighashHash,
-    hash_ty: SchnorrSighashType,
+    hash: TapSighash,
+    hash_ty: TapSighashType,
     secp: &SecpCtx,
 ) {
-    use schnorr::TapTweak;
-
     let keypair = secp256k1::KeyPair::from_seckey_slice(secp, secret_key.as_ref()).unwrap();
     let keypair = match leaf_hash {
         None => keypair
@@ -536,12 +584,12 @@ fn sign_psbt_schnorr(
         Some(_) => keypair, // no tweak for script spend
     };
 
-    let msg = &Message::from_slice(&hash.into_inner()[..]).unwrap();
+    let msg = &Message::from(hash);
     let sig = secp.sign_schnorr(msg, &keypair);
     secp.verify_schnorr(&sig, msg, &XOnlyPublicKey::from_keypair(&keypair).0)
         .expect("invalid or corrupted schnorr signature");
 
-    let final_signature = schnorr::SchnorrSig { sig, hash_ty };
+    let final_signature = taproot::Signature { sig, hash_ty };
 
     if let Some(lh) = leaf_hash {
         psbt_input
@@ -631,6 +679,11 @@ impl SignersContainer {
                     SignerOrdering::default(),
                     Arc::new(SignerWrapper::new(xprv, ctx)),
                 ),
+                DescriptorSecretKey::MultiXPrv(xprv) => container.add_external(
+                    SignerId::from(xprv.root_fingerprint(secp)),
+                    SignerOrdering::default(),
+                    Arc::new(SignerWrapper::new(xprv, ctx)),
+                ),
             };
         }
 
@@ -801,7 +854,7 @@ pub(crate) trait ComputeSighash {
 
 impl ComputeSighash for Legacy {
     type Extra = ();
-    type Sighash = bitcoin::Sighash;
+    type Sighash = sighash::LegacySighash;
     type SighashType = EcdsaSighashType;
 
     fn sighash(
@@ -848,19 +901,9 @@ impl ComputeSighash for Legacy {
     }
 }
 
-fn p2wpkh_script_code(script: &Script) -> Script {
-    ScriptBuilder::new()
-        .push_opcode(opcodes::all::OP_DUP)
-        .push_opcode(opcodes::all::OP_HASH160)
-        .push_slice(&script[2..])
-        .push_opcode(opcodes::all::OP_EQUALVERIFY)
-        .push_opcode(opcodes::all::OP_CHECKSIG)
-        .into_script()
-}
-
 impl ComputeSighash for Segwitv0 {
     type Extra = ();
-    type Sighash = bitcoin::Sighash;
+    type Sighash = sighash::SegwitV0Sighash;
     type SighashType = EcdsaSighashType;
 
     fn sighash(
@@ -907,14 +950,21 @@ impl ComputeSighash for Segwitv0 {
             Some(ref witness_script) => witness_script.clone(),
             None => {
                 if utxo.script_pubkey.is_v0_p2wpkh() {
-                    p2wpkh_script_code(&utxo.script_pubkey)
+                    utxo.script_pubkey
+                        .p2wpkh_script_code()
+                        .expect("We check above that the spk is a p2wpkh")
                 } else if psbt_input
                     .redeem_script
                     .as_ref()
-                    .map(Script::is_v0_p2wpkh)
+                    .map(|s| s.is_v0_p2wpkh())
                     .unwrap_or(false)
                 {
-                    p2wpkh_script_code(psbt_input.redeem_script.as_ref().unwrap())
+                    psbt_input
+                        .redeem_script
+                        .as_ref()
+                        .unwrap()
+                        .p2wpkh_script_code()
+                        .expect("We check above that the spk is a p2wpkh")
                 } else {
                     return Err(SignerError::MissingWitnessScript);
                 }
@@ -935,14 +985,14 @@ impl ComputeSighash for Segwitv0 {
 
 impl ComputeSighash for Tap {
     type Extra = Option<taproot::TapLeafHash>;
-    type Sighash = taproot::TapSighashHash;
-    type SighashType = SchnorrSighashType;
+    type Sighash = TapSighash;
+    type SighashType = TapSighashType;
 
     fn sighash(
         psbt: &psbt::PartiallySignedTransaction,
         input_index: usize,
         extra: Self::Extra,
-    ) -> Result<(Self::Sighash, SchnorrSighashType), SignerError> {
+    ) -> Result<(Self::Sighash, TapSighashType), SignerError> {
         if input_index >= psbt.inputs.len() || input_index >= psbt.unsigned_tx.input.len() {
             return Err(SignerError::InputIndexOutOfRange);
         }
@@ -951,8 +1001,8 @@ impl ComputeSighash for Tap {
 
         let sighash_type = psbt_input
             .sighash_type
-            .unwrap_or_else(|| SchnorrSighashType::Default.into())
-            .schnorr_hash_ty()
+            .unwrap_or_else(|| TapSighashType::Default.into())
+            .taproot_hash_ty()
             .map_err(|_| SignerError::InvalidSighash)?;
         let witness_utxos = (0..psbt.inputs.len())
             .map(|i| psbt.get_utxo_for(i))
@@ -1014,8 +1064,8 @@ mod signers_container_tests {
     use crate::descriptor::IntoWalletDescriptor;
     use crate::keys::{DescriptorKey, IntoDescriptorKey};
     use assert_matches::assert_matches;
+    use bitcoin::bip32;
     use bitcoin::secp256k1::{All, Secp256k1};
-    use bitcoin::util::bip32;
     use bitcoin::Network;
     use miniscript::ScriptContext;
     use std::str::FromStr;
index 6d52b8d9040c1d3bca901bcdbf630c49b2d8500d..b7eed0d4db0f4749ba5a5ee674646053fd3fe8f5 100644 (file)
@@ -18,7 +18,7 @@
 //! # use bitcoin::*;
 //! # use bdk::*;
 //! # use bdk::wallet::tx_builder::CreateTx;
-//! # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+//! # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
 //! # let wallet = doctest_wallet!();
 //! // create a TxBuilder from a wallet
 //! let mut tx_builder = wallet.build_tx();
@@ -27,7 +27,7 @@
 //!     // Create a transaction with one output to `to_address` of 50_000 satoshi
 //!     .add_recipient(to_address.script_pubkey(), 50_000)
 //!     // With a custom fee rate of 5.0 satoshi/vbyte
-//!     .fee_rate(FeeRate::from_sat_per_vb(5.0))
+//!     .fee_rate(bdk::FeeRate::from_sat_per_vb(5.0))
 //!     // Only spend non-change outputs
 //!     .do_not_spend_change()
 //!     // Turn on RBF signaling
@@ -41,8 +41,8 @@ use std::collections::HashSet;
 use std::default::Default;
 use std::marker::PhantomData;
 
-use bitcoin::util::psbt::{self, PartiallySignedTransaction as Psbt};
-use bitcoin::{LockTime, OutPoint, Script, Sequence, Transaction};
+use bitcoin::psbt::{self, PartiallySignedTransaction as Psbt};
+use bitcoin::{absolute, script::PushBytes, OutPoint, ScriptBuf, Sequence, Transaction};
 
 use super::coin_selection::{CoinSelectionAlgorithm, DefaultCoinSelectionAlgorithm};
 use crate::{database::BatchDatabase, Error, Utxo, Wallet};
@@ -79,7 +79,7 @@ impl TxBuilderContext for BumpFee {}
 /// # use bitcoin::*;
 /// # use core::str::FromStr;
 /// # let wallet = doctest_wallet!();
-/// # let addr1 = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+/// # let addr1 = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
 /// # let addr2 = addr1.clone();
 /// // chaining
 /// let (psbt1, details) = {
@@ -126,9 +126,9 @@ pub struct TxBuilder<'a, D, Cs, Ctx> {
 //TODO: TxParams should eventually be exposed publicly.
 #[derive(Default, Debug, Clone)]
 pub(crate) struct TxParams {
-    pub(crate) recipients: Vec<(Script, u64)>,
+    pub(crate) recipients: Vec<(ScriptBuf, u64)>,
     pub(crate) drain_wallet: bool,
-    pub(crate) drain_to: Option<Script>,
+    pub(crate) drain_to: Option<ScriptBuf>,
     pub(crate) fee_policy: Option<FeePolicy>,
     pub(crate) internal_policy_path: Option<BTreeMap<String, Vec<usize>>>,
     pub(crate) external_policy_path: Option<BTreeMap<String, Vec<usize>>>,
@@ -137,7 +137,7 @@ pub(crate) struct TxParams {
     pub(crate) manually_selected_only: bool,
     pub(crate) sighash: Option<psbt::PsbtSighashType>,
     pub(crate) ordering: TxOrdering,
-    pub(crate) locktime: Option<LockTime>,
+    pub(crate) locktime: Option<absolute::LockTime>,
     pub(crate) rbf: Option<RbfValue>,
     pub(crate) version: Option<Version>,
     pub(crate) change_policy: ChangeSpendPolicy,
@@ -145,7 +145,7 @@ pub(crate) struct TxParams {
     pub(crate) add_global_xpubs: bool,
     pub(crate) include_output_redeem_witness_script: bool,
     pub(crate) bumping_fee: Option<PreviousFee>,
-    pub(crate) current_height: Option<LockTime>,
+    pub(crate) current_height: Option<absolute::LockTime>,
     pub(crate) allow_dust: bool,
 }
 
@@ -241,7 +241,10 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
     /// # use std::collections::BTreeMap;
     /// # use bitcoin::*;
     /// # use bdk::*;
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address =
+    /// Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
+    ///     .unwrap()
+    ///     .assume_checked();
     /// # let wallet = doctest_wallet!();
     /// let mut path = BTreeMap::new();
     /// path.insert("aabbccdd".to_string(), vec![0, 1]);
@@ -281,6 +284,7 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
 
         for utxo in utxos {
             let descriptor = self.wallet.get_descriptor_for_keychain(utxo.keychain);
+            #[allow(deprecated)]
             let satisfaction_weight = descriptor.max_satisfaction_weight().unwrap();
             self.params.utxos.push(WeightedUtxo {
                 satisfaction_weight,
@@ -424,7 +428,7 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
     /// Use a specific nLockTime while creating the transaction
     ///
     /// This can cause conflicts if the wallet's descriptors contain an "after" (OP_CLTV) operator.
-    pub fn nlocktime(&mut self, locktime: LockTime) -> &mut Self {
+    pub fn nlocktime(&mut self, locktime: absolute::LockTime) -> &mut Self {
         self.params.locktime = Some(locktime);
         self
     }
@@ -463,7 +467,7 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
         self
     }
 
-    /// Only Fill-in the [`psbt::Input::witness_utxo`](bitcoin::util::psbt::Input::witness_utxo) field when spending from
+    /// Only Fill-in the [`psbt::Input::witness_utxo`](bitcoin::psbt::Input::witness_utxo) field when spending from
     /// SegWit descriptors.
     ///
     /// This reduces the size of the PSBT, but some signers might reject them due to the lack of
@@ -473,8 +477,8 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
         self
     }
 
-    /// Fill-in the [`psbt::Output::redeem_script`](bitcoin::util::psbt::Output::redeem_script) and
-    /// [`psbt::Output::witness_script`](bitcoin::util::psbt::Output::witness_script) fields.
+    /// Fill-in the [`psbt::Output::redeem_script`](bitcoin::psbt::Output::redeem_script) and
+    /// [`psbt::Output::witness_script`](bitcoin::psbt::Output::witness_script) fields.
     ///
     /// This is useful for signers which always require it, like ColdCard hardware wallets.
     pub fn include_output_redeem_witness_script(&mut self) -> &mut Self {
@@ -556,7 +560,8 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
     ///
     /// In both cases, if you don't provide a current height, we use the last sync height.
     pub fn current_height(&mut self, height: u32) -> &mut Self {
-        self.params.current_height = Some(LockTime::from_height(height).expect("Invalid height"));
+        self.params.current_height =
+            Some(absolute::LockTime::from_height(height).expect("Invalid height"));
         self
     }
 
@@ -571,20 +576,20 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>, Ctx: TxBuilderContext>
 
 impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>> TxBuilder<'a, D, Cs, CreateTx> {
     /// Replace the recipients already added with a new list
-    pub fn set_recipients(&mut self, recipients: Vec<(Script, u64)>) -> &mut Self {
+    pub fn set_recipients(&mut self, recipients: Vec<(ScriptBuf, u64)>) -> &mut Self {
         self.params.recipients = recipients;
         self
     }
 
     /// Add a recipient to the internal list
-    pub fn add_recipient(&mut self, script_pubkey: Script, amount: u64) -> &mut Self {
+    pub fn add_recipient(&mut self, script_pubkey: ScriptBuf, amount: u64) -> &mut Self {
         self.params.recipients.push((script_pubkey, amount));
         self
     }
 
     /// Add data as an output, using OP_RETURN
-    pub fn add_data(&mut self, data: &[u8]) -> &mut Self {
-        let script = Script::new_op_return(data);
+    pub fn add_data<T: AsRef<PushBytes>>(&mut self, data: &T) -> &mut Self {
+        let script = ScriptBuf::new_op_return(data);
         self.add_recipient(script, 0u64);
         self
     }
@@ -614,7 +619,10 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>> TxBuilder<'a, D, Cs, C
     /// # use bitcoin::*;
     /// # use bdk::*;
     /// # use bdk::wallet::tx_builder::CreateTx;
-    /// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap();
+    /// # let to_address =
+    /// Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
+    ///     .unwrap()
+    ///     .assume_checked();
     /// # let wallet = doctest_wallet!();
     /// let mut tx_builder = wallet.build_tx();
     ///
@@ -623,7 +631,7 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>> TxBuilder<'a, D, Cs, C
     ///     .drain_wallet()
     ///     // Send the excess (which is all the coins minus the fee) to this address.
     ///     .drain_to(to_address.script_pubkey())
-    ///     .fee_rate(FeeRate::from_sat_per_vb(5.0))
+    ///     .fee_rate(bdk::FeeRate::from_sat_per_vb(5.0))
     ///     .enable_rbf();
     /// let (psbt, tx_details) = tx_builder.finish()?;
     /// # Ok::<(), bdk::Error>(())
@@ -633,7 +641,7 @@ impl<'a, D: BatchDatabase, Cs: CoinSelectionAlgorithm<D>> TxBuilder<'a, D, Cs, C
     /// [`add_recipient`]: Self::add_recipient
     /// [`add_utxos`]: Self::add_utxos
     /// [`drain_wallet`]: Self::drain_wallet
-    pub fn drain_to(&mut self, script_pubkey: Script) -> &mut Self {
+    pub fn drain_to(&mut self, script_pubkey: ScriptBuf) -> &mut Self {
         self.params.drain_to = Some(script_pubkey);
         self
     }
@@ -651,7 +659,7 @@ impl<'a, D: BatchDatabase> TxBuilder<'a, D, DefaultCoinSelectionAlgorithm, BumpF
     ///
     /// Returns an `Err` if `script_pubkey` can't be found among the recipients of the
     /// transaction we are bumping.
-    pub fn allow_shrinking(&mut self, script_pubkey: Script) -> Result<&mut Self, Error> {
+    pub fn allow_shrinking(&mut self, script_pubkey: ScriptBuf) -> Result<&mut Self, Error> {
         match self
             .params
             .recipients
@@ -790,6 +798,7 @@ mod test {
 
     use bitcoin::consensus::deserialize;
     use bitcoin::hashes::hex::FromHex;
+    use std::str::FromStr;
 
     use super::*;
 
@@ -821,8 +830,6 @@ mod test {
 
     #[test]
     fn test_output_ordering_bip69() {
-        use std::str::FromStr;
-
         let original_tx = ordering_test_tx!();
         let mut tx = original_tx;
 
@@ -851,8 +858,11 @@ mod test {
         );
 
         assert_eq!(tx.output[0].value, 800);
-        assert_eq!(tx.output[1].script_pubkey, From::from(vec![0xAA]));
-        assert_eq!(tx.output[2].script_pubkey, From::from(vec![0xAA, 0xEE]));
+        assert_eq!(tx.output[1].script_pubkey, ScriptBuf::from(vec![0xAA]));
+        assert_eq!(
+            tx.output[2].script_pubkey,
+            ScriptBuf::from(vec![0xAA, 0xEE])
+        );
     }
 
     fn get_test_utxos() -> Vec<LocalUtxo> {
@@ -861,7 +871,7 @@ mod test {
         vec![
             LocalUtxo {
                 outpoint: OutPoint {
-                    txid: bitcoin::Txid::from_inner([0; 32]),
+                    txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(),
                     vout: 0,
                 },
                 txout: Default::default(),
@@ -870,7 +880,7 @@ mod test {
             },
             LocalUtxo {
                 outpoint: OutPoint {
-                    txid: bitcoin::Txid::from_inner([0; 32]),
+                    txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(),
                     vout: 1,
                 },
                 txout: Default::default(),
index 163d417eef27fd5afe282376fd8c36e636150c0e..e1ed79d52a839a082f873a3cfbd998e2bbaf4002 100644 (file)
@@ -10,7 +10,7 @@
 // licenses.
 
 use bitcoin::secp256k1::{All, Secp256k1};
-use bitcoin::{LockTime, Script, Sequence};
+use bitcoin::{absolute, Script, Sequence};
 
 use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
 
@@ -65,7 +65,7 @@ pub(crate) fn check_nsequence_rbf(rbf: Sequence, csv: Sequence) -> bool {
 }
 
 impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for After {
-    fn check_after(&self, n: LockTime) -> bool {
+    fn check_after(&self, n: absolute::LockTime) -> bool {
         if let Some(current_height) = self.current_height {
             current_height >= n.to_consensus_u32()
         } else {
@@ -114,17 +114,20 @@ pub(crate) type SecpCtx = Secp256k1<All>;
 
 #[cfg(test)]
 mod test {
+    use std::str::FromStr;
+
     // When nSequence is lower than this flag the timelock is interpreted as block-height-based,
     // otherwise it's time-based
     pub(crate) const SEQUENCE_LOCKTIME_TYPE_FLAG: u32 = 1 << 22;
 
     use super::{check_nsequence_rbf, IsDust};
-    use crate::bitcoin::{Address, Sequence};
-    use std::str::FromStr;
+    use crate::bitcoin::{Address, Network, Sequence};
 
     #[test]
     fn test_is_dust() {
         let script_p2pkh = Address::from_str("1GNgwA8JfG7Kc8akJ8opdNWJUihqUztfPe")
+            .unwrap()
+            .require_network(Network::Bitcoin)
             .unwrap()
             .script_pubkey();
         assert!(script_p2pkh.is_p2pkh());
@@ -132,6 +135,8 @@ mod test {
         assert!(!546.is_dust(&script_p2pkh));
 
         let script_p2wpkh = Address::from_str("bc1qxlh2mnc0yqwas76gqq665qkggee5m98t8yskd8")
+            .unwrap()
+            .require_network(Network::Bitcoin)
             .unwrap()
             .script_pubkey();
         assert!(script_p2wpkh.is_v0_p2wpkh());