1use axiom_codec::{
2 constants::MAX_SOLIDITY_MAPPING_KEYS,
3 types::{
4 field_elements::FieldSubqueryResult,
5 native::{
6 AccountSubquery, AnySubquery, HeaderSubquery, ReceiptSubquery,
7 SolidityNestedMappingSubquery, StorageSubquery, TxSubquery,
8 },
9 },
10 utils::native::{decode_field_to_addr, decode_hilo_to_h256},
11 HiLo,
12};
13use axiom_query::axiom_eth::{halo2_base::AssignedValue, Field};
14use ethers::types::{BigEndianHash, H256};
15use serde::{Serialize, Serializer};
16
17#[derive(Clone, Copy)]
18pub struct AssignedHeaderSubquery<F: Field> {
19 pub block_number: AssignedValue<F>,
20 pub field_idx: AssignedValue<F>,
21}
22
23impl<F: Field> From<AssignedHeaderSubquery<F>> for HeaderSubquery {
24 fn from(subquery: AssignedHeaderSubquery<F>) -> Self {
25 Self {
26 block_number: subquery.block_number.value().get_lower_32(),
27 field_idx: subquery.field_idx.value().get_lower_32(),
28 }
29 }
30}
31
32#[derive(Clone, Copy)]
33pub struct AssignedAccountSubquery<F: Field> {
34 pub block_number: AssignedValue<F>,
35 pub addr: AssignedValue<F>,
36 pub field_idx: AssignedValue<F>,
37}
38
39impl<F: Field> From<AssignedAccountSubquery<F>> for AccountSubquery {
40 fn from(subquery: AssignedAccountSubquery<F>) -> Self {
41 Self {
42 block_number: subquery.block_number.value().get_lower_32(),
43 field_idx: subquery.field_idx.value().get_lower_32(),
44 addr: decode_field_to_addr(subquery.addr.value()),
45 }
46 }
47}
48
49#[derive(Clone, Copy)]
50pub struct AssignedStorageSubquery<F: Field> {
51 pub block_number: AssignedValue<F>,
52 pub addr: AssignedValue<F>,
53 pub slot: HiLo<AssignedValue<F>>,
54}
55
56impl<F: Field> From<AssignedStorageSubquery<F>> for StorageSubquery {
57 fn from(subquery: AssignedStorageSubquery<F>) -> Self {
58 let hi = subquery.slot.hi();
59 let lo = subquery.slot.lo();
60 let hilo = HiLo::from_hi_lo([*hi.value(), *lo.value()]);
61 let slot = decode_hilo_to_h256(hilo);
62 Self {
63 block_number: subquery.block_number.value().get_lower_32(),
64 addr: decode_field_to_addr(subquery.addr.value()),
65 slot: slot.into_uint(),
66 }
67 }
68}
69
70#[derive(Clone, Copy)]
71pub struct AssignedTxSubquery<F: Field> {
72 pub block_number: AssignedValue<F>,
73 pub tx_idx: AssignedValue<F>,
74 pub field_or_calldata_idx: AssignedValue<F>,
75}
76
77impl<F: Field> From<AssignedTxSubquery<F>> for TxSubquery {
78 fn from(subquery: AssignedTxSubquery<F>) -> Self {
79 Self {
80 block_number: subquery.block_number.value().get_lower_32(),
81 tx_idx: subquery.tx_idx.value().get_lower_32() as u16,
82 field_or_calldata_idx: subquery.field_or_calldata_idx.value().get_lower_32(),
83 }
84 }
85}
86
87#[derive(Clone, Copy)]
88pub struct AssignedReceiptSubquery<F: Field> {
89 pub block_number: AssignedValue<F>,
90 pub tx_idx: AssignedValue<F>,
91 pub field_or_log_idx: AssignedValue<F>,
92 pub topic_or_data_or_address_idx: AssignedValue<F>,
93 pub event_schema: HiLo<AssignedValue<F>>,
94}
95
96impl<F: Field> From<AssignedReceiptSubquery<F>> for ReceiptSubquery {
97 fn from(subquery: AssignedReceiptSubquery<F>) -> Self {
98 let hi = subquery.event_schema.hi();
99 let lo = subquery.event_schema.lo();
100 let hilo = HiLo::from_hi_lo([*hi.value(), *lo.value()]);
101 let event_schema = decode_hilo_to_h256(hilo);
102 Self {
103 block_number: subquery.block_number.value().get_lower_32(),
104 tx_idx: subquery.tx_idx.value().get_lower_32() as u16,
105 field_or_log_idx: subquery.field_or_log_idx.value().get_lower_32(),
106 topic_or_data_or_address_idx: subquery
107 .topic_or_data_or_address_idx
108 .value()
109 .get_lower_32(),
110 event_schema,
111 }
112 }
113}
114
115#[derive(Clone, Copy)]
116pub struct AssignedSolidityNestedMappingSubquery<F: Field> {
117 pub block_number: AssignedValue<F>,
118 pub addr: AssignedValue<F>,
119 pub mapping_slot: HiLo<AssignedValue<F>>,
120 pub mapping_depth: AssignedValue<F>,
121 pub keys: [HiLo<AssignedValue<F>>; MAX_SOLIDITY_MAPPING_KEYS],
122}
123
124impl<F: Field> From<AssignedSolidityNestedMappingSubquery<F>> for SolidityNestedMappingSubquery {
125 fn from(subquery: AssignedSolidityNestedMappingSubquery<F>) -> Self {
126 let hi = subquery.mapping_slot.hi();
127 let lo = subquery.mapping_slot.lo();
128 let hilo = HiLo::from_hi_lo([*hi.value(), *lo.value()]);
129 let mapping_slot = decode_hilo_to_h256(hilo);
130 let keys = subquery
131 .keys
132 .iter()
133 .map(|key| {
134 let hilo = HiLo::from_hi_lo([*key.hi().value(), *key.lo().value()]);
135 decode_hilo_to_h256(hilo)
136 })
137 .collect();
138 Self {
139 block_number: subquery.block_number.value().get_lower_32(),
140 addr: decode_field_to_addr(subquery.addr.value()),
141 mapping_slot: mapping_slot.into_uint(),
142 mapping_depth: subquery.mapping_depth.value().get_lower_32() as u8,
143 keys,
144 }
145 }
146}
147
148#[derive(Debug, Clone)]
149pub(crate) struct RawSubquery(pub(crate) AnySubquery);
150
151impl Serialize for RawSubquery {
152 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
153 where
154 S: Serializer,
155 {
156 match self.0 {
157 AnySubquery::Null => serializer.serialize_unit_variant("AnySubquery", 0, "Null"),
158 AnySubquery::Header(ref inner) => inner.serialize(serializer),
159 AnySubquery::Account(ref inner) => inner.serialize(serializer),
160 AnySubquery::Storage(ref inner) => inner.serialize(serializer),
161 AnySubquery::Transaction(ref inner) => inner.serialize(serializer),
162 AnySubquery::Receipt(ref inner) => inner.serialize(serializer),
163 AnySubquery::SolidityNestedMapping(ref inner) => inner.serialize(serializer),
164 }
165 }
166}
167
168#[derive(Debug, Serialize, Clone)]
169pub struct Subquery {
170 #[serde(rename = "subqueryData")]
171 pub(crate) subquery_data: RawSubquery,
172 #[serde(rename = "type")]
173 pub(crate) subquery_type: u64,
174 pub(crate) val: H256,
175}
176
177impl From<Subquery> for AnySubquery {
178 fn from(subquery: Subquery) -> Self {
179 subquery.subquery_data.0
180 }
181}
182
183impl<F: Field> From<Subquery> for FieldSubqueryResult<F> {
184 fn from(value: Subquery) -> Self {
185 FieldSubqueryResult {
186 subquery: value.subquery_data.0.into(),
187 value: value.val.into(),
188 }
189 }
190}