stratus/eth/storage/permanent/rocks/types/
transaction_mined.rs

1use std::fmt::Debug;
2
3use super::block_number::BlockNumberRocksdb;
4use super::execution::ExecutionRocksdb;
5use super::hash::HashRocksdb;
6use super::index::IndexRocksdb;
7use super::log_mined::LogMinedRocksdb;
8use super::transaction_input::TransactionInputRocksdb;
9use crate::eth::executor::EvmExecutionResult;
10use crate::eth::executor::EvmInput;
11use crate::eth::primitives::EvmExecution;
12use crate::eth::primitives::EvmExecutionMetrics;
13use crate::eth::primitives::ExecutionChanges;
14use crate::eth::primitives::Index;
15use crate::eth::primitives::MinedData;
16use crate::eth::primitives::TransactionExecution;
17use crate::eth::primitives::TransactionInput;
18use crate::eth::primitives::TransactionMined;
19use crate::eth::storage::permanent::rocks::SerializeDeserializeWithContext;
20use crate::eth::storage::permanent::rocks::types::execution_result::ExecutionResultBuilder;
21use crate::ext::OptionExt;
22use crate::ext::RuintExt;
23
24#[derive(Debug, Clone, PartialEq, Eq, bincode::Encode, bincode::Decode, serde::Serialize, serde::Deserialize)]
25#[cfg_attr(test, derive(fake::Dummy))]
26pub struct TransactionMinedRocksdb {
27    pub input: TransactionInputRocksdb,
28    pub execution: ExecutionRocksdb,
29    pub logs: Vec<LogMinedRocksdb>,
30    pub transaction_index: IndexRocksdb,
31}
32
33impl From<TransactionMined> for TransactionMinedRocksdb {
34    fn from(item: TransactionMined) -> Self {
35        let execution = item.execution;
36        Self {
37            input: TransactionInputRocksdb {
38                tx_type: execution.info.tx_type.map(|inner| inner.as_u64() as u8),
39                chain_id: execution.evm_input.chain_id.map_into(),
40                hash: execution.info.hash.into(),
41                nonce: execution.evm_input.nonce.unwrap_or_default().into(),
42                signer: execution.evm_input.from.into(),
43                from: execution.evm_input.from.into(),
44                to: execution.evm_input.to.map_into(),
45                value: execution.evm_input.value.into(),
46                input: execution.evm_input.data.clone().into(),
47                gas_limit: execution.evm_input.gas_limit.into(),
48                gas_price: execution.evm_input.gas_price.into(),
49                v: execution.signature.v.as_u64(),
50                r: execution.signature.r.into_limbs(),
51                s: execution.signature.s.into_limbs(),
52            },
53            execution: ExecutionRocksdb::new(
54                execution.evm_input.block_timestamp.into(),
55                execution.result.execution.result.into(),
56                execution.result.execution.output.into(),
57                execution.result.execution.gas_used.into(),
58                execution.result.execution.deployed_contract_address.map_into(),
59            ),
60            logs: execution
61                .result
62                .execution
63                .logs
64                .into_iter()
65                .enumerate()
66                .map(|(idx, log)| (log, item.mined_data.first_log_index + Index(idx as u64)).into())
67                .collect(),
68            transaction_index: item.mined_data.index.into(),
69        }
70    }
71}
72
73impl TransactionMined {
74    pub fn from_rocks_primitives(other: TransactionMinedRocksdb, block_number: BlockNumberRocksdb, block_hash: HashRocksdb) -> Self {
75        let mined_data = MinedData {
76            first_log_index: other.logs.first().map(|log| log.index).unwrap_or_default().into(),
77            index: other.transaction_index.into(),
78            block_hash: block_hash.into(),
79        };
80
81        let logs = other.logs.into_iter().map(|log| log.into()).collect();
82
83        let (result, output) = ExecutionResultBuilder((other.execution.result, other.execution.output)).build();
84
85        let input = TransactionInput::from(other.input);
86        let evm_result = EvmExecutionResult {
87            execution: EvmExecution {
88                block_timestamp: other.execution.block_timestamp.into(),
89                result,
90                output,
91                logs,
92                gas_used: other.execution.gas.into(),
93                changes: ExecutionChanges::default(),
94                deployed_contract_address: other.execution.deployed_contract_address.map_into(),
95            },
96            metrics: EvmExecutionMetrics::default(),
97        };
98
99        let execution = TransactionExecution {
100            info: input.transaction_info,
101            signature: input.signature,
102            evm_input: EvmInput::from_eth_transaction(&input.execution_info, block_number.into(), other.execution.block_timestamp.into()),
103            result: evm_result,
104        };
105
106        Self { execution, mined_data }
107    }
108}
109
110impl SerializeDeserializeWithContext for TransactionMinedRocksdb {}