little improvements in evm ext

This commit is contained in:
debris 2016-01-08 00:16:15 +01:00
parent 8335d40102
commit d0180df167
3 changed files with 103 additions and 62 deletions

View File

@ -6,9 +6,9 @@ use state::*;
use env_info::*;
use engine::*;
use transaction::*;
use evm::VmFactory;
use evm::{VmFactory, ExtFace, Ext, RuntimeData};
fn contract_address(address: &Address, nonce: &U256) -> Address {
pub fn contract_address(address: &Address, nonce: &U256) -> Address {
let mut stream = RlpStream::new_list(2);
stream.append(address);
stream.append(nonce);
@ -23,16 +23,16 @@ pub struct Executive<'a> {
state: &'a mut State,
info: &'a EnvInfo,
engine: &'a Engine,
level: usize
depth: usize
}
impl<'a> Executive<'a> {
pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, level: usize) -> Self {
pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize) -> Self {
Executive {
state: state,
info: info,
engine: engine,
level: level
depth: depth
}
}
@ -57,9 +57,12 @@ impl<'a> Executive<'a> {
}
fn create(&mut self, sender: &Address, endowment: &U256, gas_price: &U256, gas: &U256, init: &[u8], origin: &Address) -> ExecutiveResult {
let _new_address = contract_address(&sender, &(self.state.nonce(sender) - U256::one()));
let _evm = VmFactory::create();
let new_address = contract_address(&sender, &(self.state.nonce(sender) - U256::one()));
let mut ext = Ext::new(self.state, self.info, new_address, self.depth);
let data = RuntimeData::new();
// TODO: init runtime data
let evm = VmFactory::create();
evm.exec(data, &mut ext);
ExecutiveResult::Ok
}
}

View File

@ -42,11 +42,11 @@ pub trait ExtFace {
/// Creates new contract.
/// Returns new contract address and gas used.
fn create(&self, _gas: u64, _endowment: &U256, _code: &[u8]) -> (Address, u64);
fn create(&self, gas: u64, endowment: &U256, code: &[u8]) -> (Address, u64);
/// Calls existing contract.
/// Returns call output and gas used.
fn call(&self, _gas: u64, _call_gas: u64, _receive_address: &Address, _value: &U256, _data: &[u8], _code_address: &Address) -> Option<(Vec<u8>, u64)>;
fn call(&self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address) -> Option<(Vec<u8>, u64)>;
/// Returns code at given address
fn extcode(&self, address: &Address) -> Vec<u8>;
@ -68,41 +68,38 @@ pub trait ExtFace {
///
/// fn main() {
/// let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
/// let mut data = RuntimeData::new();
/// let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address);
/// let mut state = State::new_temp();
/// let info = EnvInfo::new();
/// let ext = Ext::new(&mut state, &info, address);
/// }
/// ```
pub struct Ext {
info: EnvInfo,
state: State,
pub struct Ext<'a> {
state: &'a mut State,
info: &'a EnvInfo,
address: Address,
substate: SubState
substate: SubState,
depth: usize
}
impl Ext {
impl<'a> Ext<'a> {
/// Creates new evm environment object with backing state.
pub fn new(info: EnvInfo, state: State, address: Address) -> Ext {
pub fn new(state: &'a mut State, info: &'a EnvInfo, address: Address, depth: usize) -> Self {
Ext {
info: info,
state: state,
info: info,
address: address,
substate: SubState::new()
substate: SubState::new(),
depth: depth
}
}
/// Returns state
// not sure if this is the best solution, but seems to be the easiest one, mk
pub fn state(&self) -> &State {
&self.state
}
/// Returns substate
/// Returns substate logs.
pub fn logs(&self) -> &[LogEntry] {
&self.substate.logs
}
}
impl ExtFace for Ext {
impl<'a> ExtFace for Ext<'a> {
fn sload(&self, key: &H256) -> H256 {
self.state.storage_at(&self.address, key)
}

View File

@ -321,10 +321,15 @@ mod tests {
data.gas = 0x174876e800;
data.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap();
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let state = ext.state();
let mut state = State::new_temp();
let info = EnvInfo::new();
{
let mut ext = Ext::new(&mut state, &info, address.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
}
assert_eq!(state.storage_at(&address, &H256::new()),
H256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap());
}
@ -337,10 +342,15 @@ mod tests {
data.gas = 0x174876e800;
data.code = "6000600020600055".from_hex().unwrap();
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let state = ext.state();
let mut state = State::new_temp();
let info = EnvInfo::new();
{
let mut ext = Ext::new(&mut state, &info, address.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
}
assert_eq!(state.storage_at(&address, &H256::new()),
H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap());
}
@ -353,10 +363,15 @@ mod tests {
data.gas = 0x174876e800;
data.code = "6005600420600055".from_hex().unwrap();
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let state = ext.state();
let mut state = State::new_temp();
let info = EnvInfo::new();
{
let mut ext = Ext::new(&mut state, &info, address.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
}
assert_eq!(state.storage_at(&address, &H256::new()),
H256::from_str("c41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec").unwrap());
}
@ -370,10 +385,15 @@ mod tests {
data.gas = 0x174876e800;
data.code = "32600055".from_hex().unwrap();
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let state = ext.state();
let mut state = State::new_temp();
let info = EnvInfo::new();
{
let mut ext = Ext::new(&mut state, &info, address.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
}
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
}
@ -386,10 +406,15 @@ mod tests {
data.gas = 0x174876e800;
data.code = "33600055".from_hex().unwrap();
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let state = ext.state();
let mut state = State::new_temp();
let info = EnvInfo::new();
{
let mut ext = Ext::new(&mut state, &info, address.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
}
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
}
@ -420,10 +445,14 @@ mod tests {
let mut state = State::new_temp();
state.set_code(&address, address_code);
state.set_code(&caller, caller_code);
let mut ext = Ext::new(EnvInfo::new(), state, caller.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let state = ext.state();
let info = EnvInfo::new();
{
let mut ext = Ext::new(&mut state, &info, caller.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
}
assert_eq!(state.storage_at(&caller, &H256::new()),
H256::from_str("6005600055000000000000000000000000000000000000000000000000000000").unwrap());
}
@ -439,10 +468,14 @@ mod tests {
let mut state = State::new_temp();
state.add_balance(&address, &U256::from(0x10));
let mut ext = Ext::new(EnvInfo::new(), state, address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let state = ext.state();
let info = EnvInfo::new();
{
let mut ext = Ext::new(&mut state, &info, address.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
}
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0x10)));
}
@ -455,7 +488,9 @@ mod tests {
data.gas = 0x174876e800;
data.code = "60006000a0".from_hex().unwrap();
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
let mut state = State::new_temp();
let info = EnvInfo::new();
let mut ext = Ext::new(&mut state, &info, address.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let logs = ext.logs();
@ -483,7 +518,9 @@ mod tests {
data.gas = 0x174876e800;
data.code = "60ff6000533360206000a1".from_hex().unwrap();
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
let mut state = State::new_temp();
let info = EnvInfo::new();
let mut ext = Ext::new(&mut state, &info, address.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let logs = ext.logs();
@ -506,13 +543,17 @@ mod tests {
data.gas = 0x174876e800;
data.code = "600040600055".from_hex().unwrap();
let mut state = State::new_temp();
let mut info = EnvInfo::new();
info.number = U256::one();
info.last_hashes.push(H256::from(address.clone()));
let mut ext = Ext::new(info, State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
let state = ext.state();
{
let mut ext = Ext::new(&mut state, &info, address.clone(), 0);
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
}
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone()));
}
}