little improvements in evm ext
This commit is contained in:
parent
8335d40102
commit
d0180df167
@ -6,9 +6,9 @@ use state::*;
|
|||||||
use env_info::*;
|
use env_info::*;
|
||||||
use engine::*;
|
use engine::*;
|
||||||
use transaction::*;
|
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);
|
let mut stream = RlpStream::new_list(2);
|
||||||
stream.append(address);
|
stream.append(address);
|
||||||
stream.append(nonce);
|
stream.append(nonce);
|
||||||
@ -23,16 +23,16 @@ pub struct Executive<'a> {
|
|||||||
state: &'a mut State,
|
state: &'a mut State,
|
||||||
info: &'a EnvInfo,
|
info: &'a EnvInfo,
|
||||||
engine: &'a Engine,
|
engine: &'a Engine,
|
||||||
level: usize
|
depth: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Executive<'a> {
|
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 {
|
Executive {
|
||||||
state: state,
|
state: state,
|
||||||
info: info,
|
info: info,
|
||||||
engine: engine,
|
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 {
|
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 new_address = contract_address(&sender, &(self.state.nonce(sender) - U256::one()));
|
||||||
let _evm = VmFactory::create();
|
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
|
ExecutiveResult::Ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,11 @@ pub trait ExtFace {
|
|||||||
|
|
||||||
/// Creates new contract.
|
/// Creates new contract.
|
||||||
/// Returns new contract address and gas used.
|
/// 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.
|
/// Calls existing contract.
|
||||||
/// Returns call output and gas used.
|
/// 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
|
/// Returns code at given address
|
||||||
fn extcode(&self, address: &Address) -> Vec<u8>;
|
fn extcode(&self, address: &Address) -> Vec<u8>;
|
||||||
@ -68,41 +68,38 @@ pub trait ExtFace {
|
|||||||
///
|
///
|
||||||
/// fn main() {
|
/// fn main() {
|
||||||
/// let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
/// let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
/// let mut data = RuntimeData::new();
|
/// let mut state = State::new_temp();
|
||||||
/// let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address);
|
/// let info = EnvInfo::new();
|
||||||
|
/// let ext = Ext::new(&mut state, &info, address);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Ext {
|
pub struct Ext<'a> {
|
||||||
info: EnvInfo,
|
state: &'a mut State,
|
||||||
state: State,
|
info: &'a EnvInfo,
|
||||||
address: Address,
|
address: Address,
|
||||||
substate: SubState
|
substate: SubState,
|
||||||
|
depth: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ext {
|
impl<'a> Ext<'a> {
|
||||||
/// Creates new evm environment object with backing state.
|
/// 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 {
|
Ext {
|
||||||
info: info,
|
|
||||||
state: state,
|
state: state,
|
||||||
|
info: info,
|
||||||
address: address,
|
address: address,
|
||||||
substate: SubState::new()
|
substate: SubState::new(),
|
||||||
|
depth: depth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns state
|
/// Returns substate logs.
|
||||||
// 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
|
|
||||||
pub fn logs(&self) -> &[LogEntry] {
|
pub fn logs(&self) -> &[LogEntry] {
|
||||||
&self.substate.logs
|
&self.substate.logs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtFace for Ext {
|
impl<'a> ExtFace for Ext<'a> {
|
||||||
fn sload(&self, key: &H256) -> H256 {
|
fn sload(&self, key: &H256) -> H256 {
|
||||||
self.state.storage_at(&self.address, key)
|
self.state.storage_at(&self.address, key)
|
||||||
}
|
}
|
||||||
|
109
src/evm/jit.rs
109
src/evm/jit.rs
@ -321,10 +321,15 @@ mod tests {
|
|||||||
data.gas = 0x174876e800;
|
data.gas = 0x174876e800;
|
||||||
data.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap();
|
data.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
|
let mut state = State::new_temp();
|
||||||
let evm = JitEvm;
|
let info = EnvInfo::new();
|
||||||
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()),
|
assert_eq!(state.storage_at(&address, &H256::new()),
|
||||||
H256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap());
|
H256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap());
|
||||||
}
|
}
|
||||||
@ -337,10 +342,15 @@ mod tests {
|
|||||||
data.gas = 0x174876e800;
|
data.gas = 0x174876e800;
|
||||||
data.code = "6000600020600055".from_hex().unwrap();
|
data.code = "6000600020600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
|
let mut state = State::new_temp();
|
||||||
let evm = JitEvm;
|
let info = EnvInfo::new();
|
||||||
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()),
|
assert_eq!(state.storage_at(&address, &H256::new()),
|
||||||
H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap());
|
H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap());
|
||||||
}
|
}
|
||||||
@ -353,10 +363,15 @@ mod tests {
|
|||||||
data.gas = 0x174876e800;
|
data.gas = 0x174876e800;
|
||||||
data.code = "6005600420600055".from_hex().unwrap();
|
data.code = "6005600420600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
|
let mut state = State::new_temp();
|
||||||
let evm = JitEvm;
|
let info = EnvInfo::new();
|
||||||
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()),
|
assert_eq!(state.storage_at(&address, &H256::new()),
|
||||||
H256::from_str("c41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec").unwrap());
|
H256::from_str("c41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec").unwrap());
|
||||||
}
|
}
|
||||||
@ -370,10 +385,15 @@ mod tests {
|
|||||||
data.gas = 0x174876e800;
|
data.gas = 0x174876e800;
|
||||||
data.code = "32600055".from_hex().unwrap();
|
data.code = "32600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
|
let mut state = State::new_temp();
|
||||||
let evm = JitEvm;
|
let info = EnvInfo::new();
|
||||||
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!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
|
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,10 +406,15 @@ mod tests {
|
|||||||
data.gas = 0x174876e800;
|
data.gas = 0x174876e800;
|
||||||
data.code = "33600055".from_hex().unwrap();
|
data.code = "33600055".from_hex().unwrap();
|
||||||
|
|
||||||
let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone());
|
let mut state = State::new_temp();
|
||||||
let evm = JitEvm;
|
let info = EnvInfo::new();
|
||||||
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!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
|
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,10 +445,14 @@ mod tests {
|
|||||||
let mut state = State::new_temp();
|
let mut state = State::new_temp();
|
||||||
state.set_code(&address, address_code);
|
state.set_code(&address, address_code);
|
||||||
state.set_code(&caller, caller_code);
|
state.set_code(&caller, caller_code);
|
||||||
let mut ext = Ext::new(EnvInfo::new(), state, caller.clone());
|
let info = EnvInfo::new();
|
||||||
let evm = JitEvm;
|
|
||||||
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
|
{
|
||||||
let state = ext.state();
|
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()),
|
assert_eq!(state.storage_at(&caller, &H256::new()),
|
||||||
H256::from_str("6005600055000000000000000000000000000000000000000000000000000000").unwrap());
|
H256::from_str("6005600055000000000000000000000000000000000000000000000000000000").unwrap());
|
||||||
}
|
}
|
||||||
@ -439,10 +468,14 @@ mod tests {
|
|||||||
|
|
||||||
let mut state = State::new_temp();
|
let mut state = State::new_temp();
|
||||||
state.add_balance(&address, &U256::from(0x10));
|
state.add_balance(&address, &U256::from(0x10));
|
||||||
let mut ext = Ext::new(EnvInfo::new(), state, address.clone());
|
let info = EnvInfo::new();
|
||||||
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(&U256::from(0x10)));
|
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0x10)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,7 +488,9 @@ mod tests {
|
|||||||
data.gas = 0x174876e800;
|
data.gas = 0x174876e800;
|
||||||
data.code = "60006000a0".from_hex().unwrap();
|
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;
|
let evm = JitEvm;
|
||||||
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
|
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
|
||||||
let logs = ext.logs();
|
let logs = ext.logs();
|
||||||
@ -483,7 +518,9 @@ mod tests {
|
|||||||
data.gas = 0x174876e800;
|
data.gas = 0x174876e800;
|
||||||
data.code = "60ff6000533360206000a1".from_hex().unwrap();
|
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;
|
let evm = JitEvm;
|
||||||
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
|
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
|
||||||
let logs = ext.logs();
|
let logs = ext.logs();
|
||||||
@ -506,13 +543,17 @@ mod tests {
|
|||||||
data.gas = 0x174876e800;
|
data.gas = 0x174876e800;
|
||||||
data.code = "600040600055".from_hex().unwrap();
|
data.code = "600040600055".from_hex().unwrap();
|
||||||
|
|
||||||
|
let mut state = State::new_temp();
|
||||||
let mut info = EnvInfo::new();
|
let mut info = EnvInfo::new();
|
||||||
info.number = U256::one();
|
info.number = U256::one();
|
||||||
info.last_hashes.push(H256::from(address.clone()));
|
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 mut ext = Ext::new(&mut state, &info, address.clone(), 0);
|
||||||
let state = ext.state();
|
let evm = JitEvm;
|
||||||
|
assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop);
|
||||||
|
}
|
||||||
|
|
||||||
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone()));
|
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user