Skip to content

Commit fd95c6d

Browse files
authored
chore: Improves EVM sent -> submitted flow (#577)
1 parent 26e66a2 commit fd95c6d

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed

src/domain/transaction/evm/evm_transaction.rs

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)