axiom_query/subquery_aggregation/
types.rs

1use std::iter;
2use std::marker::PhantomData;
3
4use anyhow::anyhow;
5use axiom_codec::HiLo;
6use axiom_eth::{
7    halo2_base::AssignedValue,
8    impl_flatten_conversion,
9    utils::{
10        component::{types::LogicalEmpty, ComponentType, ComponentTypeId, LogicalResult},
11        snark_verifier::EnhancedSnark,
12    },
13};
14use serde::{Deserialize, Serialize};
15
16pub(crate) type F = axiom_eth::halo2curves::bn256::Fr;
17
18#[derive(Clone, Debug, Hash, Serialize, Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct InputSubqueryAggregation {
21    /// Header snark always required
22    pub snark_header: EnhancedSnark,
23
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub snark_account: Option<EnhancedSnark>,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub snark_storage: Option<EnhancedSnark>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub snark_solidity_mapping: Option<EnhancedSnark>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub snark_tx: Option<EnhancedSnark>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub snark_receipt: Option<EnhancedSnark>,
34
35    /// The keccak commit is provided as a public input.
36    /// The SubqueryAggregation circuit will check that all subquery component circuits use the same promise commit for keccak.
37    /// It will not check the promise commit itself. That will be done by AxiomAggregation1, which aggregates this SubqueryAggregation circuit.
38    pub promise_commit_keccak: F,
39
40    /// Results root snark always required
41    pub snark_results_root: EnhancedSnark,
42}
43
44pub struct ComponentTypeSubqueryAgg {
45    _phatnom: PhantomData<F>,
46}
47impl ComponentType<F> for ComponentTypeSubqueryAgg {
48    type InputValue = LogicalEmpty<F>;
49    type InputWitness = LogicalEmpty<AssignedValue<F>>;
50    type OutputValue = LogicalEmpty<F>;
51    type OutputWitness = LogicalEmpty<AssignedValue<F>>;
52    type LogicalInput = LogicalEmpty<F>;
53
54    fn get_type_id() -> ComponentTypeId {
55        "axiom-query:ComponentTypeSubqueryAgg".to_string()
56    }
57
58    fn logical_result_to_virtual_rows_impl(
59        _ins: &LogicalResult<F, Self>,
60    ) -> Vec<(Self::InputValue, Self::OutputValue)> {
61        unreachable!()
62    }
63    fn logical_input_to_virtual_rows_impl(_li: &Self::LogicalInput) -> Vec<Self::InputValue> {
64        unreachable!()
65    }
66}
67
68/// The public instances **without** the accumulator
69const FIELD_SIZE_PUBLIC_INSTANCES: [usize; 6] = [
70    9999, // promise_keccak
71    9999, // agg_vk_hash
72    9999, // results_root_poseidon
73    9999, // commit_subquery_hashes
74    128, 128, // mmr_keccak
75];
76pub const SUBQUERY_AGGREGATION_AGG_VKEY_HASH_IDX: usize = 1;
77
78/// Public instances **without** the accumulator (accumulator is 12 field elements)
79#[derive(Debug, Clone, PartialEq, Eq, Hash)]
80pub struct LogicalPublicInstanceSubqueryAgg<T> {
81    pub promise_keccak: T,
82    pub agg_vkey_hash: T,
83    pub results_root_poseidon: T,
84    pub commit_subquery_hashes: T,
85    pub mmr_keccak: HiLo<T>,
86}
87
88impl<T> TryFrom<Vec<T>> for LogicalPublicInstanceSubqueryAgg<T> {
89    type Error = anyhow::Error;
90    fn try_from(value: Vec<T>) -> Result<Self, Self::Error> {
91        let [promise_keccak, agg_vkey_hash, results_root_poseidon, commit_subquery_hashes, mmr_hi, mmr_lo] =
92            value
93                .try_into()
94                .map_err(|_| anyhow!("LogicalPublicInstanceSubqueryAgg invalid length"))?;
95        Ok(Self {
96            promise_keccak,
97            agg_vkey_hash,
98            results_root_poseidon,
99            commit_subquery_hashes,
100            mmr_keccak: HiLo::from_hi_lo([mmr_hi, mmr_lo]),
101        })
102    }
103}
104
105impl<T: Copy> LogicalPublicInstanceSubqueryAgg<T> {
106    pub fn flatten(&self) -> Vec<T> {
107        iter::empty()
108            .chain([self.promise_keccak, self.agg_vkey_hash])
109            .chain([self.results_root_poseidon, self.commit_subquery_hashes])
110            .chain(self.mmr_keccak.hi_lo())
111            .collect()
112    }
113}
114
115// This is not used:
116impl_flatten_conversion!(LogicalPublicInstanceSubqueryAgg, FIELD_SIZE_PUBLIC_INSTANCES);