@@ -517,4 +517,74 @@ mod tests {
517
517
. cmr( )
518
518
) ;
519
519
}
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
+ }
520
590
}
0 commit comments