use alloc::sync::Arc;
use core::ops::ControlFlow;
use miden_air::trace::{RowIndex, chiplets::hasher::HasherState};
use crate::{
BreakReason, ContextId, ExecutionError, Felt, Host, MemoryError, Word,
advice::AdviceError,
crypto::merkle::MerklePath,
errors::OperationError,
mast::{BasicBlockNode, MastForest, MastNodeId},
precompile::PrecompileTranscriptState,
};
pub(crate) trait Processor: Sized {
type System: SystemInterface;
type Stack: StackInterface;
type AdviceProvider: AdviceProviderInterface;
type Memory: MemoryInterface;
type Hasher: HasherInterface;
fn stack(&self) -> &Self::Stack;
fn stack_mut(&mut self) -> &mut Self::Stack;
fn system(&self) -> &Self::System;
fn system_mut(&mut self) -> &mut Self::System;
fn advice_provider(&self) -> &Self::AdviceProvider;
fn advice_provider_mut(&mut self) -> &mut Self::AdviceProvider;
fn memory_mut(&mut self) -> &mut Self::Memory;
fn hasher(&mut self) -> &mut Self::Hasher;
fn save_context_and_truncate_stack(&mut self);
fn restore_context(&mut self) -> Result<(), OperationError>;
fn precompile_transcript_state(&self) -> PrecompileTranscriptState;
fn set_precompile_transcript_state(&mut self, state: PrecompileTranscriptState);
fn execute_before_enter_decorators(
&self,
node_id: MastNodeId,
current_forest: &MastForest,
host: &mut impl Host,
) -> ControlFlow<BreakReason>;
fn execute_after_exit_decorators(
&self,
node_id: MastNodeId,
current_forest: &MastForest,
host: &mut impl Host,
) -> ControlFlow<BreakReason>;
fn execute_decorators_for_op(
&self,
node_id: MastNodeId,
op_idx_in_block: usize,
current_forest: &MastForest,
host: &mut impl Host,
) -> ControlFlow<BreakReason>;
fn execute_end_of_block_decorators(
&self,
basic_block_node: &BasicBlockNode,
node_id: MastNodeId,
current_forest: &Arc<MastForest>,
host: &mut impl Host,
) -> ControlFlow<BreakReason>;
}
pub(crate) trait SystemInterface {
fn caller_hash(&self) -> Word;
fn clock(&self) -> RowIndex;
fn ctx(&self) -> ContextId;
fn set_caller_hash(&mut self, caller_hash: Word);
fn set_ctx(&mut self, ctx: ContextId);
fn increment_clock(&mut self);
}
pub(crate) trait StackInterface {
fn top(&self) -> &[Felt];
fn get(&self, idx: usize) -> Felt;
fn get_mut(&mut self, idx: usize) -> &mut Felt;
fn get_word(&self, start_idx: usize) -> Word;
fn get_double_word(&self, start_idx: usize) -> [Felt; 8] {
core::array::from_fn(|i| self.get(start_idx + i))
}
fn depth(&self) -> u32;
fn set(&mut self, idx: usize, element: Felt);
fn set_word(&mut self, start_idx: usize, word: &Word);
fn swap(&mut self, idx1: usize, idx2: usize);
fn swapw_nth(&mut self, n: usize);
fn rotate_left(&mut self, n: usize);
fn rotate_right(&mut self, n: usize);
fn increment_size(&mut self) -> Result<(), ExecutionError>;
fn decrement_size(&mut self) -> Result<(), OperationError>;
}
pub(crate) trait AdviceProviderInterface {
fn pop_stack(&mut self) -> Result<Felt, AdviceError>;
fn pop_stack_word(&mut self) -> Result<Word, AdviceError>;
fn pop_stack_dword(&mut self) -> Result<[Word; 2], AdviceError>;
fn get_merkle_path(
&self,
root: Word,
depth: Felt,
index: Felt,
) -> Result<Option<MerklePath>, AdviceError>;
fn update_merkle_node(
&mut self,
root: Word,
depth: Felt,
index: Felt,
value: Word,
) -> Result<Option<MerklePath>, AdviceError>;
}
pub(crate) trait MemoryInterface {
fn read_element(&mut self, ctx: ContextId, addr: Felt) -> Result<Felt, MemoryError>;
fn read_word(&mut self, ctx: ContextId, addr: Felt, clk: RowIndex)
-> Result<Word, MemoryError>;
fn write_element(
&mut self,
ctx: ContextId,
addr: Felt,
element: Felt,
) -> Result<(), MemoryError>;
fn write_word(
&mut self,
ctx: ContextId,
addr: Felt,
clk: RowIndex,
word: Word,
) -> Result<(), MemoryError>;
}
pub(crate) trait HasherInterface {
fn permute(&mut self, state: HasherState) -> Result<(Felt, HasherState), OperationError>;
fn verify_merkle_root(
&mut self,
claimed_root: Word,
value: Word,
path: Option<&MerklePath>,
index: Felt,
on_err: impl FnOnce() -> OperationError,
) -> Result<Felt, OperationError>;
fn update_merkle_root(
&mut self,
claimed_old_root: Word,
old_value: Word,
new_value: Word,
path: Option<&MerklePath>,
index: Felt,
on_err: impl FnOnce() -> OperationError,
) -> Result<(Felt, Word), OperationError>;
}