Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.
Merged

evm #52

Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
353d4fb
evm adapter init
debris Dec 23, 2015
c695e09
docs
debris Dec 23, 2015
000d8fe
runtime_data, tests in progress
debris Dec 24, 2015
142bba0
"importing" evmjit callbacks abi
debris Dec 24, 2015
4ce53e8
updated import_evmjit_abi docs
debris Dec 24, 2015
f2ae870
fixed env address
debris Dec 28, 2015
4e31fe5
fixed signal 11 error
debris Dec 28, 2015
3dd2658
env implementation in progress
debris Dec 29, 2015
e3f59d8
vm factory
debris Dec 29, 2015
2e7f0e2
tests for sload, sstore, sha3
debris Dec 30, 2015
156fcad
docs
debris Dec 30, 2015
7f7dcef
evmjit is dynamically linked
debris Jan 4, 2016
359ba8d
extcode working
debris Jan 5, 2016
cdcabc2
Merge branch 'master' of https://github.com/gavofyork/ethcore into evm
debris Jan 5, 2016
8bc2e65
distinguish between i256 and h256 on evmjit wrapper layer
debris Jan 5, 2016
ad43079
test balance
debris Jan 6, 2016
293bca3
evm logs
debris Jan 6, 2016
b447de9
additional asserts in jit log test
debris Jan 6, 2016
a0bb106
evm env uses EnvInfo. blockhash function implementation
debris Jan 6, 2016
8c6d695
evm call and create in progress
debris Jan 6, 2016
146999c
executive init
debris Jan 7, 2016
ec720ae
env -> ext
debris Jan 7, 2016
d27a16c
executive in progress
debris Jan 7, 2016
8335d40
contract_address && ExtFace
debris Jan 7, 2016
d0180df
little improvements in evm ext
debris Jan 7, 2016
bed4bfc
executive in progress...
debris Jan 8, 2016
4932720
evm params
debris Jan 8, 2016
43c612f
moved runtime data to jit
debris Jan 8, 2016
68beb00
executive tests in progress
debris Jan 9, 2016
bcd026a
Merge branch 'master' of https://github.com/gavofyork/ethcore into evm
debris Jan 9, 2016
5ae0f71
executive create fixes
debris Jan 9, 2016
50af19a
contract creating contract
debris Jan 9, 2016
130b2fc
separated executive and externalities
debris Jan 9, 2016
300a950
evmjit output data
debris Jan 9, 2016
9cc88e2
Merge branch 'master' of https://github.com/gavofyork/ethcore into evm
debris Jan 9, 2016
f7e9816
substate in progress
debris Jan 9, 2016
3e90859
executive call
debris Jan 9, 2016
55a0235
Merge branch 'master' of https://github.com/gavofyork/ethcore into evm
debris Jan 9, 2016
efa6c42
fixed jit tests
debris Jan 9, 2016
9f06c2f
errors, fees, and refunds
debris Jan 10, 2016
b72da41
proper calculatng of executive gas in progress
debris Jan 10, 2016
b273792
big refactor of executive in progress
debris Jan 11, 2016
7f8f0c5
minor fixes
debris Jan 11, 2016
6d3097a
updated output policy docs
debris Jan 11, 2016
88409e7
refactor in progress... evmjit compiling
debris Jan 11, 2016
d1aadf4
shorter constructor for externalities
debris Jan 11, 2016
dea9ec2
removed unused stuff
debris Jan 11, 2016
bbb25fb
propagate evmjit errors upstream
debris Jan 11, 2016
22859a0
changes in executive return
debris Jan 11, 2016
f611b6c
state clone
debris Jan 11, 2016
65bce78
Merge branch 'master' into evm
debris Jan 11, 2016
3f725ce
reverting the execution state when out of gas
debris Jan 11, 2016
f19a6e5
removed warnings
debris Jan 11, 2016
85ac9af
Move EvmSchedule -> evm::Schedule
gavofyork Jan 11, 2016
b0ccedd
Move evm::EvmParams -> ActionParams.
gavofyork Jan 11, 2016
0cc5748
Move Executive down, remove unneeded Evm prefixes.
gavofyork Jan 11, 2016
7650dea
Bring in Executive.
gavofyork Jan 11, 2016
0004ed8
Integrate Executive into State.
gavofyork Jan 11, 2016
1d81b4f
EVMJIT build fixes.
gavofyork Jan 11, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion rust-evmjit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ version = "0.1.0"
authors = ["debris <marek.kotewicz@gmail.com>"]

[dependencies]
libc = "0.2.2"
tiny-keccak = "1.0"
106 changes: 82 additions & 24 deletions rust-evmjit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
//!
//! ```

extern crate libc;
extern crate tiny_keccak;

use std::ops::{Deref, DerefMut};
use self::ffi::*;

