alloy_network_primitives/
traits.rs1use crate::{BlockTransactions, InclusionInfo};
2use alloy_consensus::{BlockHeader, Transaction};
3use alloy_eips::BlockNumHash;
4use alloy_primitives::{Address, BlockHash, TxHash, B256};
5use alloy_serde::WithOtherFields;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct TransactionFailedError {
10 pub transaction_hash: TxHash,
12}
13
14impl core::fmt::Display for TransactionFailedError {
15 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16 write!(f, "Transaction {} failed", self.transaction_hash)
17 }
18}
19
20impl core::error::Error for TransactionFailedError {}
21
22pub trait ReceiptResponse {
24 fn contract_address(&self) -> Option<Address>;
26
27 fn status(&self) -> bool;
36
37 fn block_hash(&self) -> Option<BlockHash>;
39
40 fn block_number(&self) -> Option<u64>;
42
43 fn block_hash_num(&self) -> Option<BlockNumHash> {
47 Some(BlockNumHash::new(self.block_number()?, self.block_hash()?))
48 }
49
50 fn transaction_hash(&self) -> TxHash;
52
53 fn transaction_index(&self) -> Option<u64>;
55
56 fn gas_used(&self) -> u64;
58
59 fn effective_gas_price(&self) -> u128;
61
62 fn cost(&self) -> u128 {
64 self.gas_used() as u128 * self.effective_gas_price()
65 }
66
67 fn blob_gas_used(&self) -> Option<u64>;
69
70 fn blob_gas_price(&self) -> Option<u128>;
72
73 fn from(&self) -> Address;
75
76 fn to(&self) -> Option<Address>;
78
79 fn cumulative_gas_used(&self) -> u64;
81
82 fn state_root(&self) -> Option<B256>;
86
87 fn ensure_success(&self) -> Result<(), TransactionFailedError> {
89 if self.status() {
90 Ok(())
91 } else {
92 Err(TransactionFailedError { transaction_hash: self.transaction_hash() })
93 }
94 }
95}
96
97pub trait TransactionResponse: Transaction {
99 #[doc(alias = "transaction_hash")]
101 fn tx_hash(&self) -> TxHash;
102
103 fn block_hash(&self) -> Option<BlockHash>;
107
108 fn block_number(&self) -> Option<u64>;
112
113 fn block_hash_num(&self) -> Option<BlockNumHash> {
117 Some(BlockNumHash::new(self.block_number()?, self.block_hash()?))
118 }
119
120 fn transaction_index(&self) -> Option<u64>;
122
123 fn from(&self) -> Address;
125
126 fn gas_price(&self) -> Option<u128> {
128 if self.ty() < 2 {
129 return Some(Transaction::max_fee_per_gas(self));
130 }
131 None
132 }
133
134 fn max_fee_per_gas(&self) -> Option<u128> {
137 if self.ty() < 2 {
138 return None;
139 }
140 Some(Transaction::max_fee_per_gas(self))
141 }
142
143 fn transaction_type(&self) -> Option<u8> {
145 match self.ty() {
146 0 => None,
147 ty => Some(ty),
148 }
149 }
150
151 fn inclusion_info(&self) -> Option<InclusionInfo> {
155 Some(InclusionInfo {
156 block_hash: self.block_hash()?,
157 block_number: self.block_number()?,
158 transaction_index: self.transaction_index()?,
159 })
160 }
161}
162
163pub trait HeaderResponse: BlockHeader {
165 fn hash(&self) -> BlockHash;
167
168 fn num_hash(&self) -> BlockNumHash {
170 BlockNumHash::new(self.number(), self.hash())
171 }
172}
173
174pub trait BlockResponse {
176 type Header;
178 type Transaction: TransactionResponse;
180
181 fn header(&self) -> &Self::Header;
183
184 fn transactions(&self) -> &BlockTransactions<Self::Transaction>;
186
187 fn transactions_mut(&mut self) -> &mut BlockTransactions<Self::Transaction>;
189
190 fn other_fields(&self) -> Option<&alloy_serde::OtherFields> {
192 None
193 }
194}
195
196impl<T: TransactionResponse> TransactionResponse for WithOtherFields<T> {
197 fn tx_hash(&self) -> TxHash {
198 self.inner.tx_hash()
199 }
200
201 fn block_hash(&self) -> Option<BlockHash> {
202 self.inner.block_hash()
203 }
204
205 fn block_number(&self) -> Option<u64> {
206 self.inner.block_number()
207 }
208
209 fn transaction_index(&self) -> Option<u64> {
210 self.inner.transaction_index()
211 }
212
213 fn from(&self) -> Address {
214 self.inner.from()
215 }
216}
217
218impl<T: ReceiptResponse> ReceiptResponse for WithOtherFields<T> {
219 fn contract_address(&self) -> Option<Address> {
220 self.inner.contract_address()
221 }
222
223 fn status(&self) -> bool {
224 self.inner.status()
225 }
226
227 fn block_hash(&self) -> Option<BlockHash> {
228 self.inner.block_hash()
229 }
230
231 fn block_number(&self) -> Option<u64> {
232 self.inner.block_number()
233 }
234
235 fn transaction_hash(&self) -> TxHash {
236 self.inner.transaction_hash()
237 }
238
239 fn transaction_index(&self) -> Option<u64> {
240 self.inner.transaction_index()
241 }
242
243 fn gas_used(&self) -> u64 {
244 self.inner.gas_used()
245 }
246
247 fn effective_gas_price(&self) -> u128 {
248 self.inner.effective_gas_price()
249 }
250
251 fn blob_gas_used(&self) -> Option<u64> {
252 self.inner.blob_gas_used()
253 }
254
255 fn blob_gas_price(&self) -> Option<u128> {
256 self.inner.blob_gas_price()
257 }
258
259 fn from(&self) -> Address {
260 self.inner.from()
261 }
262
263 fn to(&self) -> Option<Address> {
264 self.inner.to()
265 }
266
267 fn cumulative_gas_used(&self) -> u64 {
268 self.inner.cumulative_gas_used()
269 }
270
271 fn state_root(&self) -> Option<B256> {
272 self.inner.state_root()
273 }
274}
275
276impl<T: BlockResponse> BlockResponse for WithOtherFields<T> {
277 type Header = T::Header;
278 type Transaction = T::Transaction;
279
280 fn header(&self) -> &Self::Header {
281 self.inner.header()
282 }
283
284 fn transactions(&self) -> &BlockTransactions<Self::Transaction> {
285 self.inner.transactions()
286 }
287
288 fn transactions_mut(&mut self) -> &mut BlockTransactions<Self::Transaction> {
289 self.inner.transactions_mut()
290 }
291
292 fn other_fields(&self) -> Option<&alloy_serde::OtherFields> {
293 Some(&self.other)
294 }
295}
296
297impl<T: HeaderResponse> HeaderResponse for WithOtherFields<T> {
298 fn hash(&self) -> BlockHash {
299 self.inner.hash()
300 }
301}