@@ -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,151 @@ 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 sketches = contracts_client
161
+ . get_evm_state_sketches (
162
+ BlockNumberOrTag :: Number ( request. aggchain_proof_inputs . start_block ) ,
163
+ BlockNumberOrTag :: Number ( request. end_block ) ,
164
+ )
165
+ . await
166
+ . map_err ( Error :: L2ChainDataRetrievalError ) ?;
167
+
168
+ // From the request
169
+ let inserted_gers: Vec < InsertedGER > = request
170
+ . aggchain_proof_inputs
171
+ . ger_leaves
172
+ . values ( )
173
+ . map ( |claim_data| {
174
+ Ok ( InsertedGER {
175
+ proof : claim_data. inclusion_proof . clone ( ) . try_into ( ) . map_err ( |_| {
176
+ Error :: ProverWitnessGenerationError ( WitnessGeneration :: InvalidInsertedGer )
177
+ } ) ?,
178
+ l1_info_tree_leaf : claim_data. l1_leaf . clone ( ) . into ( ) ,
179
+ l1_info_tree_index : claim_data. l1_leaf . l1_info_tree_index ,
180
+ } )
181
+ } )
182
+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
183
+
184
+ let inserted_gers_hash_chain = inserted_gers
185
+ . iter ( )
186
+ . map ( |inserted_ger| inserted_ger. ger ( ) )
187
+ . collect ( ) ;
188
+
189
+ let global_indices: Vec < B256 > = request
190
+ . aggchain_proof_inputs
191
+ . imported_bridge_exits
192
+ . iter ( )
193
+ . map ( |ib| ( & ib. global_index ) . into ( ) )
194
+ . collect ( ) ;
195
+
196
+ let l1_info_tree_leaf: ( u32 , L1InfoTreeLeaf ) = (
197
+ request
198
+ . aggchain_proof_inputs
199
+ . l1_info_tree_leaf
200
+ . l1_info_tree_index ,
201
+ request. aggchain_proof_inputs . l1_info_tree_leaf . into ( ) ,
202
+ ) ;
203
+
204
+ // Considered empty for now
205
+ let ( removed_gers_hash_chain, global_indices_unset) = ( vec ! [ ] , vec ! [ ] ) ;
206
+
207
+ let trusted_sequencer = Address :: default ( ) ; // TODO: from config or l1
208
+
209
+ let fep = FepPublicValues {
210
+ l1_head : l1_info_tree_leaf. 1 . block_hash ,
211
+ claim_block_num : request. end_block as u32 ,
212
+ rollup_config_hash,
213
+ prev_state_root : l2_pre_root_output_at_block. state_root ,
214
+ prev_withdrawal_storage_root : l2_pre_root_output_at_block. withdrawal_storage_root ,
215
+ prev_block_hash : l2_pre_root_output_at_block. latest_block_hash ,
216
+ new_state_root : claim_root_output_at_block. state_root ,
217
+ new_withdrawal_storage_root : claim_root_output_at_block. withdrawal_storage_root ,
218
+ new_block_hash : claim_root_output_at_block. latest_block_hash ,
219
+ trusted_sequencer,
220
+ signature_optimistic_mode : None , // unsupported for now
221
+ } ;
222
+
223
+ let prover_witness = AggchainProofWitness {
224
+ prev_local_exit_root,
225
+ new_local_exit_root,
226
+ l1_info_root : request. aggchain_proof_inputs . l1_info_tree_root_hash ,
227
+ origin_network,
228
+ fep,
229
+ l1_info_tree_leaf,
230
+ l1_head_inclusion_proof : LETMerkleProof :: < Keccak256Hasher > {
231
+ siblings : request
232
+ . aggchain_proof_inputs
233
+ . l1_info_tree_merkle_proof
234
+ . clone ( ) ,
235
+ } ,
236
+ global_indices : global_indices. clone ( ) ,
237
+ bridge_witness : BridgeWitness {
238
+ inserted_gers,
239
+ inserted_gers_hash_chain,
240
+ removed_gers_hash_chain,
241
+ global_indices_claimed : global_indices,
242
+ global_indices_unset,
243
+ inserted_ger_sketches : sketches. inserted_ger_sketches ,
244
+ removed_ger_sketches : sketches. removed_ger_sketches ,
245
+ claimed_global_index_sketches : sketches. claimed_global_index_sketches ,
246
+ unset_global_index_sketches : sketches. unset_global_index_sketches ,
247
+ bridge_address_sketch : sketches. bridge_address_sketch ,
248
+ new_ler_sketch : sketches. new_ler_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
+
258
+ let aggregation_vkey = aggregation_proof. vk . clone ( ) ;
259
+ let sp1_stdin = {
260
+ let mut stdin = SP1Stdin :: new ( ) ;
261
+ stdin. write ( & prover_witness) ;
262
+ stdin. write_proof ( * aggregation_proof, aggregation_vkey) ;
263
+ stdin
264
+ } ;
265
+
266
+ Ok ( AggchainProverInputs {
267
+ start_block : request. aggchain_proof_inputs . start_block ,
268
+ end_block : request. end_block ,
269
+ sp1_stdin,
270
+ } )
141
271
}
142
272
143
273
/// Generate aggchain proof
@@ -173,10 +303,12 @@ where
173
303
fn call ( & mut self , req : AggchainProofBuilderRequest ) -> Self :: Future {
174
304
let contracts_client = self . contracts_client . clone ( ) ;
175
305
let prover = self . prover . clone ( ) ;
306
+ let origin_network = self . network_id ;
176
307
async move {
177
308
// Retrieve all the necessary public inputs. Combine with
178
309
// the data provided by the agg-sender in the request.
179
- let aggchain_prover_inputs = Self :: retrieve_chain_data ( contracts_client, req) . await ?;
310
+ let aggchain_prover_inputs =
311
+ Self :: retrieve_chain_data ( contracts_client, req, origin_network) . await ?;
180
312
181
313
// Generate aggchain proof.
182
314
Self :: generate_aggchain_proof ( prover, aggchain_prover_inputs) . await
0 commit comments