Complete the verification in MainMockPod (#302)
- Update the `RecursivePod` trait to return `vd_set` instead of `vds_root` - A native verifier requires the entire set to reason about the circuits that have been used in the recursive tree - Implement serialization/deserialization for `VDSet` - Remove `DynError` and use `BackendError` instead for middleware functions that wrap or define trait functions implemented in the backend. This is based on the fact that we will only have a single backend enabled at a time, so there's no need for a `dyn Error` - Move the implementations of `_verify` functions to `verify` and similarly for `_prove` - Complete the verification of a MockMainPod: the verification of input pods was missing. The inclusion of these input pods in the serialization was also missing. With this change a `MockMainPod` will grow after each recursion. This was expected from the design but was not the case because of the missing recursive native verification implementation. * apply feedback from @arnaucube
This commit is contained in:
parent
df8fce76d6
commit
6249406cb2
16 changed files with 427 additions and 350 deletions
|
|
@ -774,11 +774,9 @@ pub fn normalize_statement(statement: &Statement, self_id: PodId) -> Statement {
|
|||
Statement::from_args(predicate, args).expect("statement was valid before normalization")
|
||||
}
|
||||
|
||||
pub type DynError = dyn std::error::Error + Send + Sync;
|
||||
|
||||
pub trait Pod: fmt::Debug + DynClone + Any {
|
||||
fn params(&self) -> &Params;
|
||||
fn verify(&self) -> Result<(), Box<DynError>>;
|
||||
fn verify(&self) -> Result<(), BackendError>;
|
||||
fn id(&self) -> PodId;
|
||||
/// Return a uuid of the pod type and its name. The name is only used as metadata.
|
||||
fn pod_type(&self) -> (usize, &'static str);
|
||||
|
|
@ -807,18 +805,6 @@ pub trait Pod: fmt::Debug + DynClone + Any {
|
|||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
// Front-end Pods keep references to middleware Pods. Most of the
|
||||
// middleware data can be derived directly from front-end data, but the
|
||||
// "proof" data is only created at the point of proving/signing, and
|
||||
// cannot be reconstructed. As such, we need to serialize it whenever
|
||||
// we serialize a front-end Pod. Since the front-end does not understand
|
||||
// the implementation details of the middleware, this method allows the
|
||||
// middleware to provide some serialized data that can be used to
|
||||
// reconstruct the proof.
|
||||
// It is an important principle that this data is opaque to the front-end
|
||||
// and any third-party code.
|
||||
// fn serialized_proof(&self) -> String;
|
||||
}
|
||||
|
||||
// impl Clone for Box<dyn Pod>
|
||||
|
|
@ -830,15 +816,15 @@ dyn_clone::clone_trait_object!(Pod);
|
|||
pub trait RecursivePod: Pod {
|
||||
fn verifier_data(&self) -> VerifierOnlyCircuitData;
|
||||
fn proof(&self) -> Proof;
|
||||
fn vds_root(&self) -> Hash;
|
||||
fn vd_set(&self) -> &VDSet;
|
||||
|
||||
/// Returns the deserialized RecursivePod.
|
||||
fn deserialize_data(
|
||||
params: Params,
|
||||
data: serde_json::Value,
|
||||
vds_root: Hash,
|
||||
vd_set: VDSet,
|
||||
id: PodId,
|
||||
) -> Result<Box<dyn RecursivePod>, Box<DynError>>
|
||||
) -> Result<Box<dyn RecursivePod>, BackendError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
|
@ -851,7 +837,7 @@ pub trait PodSigner {
|
|||
&mut self,
|
||||
params: &Params,
|
||||
kvs: &HashMap<Key, Value>,
|
||||
) -> Result<Box<dyn Pod>, Box<DynError>>;
|
||||
) -> Result<Box<dyn Pod>, BackendError>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -863,7 +849,7 @@ pub struct MainPodInputs<'a> {
|
|||
/// Statements that need to be made public (they can come from input pods or input
|
||||
/// statements)
|
||||
pub public_statements: &'a [Statement],
|
||||
pub vds_set: VDSet,
|
||||
pub vd_set: VDSet,
|
||||
}
|
||||
|
||||
pub trait PodProver {
|
||||
|
|
@ -872,7 +858,7 @@ pub trait PodProver {
|
|||
params: &Params,
|
||||
vd_set: &VDSet,
|
||||
inputs: MainPodInputs,
|
||||
) -> Result<Box<dyn RecursivePod>, Box<DynError>>;
|
||||
) -> Result<Box<dyn RecursivePod>, BackendError>;
|
||||
}
|
||||
|
||||
pub trait ToFields {
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ use std::{
|
|||
sync::{LazyLock, Mutex},
|
||||
};
|
||||
|
||||
use crate::middleware::{DynError, Error, Hash, Params, Pod, PodId, PodType, RecursivePod, Result};
|
||||
use crate::middleware::{BackendError, Params, Pod, PodId, PodType, RecursivePod, Result, VDSet};
|
||||
|
||||
type DeserializeFn = fn(
|
||||
params: Params,
|
||||
data: serde_json::Value,
|
||||
vds_root: Hash,
|
||||
vd_set: VDSet,
|
||||
id: PodId,
|
||||
) -> Result<Box<dyn RecursivePod>, Box<DynError>>;
|
||||
) -> Result<Box<dyn RecursivePod>, BackendError>;
|
||||
|
||||
static DESERIALIZERS: LazyLock<Mutex<HashMap<usize, DeserializeFn>>> =
|
||||
LazyLock::new(backend::deserializers_default);
|
||||
|
|
@ -26,28 +26,27 @@ pub fn deserialize_pod(
|
|||
pod_type: usize,
|
||||
params: Params,
|
||||
id: PodId,
|
||||
vds_root: Hash,
|
||||
vd_set: VDSet,
|
||||
data: serde_json::Value,
|
||||
) -> Result<Box<dyn RecursivePod>> {
|
||||
) -> Result<Box<dyn RecursivePod>, BackendError> {
|
||||
let deserialize_fn: DeserializeFn =
|
||||
*DESERIALIZERS
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get(&pod_type)
|
||||
.ok_or(Error::custom(format!(
|
||||
.ok_or(BackendError::custom(format!(
|
||||
"pod deserializer for pod_type={} not registered. See https://github.com/0xPARC/pod2/wiki/PodType for pod type assignments.",
|
||||
pod_type
|
||||
)))?;
|
||||
|
||||
deserialize_fn(params, data, vds_root, id)
|
||||
.map_err(|e| Error::custom(format!("deserialize error: {:?}", e)))
|
||||
deserialize_fn(params, data, vd_set, id)
|
||||
}
|
||||
|
||||
pub fn deserialize_signed_pod(
|
||||
pod_type: usize,
|
||||
id: PodId,
|
||||
data: serde_json::Value,
|
||||
) -> Result<Box<dyn Pod>> {
|
||||
) -> Result<Box<dyn Pod>, BackendError> {
|
||||
backend::deserialize_signed_pod(pod_type, id, data)
|
||||
}
|
||||
|
||||
|
|
@ -74,15 +73,13 @@ mod backend {
|
|||
pod_type: usize,
|
||||
id: PodId,
|
||||
data: serde_json::Value,
|
||||
) -> Result<Box<dyn Pod>> {
|
||||
) -> Result<Box<dyn Pod>, BackendError> {
|
||||
if pod_type == PodType::MockSigned as usize {
|
||||
MockSignedPod::deserialize(id, data)
|
||||
.map_err(|e| Error::custom(format!("deserialize error: {:?}", e)))
|
||||
} else if pod_type == PodType::Signed as usize {
|
||||
SignedPod::deserialize(id, data)
|
||||
.map_err(|e| Error::custom(format!("deserialize error: {:?}", e)))
|
||||
} else {
|
||||
Err(Error::custom(format!(
|
||||
Err(BackendError::custom(format!(
|
||||
"unexpected pod_type={} for deserialize_signed_pod",
|
||||
pod_type
|
||||
)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue