stratus/eth/primitives/
transaction_mined.rs

1use derive_more::Deref;
2use display_json::DebugAsJson;
3
4use crate::alias::AlloyLog;
5use crate::alias::AlloyLogData;
6use crate::alias::AlloyLogPrimitive;
7use crate::alias::AlloyReceipt;
8use crate::alias::AlloyTransaction;
9use crate::eth::primitives::Hash;
10use crate::eth::primitives::Index;
11use crate::eth::primitives::TransactionExecution;
12use crate::eth::primitives::TransactionInput;
13use crate::eth::primitives::transaction_execution::_tx_to_alloy_receipt_impl;
14
15#[derive(DebugAsJson, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
16#[cfg_attr(test, derive(fake::Dummy))]
17pub struct MinedData {
18    pub index: Index,
19    pub first_log_index: Index,
20    pub block_hash: Hash,
21}
22
23#[derive(DebugAsJson, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, Deref)]
24#[cfg_attr(test, derive(fake::Dummy))]
25pub struct TransactionMined {
26    #[deref]
27    pub execution: TransactionExecution,
28    pub mined_data: MinedData,
29}
30
31impl TransactionMined {
32    pub fn create_alloy_logs(&self) -> Vec<AlloyLog> {
33        self.logs()
34            .iter()
35            .enumerate()
36            .map(|(idx, log)| AlloyLog {
37                inner: AlloyLogPrimitive {
38                    address: log.address.into(),
39                    data: AlloyLogData::new_unchecked(log.topics_non_empty().into_iter().map(Into::into).collect(), log.data.clone().into()),
40                },
41                block_hash: Some(self.mined_data.block_hash.into()),
42                block_number: Some(self.evm_input.block_number.as_u64()),
43                block_timestamp: None,
44                transaction_hash: Some(self.info.hash.into()),
45                transaction_index: Some(*self.mined_data.index),
46                log_index: Some(*self.mined_data.first_log_index + idx as u64),
47                removed: false,
48            })
49            .collect()
50    }
51
52    pub fn from_execution(execution: TransactionExecution, block_hash: Hash, tx_index: Index, first_log_index: Index) -> Self {
53        Self {
54            execution,
55            mined_data: MinedData {
56                index: tx_index,
57                first_log_index,
58                block_hash,
59            },
60        }
61    }
62}
63
64impl From<TransactionMined> for AlloyTransaction {
65    fn from(value: TransactionMined) -> Self {
66        let gas_price = value.execution.evm_input.gas_price;
67        let block_hash = value.mined_data.block_hash;
68        let block_number = value.execution.evm_input.block_number;
69        let transaction_index = value.mined_data.index;
70
71        let tx_input: TransactionInput = value.into();
72        let inner = AlloyTransaction::from(tx_input).inner;
73
74        Self {
75            inner,
76            block_hash: Some(block_hash.into()),
77            block_number: Some(block_number.as_u64()),
78            transaction_index: Some(transaction_index.into()),
79            effective_gas_price: Some(gas_price),
80        }
81    }
82}
83
84impl From<TransactionMined> for TransactionInput {
85    fn from(value: TransactionMined) -> Self {
86        value.execution.into()
87    }
88}
89
90impl From<TransactionMined> for AlloyReceipt {
91    fn from(value: TransactionMined) -> Self {
92        let alloy_logs = value.create_alloy_logs();
93        _tx_to_alloy_receipt_impl(value.execution, alloy_logs, Some(value.mined_data))
94    }
95}