diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 40dab3f5a..4693f18ab 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -259,6 +259,7 @@ pub struct FullDependencies { pub gas_price_percentile: usize, pub poll_lifetime: u32, pub allow_missing_blocks: bool, + pub no_ancient_blocks: bool, } impl FullDependencies { @@ -310,6 +311,7 @@ impl FullDependencies { gas_price_percentile: self.gas_price_percentile, allow_missing_blocks: self.allow_missing_blocks, allow_experimental_rpcs: self.experimental_rpcs, + no_ancient_blocks: self.no_ancient_blocks } ); handler.extend_with(client.to_delegate()); diff --git a/parity/run.rs b/parity/run.rs index a4c24108c..5858dcf5e 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -745,6 +745,7 @@ fn execute_impl(cmd: RunCmd, logger: Arc, on_client_rq: gas_price_percentile: cmd.gas_price_percentile, poll_lifetime: cmd.poll_lifetime, allow_missing_blocks: cmd.allow_missing_blocks, + no_ancient_blocks: !cmd.download_old_blocks, }); let dependencies = rpc::Dependencies { diff --git a/rpc/src/v1/helpers/errors.rs b/rpc/src/v1/helpers/errors.rs index c04374d65..70c94904b 100644 --- a/rpc/src/v1/helpers/errors.rs +++ b/rpc/src/v1/helpers/errors.rs @@ -29,6 +29,7 @@ use light::on_demand::error::{Error as OnDemandError, ErrorKind as OnDemandError use ethcore::client::BlockChainClient; use types::blockchain_info::BlockChainInfo; use v1::types::BlockNumber; +use v1::impls::EthClientOptions; mod codes { // NOTE [ToDr] Codes from [-32099, -32000] @@ -221,18 +222,34 @@ pub fn cannot_submit_work(err: EthcoreError) -> Error { } } -pub fn unavailable_block() -> Error { - Error { - code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), - message: "Ancient block sync is still in progress".into(), - data: None, +pub fn unavailable_block(no_ancient_block: bool, by_hash: bool) -> Error { + if no_ancient_block { + Error { + code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), + message: "Looks like you disabled ancient block download, unfortunately the information you're \ + trying to fetch doesn't exist in the db and is probably in the ancient blocks.".into(), + data: None, + } + } else if by_hash { + Error { + code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), + message: "Block information is incomplete while ancient block sync is still in progress, before \ + it's finished we can't determine the existence of requested item.".into(), + data: None, + } + } else { + Error { + code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), + message: "Requested block number is in a range that is not available yet, because the ancient block sync is still in progress.".into(), + data: None, + } } } pub fn check_block_number_existence<'a, T, C>( client: &'a C, num: BlockNumber, - allow_missing_blocks: bool, + options: EthClientOptions, ) -> impl Fn(Option) -> RpcResult> + 'a where C: BlockChainClient, @@ -242,8 +259,8 @@ pub fn check_block_number_existence<'a, T, C>( if let BlockNumber::Num(block_number) = num { // tried to fetch block number and got nothing even though the block number is // less than the latest block number - if block_number < client.chain_info().best_block_number && !allow_missing_blocks { - return Err(unavailable_block()); + if block_number < client.chain_info().best_block_number && !options.allow_missing_blocks { + return Err(unavailable_block(options.no_ancient_blocks, false)); } } } @@ -253,22 +270,17 @@ pub fn check_block_number_existence<'a, T, C>( pub fn check_block_gap<'a, T, C>( client: &'a C, - allow_missing_blocks: bool, + options: EthClientOptions, ) -> impl Fn(Option) -> RpcResult> + 'a where C: BlockChainClient, { move |response| { - if response.is_none() && !allow_missing_blocks { + if response.is_none() && !options.allow_missing_blocks { let BlockChainInfo { ancient_block_hash, .. } = client.chain_info(); // block information was requested, but unfortunately we couldn't find it and there // are gaps in the database ethcore/src/blockchain/blockchain.rs if ancient_block_hash.is_some() { - return Err(Error { - code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), - message: "Block information is incomplete while ancient block sync is still in progress, before \ - it's finished we can't determine the existence of requested item.".into(), - data: None, - }) + return Err(unavailable_block(options.no_ancient_blocks, true)) } } Ok(response) diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index bb744367d..a24d49d50 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -53,6 +53,7 @@ use v1::metadata::Metadata; const EXTRA_INFO_PROOF: &str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed"; /// Eth RPC options +#[derive(Copy, Clone)] pub struct EthClientOptions { /// Return nonce from transaction queue when pending block not available. pub pending_nonce_from_queue: bool, @@ -67,6 +68,8 @@ pub struct EthClientOptions { pub allow_missing_blocks: bool, /// Enable Experimental RPC-Calls pub allow_experimental_rpcs: bool, + /// flag for ancient block sync + pub no_ancient_blocks: bool, } impl EthClientOptions { @@ -88,6 +91,7 @@ impl Default for EthClientOptions { gas_price_percentile: 50, allow_missing_blocks: false, allow_experimental_rpcs: false, + no_ancient_blocks: false, } } } @@ -668,7 +672,7 @@ impl Eth for EthClient< let trx_count = self.client.block(BlockId::Hash(hash)) .map(|block| block.transactions_count().into()); let result = Ok(trx_count) - .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + .and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -683,7 +687,7 @@ impl Eth for EthClient< .and_then(errors::check_block_number_existence( &*self.client, num, - self.options.allow_missing_blocks + self.options )) } })) @@ -693,7 +697,7 @@ impl Eth for EthClient< let uncle_count = self.client.block(BlockId::Hash(hash)) .map(|block| block.uncles_count().into()); let result = Ok(uncle_count) - .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + .and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -707,7 +711,7 @@ impl Eth for EthClient< .and_then(errors::check_block_number_existence( &*self.client, num, - self.options.allow_missing_blocks + self.options )) } })) @@ -729,13 +733,13 @@ impl Eth for EthClient< fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture> { let result = self.rich_block(BlockId::Hash(hash).into(), include_txs) - .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + .and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } fn block_by_number(&self, num: BlockNumber, include_txs: bool) -> BoxFuture> { let result = self.rich_block(num.clone().into(), include_txs).and_then( - errors::check_block_number_existence(&*self.client, num, self.options.allow_missing_blocks)); + errors::check_block_number_existence(&*self.client, num, self.options)); Box::new(future::done(result)) } @@ -745,14 +749,14 @@ impl Eth for EthClient< .map(|t| Transaction::from_pending(t.pending().clone())) }); let result = Ok(tx).and_then( - errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } fn transaction_by_block_hash_and_index(&self, hash: H256, index: Index) -> BoxFuture> { let id = PendingTransactionId::Location(PendingOrBlock::Block(BlockId::Hash(hash)), index.value()); let result = self.transaction(id).and_then( - errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -766,7 +770,7 @@ impl Eth for EthClient< let transaction_id = PendingTransactionId::Location(block_id, index.value()); let result = self.transaction(transaction_id).and_then( - errors::check_block_number_existence(&*self.client, num, self.options.allow_missing_blocks)); + errors::check_block_number_existence(&*self.client, num, self.options)); Box::new(future::done(result)) } @@ -780,7 +784,7 @@ impl Eth for EthClient< let receipt = self.client.transaction_receipt(TransactionId::Hash(hash)); let result = Ok(receipt.map(Into::into)) - .and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + .and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -788,7 +792,7 @@ impl Eth for EthClient< let result = self.uncle(PendingUncleId { id: PendingOrBlock::Block(BlockId::Hash(hash)), position: index.value() - }).and_then(errors::check_block_gap(&*self.client, self.options.allow_missing_blocks)); + }).and_then(errors::check_block_gap(&*self.client, self.options)); Box::new(future::done(result)) } @@ -805,7 +809,7 @@ impl Eth for EthClient< .and_then(errors::check_block_number_existence( &*self.client, num, - self.options.allow_missing_blocks + self.options )); Box::new(future::done(result)) diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 68710ae55..9c2273746 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -143,7 +143,8 @@ impl EthTester { send_block_number_in_get_work: true, gas_price_percentile: 50, allow_experimental_rpcs: true, - allow_missing_blocks: false + allow_missing_blocks: false, + no_ancient_blocks: false }, );