Skip to content

Commit 172c65d

Browse files
Add_support_for_pies_with_simulated_builtins
1 parent 9c44e1c commit 172c65d

File tree

3 files changed

+75
-18
lines changed

3 files changed

+75
-18
lines changed

vm/src/cairo_run.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ use crate::{
88
errors::{
99
cairo_run_errors::CairoRunError, runner_errors::RunnerError, vm_exception::VmException,
1010
},
11-
runners::{cairo_pie::CairoPie, cairo_runner::CairoRunner},
11+
runners::{
12+
builtin_runner::{EcOpBuiltinRunner, KeccakBuiltinRunner, SignatureBuiltinRunner},
13+
cairo_pie::CairoPie,
14+
cairo_runner::CairoRunner,
15+
},
1216
security::verify_secure_runner,
1317
},
1418
};
@@ -178,6 +182,31 @@ pub fn cairo_run_pie(
178182
let end = cairo_runner.initialize(allow_missing_builtins)?;
179183
cairo_runner.vm.finalize_segments_by_cairo_pie(pie);
180184
// Load builtin additional data
185+
for builtin_name in pie.metadata.simulated_builtins.iter() {
186+
match builtin_name {
187+
BuiltinName::ecdsa => {
188+
cairo_runner
189+
.vm
190+
.simulated_builtin_runners
191+
.push(SignatureBuiltinRunner::new(Some(1), false).into());
192+
}
193+
BuiltinName::keccak => {
194+
cairo_runner
195+
.vm
196+
.simulated_builtin_runners
197+
.push(KeccakBuiltinRunner::new(Some(1), false).into());
198+
}
199+
BuiltinName::ec_op => {
200+
cairo_runner
201+
.vm
202+
.simulated_builtin_runners
203+
.push(EcOpBuiltinRunner::new(Some(1), false).into());
204+
}
205+
_ => {
206+
panic!("Unsupported simulated builtin in Cairo PIE");
207+
}
208+
}
209+
}
181210
for (name, data) in pie.additional_data.0.iter() {
182211
// Data is not trusted in secure_run, therefore we skip extending the hash builtin's data
183212
if matches!(name, BuiltinName::pedersen) && secure_run {

vm/src/vm/runners/cairo_pie.rs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ pub struct CairoPieMetadata {
147147
#[serde(serialize_with = "serde_impl::serialize_builtin_segments")]
148148
pub builtin_segments: HashMap<BuiltinName, SegmentInfo>,
149149
pub extra_segments: Vec<SegmentInfo>,
150+
#[serde(default)]
151+
pub simulated_builtins: Vec<BuiltinName>,
150152
}
151153

152154
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
@@ -175,12 +177,11 @@ impl CairoPieMetadata {
175177
if self.program.data.len() != self.program_segment.size {
176178
return Err(CairoPieValidationError::ProgramLenVsSegmentSizeMismatch);
177179
}
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+
})
184185
{
185186
return Err(CairoPieValidationError::BuiltinListVsSegmentsMismatch);
186187
}
@@ -200,23 +201,32 @@ impl CairoPieMetadata {
200201
if !self.execution_segment.index.is_one() {
201202
return Err(CairoPieValidationError::InvalidExecutionSegmentIndex);
202203
}
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 {
206214
return Err(CairoPieValidationError::InvalidBuiltinSegmentIndex(
207215
*builtin_name,
208216
));
209217
}
218+
non_simulated_index += 1;
210219
}
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 {
213223
return Err(CairoPieValidationError::InvalidRetFpSegmentIndex);
214224
}
215-
if self.ret_pc_segment.index != n_builtins + 3 {
225+
if self.ret_pc_segment.index != n_builtin_segments + 3 {
216226
return Err(CairoPieValidationError::InvalidRetPcSegmentIndex);
217227
}
218228
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 {
220230
return Err(CairoPieValidationError::InvalidExtraSegmentIndex);
221231
}
222232
}
@@ -230,11 +240,13 @@ impl CairoPie {
230240
self.metadata.run_validity_checks()?;
231241
self.run_memory_validity_checks()?;
232242
if self.execution_resources.builtin_instance_counter.len()
243+
+ self.metadata.simulated_builtins.len()
233244
!= self.metadata.program.builtins.len()
234245
|| !self.metadata.program.builtins.iter().all(|b| {
235246
self.execution_resources
236247
.builtin_instance_counter
237248
.contains_key(b)
249+
|| self.metadata.simulated_builtins.contains(b)
238250
})
239251
{
240252
return Err(CairoPieValidationError::BuiltinListVsSegmentsMismatch);

vm/src/vm/runners/cairo_runner.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,18 +1405,34 @@ impl CairoRunner {
14051405
}
14061406
}
14071407

1408+
let stripped_program = self
1409+
.get_program()
1410+
.get_stripped_program()
1411+
.map_err(|_| RunnerError::StrippedProgramNoMain)?;
1412+
let mut simulated_builtins = self
1413+
.vm
1414+
.simulated_builtin_runners
1415+
.iter()
1416+
.map(|builtin| builtin.name())
1417+
.collect::<Vec<_>>();
1418+
// Sort the simulated builtins by their order in the program.
1419+
simulated_builtins.sort_by_key(|builtin| {
1420+
stripped_program
1421+
.builtins
1422+
.iter()
1423+
.position(|b| b == builtin)
1424+
.unwrap()
1425+
});
14081426
let execution_size = (self.vm.get_ap() - execution_base)?;
14091427
let metadata = CairoPieMetadata {
1410-
program: self
1411-
.get_program()
1412-
.get_stripped_program()
1413-
.map_err(|_| RunnerError::StrippedProgramNoMain)?,
1428+
program: stripped_program,
14141429
program_segment: (program_base.segment_index, self.program.data_len()).into(),
14151430
execution_segment: (execution_base.segment_index, execution_size).into(),
14161431
ret_fp_segment: (return_fp.segment_index, 0).into(),
14171432
ret_pc_segment: (return_pc.segment_index, 0).into(),
14181433
builtin_segments,
14191434
extra_segments,
1435+
simulated_builtins,
14201436
};
14211437

14221438
Ok(CairoPie {

0 commit comments

Comments
 (0)