@@ -79,7 +79,13 @@ impl CardanoTransactionsImporter {
79
79
return Ok ( ( ) ) ;
80
80
}
81
81
82
- let parsed_transactions = self . block_scanner . parse ( & self . dirpath , from, until) . await ?;
82
+ // todo: temp algorithm, should be optimized to avoid loading all blocks & transactions
83
+ // at once in memory (probably using iterators)
84
+ let scanned_blocks = self . block_scanner . scan ( & self . dirpath , from, until) . await ?;
85
+ let parsed_transactions: Vec < CardanoTransaction > = scanned_blocks
86
+ . into_iter ( )
87
+ . flat_map ( |b| b. into_transactions ( ) )
88
+ . collect ( ) ;
83
89
debug ! (
84
90
self . logger,
85
91
"TransactionsImporter retrieved '{}' Cardano transactions between immutables '{}' and '{until}'" ,
@@ -114,6 +120,8 @@ mod tests {
114
120
use mockall:: mock;
115
121
use mockall:: predicate:: eq;
116
122
123
+ use mithril_common:: cardano_block_scanner:: ScannedBlock ;
124
+
117
125
use crate :: database:: repository:: CardanoTransactionRepository ;
118
126
use crate :: database:: test_helper:: cardano_tx_db_connection;
119
127
@@ -124,19 +132,23 @@ mod tests {
124
132
125
133
#[ async_trait]
126
134
impl BlockScanner for BlockScannerImpl {
127
- async fn parse (
135
+ async fn scan (
128
136
& self ,
129
137
dirpath: & Path ,
130
138
from_immutable: Option <ImmutableFileNumber >,
131
139
until_immutable: ImmutableFileNumber ,
132
- ) -> StdResult <Vec <CardanoTransaction >>;
140
+ ) -> StdResult <Vec <ScannedBlock >>;
133
141
}
134
142
}
135
143
136
- fn build_importer (
137
- scanner_mock_config : & dyn Fn ( & mut MockBlockScannerImpl ) ,
138
- store_mock_config : & dyn Fn ( & mut MockTransactionStore ) ,
139
- ) -> CardanoTransactionsImporter {
144
+ fn build_importer < TParser , TStore > (
145
+ scanner_mock_config : TParser ,
146
+ store_mock_config : TStore ,
147
+ ) -> CardanoTransactionsImporter
148
+ where
149
+ TParser : FnOnce ( & mut MockBlockScannerImpl ) ,
150
+ TStore : FnOnce ( & mut MockTransactionStore ) ,
151
+ {
140
152
let db_path = Path :: new ( "" ) ;
141
153
let mut scanner = MockBlockScannerImpl :: new ( ) ;
142
154
scanner_mock_config ( & mut scanner) ;
@@ -156,23 +168,24 @@ mod tests {
156
168
157
169
#[ tokio:: test]
158
170
async fn if_nothing_stored_parse_and_store_all_transactions ( ) {
159
- let transactions = vec ! [
160
- CardanoTransaction :: new( "tx_hash-1" , 10 , 15 , "block_hash-1" , 11 ) ,
161
- CardanoTransaction :: new( "tx_hash-2" , 10 , 20 , "block_hash-1" , 11 ) ,
162
- CardanoTransaction :: new( "tx_hash-3" , 20 , 25 , "block_hash-2" , 12 ) ,
163
- CardanoTransaction :: new( "tx_hash-4" , 20 , 30 , "block_hash-2" , 12 ) ,
171
+ let blocks = vec ! [
172
+ ScannedBlock :: new( "block_hash-1" , 10 , 15 , 11 , vec![ "tx_hash-1" , "tx_hash-2" ] ) ,
173
+ ScannedBlock :: new( "block_hash-2" , 20 , 25 , 12 , vec![ "tx_hash-3" , "tx_hash-4" ] ) ,
164
174
] ;
175
+ let transactions: Vec < CardanoTransaction > = blocks
176
+ . iter ( )
177
+ . flat_map ( |b| b. clone ( ) . into_transactions ( ) )
178
+ . collect ( ) ;
165
179
let up_to_beacon = 12 ;
166
180
167
181
let importer = build_importer (
168
- & |scanner_mock| {
169
- let parsed_transactions = transactions. clone ( ) ;
182
+ |scanner_mock| {
170
183
scanner_mock
171
- . expect_parse ( )
184
+ . expect_scan ( )
172
185
. withf ( move |_, from, until| from. is_none ( ) && until == & up_to_beacon)
173
- . return_once ( move |_, _, _| Ok ( parsed_transactions ) ) ;
186
+ . return_once ( move |_, _, _| Ok ( blocks ) ) ;
174
187
} ,
175
- & |store_mock| {
188
+ |store_mock| {
176
189
let expected_stored_transactions = transactions. clone ( ) ;
177
190
store_mock
178
191
. expect_get_highest_beacon ( )
@@ -196,10 +209,10 @@ mod tests {
196
209
let up_to_beacon = 12 ;
197
210
198
211
let importer = build_importer (
199
- & |scanner_mock| {
200
- scanner_mock. expect_parse ( ) . never ( ) ;
212
+ |scanner_mock| {
213
+ scanner_mock. expect_scan ( ) . never ( ) ;
201
214
} ,
202
- & |store_mock| {
215
+ |store_mock| {
203
216
store_mock
204
217
. expect_get_highest_beacon ( )
205
218
. returning ( || Ok ( Some ( 12 ) ) ) ;
@@ -215,23 +228,25 @@ mod tests {
215
228
216
229
#[ tokio:: test]
217
230
async fn if_all_half_are_stored_the_other_half_is_parsed_and_stored ( ) {
218
- let transactions = vec ! [
219
- CardanoTransaction :: new( "tx_hash-1" , 10 , 15 , "block_hash-10" , 11 ) ,
220
- CardanoTransaction :: new( "tx_hash-2" , 20 , 20 , "block_hash-20" , 12 ) ,
221
- CardanoTransaction :: new( "tx_hash-3" , 30 , 25 , "block_hash-30" , 13 ) ,
222
- CardanoTransaction :: new( "tx_hash-4" , 40 , 30 , "block_hash-40" , 14 ) ,
231
+ let blocks = [
232
+ ScannedBlock :: new ( "block_hash-1" , 10 , 15 , 11 , vec ! [ "tx_hash-1" , "tx_hash-2" ] ) ,
233
+ ScannedBlock :: new ( "block_hash-2" , 20 , 25 , 12 , vec ! [ "tx_hash-3" , "tx_hash-4" ] ) ,
223
234
] ;
235
+ let transactions: Vec < CardanoTransaction > = blocks
236
+ . iter ( )
237
+ . flat_map ( |b| b. clone ( ) . into_transactions ( ) )
238
+ . collect ( ) ;
224
239
let up_to_beacon = 14 ;
225
240
226
241
let importer = build_importer (
227
- & |scanner_mock| {
228
- let parsed_transactions = transactions [ 2 ..= 3 ] . to_vec ( ) ;
242
+ |scanner_mock| {
243
+ let scanned_blocks = vec ! [ blocks [ 1 ] . clone ( ) ] ;
229
244
scanner_mock
230
- . expect_parse ( )
245
+ . expect_scan ( )
231
246
. withf ( move |_, from, until| from == & Some ( 13 ) && until == & up_to_beacon)
232
- . return_once ( move |_, _, _| Ok ( parsed_transactions ) ) ;
247
+ . return_once ( move |_, _, _| Ok ( scanned_blocks ) ) ;
233
248
} ,
234
- & |store_mock| {
249
+ |store_mock| {
235
250
store_mock
236
251
. expect_get_highest_beacon ( )
237
252
. returning ( || Ok ( Some ( 12 ) ) ) ;
@@ -253,19 +268,18 @@ mod tests {
253
268
#[ tokio:: test]
254
269
async fn importing_twice_starting_with_nothing_in_a_real_db_should_yield_the_transactions_in_same_order (
255
270
) {
256
- let transactions = vec ! [
257
- CardanoTransaction :: new( "tx_hash-1" , 10 , 15 , "block_hash-1" , 11 ) ,
258
- CardanoTransaction :: new( "tx_hash-2" , 10 , 20 , "block_hash-1" , 11 ) ,
259
- CardanoTransaction :: new( "tx_hash-3" , 20 , 25 , "block_hash-2" , 12 ) ,
260
- CardanoTransaction :: new( "tx_hash-4" , 20 , 30 , "block_hash-2" , 12 ) ,
271
+ let blocks = vec ! [
272
+ ScannedBlock :: new( "block_hash-1" , 10 , 15 , 11 , vec![ "tx_hash-1" , "tx_hash-2" ] ) ,
273
+ ScannedBlock :: new( "block_hash-2" , 20 , 25 , 12 , vec![ "tx_hash-3" , "tx_hash-4" ] ) ,
261
274
] ;
275
+ let transactions: Vec < CardanoTransaction > = blocks
276
+ . iter ( )
277
+ . flat_map ( |b| b. clone ( ) . into_transactions ( ) )
278
+ . collect ( ) ;
262
279
let importer = {
263
280
let connection = cardano_tx_db_connection ( ) . unwrap ( ) ;
264
- let parsed_transactions = transactions. clone ( ) ;
265
281
let mut scanner = MockBlockScannerImpl :: new ( ) ;
266
- scanner
267
- . expect_parse ( )
268
- . return_once ( move |_, _, _| Ok ( parsed_transactions) ) ;
282
+ scanner. expect_scan ( ) . return_once ( move |_, _, _| Ok ( blocks) ) ;
269
283
270
284
CardanoTransactionsImporter :: new (
271
285
Arc :: new ( scanner) ,
0 commit comments