@@ -841,6 +841,7 @@ where
841841 TransactionUpdateRequest {
842842 network_data : Some ( NetworkTransactionData :: Evm ( final_evm_data) ) ,
843843 hashes : Some ( hashes) ,
844+ status : Some ( TransactionStatus :: Submitted ) ,
844845 priced_at : Some ( Utc :: now ( ) . to_rfc3339 ( ) ) ,
845846 sent_at : Some ( Utc :: now ( ) . to_rfc3339 ( ) ) ,
846847 ..Default :: default ( )
@@ -3067,4 +3068,121 @@ mod tests {
30673068 _ => panic ! ( "Expected UnexpectedError" ) ,
30683069 }
30693070 }
3071+
3072+ /// Test resubmit_transaction successfully transitions from Sent to Submitted status
3073+ #[ tokio:: test]
3074+ async fn test_resubmit_transaction_sent_to_submitted ( ) {
3075+ let mut mock_transaction = MockTransactionRepository :: new ( ) ;
3076+ let mock_relayer = MockRelayerRepository :: new ( ) ;
3077+ let mut mock_provider = MockEvmProviderTrait :: new ( ) ;
3078+ let mut mock_signer = MockSigner :: new ( ) ;
3079+ let mock_job_producer = MockJobProducerTrait :: new ( ) ;
3080+ let mut mock_price_calculator = MockPriceCalculator :: new ( ) ;
3081+ let counter_service = MockTransactionCounterTrait :: new ( ) ;
3082+ let mock_network = MockNetworkRepository :: new ( ) ;
3083+
3084+ let relayer = create_test_relayer ( ) ;
3085+ let mut test_tx = create_test_transaction ( ) ;
3086+ test_tx. status = TransactionStatus :: Sent ;
3087+ test_tx. sent_at = Some ( Utc :: now ( ) . to_rfc3339 ( ) ) ;
3088+ let original_hash = "0xoriginal_hash" . to_string ( ) ;
3089+ test_tx. network_data = NetworkTransactionData :: Evm ( EvmTransactionData {
3090+ nonce : Some ( 42 ) ,
3091+ hash : Some ( original_hash. clone ( ) ) ,
3092+ raw : Some ( vec ! [ 1 , 2 , 3 ] ) ,
3093+ gas_price : Some ( 20000000000 ) , // 20 Gwei
3094+ ..test_tx. network_data . get_evm_transaction_data ( ) . unwrap ( )
3095+ } ) ;
3096+ test_tx. hashes = vec ! [ original_hash. clone( ) ] ;
3097+
3098+ // Price calculator returns bumped price
3099+ mock_price_calculator
3100+ . expect_calculate_bumped_gas_price ( )
3101+ . times ( 1 )
3102+ . returning ( |_, _| {
3103+ Ok ( PriceParams {
3104+ gas_price : Some ( 25000000000 ) , // 25 Gwei (25% bump)
3105+ max_fee_per_gas : None ,
3106+ max_priority_fee_per_gas : None ,
3107+ is_min_bumped : Some ( true ) ,
3108+ extra_fee : None ,
3109+ total_cost : U256 :: from ( 525000000000000u64 ) ,
3110+ } )
3111+ } ) ;
3112+
3113+ // Mock balance check
3114+ mock_provider
3115+ . expect_get_balance ( )
3116+ . returning ( |_| Box :: pin ( ready ( Ok ( U256 :: from ( 1000000000000000000u64 ) ) ) ) ) ;
3117+
3118+ // Mock signer to return new signed transaction
3119+ mock_signer. expect_sign_transaction ( ) . returning ( |_| {
3120+ Box :: pin ( ready ( Ok (
3121+ crate :: domain:: relayer:: SignTransactionResponse :: Evm (
3122+ crate :: domain:: relayer:: SignTransactionResponseEvm {
3123+ hash : "0xnew_hash" . to_string ( ) ,
3124+ signature : crate :: models:: EvmTransactionDataSignature {
3125+ r : "r" . to_string ( ) ,
3126+ s : "s" . to_string ( ) ,
3127+ v : 1 ,
3128+ sig : "0xsignature" . to_string ( ) ,
3129+ } ,
3130+ raw : vec ! [ 4 , 5 , 6 ] ,
3131+ } ,
3132+ ) ,
3133+ ) ) )
3134+ } ) ;
3135+
3136+ // Provider successfully sends the resubmitted transaction
3137+ mock_provider
3138+ . expect_send_raw_transaction ( )
3139+ . times ( 1 )
3140+ . returning ( |_| Box :: pin ( async { Ok ( "0xnew_hash" . to_string ( ) ) } ) ) ;
3141+
3142+ // Should update to Submitted status with new hash
3143+ let test_tx_clone = test_tx. clone ( ) ;
3144+ mock_transaction
3145+ . expect_partial_update ( )
3146+ . times ( 1 )
3147+ . withf ( |_, update| {
3148+ update. status == Some ( TransactionStatus :: Submitted )
3149+ && update. sent_at . is_some ( )
3150+ && update. priced_at . is_some ( )
3151+ && update. hashes . is_some ( )
3152+ } )
3153+ . returning ( move |_, update| {
3154+ let mut updated_tx = test_tx_clone. clone ( ) ;
3155+ updated_tx. status = update. status . unwrap ( ) ;
3156+ updated_tx. sent_at = update. sent_at . clone ( ) ;
3157+ updated_tx. priced_at = update. priced_at . clone ( ) ;
3158+ if let Some ( hashes) = update. hashes . clone ( ) {
3159+ updated_tx. hashes = hashes;
3160+ }
3161+ if let Some ( network_data) = update. network_data . clone ( ) {
3162+ updated_tx. network_data = network_data;
3163+ }
3164+ Ok ( updated_tx)
3165+ } ) ;
3166+
3167+ let evm_transaction = EvmRelayerTransaction {
3168+ relayer : relayer. clone ( ) ,
3169+ provider : mock_provider,
3170+ relayer_repository : Arc :: new ( mock_relayer) ,
3171+ network_repository : Arc :: new ( mock_network) ,
3172+ transaction_repository : Arc :: new ( mock_transaction) ,
3173+ transaction_counter_service : Arc :: new ( counter_service) ,
3174+ job_producer : Arc :: new ( mock_job_producer) ,
3175+ price_calculator : mock_price_calculator,
3176+ signer : mock_signer,
3177+ } ;
3178+
3179+ let result = evm_transaction. resubmit_transaction ( test_tx. clone ( ) ) . await ;
3180+ assert ! ( result. is_ok( ) , "Expected Ok, got: {:?}" , result) ;
3181+ let updated_tx = result. unwrap ( ) ;
3182+ assert_eq ! (
3183+ updated_tx. status,
3184+ TransactionStatus :: Submitted ,
3185+ "Transaction status should transition from Sent to Submitted"
3186+ ) ;
3187+ }
30703188}
0 commit comments