From ed0e243506e59fe999707f0057f5275dde25b554 Mon Sep 17 00:00:00 2001 From: debris Date: Fri, 15 Jan 2016 15:00:28 +0100 Subject: [PATCH] callcode builtins are working --- src/action_params.rs | 12 ++++++++---- src/evm/jit.rs | 4 ++-- src/evm/tests.rs | 32 +++++++++++++++--------------- src/executive.rs | 46 ++++++++++++++++++++++++++------------------ 4 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/action_params.rs b/src/action_params.rs index c92fe4c80..372927326 100644 --- a/src/action_params.rs +++ b/src/action_params.rs @@ -9,6 +9,9 @@ use util::bytes::*; #[derive(Clone, Debug)] pub struct ActionParams { /// Address of currently executed code. + pub code_address: Address, + /// Receive address. Usually equal to code_address, + /// except when called using CALLCODE. pub address: Address, /// Sender of current part of the transaction. pub sender: Address, @@ -21,22 +24,23 @@ pub struct ActionParams { /// Transaction value. pub value: U256, /// Code being executed. - pub code: Bytes, + pub code: Option, /// Input data. - pub data: Bytes + pub data: Option } impl ActionParams { pub fn new() -> ActionParams { ActionParams { + code_address: Address::new(), address: Address::new(), sender: Address::new(), origin: Address::new(), gas: U256::zero(), gas_price: U256::zero(), value: U256::zero(), - code: vec![], - data: vec![], + code: None, + data: None } } } diff --git a/src/evm/jit.rs b/src/evm/jit.rs index 4e0bb1012..19a28de6f 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -310,12 +310,12 @@ impl evm::Evm for JitEvm { let mut data = RuntimeData::new(); data.gas = params.gas; data.gas_price = params.gas_price; - data.call_data = params.data.clone(); + data.call_data = params.data.clone().unwrap_or(vec![]); data.address = params.address.clone(); data.caller = params.sender.clone(); data.origin = params.origin.clone(); data.call_value = params.value; - data.code = params.code.clone(); + data.code = params.code.clone().unwrap_or(vec![]); data.author = ext.env_info().author.clone(); data.difficulty = ext.env_info().difficulty; diff --git a/src/evm/tests.rs b/src/evm/tests.rs index 648d35646..3ed56bc39 100644 --- a/src/evm/tests.rs +++ b/src/evm/tests.rs @@ -93,7 +93,7 @@ fn test_add() { let mut params = ActionParams::new(); params.address = address.clone(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); let gas_left = { @@ -113,7 +113,7 @@ fn test_sha3() { let mut params = ActionParams::new(); params.address = address.clone(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); let gas_left = { @@ -133,7 +133,7 @@ fn test_address() { let mut params = ActionParams::new(); params.address = address.clone(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); let gas_left = { @@ -155,7 +155,7 @@ fn test_origin() { params.address = address.clone(); params.origin = origin.clone(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); let gas_left = { @@ -177,7 +177,7 @@ fn test_sender() { params.address = address.clone(); params.sender = sender.clone(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); let gas_left = { @@ -211,7 +211,7 @@ fn test_extcodecopy() { params.address = address.clone(); params.sender = sender.clone(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); ext.codes.insert(sender, sender_code); @@ -232,7 +232,7 @@ fn test_log_empty() { let mut params = ActionParams::new(); params.address = address.clone(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); let gas_left = { @@ -264,7 +264,7 @@ fn test_log_sender() { params.address = address.clone(); params.sender = sender.clone(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); let gas_left = { @@ -288,7 +288,7 @@ fn test_blockhash() { let mut params = ActionParams::new(); params.address = address.clone(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); ext.blockhashes.insert(U256::zero(), blockhash.clone()); @@ -310,8 +310,8 @@ fn test_calldataload() { let mut params = ActionParams::new(); params.address = address.clone(); params.gas = U256::from(100_000); - params.code = code; - params.data = data; + params.code = Some(code); + params.data = Some(data); let mut ext = FakeExt::new(); let gas_left = { @@ -331,7 +331,7 @@ fn test_author() { let mut params = ActionParams::new(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); ext.info.author = author; @@ -351,7 +351,7 @@ fn test_timestamp() { let mut params = ActionParams::new(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); ext.info.timestamp = timestamp; @@ -371,7 +371,7 @@ fn test_number() { let mut params = ActionParams::new(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); ext.info.number = number; @@ -391,7 +391,7 @@ fn test_difficulty() { let mut params = ActionParams::new(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); ext.info.difficulty = difficulty; @@ -411,7 +411,7 @@ fn test_gas_limit() { let mut params = ActionParams::new(); params.gas = U256::from(100_000); - params.code = code; + params.code = Some(code); let mut ext = FakeExt::new(); ext.info.gas_limit = gas_limit; diff --git a/src/executive.rs b/src/executive.rs index 3251763f4..ea95c69e4 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -150,28 +150,31 @@ impl<'a> Executive<'a> { let res = match t.action() { &Action::Create => { + let new_address = contract_address(&sender, &nonce); let params = ActionParams { - address: contract_address(&sender, &nonce), + code_address: new_address.clone(), + address: new_address, sender: sender.clone(), origin: sender.clone(), gas: init_gas, gas_price: t.gas_price, value: t.value, - code: t.data.clone(), - data: vec![], + code: Some(t.data.clone()), + data: None, }; self.create(¶ms, &mut substate) }, &Action::Call(ref address) => { let params = ActionParams { + code_address: address.clone(), address: address.clone(), sender: sender.clone(), origin: sender.clone(), gas: init_gas, gas_price: t.gas_price, value: t.value, - code: self.state.code(address).unwrap_or(vec![]), - data: t.data.clone(), + code: self.state.code(address), + data: Some(t.data.clone()), }; // TODO: move output upstream let mut out = vec![]; @@ -194,12 +197,14 @@ impl<'a> Executive<'a> { // at first, transfer value to destination self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); - if self.engine.is_builtin(¶ms.address) { + if self.engine.is_builtin(¶ms.code_address) { + let default = []; + let data = if let &Some(ref d) = ¶ms.data { d as &[u8] } else { &default as &[u8] }; // if destination is builtin, try to execute it - let cost = self.engine.cost_of_builtin(¶ms.address, ¶ms.data); + let cost = self.engine.cost_of_builtin(¶ms.code_address, &data); match cost <= params.gas { true => { - self.engine.execute_builtin(¶ms.address, ¶ms.data, &mut output); + self.engine.execute_builtin(¶ms.code_address, &data, &mut output); Ok(params.gas - cost) }, // just drain the whole gas @@ -208,7 +213,7 @@ impl<'a> Executive<'a> { Err(evm::Error::OutOfGas) } } - } else if params.code.len() > 0 { + } else if params.code.is_some() { // if destination is a contract, do normal message call // part of substate that may be reverted @@ -411,14 +416,15 @@ impl<'a> Ext for Externalities<'a> { // prepare the params let params = ActionParams { + code_address: address.clone(), address: address.clone(), sender: self.params.address.clone(), origin: self.params.origin.clone(), gas: *gas, gas_price: self.params.gas_price.clone(), value: value.clone(), - code: code.to_vec(), - data: vec![], + code: Some(code.to_vec()), + data: None }; let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth); @@ -440,6 +446,7 @@ impl<'a> Ext for Externalities<'a> { let mut gas_cost = *call_gas; let mut call_gas = *call_gas; + // TODO: move gas calculation out! let is_call = receive_address == code_address; if is_call && !self.state.exists(&code_address) { gas_cost = gas_cost + U256::from(self.schedule.call_new_account_gas); @@ -463,14 +470,15 @@ impl<'a> Ext for Externalities<'a> { } let params = ActionParams { + code_address: code_address.clone(), address: receive_address.clone(), sender: self.params.address.clone(), origin: self.params.origin.clone(), gas: call_gas, gas_price: self.params.gas_price.clone(), value: value.clone(), - code: self.state.code(code_address).unwrap_or(vec![]), - data: data.to_vec(), + code: self.state.code(code_address), + data: Some(data.to_vec()), }; let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth); @@ -591,7 +599,7 @@ mod tests { params.address = address.clone(); params.sender = sender.clone(); params.gas = U256::from(100_000); - params.code = "3331600055".from_hex().unwrap(); + params.code = Some("3331600055".from_hex().unwrap()); params.value = U256::from(0x7); let mut state = State::new_temp(); state.add_balance(&sender, &U256::from(0x100u64)); @@ -649,7 +657,7 @@ mod tests { params.sender = sender.clone(); params.origin = sender.clone(); params.gas = U256::from(100_000); - params.code = code.clone(); + params.code = Some(code.clone()); params.value = U256::from(100); let mut state = State::new_temp(); state.add_balance(&sender, &U256::from(100)); @@ -702,7 +710,7 @@ mod tests { params.sender = sender.clone(); params.origin = sender.clone(); params.gas = U256::from(100_000); - params.code = code.clone(); + params.code = Some(code.clone()); params.value = U256::from(100); let mut state = State::new_temp(); state.add_balance(&sender, &U256::from(100)); @@ -753,7 +761,7 @@ mod tests { params.sender = sender.clone(); params.origin = sender.clone(); params.gas = U256::from(100_000); - params.code = code.clone(); + params.code = Some(code.clone()); params.value = U256::from(100); let mut state = State::new_temp(); state.add_balance(&sender, &U256::from(100)); @@ -807,7 +815,7 @@ mod tests { params.address = address_a.clone(); params.sender = sender.clone(); params.gas = U256::from(100_000); - params.code = code_a.clone(); + params.code = Some(code_a.clone()); params.value = U256::from(100_000); let mut state = State::new_temp(); @@ -854,7 +862,7 @@ mod tests { let mut params = ActionParams::new(); params.address = address.clone(); params.gas = U256::from(100_000); - params.code = code.clone(); + params.code = Some(code.clone()); let mut state = State::new_temp(); state.init_code(&address, code.clone()); let info = EnvInfo::new();