diff --git a/src/action_params.rs b/src/action_params.rs index 6f876874b..a56e64f4d 100644 --- a/src/action_params.rs +++ b/src/action_params.rs @@ -3,8 +3,16 @@ use util::hash::*; use util::uint::*; use util::bytes::*; -// TODO: should be a trait, possible to avoid cloning everything from a Transaction(/View). +/// Transaction value +#[derive(Clone, Debug)] +pub enum ActionValue { + /// Value that should be transfered + Transfer(U256), + /// Apparent value for transaction (not transfered) + Apparent(U256) +} +// TODO: should be a trait, possible to avoid cloning everything from a Transaction(/View). /// Action (call/create) input params. Everything else should be specified in Externalities. #[derive(Clone, Debug)] pub struct ActionParams { @@ -22,9 +30,7 @@ pub struct ActionParams { /// Gas price. pub gas_price: U256, /// Transaction value. - pub value: U256, - /// Should transfer value from sender to origin - pub is_value_transfer: bool, + pub value: ActionValue, /// Code being executed. pub code: Option, /// Input data. @@ -41,10 +47,9 @@ impl Default for ActionParams { origin: Address::new(), gas: U256::zero(), gas_price: U256::zero(), - value: U256::zero(), + value: ActionValue::Transfer(U256::zero()), code: None, - data: None, - is_value_transfer: true + data: None } } } diff --git a/src/evm/interpreter.rs b/src/evm/interpreter.rs index a5e8efc91..52509a2c0 100644 --- a/src/evm/interpreter.rs +++ b/src/evm/interpreter.rs @@ -741,7 +741,10 @@ impl Interpreter { stack.push(address_to_u256(params.sender.clone())); }, instructions::CALLVALUE => { - stack.push(params.value.clone()); + stack.push(match params.value { + ActionValue::Transfer(val) => val, + ActionValue::Apparent(val) => val, + }); }, instructions::CALLDATALOAD => { let big_id = stack.pop_back(); diff --git a/src/executive.rs b/src/executive.rs index ea1a8f6de..dd61a5b97 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -133,8 +133,7 @@ impl<'a> Executive<'a> { origin: sender.clone(), gas: init_gas, gas_price: t.gas_price, - value: t.value, - is_value_transfer: true, + value: ActionValue::Transfer(t.value), code: Some(t.data.clone()), data: None, }; @@ -148,8 +147,7 @@ impl<'a> Executive<'a> { origin: sender.clone(), gas: init_gas, gas_price: t.gas_price, - value: t.value, - is_value_transfer: true, + value: ActionValue::Transfer(t.value), code: self.state.code(address), data: Some(t.data.clone()), }; @@ -173,8 +171,8 @@ impl<'a> Executive<'a> { let backup = self.state.clone(); // at first, transfer value to destination - if params.is_value_transfer { - self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); + if let ActionValue::Transfer(val) = params.value { + self.state.transfer_balance(¶ms.sender, ¶ms.address, &val); } trace!("Executive::call(params={:?}) self.env_info={:?}", params, self.info); @@ -232,8 +230,8 @@ impl<'a> Executive<'a> { self.state.new_contract(¶ms.address); // then transfer value to it - if params.is_value_transfer { - self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); + if let ActionValue::Transfer(val) = params.value { + self.state.transfer_balance(¶ms.sender, ¶ms.address, &val); } let res = { diff --git a/src/externalities.rs b/src/externalities.rs index 20326fe03..a9a14c5c2 100644 --- a/src/externalities.rs +++ b/src/externalities.rs @@ -29,10 +29,13 @@ impl OriginInfo { pub fn from(params: &ActionParams) -> Self { OriginInfo { sender: params.sender.clone(), - value: params.value.clone(), address: params.address.clone(), origin: params.origin.clone(), - gas_price: params.gas_price.clone() + gas_price: params.gas_price.clone(), + value: match params.value { + ActionValue::Transfer(val) => val, + ActionValue::Apparent(val) => val, + } } } } @@ -115,8 +118,7 @@ impl<'a> Ext for Externalities<'a> { origin: self.origin_info.origin.clone(), gas: *gas, gas_price: self.origin_info.gas_price.clone(), - value: value.clone(), - is_value_transfer: true, + value: ActionValue::Transfer(value.clone()), code: Some(code.to_vec()), data: None, }; @@ -147,8 +149,7 @@ impl<'a> Ext for Externalities<'a> { origin: self.origin_info.origin.clone(), gas: *gas, gas_price: self.origin_info.gas_price.clone(), - value: self.origin_info.value.clone(), - is_value_transfer: false, + value: ActionValue::Apparent(self.origin_info.value.clone()), code: self.state.code(code_address), data: Some(data.to_vec()), }; @@ -176,8 +177,7 @@ impl<'a> Ext for Externalities<'a> { origin: self.origin_info.origin.clone(), gas: *gas, gas_price: self.origin_info.gas_price.clone(), - value: value.clone(), - is_value_transfer: true, + value: ActionValue::Transfer(value.clone()), code: self.state.code(code_address), data: Some(data.to_vec()), };