Unknown block error for RPC (#3965)
This commit is contained in:
parent
612f14188f
commit
546246c56b
@ -619,7 +619,8 @@ impl Client {
|
||||
/// Attempt to get a copy of a specific block's final state.
|
||||
///
|
||||
/// This will not fail if given BlockId::Latest.
|
||||
/// Otherwise, this can fail (but may not) if the DB prunes state.
|
||||
/// Otherwise, this can fail (but may not) if the DB prunes state or the block
|
||||
/// is unknown.
|
||||
pub fn state_at(&self, id: BlockId) -> Option<State> {
|
||||
// fast path for latest state.
|
||||
match id.clone() {
|
||||
|
@ -523,7 +523,8 @@ impl BlockChainClient for TestBlockChainClient {
|
||||
match id {
|
||||
BlockId::Number(number) if (number as usize) < self.blocks.read().len() => BlockStatus::InChain,
|
||||
BlockId::Hash(ref hash) if self.blocks.read().get(hash).is_some() => BlockStatus::InChain,
|
||||
_ => BlockStatus::Unknown
|
||||
BlockId::Latest | BlockId::Pending | BlockId::Earliest => BlockStatus::InChain,
|
||||
_ => BlockStatus::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ pub trait BlockChainClient : Sync + Send {
|
||||
/// Get the address of the registry itself.
|
||||
fn registrar_address(&self) -> Option<Address>;
|
||||
|
||||
/// Get the address of a particular blockchain service, if available.
|
||||
/// Get the address of a particular blockchain service, if available.
|
||||
fn registry_address(&self, name: String) -> Option<Address>;
|
||||
}
|
||||
|
||||
|
@ -290,3 +290,11 @@ pub fn from_call_error(error: CallError) -> Error {
|
||||
CallError::TransactionNotFound => internal("{}, this should not be the case with eth_call, most likely a bug.", CallError::TransactionNotFound),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unknown_block() -> Error {
|
||||
Error {
|
||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||
message: "Unknown block number".into(),
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
|
@ -238,6 +238,15 @@ pub fn pending_logs<M>(miner: &M, best_block: EthBlockNumber, filter: &EthcoreFi
|
||||
result
|
||||
}
|
||||
|
||||
fn check_known<C>(client: &C, number: BlockNumber) -> Result<(), Error> where C: MiningBlockChainClient {
|
||||
use ethcore::block_status::BlockStatus;
|
||||
|
||||
match client.block_status(number.into()) {
|
||||
BlockStatus::InChain => Ok(()),
|
||||
_ => Err(errors::unknown_block()),
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_QUEUE_SIZE_TO_MINE_ON: usize = 4; // because uncles go back 6.
|
||||
|
||||
impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
|
||||
@ -359,9 +368,14 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
||||
let address = address.into();
|
||||
match num.0 {
|
||||
BlockNumber::Pending => Ok(take_weak!(self.miner).balance(&*take_weak!(self.client), &address).into()),
|
||||
id => match take_weak!(self.client).balance(&address, id.into()) {
|
||||
Some(balance) => Ok(balance.into()),
|
||||
None => Err(errors::state_pruned()),
|
||||
id => {
|
||||
let client = take_weak!(self.client);
|
||||
|
||||
check_known(&*client, id.clone())?;
|
||||
match client.balance(&address, id.into()) {
|
||||
Some(balance) => Ok(balance.into()),
|
||||
None => Err(errors::state_pruned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -372,9 +386,14 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
||||
let position: U256 = RpcU256::into(pos);
|
||||
match num.0 {
|
||||
BlockNumber::Pending => Ok(take_weak!(self.miner).storage_at(&*take_weak!(self.client), &address, &H256::from(position)).into()),
|
||||
id => match take_weak!(self.client).storage_at(&address, &H256::from(position), id.into()) {
|
||||
Some(s) => Ok(s.into()),
|
||||
None => Err(errors::state_pruned()),
|
||||
id => {
|
||||
let client = take_weak!(self.client);
|
||||
|
||||
check_known(&*client, id.clone())?;
|
||||
match client.storage_at(&address, &H256::from(position), id.into()) {
|
||||
Some(s) => Ok(s.into()),
|
||||
None => Err(errors::state_pruned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -385,9 +404,14 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
||||
let address: Address = RpcH160::into(address);
|
||||
match num.0 {
|
||||
BlockNumber::Pending => Ok(take_weak!(self.miner).nonce(&*take_weak!(self.client), &address).into()),
|
||||
id => match take_weak!(self.client).nonce(&address, id.into()) {
|
||||
Some(nonce) => Ok(nonce.into()),
|
||||
None => Err(errors::state_pruned()),
|
||||
id => {
|
||||
let client = take_weak!(self.client);
|
||||
|
||||
check_known(&*client, id.clone())?;
|
||||
match client.nonce(&address, id.into()) {
|
||||
Some(nonce) => Ok(nonce.into()),
|
||||
None => Err(errors::state_pruned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -441,10 +465,15 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
||||
let address: Address = RpcH160::into(address);
|
||||
match num.0 {
|
||||
BlockNumber::Pending => Ok(take_weak!(self.miner).code(&*take_weak!(self.client), &address).map_or_else(Bytes::default, Bytes::new)),
|
||||
_ => match take_weak!(self.client).code(&address, num.0.into()) {
|
||||
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
||||
None => Err(errors::state_pruned()),
|
||||
},
|
||||
id => {
|
||||
let client = take_weak!(self.client);
|
||||
|
||||
check_known(&*client, id.clone())?;
|
||||
match client.code(&address, id.into()) {
|
||||
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)),
|
||||
None => Err(errors::state_pruned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user