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