Skip to content

Commit e55ef58

Browse files
committed
Fix decoding up; cleanup code
1 parent 5048df6 commit e55ef58

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

src/miniscript/decode.rs

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ mod private {
9898
#[derive(Copy, Clone, Debug)]
9999
enum NonTerm {
100100
Expression,
101-
MaybeSwap,
101+
WExpression,
102+
Swap,
102103
MaybeAndV,
103104
Alt,
104105
Check,
@@ -208,6 +209,7 @@ macro_rules! match_token {
208209
}
209210

210211
///Vec representing terminals stack while decoding.
212+
#[derive(Debug)]
211213
struct TerminalStack<Pk: MiniscriptKey, Ctx: ScriptContext>(Vec<Miniscript<Pk, Ctx>>);
212214

213215
impl<Pk: MiniscriptKey, Ctx: ScriptContext> TerminalStack<Pk, Ctx> {
@@ -284,8 +286,8 @@ pub fn parse<Ctx: ScriptContext>(
284286
let mut non_term = Vec::with_capacity(tokens.len());
285287
let mut term = TerminalStack(Vec::with_capacity(tokens.len()));
286288

289+
// top level cannot be swap, must be B
287290
non_term.push(NonTerm::MaybeAndV);
288-
non_term.push(NonTerm::MaybeSwap);
289291
non_term.push(NonTerm::Expression);
290292
loop {
291293
match non_term.pop() {
@@ -439,34 +441,24 @@ pub fn parse<Ctx: ScriptContext>(
439441
// `OP_ADD` or not and do the right thing
440442
},
441443
),
442-
// fromaltstack
443-
Tk::FromAltStack => {
444-
non_term.push(NonTerm::Alt);
445-
non_term.push(NonTerm::MaybeAndV);
446-
non_term.push(NonTerm::MaybeSwap);
447-
non_term.push(NonTerm::Expression);
448-
},
449444
// most other fragments
450445
Tk::Num(0) => term.reduce0(Terminal::False)?,
451446
Tk::Num(1) => term.reduce0(Terminal::True)?,
452447
Tk::EndIf => {
453448
non_term.push(NonTerm::EndIf);
454449
non_term.push(NonTerm::MaybeAndV);
455-
non_term.push(NonTerm::MaybeSwap);
456450
non_term.push(NonTerm::Expression);
457451
},
458452
// boolean conjunctions and disjunctions
459453
Tk::BoolAnd => {
460454
non_term.push(NonTerm::AndB);
461455
non_term.push(NonTerm::Expression);
462-
non_term.push(NonTerm::MaybeSwap);
463-
non_term.push(NonTerm::Expression);
456+
non_term.push(NonTerm::WExpression);
464457
},
465458
Tk::BoolOr => {
466459
non_term.push(NonTerm::OrB);
467460
non_term.push(NonTerm::Expression);
468-
non_term.push(NonTerm::MaybeSwap);
469-
non_term.push(NonTerm::Expression);
461+
non_term.push(NonTerm::WExpression);
470462
},
471463
// CHECKMULTISIG based multisig
472464
Tk::CheckMultiSig, Tk::Num(n) => {
@@ -522,15 +514,14 @@ pub fn parse<Ctx: ScriptContext>(
522514
non_term.push(NonTerm::Expression);
523515
}
524516
}
525-
Some(NonTerm::MaybeSwap) => {
517+
Some(NonTerm::Swap) => {
526518
// Handle `SWAP` prefixing
527-
if let Some(&Tk::Swap) = tokens.peek() {
528-
tokens.next();
529-
// let top = term.pop().unwrap();
530-
term.reduce1(Terminal::Swap)?;
531-
// term.push(Terminal::Swap(Arc::new(top)));
532-
non_term.push(NonTerm::MaybeSwap);
533-
}
519+
match_token!(
520+
tokens,
521+
Tk::Swap => {},
522+
);
523+
term.reduce1(Terminal::Swap)?;
524+
// Swap must be always be terminating a NonTerm as it cannot be in and_v
534525
}
535526
Some(NonTerm::Alt) => {
536527
match_token!(
@@ -577,14 +568,14 @@ pub fn parse<Ctx: ScriptContext>(
577568
tokens,
578569
Tk::Add => {
579570
non_term.push(NonTerm::ThreshW { n: n + 1, k });
571+
non_term.push(NonTerm::WExpression);
580572
},
581573
x => {
582574
tokens.un_next(x);
583575
non_term.push(NonTerm::ThreshE { n: n + 1, k });
576+
non_term.push(NonTerm::Expression);
584577
},
585578
);
586-
non_term.push(NonTerm::MaybeSwap);
587-
non_term.push(NonTerm::Expression);
588579
}
589580
Some(NonTerm::ThreshE { n, k }) => {
590581
let mut subs = Vec::with_capacity(n);
@@ -599,7 +590,6 @@ pub fn parse<Ctx: ScriptContext>(
599590
Tk::Else => {
600591
non_term.push(NonTerm::EndIfElse);
601592
non_term.push(NonTerm::MaybeAndV);
602-
non_term.push(NonTerm::MaybeSwap);
603593
non_term.push(NonTerm::Expression);
604594
},
605595
Tk::If => match_token!(
@@ -636,6 +626,14 @@ pub fn parse<Ctx: ScriptContext>(
636626
},
637627
);
638628
}
629+
Some(NonTerm::WExpression) => {
630+
// W expression must be either from swap or Fromaltstack
631+
match_token!(tokens,
632+
Tk::FromAltStack => { non_term.push(NonTerm::Alt);},
633+
tok => { tokens.un_next(tok); non_term.push(NonTerm::Swap);},);
634+
non_term.push(NonTerm::MaybeAndV);
635+
non_term.push(NonTerm::Expression);
636+
}
639637
None => {
640638
// Done :)
641639
break;
@@ -650,7 +648,12 @@ pub fn parse<Ctx: ScriptContext>(
650648

651649
fn is_and_v(tokens: &mut TokenIter) -> bool {
652650
match tokens.peek() {
653-
None | Some(&Tk::If) | Some(&Tk::NotIf) | Some(&Tk::Else) | Some(&Tk::ToAltStack) => false,
651+
None
652+
| Some(&Tk::If)
653+
| Some(&Tk::NotIf)
654+
| Some(&Tk::Else)
655+
| Some(&Tk::ToAltStack)
656+
| Some(&Tk::Swap) => false,
654657
_ => true,
655658
}
656659
}

0 commit comments

Comments
 (0)