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

Commit

Permalink
ExecutionsRequest from light-clients as read-only
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
niklasad1 committed Sep 19, 2018
1 parent 4637215 commit 6eb3253
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 20 deletions.
10 changes: 5 additions & 5 deletions ethcore/light/src/on_demand/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub enum Request {
/// A request for a contract's code.
Code(Code),
/// A request for proof of execution.
Execution(TransactionProof),
Execution(ReadOnlyTransactionProof),
/// A request for epoch change signal.
Signal(Signal),
}
Expand Down Expand Up @@ -145,7 +145,7 @@ impl_single!(Receipts, BlockReceipts, Vec<Receipt>);
impl_single!(Body, Body, encoded::Block);
impl_single!(Account, Account, Option<BasicAccount>);
impl_single!(Code, Code, Bytes);
impl_single!(Execution, TransactionProof, super::ExecutionResult);
impl_single!(Execution, ReadOnlyTransactionProof, super::ExecutionResult);
impl_single!(Signal, Signal, Vec<u8>);

macro_rules! impl_args {
Expand Down Expand Up @@ -256,7 +256,7 @@ pub enum CheckedRequest {
Body(Body, net_request::IncompleteBodyRequest),
Account(Account, net_request::IncompleteAccountRequest),
Code(Code, net_request::IncompleteCodeRequest),
Execution(TransactionProof, net_request::IncompleteExecutionRequest),
Execution(ReadOnlyTransactionProof, net_request::IncompleteExecutionRequest),
Signal(Signal, net_request::IncompleteSignalRequest)
}

Expand Down Expand Up @@ -1030,7 +1030,7 @@ impl Code {

/// Request for transaction execution, along with the parts necessary to verify the proof.
#[derive(Clone)]
pub struct TransactionProof {
pub struct ReadOnlyTransactionProof {
/// The transaction to request proof of.
pub tx: SignedTransaction,
/// Block header.
Expand All @@ -1042,7 +1042,7 @@ pub struct TransactionProof {
pub engine: Arc<EthEngine>,
}

impl TransactionProof {
impl ReadOnlyTransactionProof {
/// Check the proof, returning the proved execution or indicate that the proof was bad.
pub fn check_response(&self, _: &Mutex<::cache::Cache>, state_items: &[DBValue]) -> Result<super::ExecutionResult, Error> {
let root = self.header.as_ref()?.state_root();
Expand Down
2 changes: 1 addition & 1 deletion ethcore/res/wasm-tests
3 changes: 2 additions & 1 deletion ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2342,6 +2342,7 @@ impl ProvingBlockChainClient for Client {
}

fn prove_transaction(&self, transaction: SignedTransaction, id: BlockId) -> Option<(Bytes, Vec<DBValue>)> {
trace!(target: "pip_provider", "prove_transaction: {:?}", transaction);
let (header, mut env_info) = match (self.block_header(id), self.env_info(id)) {
(Some(s), Some(e)) => (s, e),
_ => return None,
Expand All @@ -2357,7 +2358,7 @@ impl ProvingBlockChainClient for Client {
self.engine.machine(),
&env_info,
self.factories.clone(),
false,
true,
)
}

Expand Down
22 changes: 11 additions & 11 deletions rpc/src/v1/helpers/light_fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,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 @@ -255,14 +255,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 @@ -607,10 +607,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 All @@ -635,7 +635,7 @@ fn execute_tx(gas_known: bool, params: ExecuteParams) -> impl Future<Item = Exec
trace!(target: "light_fetch", "Placing execution request for {} gas in on_demand",
params.tx.gas);

let request = request::TransactionProof {
let request = request::ReadOnlyTransactionProof {
tx: params.tx.fake_sign(params.from),
header: params.hdr.into(),
env_info: params.env_info,
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 @@ -398,7 +398,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 @@ -408,7 +408,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 6eb3253

Please sign in to comment.