Integrate recursion into MainPod (#243)
* calculate MainPod id in a dynamic-friendly way The MainPod id is now calculated with front padding and a fixed size independent of max_public_statements so that introduction gadgets can be verified by a MainPod while paying only for the number of statements they use. This is because with front padding of none-statements we can precompute the poseidon state corresponding to absorbing all the padding statements and only pay constraints for the non-padding statements. The id is calculated as follows: `id = hash(serialize(reverse(statements || none-statements)))` * add time feature and disable timing by default * apply suggestions from @arnaucube * link issues in todos
This commit is contained in:
parent
d3fef8392e
commit
88a75986b8
23 changed files with 1405 additions and 729 deletions
|
|
@ -10,7 +10,8 @@ use serialization::{SerializedMainPod, SerializedSignedPod};
|
|||
use crate::middleware::{
|
||||
self, check_st_tmpl, hash_str, hash_values, AnchoredKey, Hash, Key, MainPodInputs,
|
||||
NativeOperation, NativePredicate, OperationAux, OperationType, Params, PodId, PodProver,
|
||||
PodSigner, Predicate, Statement, StatementArg, Value, WildcardValue, KEY_TYPE, SELF,
|
||||
PodSigner, Predicate, Statement, StatementArg, Value, WildcardValue, EMPTY_HASH, KEY_TYPE,
|
||||
SELF,
|
||||
};
|
||||
|
||||
mod custom;
|
||||
|
|
@ -553,7 +554,7 @@ impl MainPodBuilder {
|
|||
.iter()
|
||||
.map(|p| p.pod.as_ref())
|
||||
.collect_vec(),
|
||||
main_pods: &self
|
||||
recursive_pods: &self
|
||||
.input_main_pods
|
||||
.iter()
|
||||
.map(|p| p.pod.as_ref())
|
||||
|
|
@ -561,6 +562,7 @@ impl MainPodBuilder {
|
|||
statements: &statements,
|
||||
operations: &operations,
|
||||
public_statements: &public_statements,
|
||||
vds_root: EMPTY_HASH, // TODO https://github.com/0xPARC/pod2/issues/249
|
||||
};
|
||||
let pod = prover.prove(&self.params, inputs)?;
|
||||
|
||||
|
|
@ -618,7 +620,7 @@ impl MainPodBuilder {
|
|||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(try_from = "SerializedMainPod", into = "SerializedMainPod")]
|
||||
pub struct MainPod {
|
||||
pub pod: Box<dyn middleware::Pod>,
|
||||
pub pod: Box<dyn middleware::RecursivePod>,
|
||||
pub public_statements: Vec<Statement>,
|
||||
pub params: Params,
|
||||
}
|
||||
|
|
@ -898,7 +900,7 @@ pub mod tests {
|
|||
fn test_ethdos() -> Result<()> {
|
||||
let params = Params {
|
||||
max_input_signed_pods: 3,
|
||||
max_input_main_pods: 3,
|
||||
max_input_recursive_pods: 3,
|
||||
max_statements: 31,
|
||||
max_signed_pod_values: 8,
|
||||
max_public_statements: 10,
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ use crate::{
|
|||
},
|
||||
frontend::{MainPod, SignedPod},
|
||||
middleware::{
|
||||
self, containers::Dictionary, serialization::ordered_map, AnchoredKey, Key, Params, PodId,
|
||||
Statement, StatementArg, Value, SELF,
|
||||
self, containers::Dictionary, serialization::ordered_map, AnchoredKey, Hash, Key, Params,
|
||||
PodId, Statement, StatementArg, Value, EMPTY_HASH, SELF,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -45,6 +45,7 @@ pub enum MainPodType {
|
|||
#[schemars(rename = "MainPod")]
|
||||
pub struct SerializedMainPod {
|
||||
id: PodId,
|
||||
vds_root: Hash,
|
||||
public_statements: Vec<Statement>,
|
||||
proof: String,
|
||||
params: Params,
|
||||
|
|
@ -99,23 +100,23 @@ impl From<SerializedSignedPod> for SignedPod {
|
|||
|
||||
impl From<MainPod> for SerializedMainPod {
|
||||
fn from(pod: MainPod) -> Self {
|
||||
SerializedMainPod {
|
||||
id: pod.id(),
|
||||
proof: pod.pod.serialized_proof(),
|
||||
params: pod.params.clone(),
|
||||
pod_type: if (&*pod.pod as &dyn Any)
|
||||
.downcast_ref::<Plonky2MainPod>()
|
||||
.is_some()
|
||||
{
|
||||
MainPodType::Main
|
||||
let (pod_type, vds_root) =
|
||||
if let Some(pod) = (&*pod.pod as &dyn Any).downcast_ref::<Plonky2MainPod>() {
|
||||
(MainPodType::Main, pod.vds_root())
|
||||
} else if (&*pod.pod as &dyn Any)
|
||||
.downcast_ref::<MockMainPod>()
|
||||
.is_some()
|
||||
{
|
||||
MainPodType::MockMain
|
||||
(MainPodType::MockMain, EMPTY_HASH)
|
||||
} else {
|
||||
unreachable!()
|
||||
},
|
||||
};
|
||||
SerializedMainPod {
|
||||
id: pod.id(),
|
||||
vds_root,
|
||||
proof: pod.pod.serialized_proof(),
|
||||
params: pod.params.clone(),
|
||||
pod_type,
|
||||
public_statements: pod.public_statements.clone(),
|
||||
}
|
||||
}
|
||||
|
|
@ -142,6 +143,7 @@ impl TryFrom<SerializedMainPod> for MainPod {
|
|||
serialized.id,
|
||||
),
|
||||
serialized.id,
|
||||
serialized.vds_root,
|
||||
serialized.params.clone(),
|
||||
)),
|
||||
public_statements: serialized.public_statements,
|
||||
|
|
@ -369,7 +371,7 @@ mod tests {
|
|||
let params = middleware::Params {
|
||||
// Currently the circuit uses random access that only supports vectors of length 64.
|
||||
// With max_input_main_pods=3 we need random access to a vector of length 73.
|
||||
max_input_main_pods: 1,
|
||||
max_input_recursive_pods: 1,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
|
@ -420,7 +422,7 @@ mod tests {
|
|||
fn build_ethdos_pod() -> Result<MainPod> {
|
||||
let params = Params {
|
||||
max_input_signed_pods: 3,
|
||||
max_input_main_pods: 3,
|
||||
max_input_recursive_pods: 3,
|
||||
max_statements: 31,
|
||||
max_signed_pod_values: 8,
|
||||
max_public_statements: 10,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue