@@ -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