diff --git a/crates/papyrus_test_utils/src/lib.rs b/crates/papyrus_test_utils/src/lib.rs index d6bea4c7fb1..ec2b36851f8 100644 --- a/crates/papyrus_test_utils/src/lib.rs +++ b/crates/papyrus_test_utils/src/lib.rs @@ -87,8 +87,12 @@ use starknet_api::deprecated_contract_class::{ use starknet_api::execution_resources::{Builtin, ExecutionResources, GasAmount, GasVector}; use starknet_api::hash::{PoseidonHash, StarkHash}; use starknet_api::rpc_transaction::{ + DeployAccountTransactionV3WithAddress, EntryPointByType as RpcEntryPointByType, EntryPointByType, + InternalRpcDeclareTransactionV3, + InternalRpcTransaction, + InternalRpcTransactionWithoutTxHash, RpcDeclareTransaction, RpcDeclareTransactionV3, RpcDeployAccountTransaction, @@ -749,6 +753,32 @@ auto_impl_get_test_instance! { pub max_amount: GasAmount, pub max_price_per_unit: GasPrice, } + pub struct InternalRpcTransaction { + pub tx: InternalRpcTransactionWithoutTxHash, + pub tx_hash: TransactionHash, + } + pub enum InternalRpcTransactionWithoutTxHash { + Declare(InternalRpcDeclareTransactionV3) = 0, + Invoke(RpcInvokeTransaction) = 1, + DeployAccount(DeployAccountTransactionV3WithAddress) = 2, + } + pub struct InternalRpcDeclareTransactionV3 { + pub sender_address: ContractAddress, + pub compiled_class_hash: CompiledClassHash, + pub signature: TransactionSignature, + pub nonce: Nonce, + pub class_hash: ClassHash, + pub resource_bounds: AllResourceBounds, + pub tip: Tip, + pub paymaster_data: PaymasterData, + pub account_deployment_data: AccountDeploymentData, + pub nonce_data_availability_mode: DataAvailabilityMode, + pub fee_data_availability_mode: DataAvailabilityMode, + } + pub struct DeployAccountTransactionV3WithAddress { + pub tx: RpcDeployAccountTransaction, + pub contract_address: ContractAddress, + } pub enum RpcTransaction { Declare(RpcDeclareTransaction) = 0, DeployAccount(RpcDeployAccountTransaction) = 1, diff --git a/crates/starknet_gateway/src/gateway_test.rs b/crates/starknet_gateway/src/gateway_test.rs index b5eb65746a1..a25dfac6559 100644 --- a/crates/starknet_gateway/src/gateway_test.rs +++ b/crates/starknet_gateway/src/gateway_test.rs @@ -9,9 +9,13 @@ use papyrus_network_types::network_types::BroadcastedMessageMetadata; use papyrus_test_utils::{get_rng, GetTestInstance}; use rstest::{fixture, rstest}; use starknet_api::core::{ChainId, CompiledClassHash, ContractAddress, Nonce}; -use starknet_api::executable_transaction::{AccountTransaction, InvokeTransaction}; -use starknet_api::rpc_transaction::{RpcDeclareTransaction, RpcTransaction}; -use starknet_api::transaction::TransactionHash; +use starknet_api::rpc_transaction::{ + InternalRpcTransaction, + InternalRpcTransactionWithoutTxHash, + RpcDeclareTransaction, + RpcTransaction, +}; +use starknet_api::transaction::{InvokeTransaction, TransactionHash, TransactionVersion}; use starknet_class_manager_types::transaction_converter::TransactionConverter; use starknet_class_manager_types::{EmptyClassManagerClient, SharedClassManagerClient}; use starknet_gateway_types::errors::GatewaySpecError; @@ -119,18 +123,28 @@ async fn test_add_tx( #[case] expected_result: Result<(), MempoolClientError>, #[case] expected_error: Option, ) { + use starknet_api::transaction::TransactionHasher; + let (rpc_tx, address) = create_tx(); let rpc_invoke_tx = assert_matches!(rpc_tx.clone(), RpcTransaction::Invoke(rpc_invoke_tx) => rpc_invoke_tx); - let executable_tx = AccountTransaction::Invoke( - InvokeTransaction::from_rpc_tx(rpc_invoke_tx, &ChainId::create_for_testing()).unwrap(), - ); - let tx_hash = executable_tx.tx_hash(); + let InvokeTransaction::V3(invoke_tx): InvokeTransaction = rpc_invoke_tx.clone().into() else { + panic!("Unexpected transaction version") + }; + + let tx_hash = invoke_tx + .calculate_transaction_hash(&ChainId::create_for_testing(), &TransactionVersion::THREE) + .unwrap(); + + let internal_invoke_tx = InternalRpcTransaction { + tx: InternalRpcTransactionWithoutTxHash::Invoke(rpc_invoke_tx.clone()), + tx_hash, + }; let p2p_message_metadata = Some(BroadcastedMessageMetadata::get_test_instance(&mut get_rng())); let add_tx_args = AddTransactionArgs { - tx: executable_tx, + tx: internal_invoke_tx, account_state: AccountState { address, nonce: *rpc_tx.nonce() }, }; mock_dependencies.expect_add_tx( diff --git a/crates/starknet_mempool/src/communication.rs b/crates/starknet_mempool/src/communication.rs index 3b2cca41e85..d66ac604136 100644 --- a/crates/starknet_mempool/src/communication.rs +++ b/crates/starknet_mempool/src/communication.rs @@ -1,12 +1,7 @@ use async_trait::async_trait; use papyrus_network_types::network_types::BroadcastedMessageMetadata; use starknet_api::core::ContractAddress; -use starknet_api::executable_transaction::AccountTransaction; -use starknet_api::rpc_transaction::{ - RpcDeployAccountTransaction, - RpcInvokeTransaction, - RpcTransaction, -}; +use starknet_api::rpc_transaction::InternalRpcTransaction; use starknet_mempool_p2p_types::communication::SharedMempoolP2pPropagatorClient; use starknet_mempool_types::communication::{ AddTransactionArgsWrapper, @@ -47,33 +42,20 @@ impl MempoolCommunicationWrapper { async fn send_tx_to_p2p( &self, message_metadata: Option, - tx: AccountTransaction, + tx: InternalRpcTransaction, ) -> MempoolResult<()> { match message_metadata { Some(message_metadata) => self .mempool_p2p_propagator_client .continue_propagation(message_metadata) .await - .map_err(|_| MempoolError::P2pPropagatorClientError { tx_hash: tx.tx_hash() }), + .map_err(|_| MempoolError::P2pPropagatorClientError { tx_hash: tx.tx_hash }), None => { - let tx_hash = tx.tx_hash(); - match tx { - AccountTransaction::Invoke(invoke_tx) => self - .mempool_p2p_propagator_client - .add_transaction(RpcTransaction::Invoke(RpcInvokeTransaction::V3( - invoke_tx.into(), - ))) - .await - .map_err(|_| MempoolError::P2pPropagatorClientError { tx_hash })?, - AccountTransaction::DeployAccount(deploy_account_tx) => self - .mempool_p2p_propagator_client - .add_transaction(RpcTransaction::DeployAccount( - RpcDeployAccountTransaction::V3(deploy_account_tx.into()), - )) - .await - .map_err(|_| MempoolError::P2pPropagatorClientError { tx_hash })?, - AccountTransaction::Declare(_) => {} - } + let tx_hash = tx.tx_hash; + self.mempool_p2p_propagator_client + .add_transaction(tx) + .await + .map_err(|_| MempoolError::P2pPropagatorClientError { tx_hash })?; Ok(()) } } @@ -85,18 +67,14 @@ impl MempoolCommunicationWrapper { ) -> MempoolResult<()> { self.mempool.add_tx(args_wrapper.args.clone())?; // TODO(AlonH): Verify that only transactions that were added to the mempool are sent. - // TODO(AlonH): handle declare correctly and remove this match. - match args_wrapper.args.tx { - AccountTransaction::Declare(_) => Ok(()), - _ => self.send_tx_to_p2p(args_wrapper.p2p_message_metadata, args_wrapper.args.tx).await, - } + self.send_tx_to_p2p(args_wrapper.p2p_message_metadata, args_wrapper.args.tx).await } fn commit_block(&mut self, args: CommitBlockArgs) -> MempoolResult<()> { self.mempool.commit_block(args) } - fn get_txs(&mut self, n_txs: usize) -> MempoolResult> { + fn get_txs(&mut self, n_txs: usize) -> MempoolResult> { self.mempool.get_txs(n_txs) } diff --git a/crates/starknet_mempool/src/test_utils.rs b/crates/starknet_mempool/src/test_utils.rs index 221c198ed22..89e2f945a2c 100644 --- a/crates/starknet_mempool/src/test_utils.rs +++ b/crates/starknet_mempool/src/test_utils.rs @@ -1,7 +1,7 @@ use std::collections::{HashMap, HashSet}; use pretty_assertions::assert_eq; -use starknet_api::executable_transaction::AccountTransaction; +use starknet_api::rpc_transaction::InternalRpcTransaction; use starknet_api::{contract_address, nonce, tx_hash}; use starknet_mempool_types::errors::MempoolError; use starknet_mempool_types::mempool_types::{AddTransactionArgs, CommitBlockArgs}; @@ -21,7 +21,7 @@ macro_rules! tx { ) => {{ use starknet_api::block::GasPrice; use starknet_api::{invoke_tx_args, tx_hash}; - use starknet_api::test_utils::invoke::executable_invoke_tx; + use starknet_api::test_utils::invoke::internal_invoke_tx; use starknet_api::transaction::fields::{ AllResourceBounds, ResourceBounds, @@ -37,7 +37,7 @@ macro_rules! tx { ..Default::default() }); - executable_invoke_tx(invoke_tx_args!{ + internal_invoke_tx(invoke_tx_args!{ tx_hash: tx_hash!($tx_hash), sender_address: contract_address!($address), nonce: nonce!($tx_nonce), @@ -256,7 +256,7 @@ pub fn commit_block( pub fn get_txs_and_assert_expected( mempool: &mut Mempool, n_txs: usize, - expected_txs: &[AccountTransaction], + expected_txs: &[InternalRpcTransaction], ) { let txs = mempool.get_txs(n_txs).unwrap(); assert_eq!(txs, expected_txs); diff --git a/crates/starknet_mempool_p2p/src/propagator/mod.rs b/crates/starknet_mempool_p2p/src/propagator/mod.rs index a8269ea57f0..9d05c5cdf1c 100644 --- a/crates/starknet_mempool_p2p/src/propagator/mod.rs +++ b/crates/starknet_mempool_p2p/src/propagator/mod.rs @@ -4,7 +4,10 @@ mod test; use async_trait::async_trait; use papyrus_network::network_manager::{BroadcastTopicClient, BroadcastTopicClientTrait}; use papyrus_protobuf::mempool::RpcTransactionWrapper; -use starknet_class_manager_types::transaction_converter::TransactionConverter; +use starknet_class_manager_types::transaction_converter::{ + TransactionConverter, + TransactionConverterTrait, +}; use starknet_mempool_p2p_types::communication::{ MempoolP2pPropagatorRequest, MempoolP2pPropagatorResponse, @@ -16,7 +19,7 @@ use tracing::warn; pub struct MempoolP2pPropagator { broadcast_topic_client: BroadcastTopicClient, - _transaction_converter: TransactionConverter, + transaction_converter: TransactionConverter, } impl MempoolP2pPropagator { @@ -24,7 +27,7 @@ impl MempoolP2pPropagator { broadcast_topic_client: BroadcastTopicClient, transaction_converter: TransactionConverter, ) -> Self { - Self { broadcast_topic_client, _transaction_converter: transaction_converter } + Self { broadcast_topic_client, transaction_converter } } } @@ -38,6 +41,19 @@ impl ComponentRequestHandler MempoolP2pPropagatorResponse { match request { MempoolP2pPropagatorRequest::AddTransaction(transaction) => { + let transaction = match self + .transaction_converter + .convert_internal_rpc_tx_to_rpc_tx(transaction) + .await + { + Ok(transaction) => transaction, + Err(err) => { + return MempoolP2pPropagatorResponse::AddTransaction(Err( + MempoolP2pPropagatorError::TransactionConversionError(err.to_string()), + )); + } + }; + let result = self .broadcast_topic_client .broadcast_message(RpcTransactionWrapper(transaction)) diff --git a/crates/starknet_mempool_p2p/src/propagator/test.rs b/crates/starknet_mempool_p2p/src/propagator/test.rs index 6d61ce707e3..8360b6bf697 100644 --- a/crates/starknet_mempool_p2p/src/propagator/test.rs +++ b/crates/starknet_mempool_p2p/src/propagator/test.rs @@ -11,8 +11,11 @@ use papyrus_network_types::network_types::BroadcastedMessageMetadata; use papyrus_protobuf::mempool::RpcTransactionWrapper; use papyrus_test_utils::{get_rng, GetTestInstance}; use starknet_api::core::ChainId; -use starknet_api::rpc_transaction::RpcTransaction; -use starknet_class_manager_types::transaction_converter::TransactionConverter; +use starknet_api::rpc_transaction::InternalRpcTransaction; +use starknet_class_manager_types::transaction_converter::{ + TransactionConverter, + TransactionConverterTrait, +}; use starknet_class_manager_types::EmptyClassManagerClient; use starknet_mempool_p2p_types::communication::MempoolP2pPropagatorRequest; use starknet_sequencer_infra::component_definitions::ComponentRequestHandler; @@ -29,14 +32,16 @@ async fn process_handle_add_tx() { let BroadcastTopicChannels { broadcasted_messages_receiver: _, broadcast_topic_client } = subscriber_channels; let BroadcastNetworkMock { mut messages_to_broadcast_receiver, .. } = mock_network; - let rpc_transaction = RpcTransaction::get_test_instance(&mut get_rng()); + let internal_tx = InternalRpcTransaction::get_test_instance(&mut get_rng()); // TODO(noamsp): use MockTransactionConverterTrait let transaction_converter = TransactionConverter::new(Arc::new(EmptyClassManagerClient), ChainId::create_for_testing()); + let rpc_transaction = + transaction_converter.convert_internal_rpc_tx_to_rpc_tx(internal_tx.clone()).await.unwrap(); let mut mempool_p2p_propagator = MempoolP2pPropagator::new(broadcast_topic_client, transaction_converter); mempool_p2p_propagator - .handle_request(MempoolP2pPropagatorRequest::AddTransaction(rpc_transaction.clone())) + .handle_request(MempoolP2pPropagatorRequest::AddTransaction(internal_tx)) .await; let message = timeout(TIMEOUT, messages_to_broadcast_receiver.next()).await.unwrap().unwrap(); assert_eq!(message, RpcTransactionWrapper(rpc_transaction)); diff --git a/crates/starknet_mempool_p2p_types/src/errors.rs b/crates/starknet_mempool_p2p_types/src/errors.rs index 3037dd1ced2..6204f6beb7c 100644 --- a/crates/starknet_mempool_p2p_types/src/errors.rs +++ b/crates/starknet_mempool_p2p_types/src/errors.rs @@ -5,4 +5,6 @@ use thiserror::Error; pub enum MempoolP2pPropagatorError { #[error("Sender request error")] NetworkSendError, + #[error("Transaction conversion error: {0}")] + TransactionConversionError(String), }