github.com/celestiaorg/celestia-node@v0.15.0-beta.1/nodebuilder/tests/blob_test.go (about)

     1  //go:build blob || integration
     2  
     3  package tests
     4  
     5  import (
     6  	"bytes"
     7  	"context"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/libp2p/go-libp2p/core/host"
    12  	"github.com/libp2p/go-libp2p/core/peer"
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/celestiaorg/celestia-node/blob"
    17  	"github.com/celestiaorg/celestia-node/blob/blobtest"
    18  	"github.com/celestiaorg/celestia-node/nodebuilder/node"
    19  	"github.com/celestiaorg/celestia-node/nodebuilder/tests/swamp"
    20  	"github.com/celestiaorg/celestia-node/share"
    21  )
    22  
    23  func TestBlobModule(t *testing.T) {
    24  	ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
    25  	t.Cleanup(cancel)
    26  	sw := swamp.NewSwamp(t, swamp.WithBlockTime(time.Second*1))
    27  
    28  	appBlobs0, err := blobtest.GenerateV0Blobs([]int{8, 4}, true)
    29  	require.NoError(t, err)
    30  	appBlobs1, err := blobtest.GenerateV0Blobs([]int{4}, false)
    31  	require.NoError(t, err)
    32  	blobs := make([]*blob.Blob, 0, len(appBlobs0)+len(appBlobs1))
    33  
    34  	for _, b := range append(appBlobs0, appBlobs1...) {
    35  		blob, err := blob.NewBlob(b.ShareVersion, append([]byte{b.NamespaceVersion}, b.NamespaceID...), b.Data)
    36  		require.NoError(t, err)
    37  		blobs = append(blobs, blob)
    38  	}
    39  
    40  	require.NoError(t, err)
    41  	bridge := sw.NewBridgeNode()
    42  	require.NoError(t, bridge.Start(ctx))
    43  
    44  	addrs, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(bridge.Host))
    45  	require.NoError(t, err)
    46  
    47  	fullCfg := sw.DefaultTestConfig(node.Full)
    48  	fullCfg.Header.TrustedPeers = append(fullCfg.Header.TrustedPeers, addrs[0].String())
    49  	fullNode := sw.NewNodeWithConfig(node.Full, fullCfg)
    50  	require.NoError(t, fullNode.Start(ctx))
    51  
    52  	addrsFull, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(fullNode.Host))
    53  	require.NoError(t, err)
    54  
    55  	lightCfg := sw.DefaultTestConfig(node.Light)
    56  	lightCfg.Header.TrustedPeers = append(lightCfg.Header.TrustedPeers, addrsFull[0].String())
    57  	lightNode := sw.NewNodeWithConfig(node.Light, lightCfg)
    58  	require.NoError(t, lightNode.Start(ctx))
    59  
    60  	fullClient := getAdminClient(ctx, fullNode, t)
    61  	lightClient := getAdminClient(ctx, lightNode, t)
    62  
    63  	height, err := fullClient.Blob.Submit(ctx, blobs, blob.DefaultGasPrice())
    64  	require.NoError(t, err)
    65  
    66  	_, err = fullClient.Header.WaitForHeight(ctx, height)
    67  	require.NoError(t, err)
    68  	_, err = lightClient.Header.WaitForHeight(ctx, height)
    69  	require.NoError(t, err)
    70  
    71  	var test = []struct {
    72  		name string
    73  		doFn func(t *testing.T)
    74  	}{
    75  		{
    76  			name: "Get",
    77  			doFn: func(t *testing.T) {
    78  				// https://github.com/celestiaorg/celestia-node/issues/2915
    79  				time.Sleep(time.Second)
    80  				blob1, err := fullClient.Blob.Get(ctx, height, blobs[0].Namespace(), blobs[0].Commitment)
    81  				require.NoError(t, err)
    82  				require.Equal(t, blobs[0], blob1)
    83  			},
    84  		},
    85  		{
    86  			name: "GetAll",
    87  			doFn: func(t *testing.T) {
    88  				// https://github.com/celestiaorg/celestia-node/issues/2915
    89  				time.Sleep(time.Second)
    90  				newBlobs, err := fullClient.Blob.GetAll(ctx, height, []share.Namespace{blobs[0].Namespace()})
    91  				require.NoError(t, err)
    92  				require.Len(t, newBlobs, len(appBlobs0))
    93  				require.True(t, bytes.Equal(blobs[0].Commitment, newBlobs[0].Commitment))
    94  				require.True(t, bytes.Equal(blobs[1].Commitment, newBlobs[1].Commitment))
    95  			},
    96  		},
    97  		{
    98  			name: "Included",
    99  			doFn: func(t *testing.T) {
   100  				// https://github.com/celestiaorg/celestia-node/issues/2915
   101  				time.Sleep(time.Second)
   102  				proof, err := fullClient.Blob.GetProof(ctx, height, blobs[0].Namespace(), blobs[0].Commitment)
   103  				require.NoError(t, err)
   104  
   105  				included, err := lightClient.Blob.Included(
   106  					ctx,
   107  					height,
   108  					blobs[0].Namespace(),
   109  					proof,
   110  					blobs[0].Commitment,
   111  				)
   112  				require.NoError(t, err)
   113  				require.True(t, included)
   114  			},
   115  		},
   116  		{
   117  			name: "Not Found",
   118  			doFn: func(t *testing.T) {
   119  				appBlob, err := blobtest.GenerateV0Blobs([]int{4}, false)
   120  				require.NoError(t, err)
   121  				newBlob, err := blob.NewBlob(
   122  					appBlob[0].ShareVersion,
   123  					append([]byte{appBlob[0].NamespaceVersion}, appBlob[0].NamespaceID...),
   124  					appBlob[0].Data,
   125  				)
   126  				require.NoError(t, err)
   127  
   128  				b, err := fullClient.Blob.Get(ctx, height, newBlob.Namespace(), newBlob.Commitment)
   129  				assert.Nil(t, b)
   130  				require.Error(t, err)
   131  				require.ErrorContains(t, err, blob.ErrBlobNotFound.Error())
   132  			},
   133  		},
   134  		{
   135  			name: "Submit equal blobs",
   136  			doFn: func(t *testing.T) {
   137  				appBlob, err := blobtest.GenerateV0Blobs([]int{8, 4}, true)
   138  				require.NoError(t, err)
   139  				b, err := blob.NewBlob(
   140  					appBlob[0].ShareVersion,
   141  					append([]byte{appBlob[0].NamespaceVersion}, appBlob[0].NamespaceID...),
   142  					appBlob[0].Data,
   143  				)
   144  				require.NoError(t, err)
   145  
   146  				height, err := fullClient.Blob.Submit(ctx, []*blob.Blob{b, b}, blob.DefaultGasPrice())
   147  				require.NoError(t, err)
   148  
   149  				_, err = fullClient.Header.WaitForHeight(ctx, height)
   150  				require.NoError(t, err)
   151  
   152  				b0, err := fullClient.Blob.Get(ctx, height, b.Namespace(), b.Commitment)
   153  				require.NoError(t, err)
   154  				require.Equal(t, b, b0)
   155  
   156  				// give some time to store the data,
   157  				// otherwise the test will hang on the IPLD level.
   158  				// https://github.com/celestiaorg/celestia-node/issues/2915
   159  				time.Sleep(time.Second)
   160  
   161  				proof, err := fullClient.Blob.GetProof(ctx, height, b.Namespace(), b.Commitment)
   162  				require.NoError(t, err)
   163  
   164  				included, err := fullClient.Blob.Included(ctx, height, b.Namespace(), proof, b.Commitment)
   165  				require.NoError(t, err)
   166  				require.True(t, included)
   167  			},
   168  		},
   169  		{
   170  			// This test allows to check that the blob won't be
   171  			// deduplicated if it will be sent multiple times in
   172  			// different pfbs.
   173  			name: "Submit the same blob in different pfb",
   174  			doFn: func(t *testing.T) {
   175  				h, err := fullClient.Blob.Submit(ctx, []*blob.Blob{blobs[0]}, blob.DefaultGasPrice())
   176  				require.NoError(t, err)
   177  
   178  				_, err = fullClient.Header.WaitForHeight(ctx, h)
   179  				require.NoError(t, err)
   180  
   181  				b0, err := fullClient.Blob.Get(ctx, h, blobs[0].Namespace(), blobs[0].Commitment)
   182  				require.NoError(t, err)
   183  				require.Equal(t, blobs[0], b0)
   184  
   185  				// give some time to store the data,
   186  				// otherwise the test will hang on the IPLD level.
   187  				// https://github.com/celestiaorg/celestia-node/issues/2915
   188  				time.Sleep(time.Second)
   189  
   190  				proof, err := fullClient.Blob.GetProof(ctx, h, blobs[0].Namespace(), blobs[0].Commitment)
   191  				require.NoError(t, err)
   192  
   193  				included, err := fullClient.Blob.Included(ctx, h, blobs[0].Namespace(), proof, blobs[0].Commitment)
   194  				require.NoError(t, err)
   195  				require.True(t, included)
   196  
   197  			},
   198  		},
   199  	}
   200  
   201  	for _, tt := range test {
   202  		tt := tt
   203  		t.Run(tt.name, func(t *testing.T) {
   204  			tt.doFn(t)
   205  		})
   206  	}
   207  }