Merge commit 'refs/pull/438/head' of github.com:bitcoindevkit/bdk
This commit is contained in:
commit
46f7b440f5
@ -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 )*)
|
||||||
});
|
});
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user