Skip to content

Commit

Permalink
Simplify error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
upbqdn committed Dec 10, 2024
1 parent bdb8372 commit ed69359
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 60 deletions.
81 changes: 33 additions & 48 deletions zebra-rpc/src/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ where
.ready()
.and_then(|service| service.call(request))
.await
.map_error(server::error::LegacyCode::default())?;
.map_misc_error()?;

let zebra_state::ReadResponse::TipPoolValues {
tip_height,
Expand All @@ -578,7 +578,7 @@ where
.ready()
.and_then(|service| service.call(request))
.await
.map_error(server::error::LegacyCode::default())?;
.map_misc_error()?;

let zebra_state::ReadResponse::BlockHeader { header, .. } = response else {
unreachable!("unmatched response to a BlockHeader request")
Expand Down Expand Up @@ -669,10 +669,7 @@ where
let valid_addresses = address_strings.valid_addresses()?;

let request = zebra_state::ReadRequest::AddressBalance(valid_addresses);
let response = state
.oneshot(request)
.await
.map_error(server::error::LegacyCode::default())?;
let response = state.oneshot(request).await.map_misc_error()?;

match response {
zebra_state::ReadResponse::AddressBalance(balance) => Ok(AddressBalance {
Expand Down Expand Up @@ -709,10 +706,7 @@ where
let transaction_parameter = mempool::Gossip::Tx(raw_transaction.into());
let request = mempool::Request::Queue(vec![transaction_parameter]);

let response = mempool
.oneshot(request)
.await
.map_error(server::error::LegacyCode::default())?;
let response = mempool.oneshot(request).await.map_misc_error()?;

let mut queue_results = match response {
mempool::Response::Queued(results) => results,
Expand All @@ -729,9 +723,9 @@ where
.pop()
.expect("there should be exactly one item in Vec")
.inspect_err(|err| tracing::debug!("sent transaction to mempool: {:?}", &err))
.map_error(server::error::LegacyCode::default())?
.map_misc_error()?
.await
.map_error(server::error::LegacyCode::default())?;
.map_misc_error()?;

tracing::debug!("sent transaction to mempool: {:?}", &queue_result);

Expand Down Expand Up @@ -785,7 +779,7 @@ where
.ready()
.and_then(|service| service.call(request))
.await
.map_error(server::error::LegacyCode::default())?;
.map_misc_error()?;

match response {
zebra_state::ReadResponse::Block(Some(block)) => {
Expand Down Expand Up @@ -844,9 +838,9 @@ where
}

let tx_ids_response = futs.next().await.expect("`futs` should not be empty");
let tx = match tx_ids_response.map_error(server::error::LegacyCode::default())? {
let tx = match tx_ids_response.map_misc_error()? {
zebra_state::ReadResponse::TransactionIdsForBlock(tx_ids) => tx_ids
.ok_or_error(server::error::LegacyCode::default(), "block not found")?
.ok_or_misc_error("block not found")?
.iter()
.map(|tx_id| tx_id.encode_hex())
.collect(),
Expand All @@ -863,8 +857,7 @@ where
let nu5_activation = NetworkUpgrade::Nu5.activation_height(&network);

// This could be `None` if there's a chain reorg between state queries.
let orchard_tree =
orchard_tree.ok_or_misc_error("missing orchard tree for block")?;
let orchard_tree = orchard_tree.ok_or_misc_error("missing Orchard tree")?;

let final_orchard_root = match nu5_activation {
Some(activation_height) if height >= activation_height => {
Expand Down Expand Up @@ -933,50 +926,42 @@ where
.clone()
.oneshot(zebra_state::ReadRequest::BlockHeader(hash_or_height))
.await
.map_err(|_| Error {
.map_err(|_| "block height not in best chain")
.map_error(
// ## Compatibility with `zcashd`.
//
// Since this function is reused by getblock(), we return the errors
// expected by it (they differ whether a hash or a height was passed).
code: if hash_or_height.hash().is_some() {
server::error::LegacyCode::InvalidAddressOrKey.into()
if hash_or_height.hash().is_some() {
server::error::LegacyCode::InvalidAddressOrKey
} else {
server::error::LegacyCode::InvalidParameter.into()
server::error::LegacyCode::InvalidParameter
},
message: "block height not in best chain".to_owned(),
data: None,
})?
)?
else {
panic!("unexpected response to BlockHeader request")
};

let response = if !verbose {
GetBlockHeader::Raw(HexData(
header
.zcash_serialize_to_vec()
.map_error(server::error::LegacyCode::Misc)?,
))
GetBlockHeader::Raw(HexData(header.zcash_serialize_to_vec().map_misc_error()?))
} else {
let zebra_state::ReadResponse::SaplingTree(sapling_tree) = state
.clone()
.oneshot(zebra_state::ReadRequest::SaplingTree(hash_or_height))
.await
.map_error(server::error::LegacyCode::Misc)?
.map_misc_error()?
else {
panic!("unexpected response to SaplingTree request")
};

// This could be `None` if there's a chain reorg between state queries.
let sapling_tree = sapling_tree.ok_or_error(
server::error::LegacyCode::Misc,
"missing sapling tree for block",
)?;
let sapling_tree = sapling_tree.ok_or_misc_error("missing Sapling tree")?;

let zebra_state::ReadResponse::Depth(depth) = state
.clone()
.oneshot(zebra_state::ReadRequest::Depth(hash))
.await
.map_error(server::error::LegacyCode::Misc)?
.map_misc_error()?
else {
panic!("unexpected response to SaplingTree request")
};
Expand Down Expand Up @@ -1036,14 +1021,14 @@ where
self.latest_chain_tip
.best_tip_hash()
.map(GetBlockHash)
.ok_or_error(server::error::LegacyCode::default(), "No blocks in state")
.ok_or_misc_error("No blocks in state")
}

fn get_best_block_height_and_hash(&self) -> Result<GetBlockHeightAndHash> {
self.latest_chain_tip
.best_tip_height_and_hash()
.map(|(height, hash)| GetBlockHeightAndHash { height, hash })
.ok_or_error(server::error::LegacyCode::default(), "No blocks in state")
.ok_or_misc_error("No blocks in state")
}

fn get_raw_mempool(&self) -> BoxFuture<Result<Vec<String>>> {
Expand Down Expand Up @@ -1072,7 +1057,7 @@ where
.ready()
.and_then(|service| service.call(request))
.await
.map_error(server::error::LegacyCode::default())?;
.map_misc_error()?;

match response {
#[cfg(feature = "getblocktemplate-rpcs")]
Expand Down Expand Up @@ -1136,7 +1121,7 @@ where
service.call(mempool::Request::TransactionsByMinedId([txid].into()))
})
.await
.map_error(server::error::LegacyCode::default())?
.map_misc_error()?
{
mempool::Response::Transactions(txns) => {
if let Some(tx) = txns.first() {
Expand All @@ -1162,7 +1147,7 @@ where
.ready()
.and_then(|service| service.call(zebra_state::ReadRequest::Transaction(txid)))
.await
.map_error(server::error::LegacyCode::default())?
.map_misc_error()?
{
zebra_state::ReadResponse::Transaction(Some(tx)) => {
let hex = tx.tx.into();
Expand Down Expand Up @@ -1215,7 +1200,7 @@ where
.ready()
.and_then(|service| service.call(zebra_state::ReadRequest::Block(hash_or_height)))
.await
.map_error(server::error::LegacyCode::default())?
.map_misc_error()?
{
zebra_state::ReadResponse::Block(Some(block)) => block,
zebra_state::ReadResponse::Block(None) => {
Expand Down Expand Up @@ -1246,7 +1231,7 @@ where
service.call(zebra_state::ReadRequest::SaplingTree(hash.into()))
})
.await
.map_error(server::error::LegacyCode::default())?
.map_misc_error()?
{
zebra_state::ReadResponse::SaplingTree(tree) => tree.map(|t| t.to_rpc_bytes()),
_ => unreachable!("unmatched response to a Sapling tree request"),
Expand All @@ -1263,7 +1248,7 @@ where
service.call(zebra_state::ReadRequest::OrchardTree(hash.into()))
})
.await
.map_error(server::error::LegacyCode::default())?
.map_misc_error()?
{
zebra_state::ReadResponse::OrchardTree(tree) => tree.map(|t| t.to_rpc_bytes()),
_ => unreachable!("unmatched response to an Orchard tree request"),
Expand Down Expand Up @@ -1296,7 +1281,7 @@ where
.ready()
.and_then(|service| service.call(request))
.await
.map_error(server::error::LegacyCode::default())?;
.map_misc_error()?;

let subtrees = match response {
zebra_state::ReadResponse::SaplingSubtrees(subtrees) => subtrees,
Expand All @@ -1322,7 +1307,7 @@ where
.ready()
.and_then(|service| service.call(request))
.await
.map_error(server::error::LegacyCode::default())?;
.map_misc_error()?;

let subtrees = match response {
zebra_state::ReadResponse::OrchardSubtrees(subtrees) => subtrees,
Expand Down Expand Up @@ -1382,7 +1367,7 @@ where
.ready()
.and_then(|service| service.call(request))
.await
.map_error(server::error::LegacyCode::default())?;
.map_misc_error()?;

let hashes = match response {
zebra_state::ReadResponse::AddressesTransactionIds(hashes) => {
Expand Down Expand Up @@ -1429,7 +1414,7 @@ where
.ready()
.and_then(|service| service.call(request))
.await
.map_error(server::error::LegacyCode::default())?;
.map_misc_error()?;
let utxos = match response {
zebra_state::ReadResponse::AddressUtxos(utxos) => utxos,
_ => unreachable!("unmatched response to a UtxosByAddresses request"),
Expand Down Expand Up @@ -1507,7 +1492,7 @@ where
{
latest_chain_tip
.best_tip_height()
.ok_or_error(server::error::LegacyCode::default(), "No blocks in state")
.ok_or_misc_error("No blocks in state")
}

/// Response to a `getinfo` RPC request.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::{
constants::{MAX_ESTIMATED_DISTANCE_TO_NETWORK_CHAIN_TIP, NOT_SYNCED_ERROR_CODE},
types::{default_roots::DefaultRoots, transaction::TransactionTemplate},
},
server::{self, error::OkOrError},
server::error::OkOrError,
};

pub use crate::methods::get_block_template_rpcs::types::get_block_template::*;
Expand Down Expand Up @@ -87,13 +87,9 @@ pub fn check_parameters(parameters: &Option<JsonParameters>) -> Result<()> {
pub fn check_miner_address(
miner_address: Option<transparent::Address>,
) -> Result<transparent::Address> {
miner_address.ok_or_else(|| Error {
code: ErrorCode::ServerError(0),
message: "configure mining.miner_address in zebrad.toml \
with a transparent address"
.to_string(),
data: None,
})
miner_address.ok_or_misc_error(
"set `mining.miner_address` in `zebrad.toml` to a transparent address".to_string(),
)
}

/// Attempts to validate block proposal against all of the server's
Expand Down Expand Up @@ -181,10 +177,7 @@ where
// but this is ok for an estimate
let (estimated_distance_to_chain_tip, local_tip_height) = latest_chain_tip
.estimate_distance_to_network_chain_tip(network)
.ok_or_error(
server::error::LegacyCode::default(),
"no chain tip available yet",
)?;
.ok_or_misc_error("no chain tip available yet")?;

if !sync_status.is_close_to_tip()
|| estimated_distance_to_chain_tip > MAX_ESTIMATED_DISTANCE_TO_NETWORK_CHAIN_TIP
Expand Down

0 comments on commit ed69359

Please sign in to comment.