use std::iter;
use std::marker::PhantomData;
use anyhow::anyhow;
use axiom_codec::HiLo;
use axiom_eth::{
halo2_base::AssignedValue,
impl_flatten_conversion,
utils::{
component::{types::LogicalEmpty, ComponentType, ComponentTypeId, LogicalResult},
snark_verifier::EnhancedSnark,
},
};
use serde::{Deserialize, Serialize};
pub(crate) type F = axiom_eth::halo2curves::bn256::Fr;
#[derive(Clone, Debug, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InputSubqueryAggregation {
pub snark_header: EnhancedSnark,
#[serde(skip_serializing_if = "Option::is_none")]
pub snark_account: Option<EnhancedSnark>,
#[serde(skip_serializing_if = "Option::is_none")]
pub snark_storage: Option<EnhancedSnark>,
#[serde(skip_serializing_if = "Option::is_none")]
pub snark_solidity_mapping: Option<EnhancedSnark>,
#[serde(skip_serializing_if = "Option::is_none")]
pub snark_tx: Option<EnhancedSnark>,
#[serde(skip_serializing_if = "Option::is_none")]
pub snark_receipt: Option<EnhancedSnark>,
pub promise_commit_keccak: F,
pub snark_results_root: EnhancedSnark,
}
pub struct ComponentTypeSubqueryAgg {
_phatnom: PhantomData<F>,
}
impl ComponentType<F> for ComponentTypeSubqueryAgg {
type InputValue = LogicalEmpty<F>;
type InputWitness = LogicalEmpty<AssignedValue<F>>;
type OutputValue = LogicalEmpty<F>;
type OutputWitness = LogicalEmpty<AssignedValue<F>>;
type LogicalInput = LogicalEmpty<F>;
fn get_type_id() -> ComponentTypeId {
"axiom-query:ComponentTypeSubqueryAgg".to_string()
}
fn logical_result_to_virtual_rows_impl(
_ins: &LogicalResult<F, Self>,
) -> Vec<(Self::InputValue, Self::OutputValue)> {
unreachable!()
}
fn logical_input_to_virtual_rows_impl(_li: &Self::LogicalInput) -> Vec<Self::InputValue> {
unreachable!()
}
}
const FIELD_SIZE_PUBLIC_INSTANCES: [usize; 6] = [
9999, 9999, 9999, 9999, 128, 128, ];
pub const SUBQUERY_AGGREGATION_AGG_VKEY_HASH_IDX: usize = 1;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct LogicalPublicInstanceSubqueryAgg<T> {
pub promise_keccak: T,
pub agg_vkey_hash: T,
pub results_root_poseidon: T,
pub commit_subquery_hashes: T,
pub mmr_keccak: HiLo<T>,
}
impl<T> TryFrom<Vec<T>> for LogicalPublicInstanceSubqueryAgg<T> {
type Error = anyhow::Error;
fn try_from(value: Vec<T>) -> Result<Self, Self::Error> {
let [promise_keccak, agg_vkey_hash, results_root_poseidon, commit_subquery_hashes, mmr_hi, mmr_lo] =
value
.try_into()
.map_err(|_| anyhow!("LogicalPublicInstanceSubqueryAgg invalid length"))?;
Ok(Self {
promise_keccak,
agg_vkey_hash,
results_root_poseidon,
commit_subquery_hashes,
mmr_keccak: HiLo::from_hi_lo([mmr_hi, mmr_lo]),
})
}
}
impl<T: Copy> LogicalPublicInstanceSubqueryAgg<T> {
pub fn flatten(&self) -> Vec<T> {
iter::empty()
.chain([self.promise_keccak, self.agg_vkey_hash])
.chain([self.results_root_poseidon, self.commit_subquery_hashes])
.chain(self.mmr_keccak.hi_lo())
.collect()
}
}
impl_flatten_conversion!(LogicalPublicInstanceSubqueryAgg, FIELD_SIZE_PUBLIC_INSTANCES);