use cid::Cid;
use derive_more::{Deref, DerefMut};
use fvm_ipld_blockstore::Blockstore;
use fvm_shared::ActorID;
use fvm_shared::address::Address;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::econ::TokenAmount;
use fvm_shared::version::NetworkVersion;
use num_traits::Zero;
use crate::externs::Externs;
use crate::gas::{PriceList, price_list_by_network_version};
use crate::kernel::Result;
use crate::state_tree::{ActorState, StateTree};
mod default;
pub use default::DefaultMachine;
mod manifest;
pub use manifest::Manifest;
mod engine;
pub use engine::{Engine, EngineConfig, MultiEngine};
mod boxed;
pub const REWARD_ACTOR_ADDR: Address = Address::new_id(2);
pub const BURNT_FUNDS_ACTOR_ADDR: Address = Address::new_id(99);
pub trait Machine: 'static {
type Blockstore: Blockstore;
type Externs: Externs;
fn engine(&self) -> &Engine;
fn blockstore(&self) -> &Self::Blockstore;
fn context(&self) -> &MachineContext;
fn externs(&self) -> &Self::Externs;
fn builtin_actors(&self) -> &Manifest;
fn state_tree(&self) -> &StateTree<Self::Blockstore>;
fn state_tree_mut(&mut self) -> &mut StateTree<Self::Blockstore>;
fn create_actor(&mut self, addr: &Address, act: ActorState) -> Result<ActorID>;
fn transfer(&mut self, from: ActorID, to: ActorID, value: &TokenAmount) -> Result<()>;
fn flush(&mut self) -> Result<Cid> {
self.state_tree_mut().flush()
}
fn into_store(self) -> Self::Blockstore;
fn machine_id(&self) -> &str;
}
#[derive(Debug, Clone)]
pub struct NetworkConfig {
pub network_version: NetworkVersion,
pub max_call_depth: u32,
pub max_wasm_stack: u32,
pub builtin_actors_override: Option<Cid>,
pub actor_debugging: bool,
pub price_list: &'static PriceList,
pub actor_redirect: Vec<(Cid, Cid)>,
}
impl NetworkConfig {
pub fn new(network_version: NetworkVersion) -> Self {
NetworkConfig {
network_version,
max_call_depth: 1024,
max_wasm_stack: 2048,
actor_debugging: false,
builtin_actors_override: None,
price_list: price_list_by_network_version(network_version),
actor_redirect: vec![],
}
}
pub fn enable_actor_debugging(&mut self) -> &mut Self {
self.actor_debugging = true;
self
}
pub fn override_actors(&mut self, manifest: Cid) -> &mut Self {
self.builtin_actors_override = Some(manifest);
self
}
pub fn redirect_actors(&mut self, actor_redirect: Vec<(Cid, Cid)>) -> &mut Self {
self.actor_redirect = actor_redirect;
self
}
pub fn for_epoch(&self, epoch: ChainEpoch, initial_state: Cid) -> MachineContext {
MachineContext {
network: self.clone(),
epoch,
initial_state_root: initial_state,
base_fee: TokenAmount::zero(),
circ_supply: fvm_shared::TOTAL_FILECOIN.clone(),
tracing: false,
}
}
}
#[derive(Clone, Debug, Deref, DerefMut)]
pub struct MachineContext {
#[deref]
#[deref_mut]
pub network: NetworkConfig,
pub epoch: ChainEpoch,
pub initial_state_root: Cid,
pub base_fee: TokenAmount,
pub circ_supply: TokenAmount,
pub tracing: bool,
}
impl MachineContext {
pub fn set_base_fee(&mut self, amt: TokenAmount) -> &mut Self {
self.base_fee = amt;
self
}
pub fn set_circulating_supply(&mut self, amt: TokenAmount) -> &mut Self {
self.circ_supply = amt;
self
}
pub fn enable_tracing(&mut self) -> &mut Self {
self.tracing = true;
self
}
}