diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index fcc673c2789..6a27d70ac6b 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -942,6 +942,10 @@ impl ValidatableTransaction for AccountTransaction { actual: validate_call_info.execution.retdata, }); } + } else if validate_call_info.execution.failed { + return Err(TransactionExecutionError::ValidateCairo0Error( + validate_call_info.execution.retdata, + )); } Ok(Some(validate_call_info)) } diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index 464a35ee960..de0343fcb6e 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -64,11 +64,11 @@ use starknet_api::{ }; use starknet_types_core::felt::Felt; -use crate::check_tx_execution_error_for_invalid_scenario; use crate::context::{BlockContext, TransactionContext}; use crate::execution::call_info::CallInfo; use crate::execution::contract_class::TrackedResource; use crate::execution::entry_point::{EntryPointExecutionContext, SierraGasRevertTracker}; +use crate::execution::syscalls::hint_processor::ENTRYPOINT_NOT_FOUND_ERROR; use crate::execution::syscalls::SyscallSelector; use crate::fee::fee_utils::{ get_fee_by_gas_vector, @@ -96,6 +96,7 @@ use crate::transaction::account_transaction::{ AccountTransaction, ExecutionFlags as AccountExecutionFlags, }; +use crate::transaction::errors::TransactionExecutionError; use crate::transaction::objects::{HasRelatedFeeType, TransactionInfoCreator}; use crate::transaction::test_utils::{ all_resource_bounds, @@ -119,6 +120,7 @@ use crate::transaction::test_utils::{ use crate::transaction::transaction_types::TransactionType; use crate::transaction::transactions::ExecutableTransaction; use crate::utils::u64_from_usize; +use crate::{check_tx_execution_error_for_invalid_scenario, retdata}; #[rstest] #[case::cairo1(CairoVersion::Cairo1(RunnableCairo1::Casm))] @@ -2020,3 +2022,30 @@ fn test_call_contract_that_panics( } } } + +#[rstest] +fn test_missing_validate_entrypoint_rejects( + block_context: BlockContext, + default_all_resource_bounds: ValidResourceBounds, +) { + let chain_info = &block_context.chain_info; + let account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo0); + let test_contract = FeatureContract::TestContract(CairoVersion::Cairo0); + let mut state = test_state(chain_info, BALANCE, &[(account, 1u16), (test_contract, 1u16)]); + let test_contract_address = test_contract.get_instance_address(0_u16); + // Fund the test contract. + fund_account(chain_info, test_contract_address, BALANCE, &mut state.state); + // Send an invoke transaction with the test contract as the sender. + let tx_args = invoke_tx_args! { + sender_address: test_contract_address, + resource_bounds: default_all_resource_bounds + }; + let result = run_invoke_tx(&mut state, &block_context, tx_args); + assert!(result.is_err()); + let error = result.unwrap_err(); + assert_matches!( + error, + TransactionExecutionError::ValidateCairo0Error(ret) + if ret == retdata![Felt::from_hex(ENTRYPOINT_NOT_FOUND_ERROR).unwrap()] + ); +} diff --git a/crates/blockifier/src/transaction/errors.rs b/crates/blockifier/src/transaction/errors.rs index e166d1ad654..b97c9fbda50 100644 --- a/crates/blockifier/src/transaction/errors.rs +++ b/crates/blockifier/src/transaction/errors.rs @@ -116,6 +116,8 @@ pub enum TransactionExecutionError { storage_address: ContractAddress, selector: EntryPointSelector, }, + #[error("Cairo0 validate error with retdata: {0:?}")] + ValidateCairo0Error(Retdata), #[error( "Invalid segment structure: PC {0} was visited, but the beginning of the segment {1} was \ not."