axiom_circuit/subquery/
types.rs

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}