@@ -32,6 +32,7 @@ pub struct CardanoBlockScanner {
32
32
/// This situation should only happen on the test networks and not on the mainnet.
33
33
allow_unparsable_block : bool ,
34
34
lower_bound_finder : Arc < dyn ImmutableLowerBoundFinder > ,
35
+ rescan_offset : Option < usize > ,
35
36
}
36
37
37
38
impl CardanoBlockScanner {
@@ -40,6 +41,7 @@ impl CardanoBlockScanner {
40
41
logger : Logger ,
41
42
allow_unparsable_block : bool ,
42
43
lower_bound_finder : Arc < dyn ImmutableLowerBoundFinder > ,
44
+ rescan_offset : Option < usize > ,
43
45
) -> Self {
44
46
if allow_unparsable_block {
45
47
warn ! (
@@ -51,8 +53,16 @@ impl CardanoBlockScanner {
51
53
logger,
52
54
allow_unparsable_block,
53
55
lower_bound_finder,
56
+ rescan_offset,
54
57
}
55
58
}
59
+
60
+ async fn get_lower_bound ( & self ) -> StdResult < Option < ImmutableFileNumber > > {
61
+ let highest = self . lower_bound_finder . find_lower_bound ( ) . await ?;
62
+ let rescan_offset = self . rescan_offset . unwrap_or ( 0 ) ;
63
+ let highest = highest. map ( |h| ( h + 1 ) . saturating_sub ( rescan_offset as u64 ) ) ;
64
+ Ok ( highest)
65
+ }
56
66
}
57
67
58
68
#[ async_trait]
@@ -63,7 +73,7 @@ impl BlockScanner for CardanoBlockScanner {
63
73
_from : Option < ChainPoint > ,
64
74
_until : BlockNumber ,
65
75
) -> StdResult < Box < dyn BlockStreamer > > {
66
- let lower_bound = self . lower_bound_finder . find_lower_bound ( ) . await ?;
76
+ let lower_bound = self . get_lower_bound ( ) . await ?;
67
77
let is_in_bounds = |number : ImmutableFileNumber | match lower_bound {
68
78
Some ( from) => from <= number,
69
79
None => true ,
@@ -114,7 +124,7 @@ mod tests {
114
124
mock. expect_find_lower_bound ( ) . returning ( || Ok ( None ) ) ;
115
125
} ) ;
116
126
let cardano_transaction_parser =
117
- CardanoBlockScanner :: new ( TestLogger :: stdout ( ) , false , lower_bound_finder) ;
127
+ CardanoBlockScanner :: new ( TestLogger :: stdout ( ) , false , lower_bound_finder, None ) ;
118
128
119
129
for until_block_number in [ 1 , 10000 ] {
120
130
let mut streamer = cardano_transaction_parser
@@ -145,7 +155,7 @@ mod tests {
145
155
mock. expect_find_lower_bound ( ) . returning ( || Ok ( Some ( 0 ) ) ) ;
146
156
} ) ;
147
157
let cardano_transaction_parser =
148
- CardanoBlockScanner :: new ( TestLogger :: stdout ( ) , false , lower_bound_finder) ;
158
+ CardanoBlockScanner :: new ( TestLogger :: stdout ( ) , false , lower_bound_finder, None ) ;
149
159
150
160
for until_block_number in [ 1 , 10000 ] {
151
161
let mut streamer = cardano_transaction_parser
@@ -172,16 +182,20 @@ mod tests {
172
182
let db_path = Path :: new ( "../mithril-test-lab/test_data/immutable/" ) ;
173
183
assert ! ( get_number_of_immutable_chunk_in_dir( db_path) >= 3 ) ;
174
184
175
- let test_cases = [ ( 0 , None ) , ( 1 , Some ( 1 ) ) ] ;
176
- for ( expected, lowest_found_immutable) in test_cases {
185
+ let test_cases = [
186
+ ( None , 0 ) ,
187
+ // When a lowest immutable file number is found we start from the next immutable (i + 1)
188
+ ( Some ( 1 ) , 2 ) ,
189
+ ] ;
190
+ for ( lowest_found_immutable, expected) in test_cases {
177
191
let lower_bound_finder = lower_bound_finder ( |mock| {
178
192
mock. expect_find_lower_bound ( )
179
193
. return_once ( move || Ok ( lowest_found_immutable) ) ;
180
194
} ) ;
181
195
182
196
let from = ChainPoint :: dummy ( ) ;
183
197
let cardano_transaction_parser =
184
- CardanoBlockScanner :: new ( TestLogger :: stdout ( ) , false , lower_bound_finder) ;
198
+ CardanoBlockScanner :: new ( TestLogger :: stdout ( ) , false , lower_bound_finder, None ) ;
185
199
186
200
let mut streamer = cardano_transaction_parser
187
201
. scan ( db_path, Some ( from) , 10000000 )
@@ -211,6 +225,7 @@ mod tests {
211
225
TestLogger :: file ( & log_path) ,
212
226
true ,
213
227
lower_bound_finder ( |_| { } ) ,
228
+ None ,
214
229
) ;
215
230
}
216
231
@@ -232,10 +247,42 @@ mod tests {
232
247
TestLogger :: file ( & log_path) ,
233
248
false ,
234
249
lower_bound_finder ( |_| { } ) ,
250
+ None ,
235
251
) ;
236
252
}
237
253
238
254
let log_file = std:: fs:: read_to_string ( & log_path) . unwrap ( ) ;
239
255
assert ! ( !log_file. contains( "The 'allow_unparsable_block' option is activated. This option should only be used on test networks." ) ) ;
240
256
}
257
+
258
+ #[ tokio:: test]
259
+ async fn change_parsed_lower_bound_when_rescan_limit_is_set ( ) {
260
+ fn scanner_with_offset (
261
+ highest_stored_immutable : ImmutableFileNumber ,
262
+ rescan_offset : ImmutableFileNumber ,
263
+ ) -> CardanoBlockScanner {
264
+ let mut store = MockImmutableLowerBoundFinder :: new ( ) ;
265
+ store
266
+ . expect_find_lower_bound ( )
267
+ . returning ( move || Ok ( Some ( highest_stored_immutable) ) ) ;
268
+
269
+ CardanoBlockScanner :: new (
270
+ TestLogger :: stdout ( ) ,
271
+ false ,
272
+ Arc :: new ( store) ,
273
+ Some ( rescan_offset as usize ) ,
274
+ )
275
+ }
276
+ let scanner = scanner_with_offset ( 8 , 3 ) ;
277
+
278
+ let from = scanner. get_lower_bound ( ) . await . unwrap ( ) ;
279
+ // Expected should be: highest_stored_beacon + 1 - rescan_offset
280
+ assert_eq ! ( Some ( 6 ) , from) ;
281
+
282
+ let scanner = scanner_with_offset ( 5 , 10 ) ;
283
+
284
+ let from = scanner. get_lower_bound ( ) . await . unwrap ( ) ;
285
+ // If sub overflow it should be 0
286
+ assert_eq ! ( Some ( 0 ) , from) ;
287
+ }
241
288
}
0 commit comments