From f835ce825338776da9883f5acf40d8e23cbd3d3b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 26 Mar 2016 13:30:02 +0100 Subject: [PATCH 1/3] Fix eth_call so it doesn't need the secret of the sender. --- ethcore/src/executive.rs | 2 +- ethcore/src/transaction.rs | 30 +++++++++++++++++++- rpc/src/v1/impls/eth.rs | 58 +++++++++++--------------------------- rpc/src/v1/tests/eth.rs | 2 ++ 4 files changed, 49 insertions(+), 43 deletions(-) diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index 9aa3bcf9b..12bc71bb5 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -727,7 +727,7 @@ mod tests { gas: U256::from(100_000), gas_price: U256::zero(), nonce: U256::zero() - }.fake_sign(); + }.invalid_sign(); let mut state_result = get_temp_state(); let mut state = state_result.reference_mut(); let mut info = EnvInfo::default(); diff --git a/ethcore/src/transaction.rs b/ethcore/src/transaction.rs index a51824494..02507da21 100644 --- a/ethcore/src/transaction.rs +++ b/ethcore/src/transaction.rs @@ -134,7 +134,7 @@ impl Transaction { /// Useful for test incorrectly signed transactions. #[cfg(test)] - pub fn fake_sign(self) -> SignedTransaction { + pub fn invalid_sign(self) -> SignedTransaction { SignedTransaction { unsigned: self, r: U256::zero(), @@ -145,6 +145,18 @@ impl Transaction { } } + /// Specify the sender; this won't survive the serialize/deserialize process, but can be cloned. + pub fn fake_sign(self, from: Address) -> SignedTransaction { + SignedTransaction { + unsigned: self, + r: U256::zero(), + s: U256::zero(), + v: 0, + hash: Cell::new(None), + sender: Cell::new(Some(from)), + } + } + /// Get the transaction cost in gas for the given params. pub fn gas_required_for(is_create: bool, data: &[u8], schedule: &Schedule) -> u64 { data.iter().fold( @@ -342,3 +354,19 @@ fn signing() { }.sign(&key.secret()); assert_eq!(Address::from(key.public().sha3()), t.sender().unwrap()); } + +#[test] +fn fake_signing() { + let t = Transaction { + action: Action::Create, + nonce: U256::from(42), + gas_price: U256::from(3000), + gas: U256::from(50_000), + value: U256::from(1), + data: b"Hello!".to_vec() + }.fake_sign(Address::from(0x69)); + assert_eq!(Address::from(0x69), t.sender().unwrap()); + + let t = t.clone(); + assert_eq!(Address::from(0x69), t.sender().unwrap()); +} diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 13cc08996..e7710b6df 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -24,7 +24,6 @@ use jsonrpc_core::*; use util::numbers::*; use util::sha3::*; use util::rlp::{encode, UntrustedRlp, View}; -use util::crypto::KeyPair; use ethcore::client::*; use ethcore::block::IsBlock; use ethcore::views::*; @@ -168,33 +167,16 @@ impl EthClient } } - fn sign_call(client: &Arc, accounts: &Arc, request: CallRequest) -> Option { - match request.from { - Some(ref from) => { - let transaction = EthTransaction { - nonce: request.nonce.unwrap_or_else(|| client.nonce(from)), - action: request.to.map_or(Action::Create, Action::Call), - gas: request.gas.unwrap_or_else(default_gas), - gas_price: request.gas_price.unwrap_or_else(default_gas_price), - value: request.value.unwrap_or_else(U256::zero), - data: request.data.map_or_else(Vec::new, |d| d.to_vec()) - }; - - accounts.account_secret(from).ok().map(|secret| transaction.sign(&secret)) - }, - None => { - let transaction = EthTransaction { - nonce: request.nonce.unwrap_or_else(U256::zero), - action: request.to.map_or(Action::Create, Action::Call), - gas: request.gas.unwrap_or_else(default_gas), - gas_price: request.gas_price.unwrap_or_else(default_gas_price), - value: request.value.unwrap_or_else(U256::zero), - data: request.data.map_or_else(Vec::new, |d| d.to_vec()) - }; - - KeyPair::create().ok().map(|kp| transaction.sign(kp.secret())) - } - } + fn sign_call(client: &Arc, request: CallRequest) -> SignedTransaction { + let from = request.from.unwrap_or(Address::zero()); + EthTransaction { + nonce: request.nonce.unwrap_or_else(|| client.nonce(&from)), + action: request.to.map_or(Action::Create, Action::Call), + gas: request.gas.unwrap_or_else(default_gas), + gas_price: request.gas_price.unwrap_or_else(default_gas_price), + value: request.value.unwrap_or_else(U256::zero), + data: request.data.map_or_else(Vec::new, |d| d.to_vec()) + }.fake_sign(from) } } @@ -533,12 +515,10 @@ impl Eth for EthClient fn call(&self, params: Params) -> Result { from_params_discard_second(params).and_then(|(request, )| { let client = take_weak!(self.client); - let accounts = take_weak!(self.accounts); - let signed = Self::sign_call(&client, &accounts, request); - let output = signed.map(|tx| client.call(&tx) - .map(|e| Bytes::new(e.output)) - .unwrap_or(Bytes::default())); - + let signed = Self::sign_call(&client, request); + info!("call: signed={:?}", signed); + let output = client.call(&signed).map(|e| Bytes(e.output)).unwrap_or(Bytes::new(vec![])); + info!("call: output={:?}", output); to_value(&output) }) } @@ -546,13 +526,9 @@ impl Eth for EthClient fn estimate_gas(&self, params: Params) -> Result { from_params_discard_second(params).and_then(|(request, )| { let client = take_weak!(self.client); - let accounts = take_weak!(self.accounts); - let signed = Self::sign_call(&client, &accounts, request); - let output = signed.map(|tx| client.call(&tx) - .map(|e| e.gas_used + e.refunded) - .unwrap_or(U256::zero())); - - to_value(&output) + let signed = Self::sign_call(&client, request); + let used = client.call(&signed).map(|res| res.gas_used + res.refunded).unwrap_or(From::from(0)); + to_value(&used) }) } } diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 525268137..02e8485db 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -344,6 +344,7 @@ fn rpc_eth_call_default_block() { logs: vec![], contracts_created: vec![], output: vec![0x12, 0x34, 0xff], + trace: None, }); let request = r#"{ @@ -407,6 +408,7 @@ fn rpc_eth_estimate_gas_default_block() { logs: vec![], contracts_created: vec![], output: vec![0x12, 0x34, 0xff], + trace: None, }); let request = r#"{ From 54bf237e4f9a0a352e6db189d29fbdc1c7d607bf Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 26 Mar 2016 13:31:04 +0100 Subject: [PATCH 2/3] Fix backport. --- rpc/src/v1/tests/eth.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 02e8485db..525268137 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -344,7 +344,6 @@ fn rpc_eth_call_default_block() { logs: vec![], contracts_created: vec![], output: vec![0x12, 0x34, 0xff], - trace: None, }); let request = r#"{ @@ -408,7 +407,6 @@ fn rpc_eth_estimate_gas_default_block() { logs: vec![], contracts_created: vec![], output: vec![0x12, 0x34, 0xff], - trace: None, }); let request = r#"{ From 902b44c94fc5daa986b8804106a2fc9c93434f28 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 26 Mar 2016 13:44:42 +0100 Subject: [PATCH 3/3] Remove info!s. --- rpc/src/v1/impls/eth.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index e7710b6df..a68fc91fd 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -516,9 +516,7 @@ impl Eth for EthClient from_params_discard_second(params).and_then(|(request, )| { let client = take_weak!(self.client); let signed = Self::sign_call(&client, request); - info!("call: signed={:?}", signed); let output = client.call(&signed).map(|e| Bytes(e.output)).unwrap_or(Bytes::new(vec![])); - info!("call: output={:?}", output); to_value(&output) }) }