Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
fix (light/provider) : Make read_only executions read-only (#9591)
Browse files Browse the repository at this point in the history
* `ExecutionsRequest` from light-clients as read-only

This changes so all `ExecutionRequests` from light-clients are executed
as read-only which the `virtual``flag == true ensures.

This boost up the current transaction to always succeed

Note, this only affects `eth_estimateGas` and `eth_call` AFAIK.

* grumbles(revert renaming) : TransactionProof

* grumbles(trace) : remove incorrect trace

* grumbles(state/prove_tx) : explicit `virt`

Remove the boolean flag to determine that a `state::prove_transaction`
whether it should be executed in a virtual context or not.

Because of that also rename the function to
`state::prove_transction_virtual` to make more clear
  • Loading branch information
niklasad1 authored and 5chdn committed Oct 9, 2018
1 parent 6690100 commit 57030ce
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 20 deletions.
3 changes: 1 addition & 2 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2315,14 +2315,13 @@ impl ProvingBlockChainClient for Client {
env_info.gas_limit = transaction.gas.clone();
let mut jdb = self.state_db.read().journal_db().boxed_clone();

state::prove_transaction(
state::prove_transaction_virtual(
jdb.as_hashdb_mut(),
header.state_root().clone(),
&transaction,
self.engine.machine(),
&env_info,
self.factories.clone(),
false,
)
}

Expand Down
3 changes: 1 addition & 2 deletions ethcore/src/spec/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -829,14 +829,13 @@ impl Spec {
data: d,
}.fake_sign(from);

let res = ::state::prove_transaction(
let res = ::state::prove_transaction_virtual(
db.as_hashdb_mut(),
*genesis.state_root(),
&tx,
self.engine.machine(),
&env_info,
factories.clone(),
true,
);

res.map(|(out, proof)| {
Expand Down
7 changes: 3 additions & 4 deletions ethcore/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,17 +222,16 @@ pub fn check_proof(
}
}

/// Prove a transaction on the given state.
/// Prove a `virtual` transaction on the given state.
/// Returns `None` when the transacion could not be proved,
/// and a proof otherwise.
pub fn prove_transaction<H: AsHashDB<KeccakHasher> + Send + Sync>(
pub fn prove_transaction_virtual<H: AsHashDB<KeccakHasher> + Send + Sync>(
db: H,
root: H256,
transaction: &SignedTransaction,
machine: &Machine,
env_info: &EnvInfo,
factories: Factories,
virt: bool,
) -> Option<(Bytes, Vec<DBValue>)> {
use self::backend::Proving;

Expand All @@ -250,7 +249,7 @@ pub fn prove_transaction<H: AsHashDB<KeccakHasher> + Send + Sync>(
};

let options = TransactOptions::with_no_tracing().dont_check_nonce().save_output_from_contract();
match state.execute(env_info, machine, transaction, options, virt) {
match state.execute(env_info, machine, transaction, options, true) {
Err(ExecutionError::Internal(_)) => None,
Err(e) => {
trace!(target: "state", "Proved call failed: {}", e);
Expand Down
20 changes: 10 additions & 10 deletions rpc/src/v1/helpers/light_fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ impl LightFetch {
}

/// Helper for getting proved execution.
pub fn proved_execution(&self, req: CallRequest, num: Trailing<BlockNumber>) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
pub fn proved_read_only_execution(&self, req: CallRequest, num: Trailing<BlockNumber>) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
const DEFAULT_GAS_PRICE: u64 = 21_000;
// starting gas when gas not provided.
const START_GAS: u64 = 50_000;
Expand Down Expand Up @@ -253,14 +253,14 @@ impl LightFetch {
_ => return Either::A(future::err(errors::unknown_block())),
};

Either::B(execute_tx(gas_known, ExecuteParams {
from: from,
tx: tx,
hdr: hdr,
env_info: env_info,
Either::B(execute_read_only_tx(gas_known, ExecuteParams {
from,
tx,
hdr,
env_info,
engine: client.engine().clone(),
on_demand: on_demand,
sync: sync,
on_demand,
sync,
}))
}))
}
Expand Down Expand Up @@ -599,10 +599,10 @@ struct ExecuteParams {

// has a peer execute the transaction with given params. If `gas_known` is false,
// this will double the gas on each `OutOfGas` error.
fn execute_tx(gas_known: bool, params: ExecuteParams) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
fn execute_read_only_tx(gas_known: bool, params: ExecuteParams) -> impl Future<Item = ExecutionResult, Error = Error> + Send {
if !gas_known {
Box::new(future::loop_fn(params, |mut params| {
execute_tx(true, params.clone()).and_then(move |res| {
execute_read_only_tx(true, params.clone()).and_then(move |res| {
match res {
Ok(executed) => {
// TODO: how to distinguish between actual OOG and
Expand Down
4 changes: 2 additions & 2 deletions rpc/src/v1/impls/light/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {
}

fn call(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes> {
Box::new(self.fetcher().proved_execution(req, num).and_then(|res| {
Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| {
match res {
Ok(exec) => Ok(exec.output.into()),
Err(e) => Err(errors::execution(e)),
Expand All @@ -409,7 +409,7 @@ impl<T: LightChainClient + 'static> Eth for EthClient<T> {

fn estimate_gas(&self, req: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256> {
// TODO: binary chop for more accurate estimates.
Box::new(self.fetcher().proved_execution(req, num).and_then(|res| {
Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| {
match res {
Ok(exec) => Ok((exec.refunded + exec.gas_used).into()),
Err(e) => Err(errors::execution(e)),
Expand Down

0 comments on commit 57030ce

Please sign in to comment.