Skip to content

Commit 307d21c

Browse files
committed
Implement
1 parent 5ba9bfe commit 307d21c

File tree

2 files changed

+75
-15
lines changed

2 files changed

+75
-15
lines changed

src/miniscript/decode.rs

+32-15
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,20 @@ pub fn parse(tokens: &mut TokenIter) -> Result<Miniscript<bitcoin::PublicKey>, E
224224
// pubkeyhash and [T] VERIFY and [T] 0NOTEQUAL
225225
Tk::Verify => match_token!(
226226
tokens,
227-
Tk::Equal, Tk::Hash20(hash), Tk::Hash160, Tk::Dup
228-
=> term.reduce0(Terminal::PkH(
229-
hash160::Hash::from_inner(hash)
230-
))?,
227+
Tk::Equal => match_token!(
228+
tokens,
229+
Tk::Hash20(hash), Tk::Hash160, Tk::Dup => {
230+
term.reduce0(Terminal::PkH(
231+
hash160::Hash::from_inner(hash)
232+
))?
233+
},
234+
Tk::Hash32(hash), Tk::Sha256, Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
235+
non_term.push(NonTerm::Verify);
236+
term.reduce0(Terminal::Sha256(
237+
sha256::Hash::from_inner(hash)
238+
))?
239+
},
240+
),
231241
x => {
232242
tokens.un_next(x);
233243
non_term.push(NonTerm::Verify);
@@ -343,16 +353,9 @@ pub fn parse(tokens: &mut TokenIter) -> Result<Miniscript<bitcoin::PublicKey>, E
343353
}
344354
Some(NonTerm::MaybeAndV) => {
345355
// Handle `and_v` prefixing
346-
match tokens.peek() {
347-
None
348-
| Some(&Tk::If)
349-
| Some(&Tk::NotIf)
350-
| Some(&Tk::Else)
351-
| Some(&Tk::ToAltStack) => {}
352-
_ => {
353-
non_term.push(NonTerm::AndV);
354-
non_term.push(NonTerm::Expression);
355-
}
356+
if isAndV(tokens) {
357+
non_term.push(NonTerm::AndV);
358+
non_term.push(NonTerm::Expression);
356359
}
357360
}
358361
Some(NonTerm::MaybeSwap) => {
@@ -377,7 +380,14 @@ pub fn parse(tokens: &mut TokenIter) -> Result<Miniscript<bitcoin::PublicKey>, E
377380
Some(NonTerm::Verify) => term.reduce1(Terminal::Verify)?,
378381
Some(NonTerm::NonZero) => term.reduce1(Terminal::NonZero)?,
379382
Some(NonTerm::ZeroNotEqual) => term.reduce1(Terminal::ZeroNotEqual)?,
380-
Some(NonTerm::AndV) => term.reduce2(Terminal::AndV)?,
383+
Some(NonTerm::AndV) => {
384+
if isAndV(tokens) {
385+
non_term.push(NonTerm::AndV);
386+
non_term.push(NonTerm::MaybeAndV);
387+
} else {
388+
term.reduce2(Terminal::AndV)?
389+
}
390+
}
381391
Some(NonTerm::AndB) => term.reduce2(Terminal::AndB)?,
382392
Some(NonTerm::OrB) => term.reduce2(Terminal::OrB)?,
383393
Some(NonTerm::OrC) => term.reduce2(Terminal::OrC)?,
@@ -472,3 +482,10 @@ pub fn parse(tokens: &mut TokenIter) -> Result<Miniscript<bitcoin::PublicKey>, E
472482
assert_eq!(term.0.len(), 1);
473483
Ok(term.pop().unwrap())
474484
}
485+
486+
fn isAndV(tokens: &mut TokenIter) -> bool {
487+
match tokens.peek() {
488+
None | Some(&Tk::If) | Some(&Tk::NotIf) | Some(&Tk::Else) | Some(&Tk::ToAltStack) => false,
489+
_ => true,
490+
}
491+
}

src/miniscript/mod.rs

+43
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,49 @@ mod tests {
665665
OP_PUSHBYTES_33 0289637f97580a796e050791ad5a2f27af1803645d95df021a3c2d82eb8c2ca7ff \
666666
OP_PUSHNUM_5 OP_CHECKMULTISIG)",
667667
);
668+
669+
roundtrip(
670+
&ms_str!(
671+
"t:and_v(\
672+
vu:hash256(131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b),\
673+
v:sha256(ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5)\
674+
)"),
675+
"Script(OP_IF OP_SIZE OP_PUSHBYTES_1 20 OP_EQUALVERIFY OP_HASH256 OP_PUSHBYTES_32 131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b OP_EQUAL OP_ELSE OP_0 OP_ENDIF OP_VERIFY OP_SIZE OP_PUSHBYTES_1 20 OP_EQUALVERIFY OP_SHA256 OP_PUSHBYTES_32 ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5 OP_EQUALVERIFY OP_PUSHNUM_1)"
676+
);
677+
roundtrip(
678+
&ms_str!("and_n(c:pk(03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729),and_b(l:older(4252898),a:older(16)))"),
679+
"Script(OP_PUSHBYTES_33 03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729 OP_CHECKSIG OP_NOTIF OP_0 OP_ELSE OP_IF OP_0 OP_ELSE OP_PUSHBYTES_3 e2e440 OP_CSV OP_ENDIF OP_TOALTSTACK OP_PUSHNUM_16 OP_CSV OP_FROMALTSTACK OP_BOOLAND OP_ENDIF)"
680+
);
681+
roundtrip(
682+
&ms_str!(
683+
"t:andor(thresh_m(\
684+
3,\
685+
02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e,\
686+
03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,\
687+
02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13\
688+
),\
689+
v:older(4194305),\
690+
v:sha256(9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2)\
691+
)"),
692+
"Script(OP_PUSHNUM_3 OP_PUSHBYTES_33 02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e \
693+
OP_PUSHBYTES_33 03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556 \
694+
OP_PUSHBYTES_33 02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13 \
695+
OP_PUSHNUM_3 OP_CHECKMULTISIG OP_NOTIF OP_SIZE OP_PUSHBYTES_1 20 OP_EQUALVERIFY OP_SHA256 \
696+
OP_PUSHBYTES_32 9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2 OP_EQUALVERIFY \
697+
OP_ELSE OP_PUSHBYTES_3 010040 OP_CSV OP_VERIFY OP_ENDIF OP_PUSHNUM_1)"
698+
);
699+
roundtrip(
700+
&ms_str!(
701+
"t:and_v(\
702+
vu:hash256(131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b),\
703+
v:sha256(ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5)\
704+
)"),
705+
"Script(\
706+
OP_IF OP_SIZE OP_PUSHBYTES_1 20 OP_EQUALVERIFY OP_HASH256 OP_PUSHBYTES_32 131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b OP_EQUAL \
707+
OP_ELSE OP_0 OP_ENDIF OP_VERIFY OP_SIZE OP_PUSHBYTES_1 20 OP_EQUALVERIFY OP_SHA256 OP_PUSHBYTES_32 ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5 OP_EQUALVERIFY \
708+
OP_PUSHNUM_1\
709+
)"
710+
);
668711
}
669712

670713
#[test]

0 commit comments

Comments
 (0)