use std::collections::BTreeMap;
use anyhow::Error;
use cid::Cid;
use fvm_ipld_blockstore::Blockstore;
use fvm_ipld_encoding::{
ipld_block::IpldBlock,
tuple::{serde_tuple, Deserialize_tuple, Serialize_tuple},
};
use fvm_shared::{
address::Address,
clock::ChainEpoch,
consensus::ConsensusFault,
crypto::{
hash::SupportedHashes,
signature::{Signature, SECP_PUB_LEN, SECP_SIG_LEN, SECP_SIG_MESSAGE_HASH_SIZE},
},
econ::TokenAmount,
error::ExitCode,
piece::PieceInfo,
sector::{
AggregateSealVerifyProofAndInfos, RegisteredSealProof, ReplicaUpdateInfo, SealVerifyInfo,
WindowPoStVerifyInfo,
},
MethodNum,
};
use builtin::*;
pub use error::*;
use trace::*;
pub mod builtin;
mod error;
pub mod trace;
#[cfg(feature = "testing")]
pub mod util;
#[allow(clippy::type_complexity)]
pub trait VM {
fn blockstore(&self) -> &dyn Blockstore;
fn actor(&self, address: &Address) -> Option<ActorState>;
fn set_actor(&self, key: &Address, a: ActorState);
fn balance(&self, address: &Address) -> TokenAmount;
fn resolve_id_address(&self, address: &Address) -> Option<Address>;
fn execute_message(
&self,
from: &Address,
to: &Address,
value: &TokenAmount,
method: MethodNum,
params: Option<IpldBlock>,
) -> Result<MessageResult, VMError>;
fn execute_message_implicit(
&self,
from: &Address,
to: &Address,
value: &TokenAmount,
method: MethodNum,
params: Option<IpldBlock>,
) -> Result<MessageResult, VMError>;
fn take_invocations(&self) -> Vec<InvocationTrace>;
fn primitives(&self) -> &dyn Primitives;
fn mut_primitives(&self) -> &dyn MockPrimitives;
fn actor_manifest(&self) -> BTreeMap<Cid, Type>;
fn actor_states(&self) -> BTreeMap<Address, ActorState>;
fn epoch(&self) -> ChainEpoch;
fn set_epoch(&self, epoch: ChainEpoch);
fn circulating_supply(&self) -> TokenAmount;
fn set_circulating_supply(&self, supply: TokenAmount);
fn base_fee(&self) -> TokenAmount;
fn set_base_fee(&self, amount: TokenAmount);
fn timestamp(&self) -> u64;
fn set_timestamp(&self, timestamp: u64);
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct MessageResult {
pub code: ExitCode,
pub message: String,
pub ret: Option<IpldBlock>,
}
#[derive(Serialize_tuple, Deserialize_tuple, Clone, PartialEq, Eq, Debug)]
pub struct ActorState {
pub code: Cid,
pub state: Cid,
pub sequence: u64,
pub balance: TokenAmount,
pub delegated_address: Option<Address>,
}
pub fn new_actor(
code: Cid,
state: Cid,
sequence: u64,
balance: TokenAmount,
delegated_address: Option<Address>,
) -> ActorState {
ActorState { code, state, sequence, balance, delegated_address }
}
pub trait Primitives {
fn hash_blake2b(&self, data: &[u8]) -> [u8; 32];
fn hash(&self, hasher: SupportedHashes, data: &[u8]) -> Vec<u8>;
fn hash_64(&self, hasher: SupportedHashes, data: &[u8]) -> ([u8; 64], usize);
fn compute_unsealed_sector_cid(
&self,
proof_type: RegisteredSealProof,
pieces: &[PieceInfo],
) -> Result<Cid, Error>;
fn verify_signature(
&self,
signature: &Signature,
signer: &Address,
plaintext: &[u8],
) -> Result<(), Error>;
fn recover_secp_public_key(
&self,
hash: &[u8; SECP_SIG_MESSAGE_HASH_SIZE],
signature: &[u8; SECP_SIG_LEN],
) -> Result<[u8; SECP_PUB_LEN], Error>;
fn verify_post(&self, verify_info: &WindowPoStVerifyInfo) -> Result<(), anyhow::Error>;
fn verify_consensus_fault(
&self,
h1: &[u8],
h2: &[u8],
extra: &[u8],
) -> Result<Option<ConsensusFault>, anyhow::Error>;
fn batch_verify_seals(&self, batch: &[SealVerifyInfo]) -> anyhow::Result<Vec<bool>>;
fn verify_aggregate_seals(
&self,
aggregate: &AggregateSealVerifyProofAndInfos,
) -> Result<(), anyhow::Error>;
fn verify_replica_update(&self, replica: &ReplicaUpdateInfo) -> Result<(), anyhow::Error>;
}
#[allow(clippy::type_complexity)]
pub trait MockPrimitives: Primitives {
fn override_hash_blake2b(&self, f: fn(&[u8]) -> [u8; 32]);
fn override_hash(&self, f: fn(SupportedHashes, &[u8]) -> Vec<u8>);
fn override_hash_64(&self, f: fn(SupportedHashes, &[u8]) -> ([u8; 64], usize));
fn override_compute_unsealed_sector_cid(
&self,
f: fn(RegisteredSealProof, &[PieceInfo]) -> Result<Cid, Error>,
);
fn override_recover_secp_public_key(
&self,
f: fn(
&[u8; SECP_SIG_MESSAGE_HASH_SIZE],
&[u8; SECP_SIG_LEN],
) -> Result<[u8; SECP_PUB_LEN], Error>,
);
fn override_verify_post(&self, f: fn(&WindowPoStVerifyInfo) -> Result<(), Error>);
fn override_verify_consensus_fault(
&self,
f: fn(&[u8], &[u8], &[u8]) -> Result<Option<ConsensusFault>, Error>,
);
fn override_batch_verify_seals(&self, f: fn(&[SealVerifyInfo]) -> Result<Vec<bool>, Error>);
fn override_verify_aggregate_seals(
&self,
f: fn(&AggregateSealVerifyProofAndInfos) -> Result<(), Error>,
);
fn override_verify_signature(&self, f: fn(&Signature, &Address, &[u8]) -> Result<(), Error>);
fn override_verify_replica_update(&self, f: fn(&ReplicaUpdateInfo) -> Result<(), Error>);
fn as_primitives(&self) -> &dyn Primitives;
}