1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use cfx_executor::{
    executive::ExecutionOutcome, internal_contract::make_staking_events,
};
use cfx_types::{H256, U256};
use cfx_vm_types::Spec;
use pow_types::StakingEvent;
use primitives::Receipt;

use alloy_rpc_types_trace::geth::GethTrace;
use geth_tracer::GethTraceKey;

use super::{
    observer::exec_tracer::{ExecTrace, ExecTraceKey},
    phantom_tx::{recover_phantom, PhantomTransaction},
};

pub struct ProcessTxOutcome {
    pub receipt: Receipt,
    pub phantom_txs: Vec<PhantomTransaction>,
    pub tx_traces: Vec<ExecTrace>,
    pub tx_staking_events: Vec<StakingEvent>,
    pub tx_exec_error_msg: String,
    pub consider_repacked: bool,
    pub geth_trace: Option<GethTrace>,
}

fn tx_traces(outcome: &ExecutionOutcome) -> Vec<ExecTrace> {
    outcome
        .try_as_executed()
        .and_then(|executed| executed.ext_result.get::<ExecTraceKey>().cloned())
        .unwrap_or_default()
}

fn geth_traces(outcome: &ExecutionOutcome) -> Option<GethTrace> {
    outcome
        .try_as_executed()
        .and_then(|executed| executed.ext_result.get::<GethTraceKey>().cloned())
}

pub fn make_process_tx_outcome(
    outcome: ExecutionOutcome, accumulated_gas_used: &mut U256, tx_hash: H256,
    spec: &Spec,
) -> ProcessTxOutcome {
    let tx_traces = tx_traces(&outcome);
    let geth_trace = geth_traces(&outcome);
    let tx_exec_error_msg = outcome.error_message();
    let consider_repacked = outcome.consider_repacked();
    let receipt = outcome.make_receipt(accumulated_gas_used, spec);

    let tx_staking_events = make_staking_events(receipt.logs());

    let phantom_txs = recover_phantom(&receipt.logs(), tx_hash);

    ProcessTxOutcome {
        receipt,
        phantom_txs,
        tx_traces,
        tx_staking_events,
        tx_exec_error_msg,
        consider_repacked,
        geth_trace,
    }
}