[beta] Increase default gas limit for eth_call (#6337)
* Increase default gas limit for eth_call. * Fix balance increase. * Cap gas limit for dapp-originating requests.
This commit is contained in:
parent
4992064663
commit
7bf840f80a
@ -155,7 +155,7 @@ impl<'a, B: 'a + StateBackend, E: Engine + ?Sized> Executive<'a, B, E> {
|
|||||||
pub fn transact_virtual(&'a mut self, t: &SignedTransaction, options: TransactOptions) -> Result<Executed, ExecutionError> {
|
pub fn transact_virtual(&'a mut self, t: &SignedTransaction, options: TransactOptions) -> Result<Executed, ExecutionError> {
|
||||||
let sender = t.sender();
|
let sender = t.sender();
|
||||||
let balance = self.state.balance(&sender)?;
|
let balance = self.state.balance(&sender)?;
|
||||||
let needed_balance = t.value + t.gas * t.gas_price;
|
let needed_balance = t.value.saturating_add(t.gas.saturating_mul(t.gas_price));
|
||||||
if balance < needed_balance {
|
if balance < needed_balance {
|
||||||
// give the sender a sufficient balance
|
// give the sender a sufficient balance
|
||||||
self.state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty)?;
|
self.state.add_balance(&sender, &(needed_balance - balance), CleanupMode::NoEmpty)?;
|
||||||
|
@ -18,6 +18,7 @@ use std::sync::Arc;
|
|||||||
use ethcore::client::MiningBlockChainClient;
|
use ethcore::client::MiningBlockChainClient;
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use ethcore::transaction::{Transaction, SignedTransaction, Action};
|
use ethcore::transaction::{Transaction, SignedTransaction, Action};
|
||||||
|
use util::U256;
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use v1::helpers::CallRequest;
|
use v1::helpers::CallRequest;
|
||||||
@ -27,13 +28,22 @@ pub fn sign_call<B: MiningBlockChainClient, M: MinerService>(
|
|||||||
client: &Arc<B>,
|
client: &Arc<B>,
|
||||||
miner: &Arc<M>,
|
miner: &Arc<M>,
|
||||||
request: CallRequest,
|
request: CallRequest,
|
||||||
|
gas_cap: bool,
|
||||||
) -> Result<SignedTransaction, Error> {
|
) -> Result<SignedTransaction, Error> {
|
||||||
let from = request.from.unwrap_or(0.into());
|
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 {
|
Ok(Transaction {
|
||||||
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
||||||
action: request.to.map_or(Action::Create, Action::Call),
|
action: request.to.map_or(Action::Create, Action::Call),
|
||||||
gas: request.gas.unwrap_or(50_000_000.into()),
|
gas,
|
||||||
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&**client, &**miner)),
|
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&**client, &**miner)),
|
||||||
value: request.value.unwrap_or(0.into()),
|
value: request.value.unwrap_or(0.into()),
|
||||||
data: request.data.unwrap_or_default(),
|
data: request.data.unwrap_or_default(),
|
||||||
|
@ -641,9 +641,9 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
self.send_raw_transaction(raw)
|
self.send_raw_transaction(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
|
fn call(&self, meta: Self::Metadata, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
|
||||||
let request = CallRequest::into(request);
|
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,
|
Ok(signed) => signed,
|
||||||
Err(e) => return future::err(e).boxed(),
|
Err(e) => return future::err(e).boxed(),
|
||||||
};
|
};
|
||||||
@ -659,9 +659,9 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
).boxed()
|
).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn estimate_gas(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
fn estimate_gas(&self, meta: Self::Metadata, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
||||||
let request = CallRequest::into(request);
|
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,
|
Ok(signed) => signed,
|
||||||
Err(e) => return future::err(e).boxed(),
|
Err(e) => return future::err(e).boxed(),
|
||||||
};
|
};
|
||||||
|
@ -383,7 +383,7 @@ impl Eth for EthClient {
|
|||||||
self.send_raw_transaction(raw)
|
self.send_raw_transaction(raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
|
fn call(&self, _meta: Self::Metadata, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
|
||||||
self.fetcher().proved_execution(req, num).and_then(|res| {
|
self.fetcher().proved_execution(req, num).and_then(|res| {
|
||||||
match res {
|
match res {
|
||||||
Ok(exec) => Ok(exec.output.into()),
|
Ok(exec) => Ok(exec.output.into()),
|
||||||
@ -392,7 +392,7 @@ impl Eth for EthClient {
|
|||||||
}).boxed()
|
}).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn estimate_gas(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
fn estimate_gas(&self, _meta: Self::Metadata, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
||||||
// TODO: binary chop for more accurate estimates.
|
// TODO: binary chop for more accurate estimates.
|
||||||
self.fetcher().proved_execution(req, num).and_then(|res| {
|
self.fetcher().proved_execution(req, num).and_then(|res| {
|
||||||
match res {
|
match res {
|
||||||
|
@ -17,7 +17,9 @@
|
|||||||
//! Traces api implementation.
|
//! Traces api implementation.
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
|
use jsonrpc_core::futures::{future, Future, BoxFuture};
|
||||||
use jsonrpc_macros::Trailing;
|
use jsonrpc_macros::Trailing;
|
||||||
|
use v1::Metadata;
|
||||||
use v1::traits::Traces;
|
use v1::traits::Traces;
|
||||||
use v1::helpers::errors;
|
use v1::helpers::errors;
|
||||||
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
||||||
@ -27,6 +29,8 @@ use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, By
|
|||||||
pub struct TracesClient;
|
pub struct TracesClient;
|
||||||
|
|
||||||
impl Traces for TracesClient {
|
impl Traces for TracesClient {
|
||||||
|
type Metadata = Metadata;
|
||||||
|
|
||||||
fn filter(&self, _filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
fn filter(&self, _filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
@ -43,8 +47,8 @@ impl Traces for TracesClient {
|
|||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, _request: CallRequest, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
fn call(&self, _meta: Self::Metadata, _request: CallRequest, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> BoxFuture<TraceResults, Error> {
|
||||||
Err(errors::light_unimplemented(None))
|
future::err(errors::light_unimplemented(None)).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw_transaction(&self, _raw_transaction: Bytes, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
fn raw_transaction(&self, _raw_transaction: Bytes, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||||
|
@ -18,13 +18,15 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use rlp::UntrustedRlp;
|
|
||||||
use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId};
|
use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId};
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use ethcore::transaction::SignedTransaction;
|
use ethcore::transaction::SignedTransaction;
|
||||||
|
use rlp::UntrustedRlp;
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
|
use jsonrpc_core::futures::{self, Future, BoxFuture};
|
||||||
use jsonrpc_macros::Trailing;
|
use jsonrpc_macros::Trailing;
|
||||||
|
use v1::Metadata;
|
||||||
use v1::traits::Traces;
|
use v1::traits::Traces;
|
||||||
use v1::helpers::{errors, fake_sign};
|
use v1::helpers::{errors, fake_sign};
|
||||||
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
||||||
@ -54,6 +56,8 @@ impl<C, M> TracesClient<C, M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'static, M: MinerService + 'static {
|
impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'static, M: MinerService + 'static {
|
||||||
|
type Metadata = Metadata;
|
||||||
|
|
||||||
fn filter(&self, filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
fn filter(&self, filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
Ok(self.client.filter_traces(filter.into())
|
Ok(self.client.filter_traces(filter.into())
|
||||||
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||||
@ -79,15 +83,17 @@ impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'stat
|
|||||||
.map(LocalizedTrace::from))
|
.map(LocalizedTrace::from))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, request: CallRequest, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
fn call(&self, meta: Self::Metadata, request: CallRequest, flags: Vec<String>, block: Trailing<BlockNumber>) -> BoxFuture<TraceResults, Error> {
|
||||||
let block = block.unwrap_or_default();
|
let block = block.unwrap_or_default();
|
||||||
|
|
||||||
let request = CallRequest::into(request);
|
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, block.into(), to_call_analytics(flags))
|
let res = self.client.call(&signed, block.into(), to_call_analytics(flags))
|
||||||
.map(TraceResults::from)
|
.map(TraceResults::from)
|
||||||
.map_err(errors::call)
|
.map_err(errors::call);
|
||||||
|
|
||||||
|
futures::done(res).boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||||
|
@ -42,6 +42,15 @@ impl Metadata {
|
|||||||
_ => DappId::default(),
|
_ => 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 {}
|
impl jsonrpc_core::Metadata for Metadata {}
|
||||||
|
@ -25,12 +25,12 @@ use evm::CallType;
|
|||||||
|
|
||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use v1::tests::helpers::{TestMinerService};
|
use v1::tests::helpers::{TestMinerService};
|
||||||
use v1::{Traces, TracesClient};
|
use v1::{Metadata, Traces, TracesClient};
|
||||||
|
|
||||||
struct Tester {
|
struct Tester {
|
||||||
client: Arc<TestBlockChainClient>,
|
client: Arc<TestBlockChainClient>,
|
||||||
_miner: Arc<TestMinerService>,
|
_miner: Arc<TestMinerService>,
|
||||||
io: IoHandler,
|
io: IoHandler<Metadata>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn io() -> Tester {
|
fn io() -> Tester {
|
||||||
@ -67,7 +67,7 @@ fn io() -> Tester {
|
|||||||
}));
|
}));
|
||||||
let miner = Arc::new(TestMinerService::default());
|
let miner = Arc::new(TestMinerService::default());
|
||||||
let traces = TracesClient::new(&client, &miner);
|
let traces = TracesClient::new(&client, &miner);
|
||||||
let mut io = IoHandler::new();
|
let mut io = IoHandler::default();
|
||||||
io.extend_with(traces.to_delegate());
|
io.extend_with(traces.to_delegate());
|
||||||
|
|
||||||
Tester {
|
Tester {
|
||||||
|
@ -110,12 +110,12 @@ build_rpc_trait! {
|
|||||||
fn submit_transaction(&self, Bytes) -> Result<H256, Error>;
|
fn submit_transaction(&self, Bytes) -> Result<H256, Error>;
|
||||||
|
|
||||||
/// Call contract, returning the output data.
|
/// Call contract, returning the output data.
|
||||||
#[rpc(async, name = "eth_call")]
|
#[rpc(meta, name = "eth_call")]
|
||||||
fn call(&self, CallRequest, Trailing<BlockNumber>) -> BoxFuture<Bytes, Error>;
|
fn call(&self, Self::Metadata, CallRequest, Trailing<BlockNumber>) -> BoxFuture<Bytes, Error>;
|
||||||
|
|
||||||
/// Estimate gas needed for execution of given contract.
|
/// Estimate gas needed for execution of given contract.
|
||||||
#[rpc(async, name = "eth_estimateGas")]
|
#[rpc(meta, name = "eth_estimateGas")]
|
||||||
fn estimate_gas(&self, CallRequest, Trailing<BlockNumber>) -> BoxFuture<U256, Error>;
|
fn estimate_gas(&self, Self::Metadata, CallRequest, Trailing<BlockNumber>) -> BoxFuture<U256, Error>;
|
||||||
|
|
||||||
/// Get transaction by its hash.
|
/// Get transaction by its hash.
|
||||||
#[rpc(name = "eth_getTransactionByHash")]
|
#[rpc(name = "eth_getTransactionByHash")]
|
||||||
|
@ -17,12 +17,15 @@
|
|||||||
//! Traces specific rpc interface.
|
//! Traces specific rpc interface.
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
|
use jsonrpc_core::futures::BoxFuture;
|
||||||
use jsonrpc_macros::Trailing;
|
use jsonrpc_macros::Trailing;
|
||||||
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
||||||
|
|
||||||
build_rpc_trait! {
|
build_rpc_trait! {
|
||||||
/// Traces specific rpc interface.
|
/// Traces specific rpc interface.
|
||||||
pub trait Traces {
|
pub trait Traces {
|
||||||
|
type Metadata;
|
||||||
|
|
||||||
/// Returns traces matching given filter.
|
/// Returns traces matching given filter.
|
||||||
#[rpc(name = "trace_filter")]
|
#[rpc(name = "trace_filter")]
|
||||||
fn filter(&self, TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
fn filter(&self, TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
||||||
@ -40,8 +43,8 @@ build_rpc_trait! {
|
|||||||
fn block_traces(&self, BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
fn block_traces(&self, BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
||||||
|
|
||||||
/// Executes the given call and returns a number of possible traces for it.
|
/// Executes the given call and returns a number of possible traces for it.
|
||||||
#[rpc(name = "trace_call")]
|
#[rpc(meta, name = "trace_call")]
|
||||||
fn call(&self, CallRequest, Vec<String>, Trailing<BlockNumber>) -> Result<TraceResults, Error>;
|
fn call(&self, Self::Metadata, CallRequest, Vec<String>, Trailing<BlockNumber>) -> BoxFuture<TraceResults, Error>;
|
||||||
|
|
||||||
/// Executes the given raw transaction and returns a number of possible traces for it.
|
/// Executes the given raw transaction and returns a number of possible traces for it.
|
||||||
#[rpc(name = "trace_rawTransaction")]
|
#[rpc(name = "trace_rawTransaction")]
|
||||||
|
Loading…
Reference in New Issue
Block a user