@@ -83,8 +83,8 @@ pub struct CompiledClass {
83
83
/// Represents the structure of the bytecode segments, using a nested list of segment lengths.
84
84
/// For example, [2, [3, 4]] represents a bytecode with 2 segments, the first is a leaf of
85
85
/// length 2 and the second is a node with 2 children of lengths 3 and 4.
86
- #[ serde( default , skip_serializing_if = "Vec::is_empty " ) ]
87
- pub bytecode_segment_lengths : Vec < IntOrList > ,
86
+ #[ serde( default , skip_serializing_if = "Option::is_none " ) ]
87
+ pub bytecode_segment_lengths : Option < IntOrList > ,
88
88
/// Hints for non-determinism.
89
89
pub hints : Vec < Hint > ,
90
90
/// Same as `hints` but represented in Python code, which can be generated by the compiler but
@@ -658,42 +658,45 @@ impl CompiledClass {
658
658
) ;
659
659
660
660
// Hashes bytecode
661
- hasher. update ( if self . bytecode_segment_lengths . is_empty ( ) {
662
- // Pre-Sierra-1.5.0 compiled classes
663
- poseidon_hash_many ( & self . bytecode )
664
- } else {
665
- // `bytecode_segment_lengths` was added since Sierra 1.5.0 and changed hash calculation.
666
- // This implementation here is basically a direct translation of the Python code from
667
- // `cairo-lang` v0.13.1. The goal was simply to have a working implementation as quickly
668
- // as possible. There should be some optimizations to be made here.
669
- // TODO: review how this can be optimized
670
-
671
- // NOTE: this looks extremely inefficient. Maybe just use a number for tracking instead?
672
- let mut rev_visited_pcs: Vec < u64 > = ( 0 ..( self . bytecode . len ( ) as u64 ) ) . rev ( ) . collect ( ) ;
673
-
674
- let ( res, total_len) = Self :: create_bytecode_segment_structure_inner (
675
- & self . bytecode ,
676
- & IntOrList :: List ( self . bytecode_segment_lengths . clone ( ) ) ,
677
- & mut rev_visited_pcs,
678
- & mut 0 ,
679
- ) ?;
680
-
681
- if total_len != self . bytecode . len ( ) as u64 {
682
- return Err ( ComputeClassHashError :: BytecodeSegmentLengthMismatch (
683
- BytecodeSegmentLengthMismatchError {
684
- segment_length : total_len as usize ,
685
- bytecode_length : self . bytecode . len ( ) ,
686
- } ,
687
- ) ) ;
688
- }
689
- if !rev_visited_pcs. is_empty ( ) {
690
- return Err ( ComputeClassHashError :: PcOutOfRange ( PcOutOfRangeError {
691
- pc : rev_visited_pcs[ rev_visited_pcs. len ( ) - 1 ] ,
692
- } ) ) ;
693
- }
661
+ hasher. update (
662
+ if let Some ( bytecode_segment_lengths) = self . bytecode_segment_lengths . clone ( ) {
663
+ // `bytecode_segment_lengths` was added since Sierra 1.5.0 and changed hash calculation.
664
+ // This implementation here is basically a direct translation of the Python code from
665
+ // `cairo-lang` v0.13.1. The goal was simply to have a working implementation as quickly
666
+ // as possible. There should be some optimizations to be made here.
667
+ // TODO: review how this can be optimized
668
+
669
+ // NOTE: this looks extremely inefficient. Maybe just use a number for tracking instead?
670
+ let mut rev_visited_pcs: Vec < u64 > =
671
+ ( 0 ..( self . bytecode . len ( ) as u64 ) ) . rev ( ) . collect ( ) ;
672
+
673
+ let ( res, total_len) = Self :: create_bytecode_segment_structure_inner (
674
+ & self . bytecode ,
675
+ & bytecode_segment_lengths,
676
+ & mut rev_visited_pcs,
677
+ & mut 0 ,
678
+ ) ?;
679
+
680
+ if total_len != self . bytecode . len ( ) as u64 {
681
+ return Err ( ComputeClassHashError :: BytecodeSegmentLengthMismatch (
682
+ BytecodeSegmentLengthMismatchError {
683
+ segment_length : total_len as usize ,
684
+ bytecode_length : self . bytecode . len ( ) ,
685
+ } ,
686
+ ) ) ;
687
+ }
688
+ if !rev_visited_pcs. is_empty ( ) {
689
+ return Err ( ComputeClassHashError :: PcOutOfRange ( PcOutOfRangeError {
690
+ pc : rev_visited_pcs[ rev_visited_pcs. len ( ) - 1 ] ,
691
+ } ) ) ;
692
+ }
694
693
695
- res. hash ( )
696
- } ) ;
694
+ res. hash ( )
695
+ } else {
696
+ // Pre-Sierra-1.5.0 compiled classes
697
+ poseidon_hash_many ( & self . bytecode )
698
+ } ,
699
+ ) ;
697
700
698
701
Ok ( hasher. finalize ( ) )
699
702
}
@@ -1022,6 +1025,7 @@ mod tests {
1022
1025
include_str ! ( "../../../test-data/contracts/cairo2/artifacts/abi_types_sierra.txt" ) ,
1023
1026
include_str ! ( "../../../test-data/contracts/cairo2/artifacts/erc20_sierra.txt" ) ,
1024
1027
include_str ! ( "../../../test-data/contracts/cairo2.6/artifacts/erc20_sierra.txt" ) ,
1028
+ include_str ! ( "../../../test-data/contracts/cairo2.6/artifacts/trivial_sierra.txt" ) ,
1025
1029
] {
1026
1030
let direct_deser = serde_json:: from_str :: < SierraClass > ( raw_artifact) . unwrap ( ) ;
1027
1031
let via_contract_artifact = match serde_json:: from_str :: < ContractArtifact > ( raw_artifact)
@@ -1047,6 +1051,7 @@ mod tests {
1047
1051
include_str ! ( "../../../test-data/contracts/cairo2/artifacts/abi_types_compiled.txt" ) ,
1048
1052
include_str ! ( "../../../test-data/contracts/cairo2/artifacts/erc20_compiled.txt" ) ,
1049
1053
include_str ! ( "../../../test-data/contracts/cairo2.6/artifacts/erc20_compiled.txt" ) ,
1054
+ include_str ! ( "../../../test-data/contracts/cairo2.6/artifacts/trivial_compiled.txt" ) ,
1050
1055
] {
1051
1056
let direct_deser = serde_json:: from_str :: < CompiledClass > ( raw_artifact) . unwrap ( ) ;
1052
1057
let via_contract_artifact = match serde_json:: from_str :: < ContractArtifact > ( raw_artifact)
@@ -1133,6 +1138,12 @@ mod tests {
1133
1138
include_str ! ( "../../../test-data/contracts/cairo2.6/artifacts/erc20_compiled.txt" ) ,
1134
1139
include_str ! ( "../../../test-data/contracts/cairo2.6/artifacts/erc20.hashes.json" ) ,
1135
1140
) ,
1141
+ (
1142
+ include_str ! (
1143
+ "../../../test-data/contracts/cairo2.6/artifacts/trivial_compiled.txt"
1144
+ ) ,
1145
+ include_str ! ( "../../../test-data/contracts/cairo2.6/artifacts/trivial.hashes.json" ) ,
1146
+ ) ,
1136
1147
] {
1137
1148
let compiled_class = serde_json:: from_str :: < CompiledClass > ( raw_artifact) . unwrap ( ) ;
1138
1149
let computed_hash = compiled_class. class_hash ( ) . unwrap ( ) ;
0 commit comments