From 89f828be1c6dc2882ddafb46d96aa71faa65c236 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Sun, 31 Mar 2019 11:54:19 +0200 Subject: [PATCH] fix(light account response): update `tx_queue` (#10545) --- rpc/src/v1/helpers/light_fetch.rs | 33 ++++++++++++++++++++++++------- rpc/src/v1/impls/light/eth.rs | 8 ++++---- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 7167a7316..e18695fcb 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -40,12 +40,13 @@ use light::on_demand::{ }; use light::on_demand::error::Error as OnDemandError; use light::request::Field; +use light::TransactionQueue; use sync::{LightNetworkDispatcher, ManageNetwork, LightSyncProvider}; use ethereum_types::{Address, U256}; use hash::H256; -use parking_lot::Mutex; +use parking_lot::{Mutex, RwLock}; use fastmap::H256FastMap; use std::collections::BTreeMap; use types::transaction::{Action, Transaction as EthTransaction, PendingTransaction, SignedTransaction, LocalizedTransaction}; @@ -100,7 +101,7 @@ where on_demand: self.on_demand.clone(), sync: self.sync.clone(), cache: self.cache.clone(), - gas_price_percentile: self.gas_price_percentile + gas_price_percentile: self.gas_price_percentile, } } } @@ -215,7 +216,13 @@ where /// Helper for getting account info at a given block. /// `None` indicates the account doesn't exist at the given block. - pub fn account(&self, address: Address, id: BlockId) -> impl Future, Error = Error> + Send { + pub fn account( + &self, + address: Address, + id: BlockId, + tx_queue: Arc> + ) -> impl Future, Error = Error> + Send { + let mut reqs = Vec::new(); let header_ref = match self.make_header_requests(id, &mut reqs) { Ok(r) => r, @@ -224,14 +231,26 @@ where reqs.push(request::Account { header: header_ref, address }.into()); - Either::B(self.send_requests(reqs, |mut res|match res.pop() { - Some(OnDemandResponse::Account(acc)) => acc, + Either::B(self.send_requests(reqs, move |mut res| match res.pop() { + Some(OnDemandResponse::Account(maybe_account)) => { + if let Some(ref acc) = maybe_account { + let mut txq = tx_queue.write(); + txq.cull(address, acc.nonce); + } + maybe_account + } _ => panic!(WRONG_RESPONSE_AMOUNT_TYPE_PROOF), })) } /// Helper for getting proved execution. - pub fn proved_read_only_execution(&self, req: CallRequest, num: Option) -> impl Future + Send { + pub fn proved_read_only_execution( + &self, + req: CallRequest, + num: Option, + txq: Arc> + ) -> impl Future + Send { + // (21000 G_transaction + 32000 G_create + some marginal to allow a few operations) const START_GAS: u64 = 60_000; @@ -254,7 +273,7 @@ where let from = req.from.unwrap_or_default(); let nonce_fut = match req.nonce { Some(nonce) => Either::A(future::ok(Some(nonce))), - None => Either::B(self.account(from, id).map(|acc| acc.map(|a| a.nonce))), + None => Either::B(self.account(from, id, txq).map(|acc| acc.map(|a| a.nonce))), }; let gas_price_fut = match req.gas_price { diff --git a/rpc/src/v1/impls/light/eth.rs b/rpc/src/v1/impls/light/eth.rs index cd17b0673..73e2b99c6 100644 --- a/rpc/src/v1/impls/light/eth.rs +++ b/rpc/src/v1/impls/light/eth.rs @@ -288,7 +288,7 @@ where } fn balance(&self, address: H160, num: Option) -> BoxFuture { - Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id()) + Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id(), self.transaction_queue.clone()) .map(|acc| acc.map_or(0.into(), |a| a.balance))) } @@ -305,7 +305,7 @@ where } fn transaction_count(&self, address: H160, num: Option) -> BoxFuture { - Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id()) + Box::new(self.fetcher().account(address, num.unwrap_or_default().to_block_id(), self.transaction_queue.clone()) .map(|acc| acc.map_or(0.into(), |a| a.nonce))) } @@ -401,7 +401,7 @@ where } fn call(&self, req: CallRequest, num: Option) -> BoxFuture { - Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { + Box::new(self.fetcher().proved_read_only_execution(req, num, self.transaction_queue.clone()).and_then(|res| { match res { Ok(exec) => Ok(exec.output.into()), Err(e) => Err(errors::execution(e)), @@ -411,7 +411,7 @@ where fn estimate_gas(&self, req: CallRequest, num: Option) -> BoxFuture { // TODO: binary chop for more accurate estimates. - Box::new(self.fetcher().proved_read_only_execution(req, num).and_then(|res| { + Box::new(self.fetcher().proved_read_only_execution(req, num, self.transaction_queue.clone()).and_then(|res| { match res { Ok(exec) => Ok(exec.refunded + exec.gas_used), Err(e) => Err(errors::execution(e)),