-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlib.rs
176 lines (151 loc) · 6.14 KB
/
lib.rs
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
pub mod config;
mod error;
use std::collections::HashMap;
use std::sync::Arc;
use std::task::{Context, Poll};
use aggchain_proof_contracts::AggchainProofContractsClient;
use aggchain_proof_core::proof::{AggchainProofWitness, InclusionProof, L1InfoTreeLeaf};
use aggkit_prover_types::Hash;
pub use error::Error;
use futures::{future::BoxFuture, FutureExt};
use prover_executor::Executor;
use sp1_sdk::{SP1Proof, SP1ProofWithPublicValues, SP1VerifyingKey};
use tower::buffer::Buffer;
use tower::util::BoxService;
use tower::ServiceExt as _;
use crate::config::AggchainProofBuilderConfig;
const MAX_CONCURRENT_REQUESTS: usize = 100;
const ELF: &[u8] =
include_bytes!("../../../crates/aggchain-proof-program/elf/riscv32im-succinct-zkvm-elf");
pub(crate) type ProverService = Buffer<
BoxService<prover_executor::Request, prover_executor::Response, prover_executor::Error>,
prover_executor::Request,
>;
/// All the data `aggchain-proof-builder` needs for the agghchain
/// proof generation. Collected from various sources.
pub struct AggchainProverInputs {
pub proof_witness: AggchainProofWitness,
pub start_block: u64,
pub end_block: u64,
}
pub struct AggchainProofBuilderRequest {
/// Aggregated full execution proof for the number of aggregated block
/// spans.
pub agg_span_proof: SP1ProofWithPublicValues,
/// Start block of the aggregated span proof.
/// This block must match the end_block of the last proof, to check the
/// consistency between proofs, but it's not proved. The span of blocks
/// processed and proved goes from start_block+1 to end_block both
/// inclusive.
// Proof (start_block, end_block]
pub start_block: u64,
/// Last block in the aggregated span (inclusive).
pub end_block: u64,
/// Root hash of the l1 info tree, containing all relevant GER.
/// Provided by agg-sender.
pub l1_info_tree_root_hash: Hash,
/// Particular leaf of the l1 info tree corresponding
/// to the max_block.
pub l1_info_tree_leaf: L1InfoTreeLeaf,
/// Inclusion proof of the l1 info tree leaf to the
/// l1 info tree root
pub l1_info_tree_merkle_proof: [Hash; 32],
/// Map of the Global Exit Roots with their inclusion proof.
/// Note: the GER (string) is a base64 encoded string of the GER digest.
pub ger_inclusion_proofs: HashMap<String, InclusionProof>,
}
#[derive(Clone, Debug)]
pub struct AggchainProofBuilderResponse {
/// Aggchain proof generated by the `aggchain-proof-builder` service
/// per `agg-sender` request.
pub proof: SP1Proof,
/// Start block of the generated aggchain proof.
pub start_block: u64,
/// Last block included in the aggchain proof.
pub end_block: u64,
}
/// This service is responsible for building an Aggchain proof.
#[derive(Clone)]
#[allow(unused)]
pub struct AggchainProofBuilder {
/// Client for interacting with the smart contracts relevant for the
/// aggchain prover.
contracts_client: Arc<AggchainProofContractsClient>,
/// Network id of the l2 chain for which the proof is generated.
network_id: u32,
/// Prover client service.
prover: ProverService,
/// Verification key for the aggchain proof.
aggchain_proof_vkey: SP1VerifyingKey,
}
impl AggchainProofBuilder {
pub fn new(config: &AggchainProofBuilderConfig) -> Result<Self, Error> {
let executor = tower::ServiceBuilder::new()
.service(Executor::new(
&config.primary_prover,
&config.fallback_prover,
ELF,
))
.boxed();
let prover = Buffer::new(executor, MAX_CONCURRENT_REQUESTS);
let aggchain_proof_vkey = Executor::get_vkey(ELF);
Ok(AggchainProofBuilder {
contracts_client: Arc::new(
AggchainProofContractsClient::new(&config.l1_rpc_endpoint, &config.l2_rpc_endpoint)
.map_err(Error::ContractsClientInitFailed)?,
),
prover,
network_id: config.network_id,
aggchain_proof_vkey,
})
}
/// Retrieve l1 and l2 public data needed for aggchain proof generation.
/// Combine with the rest of the inputs to form an `AggchainProverInputs`.
pub(crate) async fn retrieve_chain_data(
contracts_client: Arc<AggchainProofContractsClient>,
request: AggchainProofBuilderRequest,
) -> Result<AggchainProverInputs, Error> {
let _prev_local_exit_root = contracts_client
.get_l2_local_exit_root(request.start_block)
.await
.map_err(Error::L2ChainDataRetrievalError)?;
let _new_local_exit_root = contracts_client
.get_l2_local_exit_root(request.end_block)
.await
.map_err(Error::L2ChainDataRetrievalError)?;
todo!()
}
/// Generate aggchain proof
pub(crate) async fn generate_aggchain_proof(
mut _prover: ProverService,
_inputs: AggchainProverInputs,
) -> Result<AggchainProofBuilderResponse, Error> {
todo!()
}
}
impl tower::Service<AggchainProofBuilderRequest> for AggchainProofBuilder {
type Response = AggchainProofBuilderResponse;
type Error = Error;
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.prover.poll_ready(cx).map_err(|e| {
if let Some(error) = e.downcast_ref::<prover_executor::Error>() {
Error::ProverExecutorError(error.clone())
} else {
Error::ProverServiceError(e.to_string())
}
})
}
fn call(&mut self, req: AggchainProofBuilderRequest) -> Self::Future {
let contracts_client = self.contracts_client.clone();
let prover = self.prover.clone();
async move {
// Retrieve all the necessary public inputs. Combine with
// the data provided by the agg-sender in the request.
let aggchain_prover_inputs = Self::retrieve_chain_data(contracts_client, req).await?;
// Generate aggchain proof.
Self::generate_aggchain_proof(prover, aggchain_prover_inputs).await
}
.boxed()
}
}