Make bdk no_std

This commit is contained in:
LLFourn 2023-01-10 15:10:02 +11:00 committed by Daniela Brozzoni
parent aab2b12f7a
commit a40da9ba6c
No known key found for this signature in database
GPG Key ID: 7DE4F1FDCED0AB87
20 changed files with 138 additions and 102 deletions

View File

@ -35,6 +35,8 @@ getrandom = "0.2"
js-sys = "0.3" js-sys = "0.3"
[features] [features]
default = ["std"]
std = []
compiler = ["miniscript/compiler"] compiler = ["miniscript/compiler"]
all-keys = ["keys-bip39"] all-keys = ["keys-bip39"]
keys-bip39 = ["bip39"] keys-bip39 = ["bip39"]
@ -66,6 +68,7 @@ required-features = ["compiler"]
[[example]] [[example]]
name = "policy" name = "policy"
path = "examples/policy.rs" path = "examples/policy.rs"
required-features = ["std"]
[[example]] [[example]]
name = "mnemonic_to_descriptors" name = "mnemonic_to_descriptors"

View File

@ -5,15 +5,15 @@ use bitcoin::{Address, PackedLockTime, Script, Sequence, Transaction, Txid, Witn
pub use bitcoincore_rpc::bitcoincore_rpc_json::AddressType; pub use bitcoincore_rpc::bitcoincore_rpc_json::AddressType;
use bitcoincore_rpc::jsonrpc::serde_json::{self, json}; use bitcoincore_rpc::jsonrpc::serde_json::{self, json};
pub use bitcoincore_rpc::{Auth, Client as RpcClient, Error as RpcError, RpcApi}; pub use bitcoincore_rpc::{Auth, Client as RpcClient, Error as RpcError, RpcApi};
use core::ops::Deref;
use core::str::FromStr; use core::str::FromStr;
use core::time::Duration;
use electrsd::bitcoind::BitcoinD; use electrsd::bitcoind::BitcoinD;
use electrsd::{bitcoind, ElectrsD}; use electrsd::{bitcoind, ElectrsD};
pub use electrum_client::{Client as ElectrumClient, ElectrumApi}; pub use electrum_client::{Client as ElectrumClient, ElectrumApi};
#[allow(unused_imports)] #[allow(unused_imports)]
use log::{debug, error, info, log_enabled, trace, Level}; use log::{debug, error, info, log_enabled, trace, Level};
use std::env; use std::env;
use std::ops::Deref;
use std::time::Duration;
pub struct TestClient { pub struct TestClient {
pub bitcoind: BitcoinD, pub bitcoind: BitcoinD,

View File

@ -15,6 +15,7 @@
//! checksum of a descriptor //! checksum of a descriptor
use crate::descriptor::DescriptorError; use crate::descriptor::DescriptorError;
use alloc::string::String;
const INPUT_CHARSET: &[u8] = b"0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ "; const INPUT_CHARSET: &[u8] = b"0123456789()[],'/*abcdefgh@:$%{}IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
const CHECKSUM_CHARSET: &[u8] = b"qpzry9x8gf2tvdw0s3jn54khce6mua7l"; const CHECKSUM_CHARSET: &[u8] = b"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
@ -170,7 +171,7 @@ mod test {
#[test] #[test]
fn test_calc_checksum_invalid_character() { fn test_calc_checksum_invalid_character() {
let sparkle_heart = unsafe { std::str::from_utf8_unchecked(&[240, 159, 146, 150]) }; let sparkle_heart = unsafe { core::str::from_utf8_unchecked(&[240, 159, 146, 150]) };
let invalid_desc = format!("wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcL{}fjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)", sparkle_heart); let invalid_desc = format!("wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcL{}fjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)", sparkle_heart);
assert_matches!( assert_matches!(

View File

@ -23,7 +23,7 @@ macro_rules! impl_top_level_sh {
}; };
( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, sortedmulti $( $inner:tt )* ) => {{ ( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, sortedmulti $( $inner:tt )* ) => {{
use std::marker::PhantomData; use core::marker::PhantomData;
use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey}; use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey};
use $crate::miniscript::$ctx; use $crate::miniscript::$ctx;
@ -35,7 +35,7 @@ macro_rules! impl_top_level_sh {
$crate::impl_sortedmulti!(build_desc, sortedmulti $( $inner )*) $crate::impl_sortedmulti!(build_desc, sortedmulti $( $inner )*)
}}; }};
( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, sortedmulti_vec $( $inner:tt )* ) => {{ ( $inner_struct:ident, $constructor:ident, $sortedmulti_constructor:ident, $ctx:ident, sortedmulti_vec $( $inner:tt )* ) => {{
use std::marker::PhantomData; use core::marker::PhantomData;
use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey}; use $crate::miniscript::descriptor::{$inner_struct, Descriptor, DescriptorPublicKey};
use $crate::miniscript::$ctx; use $crate::miniscript::$ctx;
@ -203,8 +203,8 @@ macro_rules! impl_node_opcode_two {
a_keymap.extend(b_keymap.into_iter()); a_keymap.extend(b_keymap.into_iter());
let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant( let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
std::sync::Arc::new(a_minisc), alloc::sync::Arc::new(a_minisc),
std::sync::Arc::new(b_minisc), alloc::sync::Arc::new(b_minisc),
))?; ))?;
minisc.check_miniscript()?; minisc.check_miniscript()?;
@ -234,9 +234,9 @@ macro_rules! impl_node_opcode_three {
let networks = $crate::keys::merge_networks(&networks, &c_networks); let networks = $crate::keys::merge_networks(&networks, &c_networks);
let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant( let minisc = $crate::miniscript::Miniscript::from_ast($crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
std::sync::Arc::new(a_minisc), alloc::sync::Arc::new(a_minisc),
std::sync::Arc::new(b_minisc), alloc::sync::Arc::new(b_minisc),
std::sync::Arc::new(c_minisc), alloc::sync::Arc::new(c_minisc),
))?; ))?;
minisc.check_miniscript()?; minisc.check_miniscript()?;
@ -263,7 +263,7 @@ macro_rules! impl_sortedmulti {
)* )*
]; ];
keys.into_iter().collect::<Result<Vec<_>, _>>() keys.into_iter().collect::<Result<alloc::vec::Vec<_>, _>>()
.map_err($crate::descriptor::DescriptorError::Key) .map_err($crate::descriptor::DescriptorError::Key)
.and_then(|keys| $crate::keys::make_sortedmulti($thresh, keys, $build_desc, &secp)) .and_then(|keys| $crate::keys::make_sortedmulti($thresh, keys, $build_desc, &secp))
}); });
@ -274,7 +274,7 @@ macro_rules! impl_sortedmulti {
#[macro_export] #[macro_export]
macro_rules! parse_tap_tree { macro_rules! parse_tap_tree {
( @merge $tree_a:expr, $tree_b:expr) => {{ ( @merge $tree_a:expr, $tree_b:expr) => {{
use std::sync::Arc; use alloc::sync::Arc;
use $crate::miniscript::descriptor::TapTree; use $crate::miniscript::descriptor::TapTree;
$tree_a $tree_a
@ -318,7 +318,7 @@ macro_rules! parse_tap_tree {
// Single leaf // Single leaf
( $op:ident ( $( $minisc:tt )* ) ) => {{ ( $op:ident ( $( $minisc:tt )* ) ) => {{
use std::sync::Arc; use alloc::sync::Arc;
use $crate::miniscript::descriptor::TapTree; use $crate::miniscript::descriptor::TapTree;
$crate::fragment!( $op ( $( $minisc )* ) ) $crate::fragment!( $op ( $( $minisc )* ) )
@ -337,7 +337,7 @@ macro_rules! apply_modifier {
.and_then(|(minisc, keymap, networks)| { .and_then(|(minisc, keymap, networks)| {
let minisc = $crate::miniscript::Miniscript::from_ast( let minisc = $crate::miniscript::Miniscript::from_ast(
$crate::miniscript::miniscript::decode::Terminal::$terminal_variant( $crate::miniscript::miniscript::decode::Terminal::$terminal_variant(
std::sync::Arc::new(minisc), alloc::sync::Arc::new(minisc),
), ),
)?; )?;
@ -374,8 +374,8 @@ macro_rules! apply_modifier {
$inner.and_then(|(a_minisc, a_keymap, a_networks)| { $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
$crate::impl_leaf_opcode_value_two!( $crate::impl_leaf_opcode_value_two!(
AndV, AndV,
std::sync::Arc::new(a_minisc), alloc::sync::Arc::new(a_minisc),
std::sync::Arc::new($crate::fragment!(true).unwrap().0) alloc::sync::Arc::new($crate::fragment!(true).unwrap().0)
) )
.map(|(minisc, _, _)| (minisc, a_keymap, a_networks)) .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
}) })
@ -384,8 +384,8 @@ macro_rules! apply_modifier {
$inner.and_then(|(a_minisc, a_keymap, a_networks)| { $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
$crate::impl_leaf_opcode_value_two!( $crate::impl_leaf_opcode_value_two!(
OrI, OrI,
std::sync::Arc::new($crate::fragment!(false).unwrap().0), alloc::sync::Arc::new($crate::fragment!(false).unwrap().0),
std::sync::Arc::new(a_minisc) alloc::sync::Arc::new(a_minisc)
) )
.map(|(minisc, _, _)| (minisc, a_keymap, a_networks)) .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
}) })
@ -394,8 +394,8 @@ macro_rules! apply_modifier {
$inner.and_then(|(a_minisc, a_keymap, a_networks)| { $inner.and_then(|(a_minisc, a_keymap, a_networks)| {
$crate::impl_leaf_opcode_value_two!( $crate::impl_leaf_opcode_value_two!(
OrI, OrI,
std::sync::Arc::new(a_minisc), alloc::sync::Arc::new(a_minisc),
std::sync::Arc::new($crate::fragment!(false).unwrap().0) alloc::sync::Arc::new($crate::fragment!(false).unwrap().0)
) )
.map(|(minisc, _, _)| (minisc, a_keymap, a_networks)) .map(|(minisc, _, _)| (minisc, a_keymap, a_networks))
}) })
@ -599,7 +599,7 @@ macro_rules! group_multi_keys {
)* )*
]; ];
keys.into_iter().collect::<Result<Vec<_>, _>>() keys.into_iter().collect::<Result<alloc::vec::Vec<_>, _>>()
.map_err($crate::descriptor::DescriptorError::Key) .map_err($crate::descriptor::DescriptorError::Key)
}}; }};
} }
@ -744,8 +744,8 @@ macro_rules! fragment {
( thresh_vec ( $thresh:expr, $items:expr ) ) => ({ ( thresh_vec ( $thresh:expr, $items:expr ) ) => ({
use $crate::miniscript::descriptor::KeyMap; use $crate::miniscript::descriptor::KeyMap;
let (items, key_maps_networks): (Vec<_>, Vec<_>) = $items.into_iter().map(|(a, b, c)| (a, (b, c))).unzip(); let (items, key_maps_networks): (alloc::vec::Vec<_>, alloc::vec::Vec<_>) = $items.into_iter().map(|(a, b, c)| (a, (b, c))).unzip();
let items = items.into_iter().map(std::sync::Arc::new).collect(); let items = items.into_iter().map(alloc::sync::Arc::new).collect();
let (key_maps, valid_networks) = key_maps_networks.into_iter().fold((KeyMap::default(), $crate::keys::any_network()), |(mut keys_acc, net_acc), (key, net)| { let (key_maps, valid_networks) = key_maps_networks.into_iter().fold((KeyMap::default(), $crate::keys::any_network()), |(mut keys_acc, net_acc), (key, net)| {
keys_acc.extend(key.into_iter()); keys_acc.extend(key.into_iter());
@ -760,7 +760,7 @@ macro_rules! fragment {
( thresh ( $thresh:expr, $( $inner:tt )* ) ) => ({ ( thresh ( $thresh:expr, $( $inner:tt )* ) ) => ({
let items = $crate::fragment_internal!( @v $( $inner )* ); let items = $crate::fragment_internal!( @v $( $inner )* );
items.into_iter().collect::<Result<Vec<_>, _>>() items.into_iter().collect::<Result<alloc::vec::Vec<_>, _>>()
.and_then(|items| $crate::fragment!(thresh_vec($thresh, items))) .and_then(|items| $crate::fragment!(thresh_vec($thresh, items)))
}); });
( multi_vec ( $thresh:expr, $keys:expr ) ) => ({ ( multi_vec ( $thresh:expr, $keys:expr ) ) => ({
@ -793,12 +793,13 @@ macro_rules! fragment {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use alloc::string::ToString;
use bitcoin::hashes::hex::ToHex; use bitcoin::hashes::hex::ToHex;
use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::Secp256k1;
use miniscript::descriptor::{DescriptorPublicKey, KeyMap}; use miniscript::descriptor::{DescriptorPublicKey, KeyMap};
use miniscript::{Descriptor, Legacy, Segwitv0}; use miniscript::{Descriptor, Legacy, Segwitv0};
use std::str::FromStr; use core::str::FromStr;
use crate::descriptor::{DescriptorError, DescriptorMeta}; use crate::descriptor::{DescriptorError, DescriptorMeta};
use crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks}; use crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks};

View File

@ -76,6 +76,7 @@ impl std::fmt::Display for Error {
} }
} }
#[cfg(feature = "std")]
impl std::error::Error for Error {} impl std::error::Error for Error {}
impl_error!(bitcoin::util::bip32::Error, Bip32); impl_error!(bitcoin::util::bip32::Error, Bip32);

View File

@ -14,7 +14,9 @@
//! This module contains generic utilities to work with descriptors, plus some re-exported types //! This module contains generic utilities to work with descriptors, plus some re-exported types
//! from [`miniscript`]. //! from [`miniscript`].
use std::collections::BTreeMap; use crate::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint, KeySource}; use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint, KeySource};
use bitcoin::util::{psbt, taproot}; use bitcoin::util::{psbt, taproot};
@ -581,7 +583,8 @@ impl DescriptorMeta for ExtendedDescriptor {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::str::FromStr; use alloc::string::ToString;
use core::str::FromStr;
use assert_matches::assert_matches; use assert_matches::assert_matches;
use bitcoin::consensus::encode::deserialize; use bitcoin::consensus::encode::deserialize;

View File

@ -36,9 +36,11 @@
//! # Ok::<(), bdk::Error>(()) //! # Ok::<(), bdk::Error>(())
//! ``` //! ```
use std::cmp::max; use crate::collections::{BTreeMap, HashSet, VecDeque};
use std::collections::{BTreeMap, HashSet, VecDeque}; use alloc::string::String;
use std::fmt; use alloc::vec::Vec;
use core::cmp::max;
use core::fmt;
use serde::ser::SerializeMap; use serde::ser::SerializeMap;
use serde::{Serialize, Serializer}; use serde::{Serialize, Serializer};
@ -523,6 +525,7 @@ impl fmt::Display for PolicyError {
} }
} }
#[cfg(feature = "std")]
impl std::error::Error for PolicyError {} impl std::error::Error for PolicyError {}
impl Policy { impl Policy {
@ -1146,12 +1149,12 @@ mod test {
use crate::descriptor::policy::SatisfiableItem::{EcdsaSignature, Multisig, Thresh}; use crate::descriptor::policy::SatisfiableItem::{EcdsaSignature, Multisig, Thresh};
use crate::keys::{DescriptorKey, IntoDescriptorKey}; use crate::keys::{DescriptorKey, IntoDescriptorKey};
use crate::wallet::signer::SignersContainer; use crate::wallet::signer::SignersContainer;
use alloc::{string::ToString, sync::Arc};
use assert_matches::assert_matches; use assert_matches::assert_matches;
use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::Secp256k1;
use bitcoin::util::bip32; use bitcoin::util::bip32;
use bitcoin::Network; use bitcoin::Network;
use std::str::FromStr; use core::str::FromStr;
use std::sync::Arc;
const TPRV0_STR:&str = "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf"; const TPRV0_STR:&str = "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf";
const TPRV1_STR:&str = "tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N"; const TPRV1_STR:&str = "tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N";
@ -1444,11 +1447,11 @@ mod test {
.into_wallet_descriptor(&secp, Network::Testnet) .into_wallet_descriptor(&secp, Network::Testnet)
.unwrap(); .unwrap();
let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp)); let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
let policy = wallet_desc let _policy = wallet_desc
.extract_policy(&signers_container, BuildSatisfaction::None, &secp) .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
.unwrap() .unwrap()
.unwrap(); .unwrap();
println!("desc policy = {:?}", policy); // TODO remove // println!("desc policy = {:?}", policy); // TODO remove
// TODO how should this fail with mixed timelocks? // TODO how should this fail with mixed timelocks?
} }
@ -1469,11 +1472,11 @@ mod test {
.into_wallet_descriptor(&secp, Network::Testnet) .into_wallet_descriptor(&secp, Network::Testnet)
.unwrap(); .unwrap();
let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp)); let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
let policy = wallet_desc let _policy = wallet_desc
.extract_policy(&signers_container, BuildSatisfaction::None, &secp) .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
.unwrap() .unwrap()
.unwrap(); .unwrap();
println!("desc policy = {:?}", policy); // TODO remove // println!("desc policy = {:?}", policy); // TODO remove
// TODO how should this merge timelocks? // TODO how should this merge timelocks?
let (prvkey1, _pubkey1, _fingerprint1) = setup_keys(TPRV0_STR, PATH, &secp); let (prvkey1, _pubkey1, _fingerprint1) = setup_keys(TPRV0_STR, PATH, &secp);
let locktime_seconds0 = 500000100; let locktime_seconds0 = 500000100;
@ -1487,12 +1490,12 @@ mod test {
.into_wallet_descriptor(&secp, Network::Testnet) .into_wallet_descriptor(&secp, Network::Testnet)
.unwrap(); .unwrap();
let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp)); let signers_container = Arc::new(SignersContainer::build(keymap, &wallet_desc, &secp));
let policy = wallet_desc let _policy = wallet_desc
.extract_policy(&signers_container, BuildSatisfaction::None, &secp) .extract_policy(&signers_container, BuildSatisfaction::None, &secp)
.unwrap() .unwrap()
.unwrap(); .unwrap();
println!("desc policy = {:?}", policy); // TODO remove // println!("desc policy = {:?}", policy); // TODO remove
// TODO how should this merge timelocks? // TODO how should this merge timelocks?
} }

View File

@ -418,7 +418,7 @@ macro_rules! expand_make_bipxx {
keychain: KeychainKind, keychain: KeychainKind,
network: Network, network: Network,
) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> { ) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> {
let mut derivation_path = Vec::with_capacity(4); let mut derivation_path = alloc::vec::Vec::with_capacity(4);
derivation_path.push(bip32::ChildNumber::from_hardened_idx(bip)?); derivation_path.push(bip32::ChildNumber::from_hardened_idx(bip)?);
match network { match network {
@ -478,7 +478,8 @@ expand_make_bipxx!(segwit_v0, Segwitv0);
mod test { mod test {
// test existing descriptor templates, make sure they are expanded to the right descriptors // test existing descriptor templates, make sure they are expanded to the right descriptors
use std::str::FromStr; use alloc::{string::ToString, vec::Vec};
use core::str::FromStr;
use super::*; use super::*;
use crate::descriptor::{DescriptorError, DescriptorMeta}; use crate::descriptor::{DescriptorError, DescriptorMeta};

View File

@ -9,11 +9,11 @@
// You may not use this file except in accordance with one or both of these // You may not use this file except in accordance with one or both of these
// licenses. // licenses.
use std::fmt;
use crate::bitcoin::Network; use crate::bitcoin::Network;
use crate::{descriptor, wallet}; use crate::{descriptor, wallet};
use alloc::{string::String, vec::Vec};
use bitcoin::{OutPoint, Txid}; use bitcoin::{OutPoint, Txid};
use core::fmt;
/// Errors that can be thrown by the [`Wallet`](crate::wallet::Wallet) /// Errors that can be thrown by the [`Wallet`](crate::wallet::Wallet)
#[derive(Debug)] #[derive(Debug)]
@ -249,6 +249,7 @@ impl fmt::Display for Error {
} }
} }
#[cfg(feature = "std")]
impl std::error::Error for Error {} impl std::error::Error for Error {}
macro_rules! impl_error { macro_rules! impl_error {
@ -256,7 +257,7 @@ macro_rules! impl_error {
impl_error!($from, $to, Error); impl_error!($from, $to, Error);
}; };
( $from:ty, $to:ident, $impl_for:ty ) => { ( $from:ty, $to:ident, $impl_for:ty ) => {
impl std::convert::From<$from> for $impl_for { impl core::convert::From<$from> for $impl_for {
fn from(err: $from) -> Self { fn from(err: $from) -> Self {
<$impl_for>::$to(err) <$impl_for>::$to(err)
} }

View File

@ -14,6 +14,7 @@
// TODO: maybe write our own implementation of bip39? Seems stupid to have an extra dependency for // 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. // something that should be fairly simple to re-implement.
use alloc::string::String;
use bitcoin::util::bip32; use bitcoin::util::bip32;
use bitcoin::Network; use bitcoin::Network;
@ -150,7 +151,8 @@ impl<Ctx: ScriptContext> GeneratableKey<Ctx> for Mnemonic {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::str::FromStr; use alloc::string::ToString;
use core::str::FromStr;
use bitcoin::util::bip32; use bitcoin::util::bip32;

View File

@ -11,11 +11,13 @@
//! Key formats //! Key formats
use std::any::TypeId; use crate::collections::HashSet;
use std::collections::HashSet; use alloc::string::{String, ToString};
use std::marker::PhantomData; use alloc::vec::Vec;
use std::ops::Deref; use core::any::TypeId;
use std::str::FromStr; use core::marker::PhantomData;
use core::ops::Deref;
use core::str::FromStr;
use bitcoin::secp256k1::{self, Secp256k1, Signing}; use bitcoin::secp256k1::{self, Secp256k1, Signing};
@ -277,7 +279,7 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// ///
/// ```compile_fail /// ```compile_fail
/// use bdk::bitcoin::PublicKey; /// use bdk::bitcoin::PublicKey;
/// use std::str::FromStr; /// use core::str::FromStr;
/// ///
/// use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError}; /// use bdk::keys::{DescriptorKey, IntoDescriptorKey, KeyError};
/// ///
@ -619,7 +621,7 @@ pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
/// Extra options required by the `generate_with_entropy` /// Extra options required by the `generate_with_entropy`
type Options; type Options;
/// Returned error in case of failure /// Returned error in case of failure
type Error: std::fmt::Debug; type Error: core::fmt::Debug;
/// Generate a key given the extra options and the entropy /// Generate a key given the extra options and the entropy
fn generate_with_entropy( fn generate_with_entropy(
@ -946,6 +948,7 @@ impl std::fmt::Display for KeyError {
} }
} }
#[cfg(feature = "std")]
impl std::error::Error for KeyError {} impl std::error::Error for KeyError {}
#[cfg(test)] #[cfg(test)]

View File

@ -8,7 +8,7 @@
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
// You may not use this file except in accordance with one or both of these // You may not use this file except in accordance with one or both of these
// licenses. // licenses.
//
// rustdoc will warn if there are missing docs // rustdoc will warn if there are missing docs
#![warn(missing_docs)] #![warn(missing_docs)]
// only enables the `doc_cfg` feature when // only enables the `doc_cfg` feature when
@ -147,7 +147,7 @@ fn main() -> Result<(), bdk::Error> {
//! ## Sign a transaction //! ## Sign a transaction
//! //!
//! ```no_run //! ```no_run
//! use std::str::FromStr; //! use core::str::FromStr;
//! //!
//! use bitcoin::util::psbt::PartiallySignedTransaction as Psbt; //! use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
//! //!
@ -188,6 +188,14 @@ fn main() -> Result<(), bdk::Error> {
//! * `keys-bip39`: [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) mnemonic codes for generating deterministic keys //! * `keys-bip39`: [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) mnemonic codes for generating deterministic keys
//! //!
#![no_std]
#[cfg(feature = "std")]
#[macro_use]
extern crate std;
#[macro_use]
extern crate alloc;
pub extern crate bitcoin; pub extern crate bitcoin;
#[cfg(feature = "hardware-signer")] #[cfg(feature = "hardware-signer")]
pub extern crate hwi; pub extern crate hwi;
@ -225,3 +233,4 @@ pub fn version() -> &'static str {
} }
pub use bdk_chain as chain; pub use bdk_chain as chain;
pub(crate) use bdk_chain::collections;

View File

@ -12,6 +12,7 @@
//! Additional functions on the `rust-bitcoin` `PartiallySignedTransaction` structure. //! Additional functions on the `rust-bitcoin` `PartiallySignedTransaction` structure.
use crate::FeeRate; use crate::FeeRate;
use alloc::vec::Vec;
use bitcoin::util::psbt::PartiallySignedTransaction as Psbt; use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
use bitcoin::TxOut; use bitcoin::TxOut;
@ -85,7 +86,7 @@ mod test {
use crate::wallet::AddressIndex; use crate::wallet::AddressIndex;
use crate::wallet::AddressIndex::New; use crate::wallet::AddressIndex::New;
use crate::{psbt, FeeRate, SignOptions}; use crate::{psbt, FeeRate, SignOptions};
use std::str::FromStr; use core::str::FromStr;
// from bip 174 // from bip 174
const PSBT_STR: &str = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA"; const PSBT_STR: &str = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA";

View File

@ -9,8 +9,9 @@
// You may not use this file except in accordance with one or both of these // You may not use this file except in accordance with one or both of these
// licenses. // licenses.
use std::convert::AsRef; use alloc::boxed::Box;
use std::ops::Sub; use core::convert::AsRef;
use core::ops::Sub;
use bdk_chain::ConfirmationTime; use bdk_chain::ConfirmationTime;
use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut}; use bitcoin::blockdata::transaction::{OutPoint, Transaction, TxOut};
@ -124,7 +125,7 @@ impl FeeRate {
} }
} }
impl std::default::Default for FeeRate { impl Default for FeeRate {
fn default() -> Self { fn default() -> Self {
FeeRate::default_min_relay_fee() FeeRate::default_min_relay_fee()
} }
@ -249,13 +250,13 @@ pub struct TransactionDetails {
} }
impl PartialOrd for TransactionDetails { impl PartialOrd for TransactionDetails {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other)) Some(self.cmp(other))
} }
} }
impl Ord for TransactionDetails { impl Ord for TransactionDetails {
fn cmp(&self, other: &Self) -> std::cmp::Ordering { fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.confirmation_time self.confirmation_time
.cmp(&other.confirmation_time) .cmp(&other.confirmation_time)
.then_with(|| self.txid.cmp(&other.txid)) .then_with(|| self.txid.cmp(&other.txid))
@ -287,8 +288,8 @@ impl Balance {
} }
} }
impl std::fmt::Display for Balance { impl core::fmt::Display for Balance {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!( write!(
f, f,
"{{ immature: {}, trusted_pending: {}, untrusted_pending: {}, confirmed: {} }}", "{{ immature: {}, trusted_pending: {}, untrusted_pending: {}, confirmed: {} }}",
@ -297,7 +298,7 @@ impl std::fmt::Display for Balance {
} }
} }
impl std::ops::Add for Balance { impl core::ops::Add for Balance {
type Output = Self; type Output = Self;
fn add(self, other: Self) -> Self { fn add(self, other: Self) -> Self {
@ -310,7 +311,7 @@ impl std::ops::Add for Balance {
} }
} }
impl std::iter::Sum for Balance { impl core::iter::Sum for Balance {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self { fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold( iter.fold(
Balance { Balance {

View File

@ -99,16 +99,16 @@ use crate::wallet::utils::IsDust;
use crate::WeightedUtxo; use crate::WeightedUtxo;
use crate::{error::Error, Utxo}; use crate::{error::Error, Utxo};
use alloc::vec::Vec;
use bitcoin::consensus::encode::serialize; use bitcoin::consensus::encode::serialize;
use bitcoin::Script; use bitcoin::Script;
#[cfg(test)] #[cfg(test)]
use assert_matches::assert_matches; use assert_matches::assert_matches;
use core::convert::TryInto;
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
#[cfg(not(test))] #[cfg(not(test))]
use rand::thread_rng; use rand::thread_rng;
#[cfg(test)]
use std::convert::TryInto;
/// Default coin selection algorithm used by [`TxBuilder`](super::tx_builder::TxBuilder) if not /// Default coin selection algorithm used by [`TxBuilder`](super::tx_builder::TxBuilder) if not
/// overridden /// overridden
@ -177,7 +177,7 @@ impl CoinSelectionResult {
/// selection algorithm when it creates transactions. /// selection algorithm when it creates transactions.
/// ///
/// For an example see [this module](crate::wallet::coin_selection)'s documentation. /// For an example see [this module](crate::wallet::coin_selection)'s documentation.
pub trait CoinSelectionAlgorithm: std::fmt::Debug { pub trait CoinSelectionAlgorithm: core::fmt::Debug {
/// Perform the coin selection /// Perform the coin selection
/// ///
/// - `database`: a reference to the wallet's database that can be used to lookup additional /// - `database`: a reference to the wallet's database that can be used to lookup additional
@ -695,7 +695,7 @@ impl BranchAndBoundCoinSelection {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::str::FromStr; use core::str::FromStr;
use bdk_chain::ConfirmationTime; use bdk_chain::ConfirmationTime;
use bitcoin::{OutPoint, Script, TxOut}; use bitcoin::{OutPoint, Script, TxOut};

View File

@ -59,8 +59,9 @@
//! # Ok::<_, bdk::Error>(()) //! # Ok::<_, bdk::Error>(())
//! ``` //! ```
use std::str::FromStr; use core::str::FromStr;
use alloc::string::{String, ToString};
use bdk_chain::sparse_chain::ChainPosition; use bdk_chain::sparse_chain::ChainPosition;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -217,7 +218,7 @@ impl FullyNodedExport {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::str::FromStr; use core::str::FromStr;
use bdk_chain::{BlockId, ConfirmationTime}; use bdk_chain::{BlockId, ConfirmationTime};
use bitcoin::hashes::Hash; use bitcoin::hashes::Hash;

View File

@ -12,14 +12,18 @@
//! Wallet //! Wallet
//! //!
//! This module defines the [`Wallet`] structure. //! This module defines the [`Wallet`] structure.
use bdk_chain::chain_graph; use crate::collections::{BTreeMap, HashMap, HashSet};
use bdk_chain::{keychain::KeychainTracker, sparse_chain, BlockId, ConfirmationTime}; use alloc::{
boxed::Box,
string::{String, ToString},
sync::Arc,
vec::Vec,
};
use bdk_chain::{keychain::KeychainTracker, sparse_chain, BlockId, ConfirmationTime, chain_graph};
use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::Secp256k1;
use core::fmt;
use core::ops::Deref;
use core::convert::TryInto; use core::convert::TryInto;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::fmt;
use std::ops::Deref;
use std::sync::Arc;
use bitcoin::consensus::encode::serialize; use bitcoin::consensus::encode::serialize;
use bitcoin::util::psbt; use bitcoin::util::psbt;
@ -551,7 +555,7 @@ impl Wallet {
/// [`TxBuilder`]: crate::TxBuilder /// [`TxBuilder`]: crate::TxBuilder
pub fn build_tx(&mut self) -> TxBuilder<'_, DefaultCoinSelectionAlgorithm, CreateTx> { pub fn build_tx(&mut self) -> TxBuilder<'_, DefaultCoinSelectionAlgorithm, CreateTx> {
TxBuilder { TxBuilder {
wallet: std::rc::Rc::new(core::cell::RefCell::new(self)), wallet: alloc::rc::Rc::new(core::cell::RefCell::new(self)),
params: TxParams::default(), params: TxParams::default(),
coin_selection: DefaultCoinSelectionAlgorithm::default(), coin_selection: DefaultCoinSelectionAlgorithm::default(),
phantom: core::marker::PhantomData, phantom: core::marker::PhantomData,
@ -1067,7 +1071,7 @@ impl Wallet {
}; };
Ok(TxBuilder { Ok(TxBuilder {
wallet: std::rc::Rc::new(std::cell::RefCell::new(self)), wallet: alloc::rc::Rc::new(core::cell::RefCell::new(self)),
params, params,
coin_selection: DefaultCoinSelectionAlgorithm::default(), coin_selection: DefaultCoinSelectionAlgorithm::default(),
phantom: core::marker::PhantomData, phantom: core::marker::PhantomData,
@ -1846,7 +1850,7 @@ pub(crate) mod test {
macro_rules! from_str { macro_rules! from_str {
($e:expr, $t:ty) => {{ ($e:expr, $t:ty) => {{
use std::str::FromStr; use core::str::FromStr;
<$t>::from_str($e).unwrap() <$t>::from_str($e).unwrap()
}}; }};
@ -2344,7 +2348,7 @@ pub(crate) mod test {
#[test] #[test]
fn test_create_tx_input_hd_keypaths() { fn test_create_tx_input_hd_keypaths() {
use bitcoin::util::bip32::{DerivationPath, Fingerprint}; use bitcoin::util::bip32::{DerivationPath, Fingerprint};
use std::str::FromStr; use core::str::FromStr;
let (mut wallet, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)"); let (mut wallet, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
let addr = wallet.get_address(New); let addr = wallet.get_address(New);
@ -2365,7 +2369,7 @@ pub(crate) mod test {
#[test] #[test]
fn test_create_tx_output_hd_keypaths() { fn test_create_tx_output_hd_keypaths() {
use bitcoin::util::bip32::{DerivationPath, Fingerprint}; use bitcoin::util::bip32::{DerivationPath, Fingerprint};
use std::str::FromStr; use core::str::FromStr;
let (mut wallet, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)"); let (mut wallet, _) = get_funded_wallet("wpkh([d34db33f/44'/0'/0']tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)");
@ -4118,8 +4122,8 @@ pub(crate) mod test {
#[test] #[test]
fn test_get_address_no_reuse_single_descriptor() { fn test_get_address_no_reuse_single_descriptor() {
use crate::collections::HashSet;
use crate::descriptor::template::Bip84; use crate::descriptor::template::Bip84;
use std::collections::HashSet;
let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap(); let key = bitcoin::util::bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let mut wallet = let mut wallet =

View File

@ -15,8 +15,8 @@
//! through the [`Wallet::add_signer`](super::Wallet::add_signer) function. //! through the [`Wallet::add_signer`](super::Wallet::add_signer) function.
//! //!
//! ``` //! ```
//! # use std::sync::Arc; //! # use alloc::sync::Arc;
//! # use std::str::FromStr; //! # use core::str::FromStr;
//! # use bitcoin::secp256k1::{Secp256k1, All}; //! # use bitcoin::secp256k1::{Secp256k1, All};
//! # use bitcoin::*; //! # use bitcoin::*;
//! # use bitcoin::util::psbt; //! # use bitcoin::util::psbt;
@ -80,11 +80,12 @@
//! # Ok::<_, bdk::Error>(()) //! # Ok::<_, bdk::Error>(())
//! ``` //! ```
use std::cmp::Ordering; use crate::collections::BTreeMap;
use std::collections::BTreeMap; use alloc::sync::Arc;
use std::fmt; use alloc::vec::Vec;
use std::ops::{Bound::Included, Deref}; use core::cmp::Ordering;
use std::sync::Arc; use core::fmt;
use core::ops::{Bound::Included, Deref};
use bitcoin::blockdata::opcodes; use bitcoin::blockdata::opcodes;
use bitcoin::blockdata::script::Builder as ScriptBuilder; use bitcoin::blockdata::script::Builder as ScriptBuilder;
@ -199,6 +200,7 @@ impl fmt::Display for SignerError {
} }
} }
#[cfg(feature = "std")]
impl std::error::Error for SignerError {} impl std::error::Error for SignerError {}
/// Signing context /// Signing context
@ -560,7 +562,7 @@ fn sign_psbt_schnorr(
#[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq)] #[derive(Debug, Clone, PartialOrd, PartialEq, Ord, Eq)]
pub struct SignerOrdering(pub usize); pub struct SignerOrdering(pub usize);
impl std::default::Default for SignerOrdering { impl Default for SignerOrdering {
fn default() -> Self { fn default() -> Self {
SignerOrdering(100) SignerOrdering(100)
} }
@ -1017,8 +1019,8 @@ mod signers_container_tests {
use bitcoin::secp256k1::{All, Secp256k1}; use bitcoin::secp256k1::{All, Secp256k1};
use bitcoin::util::bip32; use bitcoin::util::bip32;
use bitcoin::Network; use bitcoin::Network;
use core::str::FromStr;
use miniscript::ScriptContext; use miniscript::ScriptContext;
use std::str::FromStr;
fn is_equal(this: &Arc<dyn TransactionSigner>, that: &Arc<DummySigner>) -> bool { fn is_equal(this: &Arc<dyn TransactionSigner>, that: &Arc<DummySigner>) -> bool {
let secp = Secp256k1::new(); let secp = Secp256k1::new();

View File

@ -36,12 +36,11 @@
//! # Ok::<(), bdk::Error>(()) //! # Ok::<(), bdk::Error>(())
//! ``` //! ```
use std::cell::RefCell; use crate::collections::BTreeMap;
use std::collections::BTreeMap; use crate::collections::HashSet;
use std::collections::HashSet; use alloc::{boxed::Box, rc::Rc, string::String, vec::Vec};
use std::default::Default; use core::cell::RefCell;
use std::marker::PhantomData; use core::marker::PhantomData;
use std::rc::Rc;
use bitcoin::util::psbt::{self, PartiallySignedTransaction as Psbt}; use bitcoin::util::psbt::{self, PartiallySignedTransaction as Psbt};
use bitcoin::{LockTime, OutPoint, Script, Sequence, Transaction}; use bitcoin::{LockTime, OutPoint, Script, Sequence, Transaction};
@ -53,7 +52,7 @@ use crate::{
}; };
use crate::{Error, Utxo, Wallet}; use crate::{Error, Utxo, Wallet};
/// Context in which the [`TxBuilder`] is valid /// Context in which the [`TxBuilder`] is valid
pub trait TxBuilderContext: std::fmt::Debug + Default + Clone {} pub trait TxBuilderContext: core::fmt::Debug + Default + Clone {}
/// Marker type to indicate the [`TxBuilder`] is being used to create a new transaction (as opposed /// Marker type to indicate the [`TxBuilder`] is being used to create a new transaction (as opposed
/// to bumping the fee of an existing one). /// to bumping the fee of an existing one).
@ -163,7 +162,7 @@ pub(crate) enum FeePolicy {
FeeAmount(u64), FeeAmount(u64),
} }
impl std::default::Default for FeePolicy { impl Default for FeePolicy {
fn default() -> Self { fn default() -> Self {
FeePolicy::FeeRate(FeeRate::default_min_relay_fee()) FeePolicy::FeeRate(FeeRate::default_min_relay_fee())
} }
@ -827,7 +826,7 @@ mod test {
#[test] #[test]
fn test_output_ordering_bip69() { fn test_output_ordering_bip69() {
use std::str::FromStr; use core::str::FromStr;
let original_tx = ordering_test_tx!(); let original_tx = ordering_test_tx!();
let mut tx = original_tx; let mut tx = original_tx;

View File

@ -120,7 +120,7 @@ mod test {
use super::{check_nsequence_rbf, IsDust}; use super::{check_nsequence_rbf, IsDust};
use crate::bitcoin::{Address, Sequence}; use crate::bitcoin::{Address, Sequence};
use std::str::FromStr; use core::str::FromStr;
#[test] #[test]
fn test_is_dust() { fn test_is_dust() {