@@ -10,6 +10,8 @@ use crate::serialization::{
1010 SigmaParsingError , SigmaSerializable ,
1111} ;
1212use crate :: sigma_protocol:: sigma_boolean:: ProveDlog ;
13+ use crate :: soft_fork:: IsSoftForkable ;
14+ use crate :: soft_fork:: SoftForkError ;
1315use crate :: types:: stype:: SType ;
1416
1517use alloc:: string:: String ;
@@ -107,9 +109,9 @@ pub enum ErgoTreeError {
107109 /// IO error
108110 #[ error( "IO error: {0:?}" ) ]
109111 IoError ( String ) ,
110- /// ErgoTree root error. ErgoTree root TPE should be SigmaProp
111- #[ error( "Root Tpe error: expected SigmaProp, got {0}" ) ]
112- RootTpeError ( SType ) ,
112+ /// Soft-fork error condition
113+ #[ error( "Soft fork error: {0}" ) ]
114+ SoftForkError ( SoftForkError ) ,
113115}
114116
115117/// The root of ErgoScript IR. Serialized instances of this class are self sufficient and can be passed around.
@@ -120,14 +122,14 @@ pub enum ErgoTree {
120122 /// Original tree bytes
121123 tree_bytes : Vec < u8 > ,
122124 /// Parsing error
123- error : ErgoTreeError ,
125+ error : SoftForkError ,
124126 } ,
125127 /// Parsed tree
126128 Parsed ( ParsedErgoTree ) ,
127129}
128130
129131impl ErgoTree {
130- fn parsed_tree ( & self ) -> Result < & ParsedErgoTree , ErgoTreeError > {
132+ fn parsed_tree ( & self ) -> Result < & ParsedErgoTree , SoftForkError > {
131133 match self {
132134 ErgoTree :: Unparsed {
133135 tree_bytes : _,
@@ -138,14 +140,14 @@ impl ErgoTree {
138140 }
139141
140142 /// Return ErgoTreeHeader. Errors if deserializing ergotree failed
141- pub fn header ( & self ) -> Result < ErgoTreeHeader , ErgoTreeError > {
143+ pub fn header ( & self ) -> Result < ErgoTreeHeader , SoftForkError > {
142144 self . parsed_tree ( ) . map ( |parsed| parsed. header . clone ( ) )
143145 }
144146
145147 fn sigma_parse_sized < R : SigmaByteRead > (
146148 r : & mut R ,
147149 header : ErgoTreeHeader ,
148- ) -> Result < ParsedErgoTree , ErgoTreeError > {
150+ ) -> Result < ParsedErgoTree , SigmaParsingError > {
149151 let constants = if header. is_constant_segregation ( ) {
150152 ErgoTree :: sigma_parse_constants ( r) ?
151153 } else {
@@ -159,7 +161,7 @@ impl ErgoTree {
159161 let has_deserialize = r. was_deserialize ( ) ;
160162 r. set_deserialize ( was_deserialize) ;
161163 if root. tpe ( ) != SType :: SSigmaProp {
162- return Err ( ErgoTreeError :: RootTpeError ( root . tpe ( ) ) ) ;
164+ return Err ( SoftForkError :: InvalidRootType . into ( ) ) ;
163165 }
164166 Ok ( ParsedErgoTree {
165167 header,
@@ -273,21 +275,21 @@ impl ErgoTree {
273275
274276 /// Returns constants number as stored in serialized ErgoTree or error if the parsing of
275277 /// constants is failed
276- pub fn constants_len ( & self ) -> Result < usize , ErgoTreeError > {
278+ pub fn constants_len ( & self ) -> Result < usize , SoftForkError > {
277279 self . parsed_tree ( ) . map ( |tree| tree. constants . len ( ) )
278280 }
279281
280282 /// Returns constant with given index (as stored in serialized ErgoTree)
281283 /// or None if index is out of bounds
282284 /// or error if constants parsing were failed
283- pub fn get_constant ( & self , index : usize ) -> Result < Option < Constant > , ErgoTreeError > {
285+ pub fn get_constant ( & self , index : usize ) -> Result < Option < Constant > , SoftForkError > {
284286 self . parsed_tree ( )
285287 . map ( |tree| tree. constants . get ( index) . cloned ( ) )
286288 }
287289
288290 /// Returns all constants (as stored in serialized ErgoTree)
289291 /// or error if constants parsing were failed
290- pub fn get_constants ( & self ) -> Result < Vec < Constant > , ErgoTreeError > {
292+ pub fn get_constants ( & self ) -> Result < Vec < Constant > , SoftForkError > {
291293 self . parsed_tree ( ) . map ( |tree| tree. constants . clone ( ) )
292294 }
293295
@@ -390,16 +392,18 @@ impl SigmaSerializable for ErgoTree {
390392 ErgoTree :: sigma_parse_sized ( inner_r, header)
391393 } ) {
392394 Ok ( parsed_tree) => Ok ( parsed_tree. into ( ) ) ,
393- Err ( error) => {
395+ Err ( error) if error . is_soft_fork ( ) => {
394396 let num_bytes = ( body_pos - start_pos) + tree_size_bytes as u64 ;
395397 r. seek ( io:: SeekFrom :: Start ( start_pos) ) ?;
396398 let mut bytes = vec ! [ 0 ; num_bytes as usize ] ;
397399 r. read_exact ( & mut bytes) ?;
398400 Ok ( ErgoTree :: Unparsed {
399401 tree_bytes : bytes,
400- error,
402+ #[ allow( clippy:: unwrap_used) ] // Error is checked to be soft fork condition above
403+ error : error. to_soft_fork ( ) . unwrap ( ) . clone ( ) ,
401404 } )
402405 }
406+ Err ( error) => Err ( error) ,
403407 }
404408 } else {
405409 let constants = if header. is_constant_segregation ( ) {
@@ -503,6 +507,7 @@ mod tests {
503507 use crate :: mir:: constant:: Literal ;
504508 use crate :: mir:: deserialize_context:: DeserializeContext ;
505509 use crate :: sigma_protocol:: sigma_boolean:: SigmaProp ;
510+ use crate :: soft_fork:: SoftForkError ;
506511 use proptest:: prelude:: * ;
507512
508513 proptest ! {
@@ -537,7 +542,9 @@ mod tests {
537542 ] ;
538543 assert_eq ! (
539544 ErgoTree :: sigma_parse_bytes( & bytes) ,
540- Err ( SigmaParsingError :: InvalidTypeCode ( 0 ) )
545+ Err ( SigmaParsingError :: SoftForkError (
546+ SoftForkError :: InvalidPrimitiveType ( 0 )
547+ ) )
541548 ) ;
542549 }
543550
@@ -696,7 +703,7 @@ mod tests {
696703 tree,
697704 ErgoTree :: Unparsed {
698705 tree_bytes,
699- error: ErgoTreeError :: RootTpeError ( SType :: SByte )
706+ error: SoftForkError :: InvalidRootType
700707 }
701708 ) ;
702709 }
@@ -725,7 +732,7 @@ mod tests {
725732 tree,
726733 ErgoTree :: Unparsed {
727734 tree_bytes: bytes,
728- error: ErgoTreeError :: RootTpeError ( SType :: SShort )
735+ error: SoftForkError :: InvalidRootType
729736 }
730737 ) ;
731738 }
0 commit comments