@@ -523,3 +523,226 @@ func TestClient_Retrieve_Timeout(t *testing.T) {
523523 assert .Assert (t , result .Message != "" )
524524 })
525525}
526+
527+ func TestClient_RetrieveHeaders (t * testing.T ) {
528+ logger := zerolog .Nop ()
529+ dataLayerHeight := uint64 (100 )
530+ mockIDs := [][]byte {[]byte ("id1" )}
531+ mockBlobs := [][]byte {[]byte ("header-blob" )}
532+ mockTimestamp := time .Now ()
533+
534+ mockDAInstance := & mockDA {
535+ getIDsFunc : func (ctx context.Context , height uint64 , namespace []byte ) (* coreda.GetIDsResult , error ) {
536+ return & coreda.GetIDsResult {
537+ IDs : mockIDs ,
538+ Timestamp : mockTimestamp ,
539+ }, nil
540+ },
541+ getFunc : func (ctx context.Context , ids []coreda.ID , namespace []byte ) ([]coreda.Blob , error ) {
542+ return mockBlobs , nil
543+ },
544+ }
545+
546+ client := NewClient (Config {
547+ DA : mockDAInstance ,
548+ Logger : logger ,
549+ Namespace : "test-header-ns" ,
550+ DataNamespace : "test-data-ns" ,
551+ })
552+
553+ result := client .RetrieveHeaders (context .Background (), dataLayerHeight )
554+
555+ assert .Equal (t , coreda .StatusSuccess , result .Code )
556+ assert .Equal (t , dataLayerHeight , result .Height )
557+ assert .Equal (t , len (mockBlobs ), len (result .Data ))
558+ }
559+
560+ func TestClient_RetrieveData (t * testing.T ) {
561+ logger := zerolog .Nop ()
562+ dataLayerHeight := uint64 (200 )
563+ mockIDs := [][]byte {[]byte ("id1" ), []byte ("id2" )}
564+ mockBlobs := [][]byte {[]byte ("data-blob-1" ), []byte ("data-blob-2" )}
565+ mockTimestamp := time .Now ()
566+
567+ mockDAInstance := & mockDA {
568+ getIDsFunc : func (ctx context.Context , height uint64 , namespace []byte ) (* coreda.GetIDsResult , error ) {
569+ return & coreda.GetIDsResult {
570+ IDs : mockIDs ,
571+ Timestamp : mockTimestamp ,
572+ }, nil
573+ },
574+ getFunc : func (ctx context.Context , ids []coreda.ID , namespace []byte ) ([]coreda.Blob , error ) {
575+ return mockBlobs , nil
576+ },
577+ }
578+
579+ client := NewClient (Config {
580+ DA : mockDAInstance ,
581+ Logger : logger ,
582+ Namespace : "test-header-ns" ,
583+ DataNamespace : "test-data-ns" ,
584+ })
585+
586+ result := client .RetrieveData (context .Background (), dataLayerHeight )
587+
588+ assert .Equal (t , coreda .StatusSuccess , result .Code )
589+ assert .Equal (t , dataLayerHeight , result .Height )
590+ assert .Equal (t , len (mockBlobs ), len (result .Data ))
591+ }
592+
593+ func TestClient_RetrieveBatched (t * testing.T ) {
594+ logger := zerolog .Nop ()
595+ dataLayerHeight := uint64 (100 )
596+
597+ // Create 200 IDs to exceed default batch size
598+ numIDs := 200
599+ mockIDs := make ([][]byte , numIDs )
600+ for i := range numIDs {
601+ mockIDs [i ] = []byte {byte (i )}
602+ }
603+
604+ // Track which batches were requested
605+ batchCalls := []int {}
606+
607+ mockDAInstance := & mockDA {
608+ getIDsFunc : func (ctx context.Context , height uint64 , namespace []byte ) (* coreda.GetIDsResult , error ) {
609+ return & coreda.GetIDsResult {
610+ IDs : mockIDs ,
611+ Timestamp : time .Now (),
612+ }, nil
613+ },
614+ getFunc : func (ctx context.Context , ids []coreda.ID , namespace []byte ) ([]coreda.Blob , error ) {
615+ batchCalls = append (batchCalls , len (ids ))
616+ // Return a blob for each ID in the batch
617+ blobs := make ([][]byte , len (ids ))
618+ for i := range ids {
619+ blobs [i ] = []byte ("blob" )
620+ }
621+ return blobs , nil
622+ },
623+ }
624+
625+ client := NewClient (Config {
626+ DA : mockDAInstance ,
627+ Logger : logger ,
628+ Namespace : "test-ns" ,
629+ DataNamespace : "test-data-ns" ,
630+ RetrieveBatchSize : 50 , // Set smaller batch size for testing
631+ })
632+
633+ encodedNamespace := coreda .NamespaceFromString ("test-ns" )
634+ result := client .Retrieve (context .Background (), dataLayerHeight , encodedNamespace .Bytes ())
635+
636+ assert .Equal (t , coreda .StatusSuccess , result .Code )
637+ assert .Equal (t , numIDs , len (result .Data ))
638+
639+ // Should have made 4 batches: 50 + 50 + 50 + 50 = 200
640+ assert .Equal (t , 4 , len (batchCalls ))
641+ assert .Equal (t , 50 , batchCalls [0 ])
642+ assert .Equal (t , 50 , batchCalls [1 ])
643+ assert .Equal (t , 50 , batchCalls [2 ])
644+ assert .Equal (t , 50 , batchCalls [3 ])
645+ }
646+
647+ func TestClient_RetrieveBatched_PartialBatch (t * testing.T ) {
648+ logger := zerolog .Nop ()
649+ dataLayerHeight := uint64 (100 )
650+
651+ // Create 175 IDs to test partial batch at the end
652+ numIDs := 175
653+ mockIDs := make ([][]byte , numIDs )
654+ for i := range numIDs {
655+ mockIDs [i ] = []byte {byte (i )}
656+ }
657+
658+ batchCalls := []int {}
659+
660+ mockDAInstance := & mockDA {
661+ getIDsFunc : func (ctx context.Context , height uint64 , namespace []byte ) (* coreda.GetIDsResult , error ) {
662+ return & coreda.GetIDsResult {
663+ IDs : mockIDs ,
664+ Timestamp : time .Now (),
665+ }, nil
666+ },
667+ getFunc : func (ctx context.Context , ids []coreda.ID , namespace []byte ) ([]coreda.Blob , error ) {
668+ batchCalls = append (batchCalls , len (ids ))
669+ blobs := make ([][]byte , len (ids ))
670+ for i := range ids {
671+ blobs [i ] = []byte ("blob" )
672+ }
673+ return blobs , nil
674+ },
675+ }
676+
677+ client := NewClient (Config {
678+ DA : mockDAInstance ,
679+ Logger : logger ,
680+ Namespace : "test-ns" ,
681+ DataNamespace : "test-data-ns" ,
682+ RetrieveBatchSize : 50 ,
683+ })
684+
685+ encodedNamespace := coreda .NamespaceFromString ("test-ns" )
686+ result := client .Retrieve (context .Background (), dataLayerHeight , encodedNamespace .Bytes ())
687+
688+ assert .Equal (t , coreda .StatusSuccess , result .Code )
689+ assert .Equal (t , numIDs , len (result .Data ))
690+
691+ // Should have made 4 batches: 50 + 50 + 50 + 25 = 175
692+ assert .Equal (t , 4 , len (batchCalls ))
693+ assert .Equal (t , 50 , batchCalls [0 ])
694+ assert .Equal (t , 50 , batchCalls [1 ])
695+ assert .Equal (t , 50 , batchCalls [2 ])
696+ assert .Equal (t , 25 , batchCalls [3 ]) // Partial batch
697+ }
698+
699+ func TestClient_RetrieveBatched_ErrorInSecondBatch (t * testing.T ) {
700+ logger := zerolog .Nop ()
701+ dataLayerHeight := uint64 (100 )
702+
703+ // Create 200 IDs to require multiple batches
704+ numIDs := 200
705+ mockIDs := make ([][]byte , numIDs )
706+ for i := range numIDs {
707+ mockIDs [i ] = []byte {byte (i )}
708+ }
709+
710+ batchCallCount := 0
711+
712+ mockDAInstance := & mockDA {
713+ getIDsFunc : func (ctx context.Context , height uint64 , namespace []byte ) (* coreda.GetIDsResult , error ) {
714+ return & coreda.GetIDsResult {
715+ IDs : mockIDs ,
716+ Timestamp : time .Now (),
717+ }, nil
718+ },
719+ getFunc : func (ctx context.Context , ids []coreda.ID , namespace []byte ) ([]coreda.Blob , error ) {
720+ batchCallCount ++
721+ // Fail on second batch
722+ if batchCallCount == 2 {
723+ return nil , errors .New ("network error in batch 2" )
724+ }
725+ blobs := make ([][]byte , len (ids ))
726+ for i := range ids {
727+ blobs [i ] = []byte ("blob" )
728+ }
729+ return blobs , nil
730+ },
731+ }
732+
733+ client := NewClient (Config {
734+ DA : mockDAInstance ,
735+ Logger : logger ,
736+ Namespace : "test-ns" ,
737+ DataNamespace : "test-data-ns" ,
738+ RetrieveBatchSize : 50 ,
739+ })
740+
741+ encodedNamespace := coreda .NamespaceFromString ("test-ns" )
742+ result := client .Retrieve (context .Background (), dataLayerHeight , encodedNamespace .Bytes ())
743+
744+ assert .Equal (t , coreda .StatusError , result .Code )
745+ assert .Assert (t , result .Message != "" )
746+ // Error message should mention the batch range
747+ assert .Assert (t , len (result .Message ) > 0 )
748+ }
0 commit comments