@@ -3,15 +3,16 @@ use rayon::prelude::*;
3
3
use std:: {
4
4
collections:: { BTreeMap , BTreeSet , HashMap } ,
5
5
sync:: Arc ,
6
+ time:: Duration ,
6
7
} ;
7
- use tokio:: sync:: Mutex ;
8
8
9
9
use mithril_common:: {
10
10
crypto_helper:: { MKMap , MKMapNode , MKTree } ,
11
11
entities:: {
12
12
BlockRange , CardanoDbBeacon , CardanoTransaction , CardanoTransactionsSetProof ,
13
13
TransactionHash ,
14
14
} ,
15
+ resource_pool:: ResourcePool ,
15
16
signable_builder:: BlockRangeRootRetriever ,
16
17
StdResult ,
17
18
} ;
@@ -28,14 +29,10 @@ pub trait ProverService: Sync + Send {
28
29
) -> StdResult < Vec < CardanoTransactionsSetProof > > ;
29
30
30
31
/// Compute the cache
31
- async fn compute_cache ( & self , _up_to : & CardanoDbBeacon ) -> StdResult < ( ) > {
32
- Ok ( ( ) )
33
- }
32
+ async fn compute_cache ( & self , _up_to : & CardanoDbBeacon ) -> StdResult < ( ) > ;
34
33
35
34
/// Clear the cache
36
- async fn clear_cache ( & self ) -> StdResult < ( ) > {
37
- Ok ( ( ) )
38
- }
35
+ async fn clear_cache ( & self ) -> StdResult < ( ) > ;
39
36
}
40
37
41
38
/// Transactions retriever
@@ -62,7 +59,7 @@ pub trait TransactionsRetriever: Sync + Send {
62
59
pub struct MithrilProverService {
63
60
transaction_retriever : Arc < dyn TransactionsRetriever > ,
64
61
block_range_root_retriever : Arc < dyn BlockRangeRootRetriever > ,
65
- mk_map_cache : Mutex < Option < MKMap < BlockRange , MKMapNode < BlockRange > > > > ,
62
+ mk_map_cache : ResourcePool < MKMap < BlockRange , MKMapNode < BlockRange > > > ,
66
63
}
67
64
68
65
impl MithrilProverService {
@@ -74,7 +71,7 @@ impl MithrilProverService {
74
71
Self {
75
72
transaction_retriever,
76
73
block_range_root_retriever,
77
- mk_map_cache : Mutex :: new ( None ) ,
74
+ mk_map_cache : ResourcePool :: default ( ) ,
78
75
}
79
76
}
80
77
@@ -119,7 +116,7 @@ impl MithrilProverService {
119
116
impl ProverService for MithrilProverService {
120
117
async fn compute_transactions_proofs (
121
118
& self ,
122
- up_to : & CardanoDbBeacon ,
119
+ _up_to : & CardanoDbBeacon ,
123
120
transaction_hashes : & [ TransactionHash ] ,
124
121
) -> StdResult < Vec < CardanoTransactionsSetProof > > {
125
122
// 1 - Compute the set of block ranges with transactions to prove
@@ -139,9 +136,9 @@ impl ProverService for MithrilProverService {
139
136
let mk_trees = BTreeMap :: from_iter ( mk_trees?) ;
140
137
141
138
// 3 - Compute block range roots Merkle map
142
- self . compute_cache ( up_to ) . await ? ;
143
- let mut mk_map = self . mk_map_cache . lock ( ) . await ;
144
- let mk_map = mk_map . as_mut ( ) . unwrap ( ) ;
139
+ let mut mk_map = self
140
+ . mk_map_cache
141
+ . acquire_resource ( Duration :: from_millis ( 1000 ) ) ? ;
145
142
146
143
// 4 - Enrich the Merkle map with the block ranges Merkle trees
147
144
for ( block_range, mk_tree) in mk_trees {
@@ -150,6 +147,9 @@ impl ProverService for MithrilProverService {
150
147
151
148
// 5 - Compute the proof for all transactions
152
149
if let Ok ( mk_proof) = mk_map. compute_proof ( transaction_hashes) {
150
+ self . mk_map_cache
151
+ . return_resource ( mk_map. into_inner ( ) , mk_map. discriminant ( ) ) ?;
152
+
153
153
let transaction_hashes_certified: Vec < TransactionHash > = transaction_hashes
154
154
. iter ( )
155
155
. filter ( |hash| mk_proof. contains ( & hash. as_str ( ) . into ( ) ) . is_ok ( ) )
@@ -166,22 +166,30 @@ impl ProverService for MithrilProverService {
166
166
}
167
167
168
168
async fn compute_cache ( & self , up_to : & CardanoDbBeacon ) -> StdResult < ( ) > {
169
- let mut mk_map = self . mk_map_cache . lock ( ) . await ;
170
- if mk_map . is_none ( ) {
171
- println ! ( "Computing Merkle map from block range roots" ) ;
169
+ if self . mk_map_cache . count ( ) ? == 0 {
170
+ println ! ( "Computing Merkle map cache from block range roots" ) ;
171
+
172
172
let mk_map_cache = self
173
173
. block_range_root_retriever
174
174
. compute_merkle_map_from_block_range_roots ( up_to. immutable_file_number )
175
175
. await ?;
176
- mk_map. replace ( mk_map_cache) ;
176
+ let discriminant_new = self . mk_map_cache . discriminant ( ) ? + 1 ;
177
+ self . mk_map_cache . set_discriminant ( discriminant_new) ?;
178
+ for i in 0 ..10 {
179
+ println ! ( "Computing Merkle map cache from block range roots: {}" , i) ;
180
+ self . mk_map_cache
181
+ . return_resource ( mk_map_cache. clone ( ) , discriminant_new) ?;
182
+ }
183
+ self . mk_map_cache
184
+ . return_resource ( mk_map_cache, discriminant_new) ?;
185
+ println ! ( "Done computing Merkle map cache from block range roots" ) ;
177
186
}
178
187
179
188
Ok ( ( ) )
180
189
}
181
190
182
191
async fn clear_cache ( & self ) -> StdResult < ( ) > {
183
- let mut mk_map = self . mk_map_cache . lock ( ) . await ;
184
- mk_map. take ( ) ;
192
+ self . mk_map_cache . drain ( ) ;
185
193
186
194
Ok ( ( ) )
187
195
}
@@ -387,6 +395,7 @@ mod tests {
387
395
} ) ;
388
396
} ,
389
397
) ;
398
+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
390
399
391
400
let transactions_set_proof = prover
392
401
. compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
@@ -440,6 +449,7 @@ mod tests {
440
449
} ) ;
441
450
} ,
442
451
) ;
452
+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
443
453
444
454
let transactions_set_proof = prover
445
455
. compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
@@ -496,6 +506,7 @@ mod tests {
496
506
} ) ;
497
507
} ,
498
508
) ;
509
+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
499
510
500
511
let transactions_set_proof = prover
501
512
. compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
@@ -533,6 +544,7 @@ mod tests {
533
544
. return_once ( |_| MKMap :: new ( & [ ] ) ) ;
534
545
} ,
535
546
) ;
547
+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
536
548
537
549
prover
538
550
. compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
0 commit comments