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}