pub use blocks::{Block, BlockId, BlockRegistry, BlockStat};
use cid::Cid;
use fvm_shared::address::Address;
use fvm_shared::clock::ChainEpoch;
use fvm_shared::consensus::ConsensusFault;
use fvm_shared::crypto::signature::{
SECP_PUB_LEN, SECP_SIG_LEN, SECP_SIG_MESSAGE_HASH_SIZE, SignatureType,
};
use fvm_shared::econ::TokenAmount;
use fvm_shared::error::ExitCode;
use fvm_shared::piece::PieceInfo;
use fvm_shared::randomness::{RANDOMNESS_LENGTH, Randomness};
use fvm_shared::sector::{
AggregateSealVerifyProofAndInfos, RegisteredSealProof, ReplicaUpdateInfo, SealVerifyInfo,
WindowPoStVerifyInfo,
};
use fvm_shared::sys::SendFlags;
use fvm_shared::sys::out::network::NetworkContext;
use fvm_shared::sys::out::vm::MessageContext;
use fvm_shared::{ActorID, MethodNum};
mod hash;
mod blocks;
pub mod default;
pub(crate) mod error;
use cid::multihash::Multihash;
pub use error::{ClassifyResult, Context, ExecutionError, Result, SyscallError};
use fvm_shared::event::StampedEvent;
pub use hash::SupportedHashes;
use crate::call_manager::CallManager;
use crate::gas::{Gas, GasTimer, PriceList};
use crate::machine::Machine;
use crate::machine::limiter::MemoryLimiter;
pub struct SendResult {
pub block_id: BlockId,
pub block_stat: BlockStat,
pub exit_code: ExitCode,
}
pub trait Kernel:
ActorOps
+ IpldBlockOps
+ CircSupplyOps
+ CryptoOps
+ DebugOps
+ EventOps
+ GasOps
+ MessageOps
+ NetworkOps
+ RandomnessOps
+ SelfOps
+ LimiterOps
+ 'static
{
type CallManager: CallManager;
fn into_inner(self) -> (Self::CallManager, BlockRegistry)
where
Self: Sized;
#[allow(clippy::too_many_arguments)]
fn new(
mgr: Self::CallManager,
blocks: BlockRegistry,
caller: ActorID,
actor_id: ActorID,
method: MethodNum,
value_received: TokenAmount,
read_only: bool,
) -> Self
where
Self: Sized;
fn machine(&self) -> &<Self::CallManager as CallManager>::Machine;
fn send<K: Kernel<CallManager = Self::CallManager>>(
&mut self,
recipient: &Address,
method: u64,
params: BlockId,
value: &TokenAmount,
gas_limit: Option<Gas>,
flags: SendFlags,
) -> Result<SendResult>;
}
pub trait NetworkOps {
fn network_context(&self) -> Result<NetworkContext>;
fn tipset_cid(&self, epoch: ChainEpoch) -> Result<Cid>;
}
pub trait MessageOps {
fn msg_context(&self) -> Result<MessageContext>;
}
pub trait IpldBlockOps {
fn block_open(&mut self, cid: &Cid) -> Result<(BlockId, BlockStat)>;
fn block_create(&mut self, codec: u64, data: &[u8]) -> Result<BlockId>;
fn block_link(&mut self, id: BlockId, hash_fun: u64, hash_len: u32) -> Result<Cid>;
fn block_read(&self, id: BlockId, offset: u32, buf: &mut [u8]) -> Result<i32>;
fn block_stat(&self, id: BlockId) -> Result<BlockStat>;
}
pub trait SelfOps: IpldBlockOps {
fn root(&self) -> Result<Cid>;
fn set_root(&mut self, root: Cid) -> Result<()>;
fn current_balance(&self) -> Result<TokenAmount>;
fn self_destruct(&mut self, beneficiary: &Address) -> Result<()>;
}
pub trait ActorOps {
fn resolve_address(&self, address: &Address) -> Result<ActorID>;
fn lookup_delegated_address(&self, actor_id: ActorID) -> Result<Option<Address>>;
fn get_actor_code_cid(&self, id: ActorID) -> Result<Cid>;
fn next_actor_address(&self) -> Result<Address>;
fn create_actor(
&mut self,
code_cid: Cid,
actor_id: ActorID,
delegated_address: Option<Address>,
) -> Result<()>;
#[cfg(feature = "m2-native")]
fn install_actor(&mut self, code_cid: Cid) -> Result<()>;
fn get_builtin_actor_type(&self, code_cid: &Cid) -> Result<u32>;
fn get_code_cid_for_type(&self, typ: u32) -> Result<Cid>;
fn balance_of(&self, actor_id: ActorID) -> Result<TokenAmount>;
}
pub trait CircSupplyOps {
fn total_fil_circ_supply(&self) -> Result<TokenAmount>;
}
pub trait GasOps {
fn gas_used(&self) -> Gas;
fn gas_available(&self) -> Gas;
fn charge_gas(&self, name: &str, compute: Gas) -> Result<GasTimer>;
fn price_list(&self) -> &PriceList;
}
pub trait CryptoOps {
fn verify_signature(
&self,
sig_type: SignatureType,
signature: &[u8],
signer: &Address,
plaintext: &[u8],
) -> Result<bool>;
fn recover_secp_public_key(
&self,
hash: &[u8; SECP_SIG_MESSAGE_HASH_SIZE],
signature: &[u8; SECP_SIG_LEN],
) -> Result<[u8; SECP_PUB_LEN]>;
fn hash(&self, code: u64, data: &[u8]) -> Result<Multihash<64>>;
fn compute_unsealed_sector_cid(
&self,
proof_type: RegisteredSealProof,
pieces: &[PieceInfo],
) -> Result<Cid>;
fn verify_post(&self, verify_info: &WindowPoStVerifyInfo) -> Result<bool>;
fn verify_consensus_fault(
&self,
h1: &[u8],
h2: &[u8],
extra: &[u8],
) -> Result<Option<ConsensusFault>>;
fn batch_verify_seals(&self, vis: &[SealVerifyInfo]) -> Result<Vec<bool>>;
fn verify_aggregate_seals(&self, aggregate: &AggregateSealVerifyProofAndInfos) -> Result<bool>;
fn verify_replica_update(&self, replica: &ReplicaUpdateInfo) -> Result<bool>;
}
pub trait RandomnessOps {
fn get_randomness_from_tickets(
&self,
personalization: i64,
rand_epoch: ChainEpoch,
entropy: &[u8],
) -> Result<[u8; RANDOMNESS_LENGTH]>;
fn get_randomness_from_beacon(
&self,
personalization: i64,
rand_epoch: ChainEpoch,
entropy: &[u8],
) -> Result<[u8; RANDOMNESS_LENGTH]>;
}
pub trait DebugOps {
fn log(&self, msg: String);
fn debug_enabled(&self) -> bool;
fn store_artifact(&self, name: &str, data: &[u8]) -> Result<()>;
}
pub trait LimiterOps {
type Limiter: MemoryLimiter;
fn limiter_mut(&mut self) -> &mut Self::Limiter;
}
pub trait EventOps {
fn emit_event(&mut self, raw_evt: &[u8]) -> Result<()>;
}