|
1 | 1 | use borsh::BorshDeserialize; |
2 | 2 | use near_api_types::{ |
3 | 3 | AccessKey, Account, AccountView, ContractCodeView, Data, PublicKey, RpcBlockResponse, |
4 | | - RpcValidatorResponse, ViewStateResult, json::U64, |
| 4 | + RpcValidatorResponse, ViewStateResult, json::U64, transaction::result::ExecutionFinalResult, |
| 5 | +}; |
| 6 | +use near_openapi_client::types::{ |
| 7 | + FinalExecutionOutcomeView, RpcQueryResponse, RpcReceiptResponse, RpcTransactionResponse, |
5 | 8 | }; |
6 | | -use near_openapi_client::types::RpcQueryResponse; |
7 | 9 | use serde::de::DeserializeOwned; |
8 | 10 | use std::marker::PhantomData; |
9 | 11 | use tracing::{info, trace, warn}; |
10 | 12 |
|
11 | 13 | use crate::{ |
12 | 14 | advanced::{ |
13 | 15 | RpcType, block_rpc::SimpleBlockRpc, query_rpc::SimpleQueryRpc, |
14 | | - validator_rpc::SimpleValidatorRpc, |
| 16 | + tx_rpc::TransactionStatusRpc, validator_rpc::SimpleValidatorRpc, |
15 | 17 | }, |
16 | 18 | common::query::{QUERY_EXECUTOR_TARGET, ResultWithMethod}, |
17 | 19 | errors::QueryError, |
@@ -497,6 +499,93 @@ impl ResponseHandler for RpcBlockHandler { |
497 | 499 | } |
498 | 500 | } |
499 | 501 |
|
| 502 | +/// Handler that converts an [`RpcTransactionResponse`] into an [`ExecutionFinalResult`]. |
| 503 | +/// |
| 504 | +/// This reuses the same conversion logic from transaction sending: it extracts the |
| 505 | +/// `FinalExecutionOutcomeView` from the response and converts it using `TryFrom`. |
| 506 | +#[derive(Clone, Debug)] |
| 507 | +pub struct TransactionStatusHandler; |
| 508 | + |
| 509 | +impl ResponseHandler for TransactionStatusHandler { |
| 510 | + type Response = ExecutionFinalResult; |
| 511 | + type Query = TransactionStatusRpc; |
| 512 | + |
| 513 | + fn process_response( |
| 514 | + &self, |
| 515 | + response: Vec<RpcTransactionResponse>, |
| 516 | + ) -> ResultWithMethod<Self::Response, <Self::Query as RpcType>::Error> { |
| 517 | + let response = response |
| 518 | + .into_iter() |
| 519 | + .next() |
| 520 | + .ok_or(QueryError::InternalErrorNoResponse)?; |
| 521 | + |
| 522 | + let final_execution_outcome_view = match response { |
| 523 | + RpcTransactionResponse::Variant0 { |
| 524 | + final_execution_status: _, |
| 525 | + receipts: _, |
| 526 | + receipts_outcome, |
| 527 | + status, |
| 528 | + transaction, |
| 529 | + transaction_outcome, |
| 530 | + } => FinalExecutionOutcomeView { |
| 531 | + receipts_outcome, |
| 532 | + status, |
| 533 | + transaction, |
| 534 | + transaction_outcome, |
| 535 | + }, |
| 536 | + RpcTransactionResponse::Variant1 { |
| 537 | + final_execution_status: _, |
| 538 | + receipts_outcome, |
| 539 | + status, |
| 540 | + transaction, |
| 541 | + transaction_outcome, |
| 542 | + } => FinalExecutionOutcomeView { |
| 543 | + receipts_outcome, |
| 544 | + status, |
| 545 | + transaction, |
| 546 | + transaction_outcome, |
| 547 | + }, |
| 548 | + }; |
| 549 | + |
| 550 | + info!( |
| 551 | + target: QUERY_EXECUTOR_TARGET, |
| 552 | + "Processed TransactionStatus response, tx hash: {:?}", |
| 553 | + final_execution_outcome_view.transaction_outcome.id, |
| 554 | + ); |
| 555 | + |
| 556 | + ExecutionFinalResult::try_from(final_execution_outcome_view) |
| 557 | + .map_err(|e| QueryError::ConversionError(Box::new(e))) |
| 558 | + } |
| 559 | +} |
| 560 | + |
| 561 | +/// Handler that passes through the raw [`RpcReceiptResponse`] without transformation. |
| 562 | +#[derive(Clone, Debug)] |
| 563 | +pub struct ReceiptHandler; |
| 564 | + |
| 565 | +impl ResponseHandler for ReceiptHandler { |
| 566 | + type Response = RpcReceiptResponse; |
| 567 | + type Query = crate::advanced::tx_rpc::ReceiptRpc; |
| 568 | + |
| 569 | + fn process_response( |
| 570 | + &self, |
| 571 | + response: Vec<RpcReceiptResponse>, |
| 572 | + ) -> ResultWithMethod<Self::Response, <Self::Query as RpcType>::Error> { |
| 573 | + let response = response |
| 574 | + .into_iter() |
| 575 | + .next() |
| 576 | + .ok_or(QueryError::InternalErrorNoResponse)?; |
| 577 | + |
| 578 | + info!( |
| 579 | + target: QUERY_EXECUTOR_TARGET, |
| 580 | + "Processed Receipt response, receipt_id: {:?}, receiver: {:?}", |
| 581 | + response.receipt_id, |
| 582 | + response.receiver_id, |
| 583 | + ); |
| 584 | + |
| 585 | + Ok(response) |
| 586 | + } |
| 587 | +} |
| 588 | + |
500 | 589 | impl<T: RpcType> ResponseHandler for T { |
501 | 590 | type Response = <T as RpcType>::Response; |
502 | 591 | type Query = T; |
|
0 commit comments