Skip to content

Commit 8ef294a

Browse files
committed
Incomplete: Draft commit
1 parent 5356476 commit 8ef294a

File tree

15 files changed

+560
-335
lines changed

15 files changed

+560
-335
lines changed

examples/verify_tx.rs

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -96,21 +96,23 @@ fn main() {
9696
// to verify the signatures (trusting that if they're on
9797
// the blockchain, standardness would've required they be
9898
// either valid or 0-length.
99-
let iter = miniscript::descriptor::SatisfiedConstraints::from_descriptor(
100-
&desc,
101-
stack.clone(),
102-
|_, _| true, // Don't bother checking signatures
103-
0,
104-
0,
105-
);
106-
107-
println!("\nExample one");
108-
for elem in iter {
109-
match elem.expect("no evaluation error") {
110-
miniscript::descriptor::SatisfiedConstraint::PublicKey { key, sig } => {
111-
println!("Signed with {}: {}", key, sig);
99+
if let miniscript::SatisfiedConstraints::Segwitv0(iter) =
100+
miniscript::descriptor::SatisfiedConstraints::from_descriptor(
101+
&desc,
102+
stack.clone(),
103+
|_, _| true, // Don't bother checking signatures
104+
0,
105+
0,
106+
)
107+
{
108+
println!("\nExample one");
109+
for elem in iter {
110+
match elem.expect("no evaluation error") {
111+
miniscript::descriptor::SatisfiedConstraint::PublicKey { key, sig } => {
112+
println!("Signed with {}: {}", key, sig);
113+
}
114+
_ => {}
112115
}
113-
_ => {}
114116
}
115117
}
116118

@@ -120,23 +122,26 @@ fn main() {
120122
let sighash = transaction.signature_hash(0, &desc.witness_script(), 1);
121123
let message = secp256k1::Message::from_slice(&sighash[..]).expect("32-byte hash");
122124

123-
let iter = miniscript::descriptor::SatisfiedConstraints::from_descriptor(
124-
&desc,
125-
stack.clone(),
126-
|pk, (sig, sighashtype)| {
127-
sighashtype == bitcoin::SigHashType::All && secp.verify(&message, &sig, &pk.key).is_ok()
128-
},
129-
0,
130-
0,
131-
);
132-
133-
println!("\nExample two");
134-
for elem in iter {
135-
match elem.expect("no evaluation error") {
136-
miniscript::descriptor::SatisfiedConstraint::PublicKey { key, sig } => {
137-
println!("Signed with {}: {}", key, sig);
125+
if let miniscript::SatisfiedConstraints::Segwitv0(iter) =
126+
miniscript::descriptor::SatisfiedConstraints::from_descriptor(
127+
&desc,
128+
stack.clone(),
129+
|pk, (sig, sighashtype)| {
130+
sighashtype == bitcoin::SigHashType::All
131+
&& secp.verify(&message, &sig, &pk.key).is_ok()
132+
},
133+
0,
134+
0,
135+
)
136+
{
137+
println!("\nExample two");
138+
for elem in iter {
139+
match elem.expect("no evaluation error") {
140+
miniscript::descriptor::SatisfiedConstraint::PublicKey { key, sig } => {
141+
println!("Signed with {}: {}", key, sig);
142+
}
143+
_ => {}
138144
}
139-
_ => {}
140145
}
141146
}
142147

@@ -145,19 +150,22 @@ fn main() {
145150
let secp = secp256k1::Secp256k1::new();
146151
let message = secp256k1::Message::from_slice(&[0x01; 32][..]).expect("32-byte hash");
147152

148-
let iter = miniscript::descriptor::SatisfiedConstraints::from_descriptor(
149-
&desc,
150-
stack.clone(),
151-
|pk, (sig, sighashtype)| {
152-
sighashtype == bitcoin::SigHashType::All && secp.verify(&message, &sig, &pk.key).is_ok()
153-
},
154-
0,
155-
0,
156-
);
157-
158-
println!("\nExample three");
159-
for elem in iter {
160-
let error = elem.expect_err("evaluation error");
161-
println!("Evaluation error: {}", error);
153+
if let miniscript::SatisfiedConstraints::Segwitv0(iter) =
154+
miniscript::descriptor::SatisfiedConstraints::from_descriptor(
155+
&desc,
156+
stack.clone(),
157+
|pk, (sig, sighashtype)| {
158+
sighashtype == bitcoin::SigHashType::All
159+
&& secp.verify(&message, &sig, &pk.key).is_ok()
160+
},
161+
0,
162+
0,
163+
)
164+
{
165+
println!("\nExample three");
166+
for elem in iter {
167+
let error = elem.expect_err("evaluation error");
168+
println!("Evaluation error: {}", error);
169+
}
162170
}
163171
}

src/descriptor/create_descriptor.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use bitcoin::blockdata::script::Instruction;
99
use descriptor::satisfied_constraints::Error as IntError;
1010
use descriptor::satisfied_constraints::{Stack, StackElement};
1111
use descriptor::Descriptor;
12-
use miniscript::Miniscript;
12+
use miniscript::{Legacy, Miniscript, Segwitv0};
1313
use Error;
1414
use ToPublicKey;
1515

@@ -112,7 +112,7 @@ fn verify_wsh<'txin>(
112112
script_pubkey: &bitcoin::Script,
113113
script_sig: &bitcoin::Script,
114114
witness: &'txin [Vec<u8>],
115-
) -> Result<(Miniscript<bitcoin::PublicKey>, Stack<'txin>), Error> {
115+
) -> Result<(Miniscript<bitcoin::PublicKey, Segwitv0>, Stack<'txin>), Error> {
116116
if !script_sig.is_empty() {
117117
return Err(Error::NonEmptyScriptSig);
118118
}
@@ -121,7 +121,7 @@ fn verify_wsh<'txin>(
121121
if witness_script.to_v0_p2wsh() != *script_pubkey {
122122
return Err(Error::IncorrectScriptHash);
123123
}
124-
let ms = Miniscript::parse(&witness_script)?;
124+
let ms = Miniscript::<bitcoin::PublicKey, Segwitv0>::parse(&witness_script)?;
125125
//only iter till len -1 to not include the witness script
126126
let stack: Vec<StackElement> = witness
127127
.iter()
@@ -218,7 +218,7 @@ pub fn from_txin_with_witness_stack<'txin>(
218218
if !witness.is_empty() {
219219
return Err(Error::NonEmptyWitness);
220220
}
221-
let ms = Miniscript::parse(&redeem_script)?;
221+
let ms = Miniscript::<bitcoin::PublicKey, Legacy>::parse(&redeem_script)?;
222222
Ok((Descriptor::Sh(ms), stack))
223223
}
224224
} else {
@@ -230,7 +230,7 @@ pub fn from_txin_with_witness_stack<'txin>(
230230
if !witness.is_empty() {
231231
return Err(Error::NonEmptyWitness);
232232
}
233-
let ms = Miniscript::parse(script_pubkey)?;
233+
let ms = Miniscript::<bitcoin::PublicKey, Legacy>::parse(script_pubkey)?;
234234
Ok((Descriptor::Bare(ms), Stack(stack?)))
235235
}
236236
}

src/descriptor/mod.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use std::fmt;
3131
use std::str::{self, FromStr};
3232

3333
use expression;
34-
use miniscript::Miniscript;
34+
use miniscript::{Legacy, Miniscript, Segwitv0};
3535
use Error;
3636
use MiniscriptKey;
3737
use Satisfier;
@@ -50,7 +50,7 @@ pub use self::satisfied_constraints::Stack;
5050
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
5151
pub enum Descriptor<Pk: MiniscriptKey> {
5252
/// A raw scriptpubkey (including pay-to-pubkey)
53-
Bare(Miniscript<Pk>),
53+
Bare(Miniscript<Pk, Legacy>),
5454
/// Pay-to-Pubkey
5555
Pk(Pk),
5656
/// Pay-to-PubKey-Hash
@@ -60,11 +60,11 @@ pub enum Descriptor<Pk: MiniscriptKey> {
6060
/// Pay-to-Witness-PubKey-Hash inside P2SH
6161
ShWpkh(Pk),
6262
/// Pay-to-ScriptHash
63-
Sh(Miniscript<Pk>),
63+
Sh(Miniscript<Pk, Legacy>),
6464
/// Pay-to-Witness-ScriptHash
65-
Wsh(Miniscript<Pk>),
65+
Wsh(Miniscript<Pk, Segwitv0>),
6666
/// P2SH-P2WSH
67-
ShWsh(Miniscript<Pk>),
67+
ShWsh(Miniscript<Pk, Segwitv0>),
6868
}
6969

7070
impl<Pk: MiniscriptKey> Descriptor<Pk> {
@@ -200,7 +200,8 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
200200
let addr = bitcoin::Address::p2wpkh(&pk.to_public_key(), bitcoin::Network::Bitcoin);
201201
addr.script_pubkey()
202202
}
203-
Descriptor::Sh(ref d) | Descriptor::Wsh(ref d) | Descriptor::ShWsh(ref d) => d.encode(),
203+
Descriptor::Sh(ref d) => d.encode(),
204+
Descriptor::Wsh(ref d) | Descriptor::ShWsh(ref d) => d.encode(),
204205
}
205206
}
206207

@@ -395,25 +396,34 @@ where
395396
expression::terminal(&top.args[0], |pk| Pk::from_str(pk).map(Descriptor::Pkh))
396397
}
397398
("wpkh", 1) => {
398-
expression::terminal(&top.args[0], |pk| Pk::from_str(pk).map(Descriptor::Wpkh))
399+
let wpkh = expression::terminal(&top.args[0], |pk| Pk::from_str(pk))?;
400+
Segwitv0::is_valid_pk_str(&wpkh)?;
401+
Ok(Descriptor::Wpkh(wpkh))
399402
}
400403
("sh", 1) => {
401404
let newtop = &top.args[0];
402405
match (newtop.name, newtop.args.len()) {
403406
("wsh", 1) => {
404407
let sub = Miniscript::from_tree(&newtop.args[0])?;
408+
Segwitv0::is_valid_ms_str(&sub.node)?;
405409
Ok(Descriptor::ShWsh(sub))
406410
}
407-
("wpkh", 1) => expression::terminal(&newtop.args[0], |pk| {
408-
Pk::from_str(pk).map(Descriptor::ShWpkh)
409-
}),
411+
("wpkh", 1) => {
412+
let wpkh = expression::terminal(&newtop.args[0], |pk| Pk::from_str(pk))?;
413+
Segwitv0::is_valid_pk_str(&wpkh)?;
414+
Ok(Descriptor::ShWpkh(wpkh))
415+
},
410416
_ => {
411417
let sub = Miniscript::from_tree(&top.args[0])?;
412418
Ok(Descriptor::Sh(sub))
413419
}
414420
}
415421
}
416-
("wsh", 1) => expression::unary(top, Descriptor::Wsh),
422+
("wsh", 1) => {
423+
let sub = Miniscript::from_tree(&top.args[0])?;
424+
Segwitv0::is_valid_ms_str(&sub.node)?;
425+
Ok(Descriptor::Wsh(sub))
426+
}
417427
_ => {
418428
let sub = expression::FromTree::from_tree(&top)?;
419429
Ok(Descriptor::Bare(sub))
@@ -442,6 +452,7 @@ where
442452
}
443453
}
444454

455+
445456
impl<Pk: MiniscriptKey> fmt::Debug for Descriptor<Pk> {
446457
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
447458
match *self {
@@ -852,6 +863,8 @@ mod tests {
852863
);
853864
assert_eq!(sh.unsigned_script_sig(), bitcoin::Script::new());
854865

866+
let ms = ms_str!("c:pk_k({})", pk);
867+
855868
let wsh = Descriptor::Wsh(ms.clone());
856869
wsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
857870
assert_eq!(

0 commit comments

Comments
 (0)