@@ -147,6 +147,8 @@ pub struct CairoPieMetadata {
147
147
#[ serde( serialize_with = "serde_impl::serialize_builtin_segments" ) ]
148
148
pub builtin_segments : HashMap < BuiltinName , SegmentInfo > ,
149
149
pub extra_segments : Vec < SegmentInfo > ,
150
+ #[ serde( default ) ]
151
+ pub simulated_builtins : Vec < BuiltinName > ,
150
152
}
151
153
152
154
#[ derive( Serialize , Deserialize , Clone , Debug , PartialEq , Eq ) ]
@@ -175,12 +177,11 @@ impl CairoPieMetadata {
175
177
if self . program . data . len ( ) != self . program_segment . size {
176
178
return Err ( CairoPieValidationError :: ProgramLenVsSegmentSizeMismatch ) ;
177
179
}
178
- if self . builtin_segments . len ( ) != self . program . builtins . len ( )
179
- || !self
180
- . program
181
- . builtins
182
- . iter ( )
183
- . all ( |b| self . builtin_segments . contains_key ( b) )
180
+ if self . builtin_segments . len ( ) + self . simulated_builtins . len ( )
181
+ != self . program . builtins . len ( )
182
+ || !self . program . builtins . iter ( ) . all ( |b| {
183
+ self . builtin_segments . contains_key ( b) || self . simulated_builtins . contains ( b)
184
+ } )
184
185
{
185
186
return Err ( CairoPieValidationError :: BuiltinListVsSegmentsMismatch ) ;
186
187
}
@@ -200,23 +201,32 @@ impl CairoPieMetadata {
200
201
if !self . execution_segment . index . is_one ( ) {
201
202
return Err ( CairoPieValidationError :: InvalidExecutionSegmentIndex ) ;
202
203
}
203
- for ( i, builtin_name) in self . program . builtins . iter ( ) . enumerate ( ) {
204
- // We can safely index as run_validity_checks already ensures that the keys match
205
- if self . builtin_segments [ builtin_name] . index != 2 + i as isize {
204
+ let mut non_simulated_index = 0 ;
205
+ for builtin_name in self . program . builtins . iter ( ) {
206
+ // We can safely index as run_validity_checks already ensures that the keys match,
207
+ // to either a builtin_segments key or a simulated_builtins key.
208
+ // If the builtin is simulated, skip processing without incrementing non_simulated_index.
209
+ if self . simulated_builtins . contains ( builtin_name) {
210
+ continue ;
211
+ }
212
+
213
+ if self . builtin_segments [ builtin_name] . index != 2 + non_simulated_index as isize {
206
214
return Err ( CairoPieValidationError :: InvalidBuiltinSegmentIndex (
207
215
* builtin_name,
208
216
) ) ;
209
217
}
218
+ non_simulated_index += 1 ;
210
219
}
211
- let n_builtins = self . program . builtins . len ( ) as isize ;
212
- if self . ret_fp_segment . index != n_builtins + 2 {
220
+ let n_builtin_segments =
221
+ ( self . program . builtins . len ( ) - self . simulated_builtins . len ( ) ) as isize ;
222
+ if self . ret_fp_segment . index != n_builtin_segments + 2 {
213
223
return Err ( CairoPieValidationError :: InvalidRetFpSegmentIndex ) ;
214
224
}
215
- if self . ret_pc_segment . index != n_builtins + 3 {
225
+ if self . ret_pc_segment . index != n_builtin_segments + 3 {
216
226
return Err ( CairoPieValidationError :: InvalidRetPcSegmentIndex ) ;
217
227
}
218
228
for ( i, segment) in self . extra_segments . iter ( ) . enumerate ( ) {
219
- if segment. index != 4 + n_builtins + i as isize {
229
+ if segment. index != 4 + n_builtin_segments + i as isize {
220
230
return Err ( CairoPieValidationError :: InvalidExtraSegmentIndex ) ;
221
231
}
222
232
}
@@ -230,11 +240,13 @@ impl CairoPie {
230
240
self . metadata . run_validity_checks ( ) ?;
231
241
self . run_memory_validity_checks ( ) ?;
232
242
if self . execution_resources . builtin_instance_counter . len ( )
243
+ + self . metadata . simulated_builtins . len ( )
233
244
!= self . metadata . program . builtins . len ( )
234
245
|| !self . metadata . program . builtins . iter ( ) . all ( |b| {
235
246
self . execution_resources
236
247
. builtin_instance_counter
237
248
. contains_key ( b)
249
+ || self . metadata . simulated_builtins . contains ( b)
238
250
} )
239
251
{
240
252
return Err ( CairoPieValidationError :: BuiltinListVsSegmentsMismatch ) ;
0 commit comments