@@ -8,28 +8,32 @@ import {
88 getBlockHeaderData ,
99 getBlockHeaderDataBatch ,
1010 getBlocksDataFilePath ,
11+ getReorgBlockHeaderData ,
12+ getReorgBlockHeaderDataBatch ,
1113 Reverter ,
1214} from "@test-helpers" ;
1315
14- import { BlockHeaderMock , SPVContractMock } from "@ethers-v6" ;
16+ import { SPVContractMock } from "@ethers-v6" ;
1517
1618describe ( "SPVContract" , ( ) => {
1719 const reverter = new Reverter ( ) ;
1820
1921 let spvContract : SPVContractMock ;
20- let blockHeaderLib : BlockHeaderMock ;
2122
2223 let genesisBlockDataFilePath : string ;
24+ let regtestGenesisBlockDataFilePath : string ;
2325 let firstBlocksDataFilePath : string ;
2426 let newestBlocksDataFilePath : string ;
27+ let reorgBlocksDataFilePath : string ;
2528
2629 before ( async ( ) => {
2730 spvContract = await ethers . deployContract ( "SPVContractMock" ) ;
28- blockHeaderLib = await ethers . deployContract ( "BlockHeaderMock" ) ;
2931
3032 genesisBlockDataFilePath = getBlocksDataFilePath ( "genesis_block.json" ) ;
33+ regtestGenesisBlockDataFilePath = getBlocksDataFilePath ( "regtest_genesis_block.json" ) ;
3134 firstBlocksDataFilePath = getBlocksDataFilePath ( "headers_1_10000.json" ) ;
3235 newestBlocksDataFilePath = getBlocksDataFilePath ( "headers_800352_815000.json" ) ;
36+ reorgBlocksDataFilePath = getBlocksDataFilePath ( "headers_16_18_reorg.json" ) ;
3337
3438 await reverter . snapshot ( ) ;
3539 } ) ;
@@ -298,6 +302,61 @@ describe("SPVContract", () => {
298302 }
299303 } ) ;
300304
305+ it ( "should correctly update mainchain with the longest chain" , async ( ) => {
306+ const genesisData = getBlockHeaderData ( regtestGenesisBlockDataFilePath , 0 ) ;
307+
308+ await spvContract . __SPVContractMock_init ( genesisData . rawHeader ) ;
309+
310+ const mainchainBlocks = getReorgBlockHeaderDataBatch ( reorgBlocksDataFilePath , 1 , 15 ) ;
311+ const rawHeaders = mainchainBlocks . map ( ( blockData ) => blockData . rawHeader ) ;
312+
313+ await spvContract . addBlockHeaderBatch ( rawHeaders ) ;
314+
315+ const altBlock = getReorgBlockHeaderData ( reorgBlocksDataFilePath , 16 , false ) ;
316+
317+ let tx = await spvContract . addBlockHeader ( altBlock . rawHeader ) ;
318+
319+ let expectedCurrentBlockHeight = 16 ;
320+
321+ await expect ( tx )
322+ . to . emit ( spvContract , "MainchainHeadUpdated" )
323+ . withArgs ( expectedCurrentBlockHeight , altBlock . blockHash ) ;
324+ expect ( await spvContract . getMainchainHead ( ) ) . to . be . eq ( altBlock . blockHash ) ;
325+
326+ const newMainchainBlocks = getReorgBlockHeaderDataBatch ( reorgBlocksDataFilePath , 16 , 2 ) ;
327+ const newRawHeaders = newMainchainBlocks . map ( ( blockData ) => blockData . rawHeader ) ;
328+
329+ tx = await spvContract . addBlockHeaderBatch ( newRawHeaders ) ;
330+
331+ expectedCurrentBlockHeight = 17 ;
332+ const expectedMainchainHead = newMainchainBlocks [ 1 ] ;
333+
334+ await expect ( tx )
335+ . to . emit ( spvContract , "MainchainHeadUpdated" )
336+ . withArgs ( expectedCurrentBlockHeight , expectedMainchainHead . blockHash ) ;
337+ expect ( await spvContract . getMainchainHead ( ) ) . to . be . eq ( expectedMainchainHead . blockHash ) ;
338+ expect ( await spvContract . isInMainchain ( altBlock . blockHash ) ) . to . be . false ;
339+ } ) ;
340+
341+ it ( "should correctly add alternative block without mainchain update" , async ( ) => {
342+ const genesisData = getBlockHeaderData ( regtestGenesisBlockDataFilePath , 0 ) ;
343+
344+ await spvContract . __SPVContractMock_init ( genesisData . rawHeader ) ;
345+
346+ const mainchainBlocks = getReorgBlockHeaderDataBatch ( reorgBlocksDataFilePath , 1 , 21 ) ;
347+ const rawHeaders = mainchainBlocks . map ( ( blockData ) => blockData . rawHeader ) ;
348+
349+ await spvContract . addBlockHeaderBatch ( rawHeaders ) ;
350+
351+ const altBlock = getReorgBlockHeaderData ( reorgBlocksDataFilePath , 16 , false ) ;
352+
353+ const tx = await spvContract . addBlockHeader ( altBlock . rawHeader ) ;
354+
355+ await expect ( tx ) . to . not . emit ( spvContract , "MainchainHeadUpdated" ) ;
356+
357+ expect ( await spvContract . isInMainchain ( altBlock . blockHash ) ) . to . be . false ;
358+ } ) ;
359+
301360 it ( "should get exception if pass block that already exists" , async ( ) => {
302361 await spvContract [ "__SPVContract_init()" ] ( ) ;
303362
0 commit comments