call result
This commit is contained in:
parent
6fb580f621
commit
9cbf2427c0
@ -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<Address>);
|
||||
|
||||
/// 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<CallResult>;
|
||||
output: &mut [u8]) -> Result<(U256, bool), Error>;
|
||||
|
||||
/// Returns code at given address
|
||||
fn extcode(&self, address: &Address) -> Vec<u8>;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use common::*;
|
||||
use evm;
|
||||
use evm::{Ext, Schedule, Factory, CallResult};
|
||||
use evm::{Ext, Schedule, Factory};
|
||||
|
||||
struct FakeLogEntry {
|
||||
topics: Vec<H256>,
|
||||
@ -53,7 +53,7 @@ impl Ext for FakeExt {
|
||||
_value: &U256,
|
||||
_data: &[u8],
|
||||
_code_address: &Address,
|
||||
_output: &mut [u8]) -> Option<CallResult> {
|
||||
_output: &mut [u8]) -> result::Result<(U256, bool), evm::Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
@ -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<CallResult> {
|
||||
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)
|
||||
|
@ -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<CallResult> {
|
||||
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<u8> {
|
||||
|
Loading…
Reference in New Issue
Block a user