Skip to content

Commit 1976ba4

Browse files
authored
Merge pull request #166 from sanket1729/topubkey_update
Update ToPublicKey API to take in context param
2 parents 283ab2b + b5cdcf5 commit 1976ba4

File tree

17 files changed

+793
-413
lines changed

17 files changed

+793
-413
lines changed

examples/htlc.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ extern crate miniscript;
2020
use bitcoin::Network;
2121
use miniscript::policy::{Concrete, Liftable};
2222
use miniscript::Descriptor;
23+
use miniscript::NullCtx;
2324
use std::str::FromStr;
2425

2526
fn main() {
@@ -44,17 +45,20 @@ fn main() {
4445
);
4546

4647
assert_eq!(
47-
format!("{:x}", htlc_descriptor.script_pubkey()),
48+
format!("{:x}", htlc_descriptor.script_pubkey(NullCtx)),
4849
"00203c0a59874cb570ff3093bcd67e846c967127c9e3fcd30f0a20857b504599e50a"
4950
);
5051

5152
assert_eq!(
52-
format!("{:x}", htlc_descriptor.witness_script()),
53+
format!("{:x}", htlc_descriptor.witness_script(NullCtx)),
5354
"21022222222222222222222222222222222222222222222222222222222222222222ac6476a9144377a5acd66dc5cb67148a24818d1e51fa183bd288ad025c11b26782012088a82011111111111111111111111111111111111111111111111111111111111111118768"
5455
);
5556

5657
assert_eq!(
57-
format!("{}", htlc_descriptor.address(Network::Bitcoin).unwrap()),
58+
format!(
59+
"{}",
60+
htlc_descriptor.address(Network::Bitcoin, NullCtx).unwrap()
61+
),
5862
"bc1q8s99np6vk4c07vynhnt8aprvjecj0j0rlnfs7z3qs4a4q3veu59q8x3k8x"
5963
);
6064
}

examples/parse.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
extern crate bitcoin;
1818
extern crate miniscript;
1919

20+
use miniscript::NullCtx;
2021
use std::str::FromStr;
2122

2223
fn main() {
@@ -25,13 +26,17 @@ fn main() {
2526
)
2627
.unwrap();
2728

29+
// Sometimes it is necesarry to have additional information to get the bitcoin::PublicKey
30+
// from the MiniscriptKey which can supplied by `to_pk_ctx` parameter. For example,
31+
// when calculating the script pubkey of a descriptor with xpubs, the secp context and
32+
// child information maybe required.
2833
assert_eq!(
29-
format!("{:x}", my_descriptor.script_pubkey()),
34+
format!("{:x}", my_descriptor.script_pubkey(NullCtx)),
3035
"0020daef16dd7c946a3e735a6e43310cb2ce33dfd14a04f76bf8241a16654cb2f0f9"
3136
);
3237

3338
assert_eq!(
34-
format!("{:x}", my_descriptor.witness_script()),
39+
format!("{:x}", my_descriptor.witness_script(NullCtx)),
3540
"21020202020202020202020202020202020202020202020202020202020202020202ac"
3641
);
3742
}

examples/sign_multisig.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extern crate bitcoin;
1818
extern crate miniscript;
1919

2020
use bitcoin::secp256k1; // secp256k1 re-exported from rust-bitcoin
21+
use miniscript::NullCtx;
2122
use std::collections::HashMap;
2223
use std::str::FromStr;
2324

