axiom_query/verify_compute/
types.rs1use std::iter;
2
3use anyhow::bail;
4use axiom_codec::{types::field_elements::FlattenedSubqueryResult, HiLo};
5use axiom_eth::{
6 halo2_base::AssignedValue,
7 halo2curves::bn256::{Fr, G1Affine},
8 impl_flatten_conversion,
9 snark_verifier_sdk::{halo2::gen_dummy_snark_from_protocol, Snark, SHPLONK},
10 utils::{
11 build_utils::dummy::DummyFrom,
12 component::{
13 circuit::{CoreBuilderOutputParams, CoreBuilderParams},
14 types::LogicalEmpty,
15 ComponentType, ComponentTypeId, LogicalResult,
16 },
17 snark_verifier::NUM_FE_ACCUMULATOR,
18 },
19};
20use getset::{CopyGetters, Getters};
21use serde::{Deserialize, Serialize};
22
23use crate::{
24 components::results::{table::SubqueryResultsTable, types::CircuitOutputResultsRoot},
25 utils::client_circuit::{metadata::AxiomV2CircuitMetadata, vkey::OnchainVerifyingKey},
26};
27
28pub struct ComponentTypeVerifyCompute;
30
31#[derive(Clone, Debug, Default, Serialize, Deserialize, Getters, CopyGetters)]
38pub struct CoreParamsVerifyCompute {
39 #[getset(get_copy = "pub")]
41 subquery_results_capacity: usize,
42 #[getset(get_copy = "pub")]
44 svk: G1Affine, #[getset(get = "pub")]
47 client_metadata: AxiomV2CircuitMetadata,
48 #[getset(get_copy = "pub")]
50 preprocessed_len: usize,
51}
52
53impl CoreParamsVerifyCompute {
54 pub fn new(
55 subquery_results_capacity: usize,
56 svk: G1Affine,
57 client_metadata: AxiomV2CircuitMetadata,
58 preprocessed_len: usize,
59 ) -> Self {
60 Self { subquery_results_capacity, svk, client_metadata, preprocessed_len }
61 }
62}
63impl CoreBuilderParams for CoreParamsVerifyCompute {
64 fn get_output_params(&self) -> CoreBuilderOutputParams {
66 CoreBuilderOutputParams::new(vec![])
67 }
68}
69
70#[derive(Clone, Debug, Serialize, Deserialize, Getters)]
77pub struct CircuitInputVerifyCompute {
78 pub source_chain_id: u64,
80 pub subquery_results: CircuitOutputResultsRoot<Fr>,
82 pub nonempty_compute_query: bool,
84 pub result_len: u16,
86 #[getset(get = "pub")]
91 pub(super) compute_snark: Snark,
92}
93
94impl CircuitInputVerifyCompute {
95 pub fn new(
97 source_chain_id: u64,
98 subquery_results: CircuitOutputResultsRoot<Fr>,
99 nonempty_compute_query: bool,
100 result_len: u16,
101 compute_snark: Snark,
102 ) -> Self {
103 Self {
104 source_chain_id,
105 subquery_results,
106 nonempty_compute_query,
107 result_len,
108 compute_snark,
109 }
110 }
111}
112
113impl DummyFrom<CoreParamsVerifyCompute> for CircuitInputVerifyCompute {
114 fn dummy_from(core_params: CoreParamsVerifyCompute) -> Self {
115 let subquery_results_capacity = core_params.subquery_results_capacity();
116 let onchain_vk = OnchainVerifyingKey {
117 circuit_metadata: core_params.client_metadata().clone(),
118 transcript_initial_state: Default::default(),
119 preprocessed: vec![G1Affine::default(); core_params.preprocessed_len()],
120 };
121 let k = 7;
123 let protocol = onchain_vk.into_plonk_protocol(k).unwrap();
124 let compute_snark = gen_dummy_snark_from_protocol::<SHPLONK>(protocol);
125 let results = SubqueryResultsTable {
126 rows: vec![FlattenedSubqueryResult::default(); subquery_results_capacity],
127 };
128 let subquery_hashes = vec![HiLo::default(); subquery_results_capacity];
129
130 let subquery_results =
131 CircuitOutputResultsRoot { results, subquery_hashes, num_subqueries: 0 };
132 Self::new(0, subquery_results, true, 0, compute_snark)
133 }
134}
135
136pub(super) const NUM_LOGICAL_INSTANCE_WITHOUT_ACC: usize = 1 + 2 + 2 + 2 + 1 + 1;
137pub(super) const NUM_LOGICAL_INSTANCE: usize =
138 NUM_FE_ACCUMULATOR + NUM_LOGICAL_INSTANCE_WITHOUT_ACC;
139const NUM_BITS_PER_FE: [usize; NUM_LOGICAL_INSTANCE] = get_num_bits_per_fe();
140const fn get_num_bits_per_fe() -> [usize; NUM_LOGICAL_INSTANCE] {
143 let mut bits_per = [9999; NUM_LOGICAL_INSTANCE];
144 bits_per[NUM_FE_ACCUMULATOR] = 64;
145 bits_per[NUM_FE_ACCUMULATOR + 1] = 128;
146 bits_per[NUM_FE_ACCUMULATOR + 2] = 128;
147 bits_per[NUM_FE_ACCUMULATOR + 3] = 128;
148 bits_per[NUM_FE_ACCUMULATOR + 4] = 128;
149 bits_per[NUM_FE_ACCUMULATOR + 5] = 128;
150 bits_per[NUM_FE_ACCUMULATOR + 6] = 128;
151 bits_per
152}
153#[derive(Debug, Clone, PartialEq, Eq)]
156pub struct LogicalPublicInstanceVerifyCompute<T> {
157 pub accumulator: Vec<T>,
158 pub source_chain_id: T,
159 pub compute_results_hash: HiLo<T>,
160 pub query_hash: HiLo<T>,
161 pub query_schema: HiLo<T>,
162 pub results_root_poseidon: T,
163 pub promise_subquery_hashes: T,
164}
165#[derive(Debug, Clone, PartialEq, Eq)]
167pub struct LogicalPisVerifyComputeWithoutAccumulator<T> {
168 pub source_chain_id: T,
169 pub compute_results_hash: HiLo<T>,
170 pub query_hash: HiLo<T>,
171 pub query_schema: HiLo<T>,
172 pub results_root_poseidon: T,
173 pub promise_subquery_hashes: T,
174}
175
176type F = Fr;
177impl ComponentType<F> for ComponentTypeVerifyCompute {
179 type InputValue = LogicalEmpty<F>;
180 type InputWitness = LogicalEmpty<AssignedValue<F>>;
181 type OutputValue = LogicalEmpty<F>;
182 type OutputWitness = LogicalEmpty<AssignedValue<F>>;
183 type LogicalInput = LogicalEmpty<F>;
184
185 fn get_type_id() -> ComponentTypeId {
186 "axiom-query:ComponentTypeVerifyCompute".to_string()
187 }
188 fn logical_result_to_virtual_rows_impl(
189 _ins: &LogicalResult<F, Self>,
190 ) -> Vec<(Self::InputValue, Self::OutputValue)> {
191 unreachable!()
192 }
193 fn logical_input_to_virtual_rows_impl(_li: &Self::LogicalInput) -> Vec<Self::InputValue> {
194 unreachable!()
195 }
196}
197
198impl<T: Copy> LogicalPublicInstanceVerifyCompute<T> {
200 pub fn flatten(self) -> Vec<T> {
201 iter::empty()
202 .chain(self.accumulator)
203 .chain(Some(self.source_chain_id))
204 .chain(self.compute_results_hash.hi_lo())
205 .chain(self.query_hash.hi_lo())
206 .chain(self.query_schema.hi_lo())
207 .chain([self.results_root_poseidon, self.promise_subquery_hashes])
208 .collect()
209 }
210}
211
212impl<T: Copy> TryFrom<Vec<T>> for LogicalPublicInstanceVerifyCompute<T> {
213 type Error = anyhow::Error;
214
215 fn try_from(mut value: Vec<T>) -> anyhow::Result<Self> {
216 if value.len() != NUM_LOGICAL_INSTANCE {
217 bail!("wrong number of logical public instances")
218 };
219 let accumulator = value.drain(..NUM_FE_ACCUMULATOR).collect();
220 let drained: LogicalPisVerifyComputeWithoutAccumulator<T> = value.try_into().unwrap();
221 Ok(Self {
222 accumulator,
223 source_chain_id: drained.source_chain_id,
224 compute_results_hash: drained.compute_results_hash,
225 query_hash: drained.query_hash,
226 query_schema: drained.query_schema,
227 results_root_poseidon: drained.results_root_poseidon,
228 promise_subquery_hashes: drained.promise_subquery_hashes,
229 })
230 }
231}
232impl<T: Copy> TryFrom<Vec<T>> for LogicalPisVerifyComputeWithoutAccumulator<T> {
233 type Error = anyhow::Error;
234
235 fn try_from(value: Vec<T>) -> anyhow::Result<Self> {
236 if value.len() != NUM_LOGICAL_INSTANCE_WITHOUT_ACC {
237 bail!("wrong number of logical public instances without accumulator")
238 };
239 let source_chain_id = value[0];
240 let compute_results_hash = HiLo::from_hi_lo([value[1], value[2]]);
241 let query_hash = HiLo::from_hi_lo([value[3], value[4]]);
242 let query_schema = HiLo::from_hi_lo([value[5], value[6]]);
243 let results_root_poseidon = value[7];
244 let promise_subquery_hashes = value[8];
245 Ok(Self {
246 source_chain_id,
247 compute_results_hash,
248 query_hash,
249 query_schema,
250 results_root_poseidon,
251 promise_subquery_hashes,
252 })
253 }
254}
255
256impl_flatten_conversion!(LogicalPublicInstanceVerifyCompute, NUM_BITS_PER_FE);