Unknown block error for RPC (#3965)

This commit is contained in:
Robert Habermeier 2016-12-23 18:46:17 +01:00 committed by Gav Wood
parent 612f14188f
commit 546246c56b
5 changed files with 55 additions and 16 deletions

View File

@ -619,7 +619,8 @@ impl Client {
/// Attempt to get a copy of a specific block's final state. /// Attempt to get a copy of a specific block's final state.
/// ///
/// This will not fail if given BlockId::Latest. /// 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> { pub fn state_at(&self, id: BlockId) -> Option<State> {
// fast path for latest state. // fast path for latest state.
match id.clone() { match id.clone() {

View File

@ -523,7 +523,8 @@ impl BlockChainClient for TestBlockChainClient {
match id { match id {
BlockId::Number(number) if (number as usize) < self.blocks.read().len() => BlockStatus::InChain, 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, 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,
} }
} }

View File

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

View File

@ -238,6 +238,15 @@ pub fn pending_logs<M>(miner: &M, best_block: EthBlockNumber, filter: &EthcoreFi
result 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. 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 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(); let address = address.into();
match num.0 { match num.0 {
BlockNumber::Pending => Ok(take_weak!(self.miner).balance(&*take_weak!(self.client), &address).into()), BlockNumber::Pending => Ok(take_weak!(self.miner).balance(&*take_weak!(self.client), &address).into()),
id => match take_weak!(self.client).balance(&address, id.into()) { id => {
Some(balance) => Ok(balance.into()), let client = take_weak!(self.client);
None => Err(errors::state_pruned()),
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); let position: U256 = RpcU256::into(pos);
match num.0 { match num.0 {
BlockNumber::Pending => Ok(take_weak!(self.miner).storage_at(&*take_weak!(self.client), &address, &H256::from(position)).into()), 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()) { id => {
Some(s) => Ok(s.into()), let client = take_weak!(self.client);
None => Err(errors::state_pruned()),
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); let address: Address = RpcH160::into(address);
match num.0 { match num.0 {
BlockNumber::Pending => Ok(take_weak!(self.miner).nonce(&*take_weak!(self.client), &address).into()), BlockNumber::Pending => Ok(take_weak!(self.miner).nonce(&*take_weak!(self.client), &address).into()),
id => match take_weak!(self.client).nonce(&address, id.into()) { id => {
Some(nonce) => Ok(nonce.into()), let client = take_weak!(self.client);
None => Err(errors::state_pruned()),
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); let address: Address = RpcH160::into(address);
match num.0 { match num.0 {
BlockNumber::Pending => Ok(take_weak!(self.miner).code(&*take_weak!(self.client), &address).map_or_else(Bytes::default, Bytes::new)), 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()) { id => {
Some(code) => Ok(code.map_or_else(Bytes::default, Bytes::new)), let client = take_weak!(self.client);
None => Err(errors::state_pruned()),
}, 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()),
}
}
} }
} }