diff --git a/rpc/src/v1/helpers/fake_sign.rs b/rpc/src/v1/helpers/fake_sign.rs index b9be422c5..c5b95f6a4 100644 --- a/rpc/src/v1/helpers/fake_sign.rs +++ b/rpc/src/v1/helpers/fake_sign.rs @@ -28,14 +28,22 @@ pub fn sign_call( client: &Arc, miner: &Arc, request: CallRequest, + gas_cap: bool, ) -> Result { let from = request.from.unwrap_or(0.into()); + let mut gas = request.gas.unwrap_or(U256::max_value()); + if gas_cap { + let max_gas = 50_000_000.into(); + if gas > max_gas { + warn!("Gas limit capped to {} (from {})", max_gas, gas); + gas = max_gas + } + } Ok(Transaction { nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)), action: request.to.map_or(Action::Create, Action::Call), - // gas: request.gas.unwrap_or(U256::one() << 100), - gas: request.gas.unwrap_or(U256::max_value()), + gas, gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&**client, &**miner)), value: request.value.unwrap_or(0.into()), data: request.data.unwrap_or_default(), diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index 7c656c752..0cf70bf23 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -612,9 +612,9 @@ impl Eth for EthClient where self.send_raw_transaction(raw) } - fn call(&self, request: CallRequest, num: Trailing) -> BoxFuture { + fn call(&self, meta: Self::Metadata, request: CallRequest, num: Trailing) -> BoxFuture { let request = CallRequest::into(request); - let signed = match fake_sign::sign_call(&self.client, &self.miner, request) { + let signed = match fake_sign::sign_call(&self.client, &self.miner, request, meta.is_dapp()) { Ok(signed) => signed, Err(e) => return future::err(e).boxed(), }; @@ -628,9 +628,9 @@ impl Eth for EthClient where ).boxed() } - fn estimate_gas(&self, request: CallRequest, num: Trailing) -> BoxFuture { + fn estimate_gas(&self, meta: Self::Metadata, request: CallRequest, num: Trailing) -> BoxFuture { let request = CallRequest::into(request); - let signed = match fake_sign::sign_call(&self.client, &self.miner, request) { + let signed = match fake_sign::sign_call(&self.client, &self.miner, request, meta.is_dapp()) { Ok(signed) => signed, Err(e) => return future::err(e).boxed(), }; diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index fd03f1226..d33b5a06f 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -383,7 +383,7 @@ impl Eth for EthClient { self.send_raw_transaction(raw) } - fn call(&self, req: CallRequest, num: Trailing) -> BoxFuture { + fn call(&self, _meta: Self::Metadata, req: CallRequest, num: Trailing) -> BoxFuture { self.fetcher().proved_execution(req, num).and_then(|res| { match res { Ok(exec) => Ok(exec.output.into()), @@ -392,7 +392,7 @@ impl Eth for EthClient { }).boxed() } - fn estimate_gas(&self, req: CallRequest, num: Trailing) -> BoxFuture { + fn estimate_gas(&self, _meta: Self::Metadata, req: CallRequest, num: Trailing) -> BoxFuture { // TODO: binary chop for more accurate estimates. self.fetcher().proved_execution(req, num).and_then(|res| { match res { diff --git a/rpc/src/v1/impls/light/parity.rs b/rpc/src/v1/impls/light/parity.rs index 62a7721fc..676e39b11 100644 --- a/rpc/src/v1/impls/light/parity.rs +++ b/rpc/src/v1/impls/light/parity.rs @@ -390,7 +390,7 @@ impl Parity for ParityClient { ipfs::cid(content) } - fn call(&self, _requests: Vec, _block: Trailing) -> BoxFuture, Error> { + fn call(&self, _meta: Self::Metadata, _requests: Vec, _block: Trailing) -> BoxFuture, Error> { future::err(errors::light_unimplemented(None)).boxed() } } diff --git a/rpc/src/v1/impls/light/trace.rs b/rpc/src/v1/impls/light/trace.rs index 81ed592c5..22360183d 100644 --- a/rpc/src/v1/impls/light/trace.rs +++ b/rpc/src/v1/impls/light/trace.rs @@ -17,7 +17,9 @@ //! Traces api implementation. use jsonrpc_core::Error; +use jsonrpc_core::futures::{future, Future, BoxFuture}; use jsonrpc_macros::Trailing; +use v1::Metadata; use v1::traits::Traces; use v1::helpers::errors; use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, TraceOptions, H256}; @@ -27,6 +29,8 @@ use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, By pub struct TracesClient; impl Traces for TracesClient { + type Metadata = Metadata; + fn filter(&self, _filter: TraceFilter) -> Result>, Error> { Err(errors::light_unimplemented(None)) } @@ -43,12 +47,12 @@ impl Traces for TracesClient { Err(errors::light_unimplemented(None)) } - fn call(&self, _request: CallRequest, _flags: TraceOptions, _block: Trailing) -> Result { - Err(errors::light_unimplemented(None)) + fn call(&self, _meta: Self::Metadata, _request: CallRequest, _flags: TraceOptions, _block: Trailing) -> BoxFuture { + future::err(errors::light_unimplemented(None)).boxed() } - fn call_many(&self, _request: Vec<(CallRequest, TraceOptions)>, _block: Trailing) -> Result, Error> { - Err(errors::light_unimplemented(None)) + fn call_many(&self, _meta: Self::Metadata, _request: Vec<(CallRequest, TraceOptions)>, _block: Trailing) -> BoxFuture, Error> { + future::err(errors::light_unimplemented(None)).boxed() } fn raw_transaction(&self, _raw_transaction: Bytes, _flags: TraceOptions, _block: Trailing) -> Result { diff --git a/rpc/src/v1/impls/parity.rs b/rpc/src/v1/impls/parity.rs index d855d7e17..fb82c5205 100644 --- a/rpc/src/v1/impls/parity.rs +++ b/rpc/src/v1/impls/parity.rs @@ -411,11 +411,11 @@ impl Parity for ParityClient where ipfs::cid(content) } - fn call(&self, requests: Vec, block: Trailing) -> BoxFuture, Error> { + fn call(&self, meta: Self::Metadata, requests: Vec, block: Trailing) -> BoxFuture, Error> { let requests: Result, Error> = requests .into_iter() .map(|request| Ok(( - fake_sign::sign_call(&self.client, &self.miner, request.into())?, + fake_sign::sign_call(&self.client, &self.miner, request.into(), meta.is_dapp())?, Default::default() ))) .collect(); diff --git a/rpc/src/v1/impls/traces.rs b/rpc/src/v1/impls/traces.rs index 31a0e889e..9ed2c39a4 100644 --- a/rpc/src/v1/impls/traces.rs +++ b/rpc/src/v1/impls/traces.rs @@ -18,13 +18,15 @@ use std::sync::Arc; -use rlp::UntrustedRlp; use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId}; use ethcore::miner::MinerService; use ethcore::transaction::SignedTransaction; +use rlp::UntrustedRlp; use jsonrpc_core::Error; +use jsonrpc_core::futures::{self, Future, BoxFuture}; use jsonrpc_macros::Trailing; +use v1::Metadata; use v1::traits::Traces; use v1::helpers::{errors, fake_sign}; use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, TraceOptions, H256}; @@ -54,6 +56,8 @@ impl TracesClient { } impl Traces for TracesClient where C: MiningBlockChainClient + 'static, M: MinerService + 'static { + type Metadata = Metadata; + fn filter(&self, filter: TraceFilter) -> Result>, Error> { Ok(self.client.filter_traces(filter.into()) .map(|traces| traces.into_iter().map(LocalizedTrace::from).collect())) @@ -79,31 +83,35 @@ impl Traces for TracesClient where C: MiningBlockChainClient + 'stat .map(LocalizedTrace::from)) } - fn call(&self, request: CallRequest, flags: TraceOptions, block: Trailing) -> Result { + fn call(&self, meta: Self::Metadata, request: CallRequest, flags: TraceOptions, block: Trailing) -> BoxFuture { let block = block.unwrap_or_default(); let request = CallRequest::into(request); - let signed = fake_sign::sign_call(&self.client, &self.miner, request)?; + let signed = try_bf!(fake_sign::sign_call(&self.client, &self.miner, request, meta.is_dapp())); - self.client.call(&signed, to_call_analytics(flags), block.into()) + let res = self.client.call(&signed, to_call_analytics(flags), block.into()) .map(TraceResults::from) - .map_err(errors::call) + .map_err(errors::call); + + futures::done(res).boxed() } - fn call_many(&self, requests: Vec<(CallRequest, TraceOptions)>, block: Trailing) -> Result, Error> { + fn call_many(&self, meta: Self::Metadata, requests: Vec<(CallRequest, TraceOptions)>, block: Trailing) -> BoxFuture, Error> { let block = block.unwrap_or_default(); - let requests = requests.into_iter() + let requests = try_bf!(requests.into_iter() .map(|(request, flags)| { let request = CallRequest::into(request); - let signed = fake_sign::sign_call(&self.client, &self.miner, request)?; + let signed = fake_sign::sign_call(&self.client, &self.miner, request, meta.is_dapp())?; Ok((signed, to_call_analytics(flags))) }) - .collect::, _>>()?; + .collect::, Error>>()); - self.client.call_many(&requests, block.into()) + let res = self.client.call_many(&requests, block.into()) .map(|results| results.into_iter().map(TraceResults::from).collect()) - .map_err(errors::call) + .map_err(errors::call); + + futures::done(res).boxed() } fn raw_transaction(&self, raw_transaction: Bytes, flags: TraceOptions, block: Trailing) -> Result { diff --git a/rpc/src/v1/metadata.rs b/rpc/src/v1/metadata.rs index b65003ad8..f0644d455 100644 --- a/rpc/src/v1/metadata.rs +++ b/rpc/src/v1/metadata.rs @@ -42,6 +42,15 @@ impl Metadata { _ => DappId::default(), } } + + /// Returns true if the request originates from a Dapp. + pub fn is_dapp(&self) -> bool { + if let Origin::Dapps(_) = self.origin { + true + } else { + false + } + } } impl jsonrpc_core::Metadata for Metadata {} diff --git a/rpc/src/v1/tests/mocked/traces.rs b/rpc/src/v1/tests/mocked/traces.rs index 50890648c..cd3ae3666 100644 --- a/rpc/src/v1/tests/mocked/traces.rs +++ b/rpc/src/v1/tests/mocked/traces.rs @@ -25,12 +25,12 @@ use vm::CallType; use jsonrpc_core::IoHandler; use v1::tests::helpers::{TestMinerService}; -use v1::{Traces, TracesClient}; +use v1::{Metadata, Traces, TracesClient}; struct Tester { client: Arc, _miner: Arc, - io: IoHandler, + io: IoHandler, } fn io() -> Tester { @@ -67,7 +67,7 @@ fn io() -> Tester { })); let miner = Arc::new(TestMinerService::default()); let traces = TracesClient::new(&client, &miner); - let mut io = IoHandler::new(); + let mut io = IoHandler::default(); io.extend_with(traces.to_delegate()); Tester { diff --git a/rpc/src/v1/traits/eth.rs b/rpc/src/v1/traits/eth.rs index 941263335..9e7ed9715 100644 --- a/rpc/src/v1/traits/eth.rs +++ b/rpc/src/v1/traits/eth.rs @@ -110,12 +110,12 @@ build_rpc_trait! { fn submit_transaction(&self, Bytes) -> Result; /// Call contract, returning the output data. - #[rpc(async, name = "eth_call")] - fn call(&self, CallRequest, Trailing) -> BoxFuture; + #[rpc(meta, name = "eth_call")] + fn call(&self, Self::Metadata, CallRequest, Trailing) -> BoxFuture; /// Estimate gas needed for execution of given contract. - #[rpc(async, name = "eth_estimateGas")] - fn estimate_gas(&self, CallRequest, Trailing) -> BoxFuture; + #[rpc(meta, name = "eth_estimateGas")] + fn estimate_gas(&self, Self::Metadata, CallRequest, Trailing) -> BoxFuture; /// Get transaction by its hash. #[rpc(name = "eth_getTransactionByHash")] diff --git a/rpc/src/v1/traits/parity.rs b/rpc/src/v1/traits/parity.rs index a0b1a6e99..c9ca522c1 100644 --- a/rpc/src/v1/traits/parity.rs +++ b/rpc/src/v1/traits/parity.rs @@ -205,7 +205,7 @@ build_rpc_trait! { fn ipfs_cid(&self, Bytes) -> Result; /// Call contract, returning the output data. - #[rpc(async, name = "parity_call")] - fn call(&self, Vec, Trailing) -> BoxFuture, Error>; + #[rpc(meta, name = "parity_call")] + fn call(&self, Self::Metadata, Vec, Trailing) -> BoxFuture, Error>; } } diff --git a/rpc/src/v1/traits/traces.rs b/rpc/src/v1/traits/traces.rs index 568788af2..33bcb0afd 100644 --- a/rpc/src/v1/traits/traces.rs +++ b/rpc/src/v1/traits/traces.rs @@ -17,12 +17,15 @@ //! Traces specific rpc interface. use jsonrpc_core::Error; +use jsonrpc_core::futures::BoxFuture; use jsonrpc_macros::Trailing; use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256, TraceOptions}; build_rpc_trait! { /// Traces specific rpc interface. pub trait Traces { + type Metadata; + /// Returns traces matching given filter. #[rpc(name = "trace_filter")] fn filter(&self, TraceFilter) -> Result>, Error>; @@ -40,12 +43,12 @@ build_rpc_trait! { fn block_traces(&self, BlockNumber) -> Result>, Error>; /// Executes the given call and returns a number of possible traces for it. - #[rpc(name = "trace_call")] - fn call(&self, CallRequest, TraceOptions, Trailing) -> Result; + #[rpc(meta, name = "trace_call")] + fn call(&self, Self::Metadata, CallRequest, TraceOptions, Trailing) -> BoxFuture; /// Executes all given calls and returns a number of possible traces for each of it. - #[rpc(name = "trace_callMany")] - fn call_many(&self, Vec<(CallRequest, TraceOptions)>, Trailing) -> Result, Error>; + #[rpc(meta, name = "trace_callMany")] + fn call_many(&self, Self::Metadata, Vec<(CallRequest, TraceOptions)>, Trailing) -> BoxFuture, Error>; /// Executes the given raw transaction and returns a number of possible traces for it. #[rpc(name = "trace_rawTransaction")]