github.com/celestiaorg/celestia-node@v0.15.0-beta.1/share/p2p/shrexnd/exchange_test.go (about) 1 package shrexnd 2 3 import ( 4 "context" 5 "sync" 6 "testing" 7 "time" 8 9 "github.com/ipfs/go-datastore" 10 ds_sync "github.com/ipfs/go-datastore/sync" 11 libhost "github.com/libp2p/go-libp2p/core/host" 12 "github.com/libp2p/go-libp2p/core/network" 13 mocknet "github.com/libp2p/go-libp2p/p2p/net/mock" 14 "github.com/stretchr/testify/require" 15 16 "github.com/celestiaorg/celestia-node/share" 17 "github.com/celestiaorg/celestia-node/share/eds" 18 "github.com/celestiaorg/celestia-node/share/eds/edstest" 19 "github.com/celestiaorg/celestia-node/share/p2p" 20 "github.com/celestiaorg/celestia-node/share/sharetest" 21 ) 22 23 func TestExchange_RequestND_NotFound(t *testing.T) { 24 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 25 t.Cleanup(cancel) 26 edsStore, client, server := makeExchange(t) 27 require.NoError(t, edsStore.Start(ctx)) 28 require.NoError(t, server.Start(ctx)) 29 30 t.Run("CAR_not_exist", func(t *testing.T) { 31 ctx, cancel := context.WithTimeout(ctx, time.Second) 32 t.Cleanup(cancel) 33 34 root := share.Root{} 35 namespace := sharetest.RandV0Namespace() 36 _, err := client.RequestND(ctx, &root, namespace, server.host.ID()) 37 require.ErrorIs(t, err, p2p.ErrNotFound) 38 }) 39 40 t.Run("ErrNamespaceNotFound", func(t *testing.T) { 41 ctx, cancel := context.WithTimeout(ctx, time.Second) 42 t.Cleanup(cancel) 43 44 eds := edstest.RandEDS(t, 4) 45 dah, err := share.NewRoot(eds) 46 require.NoError(t, err) 47 require.NoError(t, edsStore.Put(ctx, dah.Hash(), eds)) 48 49 namespace := sharetest.RandV0Namespace() 50 emptyShares, err := client.RequestND(ctx, dah, namespace, server.host.ID()) 51 require.NoError(t, err) 52 require.Empty(t, emptyShares.Flatten()) 53 }) 54 } 55 56 func TestExchange_RequestND(t *testing.T) { 57 t.Run("ND_concurrency_limit", func(t *testing.T) { 58 net, err := mocknet.FullMeshConnected(2) 59 require.NoError(t, err) 60 61 client, err := NewClient(DefaultParameters(), net.Hosts()[0]) 62 require.NoError(t, err) 63 server, err := NewServer(DefaultParameters(), net.Hosts()[1], nil) 64 require.NoError(t, err) 65 66 require.NoError(t, server.Start(context.Background())) 67 68 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 69 t.Cleanup(cancel) 70 71 rateLimit := 2 72 wg := sync.WaitGroup{} 73 wg.Add(rateLimit) 74 75 // mockHandler will block requests on server side until test is over 76 lock := make(chan struct{}) 77 defer close(lock) 78 mockHandler := func(network.Stream) { 79 wg.Done() 80 select { 81 case <-lock: 82 case <-ctx.Done(): 83 t.Fatal("timeout") 84 } 85 } 86 middleware := p2p.NewMiddleware(rateLimit) 87 server.host.SetStreamHandler(server.protocolID, 88 middleware.RateLimitHandler(mockHandler)) 89 90 // take server concurrency slots with blocked requests 91 for i := 0; i < rateLimit; i++ { 92 go func(i int) { 93 client.RequestND(ctx, nil, sharetest.RandV0Namespace(), server.host.ID()) //nolint:errcheck 94 }(i) 95 } 96 97 // wait until all server slots are taken 98 wg.Wait() 99 _, err = client.RequestND(ctx, nil, sharetest.RandV0Namespace(), server.host.ID()) 100 require.ErrorIs(t, err, p2p.ErrRateLimited) 101 }) 102 } 103 104 func newStore(t *testing.T) *eds.Store { 105 t.Helper() 106 107 storeCfg := eds.DefaultParameters() 108 ds := ds_sync.MutexWrap(datastore.NewMapDatastore()) 109 store, err := eds.NewStore(storeCfg, t.TempDir(), ds) 110 require.NoError(t, err) 111 return store 112 } 113 114 func createMocknet(t *testing.T, amount int) []libhost.Host { 115 t.Helper() 116 117 net, err := mocknet.FullMeshConnected(amount) 118 require.NoError(t, err) 119 // get host and peer 120 return net.Hosts() 121 } 122 123 func makeExchange(t *testing.T) (*eds.Store, *Client, *Server) { 124 t.Helper() 125 store := newStore(t) 126 hosts := createMocknet(t, 2) 127 128 client, err := NewClient(DefaultParameters(), hosts[0]) 129 require.NoError(t, err) 130 server, err := NewServer(DefaultParameters(), hosts[1], store) 131 require.NoError(t, err) 132 133 return store, client, server 134 }