From d0e9d09823e37d8c0ce05204c0632c09782b8909 Mon Sep 17 00:00:00 2001 From: Yair Bakalchuk Date: Wed, 24 Jul 2024 10:22:22 +0300 Subject: [PATCH] feat(gateway): return GatewaySpecErrr to match the SN spec --- Cargo.lock | 22 +++++ Cargo.toml | 1 + crates/gateway/Cargo.toml | 1 + crates/gateway/src/compilation.rs | 43 ++++++--- crates/gateway/src/compilation_test.rs | 33 ++++--- crates/gateway/src/errors.rs | 90 ++++++++----------- crates/gateway/src/gateway.rs | 19 ++-- .../src/stateful_transaction_validator.rs | 18 +++- .../stateful_transaction_validator_test.rs | 31 ++++--- .../src/stateless_transaction_validator.rs | 2 + crates/gateway/src/utils.rs | 35 ++++++-- .../src/integration_test_setup.rs | 4 +- .../src/integration_test_utils.rs | 4 +- 13 files changed, 185 insertions(+), 118 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b84512c6d..1d893722c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5486,6 +5486,7 @@ dependencies = [ "thiserror", "tokio", "tracing", + "tracing-test", "validator", ] @@ -6199,6 +6200,27 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "tracing-test" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "557b891436fe0d5e0e363427fc7f217abf9ccd510d5136549847bdcbcd011d68" +dependencies = [ + "tracing-core", + "tracing-subscriber", + "tracing-test-macro", +] + +[[package]] +name = "tracing-test-macro" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" +dependencies = [ + "quote", + "syn 2.0.70", +] + [[package]] name = "try-lock" version = "0.2.5" diff --git a/Cargo.toml b/Cargo.toml index a354c9b38..cc13442da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,5 +78,6 @@ tokio = { version = "1.37.0", features = ["full"] } tokio-test = "0.4.4" tracing = "0.1.37" tracing-subscriber = "0.3.16" +tracing-test = "0.2" url = "2.5.0" validator = "0.12" diff --git a/crates/gateway/Cargo.toml b/crates/gateway/Cargo.toml index 07e22a745..751f8365e 100644 --- a/crates/gateway/Cargo.toml +++ b/crates/gateway/Cargo.toml @@ -45,3 +45,4 @@ num-bigint.workspace = true pretty_assertions.workspace = true rstest.workspace = true starknet_mempool = { path = "../mempool", version = "0.0" } +tracing-test.workspace = true diff --git a/crates/gateway/src/compilation.rs b/crates/gateway/src/compilation.rs index 2eaf81017..28094c003 100644 --- a/crates/gateway/src/compilation.rs +++ b/crates/gateway/src/compilation.rs @@ -6,11 +6,11 @@ use cairo_lang_starknet_classes::contract_class::ContractClass as CairoLangContr use starknet_api::core::CompiledClassHash; use starknet_api::rpc_transaction::RPCDeclareTransaction; use starknet_sierra_compile::compile::compile_sierra_to_casm; -use starknet_sierra_compile::errors::CompilationUtilError; use starknet_sierra_compile::utils::into_contract_class_for_compilation; +use tracing::{debug, error}; use crate::config::GatewayCompilerConfig; -use crate::errors::{GatewayError, GatewayResult}; +use crate::errors::{GatewayResult, GatewaySpecError}; #[cfg(test)] #[path = "compilation_test.rs"] @@ -39,22 +39,38 @@ impl GatewayCompiler { validate_compiled_class_hash(&casm_contract_class, &tx.compiled_class_hash)?; - Ok(ClassInfo::new( - &ContractClass::V1(ContractClassV1::try_from(casm_contract_class)?), + ClassInfo::new( + &ContractClass::V1(ContractClassV1::try_from(casm_contract_class).map_err(|e| { + error!("Failed to convert CasmContractClass to Blockifier ContractClass: {:?}", e); + GatewaySpecError::UnexpectedError("Internal server error.".to_owned()) + })?), rpc_contract_class.sierra_program.len(), rpc_contract_class.abi.len(), - )?) + ) + .map_err(|e| { + error!("Failed to convert Blockifier ContractClass to Blockifier ClassInfo: {:?}", e); + GatewaySpecError::UnexpectedError("Internal server error.".to_owned()) + }) } // TODO(Arni): Pass the compilation args from the config. fn compile( &self, cairo_lang_contract_class: CairoLangContractClass, - ) -> Result { + ) -> GatewayResult { let catch_unwind_result = panic::catch_unwind(|| compile_sierra_to_casm(cairo_lang_contract_class)); - let casm_contract_class = - catch_unwind_result.map_err(|_| CompilationUtilError::CompilationPanic)??; + let casm_contract_class = match catch_unwind_result { + Ok(compilation_result) => compilation_result.map_err(|e| { + debug!("Compilation failed: {:?}", e); + GatewaySpecError::CompilationFailed + })?, + Err(_panicked_compilation) => { + // TODO(Arni): Log the panic. + error!("Compilation panicked."); + return Err(GatewaySpecError::UnexpectedError("Internal server error.".to_owned())); + } + }; Ok(casm_contract_class) } @@ -65,13 +81,14 @@ impl GatewayCompiler { fn validate_compiled_class_hash( casm_contract_class: &CasmContractClass, supplied_compiled_class_hash: &CompiledClassHash, -) -> Result<(), GatewayError> { +) -> GatewayResult<()> { let compiled_class_hash = CompiledClassHash(casm_contract_class.compiled_class_hash()); if compiled_class_hash != *supplied_compiled_class_hash { - return Err(GatewayError::CompiledClassHashMismatch { - supplied: *supplied_compiled_class_hash, - hash_result: compiled_class_hash, - }); + debug!( + "Compiled class hash mismatch. Supplied: {:?}, Hash result: {:?}", + supplied_compiled_class_hash, compiled_class_hash + ); + return Err(GatewaySpecError::CompiledClassHashMismatch); } Ok(()) } diff --git a/crates/gateway/src/compilation_test.rs b/crates/gateway/src/compilation_test.rs index 913f71857..a5318e81f 100644 --- a/crates/gateway/src/compilation_test.rs +++ b/crates/gateway/src/compilation_test.rs @@ -6,9 +6,10 @@ use rstest::{fixture, rstest}; use starknet_api::core::CompiledClassHash; use starknet_api::rpc_transaction::{RPCDeclareTransaction, RPCTransaction}; use starknet_sierra_compile::errors::CompilationUtilError; +use tracing_test::traced_test; use crate::compilation::GatewayCompiler; -use crate::errors::GatewayError; +use crate::errors::GatewaySpecError; #[fixture] fn gateway_compiler() -> GatewayCompiler { @@ -16,6 +17,7 @@ fn gateway_compiler() -> GatewayCompiler { } // TODO(Arni): Redesign this test once the compiler is passed with dependancy injection. +#[traced_test] #[rstest] fn test_compile_contract_class_compiled_class_hash_mismatch(gateway_compiler: GatewayCompiler) { let mut tx = assert_matches!( @@ -27,14 +29,18 @@ fn test_compile_contract_class_compiled_class_hash_mismatch(gateway_compiler: Ga tx.compiled_class_hash = wrong_supplied_hash; let declare_tx = RPCDeclareTransaction::V3(tx); - let result = gateway_compiler.process_declare_tx(&declare_tx); - assert_matches!( - result.unwrap_err(), - GatewayError::CompiledClassHashMismatch { supplied, hash_result } - if supplied == wrong_supplied_hash && hash_result == expected_hash - ); + let err = gateway_compiler.process_declare_tx(&declare_tx).unwrap_err(); + assert_eq!(err, GatewaySpecError::CompiledClassHashMismatch); + assert!(logs_contain( + format!( + "Compiled class hash mismatch. Supplied: {:?}, Hash result: {:?}", + wrong_supplied_hash, expected_hash + ) + .as_str() + )); } +#[traced_test] #[rstest] fn test_compile_contract_class_bad_sierra(gateway_compiler: GatewayCompiler) { let mut tx = assert_matches!( @@ -45,13 +51,12 @@ fn test_compile_contract_class_bad_sierra(gateway_compiler: GatewayCompiler) { tx.contract_class.sierra_program = tx.contract_class.sierra_program[..100].to_vec(); let declare_tx = RPCDeclareTransaction::V3(tx); - let result = gateway_compiler.process_declare_tx(&declare_tx); - assert_matches!( - result.unwrap_err(), - GatewayError::CompilationError(CompilationUtilError::AllowedLibfuncsError( - AllowedLibfuncsError::SierraProgramError - )) - ) + let err = gateway_compiler.process_declare_tx(&declare_tx).unwrap_err(); + assert_eq!(err, GatewaySpecError::CompilationFailed); + + let expected_compilation_error = + CompilationUtilError::AllowedLibfuncsError(AllowedLibfuncsError::SierraProgramError); + assert!(logs_contain(format!("Compilation failed: {:?}", expected_compilation_error).as_str())); } #[rstest] diff --git a/crates/gateway/src/errors.rs b/crates/gateway/src/errors.rs index c4e96937f..0182726fd 100644 --- a/crates/gateway/src/errors.rs +++ b/crates/gateway/src/errors.rs @@ -1,62 +1,27 @@ use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; -use blockifier::blockifier::stateful_validator::StatefulValidatorError; -use blockifier::execution::errors::ContractClassError; use blockifier::state::errors::StateError; -use blockifier::transaction::errors::TransactionExecutionError; -use cairo_vm::types::errors::program_errors::ProgramError; use enum_assoc::Assoc; use serde::Serialize; use serde_json::{Error as SerdeError, Value}; use starknet_api::block::GasPrice; -use starknet_api::core::CompiledClassHash; use starknet_api::transaction::{Resource, ResourceBounds}; -use starknet_api::StarknetApiError; -use starknet_sierra_compile::errors::CompilationUtilError; use strum::EnumIter; use thiserror::Error; -use tokio::task::JoinError; use crate::compiler_version::{VersionId, VersionIdError}; -/// Errors directed towards the end-user, as a result of gateway requests. -#[derive(Debug, Error)] -pub enum GatewayError { - #[error(transparent)] - CompilationError(#[from] CompilationUtilError), - #[error( - "The supplied compiled class hash {supplied:?} does not match the hash of the Casm class \ - compiled from the supplied Sierra {hash_result:?}" - )] - CompiledClassHashMismatch { supplied: CompiledClassHash, hash_result: CompiledClassHash }, - #[error(transparent)] - DeclaredContractClassError(#[from] ContractClassError), - #[error(transparent)] - DeclaredContractProgramError(#[from] ProgramError), - #[error("Internal server error: {0}")] - InternalServerError(#[from] JoinError), - #[error("Error sending message: {0}")] - MessageSendError(String), - #[error(transparent)] - StatefulTransactionValidatorError(#[from] StatefulTransactionValidatorError), - #[error(transparent)] - StatelessTransactionValidatorError(#[from] StatelessTransactionValidatorError), - #[error("{builtins:?} is not a subsquence of {supported_builtins:?}")] - UnsupportedBuiltins { builtins: Vec, supported_builtins: Vec }, -} - -pub type GatewayResult = Result; +pub type GatewayResult = Result; -impl IntoResponse for GatewayError { - // TODO(Arni, 1/5/2024): Be more fine tuned about the error response. Not all Gateway errors - // are internal server errors. +impl IntoResponse for GatewaySpecError { fn into_response(self) -> Response { let body = self.to_string(); - (StatusCode::INTERNAL_SERVER_ERROR, body).into_response() + (StatusCode::from_u16(self.code()).expect("Expecting a valid error code"), body) + .into_response() } } -#[derive(Error, Debug, Assoc, Clone, EnumIter, Serialize)] +#[derive(Error, Debug, Assoc, Clone, EnumIter, Serialize, PartialEq)] #[func(pub fn code(&self) -> u16)] #[func(pub fn data(&self) -> Option<&str>)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] @@ -146,21 +111,40 @@ pub enum StatelessTransactionValidatorError { EntryPointsNotUniquelySorted, } -pub type StatelessTransactionValidatorResult = Result; - -#[derive(Debug, Error)] -pub enum StatefulTransactionValidatorError { - #[error(transparent)] - StarknetApiError(#[from] StarknetApiError), - #[error(transparent)] - StateError(#[from] StateError), - #[error(transparent)] - StatefulValidatorError(#[from] StatefulValidatorError), - #[error(transparent)] - TransactionExecutionError(#[from] TransactionExecutionError), +impl From for GatewaySpecError { + fn from(e: StatelessTransactionValidatorError) -> Self { + match e { + StatelessTransactionValidatorError::ZeroResourceBounds { .. } => { + GatewaySpecError::ValidationFailure(e.to_string()) + } + StatelessTransactionValidatorError::CalldataTooLong { .. } => { + GatewaySpecError::ValidationFailure(e.to_string()) + } + StatelessTransactionValidatorError::SignatureTooLong { .. } => { + GatewaySpecError::ValidationFailure(e.to_string()) + } + StatelessTransactionValidatorError::InvalidSierraVersion(..) => { + GatewaySpecError::ValidationFailure(e.to_string()) + } + StatelessTransactionValidatorError::UnsupportedSierraVersion { .. } => { + GatewaySpecError::UnsupportedContractClassVersion + } + StatelessTransactionValidatorError::BytecodeSizeTooLarge { .. } => { + GatewaySpecError::ContractClassSizeIsTooLarge + } + StatelessTransactionValidatorError::ContractClassObjectSizeTooLarge { .. } => { + GatewaySpecError::ContractClassSizeIsTooLarge + } + StatelessTransactionValidatorError::EntryPointsNotUniquelySorted => { + GatewaySpecError::ValidationFailure(e.to_string()) + } + } + } } -pub type StatefulTransactionValidatorResult = Result; +pub type StatelessTransactionValidatorResult = Result; + +pub type StatefulTransactionValidatorResult = Result; /// Errors originating from `[`Gateway::run`]` command, to be handled by infrastructure code. #[derive(Debug, Error)] diff --git a/crates/gateway/src/gateway.rs b/crates/gateway/src/gateway.rs index 61c1b4764..2ef95c18d 100644 --- a/crates/gateway/src/gateway.rs +++ b/crates/gateway/src/gateway.rs @@ -11,11 +11,11 @@ use starknet_api::transaction::TransactionHash; use starknet_mempool_infra::component_runner::{ComponentStartError, ComponentStarter}; use starknet_mempool_types::communication::SharedMempoolClient; use starknet_mempool_types::mempool_types::{Account, MempoolInput}; -use tracing::{info, instrument}; +use tracing::{error, info, instrument}; use crate::compilation::GatewayCompiler; use crate::config::{GatewayConfig, GatewayNetworkConfig, RpcStateReaderConfig}; -use crate::errors::{GatewayError, GatewayResult, GatewayRunError}; +use crate::errors::{GatewayResult, GatewayRunError, GatewaySpecError}; use crate::rpc_state_reader::RpcStateReaderFactory; use crate::state_reader::StateReaderFactory; use crate::stateful_transaction_validator::StatefulTransactionValidator; @@ -100,15 +100,18 @@ async fn add_tx( tx, ) }) - .await??; + .await + .map_err(|join_err| { + error!("Failed to process tx: {}", join_err); + GatewaySpecError::UnexpectedError("Internal server error".to_owned()) + })??; let tx_hash = mempool_input.tx.tx_hash; - app_state - .mempool_client - .add_tx(mempool_input) - .await - .map_err(|e| GatewayError::MessageSendError(e.to_string()))?; + app_state.mempool_client.add_tx(mempool_input).await.map_err(|e| { + error!("Failed to send tx to mempool: {}", e); + GatewaySpecError::UnexpectedError("Internal server error".to_owned()) + })?; // TODO: Also return `ContractAddress` for deploy and `ClassHash` for Declare. Ok(Json(tx_hash)) } diff --git a/crates/gateway/src/stateful_transaction_validator.rs b/crates/gateway/src/stateful_transaction_validator.rs index 50b2c3c10..084adedd2 100644 --- a/crates/gateway/src/stateful_transaction_validator.rs +++ b/crates/gateway/src/stateful_transaction_validator.rs @@ -14,9 +14,10 @@ use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::rpc_transaction::{RPCInvokeTransaction, RPCTransaction}; use starknet_api::transaction::TransactionHash; use starknet_types_core::felt::Felt; +use tracing::error; use crate::config::StatefulTransactionValidatorConfig; -use crate::errors::StatefulTransactionValidatorResult; +use crate::errors::{GatewaySpecError, StatefulTransactionValidatorResult}; use crate::state_reader::{MempoolStateReader, StateReaderFactory}; use crate::utils::{external_tx_to_account_tx, get_sender_address, get_tx_hash}; @@ -75,9 +76,15 @@ impl StatefulTransactionValidator { &self.config.chain_info.chain_id, )?; let tx_hash = get_tx_hash(&account_tx); - let account_nonce = validator.get_nonce(get_sender_address(external_tx))?; + let sender_address = get_sender_address(external_tx); + let account_nonce = validator.get_nonce(sender_address).map_err(|e| { + error!("Failed to get nonce for sender address {}: {}", sender_address, e); + GatewaySpecError::UnexpectedError("Internal server error.".to_owned()) + })?; let skip_validate = skip_stateful_validations(external_tx, account_nonce); - validator.validate(account_tx, skip_validate)?; + validator + .validate(account_tx, skip_validate) + .map_err(|err| GatewaySpecError::ValidationFailure(err.to_string()))?; Ok(tx_hash) } @@ -128,5 +135,8 @@ pub fn get_latest_block_info( state_reader_factory: &dyn StateReaderFactory, ) -> StatefulTransactionValidatorResult { let state_reader = state_reader_factory.get_state_reader_from_latest_block(); - Ok(state_reader.get_block_info()?) + state_reader.get_block_info().map_err(|e| { + error!("Failed to get latest block info: {}", e); + GatewaySpecError::UnexpectedError("Internal server error.".to_owned()) + }) } diff --git a/crates/gateway/src/stateful_transaction_validator_test.rs b/crates/gateway/src/stateful_transaction_validator_test.rs index 8b143d03b..d10d40ed1 100644 --- a/crates/gateway/src/stateful_transaction_validator_test.rs +++ b/crates/gateway/src/stateful_transaction_validator_test.rs @@ -1,11 +1,13 @@ -use blockifier::blockifier::stateful_validator::StatefulValidatorError; +use blockifier::blockifier::stateful_validator::{ + StatefulValidatorError as BlockifierStatefulValidatorError, + StatefulValidatorResult as BlockifierStatefulValidatorResult, +}; use blockifier::context::BlockContext; use blockifier::test_utils::CairoVersion; use blockifier::transaction::errors::{TransactionFeeError, TransactionPreValidationError}; use mempool_test_utils::invoke_tx_args; use mempool_test_utils::starknet_api_test_utils::{ deploy_account_tx, external_invoke_tx, invoke_tx, TEST_SENDER_ADDRESS, VALID_L1_GAS_MAX_AMOUNT, - VALID_L1_GAS_MAX_PRICE_PER_UNIT, }; use mockall::predicate::eq; use num_bigint::BigUint; @@ -19,13 +21,12 @@ use starknet_types_core::felt::Felt; use crate::compilation::GatewayCompiler; use crate::config::{GatewayCompilerConfig, StatefulTransactionValidatorConfig}; -use crate::errors::{StatefulTransactionValidatorError, StatefulTransactionValidatorResult}; +use crate::errors::GatewaySpecError; use crate::state_reader::{MockStateReaderFactory, StateReaderFactory}; use crate::state_reader_test_utils::local_test_state_reader_factory; use crate::stateful_transaction_validator::{ MockStatefulTransactionValidatorTrait, StatefulTransactionValidator, }; - #[fixture] fn block_context() -> BlockContext { BlockContext::create_for_testing() @@ -52,21 +53,20 @@ fn stateful_validator(block_context: BlockContext) -> StatefulTransactionValidat )] #[case::invalid_tx( invoke_tx(CairoVersion::Cairo1), - Err(StatefulTransactionValidatorError::StatefulValidatorError( - StatefulValidatorError::TransactionPreValidationError( + Err( + BlockifierStatefulValidatorError::TransactionPreValidationError( TransactionPreValidationError::TransactionFeeError( TransactionFeeError::L1GasBoundsExceedBalance { max_amount: VALID_L1_GAS_MAX_AMOUNT, - max_price: VALID_L1_GAS_MAX_PRICE_PER_UNIT, + max_price: mempool_test_utils::starknet_api_test_utils::VALID_L1_GAS_MAX_PRICE_PER_UNIT, balance: BigUint::ZERO, } ) - ) )) )] fn test_stateful_tx_validator( #[case] external_tx: RPCTransaction, - #[case] expected_result: StatefulTransactionValidatorResult, + #[case] expected_result: BlockifierStatefulValidatorResult, stateful_validator: StatefulTransactionValidator, ) { let optional_class_info = match &external_tx { @@ -78,18 +78,17 @@ fn test_stateful_tx_validator( _ => None, }; - let expected_result_msg = format!("{:?}", expected_result); + let expected_result_as_stateful_transaction_result = + expected_result.as_ref().map(|tx_hash| *tx_hash).map_err(|blockifier_error| { + GatewaySpecError::ValidationFailure(blockifier_error.to_string()) + }); let mut mock_validator = MockStatefulTransactionValidatorTrait::new(); - mock_validator.expect_validate().return_once(|_, _| match expected_result { - Ok(_) => Ok(()), - Err(StatefulTransactionValidatorError::StatefulValidatorError(err)) => Err(err), - _ => panic!("Expecting StatefulTransactionValidatorError::StatefulValidatorError"), - }); + mock_validator.expect_validate().return_once(|_, _| expected_result.map(|_| ())); mock_validator.expect_get_nonce().returning(|_| Ok(Nonce(Felt::ZERO))); let result = stateful_validator.run_validate(&external_tx, optional_class_info, mock_validator); - assert_eq!(format!("{:?}", result), expected_result_msg); + assert_eq!(result, expected_result_as_stateful_transaction_result); } #[test] diff --git a/crates/gateway/src/stateless_transaction_validator.rs b/crates/gateway/src/stateless_transaction_validator.rs index 70805ab5e..5cc72fb3d 100644 --- a/crates/gateway/src/stateless_transaction_validator.rs +++ b/crates/gateway/src/stateless_transaction_validator.rs @@ -5,6 +5,7 @@ use starknet_api::rpc_transaction::{ use starknet_api::state::EntryPoint; use starknet_api::transaction::Resource; use starknet_types_core::felt::Felt; +use tracing::{instrument, Level}; use crate::compiler_version::VersionId; use crate::config::StatelessTransactionValidatorConfig; @@ -20,6 +21,7 @@ pub struct StatelessTransactionValidator { } impl StatelessTransactionValidator { + #[instrument(skip(self), level = Level::INFO, err)] pub fn validate(&self, tx: &RPCTransaction) -> StatelessTransactionValidatorResult<()> { // TODO(Arni, 1/5/2024): Add a mechanism that validate the sender address is not blocked. // TODO(Arni, 1/5/2024): Validate transaction version. diff --git a/crates/gateway/src/utils.rs b/crates/gateway/src/utils.rs index 64040f64e..e5da26763 100644 --- a/crates/gateway/src/utils.rs +++ b/crates/gateway/src/utils.rs @@ -14,8 +14,9 @@ use starknet_api::transaction::{ InvokeTransaction, InvokeTransactionV3, Tip, TransactionHash, TransactionHasher, }; use starknet_mempool_types::mempool_types::ThinTransaction; +use tracing::debug; -use crate::errors::StatefulTransactionValidatorResult; +use crate::errors::{GatewaySpecError, StatefulTransactionValidatorResult}; macro_rules! implement_ref_getters { ($(($member_name:ident, $member_type:ty));* $(;)?) => { @@ -94,10 +95,19 @@ pub fn external_tx_to_account_tx( paymaster_data: tx.paymaster_data.clone(), account_deployment_data: tx.account_deployment_data.clone(), }); - let tx_hash = declare_tx.calculate_transaction_hash(chain_id, &declare_tx.version())?; + let tx_hash = declare_tx + .calculate_transaction_hash(chain_id, &declare_tx.version()) + .map_err(|e| { + debug!("Failed to calculate tx hash: {}", e); + GatewaySpecError::UnexpectedError("Internal server error".to_owned()) + })?; let class_info = optional_class_info.expect("declare transaction should contain class info"); - let declare_tx = BlockifierDeclareTransaction::new(declare_tx, tx_hash, class_info)?; + let declare_tx = BlockifierDeclareTransaction::new(declare_tx, tx_hash, class_info) + .map_err(|e| { + debug!("Failed to convert declare tx hash to blockifier tx type: {}", e); + GatewaySpecError::UnexpectedError("Internal server error".to_owned()) + })?; Ok(AccountTransaction::Declare(declare_tx)) } RPCTransaction::DeployAccount(RPCDeployAccountTransaction::V3(tx)) => { @@ -118,9 +128,17 @@ pub fn external_tx_to_account_tx( deploy_account_tx.class_hash(), &deploy_account_tx.constructor_calldata(), ContractAddress::default(), - )?; + ) + .map_err(|e| { + debug!("Failed to calculate contract address: {}", e); + GatewaySpecError::UnexpectedError("Internal server error".to_owned()) + })?; let tx_hash = deploy_account_tx - .calculate_transaction_hash(chain_id, &deploy_account_tx.version())?; + .calculate_transaction_hash(chain_id, &deploy_account_tx.version()) + .map_err(|e| { + debug!("Failed to calculate tx hash: {}", e); + GatewaySpecError::UnexpectedError("Internal server error".to_owned()) + })?; let deploy_account_tx = BlockifierDeployAccountTransaction::new( deploy_account_tx, tx_hash, @@ -141,7 +159,12 @@ pub fn external_tx_to_account_tx( paymaster_data: tx.paymaster_data.clone(), account_deployment_data: tx.account_deployment_data.clone(), }); - let tx_hash = invoke_tx.calculate_transaction_hash(chain_id, &invoke_tx.version())?; + let tx_hash = invoke_tx + .calculate_transaction_hash(chain_id, &invoke_tx.version()) + .map_err(|e| { + debug!("Failed to calculate tx hash: {}", e); + GatewaySpecError::UnexpectedError("Internal server error".to_owned()) + })?; let invoke_tx = BlockifierInvokeTransaction::new(invoke_tx, tx_hash); Ok(AccountTransaction::Invoke(invoke_tx)) } diff --git a/crates/tests-integration/src/integration_test_setup.rs b/crates/tests-integration/src/integration_test_setup.rs index 3edc8fe25..1bf0e1d40 100644 --- a/crates/tests-integration/src/integration_test_setup.rs +++ b/crates/tests-integration/src/integration_test_setup.rs @@ -5,7 +5,7 @@ use blockifier::test_utils::CairoVersion; use starknet_api::rpc_transaction::RPCTransaction; use starknet_api::transaction::TransactionHash; use starknet_gateway::config::GatewayNetworkConfig; -use starknet_gateway::errors::GatewayError; +use starknet_gateway::errors::GatewaySpecError; use starknet_mempool_infra::trace_util::configure_tracing; use starknet_mempool_node::communication::{create_node_channels, create_node_clients}; use starknet_mempool_node::components::create_components; @@ -87,7 +87,7 @@ impl IntegrationTestSetup { self.gateway_client.assert_add_tx_success(tx).await } - pub async fn assert_add_tx_error(&self, tx: &RPCTransaction) -> GatewayError { + pub async fn assert_add_tx_error(&self, tx: &RPCTransaction) -> GatewaySpecError { self.gateway_client.assert_add_tx_error(tx).await } diff --git a/crates/tests-integration/src/integration_test_utils.rs b/crates/tests-integration/src/integration_test_utils.rs index b9ebcbdb4..a1c94a7f7 100644 --- a/crates/tests-integration/src/integration_test_utils.rs +++ b/crates/tests-integration/src/integration_test_utils.rs @@ -12,7 +12,7 @@ use starknet_gateway::config::{ GatewayConfig, GatewayNetworkConfig, RpcStateReaderConfig, StatefulTransactionValidatorConfig, StatelessTransactionValidatorConfig, }; -use starknet_gateway::errors::GatewayError; +use starknet_gateway::errors::GatewaySpecError; use starknet_mempool_node::config::MempoolNodeConfig; use tokio::net::TcpListener; @@ -65,7 +65,7 @@ impl GatewayClient { } // TODO: implement when usage eventually arises. - pub async fn assert_add_tx_error(&self, _tx: &RPCTransaction) -> GatewayError { + pub async fn assert_add_tx_error(&self, _tx: &RPCTransaction) -> GatewaySpecError { todo!() }