1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use std::marker::PhantomData;

use blstrs::Scalar as Fr;

use storage_proofs_core::{
    compound_proof::{CircuitComponent, CompoundProof},
    error::Result,
    merkle::MerkleTreeTrait,
    parameter_cache::CacheableParameters,
};

use crate::{
    circuit, constants::TreeRHasher, EmptySectorUpdate, EmptySectorUpdateCircuit, PartitionProof,
    PublicInputs, PublicParams,
};

pub struct EmptySectorUpdateCompound<TreeR>
where
    TreeR: MerkleTreeTrait<Hasher = TreeRHasher>,
{
    pub _tree_r: PhantomData<TreeR>,
}

impl<TreeR> CacheableParameters<EmptySectorUpdateCircuit<TreeR>, PublicParams>
    for EmptySectorUpdateCompound<TreeR>
where
    TreeR: MerkleTreeTrait<Hasher = TreeRHasher>,
{
    fn cache_prefix() -> String {
        format!("empty-sector-update-{}", TreeR::display())
    }
}

impl<'a, TreeR> CompoundProof<'a, EmptySectorUpdate<TreeR>, EmptySectorUpdateCircuit<TreeR>>
    for EmptySectorUpdateCompound<TreeR>
where
    TreeR: 'static + MerkleTreeTrait<Hasher = TreeRHasher>,
{
    // Generates a partition circuit's public-inputs. If the `k` argument is `Some` we overwrite
    // `pub_inputs.k` with the `k` argument's value, otherwise if the `k` argument is `None` we use
    // `pub_inputs.k` as the circuit's public-input.
    fn generate_public_inputs(
        pub_inputs: &PublicInputs,
        pub_params: &PublicParams,
        k: Option<usize>,
    ) -> Result<Vec<Fr>> {
        // Prioritize the partition-index provided via the `k` argument; default to `pub_inputs.k`.
        let k = k.unwrap_or(pub_inputs.k);

        let PublicInputs {
            comm_r_old,
            comm_d_new,
            comm_r_new,
            h,
            ..
        } = *pub_inputs;

        let pub_inputs_circ = circuit::PublicInputs::new(
            pub_params.sector_nodes,
            k,
            h,
            comm_r_old,
            comm_d_new,
            comm_r_new,
        );

        Ok(pub_inputs_circ.to_vec())
    }

    // Generates a partition's circuit. If the `k` argument is `Some` we overwrite `pub_inputs.k`
    // with the `k` argument's value, otherwise if the `k` argument is `None` we use `pub_inputs.k`
    // as the circuit's public-input.
    fn circuit(
        pub_inputs: &PublicInputs,
        _priv_inputs: <EmptySectorUpdateCircuit<TreeR> as CircuitComponent>::ComponentPrivateInputs,
        vanilla_proof: &PartitionProof<TreeR>,
        pub_params: &PublicParams,
        k: Option<usize>,
    ) -> Result<EmptySectorUpdateCircuit<TreeR>> {
        // Prioritize the partition-index provided via the `k` argument; default to `pub_inputs.k`.
        let k = k.unwrap_or(pub_inputs.k);

        let PublicInputs {
            comm_r_old,
            comm_d_new,
            comm_r_new,
            h,
            ..
        } = *pub_inputs;

        let pub_inputs = circuit::PublicInputs::new(
            pub_params.sector_nodes,
            k,
            h,
            comm_r_old,
            comm_d_new,
            comm_r_new,
        );

        let priv_inputs = circuit::PrivateInputs::new(
            vanilla_proof.comm_c,
            &vanilla_proof.apex_leafs,
            &vanilla_proof.challenge_proofs,
        );

        Ok(EmptySectorUpdateCircuit {
            pub_params: pub_params.clone(),
            pub_inputs,
            priv_inputs,
        })
    }

    fn blank_circuit(pub_params: &PublicParams) -> EmptySectorUpdateCircuit<TreeR> {
        EmptySectorUpdateCircuit::blank(pub_params.clone())
    }
}