Skip to content

Commit

Permalink
return 500 status code for errors
Browse files Browse the repository at this point in the history
  • Loading branch information
eshaan7 committed Feb 6, 2025
1 parent 6c1ffa1 commit 16abd0f
Showing 1 changed file with 49 additions and 22 deletions.
71 changes: 49 additions & 22 deletions verifiable-api/bin/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use alloy::{
};
use axum::{
extract::{Path, Query, State},
http::StatusCode,
response::Json,
};
use eyre::Result;
use eyre::{Report, Result};
use serde::Deserialize;
use serde_json::json;

Expand All @@ -24,6 +25,10 @@ fn json_err(error: &str) -> Json<serde_json::Value> {
Json(json!({ "error": error }))
}

fn map_server_err(e: Report) -> (StatusCode, Json<serde_json::Value>) {
(StatusCode::INTERNAL_SERVER_ERROR, json_err(&e.to_string()))
}

#[derive(Deserialize)]
pub struct BlockQuery {
block: Option<BlockId>,
Expand All @@ -37,14 +42,14 @@ pub async fn get_balance<N: NetworkSpec, R: ExecutionRpc<N>>(
Path(address): Path<Address>,
Query(BlockQuery { block }): Query<BlockQuery>,
State(ApiState { execution_client }): State<ApiState<N, R>>,
) -> Result<Json<GetBalanceResponse>, Json<serde_json::Value>> {
) -> Result<Json<GetBalanceResponse>, (StatusCode, Json<serde_json::Value>)> {
let block = block.unwrap_or(BlockId::latest());

let proof = execution_client
.rpc
.get_proof(address, &[], block)
.await
.map_err(|e| json_err(&e.to_string()))?;
.map_err(map_server_err)?;

Ok(Json(GetBalanceResponse {
account: Account {
Expand All @@ -65,14 +70,14 @@ pub async fn get_transaction_count<N: NetworkSpec, R: ExecutionRpc<N>>(
Path(address): Path<Address>,
Query(BlockQuery { block }): Query<BlockQuery>,
State(ApiState { execution_client }): State<ApiState<N, R>>,
) -> Result<Json<GetTransactionCountResponse>, Json<serde_json::Value>> {
) -> Result<Json<GetTransactionCountResponse>, (StatusCode, Json<serde_json::Value>)> {
let block = block.unwrap_or(BlockId::latest());

let proof = execution_client
.rpc
.get_proof(address, &[], block)
.await
.map_err(|e| json_err(&e.to_string()))?;
.map_err(map_server_err)?;

Ok(Json(GetTransactionCountResponse {
account: Account {
Expand All @@ -93,7 +98,7 @@ pub async fn get_code<N: NetworkSpec, R: ExecutionRpc<N>>(
Path(address): Path<Address>,
Query(BlockQuery { block }): Query<BlockQuery>,
State(ApiState { execution_client }): State<ApiState<N, R>>,
) -> Result<Json<GetCodeResponse>, Json<serde_json::Value>> {
) -> Result<Json<GetCodeResponse>, (StatusCode, Json<serde_json::Value>)> {
// Ensure that BlockId is of block number variant
let block = block.unwrap_or(BlockId::latest());
let block_num = match block {
Expand All @@ -103,15 +108,20 @@ pub async fn get_code<N: NetworkSpec, R: ExecutionRpc<N>>(
.rpc
.get_block_by_number(tag, BlockTransactionsKind::Hashes)
.await
.map_err(|e| json_err(&e.to_string()))?
.ok_or_else(|| json_err("Block not found"))
.map_err(map_server_err)?
.ok_or_else(|| {
(
StatusCode::INTERNAL_SERVER_ERROR,
json_err("Block not found"),
)
})
.map(|block| block.header().number()),
},
BlockId::Hash(hash) => execution_client
.rpc
.get_block(hash.into())
.await
.map_err(|e| json_err(&e.to_string()))
.map_err(map_server_err)
.map(|block| block.header().number()),
}?;
let block = BlockId::from(block_num);
Expand All @@ -120,13 +130,13 @@ pub async fn get_code<N: NetworkSpec, R: ExecutionRpc<N>>(
.rpc
.get_proof(address, &[], block)
.await
.map_err(|e| json_err(&e.to_string()))?;
.map_err(map_server_err)?;

let code = execution_client
.rpc
.get_code(address, block_num)
.await
.map_err(|e| json_err(&e.to_string()))?;
.map_err(map_server_err)?;

Ok(Json(GetCodeResponse {
code: code.into(),
Expand All @@ -149,24 +159,29 @@ pub async fn get_storage_at<N: NetworkSpec, R: ExecutionRpc<N>>(
Path((address, key)): Path<(Address, U256)>,
Query(BlockQuery { block }): Query<BlockQuery>,
State(ApiState { execution_client }): State<ApiState<N, R>>,
) -> Result<Json<GetStorageAtResponse>, Json<serde_json::Value>> {
) -> Result<Json<GetStorageAtResponse>, (StatusCode, Json<serde_json::Value>)> {
let block = block.unwrap_or(BlockId::latest());

let storage_slot = execution_client
.rpc
.get_storage_at(address, key, block)
.await
.map_err(|e| json_err(&e.to_string()))?;
.map_err(map_server_err)?;

let proof = execution_client
.rpc
.get_proof(address, &[storage_slot.into()], block)
.await
.map_err(|e| json_err(&e.to_string()))?;
.map_err(map_server_err)?;

let storage = match proof.storage_proof.get(0) {
Some(storage) => storage.clone(),
None => return Err(json_err("Failed to get storage proof")),
None => {
return Err((
StatusCode::INTERNAL_SERVER_ERROR,
json_err("Failed to get storage proof"),
))
}
};

Ok(Json(GetStorageAtResponse {
Expand All @@ -187,20 +202,30 @@ pub async fn get_storage_at<N: NetworkSpec, R: ExecutionRpc<N>>(
pub async fn get_transaction_receipt<N: NetworkSpec, R: ExecutionRpc<N>>(
Path(tx_hash): Path<B256>,
State(ApiState { execution_client }): State<ApiState<N, R>>,
) -> Result<Json<GetTransactionReceiptResponse<N>>, Json<serde_json::Value>> {
) -> Result<Json<GetTransactionReceiptResponse<N>>, (StatusCode, Json<serde_json::Value>)> {
let receipt = execution_client
.rpc
.get_transaction_receipt(tx_hash)
.await
.map_err(|e| json_err(&e.to_string()))?
.ok_or_else(|| json_err("Transaction not found"))?;
.map_err(map_server_err)?
.ok_or_else(|| {
(
StatusCode::INTERNAL_SERVER_ERROR,
json_err("Transaction not found"),
)
})?;

let receipts = execution_client
.rpc
.get_block_receipts(BlockTag::Number(receipt.block_number().unwrap()))
.await
.map_err(|e| json_err(&e.to_string()))?
.ok_or_else(|| json_err("No receipts found for the block"))?;
.map_err(map_server_err)?
.ok_or_else(|| {
(
StatusCode::INTERNAL_SERVER_ERROR,
json_err("No receipts found for the block"),
)
})?;

let receipt_proof =
create_receipt_proof::<N>(receipts, receipt.transaction_index().unwrap() as usize);
Expand All @@ -218,13 +243,15 @@ pub async fn get_transaction_receipt<N: NetworkSpec, R: ExecutionRpc<N>>(
pub async fn get_filter_logs<N: NetworkSpec, R: ExecutionRpc<N>>(
Path(filter_id): Path<U256>,
State(ApiState { execution_client }): State<ApiState<N, R>>,
) -> Result<Json<GetFilterLogsResponse<N>>, Json<serde_json::Value>> {
) -> Result<Json<GetFilterLogsResponse<N>>, (StatusCode, Json<serde_json::Value>)> {
// Fetch the filter logs from RPC
let logs = execution_client
.rpc
.get_filter_logs(filter_id)
.await
.map_err(|e| json_err(&e.to_string()))?;
.map_err(map_server_err)?;

// Create a map of transaction hashes to their receipts and proofs
let mut receipt_proofs: HashMap<B256, GetTransactionReceiptResponse<N>> = HashMap::new();

// ToDo(@eshaan7): Optimise this by fetching receipts once per block
Expand Down

0 comments on commit 16abd0f

Please sign in to comment.