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