use crate::ExitError;
use alloc::rc::Rc;
use alloc::vec::Vec;
use primitive_types::{H160, H256, U256};
use sha3::{Digest, Keccak256};
pub trait GasState {
fn gas(&self) -> U256;
}
#[derive(Clone, Debug)]
pub struct RuntimeState {
pub context: Context,
pub transaction_context: Rc<TransactionContext>,
pub retbuf: Vec<u8>,
}
impl AsRef<Self> for RuntimeState {
fn as_ref(&self) -> &Self {
self
}
}
impl AsMut<Self> for RuntimeState {
fn as_mut(&mut self) -> &mut Self {
self
}
}
impl GasState for RuntimeState {
fn gas(&self) -> U256 {
U256::zero()
}
}
#[derive(Clone, Debug)]
pub struct Context {
pub address: H160,
pub caller: H160,
pub apparent_value: U256,
}
#[derive(Clone, Debug)]
pub struct TransactionContext {
pub gas_price: U256,
pub origin: H160,
}
#[derive(Clone, Debug)]
pub struct Transfer {
pub source: H160,
pub target: H160,
pub value: U256,
}
#[derive(Clone, Debug)]
pub struct Log {
pub address: H160,
pub topics: Vec<H256>,
pub data: Vec<u8>,
}
pub trait RuntimeEnvironment {
fn block_hash(&self, number: U256) -> H256;
fn block_number(&self) -> U256;
fn block_coinbase(&self) -> H160;
fn block_timestamp(&self) -> U256;
fn block_difficulty(&self) -> U256;
fn block_randomness(&self) -> Option<H256>;
fn block_gas_limit(&self) -> U256;
fn block_base_fee_per_gas(&self) -> U256;
fn chain_id(&self) -> U256;
}
pub trait RuntimeBaseBackend {
fn balance(&self, address: H160) -> U256;
fn code_size(&self, address: H160) -> U256 {
U256::from(self.code(address).len())
}
fn code_hash(&self, address: H160) -> H256 {
H256::from_slice(&Keccak256::digest(&self.code(address)[..]))
}
fn code(&self, address: H160) -> Vec<u8>;
fn storage(&self, address: H160, index: H256) -> H256;
fn exists(&self, address: H160) -> bool;
fn nonce(&self, address: H160) -> U256;
}
pub trait RuntimeBackend: RuntimeBaseBackend {
fn original_storage(&self, address: H160, index: H256) -> H256;
fn deleted(&self, address: H160) -> bool;
fn is_cold(&self, address: H160, index: Option<H256>) -> bool;
fn is_hot(&self, address: H160, index: Option<H256>) -> bool {
!self.is_cold(address, index)
}
fn mark_hot(&mut self, address: H160, index: Option<H256>);
fn set_storage(&mut self, address: H160, index: H256, value: H256) -> Result<(), ExitError>;
fn log(&mut self, log: Log) -> Result<(), ExitError>;
fn mark_delete(&mut self, address: H160);
fn reset_storage(&mut self, address: H160);
fn set_code(&mut self, address: H160, code: Vec<u8>) -> Result<(), ExitError>;
fn reset_balance(&mut self, address: H160);
fn deposit(&mut self, target: H160, value: U256);
fn withdrawal(&mut self, source: H160, value: U256) -> Result<(), ExitError>;
fn transfer(&mut self, transfer: Transfer) -> Result<(), ExitError> {
self.withdrawal(transfer.source, transfer.value)?;
self.deposit(transfer.target, transfer.value);
Ok(())
}
fn inc_nonce(&mut self, address: H160) -> Result<(), ExitError>;
}