|
| 1 | +//go:build share || integration |
| 2 | + |
| 3 | +package tests |
| 4 | + |
| 5 | +import ( |
| 6 | + "context" |
| 7 | + "testing" |
| 8 | + "time" |
| 9 | + |
| 10 | + "github.com/libp2p/go-libp2p/core/host" |
| 11 | + "github.com/libp2p/go-libp2p/core/peer" |
| 12 | + "github.com/stretchr/testify/assert" |
| 13 | + "github.com/stretchr/testify/require" |
| 14 | + |
| 15 | + libshare "github.com/celestiaorg/go-square/v2/share" |
| 16 | + |
| 17 | + "github.com/celestiaorg/celestia-node/api/rpc/client" |
| 18 | + "github.com/celestiaorg/celestia-node/blob" |
| 19 | + "github.com/celestiaorg/celestia-node/nodebuilder/node" |
| 20 | + "github.com/celestiaorg/celestia-node/nodebuilder/tests/swamp" |
| 21 | + "github.com/celestiaorg/celestia-node/share/shwap" |
| 22 | + "github.com/celestiaorg/celestia-node/state" |
| 23 | +) |
| 24 | + |
| 25 | +func TestShareModule(t *testing.T) { |
| 26 | + ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second) |
| 27 | + t.Cleanup(cancel) |
| 28 | + sw := swamp.NewSwamp(t, swamp.WithBlockTime(time.Second*1)) |
| 29 | + blobSize := 128 |
| 30 | + libBlob, err := libshare.GenerateV0Blobs([]int{blobSize}, true) |
| 31 | + require.NoError(t, err) |
| 32 | + |
| 33 | + nodeBlob, err := blob.ToNodeBlobs(libBlob[0]) |
| 34 | + require.NoError(t, err) |
| 35 | + |
| 36 | + bridge := sw.NewBridgeNode() |
| 37 | + require.NoError(t, bridge.Start(ctx)) |
| 38 | + addrs, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(bridge.Host)) |
| 39 | + require.NoError(t, err) |
| 40 | + |
| 41 | + fullCfg := sw.DefaultTestConfig(node.Full) |
| 42 | + fullCfg.Header.TrustedPeers = append(fullCfg.Header.TrustedPeers, addrs[0].String()) |
| 43 | + fullNode := sw.NewNodeWithConfig(node.Full, fullCfg) |
| 44 | + require.NoError(t, fullNode.Start(ctx)) |
| 45 | + |
| 46 | + addrsFull, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(fullNode.Host)) |
| 47 | + require.NoError(t, err) |
| 48 | + |
| 49 | + lightCfg := sw.DefaultTestConfig(node.Light) |
| 50 | + lightCfg.Header.TrustedPeers = append(lightCfg.Header.TrustedPeers, addrsFull[0].String()) |
| 51 | + lightNode := sw.NewNodeWithConfig(node.Light, lightCfg) |
| 52 | + require.NoError(t, lightNode.Start(ctx)) |
| 53 | + |
| 54 | + bridgeClient := getAdminClient(ctx, bridge, t) |
| 55 | + fullClient := getAdminClient(ctx, fullNode, t) |
| 56 | + lightClient := getAdminClient(ctx, lightNode, t) |
| 57 | + |
| 58 | + height, err := fullClient.Blob.Submit(ctx, nodeBlob, state.NewTxConfig()) |
| 59 | + require.NoError(t, err) |
| 60 | + |
| 61 | + _, err = fullClient.Header.WaitForHeight(ctx, height) |
| 62 | + require.NoError(t, err) |
| 63 | + _, err = lightClient.Header.WaitForHeight(ctx, height) |
| 64 | + require.NoError(t, err) |
| 65 | + |
| 66 | + sampledBlob, err := fullClient.Blob.Get(ctx, height, nodeBlob[0].Namespace(), nodeBlob[0].Commitment) |
| 67 | + require.NoError(t, err) |
| 68 | + |
| 69 | + hdr, err := fullClient.Header.GetByHeight(ctx, height) |
| 70 | + require.NoError(t, err) |
| 71 | + |
| 72 | + coords, err := shwap.SampleCoordsFrom1DIndex(sampledBlob.Index(), len(hdr.DAH.RowRoots)) |
| 73 | + require.NoError(t, err) |
| 74 | + |
| 75 | + blobAsShares, err := blob.BlobsToShares(sampledBlob) |
| 76 | + require.NoError(t, err) |
| 77 | + // different clients allow to test different getters that are used to get the data. |
| 78 | + clients := []*client.Client{lightClient, fullClient, bridgeClient} |
| 79 | + |
| 80 | + testCases := []struct { |
| 81 | + name string |
| 82 | + doFn func(t *testing.T) |
| 83 | + }{ |
| 84 | + { |
| 85 | + name: "SharesAvailable", |
| 86 | + doFn: func(t *testing.T) { |
| 87 | + for _, client := range clients { |
| 88 | + err := client.Share.SharesAvailable(ctx, height) |
| 89 | + require.NoError(t, err) |
| 90 | + } |
| 91 | + }, |
| 92 | + }, |
| 93 | + { |
| 94 | + name: "GetShareQ1", |
| 95 | + doFn: func(t *testing.T) { |
| 96 | + for _, client := range clients { |
| 97 | + // compare the share from quadrant1 by its coordinate. |
| 98 | + // Additionally check that received share the same as the first share of the blob. |
| 99 | + sh, err := client.Share.GetShare(ctx, height, coords.Row, coords.Col) |
| 100 | + require.NoError(t, err) |
| 101 | + assert.Equal(t, blobAsShares[0], sh) |
| 102 | + } |
| 103 | + }, |
| 104 | + }, |
| 105 | + { |
| 106 | + name: "GetShareQ4", |
| 107 | + doFn: func(t *testing.T) { |
| 108 | + for _, client := range clients { |
| 109 | + _, err := client.Share.GetShare(ctx, height, len(hdr.DAH.RowRoots)-1, len(hdr.DAH.ColumnRoots)-1) |
| 110 | + require.NoError(t, err) |
| 111 | + } |
| 112 | + }, |
| 113 | + }, |
| 114 | + { |
| 115 | + name: "GetSamplesQ1", |
| 116 | + doFn: func(t *testing.T) { |
| 117 | + dah := hdr.DAH |
| 118 | + requestCoords := []shwap.SampleCoords{coords} |
| 119 | + for _, client := range clients { |
| 120 | + // request from the first quadrant using the blob coordinates. |
| 121 | + samples, err := client.Share.GetSamples(ctx, hdr, requestCoords) |
| 122 | + require.NoError(t, err) |
| 123 | + err = samples[0].Verify(dah, coords.Row, coords.Col) |
| 124 | + require.NoError(t, err) |
| 125 | + require.Equal(t, blobAsShares[0], samples[0].Share) |
| 126 | + } |
| 127 | + }, |
| 128 | + }, |
| 129 | + { |
| 130 | + name: "GetSamplesQ4", |
| 131 | + doFn: func(t *testing.T) { |
| 132 | + dah := hdr.DAH |
| 133 | + coords := shwap.SampleCoords{Row: len(dah.RowRoots) - 1, Col: len(dah.RowRoots) - 1} |
| 134 | + requestCoords := []shwap.SampleCoords{coords} |
| 135 | + for _, client := range clients { |
| 136 | + // getting the last sample from the eds(from quadrant 4). |
| 137 | + samples, err := client.Share.GetSamples(ctx, hdr, requestCoords) |
| 138 | + require.NoError(t, err) |
| 139 | + err = samples[0].Verify(dah, coords.Row, coords.Col) |
| 140 | + require.NoError(t, err) |
| 141 | + } |
| 142 | + }, |
| 143 | + }, |
| 144 | + { |
| 145 | + name: "GetEDS", |
| 146 | + doFn: func(t *testing.T) { |
| 147 | + for _, client := range clients { |
| 148 | + eds, err := client.Share.GetEDS(ctx, height) |
| 149 | + require.NoError(t, err) |
| 150 | + rawShares := eds.Row(uint(coords.Row)) |
| 151 | + sh, err := libshare.FromBytes([][]byte{rawShares[coords.Col]}) |
| 152 | + require.NoError(t, err) |
| 153 | + assert.Equal(t, blobAsShares[0], sh[0]) |
| 154 | + } |
| 155 | + }, |
| 156 | + }, |
| 157 | + { |
| 158 | + name: "GetRowQ1", |
| 159 | + doFn: func(t *testing.T) { |
| 160 | + dah := hdr.DAH |
| 161 | + for _, client := range clients { |
| 162 | + // request row from the first half of the EDS(using the blob's coordinates). |
| 163 | + row, err := client.Share.GetRow(ctx, height, coords.Row) |
| 164 | + require.NoError(t, err) |
| 165 | + // verify row against the DAH. |
| 166 | + err = row.Verify(dah, coords.Row) |
| 167 | + require.NoError(t, err) |
| 168 | + shrs, err := row.Shares() |
| 169 | + require.NoError(t, err) |
| 170 | + // additionally compare shares |
| 171 | + assert.Equal(t, blobAsShares[0], shrs[coords.Col]) |
| 172 | + } |
| 173 | + }, |
| 174 | + }, |
| 175 | + { |
| 176 | + name: "GetRowQ4", |
| 177 | + doFn: func(t *testing.T) { |
| 178 | + dah := hdr.DAH |
| 179 | + coords := shwap.SampleCoords{Row: len(dah.RowRoots) - 1, Col: len(dah.RowRoots) - 1} |
| 180 | + for _, client := range clients { |
| 181 | + // request the last row |
| 182 | + row, err := client.Share.GetRow(ctx, height, coords.Row) |
| 183 | + require.NoError(t, err) |
| 184 | + // verify against DAH |
| 185 | + err = row.Verify(dah, coords.Row) |
| 186 | + require.NoError(t, err) |
| 187 | + } |
| 188 | + }, |
| 189 | + }, |
| 190 | + { |
| 191 | + name: "GetNamespaceData", |
| 192 | + doFn: func(t *testing.T) { |
| 193 | + dah := hdr.DAH |
| 194 | + for _, client := range clients { |
| 195 | + // request data from the blob's namespace |
| 196 | + nsData, err := client.Share.GetNamespaceData(ctx, height, blobAsShares[0].Namespace()) |
| 197 | + require.NoError(t, err) |
| 198 | + |
| 199 | + // verify against the DAH |
| 200 | + err = nsData.Verify(dah, blobAsShares[0].Namespace()) |
| 201 | + require.NoError(t, err) |
| 202 | + |
| 203 | + b, err := libshare.ParseBlobs(nsData.Flatten()) |
| 204 | + require.NoError(t, err) |
| 205 | + |
| 206 | + blb, err := blob.ToNodeBlobs(b[0]) |
| 207 | + require.NoError(t, err) |
| 208 | + // compare commitments |
| 209 | + require.Equal(t, nodeBlob[0].Commitment, blb[0].Commitment) |
| 210 | + |
| 211 | + } |
| 212 | + }, |
| 213 | + }, |
| 214 | + } |
| 215 | + |
| 216 | + for _, tt := range testCases { |
| 217 | + t.Run(tt.name, func(t *testing.T) { |
| 218 | + tt.doFn(t) |
| 219 | + }) |
| 220 | + } |
| 221 | +} |
0 commit comments