diff --git a/src/evm/ext.rs b/src/evm/ext.rs index 631d4ed03..52b8af24f 100644 --- a/src/evm/ext.rs +++ b/src/evm/ext.rs @@ -6,7 +6,6 @@ use util::bytes::*; 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; @@ -25,20 +24,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
), Error>; + fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> Result<(U256, Option
), 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; + output: &mut [u8]) -> Result; /// Returns code at given address fn extcode(&self, address: &Address) -> Vec; @@ -48,7 +47,7 @@ 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; + fn ret(&mut self, gas: &U256, data: &[u8]) -> Result; /// Should be called when contract commits suicide. /// Address to which funds should be refunded. diff --git a/src/evm/jit.rs b/src/evm/jit.rs index 062eb88d1..f907c4be8 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -209,9 +209,9 @@ 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; + *io_gas = gas_left.low_u64(); *address = match opt { Some(addr) => addr.into_jit(), _ => Address::new().into_jit() @@ -240,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), @@ -250,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) => { @@ -345,7 +345,7 @@ 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 => { ext.suicide(&Address::from_jit(&context.suicide_refund_address())); Ok(U256::from(context.gas_left())) diff --git a/src/evm/tests.rs b/src/evm/tests.rs index caaa2fa9c..7aff9f407 100644 --- a/src/evm/tests.rs +++ b/src/evm/tests.rs @@ -42,18 +42,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
), evm::Error> { + fn create(&mut self, _gas: &U256, _value: &U256, _code: &[u8]) -> result::Result<(U256, Option
), 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 { + _output: &mut [u8]) -> result::Result { unimplemented!(); } @@ -68,7 +68,7 @@ impl Ext for FakeExt { }); } - fn ret(&mut self, _gas: u64, _data: &[u8]) -> result::Result { + fn ret(&mut self, _gas: &U256, _data: &[u8]) -> result::Result { unimplemented!(); } diff --git a/src/executive.rs b/src/executive.rs index a0ef89427..ea135194f 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -349,10 +349,10 @@ impl<'a> Ext for Externalities<'a> { } } - fn create(&mut self, gas: u64, value: &U256, code: &[u8]) -> Result<(u64, Option
), evm::Error> { + fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> Result<(U256, Option
), evm::Error> { // if balance is insufficient or we are to deep, return if self.state.balance(&self.params.address) < *value || self.depth >= self.schedule.stack_limit { - return Ok((gas, None)); + return Ok((*gas, None)); } // create new contract address @@ -363,7 +363,7 @@ impl<'a> Ext for Externalities<'a> { address: address.clone(), sender: self.params.address.clone(), origin: self.params.origin.clone(), - gas: U256::from(gas), + gas: *gas, gas_price: self.params.gas_price.clone(), value: value.clone(), code: code.to_vec(), @@ -372,29 +372,29 @@ impl<'a> Ext for Externalities<'a> { let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth); ex.state.inc_nonce(&self.params.address); - ex.create(¶ms, self.substate).map(|gas_left| (gas_left.low_u64(), Some(address))) + ex.create(¶ms, self.substate).map(|gas_left| (gas_left, Some(address))) } - fn call(&mut self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address, output: &mut [u8]) -> Result { - let mut gas_cost = call_gas; - let mut call_gas = call_gas; + fn call(&mut self, gas: &U256, call_gas: &U256, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address, output: &mut [u8]) -> Result { + let mut gas_cost = *call_gas; + let mut call_gas = *call_gas; let is_call = receive_address == code_address; if is_call && !self.state.exists(&code_address) { - gas_cost = gas_cost + self.schedule.call_new_account_gas as u64; + gas_cost = gas_cost + U256::from(self.schedule.call_new_account_gas); } if *value > U256::zero() { assert!(self.schedule.call_value_transfer_gas > self.schedule.call_stipend, "overflow possible"); - gas_cost = gas_cost + self.schedule.call_value_transfer_gas as u64; - call_gas = call_gas + self.schedule.call_stipend as u64; + gas_cost = gas_cost + U256::from(self.schedule.call_value_transfer_gas); + call_gas = call_gas + U256::from(self.schedule.call_stipend); } - if gas_cost > gas { + if gas_cost > *gas { return Err(evm::Error::OutOfGas) } - let gas = gas - gas_cost; + let gas = *gas - gas_cost; // if balance is insufficient or we are to deep, return if self.state.balance(&self.params.address) < *value || self.depth >= self.schedule.stack_limit { @@ -405,7 +405,7 @@ impl<'a> Ext for Externalities<'a> { address: receive_address.clone(), sender: self.params.address.clone(), origin: self.params.origin.clone(), - gas: U256::from(call_gas), + gas: call_gas, gas_price: self.params.gas_price.clone(), value: value.clone(), code: self.state.code(code_address).unwrap_or(vec![]), @@ -413,35 +413,33 @@ impl<'a> Ext for Externalities<'a> { }; let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth); - ex.call(¶ms, self.substate, BytesRef::Fixed(output)).map(|gas_left| { - gas + gas_left.low_u64() - }) + ex.call(¶ms, self.substate, BytesRef::Fixed(output)) } fn extcode(&self, address: &Address) -> Vec { self.state.code(address).unwrap_or(vec![]) } - fn ret(&mut self, gas: u64, data: &[u8]) -> Result { + fn ret(&mut self, gas: &U256, data: &[u8]) -> Result { match &mut self.output { &mut OutputPolicy::Return(BytesRef::Fixed(ref mut slice)) => unsafe { let len = cmp::min(slice.len(), data.len()); ptr::copy(data.as_ptr(), slice.as_mut_ptr(), len); - Ok(gas) + Ok(*gas) }, &mut OutputPolicy::Return(BytesRef::Flexible(ref mut vec)) => unsafe { vec.clear(); vec.reserve(data.len()); ptr::copy(data.as_ptr(), vec.as_mut_ptr(), data.len()); vec.set_len(data.len()); - Ok(gas) + Ok(*gas) }, &mut OutputPolicy::InitContract => { - let return_cost = data.len() as u64 * self.schedule.create_data_gas as u64; - if return_cost > gas { + let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas); + if return_cost > *gas { return match self.schedule.exceptional_failed_code_deposit { true => Err(evm::Error::OutOfGas), - false => Ok(gas) + false => Ok(*gas) } } let mut code = vec![]; @@ -453,7 +451,7 @@ impl<'a> Ext for Externalities<'a> { let address = &self.params.address; self.state.init_code(address, code); self.substate.contracts_created.push(address.clone()); - Ok(gas - return_cost) + Ok(*gas - return_cost) } } } diff --git a/src/tests/executive.rs b/src/tests/executive.rs index c8b916b72..cfe80dfc1 100644 --- a/src/tests/executive.rs +++ b/src/tests/executive.rs @@ -71,7 +71,7 @@ impl<'a> Ext for TestExt<'a> { self.ext.blockhash(number) } - fn create(&mut self, gas: u64, value: &U256, code: &[u8]) -> Result<(u64, Option
), evm::Error> { + fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> Result<(U256, Option
), evm::Error> { // in call and create we need to check if we exited with insufficient balance or max limit reached. // in case of reaching max depth, we should store callcreates. Otherwise, ignore. let res = self.ext.create(gas, value, code); @@ -82,7 +82,7 @@ impl<'a> Ext for TestExt<'a> { self.callcreates.push(CallCreate { data: code.to_vec(), destination: address.clone(), - _gas_limit: U256::from(gas), + _gas_limit: *gas, value: *value }); Ok((gas_left, Some(address))) @@ -94,7 +94,7 @@ impl<'a> Ext for TestExt<'a> { data: code.to_vec(), // TODO: address is not stored here? destination: Address::new(), - _gas_limit: U256::from(gas), + _gas_limit: *gas, value: *value }); Ok((gas_left, Some(address))) @@ -104,13 +104,13 @@ impl<'a> Ext for TestExt<'a> { } 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 { + output: &mut [u8]) -> Result { let res = self.ext.call(gas, call_gas, receive_address, value, data, code_address, output); let ext = &self.ext; match res { @@ -118,7 +118,7 @@ impl<'a> Ext for TestExt<'a> { self.callcreates.push(CallCreate { data: data.to_vec(), destination: receive_address.clone(), - _gas_limit: U256::from(call_gas), + _gas_limit: *call_gas, value: *value }); Ok(gas_left) @@ -135,7 +135,7 @@ impl<'a> Ext for TestExt<'a> { self.ext.log(topics, data) } - fn ret(&mut self, gas: u64, data: &[u8]) -> Result { + fn ret(&mut self, gas: &U256, data: &[u8]) -> Result { self.ext.ret(gas, data) }