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 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());

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,
poll_lifetime: cmd.poll_lifetime,
allow_missing_blocks: cmd.allow_missing_blocks,
no_ancient_blocks: !cmd.download_old_blocks,
});
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 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 {
pub fn unavailable_block(no_ancient_block: bool, by_hash: bool) -> Error {
if no_ancient_block {
Error {
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
message: "Ancient block sync is still in progress".into(),
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)

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";
/// 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))

View File

@ -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
},
);