stratus/eth/executor/
evm_input.rs1use alloy_rpc_types_trace::geth::GethDebugTracingOptions;
2use display_json::DebugAsJson;
3
4use crate::eth::primitives::Address;
5use crate::eth::primitives::Block;
6use crate::eth::primitives::BlockNumber;
7use crate::eth::primitives::Bytes;
8use crate::eth::primitives::CallInput;
9use crate::eth::primitives::ChainId;
10use crate::eth::primitives::ExecutionInfo;
11use crate::eth::primitives::Gas;
12use crate::eth::primitives::Hash;
13use crate::eth::primitives::Nonce;
14use crate::eth::primitives::PendingBlockHeader;
15use crate::eth::primitives::PointInTime;
16use crate::eth::primitives::UnixTime;
17use crate::eth::primitives::Wei;
18use crate::eth::storage::ReadKind;
19use crate::eth::storage::TxCount;
20use crate::ext::OptionExt;
21use crate::ext::not;
22
23#[derive(DebugAsJson, Clone, Default, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
25#[cfg_attr(test, derive(fake::Dummy))]
26pub struct EvmInput {
27 pub from: Address,
34
35 pub to: Option<Address>,
42
43 pub value: Wei,
47
48 pub data: Bytes,
55
56 pub nonce: Option<Nonce>,
62
63 pub gas_limit: Gas,
65
66 pub gas_price: u128,
68
69 pub block_number: BlockNumber,
71
72 pub block_timestamp: UnixTime,
74
75 pub point_in_time: PointInTime,
77
78 pub chain_id: Option<ChainId>,
82
83 pub kind: ReadKind,
84}
85
86impl EvmInput {
87 pub fn from_eth_transaction(input: &ExecutionInfo, block_number: BlockNumber, block_timestamp: UnixTime) -> Self {
89 Self {
90 from: input.signer,
91 to: input.to,
92 value: input.value,
93 data: input.input.clone(),
94 gas_limit: input.gas_limit,
95 gas_price: input.gas_price,
96 nonce: Some(input.nonce),
97 block_number,
98 block_timestamp,
99 point_in_time: PointInTime::Pending,
100 chain_id: input.chain_id,
101 kind: ReadKind::Transaction,
102 }
103 }
104
105 pub fn from_pending_block(input: CallInput, pending_header: PendingBlockHeader, tx_count: TxCount) -> Self {
107 Self {
108 from: input.from.unwrap_or(Address::ZERO),
109 to: input.to.map_into(),
110 value: input.value,
111 data: input.data,
112 gas_limit: Gas::MAX,
113 gas_price: 0,
114 nonce: None,
115 block_number: pending_header.number,
116 block_timestamp: *pending_header.timestamp,
117 point_in_time: PointInTime::Pending,
118 chain_id: None,
119 kind: ReadKind::Call((pending_header.number, tx_count)),
120 }
121 }
122
123 pub fn from_mined_block(input: CallInput, block: Block, point_in_time: PointInTime) -> Self {
125 Self {
126 from: input.from.unwrap_or(Address::ZERO),
127 to: input.to.map_into(),
128 value: input.value,
129 data: input.data,
130 gas_limit: Gas::MAX,
131 gas_price: 0,
132 nonce: None,
133 block_number: block.number(),
134 block_timestamp: block.header.timestamp,
135 point_in_time,
136 chain_id: None,
137 kind: ReadKind::Call((block.number(), TxCount::Full)),
138 }
139 }
140
141 pub fn is_contract_call(&self) -> bool {
145 self.to.is_some() && not(self.data.is_empty())
146 }
147}
148
149impl PartialEq<&PendingBlockHeader> for EvmInput {
150 fn eq(&self, other: &&PendingBlockHeader) -> bool {
151 self.block_number == other.number && self.block_timestamp == *other.timestamp
152 }
153}
154
155pub struct InspectorInput {
156 pub tx_hash: Hash,
157 pub opts: GethDebugTracingOptions,
158 pub trace_unsuccessful_only: bool,
159}