Skip to content

Commit

Permalink
refactor(katana): improve error handling (#1415)
Browse files Browse the repository at this point in the history
improve error handling
  • Loading branch information
kariy authored Jan 12, 2024
1 parent 70360e2 commit 11fcd1f
Show file tree
Hide file tree
Showing 24 changed files with 768 additions and 487 deletions.
2 changes: 1 addition & 1 deletion crates/katana/core/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl Backend {
);

let blockchain = Blockchain::new_from_forked(
ForkedProvider::new(provider, forked_block_num.into()),
ForkedProvider::new(provider, forked_block_num.into()).unwrap(),
block.block_hash,
block.parent_hash,
&block_context,
Expand Down
26 changes: 3 additions & 23 deletions crates/katana/core/src/sequencer_error.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,26 @@
use blockifier::execution::errors::EntryPointExecutionError;
use blockifier::state::errors::StateError;
use blockifier::transaction::errors::TransactionExecutionError;
use katana_primitives::block::BlockIdOrTag;
use katana_primitives::contract::ContractAddress;
use katana_primitives::event::ContinuationTokenError;
use katana_primitives::transaction::TxHash;
use starknet_api::StarknetApiError;
use katana_provider::error::ProviderError;

#[derive(Debug, thiserror::Error)]
pub enum SequencerError {
#[error("Block {0:?} not found.")]
BlockNotFound(BlockIdOrTag),
#[error("Contract address {0:?} not found.")]
#[error("Contract address {0} not found.")]
ContractNotFound(ContractAddress),
#[error("State update for block {0:?} not found.")]
StateUpdateNotFound(BlockIdOrTag),
#[error("State for block {0:?} not found.")]
StateNotFound(BlockIdOrTag),
#[error("Transaction with {0} hash not found.")]
TxnNotFound(TxHash),
#[error(transparent)]
State(#[from] StateError),
#[error(transparent)]
TransactionExecution(#[from] TransactionExecutionError),
#[error("Error converting {from} into {to}: {message}")]
ConversionError { from: String, to: String, message: String },
#[error(transparent)]
StarknetApi(#[from] StarknetApiError),
#[error(transparent)]
EntryPointExecution(#[from] EntryPointExecutionError),
#[error("Wait for pending transactions.")]
PendingTransactions,
#[error("Unsupported Transaction")]
UnsupportedTransaction,
#[error(transparent)]
ContinuationToken(#[from] ContinuationTokenError),
#[error("Error serializing state.")]
StateSerialization,
#[error("Required data unavailable")]
DataUnavailable,
#[error("Failed to decode state")]
FailedToDecodeStateDump,
#[error(transparent)]
Other(#[from] anyhow::Error),
Provider(#[from] ProviderError),
}
13 changes: 7 additions & 6 deletions crates/katana/executor/src/blockifier/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use katana_primitives::contract::FlattenedSierraClass;
use katana_primitives::FieldElement;
use katana_provider::traits::contract::ContractClassProvider;
use katana_provider::traits::state::StateProvider;
use katana_provider::ProviderResult;
use parking_lot::{Mutex, RawMutex, RwLock};
use starknet_api::core::{ClassHash, CompiledClassHash, Nonce, PatriciaKey};
use starknet_api::hash::StarkHash;
Expand Down Expand Up @@ -140,7 +141,7 @@ where
fn class(
&self,
hash: katana_primitives::contract::ClassHash,
) -> anyhow::Result<Option<katana_primitives::contract::CompiledContractClass>> {
) -> ProviderResult<Option<katana_primitives::contract::CompiledContractClass>> {
let Ok(class) = self.inner().get_compiled_contract_class(&ClassHash(hash.into())) else {
return Ok(None);
};
Expand All @@ -150,7 +151,7 @@ where
fn compiled_class_hash_of_class_hash(
&self,
hash: katana_primitives::contract::ClassHash,
) -> anyhow::Result<Option<katana_primitives::contract::CompiledClassHash>> {
) -> ProviderResult<Option<katana_primitives::contract::CompiledClassHash>> {
let Ok(hash) = self.inner().get_compiled_class_hash(ClassHash(hash.into())) else {
return Ok(None);
};
Expand All @@ -160,7 +161,7 @@ where
fn sierra_class(
&self,
hash: katana_primitives::contract::ClassHash,
) -> anyhow::Result<Option<FlattenedSierraClass>> {
) -> ProviderResult<Option<FlattenedSierraClass>> {
let class @ Some(_) = self.sierra_class().get(&hash).cloned() else {
return Ok(None);
};
Expand All @@ -176,7 +177,7 @@ where
&self,
address: katana_primitives::contract::ContractAddress,
storage_key: katana_primitives::contract::StorageKey,
) -> anyhow::Result<Option<katana_primitives::contract::StorageValue>> {
) -> ProviderResult<Option<katana_primitives::contract::StorageValue>> {
let Ok(value) =
self.inner().get_storage_at(address.into(), StorageKey(patricia_key!(storage_key)))
else {
Expand All @@ -188,7 +189,7 @@ where
fn nonce(
&self,
address: katana_primitives::contract::ContractAddress,
) -> anyhow::Result<Option<katana_primitives::contract::Nonce>> {
) -> ProviderResult<Option<katana_primitives::contract::Nonce>> {
let Ok(nonce) = self.inner().get_nonce_at(address.into()) else {
return Ok(None);
};
Expand All @@ -198,7 +199,7 @@ where
fn class_hash_of_contract(
&self,
address: katana_primitives::contract::ContractAddress,
) -> anyhow::Result<Option<katana_primitives::contract::ClassHash>> {
) -> ProviderResult<Option<katana_primitives::contract::ClassHash>> {
let Ok(hash) = self.inner().get_class_hash_at(address.into()) else {
return Ok(None);
};
Expand Down
6 changes: 3 additions & 3 deletions crates/katana/rpc/rpc-types-builder/src/block.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::Result;
use katana_primitives::block::BlockHashOrNumber;
use katana_provider::traits::block::{BlockHashProvider, BlockProvider, BlockStatusProvider};
use katana_provider::ProviderResult;
use katana_rpc_types::block::{BlockWithTxHashes, BlockWithTxs};

/// A builder for building RPC block types.
Expand All @@ -19,7 +19,7 @@ impl<P> BlockBuilder<P>
where
P: BlockProvider + BlockHashProvider,
{
pub fn build(self) -> Result<Option<BlockWithTxs>> {
pub fn build(self) -> ProviderResult<Option<BlockWithTxs>> {
let Some(hash) = BlockHashProvider::block_hash_by_id(&self.provider, self.block_id)? else {
return Ok(None);
};
Expand All @@ -32,7 +32,7 @@ where
Ok(Some(BlockWithTxs::new(hash, block, finality_status)))
}

pub fn build_with_tx_hash(self) -> Result<Option<BlockWithTxHashes>> {
pub fn build_with_tx_hash(self) -> ProviderResult<Option<BlockWithTxHashes>> {
let Some(hash) = BlockHashProvider::block_hash_by_id(&self.provider, self.block_id)? else {
return Ok(None);
};
Expand Down
3 changes: 2 additions & 1 deletion crates/katana/rpc/rpc-types-builder/src/state_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use katana_primitives::FieldElement;
use katana_provider::traits::block::{BlockHashProvider, BlockNumberProvider};
use katana_provider::traits::state::StateRootProvider;
use katana_provider::traits::state_update::StateUpdateProvider;
use katana_provider::ProviderResult;
use katana_rpc_types::state_update::{StateDiff, StateUpdate};

/// A builder for building RPC state update type.
Expand All @@ -22,7 +23,7 @@ where
P: BlockHashProvider + BlockNumberProvider + StateRootProvider + StateUpdateProvider,
{
/// Builds a state update for the given block.
pub fn build(self) -> anyhow::Result<Option<StateUpdate>> {
pub fn build(self) -> ProviderResult<Option<StateUpdate>> {
let Some(block_hash) = BlockHashProvider::block_hash_by_id(&self.provider, self.block_id)?
else {
return Ok(None);
Expand Down
46 changes: 40 additions & 6 deletions crates/katana/rpc/src/api/starknet.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use jsonrpsee::core::Error;
use jsonrpsee::proc_macros::rpc;
use jsonrpsee::types::error::{CallError, ErrorObject};
use katana_core::sequencer_error::SequencerError;
use katana_primitives::block::{BlockIdOrTag, BlockNumber};
use katana_primitives::transaction::TxHash;
use katana_primitives::FieldElement;
use katana_provider::error::ProviderError;
use katana_rpc_types::block::{
BlockHashAndNumber, BlockTxCount, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs,
};
Expand Down Expand Up @@ -72,7 +74,7 @@ pub enum StarknetApiError {
#[error("The contract class version is not supported")]
UnsupportedContractClassVersion,
#[error("An unexpected error occured")]
UnexpectedError,
UnexpectedError { reason: String },
#[error("Too many storage keys requested")]
ProofLimitExceeded,
#[error("Too many keys provided in a filter")]
Expand Down Expand Up @@ -111,25 +113,57 @@ impl StarknetApiError {
StarknetApiError::CompiledClassHashMismatch => 60,
StarknetApiError::UnsupportedTransactionVersion => 61,
StarknetApiError::UnsupportedContractClassVersion => 62,
StarknetApiError::UnexpectedError => 63,
StarknetApiError::UnexpectedError { .. } => 63,
StarknetApiError::ProofLimitExceeded => 10000,
}
}
}

impl From<ProviderError> for StarknetApiError {
fn from(value: ProviderError) -> Self {
StarknetApiError::UnexpectedError { reason: value.to_string() }
}
}

impl From<StarknetApiError> for Error {
fn from(err: StarknetApiError) -> Self {
let code = err.code();
let message = err.to_string();

let data = match err {
let err = match err {
StarknetApiError::ContractError { revert_error } => {
Some(ContractErrorData { revert_error })
ErrorObject::owned(code, message, Some(ContractErrorData { revert_error }))
}
_ => None,

StarknetApiError::UnexpectedError { reason } => {
#[derive(serde::Serialize, serde::Deserialize)]
struct UnexpectedError {
reason: String,
}

ErrorObject::owned(code, message, Some(UnexpectedError { reason }))
}

_ => ErrorObject::owned(code, message, None::<()>),
};

Error::Call(CallError::Custom(ErrorObject::owned(code, message, data)))
Error::Call(CallError::Custom(err))
}
}

impl From<SequencerError> for StarknetApiError {
fn from(value: SequencerError) -> Self {
match value {
SequencerError::TransactionExecution(e) => {
StarknetApiError::ContractError { revert_error: e.to_string() }
}
SequencerError::EntryPointExecution(e) => {
StarknetApiError::ContractError { revert_error: e.to_string() }
}
SequencerError::BlockNotFound(_) => StarknetApiError::BlockNotFound,
SequencerError::ContractNotFound(_) => StarknetApiError::ContractNotFound,
err => StarknetApiError::UnexpectedError { reason: err.to_string() },
}
}
}

Expand Down
Loading

0 comments on commit 11fcd1f

Please sign in to comment.