openethereum/src/evm/jit.rs

367 lines
10 KiB
Rust
Raw Normal View History

2015-12-23 13:02:01 +01:00
use std::mem;
2015-12-30 12:03:40 +01:00
use std::ptr;
2015-12-23 13:02:01 +01:00
use evmjit;
use util::hash::*;
use util::uint::*;
use util::bytes::*;
2015-12-24 01:07:46 +01:00
use util::sha3::*;
2015-12-23 13:02:01 +01:00
use evm;
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))
}
}
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 }
}
}
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()
}
}
impl IntoJit<evmjit::RuntimeDataHandle> for evm::RuntimeData {
fn into_jit(self) -> evmjit::RuntimeDataHandle {
let mut data = evmjit::RuntimeDataHandle::new();
data.gas = self.gas as i64;
data.gas_price = self.gas_price as i64;
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
}
}
2015-12-28 22:37:15 +01:00
struct EnvAdapter<'a> {
env: &'a mut evm::Env
2015-12-23 13:02:01 +01:00
}
2015-12-28 22:37:15 +01:00
impl<'a> EnvAdapter<'a> {
fn new(env: &'a mut evm::Env) -> Self {
2015-12-23 13:02:01 +01:00
EnvAdapter {
2015-12-28 22:37:15 +01:00
env: env
2015-12-23 13:02:01 +01:00
}
}
}
2015-12-28 22:37:15 +01:00
impl<'a> evmjit::Env for EnvAdapter<'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);
let o = self.env.sload(&i);
*out_value = o.into_jit();
}
}
fn sstore(&mut self, index: *const evmjit::I256, value: *const evmjit::I256) {
unsafe {
2015-12-30 12:03:40 +01:00
self.env.sstore(H256::from_jit(&*index), H256::from_jit(&*value));
2015-12-23 13:02:01 +01:00
}
}
2015-12-29 12:04:03 +01:00
fn balance(&self, address: *const evmjit::I256, out_value: *mut evmjit::I256) {
unsafe {
let a = Address::from_jit(&*address);
let o = self.env.balance(&a);
*out_value = o.into_jit();
}
2015-12-23 13:02:01 +01:00
}
2015-12-29 12:04:03 +01:00
fn blockhash(&self, number: *const evmjit::I256, out_hash: *mut evmjit::I256) {
unsafe {
let n = U256::from_jit(&*number);
let o = self.env.blockhash(&n);
*out_hash = o.into_jit();
}
2015-12-23 13:02:01 +01:00
}
fn create(&mut self,
_io_gas: *mut u64,
_endowment: *const evmjit::I256,
_init_beg: *const u8,
_init_size: *const u64,
_address: *mut evmjit::I256) {
unimplemented!();
}
fn call(&mut self,
_io_gas: *mut u64,
_call_gas: *const u64,
_receive_address: *const evmjit::I256,
_value: *const evmjit::I256,
_in_beg: *const u8,
_in_size: *const u64,
_out_beg: *mut u8,
_out_size: *mut u64,
_code_address: evmjit::I256) -> bool {
unimplemented!();
}
fn log(&mut self,
_beg: *const u8,
_size: *const u64,
_topic1: *const evmjit::I256,
_topic2: *const evmjit::I256,
_topic3: *const evmjit::I256,
_topic4: *const evmjit::I256) {
unimplemented!();
}
2016-01-05 18:43:46 +01:00
fn extcode(&self, address: *const evmjit::I256, size: *mut u64) -> *const u8 {
unsafe {
// bytes in this callback are reverted... do not know why
// it's the same in cpp implementation
// TODO: investigate and fix it on evmjit layer
let mut a = H256::from_jit(&*address);
a.reverse();
let code = self.env.extcode(&Address::from(a));
*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
impl From<evmjit::ReturnCode> for evm::ReturnCode {
fn from(code: evmjit::ReturnCode) -> Self {
match code {
evmjit::ReturnCode::Stop => evm::ReturnCode::Stop,
evmjit::ReturnCode::Return => evm::ReturnCode::Return,
evmjit::ReturnCode::Suicide => evm::ReturnCode::Suicide,
evmjit::ReturnCode::OutOfGas => evm::ReturnCode::OutOfGas,
_ => evm::ReturnCode::InternalError
}
}
}
pub struct JitEvm;
impl evm::Evm for JitEvm {
2015-12-29 12:37:38 +01:00
fn exec(&self, data: evm::RuntimeData, env: &mut evm::Env) -> evm::ReturnCode {
2015-12-28 22:37:15 +01:00
// Dirty hack. This is unsafe, but we interact with ffi, so it's justified.
let env_adapter: EnvAdapter<'static> = unsafe { ::std::mem::transmute(EnvAdapter::new(env)) };
let mut env_handle = evmjit::EnvHandle::new(env_adapter);
let mut context = unsafe { evmjit::ContextHandle::new(data.into_jit(), &mut env_handle) };
From::from(context.exec())
}
}
2015-12-23 13:49:45 +01:00
#[cfg(test)]
mod tests {
2015-12-30 12:03:40 +01:00
use rustc_serialize::hex::FromHex;
2015-12-28 15:11:05 +01:00
use std::str::FromStr;
2015-12-23 13:49:45 +01:00
use util::hash::*;
use util::uint::*;
use evm::*;
use evm::jit::{FromJit, IntoJit};
2015-12-29 12:37:38 +01:00
use super::*;
2015-12-30 12:03:40 +01:00
use state::*;
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();
let j = h.clone().into_jit();
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();
let j = a.clone().into_jit();
let a2 = Address::from_jit(&j);
assert_eq!(a, a2);
}
2015-12-23 13:49:45 +01:00
#[test]
2015-12-30 12:03:40 +01:00
fn test_env_add() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let mut data = RuntimeData::new();
data.address = address.clone();
data.gas = 0x174876e800;
data.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap();
let mut env = Env::new(State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state();
assert_eq!(state.storage_at(&address, &H256::new()),
H256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap());
}
#[test]
fn test_env_sha3_0() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let mut data = RuntimeData::new();
data.address = address.clone();
data.gas = 0x174876e800;
data.code = "6000600020600055".from_hex().unwrap();
let mut env = Env::new(State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state();
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]
fn test_env_sha3_1() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
2015-12-24 01:07:46 +01:00
let mut data = RuntimeData::new();
2015-12-30 12:03:40 +01:00
data.address = address.clone();
2015-12-28 15:11:05 +01:00
data.gas = 0x174876e800;
2015-12-30 12:03:40 +01:00
data.code = "6005600420600055".from_hex().unwrap();
let mut env = Env::new(State::new_temp(), address.clone());
2015-12-29 12:37:38 +01:00
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
2015-12-30 12:03:40 +01:00
let state = env.state();
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();
let mut data = RuntimeData::new();
data.address = address.clone();
data.origin = address.clone();
data.gas = 0x174876e800;
data.code = "32600055".from_hex().unwrap();
let mut env = Env::new(State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state();
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
}
#[test]
fn test_caller() {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let mut data = RuntimeData::new();
data.address = address.clone();
data.caller = address.clone();
data.gas = 0x174876e800;
data.code = "33600055".from_hex().unwrap();
let mut env = Env::new(State::new_temp(), address.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state();
assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone());
}
#[test]
fn test_extcode_copy0() {
// 33 - caller
// 3b - extcodesize
// 60 00 - push 0
// 60 00 - push 0
// 33 - caller
// 3c - extcodecopy
// 60 00 - push 0
// 51 - load word from memory
// 60 00 - push 0
// 55 - sstore
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let caller = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let address_code = "333b60006000333c600051600055".from_hex().unwrap();
let caller_code = "6005600055".from_hex().unwrap();
let mut data = RuntimeData::new();
data.address = address.clone();
data.caller = caller.clone();
data.origin = caller.clone();
data.gas = 0x174876e800;
data.code = address_code.clone();
let mut state = State::new_temp();
state.set_code(&address, address_code);
state.set_code(&caller, caller_code);
let mut env = Env::new(state, caller.clone());
let evm = JitEvm;
assert_eq!(evm.exec(data, &mut env), ReturnCode::Stop);
let state = env.state();
assert_eq!(state.storage_at(&caller, &H256::new()),
H256::from_str("6005600055000000000000000000000000000000000000000000000000000000").unwrap());
}
2015-12-23 13:02:01 +01:00
}