Merge commit 'refs/pull/438/head' of github.com:bitcoindevkit/bdk

This commit is contained in:
Steve Myers 2021-09-16 11:03:52 -07:00
commit 46f7b440f5
No known key found for this signature in database
GPG Key ID: 8105A46B22C2D051
3 changed files with 48 additions and 33 deletions

View File

@ -571,8 +571,9 @@ macro_rules! fragment {
( pk ( $key:expr ) ) => ({ ( pk ( $key:expr ) ) => ({
$crate::fragment!(c:pk_k ( $key )) $crate::fragment!(c:pk_k ( $key ))
}); });
( pk_h ( $key_hash:expr ) ) => ({ ( pk_h ( $key:expr ) ) => ({
$crate::impl_leaf_opcode_value!(PkH, $key_hash) let secp = $crate::bitcoin::secp256k1::Secp256k1::new();
$crate::keys::make_pkh($key, &secp)
}); });
( after ( $value:expr ) ) => ({ ( after ( $value:expr ) ) => ({
$crate::impl_leaf_opcode_value!(After, $value) $crate::impl_leaf_opcode_value!(After, $value)
@ -601,6 +602,9 @@ macro_rules! fragment {
( and_or ( $( $inner:tt )* ) ) => ({ ( and_or ( $( $inner:tt )* ) ) => ({
$crate::impl_node_opcode_three!(AndOr, $( $inner )*) $crate::impl_node_opcode_three!(AndOr, $( $inner )*)
}); });
( andor ( $( $inner:tt )* ) ) => ({
$crate::impl_node_opcode_three!(AndOr, $( $inner )*)
});
( or_b ( $( $inner:tt )* ) ) => ({ ( or_b ( $( $inner:tt )* ) ) => ({
$crate::impl_node_opcode_two!(OrB, $( $inner )*) $crate::impl_node_opcode_two!(OrB, $( $inner )*)
}); });

View File

@ -47,14 +47,12 @@ use bitcoin::util::bip32::Fingerprint;
use bitcoin::PublicKey; use bitcoin::PublicKey;
use miniscript::descriptor::{DescriptorPublicKey, ShInner, SortedMultiVec, WshInner}; use miniscript::descriptor::{DescriptorPublicKey, ShInner, SortedMultiVec, WshInner};
use miniscript::{ use miniscript::{Descriptor, Miniscript, MiniscriptKey, Satisfier, ScriptContext, Terminal};
Descriptor, Miniscript, MiniscriptKey, Satisfier, ScriptContext, Terminal, ToPublicKey,
};
#[allow(unused_imports)] #[allow(unused_imports)]
use log::{debug, error, info, trace}; use log::{debug, error, info, trace};
use crate::descriptor::{DerivedDescriptorKey, ExtractPolicy}; use crate::descriptor::ExtractPolicy;
use crate::wallet::signer::{SignerId, SignersContainer}; use crate::wallet::signer::{SignerId, SignersContainer};
use crate::wallet::utils::{self, After, Older, SecpCtx}; use crate::wallet::utils::{self, After, Older, SecpCtx};
@ -88,13 +86,6 @@ impl PkOrF {
}, },
} }
} }
fn from_key_hash(k: hash160::Hash) -> Self {
PkOrF {
pubkey_hash: Some(k),
..Default::default()
}
}
} }
/// An item that needs to be satisfied /// An item that needs to be satisfied
@ -779,25 +770,6 @@ fn signature_in_psbt(psbt: &Psbt, key: &DescriptorPublicKey, secp: &SecpCtx) ->
}) })
} }
fn signature_key(
key: &<DescriptorPublicKey as MiniscriptKey>::Hash,
signers: &SignersContainer,
secp: &SecpCtx,
) -> Policy {
let key_hash = DerivedDescriptorKey::new(key.clone(), secp)
.to_public_key()
.to_pubkeyhash();
let mut policy: Policy = SatisfiableItem::Signature(PkOrF::from_key_hash(key_hash)).into();
if signers.find(SignerId::PkHash(key_hash)).is_some() {
policy.contribution = Satisfaction::Complete {
condition: Default::default(),
}
}
policy
}
impl<Ctx: ScriptContext> ExtractPolicy for Miniscript<DescriptorPublicKey, Ctx> { impl<Ctx: ScriptContext> ExtractPolicy for Miniscript<DescriptorPublicKey, Ctx> {
fn extract_policy( fn extract_policy(
&self, &self,
@ -809,7 +781,7 @@ impl<Ctx: ScriptContext> ExtractPolicy for Miniscript<DescriptorPublicKey, Ctx>
// Leaves // Leaves
Terminal::True | Terminal::False => None, Terminal::True | Terminal::False => None,
Terminal::PkK(pubkey) => Some(signature(pubkey, signers, build_sat, secp)), Terminal::PkK(pubkey) => Some(signature(pubkey, signers, build_sat, secp)),
Terminal::PkH(pubkey_hash) => Some(signature_key(pubkey_hash, signers, secp)), Terminal::PkH(pubkey_hash) => Some(signature(pubkey_hash, signers, build_sat, secp)),
Terminal::After(value) => { Terminal::After(value) => {
let mut policy: Policy = SatisfiableItem::AbsoluteTimelock { value: *value }.into(); let mut policy: Policy = SatisfiableItem::AbsoluteTimelock { value: *value }.into();
policy.contribution = Satisfaction::Complete { policy.contribution = Satisfaction::Complete {
@ -1444,6 +1416,7 @@ mod test {
const ALICE_TPRV_STR:&str = "tprv8ZgxMBicQKsPf6T5X327efHnvJDr45Xnb8W4JifNWtEoqXu9MRYS4v1oYe6DFcMVETxy5w3bqpubYRqvcVTqovG1LifFcVUuJcbwJwrhYzP"; const ALICE_TPRV_STR:&str = "tprv8ZgxMBicQKsPf6T5X327efHnvJDr45Xnb8W4JifNWtEoqXu9MRYS4v1oYe6DFcMVETxy5w3bqpubYRqvcVTqovG1LifFcVUuJcbwJwrhYzP";
const BOB_TPRV_STR:&str = "tprv8ZgxMBicQKsPeinZ155cJAn117KYhbaN6MV3WeG6sWhxWzcvX1eg1awd4C9GpUN1ncLEM2rzEvunAg3GizdZD4QPPCkisTz99tXXB4wZArp"; const BOB_TPRV_STR:&str = "tprv8ZgxMBicQKsPeinZ155cJAn117KYhbaN6MV3WeG6sWhxWzcvX1eg1awd4C9GpUN1ncLEM2rzEvunAg3GizdZD4QPPCkisTz99tXXB4wZArp";
const CAROL_TPRV_STR:&str = "tprv8ZgxMBicQKsPdC3CicFifuLCEyVVdXVUNYorxUWj3iGZ6nimnLAYAY9SYB7ib8rKzRxrCKFcEytCt6szwd2GHnGPRCBLAEAoSVDefSNk4Bt";
const ALICE_BOB_PATH: &str = "m/0'"; const ALICE_BOB_PATH: &str = "m/0'";
#[test] #[test]
@ -1602,4 +1575,28 @@ mod test {
); );
//println!("{}", serde_json::to_string(&policy_expired_signed).unwrap()); //println!("{}", serde_json::to_string(&policy_expired_signed).unwrap());
} }
#[test]
fn test_extract_pkh() {
let secp = Secp256k1::new();
let (prvkey_alice, _, _) = setup_keys(ALICE_TPRV_STR, ALICE_BOB_PATH, &secp);
let (prvkey_bob, _, _) = setup_keys(BOB_TPRV_STR, ALICE_BOB_PATH, &secp);
let (prvkey_carol, _, _) = setup_keys(CAROL_TPRV_STR, ALICE_BOB_PATH, &secp);
let desc = descriptor!(wsh(c: andor(
pk(prvkey_alice),
pk_k(prvkey_bob),
pk_h(prvkey_carol),
)))
.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, BuildSatisfaction::None, &secp);
assert!(policy.is_ok());
}
} }

View File

@ -753,6 +753,20 @@ pub fn make_pk<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(
Ok((minisc, key_map, valid_networks)) Ok((minisc, key_map, valid_networks))
} }
// Used internally by `bdk::fragment!` to build `pk_h()` fragments
#[doc(hidden)]
pub fn make_pkh<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.into_descriptor_key()?.extract(secp)?;
let minisc = Miniscript::from_ast(Terminal::PkH(key))?;
minisc.check_minsicript()?;
Ok((minisc, key_map, valid_networks))
}
// Used internally by `bdk::fragment!` to build `multi()` fragments // Used internally by `bdk::fragment!` to build `multi()` fragments
#[doc(hidden)] #[doc(hidden)]
pub fn make_multi<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>( pub fn make_multi<Pk: IntoDescriptorKey<Ctx>, Ctx: ScriptContext>(