adds rpc error message for --no-ancient-blocks (#10608)
* adds error message for --no-ancient-blocks, closes #10261 * Apply suggestions from code review Co-Authored-By: seunlanlege <seunlanlege@gmail.com>
This commit is contained in:
		
							parent
							
								
									4cc274e75f
								
							
						
					
					
						commit
						969a9815e4
					
				@ -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());
 | 
			
		||||
 | 
			
		||||
@ -745,6 +745,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, 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 {
 | 
			
		||||
 | 
			
		||||
@ -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<T>) -> RpcResult<Option<T>> + '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<T>) -> RpcResult<Option<T>> + '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)
 | 
			
		||||
 | 
			
		||||
@ -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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> 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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> 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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> 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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> 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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> Eth for EthClient<
 | 
			
		||||
 | 
			
		||||
	fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture<Option<RichBlock>> {
 | 
			
		||||
		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<Option<RichBlock>> {
 | 
			
		||||
		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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> 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<Option<Transaction>> {
 | 
			
		||||
		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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> 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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> 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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> 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<C, SN: ?Sized, S: ?Sized, M, EM, T: StateInfo + 'static> 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))
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
			},
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user