diff --git a/src/evm/ext.rs b/src/evm/ext.rs
index 9365c40a0..ca06b5086 100644
--- a/src/evm/ext.rs
+++ b/src/evm/ext.rs
@@ -6,20 +6,6 @@ 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;
@@ -35,12 +21,12 @@ pub trait Ext {
/// Creates new contract.
///
- /// Return gas_left and contract address if contract creation was succesfull.
+ /// Returns gas_left and contract address if contract creation was succesfull.
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> (U256, Option
);
/// Message call.
///
- /// Returns None, if we run out of gas.
+ /// Returns Err, if we run out of gas.
/// Otherwise returns call_result which contains gas left
/// and true if subcall was successfull.
fn call(&mut self,
@@ -50,7 +36,7 @@ pub trait Ext {
value: &U256,
data: &[u8],
code_address: &Address,
- output: &mut [u8]) -> Option;
+ output: &mut [u8]) -> Result<(U256, bool), Error>;
/// Returns code at given address
fn extcode(&self, address: &Address) -> Vec;
diff --git a/src/evm/jit.rs b/src/evm/jit.rs
index 4cb2e763e..c997ac89b 100644
--- a/src/evm/jit.rs
+++ b/src/evm/jit.rs
@@ -229,21 +229,29 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> {
out_size: u64,
code_address: *const evmjit::H256) -> bool {
unsafe {
- let opt = self.ext.call(&U256::from(*io_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),
&Address::from_jit(&*code_address),
slice::from_raw_parts_mut(out_beg, out_size as usize));
- match opt {
- None => {
+ match res {
+ Ok((gas_left, ok)) => {
+ *io_gas = gas_left.low_u64();
+ ok
+ }
+ Err(evm::Error::OutOfGas) => {
+ // hack to propagate out_of_gas to evmjit.
+ // must be negative
*io_gas = -1i64 as u64;
false
},
- Some(res) => {
- *io_gas = res.gas_left.low_u64();
- res.success
+ Err(err) => {
+ // internal error.
+ *self.err = Some(err);
+ *io_gas = -1i64 as u64;
+ false
}
}
}
diff --git a/src/evm/mod.rs b/src/evm/mod.rs
index d0635a017..e84e133c5 100644
--- a/src/evm/mod.rs
+++ b/src/evm/mod.rs
@@ -11,6 +11,6 @@ mod jit;
mod tests;
pub use self::evm::{Evm, Error, Result};
-pub use self::ext::{Ext, CallResult};
+pub use self::ext::{Ext};
pub use self::factory::Factory;
pub use self::schedule::Schedule;
diff --git a/src/evm/tests.rs b/src/evm/tests.rs
index f06d55943..648d35646 100644
--- a/src/evm/tests.rs
+++ b/src/evm/tests.rs
@@ -1,6 +1,6 @@
use common::*;
use evm;
-use evm::{Ext, Schedule, Factory, CallResult};
+use evm::{Ext, Schedule, Factory};
struct FakeLogEntry {
topics: Vec,
@@ -53,7 +53,7 @@ impl Ext for FakeExt {
_value: &U256,
_data: &[u8],
_code_address: &Address,
- _output: &mut [u8]) -> Option {
+ _output: &mut [u8]) -> result::Result<(U256, bool), evm::Error> {
unimplemented!();
}
diff --git a/src/executive.rs b/src/executive.rs
index e0531fdae..c9a829f8a 100644
--- a/src/executive.rs
+++ b/src/executive.rs
@@ -2,7 +2,7 @@
use common::*;
use state::*;
use engine::*;
-use evm::{self, Schedule, Factory, Ext, CallResult};
+use evm::{self, Schedule, Factory, Ext};
/// Returns new address created from address and given nonce.
pub fn contract_address(address: &Address, nonce: &U256) -> Address {
@@ -408,7 +408,7 @@ impl<'a> Ext for Externalities<'a> {
value: &U256,
data: &[u8],
code_address: &Address,
- output: &mut [u8]) -> Option {
+ output: &mut [u8]) -> Result<(U256, bool), evm::Error> {
let mut gas_cost = *call_gas;
let mut call_gas = *call_gas;
@@ -425,7 +425,7 @@ impl<'a> Ext for Externalities<'a> {
if gas_cost > *gas {
self.substate.out_of_gas = true;
- return None;
+ return Err(evm::Error::OutOfGas);
//return (U256::from(-1i64 as u64), false);
}
@@ -433,8 +433,9 @@ impl<'a> Ext for Externalities<'a> {
// if balance is insufficient or we are to deep, return
if self.state.balance(&self.params.address) < *value || self.depth >= self.schedule.max_depth {
- return Some(CallResult::new(gas + call_gas, true));
+ //return Some(CallResult::new(gas + call_gas, true));
//return (gas + call_gas, true);
+ return Ok((gas + call_gas, true));
}
let params = ActionParams {
@@ -450,10 +451,11 @@ impl<'a> Ext for Externalities<'a> {
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth);
match ex.call(¶ms, self.substate, BytesRef::Fixed(output)) {
- Ok(gas_left) => Some(CallResult::new(gas + gas_left, true)),
+ Ok(gas_left) => Ok((gas + gas_left, true)), //Some(CallResult::new(gas + gas_left, true)),
_ => {
self.substate.out_of_gas = true;
- Some(CallResult::new(gas, false))
+ Ok((gas, false))
+ //Some(CallResult::new(gas, false))
}
}
//ex.call(¶ms, self.substate, BytesRef::Fixed(output)).map(|gas_left| gas + gas_left)
diff --git a/src/tests/executive.rs b/src/tests/executive.rs
index 704ce8259..073751a72 100644
--- a/src/tests/executive.rs
+++ b/src/tests/executive.rs
@@ -4,7 +4,7 @@ use executive::*;
use spec::*;
use engine::*;
use evm;
-use evm::{Schedule, Ext, Factory, CallResult};
+use evm::{Schedule, Ext, Factory};
use ethereum;
struct TestEngine {
@@ -110,10 +110,10 @@ impl<'a> Ext for TestExt<'a> {
value: &U256,
data: &[u8],
code_address: &Address,
- output: &mut [u8]) -> Option {
- let opt = self.ext.call(gas, call_gas, receive_address, value, data, code_address, output);
+ output: &mut [u8]) -> Result<(U256, bool), evm::Error> {
+ let res = self.ext.call(gas, call_gas, receive_address, value, data, code_address, output);
let ext = &self.ext;
- if let &Some(_) = &opt {
+ if let &Ok(_some) = &res {
if ext.state.balance(&ext.params.address) >= *value {
self.callcreates.push(CallCreate {
data: data.to_vec(),
@@ -123,7 +123,7 @@ impl<'a> Ext for TestExt<'a> {
});
}
}
- opt
+ res
}
fn extcode(&self, address: &Address) -> Vec {