From 77042b16c2002cf22a1529204ae7102420dcc634 Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Sat, 12 Oct 2024 23:12:07 -0400 Subject: [PATCH] chore(katana-pool): move to different module (#2528) --- crates/katana/pool/src/lib.rs | 3 +- crates/katana/pool/src/pool.rs | 3 +- crates/katana/pool/src/validation/error.rs | 66 +++++++++++++++++++ crates/katana/pool/src/validation/mod.rs | 56 +--------------- crates/katana/pool/src/validation/stateful.rs | 2 +- .../rpc/rpc-types/src/error/starknet.rs | 4 +- 6 files changed, 76 insertions(+), 58 deletions(-) create mode 100644 crates/katana/pool/src/validation/error.rs diff --git a/crates/katana/pool/src/lib.rs b/crates/katana/pool/src/lib.rs index 465f679732..5a607907b1 100644 --- a/crates/katana/pool/src/lib.rs +++ b/crates/katana/pool/src/lib.rs @@ -12,8 +12,9 @@ use katana_primitives::transaction::{ExecutableTxWithHash, TxHash}; use ordering::{FiFo, PoolOrd}; use pool::Pool; use tx::{PendingTx, PoolTransaction}; +use validation::error::InvalidTransactionError; use validation::stateful::TxValidator; -use validation::{InvalidTransactionError, Validator}; +use validation::Validator; /// Katana default transacstion pool type. pub type TxPool = Pool>; diff --git a/crates/katana/pool/src/pool.rs b/crates/katana/pool/src/pool.rs index 47ec956073..1031f17a0f 100644 --- a/crates/katana/pool/src/pool.rs +++ b/crates/katana/pool/src/pool.rs @@ -10,7 +10,8 @@ use tracing::{error, info, warn}; use crate::ordering::PoolOrd; use crate::tx::{PendingTx, PoolTransaction, TxId}; -use crate::validation::{InvalidTransactionError, ValidationOutcome, Validator}; +use crate::validation::error::InvalidTransactionError; +use crate::validation::{ValidationOutcome, Validator}; use crate::{PoolError, PoolResult, TransactionPool}; #[derive(Debug)] diff --git a/crates/katana/pool/src/validation/error.rs b/crates/katana/pool/src/validation/error.rs new file mode 100644 index 0000000000..1dc68d5c14 --- /dev/null +++ b/crates/katana/pool/src/validation/error.rs @@ -0,0 +1,66 @@ +use katana_primitives::class::ClassHash; +use katana_primitives::contract::{ContractAddress, Nonce}; +use katana_primitives::Felt; + +// TODO: figure out how to combine this with ExecutionError +#[derive(Debug, thiserror::Error)] +pub enum InvalidTransactionError { + /// Error when the account's balance is insufficient to cover the specified transaction fee. + #[error("Max fee ({max_fee}) exceeds balance ({balance}).")] + InsufficientFunds { + /// The specified transaction fee. + max_fee: u128, + /// The account's balance of the fee token. + balance: Felt, + }, + + /// Error when the specified transaction fee is insufficient to cover the minimum fee required + /// to start the invocation (including the account's validation logic). + /// + /// It is a static check that is performed before the transaction is invoked to ensure the + /// transaction can cover the intrinsics cost ie data availability, etc. + /// + /// This is different from an error due to transaction runs out of gas during execution ie. + /// the specified max fee is lower than the amount needed to finish the transaction execution + /// (either validation or execution). + #[error("Intrinsic transaction fee is too low")] + IntrinsicFeeTooLow { + /// The minimum required for the transaction to be executed. + min: u128, + /// The specified transaction fee. + max_fee: u128, + }, + + /// Error when the account's validation logic fails (ie __validate__ function). + #[error("{error}")] + ValidationFailure { + /// The address of the contract that failed validation. + address: ContractAddress, + /// The class hash of the account contract. + class_hash: ClassHash, + /// The error message returned by Blockifier. + // TODO: this should be a more specific error type. + error: String, + }, + + /// Error when the transaction's sender is not an account contract. + #[error("Sender is not an account")] + NonAccount { + /// The address of the contract that is not an account. + address: ContractAddress, + }, + + /// Error when the transaction is using a nonexpected nonce. + #[error( + "Invalid transaction nonce of contract at address {address}. Account nonce: \ + {current_nonce:#x}; got: {tx_nonce:#x}." + )] + InvalidNonce { + /// The address of the contract that has the invalid nonce. + address: ContractAddress, + /// The current nonce of the sender's account. + current_nonce: Nonce, + /// The nonce that the tx is using. + tx_nonce: Nonce, + }, +} diff --git a/crates/katana/pool/src/validation/mod.rs b/crates/katana/pool/src/validation/mod.rs index fe885ea276..7544d853ea 100644 --- a/crates/katana/pool/src/validation/mod.rs +++ b/crates/katana/pool/src/validation/mod.rs @@ -1,9 +1,9 @@ +pub mod error; pub mod stateful; -use katana_primitives::class::ClassHash; -use katana_primitives::contract::{ContractAddress, Nonce}; +use error::InvalidTransactionError; +use katana_primitives::contract::Nonce; use katana_primitives::transaction::TxHash; -use katana_primitives::Felt; use crate::tx::PoolTransaction; @@ -16,56 +16,6 @@ pub struct Error { pub error: Box, } -// TODO: figure out how to combine this with ExecutionError -#[derive(Debug, thiserror::Error)] -pub enum InvalidTransactionError { - /// Error when the account's balance is insufficient to cover the specified transaction fee. - #[error("Max fee ({max_fee}) exceeds balance ({balance}).")] - InsufficientFunds { - /// The specified transaction fee. - max_fee: u128, - /// The account's balance of the fee token. - balance: Felt, - }, - - /// Error when the specified transaction fee is insufficient to cover the minimum fee required. - #[error("The specified tx max fee is insufficient")] - InsufficientMaxFee { min_fee: u128, max_fee: u128 }, - - /// Error when the account's validation logic fails (ie __validate__ function). - #[error("{error}")] - ValidationFailure { - /// The address of the contract that failed validation. - address: ContractAddress, - /// The class hash of the account contract. - class_hash: ClassHash, - /// The error message returned by Blockifier. - // TODO: this should be a more specific error type. - error: String, - }, - - /// Error when the transaction's sender is not an account contract. - #[error("sender is not an account")] - NonAccount { - /// The address of the contract that is not an account. - address: ContractAddress, - }, - - /// Error when the transaction is using a nonexpected nonce. - #[error( - "Invalid transaction nonce of contract at address {address}. Account nonce: \ - {current_nonce:#x}; got: {tx_nonce:#x}." - )] - InvalidNonce { - /// The address of the contract that has the invalid nonce. - address: ContractAddress, - /// The current nonce of the sender's account. - current_nonce: Nonce, - /// The nonce that the tx is using. - tx_nonce: Nonce, - }, -} - pub type ValidationResult = Result, Error>; /// A trait for validating transactions before they are added to the transaction pool. diff --git a/crates/katana/pool/src/validation/stateful.rs b/crates/katana/pool/src/validation/stateful.rs index 911ac242e2..d803c17f1d 100644 --- a/crates/katana/pool/src/validation/stateful.rs +++ b/crates/katana/pool/src/validation/stateful.rs @@ -209,7 +209,7 @@ fn map_invalid_tx_err( TransactionFeeError::MaxFeeTooLow { min_fee, max_fee } => { let max_fee = max_fee.0; let min_fee = min_fee.0; - Ok(InvalidTransactionError::InsufficientMaxFee { max_fee, min_fee }) + Ok(InvalidTransactionError::IntrinsicFeeTooLow { max_fee, min: min_fee }) } _ => Err(Box::new(err)), diff --git a/crates/katana/rpc/rpc-types/src/error/starknet.rs b/crates/katana/rpc/rpc-types/src/error/starknet.rs index d5aecfb5dd..9fdddba0cf 100644 --- a/crates/katana/rpc/rpc-types/src/error/starknet.rs +++ b/crates/katana/rpc/rpc-types/src/error/starknet.rs @@ -1,7 +1,7 @@ use jsonrpsee::core::Error; use jsonrpsee::types::error::CallError; use jsonrpsee::types::ErrorObject; -use katana_pool::validation::InvalidTransactionError; +use katana_pool::validation::error::InvalidTransactionError; use katana_pool::PoolError; use katana_primitives::event::ContinuationTokenError; use katana_provider::error::ProviderError; @@ -182,7 +182,7 @@ impl From> for StarknetApiError { fn from(error: Box) -> Self { match error.as_ref() { InvalidTransactionError::InsufficientFunds { .. } => Self::InsufficientAccountBalance, - InvalidTransactionError::InsufficientMaxFee { .. } => Self::InsufficientMaxFee, + InvalidTransactionError::IntrinsicFeeTooLow { .. } => Self::InsufficientMaxFee, InvalidTransactionError::NonAccount { .. } => Self::NonAccount, InvalidTransactionError::InvalidNonce { .. } => { Self::InvalidTransactionNonce { reason: error.to_string() }