use std::sync::Arc;
use ethereum_types::{U256, H256, Address};
use bytes::Bytes;
use action_type::ActionType;
use env_info::EnvInfo;
use schedule::Schedule;
use return_data::ReturnData;
use error::{Result, TrapKind};
#[derive(Debug)]
pub enum ContractCreateResult {
Created(Address, U256),
Failed,
Reverted(U256, ReturnData),
}
#[derive(Debug)]
pub enum MessageCallResult {
Success(U256, ReturnData),
Failed,
Reverted(U256, ReturnData),
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum CreateContractAddress {
FromSenderAndNonce,
FromSenderSaltAndCodeHash(H256),
FromSenderAndCodeHash,
}
pub trait Ext {
fn initial_storage_at(&self, key: &H256) -> Result<H256>;
fn storage_at(&self, key: &H256) -> Result<H256>;
fn set_storage(&mut self, key: H256, value: H256) -> Result<()>;
fn exists(&self, address: &Address) -> Result<bool>;
fn exists_and_not_null(&self, address: &Address) -> Result<bool>;
fn origin_balance(&self) -> Result<U256>;
fn balance(&self, address: &Address) -> Result<U256>;
fn blockhash(&mut self, number: &U256) -> H256;
fn create(
&mut self,
gas: &U256,
value: &U256,
code: &[u8],
parent_version: &U256,
address: CreateContractAddress,
trap: bool,
) -> ::std::result::Result<ContractCreateResult, TrapKind>;
fn call(
&mut self,
gas: &U256,
sender_address: &Address,
receive_address: &Address,
value: Option<U256>,
data: &[u8],
code_address: &Address,
call_type: ActionType,
trap: bool
) -> ::std::result::Result<MessageCallResult, TrapKind>;
fn extcode(&self, address: &Address) -> Result<Option<Arc<Bytes>>>;
fn extcodehash(&self, address: &Address) -> Result<Option<H256>>;
fn extcodesize(&self, address: &Address) -> Result<Option<usize>>;
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()>;
fn ret(self, gas: &U256, data: &ReturnData, apply_state: bool) -> Result<U256>;
fn suicide(&mut self, refund_address: &Address) -> Result<()> ;
fn schedule(&self) -> &Schedule;
fn env_info(&self) -> &EnvInfo;
fn chain_id(&self) -> u64;
fn depth(&self) -> usize;
fn add_sstore_refund(&mut self, value: usize);
fn sub_sstore_refund(&mut self, value: usize);
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _current_gas: U256) -> bool { false }
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256, _mem_written: Option<(usize, usize)>, _store_written: Option<(U256, U256)>) {}
fn trace_failed(&mut self) {}
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem: &[u8]) {}
fn is_static(&self) -> bool;
}