Merge branch 'master' into release/0.4.0

Merging in fixes for the CI after Rust 1.50.0
This commit is contained in:
Alekos Filini 2021-02-13 11:08:03 -05:00
commit d0ffcdd009
No known key found for this signature in database
GPG Key ID: 431401E4A4530061
9 changed files with 205 additions and 177 deletions

View File

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Keys
#### Changed
- Renamed `DerivableKey::add_metadata()` to `DerivableKey::into_descriptor_key()`
- Renamed `ToDescriptorKey::to_descriptor_key()` to `IntoDescriptorKey::into_descriptor_key()`
#### Added
- Added an `ExtendedKey` type that is an enum of `bip32::ExtendedPubKey` and `bip32::ExtendedPrivKey`
- Added `DerivableKey::into_extended_key()` as the only method that needs to be implemented
@ -29,6 +30,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Wallet
#### Changed
- Removed the explicit `id` argument from `Wallet::add_signer()` since that's now part of `Signer` itself
- Renamed `ToWalletDescriptor::to_wallet_descriptor()` to `IntoWalletDescriptor::into_wallet_descriptor()`
### Policy
#### Changed
- Removed unneeded `Result<(), PolicyError>` return type for `Satisfaction::finalize()`
## [v0.3.0] - [v0.2.0]

View File

