Skip to content

Commit 8d80b1c

Browse files
authored
Merge pull request #106 from apoelstra/issue_from_pull_63
Fixed parser bug
2 parents f61abc4 + ba02e75 commit 8d80b1c

File tree

2 files changed

+75
-15
lines changed

2 files changed

+75
-15
lines changed

src/miniscript/decode.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,20 @@ pub fn parse<Ctx: ScriptContext>(
236236
// pubkeyhash and [T] VERIFY and [T] 0NOTEQUAL
237237
Tk::Verify => match_token!(
238238
tokens,
239-
Tk::Equal, Tk::Hash20(hash), Tk::Hash160, Tk::Dup
240-
=> term.reduce0(Terminal::PkH(
241-
hash160::Hash::from_inner(hash)
242-
))?,
239+
Tk::Equal => match_token!(
240+
tokens,
241+
Tk::Hash20(hash), Tk::Hash160, Tk::Dup => {
242+
term.reduce0(Terminal::PkH(
243+
hash160::Hash::from_inner(hash)
244+
))?
245+
},
246+
Tk::Hash32(hash), Tk::Sha256, Tk::Verify, Tk::Equal, Tk::Num(32), Tk::Size => {
247+
non_term.push(NonTerm::Verify);
248+
term.reduce0(Terminal::Sha256(
249+
sha256::Hash::from_inner(hash)
250+
))?
251+
},
252+
),
243253
x => {
244254
tokens.un_next(x);
245255
non_term.push(NonTerm::Verify);
@@ -355,16 +365,9 @@ pub fn parse<Ctx: ScriptContext>(
355365
}
356366
Some(NonTerm::MaybeAndV) => {
357367
// Handle `and_v` prefixing
358-
match tokens.peek() {
359-
None
360-
| Some(&Tk::If)
361-
| Some(&Tk::NotIf)
362-
| Some(&Tk::Else)
363-
| Some(&Tk::ToAltStack) => {}
364-
_ => {
365-
non_term.push(NonTerm::AndV);
366-
non_term.push(NonTerm::Expression);
367-
}
368+
if is_and_v(tokens) {
369+
non_term.push(NonTerm::AndV);
370+
non_term.push(NonTerm::Expression);
368371
}
369372
}
370373
Some(NonTerm::MaybeSwap) => {
@@ -389,7 +392,14 @@ pub fn parse<Ctx: ScriptContext>(
389392
Some(NonTerm::Verify) => term.reduce1(Terminal::Verify)?,
390393
Some(NonTerm::NonZero) => term.reduce1(Terminal::NonZero)?,
391394
Some(NonTerm::ZeroNotEqual) => term.reduce1(Terminal::ZeroNotEqual)?,
392-
Some(NonTerm::AndV) => term.reduce2(Terminal::AndV)?,
395+
Some(NonTerm::AndV) => {
396+
if is_and_v(tokens) {
397+
non_term.push(NonTerm::AndV);
398+
non_term.push(NonTerm::MaybeAndV);
399+
} else {
400+
term.reduce2(Terminal::AndV)?
401+
}
402+
}
393403
Some(NonTerm::AndB) => term.reduce2(Terminal::AndB)?,
394404
Some(NonTerm::OrB) => term.reduce2(Terminal::OrB)?,
395405
Some(NonTerm::OrC) => term.reduce2(Terminal::OrC)?,
@@ -485,3 +495,10 @@ pub fn parse<Ctx: ScriptContext>(
485495
assert_eq!(term.0.len(), 1);
486496
Ok(term.pop().unwrap())
487497
}
498+
499+
fn is_and_v(tokens: &mut TokenIter) -> bool {
500+
match tokens.peek() {
501+
None | Some(&Tk::If) | Some(&Tk::NotIf) | Some(&Tk::Else) | Some(&Tk::ToAltStack) => false,
502+
_ => true,
503+
}
504+
}

src/miniscript/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,49 @@ mod tests {
752752
OP_PUSHBYTES_33 0289637f97580a796e050791ad5a2f27af1803645d95df021a3c2d82eb8c2ca7ff \
753753
OP_PUSHNUM_5 OP_CHECKMULTISIG)",
754754
);
755+
756+
roundtrip(
757+
&ms_str!(
758+
"t:and_v(\
759+
vu:hash256(131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b),\
760+
v:sha256(ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5)\
761+
)"),
762+
"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)"
763+
);
764+
roundtrip(
765+
&ms_str!("and_n(pk(03daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729),and_b(l:older(4252898),a:older(16)))"),
766+
"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)"
767+
);
768+
roundtrip(
769+
&ms_str!(
770+
"t:andor(multi(\
771+
3,\
772+
02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e,\
773+
03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,\
774+
02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13\
775+
),\
776+
v:older(4194305),\
777+
v:sha256(9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2)\
778+
)"),
779+
"Script(OP_PUSHNUM_3 OP_PUSHBYTES_33 02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e \
780+
OP_PUSHBYTES_33 03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556 \
781+
OP_PUSHBYTES_33 02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13 \
782+
OP_PUSHNUM_3 OP_CHECKMULTISIG OP_NOTIF OP_SIZE OP_PUSHBYTES_1 20 OP_EQUALVERIFY OP_SHA256 \
783+
OP_PUSHBYTES_32 9267d3dbed802941483f1afa2a6bc68de5f653128aca9bf1461c5d0a3ad36ed2 OP_EQUALVERIFY \
784+
OP_ELSE OP_PUSHBYTES_3 010040 OP_CSV OP_VERIFY OP_ENDIF OP_PUSHNUM_1)"
785+
);
786+
roundtrip(
787+
&ms_str!(
788+
"t:and_v(\
789+
vu:hash256(131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b),\
790+
v:sha256(ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5)\
791+
)"),
792+
"Script(\
793+
OP_IF OP_SIZE OP_PUSHBYTES_1 20 OP_EQUALVERIFY OP_HASH256 OP_PUSHBYTES_32 131772552c01444cd81360818376a040b7c3b2b7b0a53550ee3edde216cec61b OP_EQUAL \
794+
OP_ELSE OP_0 OP_ENDIF OP_VERIFY OP_SIZE OP_PUSHBYTES_1 20 OP_EQUALVERIFY OP_SHA256 OP_PUSHBYTES_32 ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5 OP_EQUALVERIFY \
795+
OP_PUSHNUM_1\
796+
)"
797+
);
755798
}
756799

757800
#[test]

0 commit comments

Comments
 (0)