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:
Seun LanLege 2019-04-23 13:54:45 +01:00 committed by GitHub
parent 4cc274e75f
commit 969a9815e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 29 deletions

View File

@ -259,6 +259,7 @@ pub struct FullDependencies {
pub gas_price_percentile: usize, pub gas_price_percentile: usize,
pub poll_lifetime: u32, pub poll_lifetime: u32,
pub allow_missing_blocks: bool, pub allow_missing_blocks: bool,
pub no_ancient_blocks: bool,
} }
impl FullDependencies { impl FullDependencies {
@ -310,6 +311,7 @@ impl FullDependencies {
gas_price_percentile: self.gas_price_percentile, gas_price_percentile: self.gas_price_percentile,
allow_missing_blocks: self.allow_missing_blocks, allow_missing_blocks: self.allow_missing_blocks,
allow_experimental_rpcs: self.experimental_rpcs, allow_experimental_rpcs: self.experimental_rpcs,
no_ancient_blocks: self.no_ancient_blocks
} }
); );
handler.extend_with(client.to_delegate()); handler.extend_with(client.to_delegate());

View File

@ -745,6 +745,7 @@ fn execute_impl<Cr, Rr>(cmd: RunCmd, logger: Arc<RotatingLogger>, on_client_rq:
gas_price_percentile: cmd.gas_price_percentile, gas_price_percentile: cmd.gas_price_percentile,
poll_lifetime: cmd.poll_lifetime, poll_lifetime: cmd.poll_lifetime,
allow_missing_blocks: cmd.allow_missing_blocks, allow_missing_blocks: cmd.allow_missing_blocks,
no_ancient_blocks: !cmd.download_old_blocks,
}); });
let dependencies = rpc::Dependencies { let dependencies = rpc::Dependencies {

View File

@ -29,6 +29,7 @@ use light::on_demand::error::{Error as OnDemandError, ErrorKind as OnDemandError
use ethcore::client::BlockChainClient; use ethcore::client::BlockChainClient;
use types::blockchain_info::BlockChainInfo; use types::blockchain_info::BlockChainInfo;
use v1::types::BlockNumber; use v1::types::BlockNumber;
use v1::impls::EthClientOptions;
mod codes { mod codes {
// NOTE [ToDr] Codes from [-32099, -32000] // NOTE [ToDr] Codes from [-32099, -32000]
@ -221,18 +222,34 @@ pub fn cannot_submit_work(err: EthcoreError) -> Error {
} }
} }
pub fn unavailable_block() -> Error { pub fn unavailable_block(no_ancient_block: bool, by_hash: bool) -> Error {
Error { if no_ancient_block {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST), Error {
message: "Ancient block sync is still in progress".into(), code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
data: None, 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>( pub fn check_block_number_existence<'a, T, C>(
client: &'a C, client: &'a C,
num: BlockNumber, num: BlockNumber,
allow_missing_blocks: bool, options: EthClientOptions,
) -> ) ->
impl Fn(Option<T>) -> RpcResult<Option<T>> + 'a impl Fn(Option<T>) -> RpcResult<Option<T>> + 'a
where C: BlockChainClient, where C: BlockChainClient,
@ -242,8 +259,8 @@ pub fn check_block_number_existence<'a, T, C>(
if let BlockNumber::Num(block_number) = num { if let BlockNumber::Num(block_number) = num {
// tried to fetch block number and got nothing even though the block number is // tried to fetch block number and got nothing even though the block number is
// less than the latest block number // less than the latest block number
if block_number < client.chain_info().best_block_number && !allow_missing_blocks { if block_number < client.chain_info().best_block_number && !options.allow_missing_blocks {
return Err(unavailable_block()); 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>( pub fn check_block_gap<'a, T, C>(
client: &'a C, client: &'a C,
allow_missing_blocks: bool, options: EthClientOptions,
) -> impl Fn(Option<T>) -> RpcResult<Option<T>> + 'a ) -> impl Fn(Option<T>) -> RpcResult<Option<T>> + 'a
where C: BlockChainClient, where C: BlockChainClient,
{ {
move |response| { 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(); let BlockChainInfo { ancient_block_hash, .. } = client.chain_info();
// block information was requested, but unfortunately we couldn't find it and there // block information was requested, but unfortunately we couldn't find it and there
// are gaps in the database ethcore/src/blockchain/blockchain.rs // are gaps in the database ethcore/src/blockchain/blockchain.rs
if ancient_block_hash.is_some() { if ancient_block_hash.is_some() {
return Err(Error { return Err(unavailable_block(options.no_ancient_blocks, true))
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,
})
} }
} }
Ok(response) Ok(response)

View File

@ -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"; const EXTRA_INFO_PROOF: &str = "Object exists in blockchain (fetched earlier), extra_info is always available if object exists; qed";
/// Eth RPC options /// Eth RPC options
#[derive(Copy, Clone)]
pub struct EthClientOptions { pub struct EthClientOptions {
/// Return nonce from transaction queue when pending block not available. /// Return nonce from transaction queue when pending block not available.
pub pending_nonce_from_queue: bool, pub pending_nonce_from_queue: bool,
@ -67,6 +68,8 @@ pub struct EthClientOptions {
pub allow_missing_blocks: bool, pub allow_missing_blocks: bool,
/// Enable Experimental RPC-Calls /// Enable Experimental RPC-Calls
pub allow_experimental_rpcs: bool, pub allow_experimental_rpcs: bool,
/// flag for ancient block sync
pub no_ancient_blocks: bool,
} }
impl EthClientOptions { impl EthClientOptions {
@ -88,6 +91,7 @@ impl Default for EthClientOptions {
gas_price_percentile: 50, gas_price_percentile: 50,
allow_missing_blocks: false, allow_missing_blocks: false,
allow_experimental_rpcs: 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)) let trx_count = self.client.block(BlockId::Hash(hash))
.map(|block| block.transactions_count().into()); .map(|block| block.transactions_count().into());
let result = Ok(trx_count) 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)) 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( .and_then(errors::check_block_number_existence(
&*self.client, &*self.client,
num, 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)) let uncle_count = self.client.block(BlockId::Hash(hash))
.map(|block| block.uncles_count().into()); .map(|block| block.uncles_count().into());
let result = Ok(uncle_count) 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)) 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( .and_then(errors::check_block_number_existence(
&*self.client, &*self.client,
num, 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>> { fn block_by_hash(&self, hash: H256, include_txs: bool) -> BoxFuture<Option<RichBlock>> {
let result = self.rich_block(BlockId::Hash(hash).into(), include_txs) 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)) Box::new(future::done(result))
} }
fn block_by_number(&self, num: BlockNumber, include_txs: bool) -> BoxFuture<Option<RichBlock>> { 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( 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)) 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())) .map(|t| Transaction::from_pending(t.pending().clone()))
}); });
let result = Ok(tx).and_then( 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)) Box::new(future::done(result))
} }
fn transaction_by_block_hash_and_index(&self, hash: H256, index: Index) -> BoxFuture<Option<Transaction>> { 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 id = PendingTransactionId::Location(PendingOrBlock::Block(BlockId::Hash(hash)), index.value());
let result = self.transaction(id).and_then( 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)) 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 transaction_id = PendingTransactionId::Location(block_id, index.value());
let result = self.transaction(transaction_id).and_then( 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)) 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 receipt = self.client.transaction_receipt(TransactionId::Hash(hash));
let result = Ok(receipt.map(Into::into)) 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)) 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 { let result = self.uncle(PendingUncleId {
id: PendingOrBlock::Block(BlockId::Hash(hash)), id: PendingOrBlock::Block(BlockId::Hash(hash)),
position: index.value() 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)) 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( .and_then(errors::check_block_number_existence(
&*self.client, &*self.client,
num, num,
self.options.allow_missing_blocks self.options
)); ));
Box::new(future::done(result)) Box::new(future::done(result))

View File

@ -143,7 +143,8 @@ impl EthTester {
send_block_number_in_get_work: true, send_block_number_in_get_work: true,
gas_price_percentile: 50, gas_price_percentile: 50,
allow_experimental_rpcs: true, allow_experimental_rpcs: true,
allow_missing_blocks: false allow_missing_blocks: false,
no_ancient_blocks: false
}, },
); );