hypersync_client/
simple_types.rs

1//! Base object types for the Hypersync client.
2use std::{collections::HashMap, sync::Arc};
3
4use arrayvec::ArrayVec;
5use hypersync_format::{
6    AccessList, Address, BlockNumber, BloomFilter, Data, Hash, LogArgument, LogIndex, Nonce,
7    Quantity, TransactionIndex, TransactionStatus, TransactionType, Withdrawal,
8};
9use nohash_hasher::IntMap;
10use serde::{Deserialize, Serialize};
11use xxhash_rust::xxh3::Xxh3Builder;
12
13use crate::types::ResponseData;
14
15/// An Ethereum event object.
16#[derive(Debug, Default, Clone, PartialEq)]
17pub struct Event {
18    /// An Ethereum event transaction object.
19    pub transaction: Option<Arc<Transaction>>,
20    /// An Ethereum event block object.
21    pub block: Option<Arc<Block>>,
22    /// An Ethereum event log object.
23    pub log: Log,
24}
25
26impl From<ResponseData> for Vec<Event> {
27    fn from(data: ResponseData) -> Self {
28        let blocks = data
29            .blocks
30            .into_iter()
31            .flat_map(|blocks| {
32                blocks
33                    .into_iter()
34                    .map(|block| (block.number.unwrap(), Arc::new(block)))
35            })
36            .collect::<IntMap<u64, _>>();
37
38        let transactions = data
39            .transactions
40            .into_iter()
41            .flat_map(|txs| {
42                txs.into_iter()
43                    .map(|tx| (tx.hash.clone().unwrap(), Arc::new(tx)))
44            })
45            .collect::<HashMap<_, _, Xxh3Builder>>();
46
47        data.logs
48            .into_iter()
49            .flat_map(|logs| {
50                logs.into_iter().map(|log| {
51                    let block = blocks.get(&log.block_number.unwrap().into()).cloned();
52                    let transaction = transactions
53                        .get(log.transaction_hash.as_ref().unwrap())
54                        .cloned();
55
56                    Event {
57                        transaction,
58                        block,
59                        log,
60                    }
61                })
62            })
63            .collect()
64    }
65}
66
67/// Block object
68#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
69pub struct Block {
70    /// A scalar value equal to the number of ancestor blocks. The genesis block has a number of
71    /// zero; formally Hi.
72    pub number: Option<u64>,
73    /// The Keccak 256-bit hash of the block
74    pub hash: Option<Hash>,
75    /// The Keccak 256-bit hash of the parent
76    /// block’s header, in its entirety; formally Hp.
77    pub parent_hash: Option<Hash>,
78    /// A 64-bit value which, combined with the mixhash, proves that a sufficient amount of
79    /// computation has been carried out on this block; formally Hn.
80    pub nonce: Option<Nonce>,
81    /// The Keccak 256-bit hash of the ommers/uncles list portion of this block; formally Ho.
82    pub sha3_uncles: Option<Hash>,
83    /// The Bloom filter composed from indexable information (logger address and log topics)
84    /// contained in each log entry from the receipt of each transaction in the transactions list;
85    /// formally Hb.
86    pub logs_bloom: Option<BloomFilter>,
87    /// The Keccak 256-bit hash of the root node of the trie structure populated with each
88    /// transaction in the transactions list portion of the block; formally Ht.
89    pub transactions_root: Option<Hash>,
90    /// The Keccak 256-bit hash of the root node of the state trie, after all transactions are
91    /// executed and finalisations applied; formally Hr.
92    pub state_root: Option<Hash>,
93    /// The Keccak 256-bit hash of the root node of the trie structure populated with each
94    /// transaction in the transactions list portion of the block; formally Ht.
95    pub receipts_root: Option<Hash>,
96    /// The 160-bit address to which all fees collected from the successful mining of this block
97    /// be transferred; formally Hc.
98    pub miner: Option<Address>,
99    /// A scalar value corresponding to the difficulty level of this block. This can be calculated
100    /// from the previous block’s difficulty level and the timestamp; formally Hd.
101    pub difficulty: Option<Quantity>,
102    /// The cumulative sum of the difficulty of all blocks that have been mined in the Ethereum
103    /// network since the inception of the network.
104    /// It measures the overall security and integrity of the Ethereum network.
105    pub total_difficulty: Option<Quantity>,
106    /// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or
107    /// fewer; formally Hx.
108    pub extra_data: Option<Data>,
109    /// The size of this block in bytes as an integer value, encoded as hexadecimal.
110    pub size: Option<Quantity>,
111    /// A scalar value equal to the current limit of gas expenditure per block; formally Hl.
112    pub gas_limit: Option<Quantity>,
113    /// A scalar value equal to the total gas used in transactions in this block; formally Hg.
114    pub gas_used: Option<Quantity>,
115    /// A scalar value equal to the reasonable output of Unix’s time() at this block’s inception;
116    /// formally Hs.
117    pub timestamp: Option<Quantity>,
118    /// Ommers/uncles header.
119    pub uncles: Option<Vec<Hash>>,
120    /// A scalar representing EIP1559 base fee which can move up or down each block according
121    /// to a formula which is a function of gas used in parent block and gas target
122    /// (block gas limit divided by elasticity multiplier) of parent block.
123    /// The algorithm results in the base fee per gas increasing when blocks are
124    /// above the gas target, and decreasing when blocks are below the gas target. The base fee per
125    /// gas is burned.
126    pub base_fee_per_gas: Option<Quantity>,
127    /// The total amount of blob gas consumed by the transactions within the block, added in
128    /// EIP-4844.
129    pub blob_gas_used: Option<Quantity>,
130    /// A running total of blob gas consumed in excess of the target, prior to the block. Blocks
131    /// with above-target blob gas consumption increase this value, blocks with below-target blob
132    /// gas consumption decrease it (bounded at 0). This was added in EIP-4844.
133    pub excess_blob_gas: Option<Quantity>,
134    /// The hash of the parent beacon block's root is included in execution blocks, as proposed by
135    /// EIP-4788.
136    ///
137    /// This enables trust-minimized access to consensus state, supporting staking pools, bridges,
138    /// and more.
139    ///
140    /// The beacon roots contract handles root storage, enhancing Ethereum's functionalities.
141    pub parent_beacon_block_root: Option<Hash>,
142    /// The Keccak 256-bit hash of the withdrawals list portion of this block.
143    ///
144    /// See [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895).
145    pub withdrawals_root: Option<Hash>,
146    /// Withdrawal represents a validator withdrawal from the consensus layer.
147    pub withdrawals: Option<Vec<Withdrawal>>,
148    /// The L1 block number that would be used for block.number calls.
149    pub l1_block_number: Option<BlockNumber>,
150    /// The number of L2 to L1 messages since Nitro genesis.
151    pub send_count: Option<Quantity>,
152    /// The Merkle root of the outbox tree state.
153    pub send_root: Option<Hash>,
154    /// A 256-bit hash which, combined with the
155    /// nonce, proves that a sufficient amount of computation has been carried out on this block;
156    /// formally Hm.
157    pub mix_hash: Option<Hash>,
158}
159
160/// Transaction object
161#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
162pub struct Transaction {
163    /// The Keccak 256-bit hash of the block
164    pub block_hash: Option<Hash>,
165    /// A scalar value equal to the number of ancestor blocks. The genesis block has a number of
166    /// zero; formally Hi.
167    pub block_number: Option<BlockNumber>,
168    /// The 160-bit address of the message call’s sender
169    pub from: Option<Address>,
170    /// A scalar value equal to the maximum
171    /// amount of gas that should be used in executing
172    /// this transaction. This is paid up-front, before any
173    /// computation is done and may not be increased
174    /// later; formally Tg.
175    pub gas: Option<Quantity>,
176    /// A scalar value equal to the number of
177    /// Wei to be paid per unit of gas for all computation
178    /// costs incurred as a result of the execution of this transaction; formally Tp.
179    pub gas_price: Option<Quantity>,
180    /// A transaction hash is a keccak hash of an RLP encoded signed transaction.
181    pub hash: Option<Hash>,
182    /// Input has two uses depending if transaction is Create or Call (if `to` field is None or
183    /// Some). pub init: An unlimited size byte array specifying the
184    /// EVM-code for the account initialisation procedure CREATE,
185    /// data: An unlimited size byte array specifying the
186    /// input data of the message call, formally Td.
187    pub input: Option<Data>,
188    /// A scalar value equal to the number of transactions sent by the sender; formally Tn.
189    pub nonce: Option<Quantity>,
190    /// The 160-bit address of the message call’s recipient or, for a contract creation
191    /// transaction, ∅, used here to denote the only member of B0 ; formally Tt.
192    pub to: Option<Address>,
193    /// Index of the transaction in the block
194    pub transaction_index: Option<TransactionIndex>,
195    /// A scalar value equal to the number of Wei to
196    /// be transferred to the message call’s recipient or,
197    /// in the case of contract creation, as an endowment
198    /// to the newly created account; formally Tv.
199    pub value: Option<Quantity>,
200    /// Replay protection value based on chain_id. See EIP-155 for more info.
201    pub v: Option<Quantity>,
202    /// The R field of the signature; the point on the curve.
203    pub r: Option<Quantity>,
204    /// The S field of the signature; the point on the curve.
205    pub s: Option<Quantity>,
206    /// yParity: Signature Y parity; formally Ty
207    pub y_parity: Option<Quantity>,
208    /// Max Priority fee that transaction is paying
209    ///
210    /// As ethereum circulation is around 120mil eth as of 2022 that is around
211    /// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
212    /// 340282366920938463463374607431768211455
213    ///
214    /// This is also known as `GasTipCap`
215    pub max_priority_fee_per_gas: Option<Quantity>,
216    /// A scalar value equal to the maximum
217    /// amount of gas that should be used in executing
218    /// this transaction. This is paid up-front, before any
219    /// computation is done and may not be increased
220    /// later; formally Tg.
221    ///
222    /// As ethereum circulation is around 120mil eth as of 2022 that is around
223    /// 120000000000000000000000000 wei we are safe to use u128 as its max number is:
224    /// 340282366920938463463374607431768211455
225    ///
226    /// This is also known as `GasFeeCap`
227    pub max_fee_per_gas: Option<Quantity>,
228    /// Added as EIP-pub 155: Simple replay attack protection
229    pub chain_id: Option<Quantity>,
230    /// The accessList specifies a list of addresses and storage keys;
231    /// these addresses and storage keys are added into the `accessed_addresses`
232    /// and `accessed_storage_keys` global sets (introduced in EIP-2929).
233    /// A gas cost is charged, though at a discount relative to the cost of
234    /// accessing outside the list.
235    pub access_list: Option<Vec<AccessList>>,
236    /// Max fee per data gas
237    ///
238    /// aka BlobFeeCap or blobGasFeeCap
239    pub max_fee_per_blob_gas: Option<Quantity>,
240    /// It contains a vector of fixed size hash(32 bytes)
241    pub blob_versioned_hashes: Option<Vec<Hash>>,
242    /// The total amount of gas used in the block until this transaction was executed.
243    pub cumulative_gas_used: Option<Quantity>,
244    /// The sum of the base fee and tip paid per unit of gas.
245    pub effective_gas_price: Option<Quantity>,
246    /// Gas used by transaction
247    pub gas_used: Option<Quantity>,
248    /// Address of created contract if transaction was a contract creation
249    pub contract_address: Option<Address>,
250    /// Bloom filter for logs produced by this transaction
251    pub logs_bloom: Option<BloomFilter>,
252    /// Transaction type. For ethereum: Legacy, Eip2930, Eip1559, Eip4844
253    #[serde(rename = "type")]
254    pub kind: Option<TransactionType>,
255    /// The Keccak 256-bit hash of the root node of the trie structure populated with each
256    /// transaction in the transactions list portion of the block; formally Ht.
257    pub root: Option<Hash>,
258    /// If transaction is executed successfully.
259    ///
260    /// This is the `statusCode`
261    pub status: Option<TransactionStatus>,
262    /// The fee associated with a transaction on the Layer 1,
263    /// it is calculated as l1GasPrice multiplied by l1GasUsed
264    pub l1_fee: Option<Quantity>,
265    /// The gas price for transactions on the Layer 1
266    pub l1_gas_price: Option<Quantity>,
267    /// The amount of gas consumed by a transaction on the Layer 1
268    pub l1_gas_used: Option<Quantity>,
269    /// A multiplier applied to the actual gas usage on Layer 1 to calculate the dynamic costs.
270    /// If set to 1, it has no impact on the L1 gas usage
271    pub l1_fee_scalar: Option<f64>,
272    /// Amount of gas spent on L1 calldata in units of L2 gas.
273    pub gas_used_for_l1: Option<Quantity>,
274}
275
276/// Log object
277#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
278pub struct Log {
279    /// The boolean value indicating if the event was removed from the blockchain due
280    /// to a chain reorganization. True if the log was removed. False if it is a valid log.
281    pub removed: Option<bool>,
282    /// The integer identifying the index of the event within the block's list of events.
283    pub log_index: Option<LogIndex>,
284    /// The integer index of the transaction within the block's list of transactions.
285    pub transaction_index: Option<TransactionIndex>,
286    /// The hash of the transaction that triggered the event.
287    pub transaction_hash: Option<Hash>,
288    /// The hash of the block in which the event was included.
289    pub block_hash: Option<Hash>,
290    /// The block number in which the event was included.
291    pub block_number: Option<BlockNumber>,
292    /// The contract address from which the event originated.
293    pub address: Option<Address>,
294    /// The non-indexed data that was emitted along with the event.
295    pub data: Option<Data>,
296    /// An array of 32-byte data fields containing indexed event parameters.
297    pub topics: ArrayVec<Option<LogArgument>, 4>,
298}
299
300/// Trace object
301#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
302pub struct Trace {
303    /// The address of the sender who initiated the transaction.
304    pub from: Option<Address>,
305    /// The address of the recipient of the transaction if it was a transaction to an address.
306    /// For contract creation transactions, this field is None.
307    pub to: Option<Address>,
308    /// The type of trace, `call` or `delegatecall`, two ways to invoke a function in a smart contract.
309    ///
310    /// `call` creates a new environment for the function to work in, so changes made in that
311    /// function won't affect the environment where the function was called.
312    ///
313    /// `delegatecall` doesn't create a new environment. Instead, it runs the function within the
314    /// environment of the caller, so changes made in that function will affect the caller's environment.
315    pub call_type: Option<String>,
316    /// The units of gas included in the transaction by the sender.
317    pub gas: Option<Quantity>,
318    /// The optional input data sent with the transaction, usually used to interact with smart contracts.
319    pub input: Option<Data>,
320    /// The init code.
321    pub init: Option<Data>,
322    /// The value of the native token transferred along with the transaction, in Wei.
323    pub value: Option<Quantity>,
324    /// The address of the receiver for reward transaction.
325    pub author: Option<Address>,
326    /// Kind of reward. `Block` reward or `Uncle` reward.
327    pub reward_type: Option<String>,
328    /// The hash of the block in which the transaction was included.
329    pub block_hash: Option<Hash>,
330    /// The number of the block in which the transaction was included.
331    pub block_number: Option<u64>,
332    /// Destroyed address.
333    pub address: Option<Address>,
334    /// Contract code.
335    pub code: Option<Data>,
336    /// The total used gas by the call, encoded as hexadecimal.
337    pub gas_used: Option<Quantity>,
338    /// The return value of the call, encoded as a hexadecimal string.
339    pub output: Option<Data>,
340    /// The number of sub-traces created during execution. When a transaction is executed on the EVM,
341    /// it may trigger additional sub-executions, such as when a smart contract calls another smart
342    /// contract or when an external account is accessed.
343    pub subtraces: Option<u64>,
344    /// An array that indicates the position of the transaction in the trace.
345    pub trace_address: Option<Vec<u64>>,
346    /// The hash of the transaction.
347    pub transaction_hash: Option<Hash>,
348    /// The index of the transaction in the block.
349    pub transaction_position: Option<u64>,
350    /// The type of action taken by the transaction, `call`, `create`, `reward` and `suicide`.
351    ///
352    /// `call` is the most common type of trace and occurs when a smart contract invokes another contract's function.
353    ///
354    /// `create` represents the creation of a new smart contract. This type of trace occurs when a smart contract is deployed to the blockchain.
355    #[serde(rename = "type")]
356    pub kind: Option<String>,
357    /// A string that indicates whether the transaction was successful or not.
358    ///
359    /// None if successful, Reverted if not.
360    pub error: Option<String>,
361}