From 4fa25cfe2b0c9269b2cd50b7eaf6956d2c7867cd Mon Sep 17 00:00:00 2001 From: sontrinh16 Date: Sun, 10 Dec 2023 22:56:21 +0700 Subject: [PATCH 1/3] remove nested layer for mutiple codecs --- extendeddatacrossword_test.go | 254 +++++++++++++++++----------------- 1 file changed, 128 insertions(+), 126 deletions(-) diff --git a/extendeddatacrossword_test.go b/extendeddatacrossword_test.go index 2a840fa..7e0ba45 100644 --- a/extendeddatacrossword_test.go +++ b/extendeddatacrossword_test.go @@ -24,16 +24,17 @@ type PseudoFraudProof struct { } func TestRepairExtendedDataSquare(t *testing.T) { + codec := NewLeoRSCodec() + tests := []struct { - name string - codec Codec + name string }{ - {"leopard", NewLeoRSCodec()}, + {"leopard"}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - name, codec := test.name, test.codec + name := test.name original := createTestEds(codec, shareSize) rowRoots, err := original.RowRoots() @@ -91,17 +92,18 @@ func TestRepairExtendedDataSquare(t *testing.T) { } func TestValidFraudProof(t *testing.T) { + codec := NewLeoRSCodec() + corruptChunk := bytes.Repeat([]byte{66}, shareSize) tests := []struct { - name string - codec Codec + name string }{ - {"leopard", NewLeoRSCodec()}, + {"leopard"}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - name, codec := test.name, test.codec + name := test.name original := createTestEds(codec, shareSize) var byzData *ErrByzantineData @@ -149,17 +151,18 @@ func TestValidFraudProof(t *testing.T) { } func TestCannotRepairSquareWithBadRoots(t *testing.T) { + codec := NewLeoRSCodec() + corruptChunk := bytes.Repeat([]byte{66}, shareSize) tests := []struct { - name string - codec Codec + name string }{ - {"leopard", NewLeoRSCodec()}, + {"leopard"}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - original := createTestEds(test.codec, shareSize) + original := createTestEds(codec, shareSize) rowRoots, err := original.RowRoots() require.NoError(t, err) @@ -223,104 +226,103 @@ func TestCorruptedEdsReturnsErrByzantineData(t *testing.T) { }, } - for codecName, codec := range codecs { - t.Run(codecName, func(t *testing.T) { - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - eds := createTestEds(codec, shareSize) + codec := NewLeoRSCodec() - // compute the rowRoots prior to corruption - rowRoots, err := eds.getRowRoots() - assert.NoError(t, err) + t.Run(codec.Name(), func(t *testing.T) { + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + eds := createTestEds(codec, shareSize) - // compute the colRoots prior to corruption - colRoots, err := eds.getColRoots() - assert.NoError(t, err) + // compute the rowRoots prior to corruption + rowRoots, err := eds.getRowRoots() + assert.NoError(t, err) - for i, coords := range test.coords { - x := coords[0] - y := coords[1] - eds.setCell(x, y, test.values[i]) - } + // compute the colRoots prior to corruption + colRoots, err := eds.getColRoots() + assert.NoError(t, err) - err = eds.Repair(rowRoots, colRoots) - assert.Error(t, err) + for i, coords := range test.coords { + x := coords[0] + y := coords[1] + eds.setCell(x, y, test.values[i]) + } - // due to parallelisation, the ErrByzantineData axis may be either row or col - var byzData *ErrByzantineData - assert.ErrorAs(t, err, &byzData, "did not return a ErrByzantineData for a bad col or row") - assert.NotEmpty(t, byzData.Shares) - assert.Contains(t, byzData.Shares, corruptChunk) - }) - } - }) - } + err = eds.Repair(rowRoots, colRoots) + assert.Error(t, err) + + // due to parallelisation, the ErrByzantineData axis may be either row or col + var byzData *ErrByzantineData + assert.ErrorAs(t, err, &byzData, "did not return a ErrByzantineData for a bad col or row") + assert.NotEmpty(t, byzData.Shares) + assert.Contains(t, byzData.Shares, corruptChunk) + }) + } + }) } func BenchmarkRepair(b *testing.B) { // For different ODS sizes for originalDataWidth := 4; originalDataWidth <= 512; originalDataWidth *= 2 { - for codecName, codec := range codecs { - if codec.MaxChunks() < originalDataWidth*originalDataWidth { - // Only test codecs that support this many chunks - continue - } + codec := NewLeoRSCodec() + if codec.MaxChunks() < originalDataWidth*originalDataWidth { + // Only test codecs that support this many chunks + continue + } - // Generate a new range original data square then extend it - square := genRandDS(originalDataWidth, shareSize) - eds, err := ComputeExtendedDataSquare(square, codec, NewDefaultTree) - if err != nil { - b.Error(err) - } + // Generate a new range original data square then extend it + square := genRandDS(originalDataWidth, shareSize) + eds, err := ComputeExtendedDataSquare(square, codec, NewDefaultTree) + if err != nil { + b.Error(err) + } - extendedDataWidth := originalDataWidth * 2 - rowRoots, err := eds.RowRoots() - assert.NoError(b, err) - - colRoots, err := eds.ColRoots() - assert.NoError(b, err) - - b.Run( - fmt.Sprintf( - "%s %dx%dx%d ODS", - codecName, - originalDataWidth, - originalDataWidth, - len(square[0]), - ), - func(b *testing.B) { - for n := 0; n < b.N; n++ { - b.StopTimer() - - flattened := eds.Flattened() - // Randomly remove 1/2 of the shares of each row - for r := 0; r < extendedDataWidth; r++ { - for c := 0; c < originalDataWidth; { - ind := rand.Intn(extendedDataWidth) - if flattened[r*extendedDataWidth+ind] == nil { - continue - } - flattened[r*extendedDataWidth+ind] = nil - c++ + extendedDataWidth := originalDataWidth * 2 + rowRoots, err := eds.RowRoots() + assert.NoError(b, err) + + colRoots, err := eds.ColRoots() + assert.NoError(b, err) + + b.Run( + fmt.Sprintf( + "%s %dx%dx%d ODS", + codec.Name(), + originalDataWidth, + originalDataWidth, + len(square[0]), + ), + func(b *testing.B) { + for n := 0; n < b.N; n++ { + b.StopTimer() + + flattened := eds.Flattened() + // Randomly remove 1/2 of the shares of each row + for r := 0; r < extendedDataWidth; r++ { + for c := 0; c < originalDataWidth; { + ind := rand.Intn(extendedDataWidth) + if flattened[r*extendedDataWidth+ind] == nil { + continue } + flattened[r*extendedDataWidth+ind] = nil + c++ } + } - // Re-import the data square. - eds, _ = ImportExtendedDataSquare(flattened, codec, NewDefaultTree) + // Re-import the data square. + eds, _ = ImportExtendedDataSquare(flattened, codec, NewDefaultTree) - b.StartTimer() + b.StartTimer() - err := eds.Repair( - rowRoots, - colRoots, - ) - if err != nil { - b.Error(err) - } + err := eds.Repair( + rowRoots, + colRoots, + ) + if err != nil { + b.Error(err) } - }, - ) - } + } + }, + ) } } @@ -420,41 +422,41 @@ func TestCorruptedEdsReturnsErrByzantineData_UnorderedShares(t *testing.T) { }, } - for codecName, codec := range codecs { - t.Run(codecName, func(t *testing.T) { - // create a DA header - eds := createTestEdsWithNMT(t, codec, shareSize, namespaceSize, 1, 2, 3, 4) - assert.NotNil(t, eds) - dAHeaderRoots, err := eds.getRowRoots() - assert.NoError(t, err) - - dAHeaderCols, err := eds.getColRoots() - assert.NoError(t, err) - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - // create an eds with the given shares - corruptEds := createTestEdsWithNMT(t, codec, shareSize, namespaceSize, sharesValue...) - assert.NotNil(t, corruptEds) - // corrupt it by setting the values at the given coordinates - for i, coords := range test.coords { - x := coords[0] - y := coords[1] - corruptEds.setCell(x, y, test.values[i]) - } + codec := NewLeoRSCodec() + + t.Run(codec.Name(), func(t *testing.T) { + // create a DA header + eds := createTestEdsWithNMT(t, codec, shareSize, namespaceSize, 1, 2, 3, 4) + assert.NotNil(t, eds) + dAHeaderRoots, err := eds.getRowRoots() + assert.NoError(t, err) + + dAHeaderCols, err := eds.getColRoots() + assert.NoError(t, err) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + // create an eds with the given shares + corruptEds := createTestEdsWithNMT(t, codec, shareSize, namespaceSize, sharesValue...) + assert.NotNil(t, corruptEds) + // corrupt it by setting the values at the given coordinates + for i, coords := range test.coords { + x := coords[0] + y := coords[1] + corruptEds.setCell(x, y, test.values[i]) + } - err = corruptEds.Repair(dAHeaderRoots, dAHeaderCols) - assert.Equal(t, err != nil, test.wantErr) - if test.wantErr { - var byzErr *ErrByzantineData - assert.ErrorAs(t, err, &byzErr) - errors.As(err, &byzErr) - assert.Equal(t, byzErr.Axis, test.corruptedAxis) - assert.Equal(t, byzErr.Index, test.corruptedIndex) - } - }) - } - }) - } + err = corruptEds.Repair(dAHeaderRoots, dAHeaderCols) + assert.Equal(t, err != nil, test.wantErr) + if test.wantErr { + var byzErr *ErrByzantineData + assert.ErrorAs(t, err, &byzErr) + errors.As(err, &byzErr) + assert.Equal(t, byzErr.Axis, test.corruptedAxis) + assert.Equal(t, byzErr.Index, test.corruptedIndex) + } + }) + } + }) } // createTestEdsWithNMT creates an extended data square with the given shares and namespace size. From 4975394a6964fdb28b95b18def8f6efdae68172e Mon Sep 17 00:00:00 2001 From: sontrinh16 Date: Mon, 11 Dec 2023 12:57:50 +0700 Subject: [PATCH 2/3] remove unnecessary test case --- extendeddatacrossword_test.go | 226 +++++++++++++++------------------- 1 file changed, 97 insertions(+), 129 deletions(-) diff --git a/extendeddatacrossword_test.go b/extendeddatacrossword_test.go index 7e0ba45..3cf48fa 100644 --- a/extendeddatacrossword_test.go +++ b/extendeddatacrossword_test.go @@ -25,128 +25,106 @@ type PseudoFraudProof struct { func TestRepairExtendedDataSquare(t *testing.T) { codec := NewLeoRSCodec() + original := createTestEds(codec, shareSize) - tests := []struct { - name string - }{ - {"leopard"}, - } + rowRoots, err := original.RowRoots() + require.NoError(t, err) - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - name := test.name - original := createTestEds(codec, shareSize) - - rowRoots, err := original.RowRoots() - require.NoError(t, err) - - colRoots, err := original.ColRoots() - require.NoError(t, err) - - // Verify that an EDS can be repaired after the maximum amount of erasures - t.Run("MaximumErasures", func(t *testing.T) { - flattened := original.Flattened() - flattened[0], flattened[2], flattened[3] = nil, nil, nil - flattened[4], flattened[5], flattened[6], flattened[7] = nil, nil, nil, nil - flattened[8], flattened[9], flattened[10] = nil, nil, nil - flattened[12], flattened[13] = nil, nil - - // Re-import the data square. - eds, err := ImportExtendedDataSquare(flattened, codec, NewDefaultTree) - if err != nil { - t.Errorf("ImportExtendedDataSquare failed: %v", err) - } + colRoots, err := original.ColRoots() + require.NoError(t, err) - err = eds.Repair(rowRoots, colRoots) - if err != nil { - t.Errorf("unexpected err while repairing data square: %v, codec: :%s", err, name) - } else { - assert.Equal(t, original.GetCell(0, 0), bytes.Repeat([]byte{1}, shareSize)) - assert.Equal(t, original.GetCell(0, 1), bytes.Repeat([]byte{2}, shareSize)) - assert.Equal(t, original.GetCell(1, 0), bytes.Repeat([]byte{3}, shareSize)) - assert.Equal(t, original.GetCell(1, 1), bytes.Repeat([]byte{4}, shareSize)) - } - }) + // Verify that an EDS can be repaired after the maximum amount of erasures + t.Run("MaximumErasures", func(t *testing.T) { + flattened := original.Flattened() + flattened[0], flattened[2], flattened[3] = nil, nil, nil + flattened[4], flattened[5], flattened[6], flattened[7] = nil, nil, nil, nil + flattened[8], flattened[9], flattened[10] = nil, nil, nil + flattened[12], flattened[13] = nil, nil - // Verify that an EDS returns an error when there are too many erasures - t.Run("Unrepairable", func(t *testing.T) { - flattened := original.Flattened() - flattened[0], flattened[2], flattened[3] = nil, nil, nil - flattened[4], flattened[5], flattened[6], flattened[7] = nil, nil, nil, nil - flattened[8], flattened[9], flattened[10] = nil, nil, nil - flattened[12], flattened[13], flattened[14] = nil, nil, nil - - // Re-import the data square. - eds, err := ImportExtendedDataSquare(flattened, codec, NewDefaultTree) - if err != nil { - t.Errorf("ImportExtendedDataSquare failed: %v", err) - } + // Re-import the data square. + eds, err := ImportExtendedDataSquare(flattened, codec, NewDefaultTree) + if err != nil { + t.Errorf("ImportExtendedDataSquare failed: %v", err) + } - err = eds.Repair(rowRoots, colRoots) - if err != ErrUnrepairableDataSquare { - t.Errorf("did not return an error on trying to repair an unrepairable square") - } - }) - }) - } + err = eds.Repair(rowRoots, colRoots) + if err != nil { + t.Errorf("unexpected err while repairing data square: %v, codec: :%s", err, codec.Name()) + } else { + assert.Equal(t, original.GetCell(0, 0), bytes.Repeat([]byte{1}, shareSize)) + assert.Equal(t, original.GetCell(0, 1), bytes.Repeat([]byte{2}, shareSize)) + assert.Equal(t, original.GetCell(1, 0), bytes.Repeat([]byte{3}, shareSize)) + assert.Equal(t, original.GetCell(1, 1), bytes.Repeat([]byte{4}, shareSize)) + } + }) + + // Verify that an EDS returns an error when there are too many erasures + t.Run("Unrepairable", func(t *testing.T) { + flattened := original.Flattened() + flattened[0], flattened[2], flattened[3] = nil, nil, nil + flattened[4], flattened[5], flattened[6], flattened[7] = nil, nil, nil, nil + flattened[8], flattened[9], flattened[10] = nil, nil, nil + flattened[12], flattened[13], flattened[14] = nil, nil, nil + + // Re-import the data square. + eds, err := ImportExtendedDataSquare(flattened, codec, NewDefaultTree) + if err != nil { + t.Errorf("ImportExtendedDataSquare failed: %v", err) + } + + err = eds.Repair(rowRoots, colRoots) + if err != ErrUnrepairableDataSquare { + t.Errorf("did not return an error on trying to repair an unrepairable square") + } + }) } func TestValidFraudProof(t *testing.T) { codec := NewLeoRSCodec() corruptChunk := bytes.Repeat([]byte{66}, shareSize) - tests := []struct { - name string - }{ - {"leopard"}, + + original := createTestEds(codec, shareSize) + + var byzData *ErrByzantineData + corrupted, err := original.deepCopy(codec) + if err != nil { + t.Fatalf("unexpected err while copying original data: %v, codec: :%s", err, codec.Name()) } + corrupted.setCell(0, 0, corruptChunk) + assert.NoError(t, err) - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - name := test.name - original := createTestEds(codec, shareSize) - - var byzData *ErrByzantineData - corrupted, err := original.deepCopy(codec) - if err != nil { - t.Fatalf("unexpected err while copying original data: %v, codec: :%s", err, name) - } - corrupted.setCell(0, 0, corruptChunk) - assert.NoError(t, err) - - rowRoots, err := corrupted.getRowRoots() - assert.NoError(t, err) - - colRoots, err := corrupted.getColRoots() - assert.NoError(t, err) - - err = corrupted.Repair(rowRoots, colRoots) - errors.As(err, &byzData) - - // Construct the fraud proof - fraudProof := PseudoFraudProof{0, byzData.Index, byzData.Shares} - // Verify the fraud proof - // TODO in a real fraud proof, also verify Merkle proof for each non-nil share. - rebuiltShares, err := codec.Decode(fraudProof.Shares) - if err != nil { - t.Errorf("could not decode fraud proof shares; got: %v", err) - } - root, err := corrupted.computeSharesRoot(rebuiltShares, byzData.Axis, fraudProof.Index) - assert.NoError(t, err) - rowRoot, err := corrupted.getRowRoot(fraudProof.Index) - assert.NoError(t, err) - if bytes.Equal(root, rowRoot) { - // If the roots match, then the fraud proof should be for invalid erasure coding. - parityShares, err := codec.Encode(rebuiltShares[0:corrupted.originalDataWidth]) - if err != nil { - t.Errorf("could not encode fraud proof shares; %v", fraudProof) - } - startIndex := len(rebuiltShares) - int(corrupted.originalDataWidth) - if bytes.Equal(flattenChunks(parityShares), flattenChunks(rebuiltShares[startIndex:])) { - t.Errorf("invalid fraud proof %v", fraudProof) - } - } - }) + rowRoots, err := corrupted.getRowRoots() + assert.NoError(t, err) + + colRoots, err := corrupted.getColRoots() + assert.NoError(t, err) + + err = corrupted.Repair(rowRoots, colRoots) + errors.As(err, &byzData) + + // Construct the fraud proof + fraudProof := PseudoFraudProof{0, byzData.Index, byzData.Shares} + // Verify the fraud proof + // TODO in a real fraud proof, also verify Merkle proof for each non-nil share. + rebuiltShares, err := codec.Decode(fraudProof.Shares) + if err != nil { + t.Errorf("could not decode fraud proof shares; got: %v", err) + } + root, err := corrupted.computeSharesRoot(rebuiltShares, byzData.Axis, fraudProof.Index) + assert.NoError(t, err) + rowRoot, err := corrupted.getRowRoot(fraudProof.Index) + assert.NoError(t, err) + if bytes.Equal(root, rowRoot) { + // If the roots match, then the fraud proof should be for invalid erasure coding. + parityShares, err := codec.Encode(rebuiltShares[0:corrupted.originalDataWidth]) + if err != nil { + t.Errorf("could not encode fraud proof shares; %v", fraudProof) + } + startIndex := len(rebuiltShares) - int(corrupted.originalDataWidth) + if bytes.Equal(flattenChunks(parityShares), flattenChunks(rebuiltShares[startIndex:])) { + t.Errorf("invalid fraud proof %v", fraudProof) + } } } @@ -154,29 +132,19 @@ func TestCannotRepairSquareWithBadRoots(t *testing.T) { codec := NewLeoRSCodec() corruptChunk := bytes.Repeat([]byte{66}, shareSize) - tests := []struct { - name string - }{ - {"leopard"}, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - original := createTestEds(codec, shareSize) + original := createTestEds(codec, shareSize) - rowRoots, err := original.RowRoots() - require.NoError(t, err) + rowRoots, err := original.RowRoots() + require.NoError(t, err) - colRoots, err := original.ColRoots() - require.NoError(t, err) + colRoots, err := original.ColRoots() + require.NoError(t, err) - original.setCell(0, 0, corruptChunk) - require.NoError(t, err) - err = original.Repair(rowRoots, colRoots) - if err == nil { - t.Errorf("did not return an error on trying to repair a square with bad roots") - } - }) + original.setCell(0, 0, corruptChunk) + require.NoError(t, err) + err = original.Repair(rowRoots, colRoots) + if err == nil { + t.Errorf("did not return an error on trying to repair a square with bad roots") } } From acaef392cfbcdfca40fb9b23f08564047c792554 Mon Sep 17 00:00:00 2001 From: sontrinh16 Date: Mon, 11 Dec 2023 23:39:40 +0700 Subject: [PATCH 3/3] remove t.Run --- extendeddatacrossword_test.go | 120 ++++++++++++++++------------------ 1 file changed, 58 insertions(+), 62 deletions(-) diff --git a/extendeddatacrossword_test.go b/extendeddatacrossword_test.go index 3cf48fa..6266b79 100644 --- a/extendeddatacrossword_test.go +++ b/extendeddatacrossword_test.go @@ -196,36 +196,34 @@ func TestCorruptedEdsReturnsErrByzantineData(t *testing.T) { codec := NewLeoRSCodec() - t.Run(codec.Name(), func(t *testing.T) { - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - eds := createTestEds(codec, shareSize) - - // compute the rowRoots prior to corruption - rowRoots, err := eds.getRowRoots() - assert.NoError(t, err) - - // compute the colRoots prior to corruption - colRoots, err := eds.getColRoots() - assert.NoError(t, err) - - for i, coords := range test.coords { - x := coords[0] - y := coords[1] - eds.setCell(x, y, test.values[i]) - } - - err = eds.Repair(rowRoots, colRoots) - assert.Error(t, err) - - // due to parallelisation, the ErrByzantineData axis may be either row or col - var byzData *ErrByzantineData - assert.ErrorAs(t, err, &byzData, "did not return a ErrByzantineData for a bad col or row") - assert.NotEmpty(t, byzData.Shares) - assert.Contains(t, byzData.Shares, corruptChunk) - }) - } - }) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + eds := createTestEds(codec, shareSize) + + // compute the rowRoots prior to corruption + rowRoots, err := eds.getRowRoots() + assert.NoError(t, err) + + // compute the colRoots prior to corruption + colRoots, err := eds.getColRoots() + assert.NoError(t, err) + + for i, coords := range test.coords { + x := coords[0] + y := coords[1] + eds.setCell(x, y, test.values[i]) + } + + err = eds.Repair(rowRoots, colRoots) + assert.Error(t, err) + + // due to parallelisation, the ErrByzantineData axis may be either row or col + var byzData *ErrByzantineData + assert.ErrorAs(t, err, &byzData, "did not return a ErrByzantineData for a bad col or row") + assert.NotEmpty(t, byzData.Shares) + assert.Contains(t, byzData.Shares, corruptChunk) + }) + } } func BenchmarkRepair(b *testing.B) { @@ -392,39 +390,37 @@ func TestCorruptedEdsReturnsErrByzantineData_UnorderedShares(t *testing.T) { codec := NewLeoRSCodec() - t.Run(codec.Name(), func(t *testing.T) { - // create a DA header - eds := createTestEdsWithNMT(t, codec, shareSize, namespaceSize, 1, 2, 3, 4) - assert.NotNil(t, eds) - dAHeaderRoots, err := eds.getRowRoots() - assert.NoError(t, err) - - dAHeaderCols, err := eds.getColRoots() - assert.NoError(t, err) - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - // create an eds with the given shares - corruptEds := createTestEdsWithNMT(t, codec, shareSize, namespaceSize, sharesValue...) - assert.NotNil(t, corruptEds) - // corrupt it by setting the values at the given coordinates - for i, coords := range test.coords { - x := coords[0] - y := coords[1] - corruptEds.setCell(x, y, test.values[i]) - } + // create a DA header + eds := createTestEdsWithNMT(t, codec, shareSize, namespaceSize, 1, 2, 3, 4) + assert.NotNil(t, eds) + dAHeaderRoots, err := eds.getRowRoots() + assert.NoError(t, err) - err = corruptEds.Repair(dAHeaderRoots, dAHeaderCols) - assert.Equal(t, err != nil, test.wantErr) - if test.wantErr { - var byzErr *ErrByzantineData - assert.ErrorAs(t, err, &byzErr) - errors.As(err, &byzErr) - assert.Equal(t, byzErr.Axis, test.corruptedAxis) - assert.Equal(t, byzErr.Index, test.corruptedIndex) - } - }) - } - }) + dAHeaderCols, err := eds.getColRoots() + assert.NoError(t, err) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + // create an eds with the given shares + corruptEds := createTestEdsWithNMT(t, codec, shareSize, namespaceSize, sharesValue...) + assert.NotNil(t, corruptEds) + // corrupt it by setting the values at the given coordinates + for i, coords := range test.coords { + x := coords[0] + y := coords[1] + corruptEds.setCell(x, y, test.values[i]) + } + + err = corruptEds.Repair(dAHeaderRoots, dAHeaderCols) + assert.Equal(t, err != nil, test.wantErr) + if test.wantErr { + var byzErr *ErrByzantineData + assert.ErrorAs(t, err, &byzErr) + errors.As(err, &byzErr) + assert.Equal(t, byzErr.Axis, test.corruptedAxis) + assert.Equal(t, byzErr.Index, test.corruptedIndex) + } + }) + } } // createTestEdsWithNMT creates an extended data square with the given shares and namespace size.