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;
38
39 fn block_hash(&self) -> Option<BlockHash>;
41
42 fn block_number(&self) -> Option<u64>;
44
45 fn block_hash_num(&self) -> Option<BlockNumHash> {
50 Some(BlockNumHash::new(self.block_number()?, self.block_hash()?))
51 }
52
53 fn transaction_hash(&self) -> TxHash;
55
56 fn transaction_index(&self) -> Option<u64>;
58
59 fn gas_used(&self) -> u64;
61
62 fn effective_gas_price(&self) -> u128;
64
65 fn cost(&self) -> u128 {
71 self.gas_used() as u128 * self.effective_gas_price()
72 }
73
74 fn blob_gas_used(&self) -> Option<u64>;
76
77 fn blob_gas_price(&self) -> Option<u128>;
79
80 fn from(&self) -> Address;
82
83 fn to(&self) -> Option<Address>;
85
86 fn cumulative_gas_used(&self) -> u64;
88
89 fn state_root(&self) -> Option<B256>;
96
97 fn ensure_success(&self) -> Result<(), TransactionFailedError> {
102 if self.status() {
103 Ok(())
104 } else {
105 Err(TransactionFailedError { transaction_hash: self.transaction_hash() })
106 }
107 }
108}
109
110pub trait TransactionResponse: Transaction {
116 #[doc(alias = "transaction_hash")]
118 fn tx_hash(&self) -> TxHash;
119
120 fn block_hash(&self) -> Option<BlockHash>;
124
125 fn block_number(&self) -> Option<u64>;
129
130 fn block_hash_num(&self) -> Option<BlockNumHash> {
135 Some(BlockNumHash::new(self.block_number()?, self.block_hash()?))
136 }
137
138 fn transaction_index(&self) -> Option<u64>;
140
141 fn from(&self) -> Address;
143
144 fn gas_price(&self) -> Option<u128> {
150 if self.ty() < 2 {
151 return Some(Transaction::max_fee_per_gas(self));
152 }
153 None
154 }
155
156 fn max_fee_per_gas(&self) -> Option<u128> {
161 if self.ty() < 2 {
162 return None;
163 }
164 Some(Transaction::max_fee_per_gas(self))
165 }
166
167 fn transaction_type(&self) -> Option<u8> {
169 match self.ty() {
170 0 => None,
171 ty => Some(ty),
172 }
173 }
174
175 fn inclusion_info(&self) -> Option<InclusionInfo> {
179 Some(InclusionInfo {
180 block_hash: self.block_hash()?,
181 block_number: self.block_number()?,
182 transaction_index: self.transaction_index()?,
183 })
184 }
185}
186
187pub trait HeaderResponse: BlockHeader {
189 fn hash(&self) -> BlockHash;
191
192 fn num_hash(&self) -> BlockNumHash {
194 BlockNumHash::new(self.number(), self.hash())
195 }
196}
197
198pub trait BlockResponse {
200 type Header;
202 type Transaction: TransactionResponse;
204
205 fn header(&self) -> &Self::Header;
207
208 fn transactions(&self) -> &BlockTransactions<Self::Transaction>;
210
211 fn transactions_mut(&mut self) -> &mut BlockTransactions<Self::Transaction>;
216
217 fn other_fields(&self) -> Option<&alloy_serde::OtherFields> {
222 None
223 }
224}
225
226impl<T: TransactionResponse> TransactionResponse for WithOtherFields<T> {
227 fn tx_hash(&self) -> TxHash {
228 self.inner.tx_hash()
229 }
230
231 fn block_hash(&self) -> Option<BlockHash> {
232 self.inner.block_hash()
233 }
234
235 fn block_number(&self) -> Option<u64> {
236 self.inner.block_number()
237 }
238
239 fn transaction_index(&self) -> Option<u64> {
240 self.inner.transaction_index()
241 }
242
243 fn from(&self) -> Address {
244 self.inner.from()
245 }
246}
247
248impl<T: ReceiptResponse> ReceiptResponse for WithOtherFields<T> {
249 fn contract_address(&self) -> Option<Address> {
250 self.inner.contract_address()
251 }
252
253 fn status(&self) -> bool {
254 self.inner.status()
255 }
256
257 fn block_hash(&self) -> Option<BlockHash> {
258 self.inner.block_hash()
259 }
260
261 fn block_number(&self) -> Option<u64> {
262 self.inner.block_number()
263 }
264
265 fn transaction_hash(&self) -> TxHash {
266 self.inner.transaction_hash()
267 }
268
269 fn transaction_index(&self) -> Option<u64> {
270 self.inner.transaction_index()
271 }
272
273 fn gas_used(&self) -> u64 {
274 self.inner.gas_used()
275 }
276
277 fn effective_gas_price(&self) -> u128 {
278 self.inner.effective_gas_price()
279 }
280
281 fn blob_gas_used(&self) -> Option<u64> {
282 self.inner.blob_gas_used()
283 }
284
285 fn blob_gas_price(&self) -> Option<u128> {
286 self.inner.blob_gas_price()
287 }
288
289 fn from(&self) -> Address {
290 self.inner.from()
291 }
292
293 fn to(&self) -> Option<Address> {
294 self.inner.to()
295 }
296
297 fn cumulative_gas_used(&self) -> u64 {
298 self.inner.cumulative_gas_used()
299 }
300
301 fn state_root(&self) -> Option<B256> {
302 self.inner.state_root()
303 }
304}
305
306impl<T: BlockResponse> BlockResponse for WithOtherFields<T> {
307 type Header = T::Header;
308 type Transaction = T::Transaction;
309
310 fn header(&self) -> &Self::Header {
311 self.inner.header()
312 }
313
314 fn transactions(&self) -> &BlockTransactions<Self::Transaction> {
315 self.inner.transactions()
316 }
317
318 fn transactions_mut(&mut self) -> &mut BlockTransactions<Self::Transaction> {
319 self.inner.transactions_mut()
320 }
321
322 fn other_fields(&self) -> Option<&alloy_serde::OtherFields> {
323 Some(&self.other)
324 }
325}
326
327impl<T: HeaderResponse> HeaderResponse for WithOtherFields<T> {
328 fn hash(&self) -> BlockHash {
329 self.inner.hash()
330 }
331}