2016-01-11 02:42:02 +01:00
|
|
|
//! Just in time compiler execution environment.
|
2016-01-11 17:01:42 +01:00
|
|
|
use common::*;
|
2015-12-23 13:02:01 +01:00
|
|
|
use evmjit;
|
|
|
|
use evm;
|
|
|
|
|
2016-01-09 00:55:17 +01:00
|
|
|
/// Ethcore representation of evmjit runtime data.
|
|
|
|
pub struct RuntimeData {
|
|
|
|
pub gas: U256,
|
|
|
|
pub gas_price: U256,
|
|
|
|
pub call_data: Vec<u8>,
|
|
|
|
pub address: Address,
|
|
|
|
pub caller: Address,
|
|
|
|
pub origin: Address,
|
|
|
|
pub call_value: U256,
|
|
|
|
pub coinbase: Address,
|
|
|
|
pub difficulty: U256,
|
|
|
|
pub gas_limit: U256,
|
|
|
|
pub number: u64,
|
|
|
|
pub timestamp: u64,
|
|
|
|
pub code: Vec<u8>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RuntimeData {
|
|
|
|
pub fn new() -> RuntimeData {
|
|
|
|
RuntimeData {
|
|
|
|
gas: U256::zero(),
|
|
|
|
gas_price: U256::zero(),
|
|
|
|
call_data: vec![],
|
|
|
|
address: Address::new(),
|
|
|
|
caller: Address::new(),
|
|
|
|
origin: Address::new(),
|
|
|
|
call_value: U256::zero(),
|
|
|
|
coinbase: Address::new(),
|
|
|
|
difficulty: U256::zero(),
|
|
|
|
gas_limit: U256::zero(),
|
|
|
|
number: 0,
|
|
|
|
timestamp: 0,
|
|
|
|
code: vec![]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
/// Should be used to convert jit types to ethcore
|
2015-12-28 22:37:15 +01:00
|
|
|
trait FromJit<T>: Sized {
|
2015-12-23 13:49:45 +01:00
|
|
|
fn from_jit(input: T) -> Self;
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
/// Should be used to covert ethcore types to jit
|
2015-12-28 22:37:15 +01:00
|
|
|
trait IntoJit<T> {
|
2015-12-23 13:49:45 +01:00
|
|
|
fn into_jit(self) -> T;
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
impl<'a> FromJit<&'a evmjit::I256> for U256 {
|
|
|
|
fn from_jit(input: &'a evmjit::I256) -> Self {
|
2015-12-30 12:03:40 +01:00
|
|
|
unsafe {
|
|
|
|
let mut res: U256 = mem::uninitialized();
|
|
|
|
ptr::copy(input.words.as_ptr(), res.0.as_mut_ptr(), 4);
|
|
|
|
res
|
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
impl<'a> FromJit<&'a evmjit::I256> for H256 {
|
|
|
|
fn from_jit(input: &'a evmjit::I256) -> Self {
|
2015-12-23 13:02:01 +01:00
|
|
|
let u = U256::from_jit(input);
|
|
|
|
H256::from(&u)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-29 12:04:03 +01:00
|
|
|
impl<'a> FromJit<&'a evmjit::I256> for Address {
|
|
|
|
fn from_jit(input: &'a evmjit::I256) -> Self {
|
|
|
|
Address::from(H256::from_jit(input))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-06 13:00:14 +01:00
|
|
|
impl<'a> FromJit<&'a evmjit::H256> for H256 {
|
|
|
|
fn from_jit(input: &'a evmjit::H256) -> Self {
|
|
|
|
H256::from_jit(&evmjit::I256::from(input.clone()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-05 20:24:43 +01:00
|
|
|
impl<'a> FromJit<&'a evmjit::H256> for Address {
|
|
|
|
fn from_jit(input: &'a evmjit::H256) -> Self {
|
2016-01-06 13:00:14 +01:00
|
|
|
Address::from(H256::from_jit(input))
|
2016-01-05 20:24:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
impl IntoJit<evmjit::I256> for U256 {
|
2015-12-23 13:02:01 +01:00
|
|
|
fn into_jit(self) -> evmjit::I256 {
|
2015-12-30 12:03:40 +01:00
|
|
|
unsafe {
|
|
|
|
let mut res: evmjit::I256 = mem::uninitialized();
|
|
|
|
ptr::copy(self.0.as_ptr(), res.words.as_mut_ptr(), 4);
|
|
|
|
res
|
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
impl IntoJit<evmjit::I256> for H256 {
|
2015-12-23 13:02:01 +01:00
|
|
|
fn into_jit(self) -> evmjit::I256 {
|
|
|
|
let mut ret = [0; 4];
|
|
|
|
for i in 0..self.bytes().len() {
|
|
|
|
let rev = self.bytes().len() - 1 - i;
|
2015-12-30 12:03:40 +01:00
|
|
|
let pos = rev / 8;
|
2015-12-23 13:02:01 +01:00
|
|
|
ret[pos] += (self.bytes()[i] as u64) << (rev % 8) * 8;
|
|
|
|
}
|
|
|
|
evmjit::I256 { words: ret }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-06 17:53:59 +01:00
|
|
|
impl IntoJit<evmjit::H256> for H256 {
|
|
|
|
fn into_jit(self) -> evmjit::H256 {
|
|
|
|
let i: evmjit::I256 = self.into_jit();
|
|
|
|
From::from(i)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-24 01:07:46 +01:00
|
|
|
impl IntoJit<evmjit::I256> for Address {
|
|
|
|
fn into_jit(self) -> evmjit::I256 {
|
|
|
|
H256::from(self).into_jit()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-06 20:00:32 +01:00
|
|
|
impl IntoJit<evmjit::H256> for Address {
|
|
|
|
fn into_jit(self) -> evmjit::H256 {
|
|
|
|
H256::from(self).into_jit()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-09 00:55:17 +01:00
|
|
|
impl IntoJit<evmjit::RuntimeDataHandle> for RuntimeData {
|
2015-12-24 01:07:46 +01:00
|
|
|
fn into_jit(self) -> evmjit::RuntimeDataHandle {
|
|
|
|
let mut data = evmjit::RuntimeDataHandle::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
assert!(self.gas <= U256::from(u64::max_value()), "evmjit gas must be lower than 2 ^ 64");
|
|
|
|
assert!(self.gas_price <= U256::from(u64::max_value()), "evmjit gas_price must be lower than 2 ^ 64");
|
|
|
|
data.gas = self.gas.low_u64() as i64;
|
|
|
|
data.gas_price = self.gas_price.low_u64() as i64;
|
2015-12-24 01:07:46 +01:00
|
|
|
data.call_data = self.call_data.as_ptr();
|
|
|
|
data.call_data_size = self.call_data.len() as u64;
|
|
|
|
mem::forget(self.call_data);
|
|
|
|
data.address = self.address.into_jit();
|
|
|
|
data.caller = self.caller.into_jit();
|
|
|
|
data.origin = self.origin.into_jit();
|
|
|
|
data.call_value = self.call_value.into_jit();
|
|
|
|
data.coinbase = self.coinbase.into_jit();
|
|
|
|
data.difficulty = self.difficulty.into_jit();
|
|
|
|
data.gas_limit = self.gas_limit.into_jit();
|
|
|
|
data.number = self.number;
|
|
|
|
data.timestamp = self.timestamp as i64;
|
|
|
|
data.code = self.code.as_ptr();
|
|
|
|
data.code_size = self.code.len() as u64;
|
|
|
|
data.code_hash = self.code.sha3().into_jit();
|
|
|
|
mem::forget(self.code);
|
|
|
|
data
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-11 15:55:54 +01:00
|
|
|
/// Externalities adapter. Maps callbacks from evmjit to externalities trait.
|
|
|
|
///
|
|
|
|
/// Evmjit doesn't have to know about children execution failures.
|
|
|
|
/// This adapter 'catches' them and moves upstream.
|
2016-01-07 19:20:23 +01:00
|
|
|
struct ExtAdapter<'a> {
|
2016-01-11 14:08:03 +01:00
|
|
|
ext: &'a mut evm::Ext,
|
2016-01-11 17:01:42 +01:00
|
|
|
err: &'a mut Option<evm::Error>
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
|
2016-01-07 19:20:23 +01:00
|
|
|
impl<'a> ExtAdapter<'a> {
|
2016-01-11 17:01:42 +01:00
|
|
|
fn new(ext: &'a mut evm::Ext, err: &'a mut Option<evm::Error>) -> Self {
|
2016-01-07 19:20:23 +01:00
|
|
|
ExtAdapter {
|
2016-01-11 14:08:03 +01:00
|
|
|
ext: ext,
|
|
|
|
err: err
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-07 19:20:23 +01:00
|
|
|
impl<'a> evmjit::Ext for ExtAdapter<'a> {
|
2015-12-23 13:02:01 +01:00
|
|
|
fn sload(&self, index: *const evmjit::I256, out_value: *mut evmjit::I256) {
|
|
|
|
unsafe {
|
|
|
|
let i = H256::from_jit(&*index);
|
2016-01-07 19:20:23 +01:00
|
|
|
let o = self.ext.sload(&i);
|
2015-12-23 13:02:01 +01:00
|
|
|
*out_value = o.into_jit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sstore(&mut self, index: *const evmjit::I256, value: *const evmjit::I256) {
|
|
|
|
unsafe {
|
2016-01-07 19:20:23 +01:00
|
|
|
self.ext.sstore(H256::from_jit(&*index), H256::from_jit(&*value));
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-05 20:24:43 +01:00
|
|
|
fn balance(&self, address: *const evmjit::H256, out_value: *mut evmjit::I256) {
|
2015-12-29 12:04:03 +01:00
|
|
|
unsafe {
|
|
|
|
let a = Address::from_jit(&*address);
|
2016-01-07 19:20:23 +01:00
|
|
|
let o = self.ext.balance(&a);
|
2015-12-29 12:04:03 +01:00
|
|
|
*out_value = o.into_jit();
|
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
|
2016-01-06 17:53:59 +01:00
|
|
|
fn blockhash(&self, number: *const evmjit::I256, out_hash: *mut evmjit::H256) {
|
2015-12-29 12:04:03 +01:00
|
|
|
unsafe {
|
|
|
|
let n = U256::from_jit(&*number);
|
2016-01-07 19:20:23 +01:00
|
|
|
let o = self.ext.blockhash(&n);
|
2015-12-29 12:04:03 +01:00
|
|
|
*out_hash = o.into_jit();
|
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn create(&mut self,
|
2016-01-06 20:00:32 +01:00
|
|
|
io_gas: *mut u64,
|
|
|
|
endowment: *const evmjit::I256,
|
|
|
|
init_beg: *const u8,
|
|
|
|
init_size: u64,
|
|
|
|
address: *mut evmjit::H256) {
|
|
|
|
unsafe {
|
2016-01-09 23:24:01 +01:00
|
|
|
match self.ext.create(*io_gas, &U256::from_jit(&*endowment), slice::from_raw_parts(init_beg, init_size as usize)) {
|
2016-01-11 14:08:03 +01:00
|
|
|
Ok((gas_left, opt)) => {
|
2016-01-11 03:13:41 +01:00
|
|
|
*io_gas = gas_left;
|
2016-01-11 14:08:03 +01:00
|
|
|
if let Some(addr) = opt {
|
|
|
|
*address = addr.into_jit();
|
|
|
|
}
|
2016-01-09 23:24:01 +01:00
|
|
|
},
|
2016-01-11 17:01:42 +01:00
|
|
|
Err(err @ evm::Error::OutOfGas) => {
|
2016-01-11 14:08:03 +01:00
|
|
|
*self.err = Some(err);
|
|
|
|
// hack to propagate `OutOfGas` to evmjit and stop
|
|
|
|
// the execution immediately.
|
|
|
|
// Works, cause evmjit uses i64, not u64
|
|
|
|
*io_gas = -1i64 as u64
|
|
|
|
},
|
|
|
|
Err(err) => *self.err = Some(err)
|
|
|
|
}
|
2016-01-06 20:00:32 +01:00
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn call(&mut self,
|
2016-01-06 20:00:32 +01:00
|
|
|
io_gas: *mut u64,
|
|
|
|
call_gas: u64,
|
|
|
|
receive_address: *const evmjit::H256,
|
|
|
|
value: *const evmjit::I256,
|
|
|
|
in_beg: *const u8,
|
|
|
|
in_size: u64,
|
2016-01-11 16:05:21 +01:00
|
|
|
out_beg: *mut u8,
|
2016-01-06 20:00:32 +01:00
|
|
|
out_size: u64,
|
|
|
|
code_address: *const evmjit::H256) -> bool {
|
|
|
|
unsafe {
|
2016-01-11 14:08:03 +01:00
|
|
|
let res = self.ext.call(*io_gas,
|
2016-01-06 20:00:32 +01:00
|
|
|
call_gas,
|
|
|
|
&Address::from_jit(&*receive_address),
|
|
|
|
&U256::from_jit(&*value),
|
|
|
|
slice::from_raw_parts(in_beg, in_size as usize),
|
2016-01-11 03:13:41 +01:00
|
|
|
&Address::from_jit(&*code_address),
|
|
|
|
slice::from_raw_parts_mut(out_beg, out_size as usize));
|
|
|
|
|
2016-01-11 14:08:03 +01:00
|
|
|
match res {
|
|
|
|
Ok(gas_left) => {
|
2016-01-11 03:13:41 +01:00
|
|
|
*io_gas = gas_left;
|
|
|
|
true
|
2016-01-11 14:08:03 +01:00
|
|
|
},
|
2016-01-11 17:01:42 +01:00
|
|
|
Err(err @ evm::Error::OutOfGas) => {
|
2016-01-11 14:08:03 +01:00
|
|
|
*self.err = Some(err);
|
|
|
|
// hack to propagate `OutOfGas` to evmjit and stop
|
|
|
|
// the execution immediately.
|
|
|
|
// Works, cause evmjit uses i64, not u64
|
|
|
|
*io_gas = -1i64 as u64;
|
|
|
|
false
|
|
|
|
},
|
|
|
|
Err(err) => {
|
|
|
|
*self.err = Some(err);
|
|
|
|
false
|
2016-01-11 03:13:41 +01:00
|
|
|
}
|
2016-01-06 20:00:32 +01:00
|
|
|
}
|
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn log(&mut self,
|
2016-01-06 13:00:14 +01:00
|
|
|
beg: *const u8,
|
|
|
|
size: u64,
|
|
|
|
topic1: *const evmjit::H256,
|
|
|
|
topic2: *const evmjit::H256,
|
|
|
|
topic3: *const evmjit::H256,
|
|
|
|
topic4: *const evmjit::H256) {
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let mut topics = vec![];
|
|
|
|
if !topic1.is_null() {
|
|
|
|
topics.push(H256::from_jit(&*topic1));
|
|
|
|
}
|
|
|
|
|
|
|
|
if !topic2.is_null() {
|
|
|
|
topics.push(H256::from_jit(&*topic2));
|
|
|
|
}
|
|
|
|
|
|
|
|
if !topic3.is_null() {
|
|
|
|
topics.push(H256::from_jit(&*topic3));
|
|
|
|
}
|
|
|
|
|
|
|
|
if !topic4.is_null() {
|
|
|
|
topics.push(H256::from_jit(&*topic4));
|
|
|
|
}
|
|
|
|
|
|
|
|
let bytes_ref: &[u8] = slice::from_raw_parts(beg, size as usize);
|
2016-01-07 19:20:23 +01:00
|
|
|
self.ext.log(topics, bytes_ref.to_vec());
|
2016-01-06 13:00:14 +01:00
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
|
2016-01-05 20:24:43 +01:00
|
|
|
fn extcode(&self, address: *const evmjit::H256, size: *mut u64) -> *const u8 {
|
2016-01-05 18:43:46 +01:00
|
|
|
unsafe {
|
2016-01-07 19:20:23 +01:00
|
|
|
let code = self.ext.extcode(&Address::from_jit(&*address));
|
2016-01-05 18:43:46 +01:00
|
|
|
*size = code.len() as u64;
|
|
|
|
let ptr = code.as_ptr();
|
|
|
|
mem::forget(code);
|
|
|
|
ptr
|
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-28 22:37:15 +01:00
|
|
|
pub struct JitEvm;
|
|
|
|
|
|
|
|
impl evm::Evm for JitEvm {
|
2016-01-11 17:49:49 +01:00
|
|
|
fn exec(&self, params: &ActionParams, ext: &mut evm::Ext) -> evm::Result {
|
2016-01-11 14:08:03 +01:00
|
|
|
let mut optional_err = None;
|
2015-12-28 22:37:15 +01:00
|
|
|
// Dirty hack. This is unsafe, but we interact with ffi, so it's justified.
|
2016-01-11 14:08:03 +01:00
|
|
|
let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext, &mut optional_err)) };
|
2016-01-07 19:20:23 +01:00
|
|
|
let mut ext_handle = evmjit::ExtHandle::new(ext_adapter);
|
2016-01-09 00:55:17 +01:00
|
|
|
let mut data = RuntimeData::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
data.gas = params.gas;
|
|
|
|
data.gas_price = params.gas_price;
|
|
|
|
data.call_data = params.data.clone();
|
|
|
|
data.address = params.address.clone();
|
|
|
|
data.caller = params.sender.clone();
|
|
|
|
data.origin = params.origin.clone();
|
|
|
|
data.call_value = params.value;
|
|
|
|
data.code = params.code.clone();
|
|
|
|
|
|
|
|
// TODO:
|
|
|
|
data.coinbase = Address::new();
|
|
|
|
data.difficulty = U256::zero();
|
|
|
|
data.gas_limit = U256::zero();
|
|
|
|
data.number = 0;
|
|
|
|
data.timestamp = 0;
|
|
|
|
|
2016-01-07 19:20:23 +01:00
|
|
|
let mut context = unsafe { evmjit::ContextHandle::new(data.into_jit(), &mut ext_handle) };
|
2016-01-11 14:08:03 +01:00
|
|
|
let res = context.exec();
|
|
|
|
|
|
|
|
// check in adapter if execution of children contracts failed.
|
|
|
|
if let Some(err) = optional_err {
|
|
|
|
return Err(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
match res {
|
2016-01-11 03:13:41 +01:00
|
|
|
evmjit::ReturnCode::Stop => Ok(U256::from(context.gas_left())),
|
2016-01-11 14:14:35 +01:00
|
|
|
evmjit::ReturnCode::Return => ext.ret(context.gas_left(), context.output_data()).map(|gas_left| U256::from(gas_left)),
|
2016-01-11 02:17:29 +01:00
|
|
|
evmjit::ReturnCode::Suicide => {
|
|
|
|
// what if there is a suicide and we run out of gas just after?
|
|
|
|
ext.suicide();
|
2016-01-11 03:13:41 +01:00
|
|
|
Ok(U256::from(context.gas_left()))
|
2016-01-11 02:17:29 +01:00
|
|
|
},
|
2016-01-11 17:01:42 +01:00
|
|
|
evmjit::ReturnCode::OutOfGas => Err(evm::Error::OutOfGas),
|
|
|
|
_err => Err(evm::Error::Internal)
|
2016-01-09 18:25:18 +01:00
|
|
|
}
|
2015-12-28 22:37:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2015-12-29 12:37:38 +01:00
|
|
|
use super::*;
|
2016-01-11 17:49:49 +01:00
|
|
|
use common::*;
|
|
|
|
use evm::jit::{FromJit, IntoJit};
|
|
|
|
use evm::{Evm,Schedule};
|
|
|
|
use executive::*;
|
2015-12-30 12:03:40 +01:00
|
|
|
use state::*;
|
2016-01-08 12:50:06 +01:00
|
|
|
use engine::*;
|
|
|
|
use spec::*;
|
|
|
|
|
2016-01-09 18:41:12 +01:00
|
|
|
struct TestEngine;
|
2016-01-08 12:50:06 +01:00
|
|
|
|
|
|
|
impl TestEngine {
|
2016-01-09 18:41:12 +01:00
|
|
|
fn new() -> Self { TestEngine }
|
2016-01-08 12:50:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Engine for TestEngine {
|
|
|
|
fn name(&self) -> &str { "TestEngine" }
|
2016-01-09 18:41:12 +01:00
|
|
|
fn spec(&self) -> &Spec { unimplemented!() }
|
2016-01-11 16:28:30 +01:00
|
|
|
fn schedule(&self, _env_info: &EnvInfo) -> Schedule { Schedule::new_frontier() }
|
2016-01-08 12:50:06 +01:00
|
|
|
}
|
2015-12-23 13:49:45 +01:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_to_and_from_u256() {
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
let u = U256::from_str("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3").unwrap();
|
|
|
|
let j = u.into_jit();
|
|
|
|
let u2 = U256::from_jit(&j);
|
|
|
|
assert_eq!(u, u2);
|
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
#[test]
|
|
|
|
fn test_to_and_from_h256() {
|
|
|
|
use std::str::FromStr;
|
2015-12-23 13:02:01 +01:00
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
let h = H256::from_str("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3").unwrap();
|
2016-01-06 17:53:59 +01:00
|
|
|
let j: ::evmjit::I256 = h.clone().into_jit();
|
2015-12-23 13:49:45 +01:00
|
|
|
let h2 = H256::from_jit(&j);
|
|
|
|
assert_eq!(h, h2);
|
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
|
2015-12-29 12:04:03 +01:00
|
|
|
#[test]
|
|
|
|
fn test_to_and_from_address() {
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
|
|
let a = Address::from_str("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba").unwrap();
|
2016-01-06 20:00:32 +01:00
|
|
|
let j: ::evmjit::I256 = a.clone().into_jit();
|
2015-12-29 12:04:03 +01:00
|
|
|
let a2 = Address::from_jit(&j);
|
|
|
|
assert_eq!(a, a2);
|
|
|
|
}
|
|
|
|
|
2015-12-23 13:49:45 +01:00
|
|
|
#[test]
|
2016-01-07 19:20:23 +01:00
|
|
|
fn test_ext_add() {
|
2015-12-30 12:03:40 +01:00
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap();
|
2015-12-30 12:03:40 +01:00
|
|
|
|
2016-01-08 00:16:15 +01:00
|
|
|
let mut state = State::new_temp();
|
|
|
|
let info = EnvInfo::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
2016-01-08 00:16:15 +01:00
|
|
|
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-08 00:16:15 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop);
|
2016-01-08 00:16:15 +01:00
|
|
|
}
|
|
|
|
|
2015-12-30 12:03:40 +01:00
|
|
|
assert_eq!(state.storage_at(&address, &H256::new()),
|
|
|
|
H256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-01-07 19:20:23 +01:00
|
|
|
fn test_ext_sha3_0() {
|
2015-12-30 12:03:40 +01:00
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "6000600020600055".from_hex().unwrap();
|
2015-12-30 12:03:40 +01:00
|
|
|
|
2016-01-08 00:16:15 +01:00
|
|
|
let mut state = State::new_temp();
|
|
|
|
let info = EnvInfo::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
2016-01-08 00:16:15 +01:00
|
|
|
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-08 00:16:15 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-08 00:16:15 +01:00
|
|
|
}
|
|
|
|
|
2015-12-30 12:03:40 +01:00
|
|
|
assert_eq!(state.storage_at(&address, &H256::new()),
|
|
|
|
H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap());
|
|
|
|
}
|
2015-12-28 22:37:15 +01:00
|
|
|
|
2015-12-30 12:03:40 +01:00
|
|
|
#[test]
|
2016-01-07 19:20:23 +01:00
|
|
|
fn test_ext_sha3_1() {
|
2015-12-30 12:03:40 +01:00
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "6005600420600055".from_hex().unwrap();
|
2015-12-30 12:03:40 +01:00
|
|
|
|
2016-01-08 00:16:15 +01:00
|
|
|
let mut state = State::new_temp();
|
|
|
|
let info = EnvInfo::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
2016-01-08 00:16:15 +01:00
|
|
|
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-08 00:16:15 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-08 00:16:15 +01:00
|
|
|
}
|
|
|
|
|
2015-12-30 12:03:40 +01:00
|
|
|
assert_eq!(state.storage_at(&address, &H256::new()),
|
|
|
|
H256::from_str("c41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec").unwrap());
|
2015-12-23 13:49:45 +01:00
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
|
2016-01-05 18:43:46 +01:00
|
|
|
#[test]
|
|
|
|
fn test_origin() {
|
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.origin = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "32600055".from_hex().unwrap();
|
2016-01-05 18:43:46 +01:00
|
|
|
|
2016-01-08 00:16:15 +01:00
|
|
|
let mut state = State::new_temp();
|
|
|
|
let info = EnvInfo::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
2016-01-08 00:16:15 +01:00
|
|
|
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-08 00:16:15 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-08 00:16:15 +01:00
|
|
|
}
|
|
|
|
|
2016-01-05 18:43:46 +01:00
|
|
|
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-01-09 00:51:09 +01:00
|
|
|
fn test_sender() {
|
2016-01-05 18:43:46 +01:00
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.sender = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "32600055".from_hex().unwrap();
|
|
|
|
params.code = "33600055".from_hex().unwrap();
|
2016-01-05 18:43:46 +01:00
|
|
|
|
2016-01-08 00:16:15 +01:00
|
|
|
let mut state = State::new_temp();
|
|
|
|
let info = EnvInfo::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
2016-01-08 00:16:15 +01:00
|
|
|
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-08 00:16:15 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-08 00:16:15 +01:00
|
|
|
}
|
|
|
|
|
2016-01-05 18:43:46 +01:00
|
|
|
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_extcode_copy0() {
|
2016-01-09 00:51:09 +01:00
|
|
|
// 33 - sender
|
2016-01-05 18:43:46 +01:00
|
|
|
// 3b - extcodesize
|
|
|
|
// 60 00 - push 0
|
|
|
|
// 60 00 - push 0
|
2016-01-09 00:51:09 +01:00
|
|
|
// 33 - sender
|
2016-01-05 18:43:46 +01:00
|
|
|
// 3c - extcodecopy
|
|
|
|
// 60 00 - push 0
|
|
|
|
// 51 - load word from memory
|
|
|
|
// 60 00 - push 0
|
|
|
|
// 55 - sstore
|
|
|
|
|
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-09 00:51:09 +01:00
|
|
|
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
2016-01-05 18:43:46 +01:00
|
|
|
let address_code = "333b60006000333c600051600055".from_hex().unwrap();
|
2016-01-09 00:51:09 +01:00
|
|
|
let sender_code = "6005600055".from_hex().unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.sender = sender.clone();
|
|
|
|
params.origin = sender.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = address_code.clone();
|
2016-01-05 18:43:46 +01:00
|
|
|
|
|
|
|
let mut state = State::new_temp();
|
2016-01-09 18:41:12 +01:00
|
|
|
state.init_code(&address, address_code);
|
|
|
|
state.init_code(&sender, sender_code);
|
2016-01-08 00:16:15 +01:00
|
|
|
let info = EnvInfo::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
2016-01-08 00:16:15 +01:00
|
|
|
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-08 00:16:15 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-08 00:16:15 +01:00
|
|
|
}
|
|
|
|
|
2016-01-09 00:51:09 +01:00
|
|
|
assert_eq!(state.storage_at(&address, &H256::new()),
|
2016-01-05 18:43:46 +01:00
|
|
|
H256::from_str("6005600055000000000000000000000000000000000000000000000000000000").unwrap());
|
|
|
|
}
|
2016-01-06 10:37:21 +01:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_balance() {
|
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.sender = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "3331600055".from_hex().unwrap();
|
2016-01-06 10:37:21 +01:00
|
|
|
|
|
|
|
let mut state = State::new_temp();
|
|
|
|
state.add_balance(&address, &U256::from(0x10));
|
2016-01-08 00:16:15 +01:00
|
|
|
let info = EnvInfo::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
2016-01-08 00:16:15 +01:00
|
|
|
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-08 00:16:15 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-08 00:16:15 +01:00
|
|
|
}
|
|
|
|
|
2016-01-06 10:37:21 +01:00
|
|
|
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0x10)));
|
|
|
|
}
|
2016-01-06 13:00:14 +01:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_empty_log() {
|
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "60006000a0".from_hex().unwrap();
|
2016-01-06 13:00:14 +01:00
|
|
|
|
2016-01-08 00:16:15 +01:00
|
|
|
let mut state = State::new_temp();
|
|
|
|
let info = EnvInfo::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-09 23:24:01 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-09 23:24:01 +01:00
|
|
|
}
|
|
|
|
let logs = substate.logs();
|
2016-01-06 13:00:14 +01:00
|
|
|
assert_eq!(logs.len(), 1);
|
|
|
|
let log = &logs[0];
|
|
|
|
assert_eq!(log.address(), &address);
|
|
|
|
assert_eq!(log.topics().len(), 0);
|
|
|
|
assert_eq!(log.bloom(), H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_log_with_one_topic() {
|
|
|
|
// 60 ff - push ff
|
|
|
|
// 60 00 - push 00
|
|
|
|
// 53 - mstore
|
2016-01-09 00:51:09 +01:00
|
|
|
// 33 - sender
|
2016-01-06 13:00:14 +01:00
|
|
|
// 60 20 - push 20
|
|
|
|
// 60 00 - push 0
|
|
|
|
// a1 - log with 1 topic
|
|
|
|
|
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.sender = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "60ff6000533360206000a1".from_hex().unwrap();
|
2016-01-06 13:00:14 +01:00
|
|
|
|
2016-01-08 00:16:15 +01:00
|
|
|
let mut state = State::new_temp();
|
|
|
|
let info = EnvInfo::new();
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-09 23:24:01 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-09 23:24:01 +01:00
|
|
|
}
|
|
|
|
let logs = substate.logs();
|
2016-01-06 13:00:14 +01:00
|
|
|
assert_eq!(logs.len(), 1);
|
|
|
|
let log = &logs[0];
|
|
|
|
assert_eq!(log.address(), &address);
|
|
|
|
assert_eq!(log.topics().len(), 1);
|
|
|
|
let topic = &log.topics()[0];
|
2016-01-06 13:09:41 +01:00
|
|
|
assert_eq!(topic, &H256::from_str("0000000000000000000000000f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap());
|
2016-01-06 13:00:14 +01:00
|
|
|
assert_eq!(topic, &H256::from(address.clone()));
|
2016-01-06 13:09:41 +01:00
|
|
|
assert_eq!(log.data(), &"ff00000000000000000000000000000000000000000000000000000000000000".from_hex().unwrap());
|
2016-01-06 13:00:14 +01:00
|
|
|
}
|
2016-01-06 17:53:59 +01:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_blockhash() {
|
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 00:51:09 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "600040600055".from_hex().unwrap();
|
2016-01-06 17:53:59 +01:00
|
|
|
|
2016-01-08 00:16:15 +01:00
|
|
|
let mut state = State::new_temp();
|
2016-01-06 17:53:59 +01:00
|
|
|
let mut info = EnvInfo::new();
|
2016-01-11 15:23:27 +01:00
|
|
|
info.number = 1;
|
2016-01-06 17:53:59 +01:00
|
|
|
info.last_hashes.push(H256::from(address.clone()));
|
2016-01-08 12:50:06 +01:00
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
2016-01-08 00:16:15 +01:00
|
|
|
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-08 00:16:15 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-08 00:16:15 +01:00
|
|
|
}
|
|
|
|
|
2016-01-06 17:53:59 +01:00
|
|
|
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone()));
|
|
|
|
}
|
2016-01-09 13:51:59 +01:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_calldataload() {
|
|
|
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
2016-01-11 16:33:08 +01:00
|
|
|
let mut params = ActionParams::new();
|
2016-01-09 13:51:59 +01:00
|
|
|
params.address = address.clone();
|
|
|
|
params.gas = U256::from(0x174876e800u64);
|
|
|
|
params.code = "600135600055".from_hex().unwrap();
|
|
|
|
params.data = "0123ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23".from_hex().unwrap();
|
|
|
|
|
|
|
|
let mut state = State::new_temp();
|
|
|
|
let mut info = EnvInfo::new();
|
2016-01-11 15:23:27 +01:00
|
|
|
info.number = 1;
|
2016-01-09 13:51:59 +01:00
|
|
|
info.last_hashes.push(H256::from(address.clone()));
|
|
|
|
let engine = TestEngine::new();
|
2016-01-09 23:24:01 +01:00
|
|
|
let mut substate = Substate::new();
|
2016-01-09 13:51:59 +01:00
|
|
|
|
|
|
|
{
|
2016-01-11 03:13:41 +01:00
|
|
|
let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract);
|
2016-01-09 13:51:59 +01:00
|
|
|
let evm = JitEvm;
|
2016-01-10 16:21:01 +01:00
|
|
|
let _res = evm.exec(¶ms, &mut ext);
|
2016-01-11 17:01:42 +01:00
|
|
|
//assert_eq!(evm.exec(¶ms, &mut ext), Result::Stop {});
|
2016-01-09 13:51:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23").unwrap());
|
|
|
|
}
|
2015-12-23 13:02:01 +01:00
|
|
|
}
|