openzeppelin_relayer/jobs/handlers/
transaction_request_handler.rs1use actix_web::web::ThinData;
6use tracing::instrument;
7
8use crate::{
9 constants::WORKER_TRANSACTION_REQUEST_RETRIES,
10 domain::{get_relayer_transaction, get_transaction_by_id, Transaction},
11 jobs::{handle_result, Job, TransactionRequest},
12 models::DefaultAppState,
13 observability::request_id::set_request_id,
14 queues::{HandlerError, WorkerContext},
15};
16
17#[instrument(
18 level = "debug",
19 skip(job, state, ctx),
20 fields(
21 request_id = ?job.request_id,
22 job_id = %job.message_id,
23 job_type = %job.job_type.to_string(),
24 attempt = %ctx.attempt,
25 tx_id = %job.data.transaction_id,
26 relayer_id = %job.data.relayer_id,
27 task_id = %ctx.task_id,
28 )
29)]
30pub async fn transaction_request_handler(
31 job: Job<TransactionRequest>,
32 state: ThinData<DefaultAppState>,
33 ctx: WorkerContext,
34) -> Result<(), HandlerError> {
35 if let Some(request_id) = job.request_id.clone() {
36 set_request_id(request_id);
37 }
38
39 tracing::debug!(
40 tx_id = %job.data.transaction_id,
41 relayer_id = %job.data.relayer_id,
42 "handling transaction request"
43 );
44
45 let result = handle_request(job.data, &state).await;
46
47 handle_result(
48 result,
49 &ctx,
50 "Transaction Request",
51 WORKER_TRANSACTION_REQUEST_RETRIES,
52 )
53}
54
55async fn handle_request(
56 request: TransactionRequest,
57 state: &ThinData<DefaultAppState>,
58) -> eyre::Result<()> {
59 let relayer_transaction = get_relayer_transaction(request.relayer_id, state).await?;
60
61 let transaction = get_transaction_by_id(request.transaction_id.clone(), state).await?;
62
63 tracing::debug!(
64 tx_id = %transaction.id,
65 relayer_id = %transaction.relayer_id,
66 status = ?transaction.status,
67 "preparing transaction"
68 );
69
70 let prepared = relayer_transaction.prepare_transaction(transaction).await?;
71
72 tracing::debug!(
73 tx_id = %prepared.id,
74 relayer_id = %prepared.relayer_id,
75 status = ?prepared.status,
76 "transaction prepared"
77 );
78
79 Ok(())
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use crate::queues::WorkerContext;
86
87 #[tokio::test]
88 async fn test_handler_result_processing() {
89 let request = TransactionRequest::new("tx123", "relayer-1");
90 let job = Job::new(crate::jobs::JobType::TransactionRequest, request);
91 let ctx = WorkerContext::new(0, "test-task".into());
92
93 assert_eq!(job.data.transaction_id, "tx123");
94 assert_eq!(job.data.relayer_id, "relayer-1");
95 assert_eq!(ctx.attempt, 0);
96 }
97}