cfxcore/consensus/consensus_graph/rpc_api/
transaction_provider.rs1use cfx_types::{H256, U256};
2use primitives::{
3 receipt::Receipt, SignedTransaction, TransactionIndex, TransactionStatus,
4};
5
6use super::super::ConsensusGraph;
7
8pub struct TransactionInfo {
9 pub tx_index: TransactionIndex,
10 pub maybe_executed_extra_info: Option<MaybeExecutedTxExtraInfo>,
11}
12
13pub struct MaybeExecutedTxExtraInfo {
14 pub receipt: Receipt,
15 pub block_number: u64,
16 pub prior_gas_used: U256,
17 pub tx_exec_error_msg: Option<String>,
18}
19
20impl ConsensusGraph {
21 pub fn get_signed_tx_and_tx_info(
22 &self, hash: &H256,
23 ) -> Option<(SignedTransaction, TransactionInfo)> {
24 let tx_info = self.get_transaction_info(hash)?;
28 if let Some(executed) = &tx_info.maybe_executed_extra_info {
29 if executed.receipt.outcome_status == TransactionStatus::Skipped {
30 return None;
33 }
34 }
35 let block = self.data_man.block_by_hash(
36 &tx_info.tx_index.block_hash,
37 false, )?;
39 let transaction =
40 (*block.transactions[tx_info.tx_index.real_index]).clone();
41 Some((transaction, tx_info))
42 }
43
44 fn get_transaction_info(&self, tx_hash: &H256) -> Option<TransactionInfo> {
45 let inner = self.inner.read();
46
47 trace!("Get receipt with tx_hash {}", tx_hash);
48 let tx_index = self.data_man.transaction_index_by_hash(
49 tx_hash, false, )?;
51 let maybe_executed_extra_info = inner
53 .block_execution_results_by_hash(
54 &tx_index.block_hash,
55 false, )
57 .map(|receipt| {
58 let block_receipts = receipt.1.block_receipts;
59
60 let prior_gas_used = if tx_index.real_index == 0 {
61 U256::zero()
62 } else {
63 block_receipts.receipts[tx_index.real_index - 1]
64 .accumulated_gas_used
65 };
66 let tx_exec_error_msg = block_receipts
67 .tx_execution_error_messages[tx_index.real_index]
68 .clone();
69
70 MaybeExecutedTxExtraInfo {
71 receipt: block_receipts
72 .receipts
73 .get(tx_index.real_index)
74 .expect("Error: can't get receipt by tx_index ")
75 .clone(),
76 block_number: block_receipts.block_number,
77 prior_gas_used,
78 tx_exec_error_msg: if tx_exec_error_msg.is_empty() {
79 None
80 } else {
81 Some(tx_exec_error_msg.clone())
82 },
83 }
84 });
85
86 Some(TransactionInfo {
87 tx_index,
88 maybe_executed_extra_info,
89 })
90 }
91}