From d355e43afb690c67be9d6a8b320145027b7a8d45 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Fri, 7 Jul 2023 14:12:02 -0400 Subject: [PATCH 1/8] feat(eds): FlattenedEDS, FlattenedsODS, Equals --- extendeddatasquare.go | 46 +++++++++++++++ extendeddatasquare_test.go | 117 +++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) diff --git a/extendeddatasquare.go b/extendeddatasquare.go index 1e71184..5396df2 100644 --- a/extendeddatasquare.go +++ b/extendeddatasquare.go @@ -232,3 +232,49 @@ func deepCopy(original [][]byte) [][]byte { func (eds *ExtendedDataSquare) Width() uint { return eds.width } + +// FlattenedEDS returns the extended data square as a flattened slice of bytes. +func (eds *ExtendedDataSquare) FlattenedEDS() [][]byte { + return eds.Flattened() +} + +// FlattenedODS returns the original data square as a flattened slice of bytes. +func (eds *ExtendedDataSquare) FlattenedsODS() (flattened [][]byte) { + flattened = make([][]byte, eds.originalDataWidth*eds.originalDataWidth) + for i := uint(0); i < eds.originalDataWidth; i++ { + row := eds.Row(i) + for j := uint(0); j < eds.originalDataWidth; j++ { + flattened[(i*eds.originalDataWidth)+j] = row[j] + } + } + return flattened +} + +// Equals returns true if other is equal to eds. +func (eds *ExtendedDataSquare) Equals(other *ExtendedDataSquare) bool { + if eds.originalDataWidth != other.originalDataWidth { + return false + } + if eds.codec.Name() != other.codec.Name() { + return false + } + if eds.chunkSize != other.chunkSize { + return false + } + if eds.width != other.width { + return false + } + + for rowIndex := uint(0); rowIndex < eds.Width(); rowIndex++ { + edsRow := eds.Row(rowIndex) + otherRow := other.Row(rowIndex) + + for colIndex := 0; colIndex < len(edsRow); colIndex++ { + if !bytes.Equal(edsRow[colIndex], otherRow[colIndex]) { + return false + } + } + } + + return true +} diff --git a/extendeddatasquare_test.go b/extendeddatasquare_test.go index 683d9f4..024f5f1 100644 --- a/extendeddatasquare_test.go +++ b/extendeddatasquare_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const ShardSize = 64 @@ -229,3 +230,119 @@ func genRandDS(width int) [][]byte { } return ds } + +func TestFlattenedEDS(t *testing.T) { + example := createExampleEds(t, ShardSize) + want := [][]byte{ + ones, twos, zeros, threes, + threes, fours, eights, fifteens, + twos, elevens, thirteens, fours, + zeros, thirteens, fives, eights, + } + + got := example.FlattenedEDS() + assert.Equal(t, want, got) +} + +func TestFlattenedODS(t *testing.T) { + example := createExampleEds(t, ShardSize) + want := [][]byte{ + ones, twos, + threes, fours, + } + + got := example.FlattenedsODS() + assert.Equal(t, want, got) +} + +func TestEquals(t *testing.T) { + t.Run("returns true for two equal EDS", func(t *testing.T) { + a := createExampleEds(t, ShardSize) + b := createExampleEds(t, ShardSize) + assert.True(t, a.Equals(b)) + }) + t.Run("returns false for two unequal EDS", func(t *testing.T) { + a := createExampleEds(t, ShardSize) + + type testCase struct { + name string + other *ExtendedDataSquare + } + + unequalOriginalDataWidth := createExampleEds(t, ShardSize) + unequalOriginalDataWidth.originalDataWidth = 1 + + unequalCodecs := createExampleEds(t, ShardSize) + unequalCodecs.codec = newTestCodec() + + unequalChunkSize := createExampleEds(t, ShardSize*2) + + unequalEds, err := ComputeExtendedDataSquare([][]byte{ones}, NewLeoRSCodec(), NewDefaultTree) + require.NoError(t, err) + + testCases := []testCase{ + { + name: "unequal original data width", + other: unequalOriginalDataWidth, + }, + { + name: "unequal codecs", + other: unequalCodecs, + }, + { + name: "unequal chunkSize", + other: unequalChunkSize, + }, + { + name: "unequalEds", + other: unequalEds, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + assert.False(t, a.Equals(tc.other)) + // Question: reflect.DeepEqual matches the behavior of Equals + // for all these test cases. Is it sufficient for clients to use + // reflect.DeepEqual and remove Equals from the API? + assert.False(t, reflect.DeepEqual(a, tc.other)) + }) + } + }) +} + +func createExampleEds(t *testing.T, chunkSize int) (eds *ExtendedDataSquare) { + ones := bytes.Repeat([]byte{1}, chunkSize) + twos := bytes.Repeat([]byte{2}, chunkSize) + threes := bytes.Repeat([]byte{3}, chunkSize) + fours := bytes.Repeat([]byte{4}, chunkSize) + ods := [][]byte{ + ones, twos, + threes, fours, + } + + eds, err := ComputeExtendedDataSquare(ods, NewLeoRSCodec(), NewDefaultTree) + require.NoError(t, err) + return eds +} + +func newTestCodec() Codec { + return &testCodec{} +} + +type testCodec struct{} + +func (c *testCodec) Encode(chunk [][]byte) ([][]byte, error) { + return chunk, nil +} + +func (c *testCodec) Decode(chunk [][]byte) ([][]byte, error) { + return chunk, nil +} + +func (c *testCodec) MaxChunks() int { + return 0 +} + +func (c *testCodec) Name() string { + return "testCodec" +} From 34f10843e5cc569dc3d29a4e916603aeb9a4fdf1 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Fri, 7 Jul 2023 14:29:40 -0400 Subject: [PATCH 2/8] fix: typo in FlattenedODS --- extendeddatasquare.go | 2 +- extendeddatasquare_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/extendeddatasquare.go b/extendeddatasquare.go index 5396df2..71525df 100644 --- a/extendeddatasquare.go +++ b/extendeddatasquare.go @@ -239,7 +239,7 @@ func (eds *ExtendedDataSquare) FlattenedEDS() [][]byte { } // FlattenedODS returns the original data square as a flattened slice of bytes. -func (eds *ExtendedDataSquare) FlattenedsODS() (flattened [][]byte) { +func (eds *ExtendedDataSquare) FlattenedODS() (flattened [][]byte) { flattened = make([][]byte, eds.originalDataWidth*eds.originalDataWidth) for i := uint(0); i < eds.originalDataWidth; i++ { row := eds.Row(i) diff --git a/extendeddatasquare_test.go b/extendeddatasquare_test.go index 024f5f1..f28e34b 100644 --- a/extendeddatasquare_test.go +++ b/extendeddatasquare_test.go @@ -251,7 +251,7 @@ func TestFlattenedODS(t *testing.T) { threes, fours, } - got := example.FlattenedsODS() + got := example.FlattenedODS() assert.Equal(t, want, got) } From ce6d92c9cace7b797a4208a979b42ca106a70eb2 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Mon, 10 Jul 2023 10:25:55 -0400 Subject: [PATCH 3/8] chore: remove question --- extendeddatasquare_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/extendeddatasquare_test.go b/extendeddatasquare_test.go index f0501a5..aab400c 100644 --- a/extendeddatasquare_test.go +++ b/extendeddatasquare_test.go @@ -346,9 +346,6 @@ func TestEquals(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { assert.False(t, a.Equals(tc.other)) - // Question: reflect.DeepEqual matches the behavior of Equals - // for all these test cases. Is it sufficient for clients to use - // reflect.DeepEqual and remove Equals from the API? assert.False(t, reflect.DeepEqual(a, tc.other)) }) } From b3ddfaa68b9ca9b0a2cf8d7a9f8534c03a643f04 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Mon, 10 Jul 2023 10:33:38 -0400 Subject: [PATCH 4/8] fix: lint --- codec_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codec_test.go b/codec_test.go index fcfcc5d..e6b1f49 100644 --- a/codec_test.go +++ b/codec_test.go @@ -114,6 +114,6 @@ func (c *testCodec) Name() string { return "testCodec" } -func (c *testCodec) ValidateChunkSize(chunkSize int) error { +func (c *testCodec) ValidateChunkSize(_ int) error { return nil } From 74da9a2cf48d358ff697060002a45fb843fc334d Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Tue, 11 Jul 2023 09:55:53 -0400 Subject: [PATCH 5/8] chore: rename FlattenedEDS to Flattened --- extendeddatasquare.go | 4 ++-- extendeddatasquare_test.go | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/extendeddatasquare.go b/extendeddatasquare.go index 3f79f5e..5e6af6c 100644 --- a/extendeddatasquare.go +++ b/extendeddatasquare.go @@ -275,8 +275,8 @@ func (eds *ExtendedDataSquare) Width() uint { } // FlattenedEDS returns the extended data square as a flattened slice of bytes. -func (eds *ExtendedDataSquare) FlattenedEDS() [][]byte { - return eds.Flattened() +func (eds *ExtendedDataSquare) Flattened() [][]byte { + return eds.dataSquare.Flattened() } // FlattenedODS returns the original data square as a flattened slice of bytes. diff --git a/extendeddatasquare_test.go b/extendeddatasquare_test.go index 84c366e..caccadb 100644 --- a/extendeddatasquare_test.go +++ b/extendeddatasquare_test.go @@ -293,7 +293,10 @@ func genRandDS(width int, chunkSize int) [][]byte { return ds } -func TestFlattenedEDS(t *testing.T) { +// TestFlattened_EDS tests that eds.Flattened() returns all the shares in the +// EDS. This function has the `_EDS` suffix to avoid a name collision with the +// TestFlattened. +func TestFlattened_EDS(t *testing.T) { example := createExampleEds(t, shareSize) want := [][]byte{ ones, twos, zeros, threes, @@ -302,7 +305,7 @@ func TestFlattenedEDS(t *testing.T) { zeros, thirteens, fives, eights, } - got := example.FlattenedEDS() + got := example.Flattened() assert.Equal(t, want, got) } From 5ca7f3f4c96c84bc01a373b19e80fa90fb95579a Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Wed, 12 Jul 2023 08:58:22 -0400 Subject: [PATCH 6/8] fix: godoc --- extendeddatasquare.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extendeddatasquare.go b/extendeddatasquare.go index 5e6af6c..c1a74de 100644 --- a/extendeddatasquare.go +++ b/extendeddatasquare.go @@ -274,7 +274,7 @@ func (eds *ExtendedDataSquare) Width() uint { return eds.width } -// FlattenedEDS returns the extended data square as a flattened slice of bytes. +// Flattened returns the extended data square as a flattened slice of bytes. func (eds *ExtendedDataSquare) Flattened() [][]byte { return eds.dataSquare.Flattened() } From 2b22e3aa0e303b2a240c540ea55a226f5b9f4a91 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Wed, 12 Jul 2023 11:39:59 -0400 Subject: [PATCH 7/8] chore: pluralize --- extendeddatasquare.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/extendeddatasquare.go b/extendeddatasquare.go index c1a74de..e99ac6e 100644 --- a/extendeddatasquare.go +++ b/extendeddatasquare.go @@ -274,6 +274,24 @@ func (eds *ExtendedDataSquare) Width() uint { return eds.width } +// Roots returns a byte slice with this eds's RowRoots and ColRoots +// concatenated. +func (eds *ExtendedDataSquare) Roots() (roots [][]byte, err error) { + rowRoots, err := eds.RowRoots() + if err != nil { + return nil, err + } + colRoots, err := eds.ColRoots() + if err != nil { + return nil, err + } + + roots = make([][]byte, 0, len(rowRoots)+len(colRoots)) + roots = append(roots, rowRoots...) + roots = append(roots, colRoots...) + return roots, nil +} + // Flattened returns the extended data square as a flattened slice of bytes. func (eds *ExtendedDataSquare) Flattened() [][]byte { return eds.dataSquare.Flattened() From 8e824027e7ad8e45d72781b2bcdc7ff1468e8a58 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Wed, 12 Jul 2023 11:41:04 -0400 Subject: [PATCH 8/8] Revert "chore: pluralize" This reverts commit 2b22e3aa0e303b2a240c540ea55a226f5b9f4a91. --- extendeddatasquare.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/extendeddatasquare.go b/extendeddatasquare.go index e99ac6e..c1a74de 100644 --- a/extendeddatasquare.go +++ b/extendeddatasquare.go @@ -274,24 +274,6 @@ func (eds *ExtendedDataSquare) Width() uint { return eds.width } -// Roots returns a byte slice with this eds's RowRoots and ColRoots -// concatenated. -func (eds *ExtendedDataSquare) Roots() (roots [][]byte, err error) { - rowRoots, err := eds.RowRoots() - if err != nil { - return nil, err - } - colRoots, err := eds.ColRoots() - if err != nil { - return nil, err - } - - roots = make([][]byte, 0, len(rowRoots)+len(colRoots)) - roots = append(roots, rowRoots...) - roots = append(roots, colRoots...) - return roots, nil -} - // Flattened returns the extended data square as a flattened slice of bytes. func (eds *ExtendedDataSquare) Flattened() [][]byte { return eds.dataSquare.Flattened()