sp1_core_machine/
executor.rs1use std::sync::Arc;
4
5use serde::{Deserialize, Serialize};
6use slop_algebra::PrimeField32;
7use sp1_core_executor::{events::MemoryRecord, ExecutionError, ExecutionRecord, SP1CoreOpts};
8use sp1_core_executor::{Program, TracingVMEnum};
9use sp1_hypercube::air::PROOF_NONCE_NUM_WORDS;
10use sp1_jit::MinimalTrace;
11use tracing::Level;
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct ExecutionOutput {
16 pub public_value_stream: Vec<u8>,
17 pub cycles: u64,
18}
19
20#[tracing::instrument(
25 level = Level::DEBUG,
26 name = "trace_chunk",
27 skip_all,
28)]
29pub fn trace_chunk<F: PrimeField32>(
30 program: Arc<Program>,
31 opts: SP1CoreOpts,
32 chunk: impl MinimalTrace,
33 proof_nonce: [u32; PROOF_NONCE_NUM_WORDS],
34 mut record: ExecutionRecord,
35) -> Result<(bool, ExecutionRecord, [MemoryRecord; 32]), ExecutionError> {
36 let mut vm = TracingVMEnum::new(&chunk, program, opts, proof_nonce, &mut record);
37 let status = vm.execute()?;
38 tracing::trace!("chunk ended at clk: {}", vm.clk());
39 tracing::trace!("chunk ended at pc: {}", vm.pc());
40
41 let pv = vm.public_values();
42
43 if status.is_shard_boundry() && (pv.commit_syscall == 1 || pv.commit_deferred_syscall == 1) {
44 tracing::trace!("commit syscall or commit deferred proofs across last two shards");
45
46 loop {
47 if vm.execute()?.is_done() {
48 let pv = *vm.public_values();
49
50 vm.record_mut().public_values.commit_syscall = 1;
51 vm.record_mut().public_values.commit_deferred_syscall = 1;
52 vm.record_mut().public_values.committed_value_digest = pv.committed_value_digest;
53 vm.record_mut().public_values.deferred_proofs_digest = pv.deferred_proofs_digest;
54
55 break;
56 }
57 }
58 }
59
60 vm.record_mut().finalize_public_values::<F>(true);
61
62 let registers = *vm.registers();
63 drop(vm);
64 Ok((status.is_done(), record, registers))
65}