@@ -5,15 +5,23 @@ use std::sync::Arc;
5
5
use std:: task:: { Context , Poll } ;
6
6
7
7
use aggchain_proof_contracts:: contracts:: {
8
- L1RollupConfigHashFetcher , L2LocalExitRootFetcher , L2OutputAtBlockFetcher ,
8
+ L1RollupConfigHashFetcher , L2EVMStateSketchesFetched , L2LocalExitRootFetcher ,
9
+ L2OutputAtBlockFetcher ,
9
10
} ;
10
11
use aggchain_proof_contracts:: AggchainContractsClient ;
12
+ use aggchain_proof_core:: full_execution_proof:: FepPublicValues ;
13
+ use aggchain_proof_core:: local_exit_tree:: hasher:: Keccak256Hasher ;
14
+ use aggchain_proof_core:: local_exit_tree:: proof:: LETMerkleProof ;
11
15
use aggchain_proof_core:: proof:: AggchainProofWitness ;
16
+ use aggchain_proof_core:: { BridgeWitness , InsertedGER , L1InfoTreeLeaf } ;
12
17
use aggchain_proof_types:: { AggchainProofInputs , Digest } ;
18
+ use alloy:: eips:: BlockNumberOrTag ;
19
+ use alloy_primitives:: Address ;
13
20
pub use error:: Error ;
14
21
use futures:: { future:: BoxFuture , FutureExt } ;
15
22
use prover_executor:: Executor ;
16
- use sp1_sdk:: { SP1Proof , SP1ProofWithPublicValues , SP1VerifyingKey } ;
23
+ use sp1_sdk:: network:: B256 ;
24
+ use sp1_sdk:: { SP1Proof , SP1ProofWithPublicValues , SP1Stdin , SP1VerifyingKey } ;
17
25
use tower:: buffer:: Buffer ;
18
26
use tower:: util:: BoxService ;
19
27
use tower:: ServiceExt as _;
@@ -32,7 +40,7 @@ pub(crate) type ProverService = Buffer<
32
40
/// All the data `aggchain-proof-builder` needs for the agghchain
33
41
/// proof generation. Collected from various sources.
34
42
pub struct AggchainProverInputs {
35
- pub proof_witness : AggchainProofWitness ,
43
+ pub sp1_stdin : SP1Stdin ,
36
44
pub start_block : u64 ,
37
45
pub end_block : u64 ,
38
46
}
@@ -78,6 +86,14 @@ pub struct AggchainProofBuilder<ContractsClient> {
78
86
aggchain_proof_vkey : SP1VerifyingKey ,
79
87
}
80
88
89
+ #[ derive( Debug , Clone , thiserror:: Error ) ]
90
+ pub enum WitnessGeneration {
91
+ #[ error( "Invalid inserted GER." ) ]
92
+ InvalidInsertedGer ,
93
+ #[ error( "Cannot interpret the aggregation proof as 'compressed' type." ) ]
94
+ WrongAggregationProofType ,
95
+ }
96
+
81
97
impl < ContractsClient > AggchainProofBuilder < ContractsClient > {
82
98
pub async fn new (
83
99
config : & AggchainProofBuilderConfig ,
@@ -107,37 +123,150 @@ impl<ContractsClient> AggchainProofBuilder<ContractsClient> {
107
123
pub ( crate ) async fn retrieve_chain_data (
108
124
contracts_client : Arc < ContractsClient > ,
109
125
request : AggchainProofBuilderRequest ,
126
+ origin_network : u32 ,
110
127
) -> Result < AggchainProverInputs , Error >
111
128
where
112
- ContractsClient :
113
- L2LocalExitRootFetcher + L2OutputAtBlockFetcher + L1RollupConfigHashFetcher ,
129
+ ContractsClient : L2LocalExitRootFetcher
130
+ + L2OutputAtBlockFetcher
131
+ + L2EVMStateSketchesFetched
132
+ + L1RollupConfigHashFetcher ,
114
133
{
115
- let _prev_local_exit_root = contracts_client
134
+ // Fetch from RPCs
135
+ let prev_local_exit_root = contracts_client
116
136
. get_l2_local_exit_root ( request. aggchain_proof_inputs . start_block - 1 )
117
137
. await
118
138
. map_err ( Error :: L2ChainDataRetrievalError ) ?;
119
139
120
- let _new_local_exit_root = contracts_client
140
+ let new_local_exit_root = contracts_client
121
141
. get_l2_local_exit_root ( request. end_block )
122
142
. await
123
143
. map_err ( Error :: L2ChainDataRetrievalError ) ?;
124
144
125
- let _l2_pre_root_output_at_block = contracts_client
145
+ let l2_pre_root_output_at_block = contracts_client
126
146
. get_l2_output_at_block ( request. aggchain_proof_inputs . start_block - 1 )
127
147
. await
128
148
. map_err ( Error :: L2ChainDataRetrievalError ) ?;
129
149
130
- let _claim_root_output_at_block = contracts_client
150
+ let claim_root_output_at_block = contracts_client
131
151
. get_l2_output_at_block ( request. end_block )
132
152
. await
133
153
. map_err ( Error :: L2ChainDataRetrievalError ) ?;
134
154
135
- let _rollup_config_hash = contracts_client
155
+ let rollup_config_hash = contracts_client
136
156
. get_rollup_config_hash ( )
137
157
. await
138
158
. map_err ( Error :: L1ChainDataRetrievalError ) ?;
139
159
140
- todo ! ( )
160
+ let prev_l2_block_sketch = contracts_client
161
+ . get_prev_l2_block_sketch ( BlockNumberOrTag :: Number (
162
+ request. aggchain_proof_inputs . start_block ,
163
+ ) )
164
+ . await
165
+ . map_err ( Error :: L2ChainDataRetrievalError ) ?;
166
+
167
+ let new_l2_block_sketch = contracts_client
168
+ . get_new_l2_block_sketch ( BlockNumberOrTag :: Number ( request. end_block ) )
169
+ . await
170
+ . map_err ( Error :: L2ChainDataRetrievalError ) ?;
171
+
172
+ // From the request
173
+ let inserted_gers: Vec < InsertedGER > = request
174
+ . aggchain_proof_inputs
175
+ . ger_leaves
176
+ . values ( )
177
+ . map ( |claim_data| {
178
+ Ok ( InsertedGER {
179
+ proof : claim_data. inclusion_proof . clone ( ) . try_into ( ) . map_err ( |_| {
180
+ Error :: ProverWitnessGenerationError ( WitnessGeneration :: InvalidInsertedGer )
181
+ } ) ?,
182
+ l1_info_tree_leaf : claim_data. l1_leaf . clone ( ) . into ( ) ,
183
+ l1_info_tree_index : claim_data. l1_leaf . l1_info_tree_index ,
184
+ } )
185
+ } )
186
+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
187
+
188
+ let inserted_gers_hash_chain = inserted_gers
189
+ . iter ( )
190
+ . map ( |inserted_ger| inserted_ger. ger ( ) )
191
+ . collect ( ) ;
192
+
193
+ let global_indices: Vec < B256 > = request
194
+ . aggchain_proof_inputs
195
+ . imported_bridge_exits
196
+ . iter ( )
197
+ . map ( |ib| ( & ib. global_index ) . into ( ) )
198
+ . collect ( ) ;
199
+
200
+ let l1_info_tree_leaf: ( u32 , L1InfoTreeLeaf ) = (
201
+ request
202
+ . aggchain_proof_inputs
203
+ . l1_info_tree_leaf
204
+ . l1_info_tree_index ,
205
+ request. aggchain_proof_inputs . l1_info_tree_leaf . into ( ) ,
206
+ ) ;
207
+
208
+ // Considered empty for now
209
+ let ( removed_gers_hash_chain, global_indices_unset) = ( vec ! [ ] , vec ! [ ] ) ;
210
+
211
+ let trusted_sequencer = Address :: default ( ) ; // TODO: from config or l1
212
+
213
+ let fep = FepPublicValues {
214
+ l1_head : l1_info_tree_leaf. 1 . block_hash ,
215
+ claim_block_num : request. end_block as u32 ,
216
+ rollup_config_hash,
217
+ prev_state_root : l2_pre_root_output_at_block. state_root ,
218
+ prev_withdrawal_storage_root : l2_pre_root_output_at_block. withdrawal_storage_root ,
219
+ prev_block_hash : l2_pre_root_output_at_block. latest_block_hash ,
220
+ new_state_root : claim_root_output_at_block. state_root ,
221
+ new_withdrawal_storage_root : claim_root_output_at_block. withdrawal_storage_root ,
222
+ new_block_hash : claim_root_output_at_block. latest_block_hash ,
223
+ trusted_sequencer,
224
+ signature_optimistic_mode : None , // unsupported for now
225
+ } ;
226
+
227
+ let prover_witness = AggchainProofWitness {
228
+ prev_local_exit_root,
229
+ new_local_exit_root,
230
+ l1_info_root : request. aggchain_proof_inputs . l1_info_tree_root_hash ,
231
+ origin_network,
232
+ fep,
233
+ l1_info_tree_leaf,
234
+ l1_head_inclusion_proof : LETMerkleProof :: < Keccak256Hasher > {
235
+ siblings : request
236
+ . aggchain_proof_inputs
237
+ . l1_info_tree_merkle_proof
238
+ . clone ( ) ,
239
+ } ,
240
+ global_indices : global_indices. clone ( ) ,
241
+ bridge_witness : BridgeWitness {
242
+ inserted_gers,
243
+ global_indices_claimed : global_indices,
244
+ global_indices_unset,
245
+ raw_inserted_gers : inserted_gers_hash_chain,
246
+ removed_gers : removed_gers_hash_chain,
247
+ prev_l2_block_sketch,
248
+ new_l2_block_sketch,
249
+ } ,
250
+ } ;
251
+
252
+ let SP1Proof :: Compressed ( aggregation_proof) = request. aggregation_proof . proof else {
253
+ return Err ( Error :: ProverWitnessGenerationError (
254
+ WitnessGeneration :: WrongAggregationProofType ,
255
+ ) ) ;
256
+ } ;
257
+ let aggregation_vkey = aggregation_proof. vk . clone ( ) ;
258
+ let sp1_stdin = {
259
+ let mut stdin = SP1Stdin :: new ( ) ;
260
+ stdin. write ( & prover_witness) ;
261
+ stdin. write_proof ( * aggregation_proof, aggregation_vkey) ;
262
+ stdin
263
+ } ;
264
+
265
+ Ok ( AggchainProverInputs {
266
+ start_block : request. aggchain_proof_inputs . start_block ,
267
+ end_block : request. end_block ,
268
+ sp1_stdin,
269
+ } )
141
270
}
142
271
143
272
/// Generate aggchain proof
@@ -173,10 +302,12 @@ where
173
302
fn call ( & mut self , req : AggchainProofBuilderRequest ) -> Self :: Future {
174
303
let contracts_client = self . contracts_client . clone ( ) ;
175
304
let prover = self . prover . clone ( ) ;
305
+ let origin_network = self . network_id ;
176
306
async move {
177
307
// Retrieve all the necessary public inputs. Combine with
178
308
// the data provided by the agg-sender in the request.
179
- let aggchain_prover_inputs = Self :: retrieve_chain_data ( contracts_client, req) . await ?;
309
+ let aggchain_prover_inputs =
310
+ Self :: retrieve_chain_data ( contracts_client, req, origin_network) . await ?;
180
311
181
312
// Generate aggchain proof.
182
313
Self :: generate_aggchain_proof ( prover, aggchain_prover_inputs) . await
0 commit comments