@@ -3,6 +3,7 @@ use scriptful::{
33 prelude:: Stack ,
44} ;
55use serde:: { Deserialize , Serialize } ;
6+ use std:: fmt:: Formatter ;
67use std:: marker:: PhantomData ;
78
89use witnet_crypto:: hash:: { calculate_sha256, Sha256 } ;
@@ -364,22 +365,41 @@ where
364365 }
365366}
366367
367- pub fn decode ( a : & [ u8 ] ) -> Script < MyOperator , MyValue > {
368- let x: Vec < Item2 < MyOperator , MyValue > > = serde_json:: from_slice ( a) . unwrap ( ) ;
368+ pub fn decode ( a : & [ u8 ] ) -> Result < Script < MyOperator , MyValue > , ScriptError > {
369+ let x: Vec < Item2 < MyOperator , MyValue > > =
370+ serde_json:: from_slice ( a) . map_err ( ScriptError :: Decode ) ?;
369371
370- x. into_iter ( ) . map ( Into :: into) . collect ( )
372+ Ok ( x. into_iter ( ) . map ( Into :: into) . collect ( ) )
371373}
372374
373- pub fn encode ( a : Script < MyOperator , MyValue > ) -> Vec < u8 > {
375+ pub fn encode ( a : Script < MyOperator , MyValue > ) -> Result < Vec < u8 > , ScriptError > {
374376 let x: Vec < Item2 < MyOperator , MyValue > > = a. into_iter ( ) . map ( Into :: into) . collect ( ) ;
375- serde_json:: to_vec ( & x) . unwrap ( )
377+
378+ serde_json:: to_vec ( & x) . map_err ( ScriptError :: Encode )
376379}
377380
378381#[ derive( Default ) ]
379382pub struct ScriptContext {
380383 pub block_timestamp : i64 ,
381384}
382385
386+ #[ derive( Debug ) ]
387+ pub enum ScriptError {
388+ Decode ( serde_json:: Error ) ,
389+ Encode ( serde_json:: Error ) ,
390+ }
391+
392+ impl std:: fmt:: Display for ScriptError {
393+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
394+ match self {
395+ ScriptError :: Decode ( e) => write ! ( f, "Decode script failed: {}" , e) ,
396+ ScriptError :: Encode ( e) => write ! ( f, "Encode script failed: {}" , e) ,
397+ }
398+ }
399+ }
400+
401+ impl std:: error:: Error for ScriptError { }
402+
383403fn execute_script ( script : Script < MyOperator , MyValue > , context : & ScriptContext ) -> bool {
384404 // Instantiate the machine with a reference to your operator system.
385405 let mut machine = Machine2 :: new ( |a, b, c| my_operator_system ( a, b, c, context) ) ;
@@ -411,26 +431,26 @@ fn execute_redeem_script(
411431 witness_bytes : & [ u8 ] ,
412432 redeem_bytes : & [ u8 ] ,
413433 context : & ScriptContext ,
414- ) -> bool {
434+ ) -> Result < bool , ScriptError > {
415435 // Execute witness script concatenated with redeem script
416- let mut witness_script = decode ( witness_bytes) ;
417- let redeem_script = decode ( redeem_bytes) ;
436+ let mut witness_script = decode ( witness_bytes) ? ;
437+ let redeem_script = decode ( redeem_bytes) ? ;
418438 witness_script. extend ( redeem_script) ;
419439
420440 // Execute the script
421- execute_script ( witness_script, context)
441+ Ok ( execute_script ( witness_script, context) )
422442}
423443
424444pub fn execute_complete_script (
425445 witness_bytes : & [ u8 ] ,
426446 redeem_bytes : & [ u8 ] ,
427447 locking_bytes : & [ u8 ; 20 ] ,
428448 context : & ScriptContext ,
429- ) -> bool {
449+ ) -> Result < bool , ScriptError > {
430450 // Execute locking script
431451 let result = execute_locking_script ( redeem_bytes, locking_bytes, context) ;
432452 if !result {
433- return false ;
453+ return Ok ( false ) ;
434454 }
435455
436456 // Execute witness script concatenated with redeem script
@@ -531,15 +551,15 @@ mod tests {
531551 let redeem_script = vec ! [ Item :: Operator ( MyOperator :: Equal ) ] ;
532552 let locking_script = EQUAL_OPERATOR_HASH ;
533553 assert ! ( execute_locking_script(
534- & encode( redeem_script) ,
554+ & encode( redeem_script) . unwrap ( ) ,
535555 & locking_script,
536556 & ScriptContext :: default ( ) ,
537557 ) ) ;
538558
539559 let redeem_script = vec ! [ Item :: Operator ( MyOperator :: Equal ) ] ;
540560 let locking_script = [ 1 ; 20 ] ;
541561 assert ! ( !execute_locking_script(
542- & encode( redeem_script) ,
562+ & encode( redeem_script) . unwrap ( ) ,
543563 & locking_script,
544564 & ScriptContext :: default ( ) ,
545565 ) ) ;
@@ -553,21 +573,23 @@ mod tests {
553573 ] ;
554574 let redeem_script = vec ! [ Item :: Operator ( MyOperator :: Equal ) ] ;
555575 assert ! ( execute_redeem_script(
556- & encode( witness) ,
557- & encode( redeem_script) ,
576+ & encode( witness) . unwrap ( ) ,
577+ & encode( redeem_script) . unwrap ( ) ,
558578 & ScriptContext :: default ( ) ,
559- ) ) ;
579+ )
580+ . unwrap( ) ) ;
560581
561582 let witness = vec ! [
562583 Item :: Value ( MyValue :: String ( "patata" . to_string( ) ) ) ,
563584 Item :: Value ( MyValue :: String ( "potato" . to_string( ) ) ) ,
564585 ] ;
565586 let redeem_script = vec ! [ Item :: Operator ( MyOperator :: Equal ) ] ;
566587 assert ! ( !execute_redeem_script(
567- & encode( witness) ,
568- & encode( redeem_script) ,
588+ & encode( witness) . unwrap ( ) ,
589+ & encode( redeem_script) . unwrap ( ) ,
569590 & ScriptContext :: default ( ) ,
570- ) ) ;
591+ )
592+ . unwrap( ) ) ;
571593 }
572594
573595 #[ test]
@@ -579,11 +601,12 @@ mod tests {
579601 let redeem_script = vec ! [ Item :: Operator ( MyOperator :: Equal ) ] ;
580602 let locking_script = EQUAL_OPERATOR_HASH ;
581603 assert ! ( execute_complete_script(
582- & encode( witness) ,
583- & encode( redeem_script) ,
604+ & encode( witness) . unwrap ( ) ,
605+ & encode( redeem_script) . unwrap ( ) ,
584606 & locking_script,
585607 & ScriptContext :: default ( ) ,
586- ) ) ;
608+ )
609+ . unwrap( ) ) ;
587610
588611 let witness = vec ! [
589612 Item :: Value ( MyValue :: String ( "patata" . to_string( ) ) ) ,
@@ -592,11 +615,12 @@ mod tests {
592615 let redeem_script = vec ! [ Item :: Operator ( MyOperator :: Equal ) ] ;
593616 let locking_script = EQUAL_OPERATOR_HASH ;
594617 assert ! ( !execute_complete_script(
595- & encode( witness) ,
596- & encode( redeem_script) ,
618+ & encode( witness) . unwrap ( ) ,
619+ & encode( redeem_script) . unwrap ( ) ,
597620 & locking_script,
598621 & ScriptContext :: default ( ) ,
599- ) ) ;
622+ )
623+ . unwrap( ) ) ;
600624
601625 let witness = vec ! [
602626 Item :: Value ( MyValue :: String ( "patata" . to_string( ) ) ) ,
@@ -605,11 +629,12 @@ mod tests {
605629 let redeem_script = vec ! [ Item :: Operator ( MyOperator :: Equal ) ] ;
606630 let locking_script: [ u8 ; 20 ] = [ 1 ; 20 ] ;
607631 assert ! ( !execute_complete_script(
608- & encode( witness) ,
609- & encode( redeem_script) ,
632+ & encode( witness) . unwrap ( ) ,
633+ & encode( redeem_script) . unwrap ( ) ,
610634 & locking_script,
611635 & ScriptContext :: default ( ) ,
612- ) ) ;
636+ )
637+ . unwrap( ) ) ;
613638 }
614639
615640 fn ks_from_pk ( pk : PublicKey ) -> KeyedSignature {
@@ -641,10 +666,11 @@ mod tests {
641666 Item :: Operator ( MyOperator :: CheckMultiSig ) ,
642667 ] ;
643668 assert ! ( execute_redeem_script(
644- & encode( witness) ,
645- & encode( redeem_script) ,
669+ & encode( witness) . unwrap ( ) ,
670+ & encode( redeem_script) . unwrap ( ) ,
646671 & ScriptContext :: default ( ) ,
647- ) ) ;
672+ )
673+ . unwrap( ) ) ;
648674
649675 let other_valid_witness = vec ! [
650676 Item :: Value ( MyValue :: Signature ( ks_1. to_pb_bytes( ) . unwrap( ) ) ) ,
@@ -659,10 +685,11 @@ mod tests {
659685 Item :: Operator ( MyOperator :: CheckMultiSig ) ,
660686 ] ;
661687 assert ! ( execute_redeem_script(
662- & encode( other_valid_witness) ,
663- & encode( redeem_script) ,
688+ & encode( other_valid_witness) . unwrap ( ) ,
689+ & encode( redeem_script) . unwrap ( ) ,
664690 & ScriptContext :: default ( ) ,
665- ) ) ;
691+ )
692+ . unwrap( ) ) ;
666693
667694 let pk_4 = PublicKey :: from_bytes ( [ 4 ; 33 ] ) ;
668695 let ks_4 = ks_from_pk ( pk_4) ;
@@ -679,10 +706,11 @@ mod tests {
679706 Item :: Operator ( MyOperator :: CheckMultiSig ) ,
680707 ] ;
681708 assert ! ( !execute_redeem_script(
682- & encode( invalid_witness) ,
683- & encode( redeem_script) ,
709+ & encode( invalid_witness) . unwrap ( ) ,
710+ & encode( redeem_script) . unwrap ( ) ,
684711 & ScriptContext :: default ( ) ,
685- ) ) ;
712+ )
713+ . unwrap( ) ) ;
686714 }
687715
688716 #[ test]
0 commit comments