ext call refactored

This commit is contained in:
debris
2016-01-14 19:52:40 +01:00
parent 777ac4dc87
commit 6fb580f621
6 changed files with 64 additions and 39 deletions

View File

@@ -6,6 +6,20 @@ use util::bytes::*;
use evm::{Schedule, Error};
use env_info::*;
pub struct CallResult {
pub gas_left: U256,
pub success: bool
}
impl CallResult {
pub fn new(gas_left: U256, success: bool) -> Self {
CallResult {
gas_left: gas_left,
success: success
}
}
}
pub trait Ext {
/// Returns a value for given key.
fn sload(&self, key: &H256) -> H256;
@@ -26,8 +40,9 @@ pub trait Ext {
/// Message call.
///
/// If call is successfull, returns gas left.
/// otherwise `Error`.
/// Returns None, if we run out of gas.
/// Otherwise returns call_result which contains gas left
/// and true if subcall was successfull.
fn call(&mut self,
gas: &U256,
call_gas: &U256,
@@ -35,7 +50,7 @@ pub trait Ext {
value: &U256,
data: &[u8],
code_address: &Address,
output: &mut [u8]) -> Result<U256, Error>;
output: &mut [u8]) -> Option<CallResult>;
/// Returns code at given address
fn extcode(&self, address: &Address) -> Vec<u8>;

View File

@@ -229,30 +229,21 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
out_size: u64,
code_address: *const evmjit::H256) -> bool {
unsafe {
let res = self.ext.call(&U256::from(*io_gas),
let opt = 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),
&Address::from_jit(&*code_address),
slice::from_raw_parts_mut(out_beg, out_size as usize));
match res {
Ok(gas_left) => {
*io_gas = gas_left.low_u64();
true
},
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
match opt {
None => {
*io_gas = -1i64 as u64;
false
},
Err(err) => {
*self.err = Some(err);
false
Some(res) => {
*io_gas = res.gas_left.low_u64();
res.success
}
}
}

View File

@@ -11,6 +11,6 @@ mod jit;
mod tests;
pub use self::evm::{Evm, Error, Result};
pub use self::ext::Ext;
pub use self::ext::{Ext, CallResult};
pub use self::factory::Factory;
pub use self::schedule::Schedule;

View File

@@ -1,6 +1,6 @@
use common::*;
use evm;
use evm::{Ext, Schedule, Factory};
use evm::{Ext, Schedule, Factory, CallResult};
struct FakeLogEntry {
topics: Vec<H256>,
@@ -53,7 +53,7 @@ impl Ext for FakeExt {
_value: &U256,
_data: &[u8],
_code_address: &Address,
_output: &mut [u8]) -> result::Result<U256, evm::Error> {
_output: &mut [u8]) -> Option<CallResult> {
unimplemented!();
}