use cid::Cid;
use derive_more::{Deref, DerefMut};
use fvm_ipld_blockstore::Blockstore;
use fvm_shared::ActorID;
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::StateTree;
mod default;
pub use default::DefaultMachine;
use fvm_shared::chainid::ChainID;
pub mod limiter;
mod manifest;
pub use manifest::Manifest;
use self::limiter::MemoryLimiter;
mod boxed;
pub const REWARD_ACTOR_ID: ActorID = 2;
pub const BURNT_FUNDS_ACTOR_ID: ActorID = 99;
pub trait Machine: 'static {
type Blockstore: Blockstore;
type Externs: Externs;
type Limiter: MemoryLimiter;
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 flush(&mut self) -> Result<Cid> {
self.state_tree_mut().flush()
}
fn into_store(self) -> Self::Blockstore;
fn machine_id(&self) -> &str;
fn new_limiter(&self) -> Self::Limiter;
}
#[derive(Debug, Clone)]
pub struct NetworkConfig {
pub network_version: NetworkVersion,
pub chain_id: ChainID,
pub max_call_depth: u32,
pub max_wasm_stack: u32,
pub max_inst_memory_bytes: u64,
pub max_memory_bytes: u64,
pub max_block_size: usize,
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 {
chain_id: ChainID::from(0u64),
network_version,
max_call_depth: 1024,
max_wasm_stack: 2048,
max_inst_memory_bytes: 512 * (1 << 20),
max_memory_bytes: 2 * (1 << 30),
actor_debugging: false,
builtin_actors_override: None,
price_list: price_list_by_network_version(network_version),
actor_redirect: vec![],
max_block_size: 1 << 20,
}
}
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,
timestamp: u64,
initial_state: Cid,
) -> MachineContext {
MachineContext {
network: self.clone(),
base_fee: TokenAmount::zero(),
epoch,
timestamp,
initial_state_root: initial_state,
circ_supply: TokenAmount::zero(),
tracing: false,
flush_all_blocks: false,
}
}
pub fn chain_id(&mut self, id: ChainID) -> &mut Self {
self.chain_id = id;
self
}
}
#[derive(Clone, Debug, Deref, DerefMut)]
pub struct MachineContext {
#[deref]
#[deref_mut]
pub network: NetworkConfig,
pub epoch: ChainEpoch,
pub timestamp: u64,
pub base_fee: TokenAmount,
pub initial_state_root: Cid,
pub circ_supply: TokenAmount,
pub tracing: bool,
pub flush_all_blocks: bool,
}
impl MachineContext {
pub fn set_base_fee(&mut self, amt: TokenAmount) -> &mut Self {
self.base_fee = amt;
self
}
pub fn set_epoch(&mut self, epoch: ChainEpoch) -> &mut Self {
self.epoch = epoch;
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
}
pub fn enable_flush_all_blocks(&mut self) -> &mut Self {
self.flush_all_blocks = true;
self
}
}