proof_of_sql/sql/evm_proof_plan/
proof_plan.rs1use super::{plans::EVMDynProofPlan, EVMProofPlanError, EVMProofPlanResult};
2use crate::{
3 base::{
4 database::{
5 ColumnField, ColumnRef, ColumnType, LiteralValue, OwnedTable, Table, TableEvaluation,
6 TableRef,
7 },
8 map::{IndexMap, IndexSet},
9 proof::{PlaceholderResult, ProofError},
10 scalar::Scalar,
11 },
12 sql::{
13 proof::{
14 FinalRoundBuilder, FirstRoundBuilder, ProofPlan, ProverEvaluate, VerificationBuilder,
15 },
16 proof_plans::DynProofPlan,
17 },
18};
19use alloc::{
20 string::{String, ToString},
21 vec::Vec,
22};
23use bumpalo::Bump;
24use core::str::FromStr;
25use itertools::Itertools;
26use serde::{Deserialize, Serialize, Serializer};
27use sqlparser::ast::Ident;
28
29#[derive(Debug)]
30pub struct EVMProofPlan {
35 inner: DynProofPlan,
36}
37
38impl EVMProofPlan {
39 #[must_use]
41 pub fn new(plan: DynProofPlan) -> Self {
42 Self { inner: plan }
43 }
44 #[must_use]
46 pub fn into_inner(self) -> DynProofPlan {
47 self.inner
48 }
49 #[must_use]
51 pub fn inner(&self) -> &DynProofPlan {
52 &self.inner
53 }
54}
55
56#[derive(Serialize, Deserialize)]
57struct CompactPlan {
58 tables: Vec<String>,
59 columns: Vec<(usize, String, ColumnType)>,
60 output_column_names: Vec<String>,
61 plan: EVMDynProofPlan,
62}
63
64impl TryFrom<&EVMProofPlan> for CompactPlan {
65 type Error = EVMProofPlanError;
66
67 fn try_from(value: &EVMProofPlan) -> Result<Self, Self::Error> {
68 let table_refs = value.get_table_references();
69 let column_refs = value.get_column_references();
70 let output_column_names = value
71 .get_column_result_fields()
72 .iter()
73 .map(|field| field.name().to_string())
74 .collect();
75
76 let plan = EVMDynProofPlan::try_from_proof_plan(value.inner(), &table_refs, &column_refs)?;
77 let columns = column_refs
78 .into_iter()
79 .map(|column_ref| -> EVMProofPlanResult<_> {
80 let table_index = table_refs
81 .get_index_of(&column_ref.table_ref())
82 .ok_or(EVMProofPlanError::TableNotFound)?;
83 Ok((
84 table_index,
85 column_ref.column_id().to_string(),
86 *column_ref.column_type(),
87 ))
88 })
89 .try_collect()?;
90 let tables = table_refs.iter().map(ToString::to_string).collect();
91
92 Ok(Self {
93 tables,
94 columns,
95 output_column_names,
96 plan,
97 })
98 }
99}
100
101impl TryFrom<CompactPlan> for EVMProofPlan {
102 type Error = EVMProofPlanError;
103
104 fn try_from(value: CompactPlan) -> Result<Self, Self::Error> {
105 let table_refs: IndexSet<TableRef> = value
106 .tables
107 .iter()
108 .map(|table| TableRef::from_str(table).map_err(|_| EVMProofPlanError::InvalidTableName))
109 .try_collect()?;
110 let table_refs_clone = table_refs.clone();
111 let column_refs: IndexSet<ColumnRef> = value
112 .columns
113 .iter()
114 .map(|(i, ident, column_type)| -> EVMProofPlanResult<_> {
115 let table_ref = table_refs_clone
116 .get_index(*i)
117 .cloned()
118 .ok_or(EVMProofPlanError::TableNotFound)?;
119 Ok(ColumnRef::new(table_ref, Ident::new(ident), *column_type))
120 })
121 .try_collect()?;
122 let output_column_names: IndexSet<String> = value.output_column_names.into_iter().collect();
123 Ok(Self {
124 inner: value.plan.try_into_proof_plan(
125 &table_refs,
126 &column_refs,
127 &output_column_names,
128 )?,
129 })
130 }
131}
132
133impl Serialize for EVMProofPlan {
134 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
135 CompactPlan::try_from(self)
136 .map_err(serde::ser::Error::custom)?
137 .serialize(serializer)
138 }
139}
140
141impl<'de> Deserialize<'de> for EVMProofPlan {
142 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
143 where
144 D: serde::Deserializer<'de>,
145 {
146 CompactPlan::deserialize(deserializer)?
147 .try_into()
148 .map_err(serde::de::Error::custom)
149 }
150}
151
152impl ProofPlan for EVMProofPlan {
153 fn verifier_evaluate<S: Scalar>(
154 &self,
155 builder: &mut impl VerificationBuilder<S>,
156 accessor: &IndexMap<TableRef, IndexMap<Ident, S>>,
157 result: Option<&OwnedTable<S>>,
158 chi_eval_map: &IndexMap<TableRef, S>,
159 params: &[LiteralValue],
160 ) -> Result<TableEvaluation<S>, ProofError> {
161 self.inner()
162 .verifier_evaluate(builder, accessor, result, chi_eval_map, params)
163 }
164 fn get_column_result_fields(&self) -> Vec<ColumnField> {
165 self.inner().get_column_result_fields()
166 }
167 fn get_column_references(&self) -> IndexSet<ColumnRef> {
168 self.inner().get_column_references()
169 }
170 fn get_table_references(&self) -> IndexSet<TableRef> {
171 self.inner().get_table_references()
172 }
173}
174impl ProverEvaluate for EVMProofPlan {
175 fn first_round_evaluate<'a, S: Scalar>(
176 &self,
177 builder: &mut FirstRoundBuilder<'a, S>,
178 alloc: &'a Bump,
179 table_map: &IndexMap<TableRef, Table<'a, S>>,
180 params: &[LiteralValue],
181 ) -> PlaceholderResult<Table<'a, S>> {
182 self.inner()
183 .first_round_evaluate(builder, alloc, table_map, params)
184 }
185 fn final_round_evaluate<'a, S: Scalar>(
186 &self,
187 builder: &mut FinalRoundBuilder<'a, S>,
188 alloc: &'a Bump,
189 table_map: &IndexMap<TableRef, Table<'a, S>>,
190 params: &[LiteralValue],
191 ) -> PlaceholderResult<Table<'a, S>> {
192 self.inner()
193 .final_round_evaluate(builder, alloc, table_map, params)
194 }
195}