pub use self::ffi::JitReturnCode as ReturnCode;
pub use self::ffi::JitI256 as I256;

/// Component oriented safe handle to `JitRuntimeData`.
pub struct RuntimeDataHandle {
Expand Down Expand Up @@ -51,20 +51,38 @@ impl Drop for RuntimeDataHandle {
}
}

impl Deref for RuntimeDataHandle {
type Target = JitRuntimeData;

fn deref(&self) -> &Self::Target {
self.runtime_data()
}
}

impl DerefMut for RuntimeDataHandle {
fn deref_mut(&mut self) -> &mut Self::Target {
self.mut_runtime_data()
}
}

/// Safe handle for jit context.
pub struct ContextHandle {
context: *mut JitContext,
_data_handle: RuntimeDataHandle
data_handle: RuntimeDataHandle,
}

impl ContextHandle {
/// Creates new context handle.
pub fn new(mut data_handle: RuntimeDataHandle, mut env: EnvHandle) -> Self {
let context = unsafe { evmjit_create_context(data_handle.mut_runtime_data(), &mut env) };
ContextHandle {
context: context,
_data_handle: data_handle
}
/// This function is unsafe cause env lifetime is not considered
pub unsafe fn new(data_handle: RuntimeDataHandle, env: &mut EnvHandle) -> Self {
import_evmjit_abi();
let mut handle = ContextHandle {
context: std::mem::uninitialized(),
data_handle: data_handle,
};

handle.context = evmjit_create_context(handle.data_handle.mut_runtime_data(), env);
handle
}

/// Executes context.
Expand Down Expand Up @@ -139,7 +157,7 @@ impl Deref for EnvHandle {
fn deref(&self) -> &Self::Target {
match self.env_impl {
Some(ref env) => env,
None => { panic!(); }
None => { panic!("Handle is empty!"); }
}
}
}
Expand All @@ -148,15 +166,14 @@ impl DerefMut for EnvHandle {
fn deref_mut(&mut self) -> &mut Self::Target {
match self.env_impl {
Some(ref mut env) => env,
None => { panic!(); }
None => { panic!("Handle is empty!"); }
}
}
}

/// ffi functions
pub mod ffi {
use std::slice;
use libc;
use tiny_keccak::Keccak;
use super::*;

Expand All @@ -178,17 +195,19 @@ pub mod ffi {
}

#[repr(C)]
#[derive(Debug)]
/// Signed 256 bit integer.
pub struct JitI256 {
pub words: [u64; 4]
}

#[repr(C)]
#[derive(Debug)]
/// Jit runtime data.
pub struct JitRuntimeData {
pub gas: i64,
pub gas_price: i64,
pub call_data: *const libc::c_char,
pub call_data: *const u8,
pub call_data_size: u64,
pub address: JitI256,
pub caller: JitI256,
Expand All @@ -199,37 +218,73 @@ pub mod ffi {
pub gas_limit: JitI256,
pub number: u64,
pub timestamp: i64,
pub code: *const libc::c_char,
pub code: *const u8,
pub code_size: u64,
pub code_hash: JitI256
}

/// Dumb function to "import" c abi in libraries
/// which inherit from this library.
///
/// It needs to be compiled as a part of main executable.
///
/// To verify that c abi is "imported" correctly, run:
///
/// ```bash
/// nm your_executable -g | grep env
/// ```
///
/// It should give the following output:
///
/// ```bash
/// 00000001000779e0 T _env_balance
/// 0000000100077a10 T _env_blockhash
/// 0000000100077a90 T _env_call
/// 0000000100077a40 T _env_create
/// 0000000100077b50 T _env_extcode
/// 0000000100077b80 T _env_log
/// 0000000100077b20 T _env_sha3
/// 0000000100077980 T _env_sload
/// 00000001000779b0 T _env_sstore
/// ```
pub fn import_evmjit_abi() {
let _env_sload = env_sload;
let _env_sstore = env_sstore;
let _env_balance = env_balance;
let _env_blockhash = env_blockhash;
let _env_create = env_create;
let _env_call = env_call;
let _env_sha3 = env_sha3;
let _env_extcode = env_extcode;
let _env_log = env_log;
}

#[no_mangle]
pub unsafe extern fn env_sload(env: *const EnvHandle, index: *const JitI256, out_value: *mut JitI256) {
pub unsafe extern "C" fn env_sload(env: *const EnvHandle, index: *const JitI256, out_value: *mut JitI256) {
let env = &*env;
env.sload(index, out_value);
}

#[no_mangle]
pub unsafe extern fn env_sstore(env: *mut EnvHandle, index: *const JitI256, value: *const JitI256) {
pub unsafe extern "C" fn env_sstore(env: *mut EnvHandle, index: *mut JitI256, value: *mut JitI256) {
let env = &mut *env;
env.sstore(index, value);
}

#[no_mangle]
pub unsafe extern fn env_balance(env: *const EnvHandle, address: *const JitI256, out_value: *mut JitI256) {
pub unsafe extern "C" fn env_balance(env: *const EnvHandle, address: *const JitI256, out_value: *mut JitI256) {
let env = &*env;
env.balance(address, out_value);
}

#[no_mangle]
pub unsafe extern fn env_blockhash(env: *const EnvHandle, number: *const JitI256, out_hash: *mut JitI256) {
pub unsafe extern "C" fn env_blockhash(env: *const EnvHandle, number: *const JitI256, out_hash: *mut JitI256) {
let env = &*env;
env.blockhash(number, out_hash);
}

#[no_mangle]
pub unsafe extern fn env_create(env: *mut EnvHandle,
pub unsafe extern "C" fn env_create(env: *mut EnvHandle,
io_gas: *mut u64,
endowment: *const JitI256,
init_beg: *const u8,
Expand All @@ -240,7 +295,7 @@ pub mod ffi {
}

#[no_mangle]
pub unsafe extern fn env_call(env: *mut EnvHandle,
pub unsafe extern "C" fn env_call(env: *mut EnvHandle,
io_gas: *mut u64,
call_gas: *const u64,
receive_address: *const JitI256,
Expand All @@ -255,24 +310,27 @@ pub mod ffi {
}

#[no_mangle]
pub unsafe extern fn env_sha3(begin: *const u8, size: *const u64, out_hash: *mut JitI256) {
pub unsafe extern "C" fn env_sha3(begin: *const u8, size: u64, out_hash: *mut JitI256) {
// TODO: write tests
// it may be incorrect due to endianess
// if it is, don't use `from_raw_parts`
let out_hash = &mut *out_hash;
let input = slice::from_raw_parts(begin, *size as usize);
let input = slice::from_raw_parts(begin, size as usize);
let outlen = out_hash.words.len() * 8;
let output = slice::from_raw_parts_mut(out_hash.words.as_mut_ptr() as *mut u8, outlen);
let mut sha3 = Keccak::new_sha3_256();
let mut sha3 = Keccak::new_keccak256();
sha3.update(input);
sha3.finalize(output);
}

#[no_mangle]
pub unsafe extern fn env_extcode(env: *const EnvHandle, address: *const JitI256, size: *mut u64) -> *const u8 {
pub unsafe extern "C" fn env_extcode(env: *const EnvHandle, address: *const JitI256, size: *mut u64) -> *const u8 {
let env = &*env;
env.extcode(address, size)
}

#[no_mangle]
pub unsafe extern fn env_log(env: *mut EnvHandle,
pub unsafe extern "C" fn env_log(env: *mut EnvHandle,
beg: *const u8,
size: *const u64,
topic1: *const JitI256,
Expand Down
63 changes: 63 additions & 0 deletions src/evm/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use util::hash::*;
use util::uint::*;
use state::*;

pub struct Env {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing docs.

state: State,
address: Address
}

impl Env {
pub fn new(state: State, address: Address) -> Env {
Env {
state: state,
address: address
}
}

pub fn sload(&self, index: &H256) -> H256 {
self.state.storage_at(&self.address, index)
}

pub fn sstore(&mut self, index: H256, value: H256) {
println!("index: {:?}, value: {:?}", index, value);
self.state.set_storage(&self.address, index, value)
}

pub fn balance(&self, _address: &Address) -> U256 {
unimplemented!();
}

pub fn blockhash(&self, _number: &U256) -> H256 {
unimplemented!();
}

/// Creates new contract
/// Returns new contract address gas used
pub fn create(&self, _gas: u64, _endowment: &U256, _code: &[u8]) -> (Address, u64) {
unimplemented!();
}

/// Calls existing contract
/// Returns call output and gas used
pub fn call(&self, _gas: u64, _call_gas: u64, _receive_address: &H256, _value: &U256, _data: &[u8], _code_address: &Address) -> Option<(Vec<u8>, u64)>{
unimplemented!();
}

/// Returns code at given address
pub fn extcode(&self, _address: &Address) -> Vec<u8> {
unimplemented!();
}

pub fn log(&self, _topics: &[H256], _data: &[u8]) {
unimplemented!();
}

/// Drain state
// not sure if this is the best solution, but seems to be the easiest one, mk
pub fn state(self) -> State {
self.state
}
}


16 changes: 16 additions & 0 deletions src/evm/evm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! EVM interface

use evm::{RuntimeData, Env};

#[derive(Debug, Eq, PartialEq)]
pub enum ReturnCode {
Stop,
Return,
Suicide,
OutOfGas,
InternalError
}

pub trait Evm {
fn exec(&self, data: RuntimeData, env: &mut Env) -> ReturnCode;
}
Loading