hypersync_net_types/
lib.rs

1use std::collections::BTreeSet;
2
3/// Used to skip serializing a defaulted serde field if
4/// the value matches the default value.
5fn is_default<T: Default + PartialEq>(t: &T) -> bool {
6    t == &T::default()
7}
8
9use arrayvec::ArrayVec;
10use hypersync_format::{Address, FilterWrapper, FixedSizeData, Hash, LogArgument};
11use serde::{Deserialize, Serialize};
12
13pub type Sighash = FixedSizeData<4>;
14
15#[allow(clippy::all)]
16pub mod hypersync_net_types_capnp {
17    include!(concat!(env!("OUT_DIR"), "/hypersync_net_types_capnp.rs"));
18}
19
20#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)]
21pub struct Selection<T> {
22    /// Filters where matching values should be included in the response
23    /// Default::default() means include everything
24    #[serde(default, flatten)]
25    pub include: T,
26    /// Filters where matching values should be excluded from the response
27    /// None means exclude nothing, Some(Default::default()) means exclude everything
28    #[serde(default, skip_serializing_if = "Option::is_none")]
29    pub exclude: Option<T>,
30}
31
32impl<T> From<T> for Selection<T> {
33    fn from(include: T) -> Self {
34        Self {
35            include,
36            exclude: None,
37        }
38    }
39}
40
41pub type BlockSelection = Selection<BlockFilter>;
42
43#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)]
44pub struct BlockFilter {
45    /// Hash of a block, any blocks that have one of these hashes will be returned.
46    /// Empty means match all.
47    #[serde(default, skip_serializing_if = "Vec::is_empty")]
48    pub hash: Vec<Hash>,
49    /// Miner address of a block, any blocks that have one of these miners will be returned.
50    /// Empty means match all.
51    #[serde(default, skip_serializing_if = "Vec::is_empty")]
52    pub miner: Vec<Address>,
53}
54
55pub type LogSelection = Selection<LogFilter>;
56
57#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)]
58pub struct LogFilter {
59    /// Address of the contract, any logs that has any of these addresses will be returned.
60    /// Empty means match all.
61    #[serde(default, skip_serializing_if = "Vec::is_empty")]
62    pub address: Vec<Address>,
63    #[serde(default, skip_serializing_if = "Option::is_none")]
64    pub address_filter: Option<FilterWrapper>,
65    /// Topics to match, each member of the top level array is another array, if the nth topic matches any
66    ///  topic specified in nth element of topics, the log will be returned. Empty means match all.
67    #[serde(default, skip_serializing_if = "ArrayVec::is_empty")]
68    pub topics: ArrayVec<Vec<LogArgument>, 4>,
69}
70
71pub type TransactionSelection = Selection<TransactionFilter>;
72
73#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)]
74pub struct TransactionFilter {
75    /// Address the transaction should originate from. If transaction.from matches any of these, the transaction
76    /// will be returned. Keep in mind that this has an and relationship with to filter, so each transaction should
77    /// match both of them. Empty means match all.
78    #[serde(default, skip_serializing_if = "Vec::is_empty")]
79    pub from: Vec<Address>,
80    #[serde(default, skip_serializing_if = "Option::is_none")]
81    pub from_filter: Option<FilterWrapper>,
82    /// Address the transaction should go to. If transaction.to matches any of these, the transaction will
83    /// be returned. Keep in mind that this has an and relationship with from filter, so each transaction should
84    /// match both of them. Empty means match all.
85    #[serde(default, skip_serializing_if = "Vec::is_empty")]
86    pub to: Vec<Address>,
87    #[serde(default, skip_serializing_if = "Option::is_none")]
88    pub to_filter: Option<FilterWrapper>,
89    /// If first 4 bytes of transaction input matches any of these, transaction will be returned. Empty means match all.
90    #[serde(default, skip_serializing_if = "Vec::is_empty")]
91    pub sighash: Vec<Sighash>,
92    /// If transaction.status matches this value, the transaction will be returned.
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub status: Option<u8>,
95    /// If transaction.type matches any of these values, the transaction will be returned
96    #[serde(rename = "type")]
97    #[serde(default, skip_serializing_if = "Vec::is_empty")]
98    pub kind: Vec<u8>,
99    /// If transaction.contract_address matches any of these values, the transaction will be returned.
100    #[serde(default, skip_serializing_if = "Vec::is_empty")]
101    pub contract_address: Vec<Address>,
102    /// Bloom filter to filter by transaction.contract_address field. If the bloom filter contains the hash
103    /// of transaction.contract_address then the transaction will be returned. This field doesn't utilize the server side filtering
104    /// so it should be used alongside some non-probabilistic filters if possible.
105    #[serde(default, skip_serializing_if = "Option::is_none")]
106    pub contract_address_filter: Option<FilterWrapper>,
107    /// If transaction.hash matches any of these values the transaction will be returned.
108    /// empty means match all.
109    #[serde(default, skip_serializing_if = "Vec::is_empty")]
110    pub hash: Vec<Hash>,
111
112    /// List of authorizations from eip-7702 transactions, the query will return transactions that match any of these selections
113    #[serde(default, skip_serializing_if = "Vec::is_empty")]
114    pub authorization_list: Vec<AuthorizationSelection>,
115}
116
117#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)]
118pub struct AuthorizationSelection {
119    /// List of chain ids to match in the transaction authorizationList
120    #[serde(default, skip_serializing_if = "Vec::is_empty")]
121    pub chain_id: Vec<u64>,
122    /// List of addresses to match in the transaction authorizationList
123    #[serde(default, skip_serializing_if = "Vec::is_empty")]
124    pub address: Vec<Address>,
125}
126
127pub type TraceSelection = Selection<TraceFilter>;
128
129#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)]
130pub struct TraceFilter {
131    #[serde(default, skip_serializing_if = "Vec::is_empty")]
132    pub from: Vec<Address>,
133    #[serde(default, skip_serializing_if = "Option::is_none")]
134    pub from_filter: Option<FilterWrapper>,
135    #[serde(default, skip_serializing_if = "Vec::is_empty")]
136    pub to: Vec<Address>,
137    #[serde(default, skip_serializing_if = "Option::is_none")]
138    pub to_filter: Option<FilterWrapper>,
139    #[serde(default, skip_serializing_if = "Vec::is_empty")]
140    pub address: Vec<Address>,
141    #[serde(default, skip_serializing_if = "Option::is_none")]
142    pub address_filter: Option<FilterWrapper>,
143    #[serde(default, skip_serializing_if = "Vec::is_empty")]
144    pub call_type: Vec<String>,
145    #[serde(default, skip_serializing_if = "Vec::is_empty")]
146    pub reward_type: Vec<String>,
147    #[serde(default, skip_serializing_if = "Vec::is_empty")]
148    #[serde(rename = "type")]
149    pub kind: Vec<String>,
150    #[serde(default, skip_serializing_if = "Vec::is_empty")]
151    pub sighash: Vec<Sighash>,
152}
153
154#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)]
155pub struct Query {
156    /// The block to start the query from
157    pub from_block: u64,
158    /// The block to end the query at. If not specified, the query will go until the
159    ///  end of data. Exclusive, the returned range will be [from_block..to_block).
160    ///
161    /// The query will return before it reaches this target block if it hits the time limit
162    ///  configured on the server. The user should continue their query by putting the
163    ///  next_block field in the response into from_block field of their next query. This implements
164    ///  pagination.
165    #[serde(skip_serializing_if = "Option::is_none")]
166    pub to_block: Option<u64>,
167    /// List of log selections, these have an OR relationship between them, so the query will return logs
168    /// that match any of these selections.
169    #[serde(default, skip_serializing_if = "Vec::is_empty")]
170    pub logs: Vec<LogSelection>,
171    /// List of transaction selections, the query will return transactions that match any of these selections
172    #[serde(default, skip_serializing_if = "Vec::is_empty")]
173    pub transactions: Vec<TransactionSelection>,
174    /// List of trace selections, the query will return traces that match any of these selections
175    #[serde(default, skip_serializing_if = "Vec::is_empty")]
176    pub traces: Vec<TraceSelection>,
177    /// List of block selections, the query will return blocks that match any of these selections
178    #[serde(default, skip_serializing_if = "Vec::is_empty")]
179    pub blocks: Vec<BlockSelection>,
180    /// Weather to include all blocks regardless of if they are related to a returned transaction or log. Normally
181    ///  the server will return only the blocks that are related to the transaction or logs in the response. But if this
182    ///  is set to true, the server will return data for all blocks in the requested range [from_block, to_block).
183    #[serde(default, skip_serializing_if = "is_default")]
184    pub include_all_blocks: bool,
185    /// Field selection. The user can select which fields they are interested in, requesting less fields will improve
186    ///  query execution time and reduce the payload size so the user should always use a minimal number of fields.
187    #[serde(default, skip_serializing_if = "is_default")]
188    pub field_selection: FieldSelection,
189    /// Maximum number of blocks that should be returned, the server might return more blocks than this number but
190    ///  it won't overshoot by too much.
191    #[serde(default, skip_serializing_if = "Option::is_none")]
192    pub max_num_blocks: Option<usize>,
193    /// Maximum number of transactions that should be returned, the server might return more transactions than this number but
194    ///  it won't overshoot by too much.
195    #[serde(default, skip_serializing_if = "Option::is_none")]
196    pub max_num_transactions: Option<usize>,
197    /// Maximum number of logs that should be returned, the server might return more logs than this number but
198    ///  it won't overshoot by too much.
199    #[serde(default, skip_serializing_if = "Option::is_none")]
200    pub max_num_logs: Option<usize>,
201    /// Maximum number of traces that should be returned, the server might return more traces than this number but
202    ///  it won't overshoot by too much.
203    #[serde(default, skip_serializing_if = "Option::is_none")]
204    pub max_num_traces: Option<usize>,
205    /// Selects join mode for the query,
206    /// Default: join in this order logs -> transactions -> traces -> blocks
207    /// JoinAll: join everything to everything. For example if logSelection matches log0, we get the
208    /// associated transaction of log0 and then we get associated logs of that transaction as well. Applites similarly
209    /// to blocks, traces.
210    /// JoinNothing: join nothing.
211    #[serde(default, skip_serializing_if = "is_default")]
212    pub join_mode: JoinMode,
213}
214
215#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Copy)]
216pub enum JoinMode {
217    /// Join in this order logs -> transactions -> traces -> blocks
218    Default,
219    /// Join everything to everything. For example if logSelection matches log0, we get the
220    /// associated transaction of log0 and then we get associated logs of that transaction as well. Applites similarly
221    /// to blocks, traces.
222    JoinAll,
223    /// JoinNothing: join nothing.
224    JoinNothing,
225}
226
227impl Default for JoinMode {
228    fn default() -> Self {
229        Self::Default
230    }
231}
232
233#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)]
234pub struct FieldSelection {
235    #[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
236    pub block: BTreeSet<String>,
237    #[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
238    pub transaction: BTreeSet<String>,
239    #[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
240    pub log: BTreeSet<String>,
241    #[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
242    pub trace: BTreeSet<String>,
243}
244
245#[derive(Clone, Copy, Deserialize, Serialize, Debug)]
246pub struct ArchiveHeight {
247    pub height: Option<u64>,
248}
249
250#[derive(Clone, Copy, Deserialize, Serialize, Debug)]
251pub struct ChainId {
252    pub chain_id: u64,
253}
254
255/// Guard for detecting rollbacks
256#[derive(Debug, Clone, Serialize)]
257pub struct RollbackGuard {
258    /// Block number of last block scanned in memory
259    pub block_number: u64,
260    /// Block timestamp of last block scanned in memory
261    pub timestamp: i64,
262    /// Block hash of last block scanned in memory
263    pub hash: Hash,
264    /// Block number of first block scanned in memory
265    pub first_block_number: u64,
266    /// Parent hash of first block scanned in memory
267    pub first_parent_hash: Hash,
268}