1+ use async_trait:: async_trait;
2+ use rayon:: prelude:: * ;
3+ use slog:: { debug, info, Logger } ;
14use std:: {
25 collections:: { BTreeMap , BTreeSet , HashMap } ,
36 sync:: Arc ,
7+ time:: Duration ,
48} ;
59
6- use async_trait:: async_trait;
7-
810use mithril_common:: {
9- crypto_helper:: MKTree ,
11+ crypto_helper:: { MKMap , MKMapNode , MKTree } ,
1012 entities:: {
1113 BlockRange , CardanoDbBeacon , CardanoTransaction , CardanoTransactionsSetProof ,
1214 TransactionHash ,
1315 } ,
16+ resource_pool:: ResourcePool ,
1417 signable_builder:: BlockRangeRootRetriever ,
1518 StdResult ,
1619} ;
@@ -25,6 +28,9 @@ pub trait ProverService: Sync + Send {
2528 up_to : & CardanoDbBeacon ,
2629 transaction_hashes : & [ TransactionHash ] ,
2730 ) -> StdResult < Vec < CardanoTransactionsSetProof > > ;
31+
32+ /// Compute the cache
33+ async fn compute_cache ( & self , _up_to : & CardanoDbBeacon ) -> StdResult < ( ) > ;
2834}
2935
3036/// Transactions retriever
@@ -51,17 +57,23 @@ pub trait TransactionsRetriever: Sync + Send {
5157pub struct MithrilProverService {
5258 transaction_retriever : Arc < dyn TransactionsRetriever > ,
5359 block_range_root_retriever : Arc < dyn BlockRangeRootRetriever > ,
60+ mk_map_pool : ResourcePool < MKMap < BlockRange , MKMapNode < BlockRange > > > ,
61+ logger : Logger ,
5462}
5563
5664impl MithrilProverService {
5765 /// Create a new Mithril prover
5866 pub fn new (
5967 transaction_retriever : Arc < dyn TransactionsRetriever > ,
6068 block_range_root_retriever : Arc < dyn BlockRangeRootRetriever > ,
69+ mk_map_pool_size : usize ,
70+ logger : Logger ,
6171 ) -> Self {
6272 Self {
6373 transaction_retriever,
6474 block_range_root_retriever,
75+ mk_map_pool : ResourcePool :: new ( mk_map_pool_size, vec ! [ ] ) ,
76+ logger,
6577 }
6678 }
6779
@@ -106,7 +118,7 @@ impl MithrilProverService {
106118impl ProverService for MithrilProverService {
107119 async fn compute_transactions_proofs (
108120 & self ,
109- up_to : & CardanoDbBeacon ,
121+ _up_to : & CardanoDbBeacon ,
110122 transaction_hashes : & [ TransactionHash ] ,
111123 ) -> StdResult < Vec < CardanoTransactionsSetProof > > {
112124 // 1 - Compute the set of block ranges with transactions to prove
@@ -124,9 +136,8 @@ impl ProverService for MithrilProverService {
124136
125137 // 3 - Compute block range roots Merkle map
126138 let mut mk_map = self
127- . block_range_root_retriever
128- . compute_merkle_map_from_block_range_roots ( up_to. immutable_file_number )
129- . await ?;
139+ . mk_map_pool
140+ . acquire_resource ( Duration :: from_millis ( 1000 ) ) ?;
130141
131142 // 4 - Enrich the Merkle map with the block ranges Merkle trees
132143 for ( block_range, mk_tree) in mk_trees {
@@ -135,6 +146,9 @@ impl ProverService for MithrilProverService {
135146
136147 // 5 - Compute the proof for all transactions
137148 if let Ok ( mk_proof) = mk_map. compute_proof ( transaction_hashes) {
149+ self . mk_map_pool
150+ . return_resource ( mk_map. into_inner ( ) , mk_map. discriminant ( ) ) ?;
151+
138152 let transaction_hashes_certified: Vec < TransactionHash > = transaction_hashes
139153 . iter ( )
140154 . filter ( |hash| mk_proof. contains ( & hash. as_str ( ) . into ( ) ) . is_ok ( ) )
@@ -149,6 +163,35 @@ impl ProverService for MithrilProverService {
149163 Ok ( vec ! [ ] )
150164 }
151165 }
166+
167+ async fn compute_cache ( & self , up_to : & CardanoDbBeacon ) -> StdResult < ( ) > {
168+ let pool_size = self . mk_map_pool . size ( ) ;
169+ info ! (
170+ self . logger,
171+ "Prover starts computing the Merkle map pool pool resource of size {pool_size}"
172+ ) ;
173+ self . mk_map_pool . drain ( ) ;
174+ let mk_map_cache = self
175+ . block_range_root_retriever
176+ . compute_merkle_map_from_block_range_roots ( up_to. immutable_file_number )
177+ . await ?;
178+ let discriminant_new = self . mk_map_pool . discriminant ( ) ? + 1 ;
179+ self . mk_map_pool . set_discriminant ( discriminant_new) ?;
180+ for i in 1 ..=pool_size {
181+ debug ! (
182+ self . logger,
183+ "Prover is computing the Merkle map pool pool resource {i}/{pool_size}"
184+ ) ;
185+ self . mk_map_pool
186+ . return_resource ( mk_map_cache. clone ( ) , discriminant_new) ?;
187+ }
188+ info ! (
189+ self . logger,
190+ "Prover completed computing the Merkle map pool pool resource of size {pool_size}"
191+ ) ;
192+
193+ Ok ( ( ) )
194+ }
152195}
153196
154197#[ cfg( test) ]
@@ -305,10 +348,14 @@ mod tests {
305348 transaction_retriever_mock_config ( & mut transaction_retriever) ;
306349 let mut block_range_root_retriever = MockBlockRangeRootRetrieverImpl :: new ( ) ;
307350 block_range_root_retriever_mock_config ( & mut block_range_root_retriever) ;
351+ let mk_map_pool_size = 1 ;
352+ let logger = slog_scope:: logger ( ) ;
308353
309354 MithrilProverService :: new (
310355 Arc :: new ( transaction_retriever) ,
311356 Arc :: new ( block_range_root_retriever) ,
357+ mk_map_pool_size,
358+ logger,
312359 )
313360 }
314361
@@ -351,6 +398,7 @@ mod tests {
351398 } ) ;
352399 } ,
353400 ) ;
401+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
354402
355403 let transactions_set_proof = prover
356404 . compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
@@ -404,6 +452,7 @@ mod tests {
404452 } ) ;
405453 } ,
406454 ) ;
455+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
407456
408457 let transactions_set_proof = prover
409458 . compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
@@ -460,6 +509,7 @@ mod tests {
460509 } ) ;
461510 } ,
462511 ) ;
512+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
463513
464514 let transactions_set_proof = prover
465515 . compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
@@ -497,6 +547,7 @@ mod tests {
497547 . return_once ( |_| MKMap :: new ( & [ ] ) ) ;
498548 } ,
499549 ) ;
550+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
500551
501552 prover
502553 . compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
0 commit comments