Skip to content

Commit bd3fe4e

Browse files
committed
test: add unit tests which demonstrate problems fixed by the last commit
You can rebase this PR to move the unit tests in front of the fix, and you will see that they both fail.
1 parent 75dd206 commit bd3fe4e

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

src/node/construct.rs

+70
Original file line numberDiff line numberDiff line change
@@ -517,4 +517,74 @@ mod tests {
517517
.cmr()
518518
);
519519
}
520+
521+
#[test]
522+
fn regression_286_1() {
523+
// This is the smallest pure Simplicity program I was able to find that exhibits the bad
524+
// behavior seen in https://github.com/BlockstreamResearch/rust-simplicity/issues/286
525+
let ctx = types::Context::new();
526+
let cmr = Cmr::from_byte_array([0xde; 32]);
527+
528+
let u0 = Arc::<ConstructNode<Core>>::unit(&ctx);
529+
let i1 = Arc::<ConstructNode<Core>>::injl(&u0);
530+
let i2 = Arc::<ConstructNode<Core>>::injr(&i1);
531+
let i3 = Arc::<ConstructNode<Core>>::injr(&i2);
532+
let i4 = Arc::<ConstructNode<Core>>::injl(&i3);
533+
let u5 = Arc::<ConstructNode<Core>>::unit(&ctx);
534+
let i6 = Arc::<ConstructNode<Core>>::injl(&u5);
535+
let i7 = Arc::<ConstructNode<Core>>::injr(&i6);
536+
let p8 = Arc::<ConstructNode<Core>>::pair(&i4, &i7).unwrap();
537+
let u9 = Arc::<ConstructNode<Core>>::unit(&ctx);
538+
let a10 = Arc::<ConstructNode<Core>>::assertr(cmr, &u9).unwrap();
539+
let u11 = Arc::<ConstructNode<Core>>::unit(&ctx);
540+
let a12 = Arc::<ConstructNode<Core>>::assertr(cmr, &u11).unwrap();
541+
let a13 = Arc::<ConstructNode<Core>>::assertl(&a12, cmr).unwrap();
542+
let c14 = Arc::<ConstructNode<Core>>::case(&a10, &a13).unwrap();
543+
let c15 = Arc::<ConstructNode<Core>>::comp(&p8, &c14).unwrap();
544+
545+
let finalized: Arc<CommitNode<_>> = c15.finalize_types().unwrap();
546+
let prog = finalized.encode_to_vec();
547+
// In #286 we are encoding correctly...
548+
assert_eq!(
549+
hex::DisplayHex::as_hex(&prog).to_string(),
550+
"dc920a28812b6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f6f243090e00b10e00680",
551+
);
552+
553+
let prog = BitIter::from(prog);
554+
let decode = CommitNode::<Core>::decode(prog).unwrap();
555+
556+
// ...but then during decoding we read the program incorrectly and this assertion fails.
557+
assert_eq!(finalized, decode);
558+
}
559+
560+
#[test]
561+
fn regression_286_2() {
562+
use crate::types::Error as TypeError;
563+
use crate::Error;
564+
565+
// This one is smaller because it starts with a witness node which has a large type.
566+
// This is a bit easier to grok but can't be serialized as a complete/valid program
567+
// without providing the witness data, which limits its ability to share with the
568+
// other libraries.
569+
//
570+
// It also exhibits the bug earlier than the other one -- it *should* just fail to
571+
// typecheck and not be constructible. So we can't get an encoding of it.
572+
let ctx = types::Context::new();
573+
574+
let w0 = Arc::<ConstructNode<Core>>::witness(&ctx, None);
575+
let i1 = Arc::<ConstructNode<Core>>::iden(&ctx);
576+
let d2 = Arc::<ConstructNode<Core>>::drop_(&i1);
577+
let i3 = Arc::<ConstructNode<Core>>::iden(&ctx);
578+
let i4 = Arc::<ConstructNode<Core>>::iden(&ctx);
579+
let t5 = Arc::<ConstructNode<Core>>::take(&i4);
580+
let ca6 = Arc::<ConstructNode<Core>>::case(&i3, &t5).unwrap();
581+
let ca7 = Arc::<ConstructNode<Core>>::case(&d2, &ca6).unwrap();
582+
let c8 = Arc::<ConstructNode<Core>>::comp(&w0, &ca7).unwrap();
583+
let u9 = Arc::<ConstructNode<Core>>::unit(&ctx);
584+
let c10 = Arc::<ConstructNode<Core>>::comp(&c8, &u9).unwrap();
585+
586+
// In #286 we incorrectly succeed finalizing the types, and then encode a bad program.
587+
let err = c10.finalize_types().unwrap_err();
588+
assert!(matches!(err, Error::Type(TypeError::OccursCheck { .. })));
589+
}
520590
}

0 commit comments

Comments
 (0)