@@ -82,19 +83,24 @@ fn main() {
8283
let my_descriptor =
8384
BitcoinDescriptor::from_str(&descriptor_str[..]).expect("parse descriptor string");
8485

86+
// Sometimes it is necesarry to have additional information to get the bitcoin::PublicKey
87+
// from the MiniscriptKey which can supplied by `to_pk_ctx` parameter. For example,
88+
// when calculating the script pubkey of a descriptor with xpubs, the secp context and
89+
// child information maybe required.
90+
8591
// Check weight for witness satisfaction cost ahead of time.
8692
// 4(scriptSig length of 0) + 1(witness stack size) + 106(serialized witnessScript)
8793
// + 73*2(signature length + signatures + sighash bytes) + 1(dummy byte) = 258
88-
assert_eq!(my_descriptor.max_satisfaction_weight().unwrap(), 258);
94+
assert_eq!(my_descriptor.max_satisfaction_weight(NullCtx).unwrap(), 258);
8995

9096
// Observe the script properties, just for fun
9197
assert_eq!(
92-
format!("{:x}", my_descriptor.script_pubkey()),
98+
format!("{:x}", my_descriptor.script_pubkey(NullCtx)),
9399
"00200ed49b334a12c37f3df8a2974ad91ff95029215a2b53f78155be737907f06163"
94100
);
95101

96102
assert_eq!(
97-
format!("{:x}", my_descriptor.witness_script()),
103+
format!("{:x}", my_descriptor.witness_script(NullCtx)),
98104
"52\
99105
21020202020202020202020202020202020202020202020202020202020202020202\
100106
21020102030405060708010203040506070801020304050607080000000000000000\
@@ -108,23 +114,31 @@ fn main() {
108114
let mut sigs = HashMap::<bitcoin::PublicKey, miniscript::BitcoinSig>::new();
109115

110116
// Doesn't work with no signatures
111-
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_err());
117+
assert!(my_descriptor
118+
.satisfy(&mut tx.input[0], &sigs, NullCtx)
119+
.is_err());
112120
assert_eq!(tx.input[0], original_txin);
113121

114122
// ...or one signature...
115123
sigs.insert(public_keys[1], bitcoin_sig);
116-
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_err());
124+
assert!(my_descriptor
125+
.satisfy(&mut tx.input[0], &sigs, NullCtx)
126+
.is_err());
117127
assert_eq!(tx.input[0], original_txin);
118128

119129
// ...but two signatures is ok
120130
sigs.insert(public_keys[2], bitcoin_sig);
121-
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_ok());
131+
assert!(my_descriptor
132+
.satisfy(&mut tx.input[0], &sigs, NullCtx)
133+
.is_ok());
122134
assert_ne!(tx.input[0], original_txin);
123135
assert_eq!(tx.input[0].witness.len(), 4); // 0, sig, sig, witness script
124136

125137
// ...and even if we give it a third signature, only two are used
126138
sigs.insert(public_keys[0], bitcoin_sig);
127-
assert!(my_descriptor.satisfy(&mut tx.input[0], &sigs).is_ok());
139+
assert!(my_descriptor
140+
.satisfy(&mut tx.input[0], &sigs, NullCtx)
141+
.is_ok());
128142
assert_ne!(tx.input[0], original_txin);
129143
assert_eq!(tx.input[0].witness.len(), 4); // 0, sig, sig, witness script
130144
}

examples/verify_tx.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extern crate miniscript;
1919

