pub struct VirtualMachine<E, VB>where
E: StarkEngine,
VB: VmBuilder<E>,{
pub engine: E,
/* private fields */
}Expand description
The VirtualMachine struct contains the API to generate proofs for arbitrary programs for a
fixed set of OpenVM instructions and a fixed VM circuit corresponding to those instructions. The
API is specific to a particular [StarkEngine], which specifies a fixed [StarkProtocolConfig] and
[ProverBackend] via associated types. The VmBuilder also fixes the choice of
RecordArena associated to the prover backend via an associated type.
In other words, this struct is the zkVM.
Fields§
§engine: EProving engine
Implementations§
Source§impl<E, VB> VirtualMachine<E, VB>where
E: StarkEngine,
VB: VmBuilder<E>,
impl<E, VB> VirtualMachine<E, VB>where
E: StarkEngine,
VB: VmBuilder<E>,
Source§impl<E, VB> VirtualMachine<E, VB>where
E: StarkEngine,
VB: VmBuilder<E>,
impl<E, VB> VirtualMachine<E, VB>where
E: StarkEngine,
VB: VmBuilder<E>,
Source§impl<E, VB> VirtualMachine<E, VB>where
E: StarkEngine,
VB: VmBuilder<E>,
impl<E, VB> VirtualMachine<E, VB>where
E: StarkEngine,
VB: VmBuilder<E>,
pub fn new( engine: E, builder: VB, config: VB::VmConfig, d_pk: DeviceMultiStarkProvingKey<E::PB>, ) -> Result<Self, VirtualMachineError>
pub fn new_with_keygen( engine: E, builder: VB, config: VB::VmConfig, ) -> Result<(Self, MultiStarkProvingKey<E::SC>), VirtualMachineError>
pub fn config(&self) -> &VB::VmConfig
Sourcepub fn interpreter(
&self,
exe: &VmExe<Val<E::SC>>,
) -> Result<InterpretedInstance<'_, Val<E::SC>, ExecutionCtx>, StaticProgramError>where
Val<E::SC>: PrimeField32,
<VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor: Executor<Val<E::SC>>,
pub fn interpreter(
&self,
exe: &VmExe<Val<E::SC>>,
) -> Result<InterpretedInstance<'_, Val<E::SC>, ExecutionCtx>, StaticProgramError>where
Val<E::SC>: PrimeField32,
<VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor: Executor<Val<E::SC>>,
Pure interpreter.
pub fn metered_interpreter(
&self,
exe: &VmExe<Val<E::SC>>,
) -> Result<InterpretedInstance<'_, Val<E::SC>, MeteredCtx>, StaticProgramError>where
Val<E::SC>: PrimeField32,
<VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor: MeteredExecutor<Val<E::SC>>,
pub fn metered_cost_interpreter(
&self,
exe: &VmExe<Val<E::SC>>,
) -> Result<InterpretedInstance<'_, Val<E::SC>, MeteredCostCtx>, StaticProgramError>where
Val<E::SC>: PrimeField32,
<VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor: MeteredExecutor<Val<E::SC>>,
pub fn preflight_interpreter( &self, exe: &VmExe<Val<E::SC>>, ) -> Result<PreflightInterpretedInstance<Val<E::SC>, <VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor>, StaticProgramError>
Sourcepub fn execute_preflight(
&self,
interpreter: &mut PreflightInterpretedInstance<Val<E::SC>, <VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor>,
state: VmState<Val<E::SC>, GuestMemory>,
num_insns: Option<u64>,
trace_heights: &[u32],
) -> Result<PreflightExecutionOutput<Val<E::SC>, VB::RecordArena>, ExecutionError>where
Val<E::SC>: PrimeField32,
<VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor: PreflightExecutor<Val<E::SC>, VB::RecordArena>,
pub fn execute_preflight(
&self,
interpreter: &mut PreflightInterpretedInstance<Val<E::SC>, <VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor>,
state: VmState<Val<E::SC>, GuestMemory>,
num_insns: Option<u64>,
trace_heights: &[u32],
) -> Result<PreflightExecutionOutput<Val<E::SC>, VB::RecordArena>, ExecutionError>where
Val<E::SC>: PrimeField32,
<VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor: PreflightExecutor<Val<E::SC>, VB::RecordArena>,
Preflight execution for a single segment. Executes for exactly num_insns instructions
using an interpreter. Preflight execution must be provided with trace_heights
instrumentation data that was collected from a previous run of metered execution so that the
preflight execution knows how much memory to allocate for record arenas.
This function should rarely be called on its own. Users are advised to call
prove directly.
Sourcepub fn create_initial_state(
&self,
exe: &VmExe<Val<E::SC>>,
inputs: impl Into<Streams<Val<E::SC>>>,
) -> VmState<Val<E::SC>, GuestMemory>
pub fn create_initial_state( &self, exe: &VmExe<Val<E::SC>>, inputs: impl Into<Streams<Val<E::SC>>>, ) -> VmState<Val<E::SC>, GuestMemory>
Calls VmState::initial but sets more information for
performance metrics when feature “perf-metrics” is enabled.
Sourcepub fn generate_proving_ctx(
&mut self,
system_records: SystemRecords<Val<E::SC>>,
record_arenas: Vec<VB::RecordArena>,
) -> Result<ProvingContext<E::PB>, GenerationError>
pub fn generate_proving_ctx( &mut self, system_records: SystemRecords<Val<E::SC>>, record_arenas: Vec<VB::RecordArena>, ) -> Result<ProvingContext<E::PB>, GenerationError>
This function mutates self but should only depend on internal state in the sense that:
- program must already be loaded as cached trace via
load_program. - initial memory image was already sent to device via
transport_init_memory_to_device. - all other state should be given by
system_recordsandrecord_arenas
Sourcepub fn prove(
&mut self,
interpreter: &mut PreflightInterpretedInstance<Val<E::SC>, <VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor>,
state: VmState<Val<E::SC>, GuestMemory>,
num_insns: Option<u64>,
trace_heights: &[u32],
) -> Result<(Proof<E::SC>, Option<GuestMemory>), VirtualMachineError>where
Val<E::SC>: PrimeField32,
<VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor: PreflightExecutor<Val<E::SC>, VB::RecordArena>,
pub fn prove(
&mut self,
interpreter: &mut PreflightInterpretedInstance<Val<E::SC>, <VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor>,
state: VmState<Val<E::SC>, GuestMemory>,
num_insns: Option<u64>,
trace_heights: &[u32],
) -> Result<(Proof<E::SC>, Option<GuestMemory>), VirtualMachineError>where
Val<E::SC>: PrimeField32,
<VB::VmConfig as VmExecutionConfig<Val<E::SC>>>::Executor: PreflightExecutor<Val<E::SC>, VB::RecordArena>,
Generates proof for zkVM execution for exactly num_insns instructions for a given program
and a given starting state.
Note: The cached program trace must be loaded via load_program
before calling this function.
Returns:
- proof for the execution segment
- final memory state only if execution ends in successful termination (exit code 0). This final memory state may be used to extract user public values afterwards.
Sourcepub fn commit_program_on_device(
&self,
program: &Program<Val<E::SC>>,
) -> CommittedTraceData<E::PB>
pub fn commit_program_on_device( &self, program: &Program<Val<E::SC>>, ) -> CommittedTraceData<E::PB>
Transforms the program into a cached trace and commits it on device using the proof system polynomial commitment scheme.
Returns the cached program trace.
Note that load_program must be called separately to load the cached
program trace into the VM itself.
Sourcepub fn load_program(&mut self, cached_program_trace: CommittedTraceData<E::PB>)
pub fn load_program(&mut self, cached_program_trace: CommittedTraceData<E::PB>)
Loads cached program trace into the VM.
pub fn transport_init_memory_to_device(&mut self, memory: &GuestMemory)
Sourcepub fn memory_top_tree(&self) -> Option<&[[Val<E::SC>; 8]]>
pub fn memory_top_tree(&self) -> Option<&[[Val<E::SC>; 8]]>
pub fn executor_idx_to_air_idx(&self) -> Vec<usize>
Sourcepub fn build_metered_ctx(&self, exe: &VmExe<Val<E::SC>>) -> MeteredCtxwhere
Val<E::SC>: PrimeField32,
pub fn build_metered_ctx(&self, exe: &VmExe<Val<E::SC>>) -> MeteredCtxwhere
Val<E::SC>: PrimeField32,
Convenience method to construct a MeteredCtx using data from the stored proving key.
Sourcepub fn build_metered_cost_ctx(&self) -> MeteredCostCtx
pub fn build_metered_cost_ctx(&self) -> MeteredCostCtx
Convenience method to construct a MeteredCostCtx using data from the stored proving key.
pub fn num_airs(&self) -> usize
pub fn air_names(&self) -> impl Iterator<Item = &str>
Source§impl<E, VC> VirtualMachine<E, VC>
impl<E, VC> VirtualMachine<E, VC>
Sourcepub fn override_system_trace_heights(&mut self, heights: &[u32])
pub fn override_system_trace_heights(&mut self, heights: &[u32])
Sets fixed trace heights for the system AIRs’ trace matrices.
Auto Trait Implementations§
impl<E, VB> Freeze for VirtualMachine<E, VB>
impl<E, VB> !RefUnwindSafe for VirtualMachine<E, VB>
impl<E, VB> !Send for VirtualMachine<E, VB>
impl<E, VB> !Sync for VirtualMachine<E, VB>
impl<E, VB> Unpin for VirtualMachine<E, VB>where
E: Unpin,
<VB as VmBuilder<E>>::VmConfig: Unpin,
<<E as StarkEngine>::SC as StarkProtocolConfig>::Digest: Unpin,
<VB as VmBuilder<E>>::SystemChipInventory: Unpin,
<<E as StarkEngine>::SC as StarkProtocolConfig>::F: Unpin,
<<E as StarkEngine>::PB as ProverBackend>::OtherAirData: Unpin,
<<E as StarkEngine>::PB as ProverBackend>::Matrix: Unpin,
impl<E, VB> !UnwindSafe for VirtualMachine<E, VB>
Blanket Implementations§
§impl<T> AlignerFor<1> for T
impl<T> AlignerFor<1> for T
§impl<T> AlignerFor<1024> for T
impl<T> AlignerFor<1024> for T
§impl<T> AlignerFor<128> for T
impl<T> AlignerFor<128> for T
§impl<T> AlignerFor<16> for T
impl<T> AlignerFor<16> for T
§impl<T> AlignerFor<16384> for T
impl<T> AlignerFor<16384> for T
§impl<T> AlignerFor<2> for T
impl<T> AlignerFor<2> for T
§impl<T> AlignerFor<2048> for T
impl<T> AlignerFor<2048> for T
§impl<T> AlignerFor<256> for T
impl<T> AlignerFor<256> for T
§impl<T> AlignerFor<32> for T
impl<T> AlignerFor<32> for T
§impl<T> AlignerFor<32768> for T
impl<T> AlignerFor<32768> for T
§impl<T> AlignerFor<4> for T
impl<T> AlignerFor<4> for T
§impl<T> AlignerFor<4096> for T
impl<T> AlignerFor<4096> for T
§impl<T> AlignerFor<512> for T
impl<T> AlignerFor<512> for T
§impl<T> AlignerFor<64> for T
impl<T> AlignerFor<64> for T
§impl<T> AlignerFor<8> for T
impl<T> AlignerFor<8> for T
§impl<T> AlignerFor<8192> for T
impl<T> AlignerFor<8192> for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<S> ROExtAcc for S
impl<S> ROExtAcc for S
§fn f_get<F>(&self, offset: FieldOffset<S, F, Aligned>) -> &F
fn f_get<F>(&self, offset: FieldOffset<S, F, Aligned>) -> &F
offset. Read more§fn f_get_mut<F>(&mut self, offset: FieldOffset<S, F, Aligned>) -> &mut F
fn f_get_mut<F>(&mut self, offset: FieldOffset<S, F, Aligned>) -> &mut F
offset. Read more§fn f_get_ptr<F, A>(&self, offset: FieldOffset<S, F, A>) -> *const F
fn f_get_ptr<F, A>(&self, offset: FieldOffset<S, F, A>) -> *const F
offset. Read more§fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<S, F, A>) -> *mut F
fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<S, F, A>) -> *mut F
offset. Read more§impl<S> ROExtOps<Aligned> for S
impl<S> ROExtOps<Aligned> for S
§fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Aligned>, value: F) -> F
fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Aligned>, value: F) -> F
offset) with value,
returning the previous value of the field. Read more§fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Aligned>) -> Fwhere
F: Copy,
fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Aligned>) -> Fwhere
F: Copy,
§impl<S> ROExtOps<Unaligned> for S
impl<S> ROExtOps<Unaligned> for S
§fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Unaligned>, value: F) -> F
fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Unaligned>, value: F) -> F
offset) with value,
returning the previous value of the field. Read more§fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Unaligned>) -> Fwhere
F: Copy,
fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Unaligned>) -> Fwhere
F: Copy,
§impl<T> SelfOps for Twhere
T: ?Sized,
impl<T> SelfOps for Twhere
T: ?Sized,
§fn piped<F, U>(self, f: F) -> U
fn piped<F, U>(self, f: F) -> U
§fn piped_ref<'a, F, U>(&'a self, f: F) -> Uwhere
F: FnOnce(&'a Self) -> U,
fn piped_ref<'a, F, U>(&'a self, f: F) -> Uwhere
F: FnOnce(&'a Self) -> U,
piped except that the function takes &Self
Useful for functions that take &Self instead of Self. Read more§fn piped_mut<'a, F, U>(&'a mut self, f: F) -> Uwhere
F: FnOnce(&'a mut Self) -> U,
fn piped_mut<'a, F, U>(&'a mut self, f: F) -> Uwhere
F: FnOnce(&'a mut Self) -> U,
piped, except that the function takes &mut Self.
Useful for functions that take &mut Self instead of Self.§fn mutated<F>(self, f: F) -> Self
fn mutated<F>(self, f: F) -> Self
§fn observe<F>(self, f: F) -> Self
fn observe<F>(self, f: F) -> Self
§fn as_ref_<T>(&self) -> &T
fn as_ref_<T>(&self) -> &T
AsRef,
using the turbofish .as_ref_::<_>() syntax. Read more§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.