diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index 288f85ab422..668206174bd 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -252,6 +252,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 { @@ -303,6 +304,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 ca4ca1af103..a23f3d032d8 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -742,6 +742,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 c04374d6562..70c94904b7b 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 32f9c1c57f1..734e70a61c1 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -54,6 +54,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, @@ -68,6 +69,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 { @@ -89,6 +92,7 @@ impl Default for EthClientOptions { gas_price_percentile: 50, allow_missing_blocks: false, allow_experimental_rpcs: false, + no_ancient_blocks: false, } } } @@ -669,7 +673,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)) } @@ -684,7 +688,7 @@ impl Eth for EthClient< .and_then(errors::check_block_number_existence( &*self.client, num, - self.options.allow_missing_blocks + self.options )) } })) @@ -694,7 +698,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)) } @@ -708,7 +712,7 @@ impl Eth for EthClient< .and_then(errors::check_block_number_existence( &*self.client, num, - self.options.allow_missing_blocks + self.options )) } })) @@ -730,13 +734,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)) } @@ -746,14 +750,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)) } @@ -767,7 +771,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)) } @@ -781,7 +785,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)) } @@ -789,7 +793,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)) } @@ -806,7 +810,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 68710ae5591..9c2273746fb 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 }, );