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
#![deny(missing_docs)]
#![doc = include_str!("../README.md")]
mod call;
mod genesis;

#[cfg(test)]
mod tests;

#[cfg(feature = "native")]
mod query;

/// The call methods specified in this module
pub use call::CallMessage;
/// The response type used by RPC queries.
#[cfg(feature = "native")]
pub use query::Response;
use sov_modules_api::{Context, Error, ModuleInfo, Zkvm};
use sov_state::codec::BcsCodec;
use sov_state::WorkingSet;

/// Configuration of the prover incentives module. Specifies the
/// address of the bonding token, the minimum bond, the commitment to
/// the allowed verifier method and a set of initial provers with their
/// bonding amount.
pub struct ProverIncentivesConfig<C: Context, Vm: Zkvm> {
    /// The address of the token to be used for bonding.
    bonding_token_address: C::Address,
    /// The minimum bond for a prover.
    minimum_bond: u64,
    /// A code commitment to be used for verifying proofs
    commitment_of_allowed_verifier_method: Vm::CodeCommitment,
    /// A list of initial provers and their bonded amount.
    initial_provers: Vec<(C::Address, u64)>,
}

/// A new module:
/// - Must derive `ModuleInfo`
/// - Must contain `[address]` field
/// - Can contain any number of ` #[state]` or `[module]` fields
#[cfg_attr(feature = "native", derive(sov_modules_api::ModuleCallJsonSchema))]
#[derive(ModuleInfo)]
pub struct ProverIncentives<C: Context, Vm: Zkvm> {
    /// Address of the module.
    #[address]
    pub address: C::Address,

    /// The address of the token used for bonding provers
    #[state]
    pub bonding_token_address: sov_state::StateValue<C::Address>,

    /// The code commitment to be used for verifying proofs
    #[state]
    pub commitment_of_allowed_verifier_method: sov_state::StateValue<Vm::CodeCommitment, BcsCodec>,

    /// The set of registered provers and their bonded amount.
    #[state]
    pub bonded_provers: sov_state::StateMap<C::Address, u64>,

    /// The minimum bond for a prover to be eligible for onchain verification
    #[state]
    pub minimum_bond: sov_state::StateValue<u64>,

    /// Reference to the Bank module.
    #[module]
    pub(crate) bank: sov_bank::Bank<C>,
}

impl<C: Context, Vm: Zkvm> sov_modules_api::Module for ProverIncentives<C, Vm> {
    type Context = C;

    type Config = ProverIncentivesConfig<C, Vm>;

    type CallMessage = call::CallMessage;

    fn genesis(
        &self,
        config: &Self::Config,
        working_set: &mut WorkingSet<C::Storage>,
    ) -> Result<(), Error> {
        // The initialization logic
        Ok(self.init_module(config, working_set)?)
    }

    fn call(
        &self,
        msg: Self::CallMessage,
        context: &Self::Context,
        working_set: &mut WorkingSet<C::Storage>,
    ) -> Result<sov_modules_api::CallResponse, Error> {
        match msg {
            call::CallMessage::BondProver(bond_amount) => {
                self.bond_prover(bond_amount, context, working_set)
            }
            call::CallMessage::UnbondProver => self.unbond_prover(context, working_set),
            call::CallMessage::VerifyProof(proof) => {
                self.process_proof(&proof, context, working_set)
            }
        }
        .map_err(|e| e.into())
    }
}