@@ -75,7 +75,6 @@ func TestNewLx(t *testing.T) {
7575 mockReorgDetector ,
7676 mockEthClient ,
7777 originNetwork ,
78- false ,
7978 )
8079
8180 require .NoError (t , err )
@@ -766,3 +765,111 @@ func TestBridgeSync_GetLastRoot(t *testing.T) {
766765 require .NotEqual (t , common.Hash {}, root .Hash )
767766 })
768767}
768+
769+ func TestBridgeSync_SubscribeToSync (t * testing.T ) {
770+ const (
771+ syncBlockChunkSize = uint64 (100 )
772+ initialBlock = uint64 (0 )
773+ waitForNewBlocksPeriod = time .Second * 10
774+ retryAfterErrorPeriod = time .Second * 5
775+ maxRetryAttemptsAfterError = 3
776+ originNetwork = uint32 (1 )
777+ )
778+
779+ var (
780+ blockFinalityType = aggkittypes .SafeBlock
781+ ctx = context .Background ()
782+ dbPath = path .Join (t .TempDir (), "TestSubscribeToSync.sqlite" )
783+ bridge = common .HexToAddress ("0x1234567890abcdef1234567890abcdef12345678" )
784+ )
785+
786+ mockEthClient := mocksethclient .NewEthClienter (t )
787+ mockEthClient .EXPECT ().CallContract (mock .Anything , mock .Anything , mock .Anything ).Return (
788+ common .FromHex ("0x000000000000000000000000000000000000000000000000000000000000002a" ), nil ).Once ()
789+ mockEthClient .EXPECT ().
790+ CallContract (
791+ mock .Anything ,
792+ mock .Anything ,
793+ mock .Anything ,
794+ ).
795+ Return (common .LeftPadBytes (common .HexToAddress ("0x3c351e10" ).Bytes (), 32 ), nil ).
796+ Maybe ()
797+ mockReorgDetector := mocksbridgesync .NewReorgDetector (t )
798+
799+ mockReorgDetector .EXPECT ().Subscribe (mock .Anything ).Return (nil , nil )
800+ mockReorgDetector .EXPECT ().GetFinalizedBlockType ().Return (blockFinalityType )
801+ mockReorgDetector .EXPECT ().String ().Return ("mockReorgDetector" )
802+
803+ dbQueryTimeout := 30 * time .Second
804+
805+ bridgeSyncCfg := Config {
806+ DBPath : dbPath ,
807+ BridgeAddr : bridge ,
808+ BlockFinality : aggkittypes .LatestBlock ,
809+ SyncBlockChunkSize : syncBlockChunkSize ,
810+ InitialBlockNum : initialBlock ,
811+ WaitForNewBlocksPeriod : cfgtypes .NewDuration (waitForNewBlocksPeriod ),
812+ RetryAfterErrorPeriod : cfgtypes .NewDuration (retryAfterErrorPeriod ),
813+ MaxRetryAttemptsAfterError : maxRetryAttemptsAfterError ,
814+ RequireStorageContentCompatibility : false ,
815+ DBQueryTimeout : cfgtypes .NewDuration (dbQueryTimeout ),
816+ }
817+
818+ s , err := NewL2 (
819+ ctx ,
820+ bridgeSyncCfg ,
821+ mockReorgDetector ,
822+ mockEthClient ,
823+ originNetwork ,
824+ false ,
825+ )
826+ require .NoError (t , err )
827+
828+ t .Run ("subscribe to sync with valid parameters" , func (t * testing.T ) {
829+ subscriberID := "test-subscriber"
830+
831+ blockChan := s .SubscribeToSync (subscriberID )
832+ require .NotNil (t , blockChan )
833+
834+ // Verify the channel is not closed immediately
835+ select {
836+ case _ , ok := <- blockChan :
837+ if ! ok {
838+ t .Fatal ("channel should not be closed immediately" )
839+ }
840+ default :
841+ // Expected - no blocks available initially
842+ }
843+ })
844+
845+ t .Run ("subscribe with empty subscriber ID" , func (t * testing.T ) {
846+ subscriberID := ""
847+
848+ blockChan := s .SubscribeToSync (subscriberID )
849+ require .NotNil (t , blockChan )
850+ })
851+
852+ t .Run ("multiple subscribers" , func (t * testing.T ) {
853+ subscriber1ID := "subscriber-1"
854+ subscriber2ID := "subscriber-2"
855+
856+ blockChan1 := s .SubscribeToSync (subscriber1ID )
857+ blockChan2 := s .SubscribeToSync (subscriber2ID )
858+
859+ require .NotNil (t , blockChan1 )
860+ require .NotNil (t , blockChan2 )
861+
862+ // Channels should be different instances
863+ require .NotEqual (t , blockChan1 , blockChan2 )
864+ })
865+
866+ t .Run ("subscribe with same subscriber ID multiple times" , func (t * testing.T ) {
867+ subscriberID := "duplicate-subscriber"
868+
869+ blockChan1 := s .SubscribeToSync (subscriberID )
870+ blockChan2 := s .SubscribeToSync (subscriberID )
871+
872+ require .NotNil (t , blockChan1 )
873+ require .NotNil (t , blockChan2 )
874+ })
875+ }
0 commit comments