1
+ use async_trait:: async_trait;
2
+ use rayon:: prelude:: * ;
3
+ use slog:: { debug, info, Logger } ;
1
4
use std:: {
2
5
collections:: { BTreeMap , BTreeSet , HashMap } ,
3
6
sync:: Arc ,
7
+ time:: Duration ,
4
8
} ;
5
9
6
- use async_trait:: async_trait;
7
-
8
10
use mithril_common:: {
9
- crypto_helper:: MKTree ,
11
+ crypto_helper:: { MKMap , MKMapNode , MKTree } ,
10
12
entities:: {
11
13
BlockRange , CardanoDbBeacon , CardanoTransaction , CardanoTransactionsSetProof ,
12
14
TransactionHash ,
13
15
} ,
16
+ resource_pool:: ResourcePool ,
14
17
signable_builder:: BlockRangeRootRetriever ,
15
18
StdResult ,
16
19
} ;
@@ -25,6 +28,9 @@ pub trait ProverService: Sync + Send {
25
28
up_to : & CardanoDbBeacon ,
26
29
transaction_hashes : & [ TransactionHash ] ,
27
30
) -> StdResult < Vec < CardanoTransactionsSetProof > > ;
31
+
32
+ /// Compute the cache
33
+ async fn compute_cache ( & self , _up_to : & CardanoDbBeacon ) -> StdResult < ( ) > ;
28
34
}
29
35
30
36
/// Transactions retriever
@@ -51,17 +57,23 @@ pub trait TransactionsRetriever: Sync + Send {
51
57
pub struct MithrilProverService {
52
58
transaction_retriever : Arc < dyn TransactionsRetriever > ,
53
59
block_range_root_retriever : Arc < dyn BlockRangeRootRetriever > ,
60
+ mk_map_pool : ResourcePool < MKMap < BlockRange , MKMapNode < BlockRange > > > ,
61
+ logger : Logger ,
54
62
}
55
63
56
64
impl MithrilProverService {
57
65
/// Create a new Mithril prover
58
66
pub fn new (
59
67
transaction_retriever : Arc < dyn TransactionsRetriever > ,
60
68
block_range_root_retriever : Arc < dyn BlockRangeRootRetriever > ,
69
+ mk_map_pool_size : usize ,
70
+ logger : Logger ,
61
71
) -> Self {
62
72
Self {
63
73
transaction_retriever,
64
74
block_range_root_retriever,
75
+ mk_map_pool : ResourcePool :: new ( mk_map_pool_size, vec ! [ ] ) ,
76
+ logger,
65
77
}
66
78
}
67
79
@@ -106,7 +118,7 @@ impl MithrilProverService {
106
118
impl ProverService for MithrilProverService {
107
119
async fn compute_transactions_proofs (
108
120
& self ,
109
- up_to : & CardanoDbBeacon ,
121
+ _up_to : & CardanoDbBeacon ,
110
122
transaction_hashes : & [ TransactionHash ] ,
111
123
) -> StdResult < Vec < CardanoTransactionsSetProof > > {
112
124
// 1 - Compute the set of block ranges with transactions to prove
@@ -124,9 +136,8 @@ impl ProverService for MithrilProverService {
124
136
125
137
// 3 - Compute block range roots Merkle map
126
138
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 ) ) ?;
130
141
131
142
// 4 - Enrich the Merkle map with the block ranges Merkle trees
132
143
for ( block_range, mk_tree) in mk_trees {
@@ -135,6 +146,9 @@ impl ProverService for MithrilProverService {
135
146
136
147
// 5 - Compute the proof for all transactions
137
148
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
+
138
152
let transaction_hashes_certified: Vec < TransactionHash > = transaction_hashes
139
153
. iter ( )
140
154
. filter ( |hash| mk_proof. contains ( & hash. as_str ( ) . into ( ) ) . is_ok ( ) )
@@ -149,6 +163,35 @@ impl ProverService for MithrilProverService {
149
163
Ok ( vec ! [ ] )
150
164
}
151
165
}
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
+ }
152
195
}
153
196
154
197
#[ cfg( test) ]
@@ -305,10 +348,14 @@ mod tests {
305
348
transaction_retriever_mock_config ( & mut transaction_retriever) ;
306
349
let mut block_range_root_retriever = MockBlockRangeRootRetrieverImpl :: new ( ) ;
307
350
block_range_root_retriever_mock_config ( & mut block_range_root_retriever) ;
351
+ let mk_map_pool_size = 1 ;
352
+ let logger = slog_scope:: logger ( ) ;
308
353
309
354
MithrilProverService :: new (
310
355
Arc :: new ( transaction_retriever) ,
311
356
Arc :: new ( block_range_root_retriever) ,
357
+ mk_map_pool_size,
358
+ logger,
312
359
)
313
360
}
314
361
@@ -351,6 +398,7 @@ mod tests {
351
398
} ) ;
352
399
} ,
353
400
) ;
401
+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
354
402
355
403
let transactions_set_proof = prover
356
404
. compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
@@ -404,6 +452,7 @@ mod tests {
404
452
} ) ;
405
453
} ,
406
454
) ;
455
+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
407
456
408
457
let transactions_set_proof = prover
409
458
. compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
@@ -460,6 +509,7 @@ mod tests {
460
509
} ) ;
461
510
} ,
462
511
) ;
512
+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
463
513
464
514
let transactions_set_proof = prover
465
515
. compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
@@ -497,6 +547,7 @@ mod tests {
497
547
. return_once ( |_| MKMap :: new ( & [ ] ) ) ;
498
548
} ,
499
549
) ;
550
+ prover. compute_cache ( & test_data. beacon ) . await . unwrap ( ) ;
500
551
501
552
prover
502
553
. compute_transactions_proofs ( & test_data. beacon , & test_data. transaction_hashes_to_prove )
0 commit comments