use cid::Cid;
use fvm_shared::address::Address;
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::{ActorID, MethodNum};
use crate::Kernel;
use crate::engine::Engine;
use crate::gas::{Gas, GasCharge, GasTimer, GasTracker, PriceList};
use crate::kernel::{self, Result};
use crate::machine::{Machine, MachineContext};
use crate::state_tree::ActorState;
pub mod backtrace;
mod state_access_tracker;
pub use backtrace::Backtrace;
mod default;
pub use default::DefaultCallManager;
use fvm_shared::event::StampedEvent;
use crate::trace::ExecutionTrace;
pub const NO_DATA_BLOCK_ID: u32 = 0;
pub trait CallManager: 'static {
type Machine: Machine;
#[allow(clippy::too_many_arguments)]
fn new(
machine: Self::Machine,
engine: Engine,
gas_limit: u64,
origin: ActorID,
origin_address: Address,
receiver: Option<ActorID>,
receiver_address: Address,
nonce: u64,
gas_premium: TokenAmount,
) -> Self;
#[allow(clippy::too_many_arguments)]
fn send<K: Kernel<CallManager = Self>>(
&mut self,
from: ActorID,
to: Address,
method: MethodNum,
params: Option<kernel::Block>,
value: &TokenAmount,
gas_limit: Option<Gas>,
read_only: bool,
) -> Result<InvocationResult>;
fn finish(self) -> (Result<FinishRet>, Self::Machine);
fn machine(&self) -> &Self::Machine;
fn machine_mut(&mut self) -> &mut Self::Machine;
fn engine(&self) -> &Engine;
fn gas_tracker(&self) -> &GasTracker;
fn gas_premium(&self) -> &TokenAmount;
fn origin(&self) -> ActorID;
fn next_actor_address(&self) -> Address;
fn create_actor(
&mut self,
code_id: Cid,
actor_id: ActorID,
delegated_address: Option<Address>,
) -> Result<()>;
fn resolve_address(&self, address: &Address) -> Result<Option<ActorID>>;
fn set_actor(&mut self, id: ActorID, state: ActorState) -> Result<()>;
fn get_actor(&self, id: ActorID) -> Result<Option<ActorState>>;
fn delete_actor(&mut self, id: ActorID) -> Result<()>;
fn transfer(&mut self, from: ActorID, to: ActorID, value: &TokenAmount) -> Result<()>;
fn nonce(&self) -> u64;
fn invocation_count(&self) -> u64;
fn price_list(&self) -> &PriceList {
self.machine().context().price_list
}
fn context(&self) -> &MachineContext {
self.machine().context()
}
fn blockstore(&self) -> &<Self::Machine as Machine>::Blockstore {
self.machine().blockstore()
}
fn externs(&self) -> &<Self::Machine as Machine>::Externs {
self.machine().externs()
}
fn charge_gas(&self, charge: GasCharge) -> Result<GasTimer> {
self.gas_tracker().apply_charge(charge)
}
fn limiter_mut(&mut self) -> &mut <Self::Machine as Machine>::Limiter;
fn append_event(&mut self, evt: StampedEvent);
}
#[derive(Clone, Debug)]
pub struct InvocationResult {
pub exit_code: ExitCode,
pub value: Option<kernel::Block>,
}
impl Default for InvocationResult {
fn default() -> Self {
Self {
value: None,
exit_code: ExitCode::OK,
}
}
}
pub struct FinishRet {
pub gas_used: u64,
pub backtrace: Backtrace,
pub exec_trace: ExecutionTrace,
pub events: Vec<StampedEvent>,
pub events_root: Option<Cid>,
}