@ -223,14 +223,14 @@ impl Peer {
)),
)?;
let version = if let NetworkMessage::Version(version) =
Self::_recv(&responses, "version", None)?.unwrap()
Self::_recv(&responses, "version", None).unwrap()
{
version
} else {
return Err(CompactFiltersError::InvalidResponse);
};
if let NetworkMessage::Verack = Self::_recv(&responses, "verack", None)?.unwrap() {
if let NetworkMessage::Verack = Self::_recv(&responses, "verack", None).unwrap() {
Self::_send(&mut locked_writer, network.magic(), NetworkMessage::Verack)?;
} else {
return Err(CompactFiltersError::InvalidResponse);
@ -271,7 +271,7 @@ impl Peer {
responses: &Arc<RwLock<ResponsesMap>>,
wait_for: &'static str,
timeout: Option<Duration>,
) -> Result<Option<NetworkMessage>, CompactFiltersError> {
) -> Option<NetworkMessage> {
let message_resp = {
let mut lock = responses.write().unwrap();
let message_resp = lock.entry(wait_for).or_default();
@ -287,15 +287,14 @@ impl Peer {
Some(t) => {
let result = cvar.wait_timeout(messages, t).unwrap();
if result.1.timed_out() {
return Ok(None);
return None;
}
messages = result.0;
}
}
}
Ok(messages.pop())
messages.pop()
}
/// Return the [`VersionMessage`] sent by the peer
@ -415,7 +414,7 @@ impl Peer {
wait_for: &'static str,
timeout: Option<Duration>,
) -> Result<Option<NetworkMessage>, CompactFiltersError> {
Self::_recv(&self.responses, wait_for, timeout)
Ok(Self::_recv(&self.responses, wait_for, timeout))
}
}

View File

@ -76,10 +76,10 @@ macro_rules! impl_top_level_pk {
use $crate::miniscript::descriptor::$inner_type;
#[allow(unused_imports)]
use $crate::keys::{DescriptorKey, ToDescriptorKey};
use $crate::keys::{DescriptorKey, IntoDescriptorKey};
let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
$key.to_descriptor_key()
$key.into_descriptor_key()
.and_then(|key: DescriptorKey<$ctx>| key.extract(&secp))
.map_err($crate::descriptor::DescriptorError::Key)
.map(|(pk, key_map, valid_networks)| ($inner_type::new(pk), key_map, valid_networks))
@ -225,12 +225,12 @@ macro_rules! impl_sortedmulti {
$crate::keys::make_sortedmulti($thresh, $keys, $build_desc, &secp)
});
( $build_desc:expr, sortedmulti ( $thresh:expr $(, $key:expr )+ ) ) => ({
use $crate::keys::ToDescriptorKey;
use $crate::keys::IntoDescriptorKey;
let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
let mut keys = vec![];
$(
keys.push($key.to_descriptor_key());
keys.push($key.into_descriptor_key());
)*
keys.into_iter().collect::<Result<Vec<_>, _>>()
@ -326,11 +326,11 @@ macro_rules! apply_modifier {
/// broken up to `s:d:v:older(144)`.
///
/// The `pk()`, `pk_k()` and `pk_h()` operands can take as argument any type that implements
/// [`ToDescriptorKey`]. This means that keys can also be written inline as strings, but in that
/// [`IntoDescriptorKey`]. This means that keys can also be written inline as strings, but in that
/// case they must be wrapped in quotes, which is another difference compared to the standard
/// descriptor syntax.
///
/// [`ToDescriptorKey`]: crate::keys::ToDescriptorKey
/// [`IntoDescriptorKey`]: crate::keys::IntoDescriptorKey
///
/// ## Example
///
@ -653,12 +653,12 @@ macro_rules! fragment {
$crate::keys::make_multi($thresh, $keys)
});
( multi ( $thresh:expr $(, $key:expr )+ ) ) => ({
use $crate::keys::ToDescriptorKey;
use $crate::keys::IntoDescriptorKey;
let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
let mut keys = vec![];
$(
keys.push($key.to_descriptor_key());
keys.push($key.into_descriptor_key());
)*
keys.into_iter().collect::<Result<Vec<_>, _>>()
@ -685,7 +685,7 @@ mod test {
use std::str::FromStr;
use crate::descriptor::{DescriptorError, DescriptorMeta};
use crate::keys::{DescriptorKey, ToDescriptorKey, ValidNetworks};
use crate::keys::{DescriptorKey, IntoDescriptorKey, ValidNetworks};
use bitcoin::network::constants::Network::{Bitcoin, Regtest, Signet, Testnet};
use bitcoin::util::bip32;
use bitcoin::PrivateKey;
@ -724,7 +724,7 @@ mod test {
}
// - at least one of each "type" of operator; ie. one modifier, one leaf_opcode, one leaf_opcode_value, etc.
// - mixing up key types that implement ToDescriptorKey in multi() or thresh()
// - mixing up key types that implement IntoDescriptorKey in multi() or thresh()
// expected script for pk and bare manually created
// expected addresses created with `bitcoin-cli getdescriptorinfo` (for hash) and `bitcoin-cli deriveaddresses`
@ -808,7 +808,7 @@ mod test {
let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap();
let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
check(
descriptor!(pk(desc_key)),
false,
@ -820,7 +820,7 @@ mod test {
],
);
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap();
let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
check(
descriptor!(pkh(desc_key)),
false,
@ -833,8 +833,8 @@ mod test {
);
let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
let desc_key1 = (xprv, path).to_descriptor_key().unwrap();
let desc_key2 = (xprv, path2).to_descriptor_key().unwrap();
let desc_key1 = (xprv, path).into_descriptor_key().unwrap();
let desc_key2 = (xprv, path2).into_descriptor_key().unwrap();
check(
descriptor!(sh(multi(1, desc_key1, desc_key2))),
@ -853,7 +853,7 @@ mod test {
let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap();
let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
check(
descriptor!(wpkh(desc_key)),
true,
@ -865,7 +865,7 @@ mod test {
],
);
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap();
let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
check(
descriptor!(sh(wpkh(desc_key))),
true,
@ -878,8 +878,8 @@ mod test {
);
let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
let desc_key1 = (xprv, path.clone()).to_descriptor_key().unwrap();
let desc_key2 = (xprv, path2.clone()).to_descriptor_key().unwrap();
let desc_key1 = (xprv, path.clone()).into_descriptor_key().unwrap();
let desc_key2 = (xprv, path2.clone()).into_descriptor_key().unwrap();
check(
descriptor!(wsh(multi(1, desc_key1, desc_key2))),
true,
@ -891,8 +891,8 @@ mod test {
],
);
let desc_key1 = (xprv, path).to_descriptor_key().unwrap();
let desc_key2 = (xprv, path2).to_descriptor_key().unwrap();
let desc_key1 = (xprv, path).into_descriptor_key().unwrap();
let desc_key2 = (xprv, path2).into_descriptor_key().unwrap();
check(
descriptor!(sh(wsh(multi(1, desc_key1, desc_key2)))),
true,
@ -968,7 +968,7 @@ mod test {
fn test_valid_networks() {
let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap();
let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
let (_desc, _key_map, valid_networks) = descriptor!(pkh(desc_key)).unwrap();
assert_eq!(
@ -978,7 +978,7 @@ mod test {
let xprv = bip32::ExtendedPrivKey::from_str("xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi").unwrap();
let path = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap();
let desc_key = (xprv, path.clone()).to_descriptor_key().unwrap();
let desc_key = (xprv, path.clone()).into_descriptor_key().unwrap();
let (_desc, _key_map, valid_networks) = descriptor!(wpkh(desc_key)).unwrap();
assert_eq!(valid_networks, [Bitcoin].iter().cloned().collect());
@ -991,26 +991,26 @@ mod test {
let xprv1 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path1 = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key1 = (xprv1, path1.clone()).to_descriptor_key().unwrap();
let desc_key1 = (xprv1, path1.clone()).into_descriptor_key().unwrap();
let xprv2 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPegBHHnq7YEgM815dG24M2Jk5RVqipgDxF1HJ1tsnT815X5Fd5FRfMVUs8NZs9XCb6y9an8hRPThnhfwfXJ36intaekySHGF").unwrap();
let path2 = bip32::DerivationPath::from_str("m/2147483647'/0").unwrap();
let desc_key2 = (xprv2, path2.clone()).to_descriptor_key().unwrap();
let desc_key2 = (xprv2, path2.clone()).into_descriptor_key().unwrap();
let xprv3 = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf").unwrap();
let path3 = bip32::DerivationPath::from_str("m/10/20/30/40").unwrap();
let desc_key3 = (xprv3, path3.clone()).to_descriptor_key().unwrap();
let desc_key3 = (xprv3, path3.clone()).into_descriptor_key().unwrap();
let (_desc, key_map, _valid_networks) =
descriptor!(sh(wsh(multi(2, desc_key1, desc_key2, desc_key3)))).unwrap();
assert_eq!(key_map.len(), 3);
let desc_key1: DescriptorKey<Segwitv0> =
(xprv1, path1.clone()).to_descriptor_key().unwrap();
(xprv1, path1.clone()).into_descriptor_key().unwrap();
let desc_key2: DescriptorKey<Segwitv0> =
(xprv2, path2.clone()).to_descriptor_key().unwrap();
(xprv2, path2.clone()).into_descriptor_key().unwrap();
let desc_key3: DescriptorKey<Segwitv0> =
(xprv3, path3.clone()).to_descriptor_key().unwrap();
(xprv3, path3.clone()).into_descriptor_key().unwrap();
let (key1, _key_map, _valid_networks) = desc_key1.extract(&secp).unwrap();
let (key2, _key_map, _valid_networks) = desc_key2.extract(&secp).unwrap();
@ -1020,19 +1020,19 @@ mod test {
assert_eq!(key_map.get(&key3).unwrap().to_string(), "tprv8ZgxMBicQKsPdZXrcHNLf5JAJWFAoJ2TrstMRdSKtEggz6PddbuSkvHKM9oKJyFgZV1B7rw8oChspxyYbtmEXYyg1AjfWbL3ho3XHDpHRZf/10/20/30/40/*");
}
// - verify the ScriptContext is correctly validated (i.e. passing a type that only impl ToDescriptorKey<Segwitv0> to a pkh() descriptor should throw a compilation error
// - verify the ScriptContext is correctly validated (i.e. passing a type that only impl IntoDescriptorKey<Segwitv0> to a pkh() descriptor should throw a compilation error
#[test]
fn test_script_context_validation() {
// this compiles
let xprv = bip32::ExtendedPrivKey::from_str("tprv8ZgxMBicQKsPcx5nBGsR63Pe8KnRUqmbJNENAfGftF3yuXoMMoVJJcYeUw5eVkm9WBPjWYt6HMWYJNesB5HaNVBaFc1M6dRjWSYnmewUMYy").unwrap();
let path = bip32::DerivationPath::from_str("m/0").unwrap();
let desc_key: DescriptorKey<Legacy> = (xprv, path.clone()).to_descriptor_key().unwrap();
let desc_key: DescriptorKey<Legacy> = (xprv, path.clone()).into_descriptor_key().unwrap();
let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap();
assert_eq!(desc.to_string(), "pkh(tpubD6NzVbkrYhZ4WR7a4vY1VT3khMJMeAxVsfq9TBJyJWrNk247zCJtV7AWf6UJP7rAVsn8NNKdJi3gFyKPTmWZS9iukb91xbn2HbFSMQm2igY/0/*)#yrnz9pp2");
// as expected this does not compile due to invalid context
//let desc_key:DescriptorKey<Segwitv0> = (xprv, path.clone()).to_descriptor_key().unwrap();
//let desc_key:DescriptorKey<Segwitv0> = (xprv, path.clone()).into_descriptor_key().unwrap();
//let (desc, _key_map, _valid_networks) = descriptor!(pkh(desc_key)).unwrap();
}

View File

@ -54,7 +54,7 @@ pub use self::derived::DerivedDescriptorKey;
pub use self::error::Error as DescriptorError;
pub use self::policy::Policy;
use self::template::DescriptorTemplateOut;
use crate::keys::{KeyError, ToDescriptorKey};
use crate::keys::{IntoDescriptorKey, KeyError};
use crate::wallet::signer::SignersContainer;
use crate::wallet::utils::SecpCtx;
@ -72,17 +72,17 @@ pub type DerivedDescriptor<'s> = Descriptor<DerivedDescriptorKey<'s>>;
pub type HDKeyPaths = BTreeMap<PublicKey, KeySource>;
/// Trait for types which can be converted into an [`ExtendedDescriptor`] and a [`KeyMap`] usable by a wallet in a specific [`Network`]
pub trait ToWalletDescriptor {
pub trait IntoWalletDescriptor {
/// Convert to wallet descriptor
fn to_wallet_descriptor(
fn into_wallet_descriptor(
self,
secp: &SecpCtx,
network: Network,
) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError>;
}
impl ToWalletDescriptor for &str {
fn to_wallet_descriptor(
impl IntoWalletDescriptor for &str {
fn into_wallet_descriptor(
self,
secp: &SecpCtx,
network: Network,
@ -102,32 +102,33 @@ impl ToWalletDescriptor for &str {
self
};
ExtendedDescriptor::parse_descriptor(secp, descriptor)?.to_wallet_descriptor(secp, network)
ExtendedDescriptor::parse_descriptor(secp, descriptor)?
.into_wallet_descriptor(secp, network)
}
}
impl ToWalletDescriptor for &String {
fn to_wallet_descriptor(
impl IntoWalletDescriptor for &String {
fn into_wallet_descriptor(
self,
secp: &SecpCtx,
network: Network,
) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
self.as_str().to_wallet_descriptor(secp, network)
self.as_str().into_wallet_descriptor(secp, network)
}
}
impl ToWalletDescriptor for ExtendedDescriptor {
fn to_wallet_descriptor(
impl IntoWalletDescriptor for ExtendedDescriptor {
fn into_wallet_descriptor(
self,
secp: &SecpCtx,
network: Network,
) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
(self, KeyMap::default()).to_wallet_descriptor(secp, network)
(self, KeyMap::default()).into_wallet_descriptor(secp, network)
}
}
impl ToWalletDescriptor for (ExtendedDescriptor, KeyMap) {
fn to_wallet_descriptor(
impl IntoWalletDescriptor for (ExtendedDescriptor, KeyMap) {
fn into_wallet_descriptor(
self,
secp: &SecpCtx,
network: Network,
@ -137,11 +138,11 @@ impl ToWalletDescriptor for (ExtendedDescriptor, KeyMap) {
let check_key = |pk: &DescriptorPublicKey| {
let (pk, _, networks) = if self.0.is_witness() {
let desciptor_key: DescriptorKey<miniscript::Segwitv0> =
pk.clone().to_descriptor_key()?;
pk.clone().into_descriptor_key()?;
desciptor_key.extract(&secp)?
} else {
let desciptor_key: DescriptorKey<miniscript::Legacy> =
pk.clone().to_descriptor_key()?;
pk.clone().into_descriptor_key()?;
desciptor_key.extract(&secp)?
};
@ -159,8 +160,8 @@ impl ToWalletDescriptor for (ExtendedDescriptor, KeyMap) {
}
}
impl ToWalletDescriptor for DescriptorTemplateOut {
fn to_wallet_descriptor(
impl IntoWalletDescriptor for DescriptorTemplateOut {
fn into_wallet_descriptor(
self,
_secp: &SecpCtx,
network: Network,
@ -613,7 +614,7 @@ mod test {
#[test]
fn test_to_wallet_descriptor_fixup_networks() {
use crate::keys::{any_network, ToDescriptorKey};
use crate::keys::{any_network, IntoDescriptorKey};
let secp = Secp256k1::new();
@ -622,116 +623,120 @@ mod test {
// here `to_descriptor_key` will set the valid networks for the key to only mainnet, since
// we are using an "xpub"
let key = (xpub, path).to_descriptor_key().unwrap();
let key = (xpub, path).into_descriptor_key().unwrap();
// override it with any. this happens in some key conversions, like bip39
let key = key.override_valid_networks(any_network());
// make a descriptor out of it
let desc = crate::descriptor!(wpkh(key)).unwrap();
// this should conver the key that supports "any_network" to the right network (testnet)
let (wallet_desc, _) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, _) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
assert_eq!(wallet_desc.to_string(), "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)#y8p7e8kk");
}
// test ToWalletDescriptor trait from &str with and without checksum appended
// test IntoWalletDescriptor trait from &str with and without checksum appended
#[test]
fn test_descriptor_from_str_with_checksum() {
let secp = Secp256k1::new();
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#tqz0nc62"
.to_wallet_descriptor(&secp, Network::Testnet);
.into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok());
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
.to_wallet_descriptor(&secp, Network::Testnet);
.into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok());
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw"
.to_wallet_descriptor(&secp, Network::Testnet);
.into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok());
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
.to_wallet_descriptor(&secp, Network::Testnet);
.into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok());
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw"
.to_wallet_descriptor(&secp, Network::Testnet);
.into_wallet_descriptor(&secp, Network::Testnet);
assert!(matches!(
desc.err(),
Some(DescriptorError::InvalidDescriptorChecksum)
));
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)#67ju93jw"
.to_wallet_descriptor(&secp, Network::Testnet);
.into_wallet_descriptor(&secp, Network::Testnet);
assert!(matches!(
desc.err(),
Some(DescriptorError::InvalidDescriptorChecksum)
));
}
// test ToWalletDescriptor trait from &str with keys from right and wrong network
// test IntoWalletDescriptor trait from &str with keys from right and wrong network
#[test]
fn test_descriptor_from_str_with_keys_network() {
let secp = Secp256k1::new();
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
.to_wallet_descriptor(&secp, Network::Testnet);
.into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok());
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
.to_wallet_descriptor(&secp, Network::Regtest);
.into_wallet_descriptor(&secp, Network::Regtest);
assert!(desc.is_ok());
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
.to_wallet_descriptor(&secp, Network::Testnet);
.into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok());
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
.to_wallet_descriptor(&secp, Network::Regtest);
.into_wallet_descriptor(&secp, Network::Regtest);
assert!(desc.is_ok());
let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))"
.to_wallet_descriptor(&secp, Network::Testnet);
.into_wallet_descriptor(&secp, Network::Testnet);
assert!(desc.is_ok());
let desc = "sh(wpkh(02864bb4ad00cefa806098a69e192bbda937494e69eb452b87bb3f20f6283baedb))"
.to_wallet_descriptor(&secp, Network::Bitcoin);
.into_wallet_descriptor(&secp, Network::Bitcoin);
assert!(desc.is_ok());
let desc = "wpkh(tprv8ZgxMBicQKsPdpkqS7Eair4YxjcuuvDPNYmKX3sCniCf16tHEVrjjiSXEkFRnUH77yXc6ZcwHHcLNfjdi5qUvw3VDfgYiH5mNsj5izuiu2N/1/2/*)"
.to_wallet_descriptor(&secp, Network::Bitcoin);
.into_wallet_descriptor(&secp, Network::Bitcoin);
assert!(matches!(
desc.err(),
Some(DescriptorError::Key(KeyError::InvalidNetwork))
));
let desc = "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)"
.to_wallet_descriptor(&secp, Network::Bitcoin);
.into_wallet_descriptor(&secp, Network::Bitcoin);
assert!(matches!(
desc.err(),
Some(DescriptorError::Key(KeyError::InvalidNetwork))
));
}
// test ToWalletDescriptor trait from the output of the descriptor!() macro
// test IntoWalletDescriptor trait from the output of the descriptor!() macro
#[test]
fn test_descriptor_from_str_from_output_of_macro() {
let secp = Secp256k1::new();
let tpub = bip32::ExtendedPubKey::from_str("tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK").unwrap();
let path = bip32::DerivationPath::from_str("m/1/2").unwrap();
let key = (tpub, path).to_descriptor_key().unwrap();
let key = (tpub, path).into_descriptor_key().unwrap();
// make a descriptor out of it
let desc = crate::descriptor!(wpkh(key)).unwrap();
let (wallet_desc, _) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, _) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let wallet_desc_str = wallet_desc.to_string();
assert_eq!(wallet_desc_str, "wpkh(tpubD6NzVbkrYhZ4XHndKkuB8FifXm8r5FQHwrN6oZuWCz13qb93rtgKvD4PQsqC4HP4yhV3tA2fqr2RbY5mNXfM7RxXUoeABoDtsFUq2zJq6YK/1/2/*)#67ju93jw");
let (wallet_desc2, _) = wallet_desc_str
.to_wallet_descriptor(&secp, Network::Testnet)
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
assert_eq!(wallet_desc, wallet_desc2)
}

View File

@ -354,7 +354,7 @@ impl Satisfaction {
}
}
fn finalize(&mut self) -> Result<(), PolicyError> {
fn finalize(&mut self) {
// if partial try to bump it to a partialcomplete
if let Satisfaction::Partial {
n,
@ -420,8 +420,6 @@ impl Satisfaction {
};
}
}
Ok(())
}
}
@ -575,7 +573,7 @@ impl Policy {
for (index, item) in items.iter().enumerate() {
contribution.add(&item.contribution, index)?;
}
contribution.finalize()?;
contribution.finalize();
let mut policy: Policy = SatisfiableItem::Thresh { items, threshold }.into();
policy.contribution = contribution;
@ -613,7 +611,7 @@ impl Policy {
)?;
}
}
contribution.finalize()?;
contribution.finalize();
let mut policy: Policy = SatisfiableItem::Multisig {
keys: parsed_keys,
@ -890,11 +888,11 @@ impl ExtractPolicy for Descriptor<DescriptorPublicKey> {
#[cfg(test)]
mod test {
use crate::descriptor;
use crate::descriptor::{ExtractPolicy, ToWalletDescriptor};
use crate::descriptor::{ExtractPolicy, IntoWalletDescriptor};
use super::*;
use crate::descriptor::policy::SatisfiableItem::{Multisig, Signature, Thresh};
use crate::keys::{DescriptorKey, ToDescriptorKey};
use crate::keys::{DescriptorKey, IntoDescriptorKey};
use crate::wallet::signer::SignersContainer;
use bitcoin::secp256k1::{All, Secp256k1};
use bitcoin::util::bip32;
@ -915,8 +913,8 @@ mod test {
let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap();
let tpub = bip32::ExtendedPubKey::from_private(&secp, &tprv);
let fingerprint = tprv.fingerprint(&secp);
let prvkey = (tprv, path.clone()).to_descriptor_key().unwrap();
let pubkey = (tpub, path).to_descriptor_key().unwrap();
let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
let pubkey = (tpub, path).into_descriptor_key().unwrap();
(prvkey, pubkey, fingerprint)
}
@ -929,7 +927,9 @@ mod test {
let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR);
let desc = descriptor!(wpkh(pubkey)).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new())
@ -942,7 +942,9 @@ mod test {
assert!(matches!(&policy.contribution, Satisfaction::None));
let desc = descriptor!(wpkh(prvkey)).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new())
@ -1025,7 +1027,9 @@ mod test {
let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR);
let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR);
let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new())
@ -1055,7 +1059,9 @@ mod test {
let (prvkey0, _pubkey0, fingerprint0) = setup_keys(TPRV0_STR);
let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR);
let desc = descriptor!(sh(multi(2, prvkey0, prvkey1))).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new())
@ -1085,7 +1091,9 @@ mod test {
let (prvkey, pubkey, fingerprint) = setup_keys(TPRV0_STR);
let desc = descriptor!(wpkh(pubkey)).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let single_key = wallet_desc.derive(0);
let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = single_key
@ -1099,7 +1107,9 @@ mod test {
assert!(matches!(&policy.contribution, Satisfaction::None));
let desc = descriptor!(wpkh(prvkey)).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let single_key = wallet_desc.derive(0);
let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = single_key
@ -1124,7 +1134,9 @@ mod test {
let (_prvkey0, pubkey0, fingerprint0) = setup_keys(TPRV0_STR);
let (prvkey1, _pubkey1, fingerprint1) = setup_keys(TPRV1_STR);
let desc = descriptor!(sh(multi(1, pubkey0, prvkey1))).unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let single_key = wallet_desc.derive(0);
let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = single_key
@ -1166,7 +1178,9 @@ mod test {
)))
.unwrap();
let (wallet_desc, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (wallet_desc, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers_container = Arc::new(SignersContainer::from(keymap));
let policy = wallet_desc
.extract_policy(&signers_container, &Secp256k1::new())

View File

@ -32,9 +32,9 @@ use bitcoin::Network;
use miniscript::{Legacy, Segwitv0};
use super::{ExtendedDescriptor, KeyMap, ToWalletDescriptor};
use super::{ExtendedDescriptor, IntoWalletDescriptor, KeyMap};
use crate::descriptor::DescriptorError;
use crate::keys::{DerivableKey, ToDescriptorKey, ValidNetworks};
use crate::keys::{DerivableKey, IntoDescriptorKey, ValidNetworks};
use crate::wallet::utils::SecpCtx;
use crate::{descriptor, KeychainKind};
@ -43,20 +43,20 @@ pub type DescriptorTemplateOut = (ExtendedDescriptor, KeyMap, ValidNetworks);
/// Trait for descriptor templates that can be built into a full descriptor
///
/// Since [`ToWalletDescriptor`] is implemented for any [`DescriptorTemplate`], they can also be
/// Since [`IntoWalletDescriptor`] is implemented for any [`DescriptorTemplate`], they can also be
/// passed directly to the [`Wallet`](crate::Wallet) constructor.
///
/// ## Example
///
/// ```
/// use bdk::descriptor::error::Error as DescriptorError;
/// use bdk::keys::{KeyError, ToDescriptorKey};
/// use bdk::keys::{KeyError, IntoDescriptorKey};
/// use bdk::miniscript::Legacy;
/// use bdk::template::{DescriptorTemplate, DescriptorTemplateOut};
///
/// struct MyP2PKH<K: ToDescriptorKey<Legacy>>(K);
/// struct MyP2PKH<K: IntoDescriptorKey<Legacy>>(K);
///
/// impl<K: ToDescriptorKey<Legacy>> DescriptorTemplate for MyP2PKH<K> {
/// impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for MyP2PKH<K> {
/// fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> {
/// Ok(bdk::descriptor!(pkh(self.0))?)
/// }
@ -69,13 +69,13 @@ pub trait DescriptorTemplate {
/// Turns a [`DescriptorTemplate`] into a valid wallet descriptor by calling its
/// [`build`](DescriptorTemplate::build) method
impl<T: DescriptorTemplate> ToWalletDescriptor for T {
fn to_wallet_descriptor(
impl<T: DescriptorTemplate> IntoWalletDescriptor for T {
fn into_wallet_descriptor(
self,
secp: &SecpCtx,
network: Network,
) -> Result<(ExtendedDescriptor, KeyMap), DescriptorError> {
Ok(self.build()?.to_wallet_descriptor(secp, network)?)
Ok(self.build()?.into_wallet_descriptor(secp, network)?)
}
}
@ -104,9 +104,9 @@ impl<T: DescriptorTemplate> ToWalletDescriptor for T {
/// );
/// # Ok::<_, Box<dyn std::error::Error>>(())
/// ```
pub struct P2PKH<K: ToDescriptorKey<Legacy>>(pub K);
pub struct P2PKH<K: IntoDescriptorKey<Legacy>>(pub K);
impl<K: ToDescriptorKey<Legacy>> DescriptorTemplate for P2PKH<K> {
impl<K: IntoDescriptorKey<Legacy>> DescriptorTemplate for P2PKH<K> {
fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> {
Ok(descriptor!(pkh(self.0))?)
}
@ -138,9 +138,9 @@ impl<K: ToDescriptorKey<Legacy>> DescriptorTemplate for P2PKH<K> {
/// # Ok::<_, Box<dyn std::error::Error>>(())
/// ```
#[allow(non_camel_case_types)]
pub struct P2WPKH_P2SH<K: ToDescriptorKey<Segwitv0>>(pub K);
pub struct P2WPKH_P2SH<K: IntoDescriptorKey<Segwitv0>>(pub K);
impl<K: ToDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH_P2SH<K> {
impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH_P2SH<K> {
fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> {
Ok(descriptor!(sh(wpkh(self.0)))?)
}
@ -171,9 +171,9 @@ impl<K: ToDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH_P2SH<K> {
/// );
/// # Ok::<_, Box<dyn std::error::Error>>(())
/// ```
pub struct P2WPKH<K: ToDescriptorKey<Segwitv0>>(pub K);
pub struct P2WPKH<K: IntoDescriptorKey<Segwitv0>>(pub K);
impl<K: ToDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH<K> {
impl<K: IntoDescriptorKey<Segwitv0>> DescriptorTemplate for P2WPKH<K> {
fn build(self) -> Result<DescriptorTemplateOut, DescriptorError> {
Ok(descriptor!(wpkh(self.0))?)
}
@ -410,7 +410,7 @@ macro_rules! expand_make_bipxx {
bip: u32,
key: K,
keychain: KeychainKind,
) -> Result<impl ToDescriptorKey<$ctx>, DescriptorError> {
) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> {
let mut derivation_path = Vec::with_capacity(4);
derivation_path.push(bip32::ChildNumber::from_hardened_idx(bip)?);
derivation_path.push(bip32::ChildNumber::from_hardened_idx(0)?);
@ -434,7 +434,7 @@ macro_rules! expand_make_bipxx {
key: K,
parent_fingerprint: bip32::Fingerprint,
keychain: KeychainKind,
) -> Result<impl ToDescriptorKey<$ctx>, DescriptorError> {
) -> Result<impl IntoDescriptorKey<$ctx>, DescriptorError> {
let derivation_path: bip32::DerivationPath = match keychain {
KeychainKind::External => vec![bip32::ChildNumber::from_normal_idx(0)?].into(),
KeychainKind::Internal => vec![bip32::ChildNumber::from_normal_idx(1)?].into(),

View File

@ -205,15 +205,15 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// ```
/// use bdk::bitcoin::PublicKey;
///
/// use bdk::keys::{DescriptorKey, KeyError, ScriptContext, ToDescriptorKey};
/// use bdk::keys::{DescriptorKey, KeyError, ScriptContext, IntoDescriptorKey};
///
/// pub struct MyKeyType {
/// pubkey: PublicKey,
/// }
///
/// impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for MyKeyType {
/// fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
/// self.pubkey.to_descriptor_key()
/// impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
/// fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
/// self.pubkey.into_descriptor_key()
/// }
/// }
/// ```
@ -225,15 +225,15 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
///
/// use bdk::keys::{
/// mainnet_network, DescriptorKey, DescriptorPublicKey, DescriptorSinglePub, KeyError,
/// ScriptContext, ToDescriptorKey,
/// ScriptContext, IntoDescriptorKey,
/// };
///
/// pub struct MyKeyType {
/// pubkey: PublicKey,
/// }
///
/// impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for MyKeyType {
/// fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
/// impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for MyKeyType {
/// fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
/// Ok(DescriptorKey::from_public(
/// DescriptorPublicKey::SinglePub(DescriptorSinglePub {
/// origin: None,
@ -250,17 +250,17 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// ```
/// use bdk::bitcoin::PublicKey;
///
/// use bdk::keys::{DescriptorKey, ExtScriptContext, KeyError, ScriptContext, ToDescriptorKey};
/// use bdk::keys::{DescriptorKey, ExtScriptContext, KeyError, ScriptContext, IntoDescriptorKey};
///
/// pub struct MyKeyType {
/// is_legacy: bool,
/// pubkey: PublicKey,
/// }
///
/// impl<Ctx: ScriptContext + 'static> ToDescriptorKey<Ctx> for MyKeyType {
/// fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
/// impl<Ctx: ScriptContext + 'static> IntoDescriptorKey<Ctx> for MyKeyType {
/// fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
/// if Ctx::is_legacy() == self.is_legacy {
/// self.pubkey.to_descriptor_key()
/// self.pubkey.into_descriptor_key()
/// } else {
/// Err(KeyError::InvalidScriptContext)
/// }
@ -279,15 +279,15 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
/// use bdk::bitcoin::PublicKey;
/// use std::str::FromStr;
///
/// use bdk::keys::{DescriptorKey, KeyError, ToDescriptorKey};
/// use bdk::keys::{DescriptorKey, KeyError, IntoDescriptorKey};
///
/// pub struct MySegwitOnlyKeyType {
/// pubkey: PublicKey,
/// }
///
/// impl ToDescriptorKey<bdk::miniscript::Segwitv0> for MySegwitOnlyKeyType {
/// fn to_descriptor_key(self) -> Result<DescriptorKey<bdk::miniscript::Segwitv0>, KeyError> {
/// self.pubkey.to_descriptor_key()
/// impl IntoDescriptorKey<bdk::miniscript::Segwitv0> for MySegwitOnlyKeyType {
/// fn into_descriptor_key(self) -> Result<DescriptorKey<bdk::miniscript::Segwitv0>, KeyError> {
/// self.pubkey.into_descriptor_key()
/// }
/// }
///
@ -299,9 +299,9 @@ impl<Ctx: ScriptContext + 'static> ExtScriptContext for Ctx {
///
/// # Ok::<_, Box<dyn std::error::Error>>(())
/// ```
pub trait ToDescriptorKey<Ctx: ScriptContext>: Sized {
pub trait IntoDescriptorKey<Ctx: ScriptContext>: Sized {
/// Turn the key into a [`DescriptorKey`] within the requested [`ScriptContext`]
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>;
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError>;
}
/// Enum for extended keys that can be either `xprv` or `xpub`
@ -370,12 +370,12 @@ impl<Ctx: ScriptContext> From<bip32::ExtendedPrivKey> for ExtendedKey<Ctx> {
/// Trait for keys that can be derived.
///
/// When extra metadata are provided, a [`DerivableKey`] can be transofrmed into a
/// [`DescriptorKey`]: the trait [`ToDescriptorKey`] is automatically implemented
/// [`DescriptorKey`]: the trait [`IntoDescriptorKey`] is automatically implemented
/// for `(DerivableKey, DerivationPath)` and
/// `(DerivableKey, KeySource, DerivationPath)` tuples.
///
/// For key types that don't encode any indication about the path to use (like bip39), it's
/// generally recommended to implemented this trait instead of [`ToDescriptorKey`]. The same
/// generally recommended to implemented this trait instead of [`IntoDescriptorKey`]. The same
/// rules regarding script context and valid networks apply.
///
/// ## Examples
@ -499,14 +499,14 @@ let xprv = xkey.into_xprv(Network::Bitcoin).unwrap();
derivation_path,
wildcard: Wildcard::Unhardened,
})
.to_descriptor_key(),
.into_descriptor_key(),
ExtendedKey::Public((xpub, _)) => DescriptorPublicKey::XPub(DescriptorXKey {
origin,
xkey: xpub,
derivation_path,
wildcard: Wildcard::Unhardened,
})
.to_descriptor_key(),
.into_descriptor_key(),
}
}
}
@ -583,25 +583,25 @@ where
// Make generated keys directly usable in descriptors, and make sure they get assigned the right
// `valid_networks`.
impl<Ctx, K> ToDescriptorKey<Ctx> for GeneratedKey<K, Ctx>
impl<Ctx, K> IntoDescriptorKey<Ctx> for GeneratedKey<K, Ctx>
where
Ctx: ScriptContext,
K: ToDescriptorKey<Ctx>,
K: IntoDescriptorKey<Ctx>,
{
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
let desc_key = self.key.to_descriptor_key()?;
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
let desc_key = self.key.into_descriptor_key()?;
Ok(desc_key.override_valid_networks(self.valid_networks))
}
}
/// Trait for keys that can be generated
///
/// The same rules about [`ScriptContext`] and [`ValidNetworks`] from [`ToDescriptorKey`] apply.
/// The same rules about [`ScriptContext`] and [`ValidNetworks`] from [`IntoDescriptorKey`] apply.
///
/// This trait is particularly useful when combined with [`DerivableKey`]: if `Self`
/// implements it, the returned [`GeneratedKey`] will also implement it. The same is true for
/// [`ToDescriptorKey`]: the generated keys can be directly used in descriptors if `Self` is also
/// [`ToDescriptorKey`].
/// [`IntoDescriptorKey`]: the generated keys can be directly used in descriptors if `Self` is also
/// [`IntoDescriptorKey`].
pub trait GeneratableKey<Ctx: ScriptContext>: Sized {
/// Type specifying the amount of entropy required e.g. `[u8;32]`
type Entropy: AsMut<[u8]> + Default;
@ -711,27 +711,29 @@ impl<Ctx: ScriptContext> GeneratableKey<Ctx> for PrivateKey {
}
}
impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> ToDescriptorKey<Ctx> for (T, bip32::DerivationPath) {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx>
for (T, bip32::DerivationPath)
{
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
self.0.into_descriptor_key(None, self.1)
}
}
impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> ToDescriptorKey<Ctx>
impl<Ctx: ScriptContext, T: DerivableKey<Ctx>> IntoDescriptorKey<Ctx>
for (T, bip32::KeySource, bip32::DerivationPath)
{
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
self.0.into_descriptor_key(Some(self.1), self.2)
}
}
fn expand_multi_keys<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>(
fn expand_multi_keys<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
pks: Vec<Pk>,
secp: &SecpCtx,
) -> Result<(Vec<DescriptorPublicKey>, KeyMap, ValidNetworks), KeyError> {
let (pks, key_maps_networks): (Vec<_>, Vec<_>) = pks
.into_iter()
.map(|key| Ok::<_, KeyError>(key.to_descriptor_key()?.extract(secp)?))
.map(|key| Ok::<_, KeyError>(key.into_descriptor_key()?.extract(secp)?))
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.map(|(a, b, c)| (a, (b, c)))
@ -752,11 +754,11 @@ fn expand_multi_keys<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>(
// Used internally by `bdk::fragment!` to build `pk_k()` fragments
#[doc(hidden)]
pub fn make_pk<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>(
pub fn make_pk<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
descriptor_key: Pk,
secp: &SecpCtx,
) -> Result<(Miniscript<DescriptorPublicKey, Ctx>, KeyMap, ValidNetworks), DescriptorError> {
let (key, key_map, valid_networks) = descriptor_key.to_descriptor_key()?.extract(secp)?;
let (key, key_map, valid_networks) = descriptor_key.into_descriptor_key()?.extract(secp)?;
let minisc = Miniscript::from_ast(Terminal::PkK(key))?;
minisc.check_minsicript()?;
@ -766,7 +768,7 @@ pub fn make_pk<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>(
// Used internally by `bdk::fragment!` to build `multi()` fragments
#[doc(hidden)]
pub fn make_multi<Pk: ToDescriptorKey<Ctx>, Ctx: ScriptContext>(
pub fn make_multi<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
thresh: usize,
pks: Vec<Pk>,
secp: &SecpCtx,
@ -788,7 +790,7 @@ pub fn make_sortedmulti<Pk, Ctx, F>(
secp: &SecpCtx,
) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap, ValidNetworks), DescriptorError>
where
Pk: ToDescriptorKey<Ctx>,
Pk: IntoDescriptorKey<Ctx>,
Ctx: ScriptContext,
F: Fn(
usize,
@ -802,14 +804,14 @@ where
}
/// The "identity" conversion is used internally by some `bdk::fragment`s
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorKey<Ctx> {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorKey<Ctx> {
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
Ok(self)
}
}
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorPublicKey {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorPublicKey {
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
let networks = match self {
DescriptorPublicKey::SinglePub(_) => any_network(),
DescriptorPublicKey::XPub(DescriptorXKey { xkey, .. })
@ -824,18 +826,18 @@ impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorPublicKey {
}
}
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for PublicKey {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PublicKey {
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
DescriptorPublicKey::SinglePub(DescriptorSinglePub {
key: self,
origin: None,
})
.to_descriptor_key()
.into_descriptor_key()
}
}
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorSecretKey {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for DescriptorSecretKey {
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
let networks = match &self {
DescriptorSecretKey::SinglePriv(sk) if sk.key.network == Network::Bitcoin => {
mainnet_network()
@ -852,21 +854,21 @@ impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for DescriptorSecretKey {
}
}
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for &'_ str {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for &'_ str {
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
DescriptorSecretKey::from_str(self)
.map_err(|e| KeyError::Message(e.to_string()))?
.to_descriptor_key()
.into_descriptor_key()
}
}
impl<Ctx: ScriptContext> ToDescriptorKey<Ctx> for PrivateKey {
fn to_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
impl<Ctx: ScriptContext> IntoDescriptorKey<Ctx> for PrivateKey {
fn into_descriptor_key(self) -> Result<DescriptorKey<Ctx>, KeyError> {
DescriptorSecretKey::SinglePriv(DescriptorSinglePriv {
key: self,
origin: None,
})
.to_descriptor_key()
.into_descriptor_key()
}
}

View File

@ -67,7 +67,7 @@ use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
use crate::descriptor::derived::AsDerived;
use crate::descriptor::{
get_checksum, DerivedDescriptor, DerivedDescriptorMeta, DescriptorMeta, DescriptorScripts,
ExtendedDescriptor, ExtractPolicy, Policy, ToWalletDescriptor, XKeyUtils,
ExtendedDescriptor, ExtractPolicy, IntoWalletDescriptor, Policy, XKeyUtils,
};
use crate::error::Error;
use crate::psbt::PSBTUtils;
@ -110,7 +110,7 @@ where
D: BatchDatabase,
{
/// Create a new "offline" wallet
pub fn new_offline<E: ToWalletDescriptor>(
pub fn new_offline<E: IntoWalletDescriptor>(
descriptor: E,
change_descriptor: Option<E>,
network: Network,
@ -124,7 +124,7 @@ impl<B, D> Wallet<B, D>
where
D: BatchDatabase,
{
fn _new<E: ToWalletDescriptor>(
fn _new<E: IntoWalletDescriptor>(
descriptor: E,
change_descriptor: Option<E>,
network: Network,
@ -134,7 +134,7 @@ where
) -> Result<Self, Error> {
let secp = Secp256k1::new();
let (descriptor, keymap) = descriptor.to_wallet_descriptor(&secp, network)?;
let (descriptor, keymap) = descriptor.into_wallet_descriptor(&secp, network)?;
database.check_descriptor_checksum(
KeychainKind::External,
get_checksum(&descriptor.to_string())?.as_bytes(),
@ -143,7 +143,7 @@ where
let (change_descriptor, change_signers) = match change_descriptor {
Some(desc) => {
let (change_descriptor, change_keymap) =
desc.to_wallet_descriptor(&secp, network)?;
desc.into_wallet_descriptor(&secp, network)?;
database.check_descriptor_checksum(
KeychainKind::Internal,
get_checksum(&change_descriptor.to_string())?.as_bytes(),
@ -1247,7 +1247,7 @@ where
{
/// Create a new "online" wallet
#[maybe_async]
pub fn new<E: ToWalletDescriptor>(
pub fn new<E: IntoWalletDescriptor>(
descriptor: E,
change_descriptor: Option<E>,
network: Network,

View File

@ -560,8 +560,8 @@ impl Eq for SignersContainerKey {}
mod signers_container_tests {
use super::*;
use crate::descriptor;
use crate::descriptor::ToWalletDescriptor;
use crate::keys::{DescriptorKey, ToDescriptorKey};
use crate::descriptor::IntoWalletDescriptor;
use crate::keys::{DescriptorKey, IntoDescriptorKey};
use bitcoin::secp256k1::{All, Secp256k1};
use bitcoin::util::bip32;
use bitcoin::util::psbt::PartiallySignedTransaction;
@ -579,7 +579,9 @@ mod signers_container_tests {
let (prvkey1, _, _) = setup_keys(TPRV0_STR);
let (prvkey2, _, _) = setup_keys(TPRV1_STR);
let desc = descriptor!(sh(multi(2, prvkey1, prvkey2))).unwrap();
let (_, keymap) = desc.to_wallet_descriptor(&secp, Network::Testnet).unwrap();
let (_, keymap) = desc
.into_wallet_descriptor(&secp, Network::Testnet)
.unwrap();
let signers = SignersContainer::from(keymap);
assert_eq!(signers.ids().len(), 2);
@ -690,8 +692,8 @@ mod signers_container_tests {
let tprv = bip32::ExtendedPrivKey::from_str(tprv).unwrap();
let tpub = bip32::ExtendedPubKey::from_private(&secp, &tprv);
let fingerprint = tprv.fingerprint(&secp);
let prvkey = (tprv, path.clone()).to_descriptor_key().unwrap();
let pubkey = (tpub, path).to_descriptor_key().unwrap();
let prvkey = (tprv, path.clone()).into_descriptor_key().unwrap();
let pubkey = (tpub, path).into_descriptor_key().unwrap();
(prvkey, pubkey, fingerprint)
}