From 528f847765a6264437695884c1e291b316abca4f Mon Sep 17 00:00:00 2001 From: Arni Hod Date: Thu, 15 Aug 2024 16:36:13 +0300 Subject: [PATCH] refactor: create executable tx in the gateway process_tx --- crates/gateway/src/gateway.rs | 21 ++++--- crates/gateway/src/gateway_test.rs | 15 ++--- crates/gateway/src/utils.rs | 99 ++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 20 deletions(-) diff --git a/crates/gateway/src/gateway.rs b/crates/gateway/src/gateway.rs index 20f0922df2..ec3732455b 100644 --- a/crates/gateway/src/gateway.rs +++ b/crates/gateway/src/gateway.rs @@ -6,7 +6,6 @@ use async_trait::async_trait; use axum::extract::State; use axum::routing::{get, post}; use axum::{Json, Router}; -use blockifier::execution::contract_class::ClassInfo; use starknet_api::rpc_transaction::RpcTransaction; use starknet_api::transaction::TransactionHash; use starknet_mempool_infra::component_runner::{ComponentStartError, ComponentStarter}; @@ -21,7 +20,7 @@ use crate::rpc_state_reader::RpcStateReaderFactory; use crate::state_reader::StateReaderFactory; use crate::stateful_transaction_validator::StatefulTransactionValidator; use crate::stateless_transaction_validator::StatelessTransactionValidator; -use crate::utils::external_tx_to_thin_tx; +use crate::utils::{external_tx_to_executable_tx, external_tx_to_thin_tx}; #[cfg(test)] #[path = "gateway_test.rs"] @@ -129,14 +128,18 @@ fn process_tx( // Perform stateless validations. stateless_tx_validator.validate(&tx)?; - // Compile Sierra to Casm. - let optional_class_info = match &tx { - RpcTransaction::Declare(declare_tx) => Some( - ClassInfo::try_from(gateway_compiler.process_declare_tx(declare_tx)?).map_err(|e| { - error!("Failed to convert Starknet API ClassInfo to Blockifier ClassInfo: {:?}", e); + let executable_tx = external_tx_to_executable_tx( + &tx, + &gateway_compiler, + &stateful_tx_validator.config.chain_info.chain_id, + )?; + let optional_class_info = match executable_tx { + starknet_api::executable_transaction::Transaction::Declare(tx) => { + Some(tx.class_info.try_into().map_err(|e| { + error!("Failed to convert class info: {}", e); GatewaySpecError::UnexpectedError { data: "Internal server error.".to_owned() } - })?, - ), + })?) + } _ => None, }; diff --git a/crates/gateway/src/gateway_test.rs b/crates/gateway/src/gateway_test.rs index 3e9c993dfa..cd3816b05a 100644 --- a/crates/gateway/src/gateway_test.rs +++ b/crates/gateway/src/gateway_test.rs @@ -21,7 +21,7 @@ use crate::gateway::{add_tx, AppState, SharedMempoolClient}; use crate::state_reader_test_utils::{local_test_state_reader_factory, TestStateReaderFactory}; use crate::stateful_transaction_validator::StatefulTransactionValidator; use crate::stateless_transaction_validator::StatelessTransactionValidator; -use crate::utils::external_tx_to_account_tx; +use crate::utils::external_tx_to_executable_tx; pub fn app_state( mempool_client: SharedMempoolClient, @@ -86,18 +86,11 @@ async fn to_bytes(res: Response) -> Bytes { } fn calculate_hash(external_tx: &RpcTransaction) -> TransactionHash { - let optional_class_info = match &external_tx { - RpcTransaction::Declare(_declare_tx) => { - panic!("Declare transactions are not supported in this test") - } - _ => None, - }; - - let account_tx = external_tx_to_account_tx( + let executable_tx = external_tx_to_executable_tx( external_tx, - optional_class_info, + &GatewayCompiler::new_cairo_lang_compiler(Default::default()), &ChainInfo::create_for_testing().chain_id, ) .unwrap(); - account_tx.tx_hash() + executable_tx.tx_hash() } diff --git a/crates/gateway/src/utils.rs b/crates/gateway/src/utils.rs index 27d3f1fabd..52a785988e 100644 --- a/crates/gateway/src/utils.rs +++ b/crates/gateway/src/utils.rs @@ -6,6 +6,12 @@ use blockifier::transaction::transactions::{ InvokeTransaction as BlockifierInvokeTransaction, }; use starknet_api::core::{calculate_contract_address, ChainId, ClassHash, ContractAddress}; +use starknet_api::executable_transaction::{ + DeclareTransaction as ExecutableDeclareTransaction, + DeployAccountTransaction as ExecutableDeployAccountTransaction, + InvokeTransaction as ExecutableInvokeTransaction, + Transaction as ExecutableTransaction, +}; use starknet_api::rpc_transaction::{ RpcDeclareTransaction, RpcDeployAccountTransaction, @@ -25,6 +31,7 @@ use starknet_api::transaction::{ use starknet_mempool_types::mempool_types::ThinTransaction; use tracing::error; +use crate::compilation::GatewayCompiler; use crate::errors::{GatewaySpecError, StatefulTransactionValidatorResult}; pub fn external_tx_to_thin_tx( @@ -40,6 +47,98 @@ pub fn external_tx_to_thin_tx( } } +pub fn external_tx_to_executable_tx( + external_tx: &RpcTransaction, + gateway_compiler: &GatewayCompiler, + chain_id: &ChainId, +) -> Result { + Ok(match external_tx { + RpcTransaction::Declare(rpc_declare_tx) => { + let class_info = gateway_compiler.process_declare_tx(rpc_declare_tx)?; + let RpcDeclareTransaction::V3(tx) = rpc_declare_tx; + let declare_tx = DeclareTransaction::V3(DeclareTransactionV3 { + class_hash: ClassHash::default(), /* FIXME(yael 15/4/24): call the starknet-api + * function once ready */ + resource_bounds: tx.resource_bounds.clone().into(), + tip: tx.tip, + signature: tx.signature.clone(), + nonce: tx.nonce, + compiled_class_hash: tx.compiled_class_hash, + sender_address: tx.sender_address, + nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: tx.fee_data_availability_mode, + 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()) + .map_err(|e| { + error!("Failed to calculate tx hash: {}", e); + GatewaySpecError::UnexpectedError { data: "Internal server error".to_owned() } + })?; + let declare_tx = ExecutableDeclareTransaction { tx: declare_tx, tx_hash, class_info }; + ExecutableTransaction::Declare(declare_tx) + } + RpcTransaction::DeployAccount(RpcDeployAccountTransaction::V3(tx)) => { + let deploy_account_tx = DeployAccountTransaction::V3(DeployAccountTransactionV3 { + resource_bounds: tx.resource_bounds.clone().into(), + tip: tx.tip, + signature: tx.signature.clone(), + nonce: tx.nonce, + class_hash: tx.class_hash, + contract_address_salt: tx.contract_address_salt, + constructor_calldata: tx.constructor_calldata.clone(), + nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: tx.fee_data_availability_mode, + paymaster_data: tx.paymaster_data.clone(), + }); + let contract_address = calculate_contract_address( + deploy_account_tx.contract_address_salt(), + deploy_account_tx.class_hash(), + &deploy_account_tx.constructor_calldata(), + ContractAddress::default(), + ) + .map_err(|e| { + error!("Failed to calculate contract address: {}", e); + GatewaySpecError::UnexpectedError { data: "Internal server error".to_owned() } + })?; + let tx_hash = deploy_account_tx + .calculate_transaction_hash(chain_id, &deploy_account_tx.version()) + .map_err(|e| { + error!("Failed to calculate tx hash: {}", e); + GatewaySpecError::UnexpectedError { data: "Internal server error".to_owned() } + })?; + ExecutableTransaction::DeployAccount(ExecutableDeployAccountTransaction { + tx: deploy_account_tx, + tx_hash, + contract_address, + }) + } + RpcTransaction::Invoke(RpcInvokeTransaction::V3(tx)) => { + let invoke_tx = InvokeTransaction::V3(InvokeTransactionV3 { + resource_bounds: tx.resource_bounds.clone().into(), + tip: tx.tip, + signature: tx.signature.clone(), + nonce: tx.nonce, + sender_address: tx.sender_address, + calldata: tx.calldata.clone(), + nonce_data_availability_mode: tx.nonce_data_availability_mode, + fee_data_availability_mode: tx.fee_data_availability_mode, + 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()) + .map_err(|e| { + error!("Failed to calculate tx hash: {}", e); + GatewaySpecError::UnexpectedError { data: "Internal server error".to_owned() } + })?; + ExecutableTransaction::Invoke(ExecutableInvokeTransaction { tx: invoke_tx, tx_hash }) + } + }) +} + +// TODO(Arni): Delete this function. pub fn external_tx_to_account_tx( external_tx: &RpcTransaction, // FIXME(yael 15/4/24): calculate class_info inside the function once compilation code is ready