Merge branch 'master' into evm

Conflicts:
	src/evm/schedule.rs
This commit is contained in:
Tomusdrw
2016-01-13 23:53:04 +01:00
16 changed files with 930 additions and 127 deletions

View File

@@ -5,7 +5,6 @@ use util::uint::*;
use evm::{Schedule, Error};
use env_info::*;
// TODO: replace all u64 with u256
pub trait Ext {
/// Returns a value for given key.
fn sload(&self, key: &H256) -> H256;
@@ -24,20 +23,20 @@ pub trait Ext {
/// If contract creation is successfull, return gas_left and contract address,
/// If depth is too big or transfer value exceeds balance, return None
/// Otherwise return appropriate `Error`.
fn create(&mut self, gas: u64, value: &U256, code: &[u8]) -> Result<(u64, Option<Address>), Error>;
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> Result<(U256, Option<Address>), Error>;
/// Message call.
///
/// If call is successfull, returns gas left.
/// otherwise `Error`.
fn call(&mut self,
gas: u64,
call_gas: u64,
gas: &U256,
call_gas: &U256,
receive_address: &Address,
value: &U256,
data: &[u8],
code_address: &Address,
output: &mut [u8]) -> Result<u64, Error>;
output: &mut [u8]) -> Result<U256, Error>;
/// Returns code at given address
fn extcode(&self, address: &Address) -> Vec<u8>;
@@ -47,10 +46,11 @@ pub trait Ext {
/// Should be called when transaction calls `RETURN` opcode.
/// Returns gas_left if cost of returning the data is not too high.
fn ret(&mut self, gas: u64, data: &[u8]) -> Result<u64, Error>;
fn ret(&mut self, gas: &U256, data: &[u8]) -> Result<U256, Error>;
/// Should be called when contract commits suicide.
fn suicide(&mut self);
/// Address to which funds should be refunded.
fn suicide(&mut self, refund_address: &Address);
/// Returns schedule.
fn schedule(&self) -> &Schedule;

View File

@@ -209,19 +209,20 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
init_size: u64,
address: *mut evmjit::H256) {
unsafe {
match self.ext.create(*io_gas, &U256::from_jit(&*endowment), slice::from_raw_parts(init_beg, init_size as usize)) {
match self.ext.create(&U256::from(*io_gas), &U256::from_jit(&*endowment), slice::from_raw_parts(init_beg, init_size as usize)) {
Ok((gas_left, opt)) => {
*io_gas = gas_left;
if let Some(addr) = opt {
*address = addr.into_jit();
}
*io_gas = gas_left.low_u64();
*address = match opt {
Some(addr) => addr.into_jit(),
_ => Address::new().into_jit()
};
},
Err(err @ evm::Error::OutOfGas) => {
*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
*io_gas = -1i64 as u64;
},
Err(err) => *self.err = Some(err)
}
@@ -239,8 +240,8 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
out_size: u64,
code_address: *const evmjit::H256) -> bool {
unsafe {
let res = self.ext.call(*io_gas,
call_gas,
let res = self.ext.call(&U256::from(*io_gas),
&U256::from(call_gas),
&Address::from_jit(&*receive_address),
&U256::from_jit(&*value),
slice::from_raw_parts(in_beg, in_size as usize),
@@ -249,7 +250,7 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
match res {
Ok(gas_left) => {
*io_gas = gas_left;
*io_gas = gas_left.low_u64();
true
},
Err(err @ evm::Error::OutOfGas) => {
@@ -344,10 +345,9 @@ impl evm::Evm for JitEvm {
match res {
evmjit::ReturnCode::Stop => Ok(U256::from(context.gas_left())),
evmjit::ReturnCode::Return => ext.ret(context.gas_left(), context.output_data()).map(|gas_left| U256::from(gas_left)),
evmjit::ReturnCode::Return => ext.ret(&U256::from(context.gas_left()), context.output_data()),
evmjit::ReturnCode::Suicide => {
// what if there is a suicide and we run out of gas just after?
ext.suicide();
ext.suicide(&Address::from_jit(&context.suicide_refund_address()));
Ok(U256::from(context.gas_left()))
},
evmjit::ReturnCode::OutOfGas => Err(evm::Error::OutOfGas),

View File

@@ -51,18 +51,18 @@ impl Ext for FakeExt {
self.blockhashes.get(number).unwrap_or(&H256::new()).clone()
}
fn create(&mut self, _gas: u64, _value: &U256, _code: &[u8]) -> result::Result<(u64, Option<Address>), evm::Error> {
fn create(&mut self, _gas: &U256, _value: &U256, _code: &[u8]) -> result::Result<(U256, Option<Address>), evm::Error> {
unimplemented!();
}
fn call(&mut self,
_gas: u64,
_call_gas: u64,
_gas: &U256,
_call_gas: &U256,
_receive_address: &Address,
_value: &U256,
_data: &[u8],
_code_address: &Address,
_output: &mut [u8]) -> result::Result<u64, evm::Error> {
_output: &mut [u8]) -> result::Result<U256, evm::Error> {
unimplemented!();
}
@@ -77,11 +77,11 @@ impl Ext for FakeExt {
});
}
fn ret(&mut self, _gas: u64, _data: &[u8]) -> result::Result<u64, evm::Error> {
fn ret(&mut self, _gas: &U256, _data: &[u8]) -> result::Result<U256, evm::Error> {
unimplemented!();
}
fn suicide(&mut self) {
fn suicide(&mut self, _refund_address: &Address) {
unimplemented!();
}