2020
use bitcoin::consensus::Decodable;
2121
use bitcoin::secp256k1; // secp256k1 re-exported from rust-bitcoin
22-
22+
use miniscript::NullCtx;
2323
fn main() {
2424
// tx `f27eba163c38ad3f34971198687a3f1882b7ec818599ffe469a8440d82261c98`
2525
#[cfg_attr(feature="cargo-fmt", rustfmt_skip)]
@@ -116,7 +116,11 @@ fn main() {
116116
// 2. Example two: verify the signatures to ensure that invalid
117117
// signatures are not treated as having participated in the script
118118
let secp = secp256k1::Secp256k1::new();
119-
let sighash = transaction.signature_hash(0, &desc.witness_script(), 1);
119+
// Sometimes it is necesarry to have additional information to get the bitcoin::PublicKey
120+
// from the MiniscriptKey which can supplied by `to_pk_ctx` parameter. For example,
121+
// when calculating the script pubkey of a descriptor with xpubs, the secp context and
122+
// child information maybe required.
123+
let sighash = transaction.signature_hash(0, &desc.witness_script(NullCtx), 1);
120124
let message = secp256k1::Message::from_slice(&sighash[..]).expect("32-byte hash");
121125

122126
let iter = miniscript::descriptor::SatisfiedConstraints::from_descriptor(

fuzz/fuzz_targets/roundtrip_miniscript_script.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ extern crate miniscript;
22

33
use miniscript::bitcoin::blockdata::script;
44
use miniscript::Miniscript;
5+
use miniscript::NullCtx;
56
use miniscript::Segwitv0;
67

78
fn do_test(data: &[u8]) {
89
// Try round-tripping as a script
910
let script = script::Script::from(data.to_owned());
1011

1112
if let Ok(pt) = Miniscript::<_, Segwitv0>::parse(&script) {
12-
let output = pt.encode();
13-
assert_eq!(pt.script_size(), output.len());
13+
let output = pt.encode(NullCtx);
14+
assert_eq!(pt.script_size(NullCtx), output.len());
1415
assert_eq!(output, script);
1516
}
1617
}

src/descriptor/create_descriptor.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use descriptor::satisfied_constraints::{Stack, StackElement};
1111
use descriptor::Descriptor;
1212
use miniscript::{Legacy, Miniscript, Segwitv0};
1313
use Error;
14+
use NullCtx;
1415
use ToPublicKey;
1516

1617
/// Helper function for creating StackElement from Push instructions. Special case required for
@@ -89,8 +90,9 @@ fn verify_p2wpkh<'txin>(
8990
}
9091
if let Some((pk_bytes, witness)) = witness.split_last() {
9192
if let Ok(pk) = bitcoin::PublicKey::from_slice(pk_bytes) {
92-
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin)
93-
.map_err(|_| Error::InterpreterError(IntError::UncompressedPubkey))?;
93+
let addr =
94+
bitcoin::Address::p2wpkh(&pk.to_public_key(NullCtx), bitcoin::Network::Bitcoin)
95+
.map_err(|_| Error::InterpreterError(IntError::UncompressedPubkey))?;
9496
if addr.script_pubkey() != *script_pubkey {
9597
return Err(Error::InterpreterError(IntError::PkEvaluationError(pk)));
9698
}
@@ -145,7 +147,7 @@ fn verify_p2pkh<'txin>(
145147
) -> Result<(Descriptor<bitcoin::PublicKey>, Stack<'txin>), Error> {
146148
let (pk_bytes, stack) = parse_scriptsig_top(script_sig)?;
147149
if let Ok(pk) = bitcoin::PublicKey::from_slice(&pk_bytes) {
148-
let addr = bitcoin::Address::p2pkh(&pk.to_public_key(), bitcoin::Network::Bitcoin);
150+
let addr = bitcoin::Address::p2pkh(&pk.to_public_key(NullCtx), bitcoin::Network::Bitcoin);
149151
if !witness.is_empty() {
150152
return Err(Error::NonEmptyWitness);
151153
}
@@ -247,7 +249,7 @@ mod tests {
247249
use descriptor::satisfied_constraints::{Stack, StackElement};
248250
use std::str::FromStr;
249251
use ToPublicKey;
250-
use {Descriptor, Miniscript};
252+
use {Descriptor, Miniscript, NullCtx};
251253

252254
macro_rules! stack {
253255
($($data:ident$(($pushdata:expr))*),*) => (
@@ -309,7 +311,7 @@ mod tests {
309311

310312
//test pk
311313
let script_pubkey = script::Builder::new()
312-
.push_key(&pks[0].to_public_key())
314+
.push_key(&pks[0].to_public_key(NullCtx))
313315
.push_opcode(opcodes::all::OP_CHECKSIG)
314316
.into_script();
315317
let script_sig = script::Builder::new().push_slice(&sigs[0]).into_script();
@@ -334,17 +336,21 @@ mod tests {
334336
//test Wsh: and(pkv, pk). Note this does not check miniscript.
335337
let ms = ms_str!("and_v(vc:pk_k({}),c:pk_k({}))", pks[0], pks[1]);
336338
let script_pubkey =
337-
bitcoin::Address::p2wsh(&ms.encode(), bitcoin::Network::Bitcoin).script_pubkey();
339+
bitcoin::Address::p2wsh(&ms.encode(NullCtx), bitcoin::Network::Bitcoin).script_pubkey();
338340
let script_sig = script::Builder::new().into_script();
339-
let witness = vec![sigs[1].clone(), sigs[0].clone(), ms.encode().to_bytes()];
341+
let witness = vec![
342+
sigs[1].clone(),
343+
sigs[0].clone(),
344+
ms.encode(NullCtx).to_bytes(),
345+
];
340346
let (des, stack) = from_txin_with_witness_stack(&script_pubkey, &script_sig, &witness)
341347
.expect("Descriptor/Witness stack creation to succeed");
342348
assert_eq!(Descriptor::Wsh(ms.clone()), des);
343349
assert_eq!(stack, stack![Push(&sigs[1]), Push(&sigs[0])]);
344350

345351
//test Bare: and(pkv, pk). Note this does not check miniscript.
346352
let ms = ms_str!("or_b(c:pk_k({}),sc:pk_k({}))", pks[0], pks[1]);
347-
let script_pubkey = ms.encode();
353+
let script_pubkey = ms.encode(NullCtx);
348354
let script_sig = script::Builder::new()
349355
.push_int(0)
350356
.push_slice(&sigs[0])
@@ -358,11 +364,11 @@ mod tests {
358364
//test Sh: and(pkv, pk). Note this does not check miniscript.
359365
let ms = ms_str!("c:or_i(pk_k({}),pk_k({}))", pks[0], pks[1]);
360366
let script_pubkey =
361-
bitcoin::Address::p2sh(&ms.encode(), bitcoin::Network::Bitcoin).script_pubkey();
367+
bitcoin::Address::p2sh(&ms.encode(NullCtx), bitcoin::Network::Bitcoin).script_pubkey();
362368
let script_sig = script::Builder::new()
363369
.push_slice(&sigs[0])
364370
.push_int(1)
365-
.push_slice(&ms.encode().to_bytes())
371+
.push_slice(&ms.encode(NullCtx).to_bytes())
366372
.into_script();
367373
let witness = vec![] as Vec<Vec<u8>>;
368374
let (des, stack) = from_txin_with_witness_stack(&script_pubkey, &script_sig, &witness)
@@ -374,11 +380,16 @@ mod tests {
374380
//This test passes incorrect witness argument.
375381
let ms = ms_str!("and_v(vc:pk_k({}),c:pk_k({}))", pks[0], pks[1]);
376382
let script_pubkey =
377-
bitcoin::Address::p2shwsh(&ms.encode(), bitcoin::Network::Bitcoin).script_pubkey();
383+
bitcoin::Address::p2shwsh(&ms.encode(NullCtx), bitcoin::Network::Bitcoin)
384+
.script_pubkey();
378385
let script_sig = script::Builder::new()
379-
.push_slice(&ms.encode().to_v0_p2wsh().to_bytes())
386+
.push_slice(&ms.encode(NullCtx).to_v0_p2wsh().to_bytes())
380387
.into_script();
381-
let witness = vec![sigs[1].clone(), sigs[3].clone(), ms.encode().to_bytes()];
388+
let witness = vec![
389+
sigs[1].clone(),
390+
sigs[3].clone(),
391+
ms.encode(NullCtx).to_bytes(),
392+
];
382393
let (des, stack) = from_txin_with_witness_stack(&script_pubkey, &script_sig, &witness)
383394
.expect("Descriptor/Witness stack creation to succeed");
384395
assert_eq!(Descriptor::ShWsh(ms.clone()), des);

0 commit comments

Comments
 (0)