@@ -265,6 +265,115 @@ fn history_sync_works() {
265265 ) ;
266266}
267267
268+ #[ test]
269+ fn history_sync_works_for_first_epoch ( ) {
270+ let genesis_block_number = Policy :: genesis_block_number ( ) ;
271+ // The minimum number of macro blocks necessary so that we have two election blocks and a few
272+ // checkpoint blocks to push.
273+ let num_macro_blocks = Policy :: batches_per_epoch ( ) as usize ;
274+
275+ // Create a blockchain to produce the macro blocks.
276+ let time = Arc :: new ( OffsetTime :: new ( ) ) ;
277+ let env = MdbxDatabase :: new_volatile ( Default :: default ( ) ) . unwrap ( ) ;
278+ let blockchain = Arc :: new ( RwLock :: new (
279+ Blockchain :: new (
280+ env,
281+ BlockchainConfig :: default ( ) ,
282+ NetworkId :: UnitAlbatross ,
283+ time,
284+ )
285+ . unwrap ( ) ,
286+ ) ) ;
287+
288+ // Create a second blockchain to push blocks to.
289+ let time = Arc :: new ( OffsetTime :: new ( ) ) ;
290+ let env2 = MdbxDatabase :: new_volatile ( Default :: default ( ) ) . unwrap ( ) ;
291+ let blockchain2 = Arc :: new ( RwLock :: new (
292+ Blockchain :: new (
293+ env2,
294+ BlockchainConfig :: default ( ) ,
295+ NetworkId :: UnitAlbatross ,
296+ time,
297+ )
298+ . unwrap ( ) ,
299+ ) ) ;
300+
301+ // Create a third blockchain to push blocks to.
302+ let time = Arc :: new ( OffsetTime :: new ( ) ) ;
303+ let env3 = MdbxDatabase :: new_volatile ( Default :: default ( ) ) . unwrap ( ) ;
304+ let blockchain3 = Arc :: new ( RwLock :: new (
305+ Blockchain :: new (
306+ env3,
307+ BlockchainConfig :: default ( ) ,
308+ NetworkId :: UnitAlbatross ,
309+ time,
310+ )
311+ . unwrap ( ) ,
312+ ) ) ;
313+
314+ // Produce the blocks on blockchain1.
315+ let producer = BlockProducer :: new ( signing_key ( ) , voting_key ( ) ) ;
316+ produce_macro_blocks ( & producer, & blockchain, num_macro_blocks) ;
317+
318+ // Get the checkpoint blocks and corresponding history tree transactions.
319+ let blockchain_rg = blockchain. read ( ) ;
320+
321+ // Get the first election block and corresponding history tree transactions.
322+ let election_txs_1 = blockchain_rg. history_store . get_epoch_transactions ( 1 , None ) ;
323+ let election_block_1 = blockchain_rg
324+ . chain_store
325+ . get_block_at (
326+ Policy :: blocks_per_epoch ( ) + genesis_block_number,
327+ true ,
328+ None ,
329+ )
330+ . unwrap ( ) ;
331+
332+ let checkpoint_block_1_2 = blockchain_rg
333+ . chain_store
334+ . get_block_at (
335+ Policy :: blocks_per_batch ( ) * 2 + genesis_block_number,
336+ true ,
337+ None ,
338+ )
339+ . unwrap ( ) ;
340+ let mut checkpoint_txs_1_2 = vec ! [ ] ;
341+
342+ for hist_tx in & election_txs_1 {
343+ if hist_tx. block_number > Policy :: blocks_per_batch ( ) * 2 + genesis_block_number {
344+ break ;
345+ }
346+ checkpoint_txs_1_2. push ( hist_tx. clone ( ) ) ;
347+ }
348+
349+ // Sync the first checkpoint to make sure it works
350+ assert_eq ! (
351+ Blockchain :: push_history_sync(
352+ blockchain2. upgradable_read( ) ,
353+ checkpoint_block_1_2,
354+ & checkpoint_txs_1_2
355+ ) ,
356+ Ok ( PushResult :: Extended )
357+ ) ;
358+ assert_eq ! (
359+ Blockchain :: push_history_sync(
360+ blockchain2. upgradable_read( ) ,
361+ election_block_1. clone( ) ,
362+ & election_txs_1
363+ ) ,
364+ Ok ( PushResult :: Extended )
365+ ) ;
366+ // Sync directly the whole first epoch
367+ assert_eq ! (
368+ Blockchain :: push_history_sync(
369+ blockchain3. upgradable_read( ) ,
370+ election_block_1,
371+ & election_txs_1
372+ ) ,
373+ Ok ( PushResult :: Extended )
374+ ) ;
375+ }
376+
268377// Tests if the history sync works when micro blocks have already been pushed in the blockchain.
269378// This basically tests if we can go from the history sync to the normal follow mode and back.
270379#[ test]
0 commit comments