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, Authorization, BlockNumber, BloomFilter, Data, Hash, LogArgument,
7 LogIndex, Nonce, 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 /// The authorization_list specifies a list of authorizations for the transaction
237 /// (introduced in EIP-7702)
238 pub authorization_list: Option<Vec<Authorization>>,
239 /// Max fee per data gas
240 ///
241 /// aka BlobFeeCap or blobGasFeeCap
242 pub max_fee_per_blob_gas: Option<Quantity>,
243 /// It contains a vector of fixed size hash(32 bytes)
244 pub blob_versioned_hashes: Option<Vec<Hash>>,
245 /// The total amount of gas used in the block until this transaction was executed.
246 pub cumulative_gas_used: Option<Quantity>,
247 /// The sum of the base fee and tip paid per unit of gas.
248 pub effective_gas_price: Option<Quantity>,
249 /// Gas used by transaction
250 pub gas_used: Option<Quantity>,
251 /// Address of created contract if transaction was a contract creation
252 pub contract_address: Option<Address>,
253 /// Bloom filter for logs produced by this transaction
254 pub logs_bloom: Option<BloomFilter>,
255 /// Transaction type. For ethereum: Legacy, Eip2930, Eip1559, Eip4844
256 #[serde(rename = "type")]
257 pub kind: Option<TransactionType>,
258 /// The Keccak 256-bit hash of the root node of the trie structure populated with each
259 /// transaction in the transactions list portion of the block; formally Ht.
260 pub root: Option<Hash>,
261 /// If transaction is executed successfully.
262 ///
263 /// This is the `statusCode`
264 pub status: Option<TransactionStatus>,
265 /// The fee associated with a transaction on the Layer 1,
266 /// it is calculated as l1GasPrice multiplied by l1GasUsed
267 pub l1_fee: Option<Quantity>,
268 /// The gas price for transactions on the Layer 1
269 pub l1_gas_price: Option<Quantity>,
270 /// The amount of gas consumed by a transaction on the Layer 1
271 pub l1_gas_used: Option<Quantity>,
272 /// A multiplier applied to the actual gas usage on Layer 1 to calculate the dynamic costs.
273 /// If set to 1, it has no impact on the L1 gas usage
274 pub l1_fee_scalar: Option<f64>,
275 /// Amount of gas spent on L1 calldata in units of L2 gas.
276 pub gas_used_for_l1: Option<Quantity>,
277}
278
279/// Log object
280#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
281pub struct Log {
282 /// The boolean value indicating if the event was removed from the blockchain due
283 /// to a chain reorganization. True if the log was removed. False if it is a valid log.
284 pub removed: Option<bool>,
285 /// The integer identifying the index of the event within the block's list of events.
286 pub log_index: Option<LogIndex>,
287 /// The integer index of the transaction within the block's list of transactions.
288 pub transaction_index: Option<TransactionIndex>,
289 /// The hash of the transaction that triggered the event.
290 pub transaction_hash: Option<Hash>,
291 /// The hash of the block in which the event was included.
292 pub block_hash: Option<Hash>,
293 /// The block number in which the event was included.
294 pub block_number: Option<BlockNumber>,
295 /// The contract address from which the event originated.
296 pub address: Option<Address>,
297 /// The non-indexed data that was emitted along with the event.
298 pub data: Option<Data>,
299 /// An array of 32-byte data fields containing indexed event parameters.
300 pub topics: ArrayVec<Option<LogArgument>, 4>,
301}
302
303/// Trace object
304#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
305pub struct Trace {
306 /// The address of the sender who initiated the transaction.
307 pub from: Option<Address>,
308 /// The address of the recipient of the transaction if it was a transaction to an address.
309 /// For contract creation transactions, this field is None.
310 pub to: Option<Address>,
311 /// The type of trace, `call` or `delegatecall`, two ways to invoke a function in a smart contract.
312 ///
313 /// `call` creates a new environment for the function to work in, so changes made in that
314 /// function won't affect the environment where the function was called.
315 ///
316 /// `delegatecall` doesn't create a new environment. Instead, it runs the function within the
317 /// environment of the caller, so changes made in that function will affect the caller's environment.
318 pub call_type: Option<String>,
319 /// The units of gas included in the transaction by the sender.
320 pub gas: Option<Quantity>,
321 /// The optional input data sent with the transaction, usually used to interact with smart contracts.
322 pub input: Option<Data>,
323 /// The init code.
324 pub init: Option<Data>,
325 /// The value of the native token transferred along with the transaction, in Wei.
326 pub value: Option<Quantity>,
327 /// The address of the receiver for reward transaction.
328 pub author: Option<Address>,
329 /// Kind of reward. `Block` reward or `Uncle` reward.
330 pub reward_type: Option<String>,
331 /// The hash of the block in which the transaction was included.
332 pub block_hash: Option<Hash>,
333 /// The number of the block in which the transaction was included.
334 pub block_number: Option<u64>,
335 /// Destroyed address.
336 pub address: Option<Address>,
337 /// Contract code.
338 pub code: Option<Data>,
339 /// The total used gas by the call, encoded as hexadecimal.
340 pub gas_used: Option<Quantity>,
341 /// The return value of the call, encoded as a hexadecimal string.
342 pub output: Option<Data>,
343 /// The number of sub-traces created during execution. When a transaction is executed on the EVM,
344 /// it may trigger additional sub-executions, such as when a smart contract calls another smart
345 /// contract or when an external account is accessed.
346 pub subtraces: Option<u64>,
347 /// An array that indicates the position of the transaction in the trace.
348 pub trace_address: Option<Vec<u64>>,
349 /// The hash of the transaction.
350 pub transaction_hash: Option<Hash>,
351 /// The index of the transaction in the block.
352 pub transaction_position: Option<u64>,
353 /// The type of action taken by the transaction, `call`, `create`, `reward` and `suicide`.
354 ///
355 /// `call` is the most common type of trace and occurs when a smart contract invokes another contract's function.
356 ///
357 /// `create` represents the creation of a new smart contract. This type of trace occurs when a smart contract is deployed to the blockchain.
358 #[serde(rename = "type")]
359 pub kind: Option<String>,
360 /// A string that indicates whether the transaction was successful or not.
361 ///
362 /// None if successful, Reverted if not.
363 pub error: Option<String>,
364}