From c86b56da971bda203febc0dc9b7a3e5e074b6812 Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sat, 3 Feb 2024 12:31:02 -0500 Subject: [PATCH 1/2] Revert "feat!: delete `getTreeNameFromConstructorFn` (#287)" This reverts commit 5a03c152ed34eb32d190d872006c267c6a4ce752. --- extendeddatacrossword_test.go | 15 +-- extendeddatasquare.go | 30 +++--- extendeddatasquare_test.go | 172 +++++++++++++++++----------------- rsmt2d_test.go | 12 +-- testdata/edsCustomTree.json | 22 ----- tree.go | 28 ++++++ tree_test.go | 83 ++++++++++++++++ 7 files changed, 228 insertions(+), 134 deletions(-) delete mode 100644 testdata/edsCustomTree.json diff --git a/extendeddatacrossword_test.go b/extendeddatacrossword_test.go index d360f68..5b15465 100644 --- a/extendeddatacrossword_test.go +++ b/extendeddatacrossword_test.go @@ -42,7 +42,7 @@ func TestRepairExtendedDataSquare(t *testing.T) { flattened[12], flattened[13] = nil, nil // Re-import the data square. - eds, err := ImportExtendedDataSquare(flattened, codec, DefaultTreeName) + eds, err := ImportExtendedDataSquare(flattened, codec, NewDefaultTree) if err != nil { t.Errorf("ImportExtendedDataSquare failed: %v", err) } @@ -67,7 +67,7 @@ func TestRepairExtendedDataSquare(t *testing.T) { flattened[12], flattened[13], flattened[14] = nil, nil, nil // Re-import the data square. - eds, err := ImportExtendedDataSquare(flattened, codec, DefaultTreeName) + eds, err := ImportExtendedDataSquare(flattened, codec, NewDefaultTree) if err != nil { t.Errorf("ImportExtendedDataSquare failed: %v", err) } @@ -237,7 +237,7 @@ func BenchmarkRepair(b *testing.B) { // Generate a new range original data square then extend it square := genRandDS(originalDataWidth, shareSize) - eds, err := ComputeExtendedDataSquare(square, codec, DefaultTreeName) + eds, err := ComputeExtendedDataSquare(square, codec, NewDefaultTree) if err != nil { b.Error(err) } @@ -275,7 +275,7 @@ func BenchmarkRepair(b *testing.B) { } // Re-import the data square. - eds, _ = ImportExtendedDataSquare(flattened, codec, DefaultTreeName) + eds, _ = ImportExtendedDataSquare(flattened, codec, NewDefaultTree) b.StartTimer() @@ -301,7 +301,7 @@ func createTestEds(codec Codec, shareSize int) *ExtendedDataSquare { eds, err := ComputeExtendedDataSquare([][]byte{ ones, twos, threes, fours, - }, codec, DefaultTreeName) + }, codec, NewDefaultTree) if err != nil { panic(err) } @@ -443,7 +443,10 @@ func createTestEdsWithNMT(t *testing.T, codec Codec, shareSize, namespaceSize in shares[i] = bytes.Repeat([]byte{byte(shareValue)}, shareSize) } - eds, err := ComputeExtendedDataSquare(shares, codec, "testing-tree") + treeConstructorFn, err := TreeFn("testing-tree") + require.NoError(t, err) + + eds, err := ComputeExtendedDataSquare(shares, codec, treeConstructorFn) require.NoError(t, err) return eds diff --git a/extendeddatasquare.go b/extendeddatasquare.go index 99b6a75..ec58197 100644 --- a/extendeddatasquare.go +++ b/extendeddatasquare.go @@ -43,11 +43,17 @@ func (eds *ExtendedDataSquare) UnmarshalJSON(b []byte) error { return err } + var treeConstructor TreeConstructorFn if aux.Tree == "" { aux.Tree = DefaultTreeName } - importedEds, err := ImportExtendedDataSquare(aux.DataSquare, codecs[aux.Codec], aux.Tree) + treeConstructor, err = TreeFn(aux.Tree) + if err != nil { + return err + } + + importedEds, err := ImportExtendedDataSquare(aux.DataSquare, codecs[aux.Codec], treeConstructor) if err != nil { return err } @@ -60,7 +66,7 @@ func (eds *ExtendedDataSquare) UnmarshalJSON(b []byte) error { func ComputeExtendedDataSquare( data [][]byte, codec Codec, - treeName string, + treeCreatorFn TreeConstructorFn, ) (*ExtendedDataSquare, error) { if len(data) > codec.MaxChunks() { return nil, errors.New("number of chunks exceeds the maximum") @@ -72,14 +78,14 @@ func ComputeExtendedDataSquare( return nil, err } - treeCreatorFn, err := TreeFn(treeName) + ds, err := newDataSquare(data, treeCreatorFn, uint(chunkSize)) if err != nil { return nil, err } - ds, err := newDataSquare(data, treeCreatorFn, uint(chunkSize)) - if err != nil { - return nil, err + treeName := getTreeNameFromConstructorFn(treeCreatorFn) + if treeName == "" { + return nil, errors.New("tree name not found") } eds := ExtendedDataSquare{dataSquare: ds, codec: codec, treeName: treeName} @@ -95,7 +101,7 @@ func ComputeExtendedDataSquare( func ImportExtendedDataSquare( data [][]byte, codec Codec, - treeName string, + treeCreatorFn TreeConstructorFn, ) (*ExtendedDataSquare, error) { if len(data) > 4*codec.MaxChunks() { return nil, errors.New("number of chunks exceeds the maximum") @@ -107,14 +113,14 @@ func ImportExtendedDataSquare( return nil, err } - treeCreatorFn, err := TreeFn(treeName) + ds, err := newDataSquare(data, treeCreatorFn, uint(chunkSize)) if err != nil { return nil, err } - ds, err := newDataSquare(data, treeCreatorFn, uint(chunkSize)) - if err != nil { - return nil, err + treeName := getTreeNameFromConstructorFn(treeCreatorFn) + if treeName == "" { + return nil, errors.New("tree name not found") } eds := ExtendedDataSquare{dataSquare: ds, codec: codec, treeName: treeName} @@ -248,7 +254,7 @@ func (eds *ExtendedDataSquare) erasureExtendCol(codec Codec, i uint) error { } func (eds *ExtendedDataSquare) deepCopy(codec Codec) (ExtendedDataSquare, error) { - imported, err := ImportExtendedDataSquare(eds.Flattened(), codec, eds.treeName) + imported, err := ImportExtendedDataSquare(eds.Flattened(), codec, eds.createTreeFn) return *imported, err } diff --git a/extendeddatasquare_test.go b/extendeddatasquare_test.go index f4fa3cb..041aac4 100644 --- a/extendeddatasquare_test.go +++ b/extendeddatasquare_test.go @@ -3,7 +3,6 @@ package rsmt2d import ( "bytes" "crypto/rand" - _ "embed" "encoding/json" "fmt" "reflect" @@ -26,9 +25,6 @@ var ( fifteens = bytes.Repeat([]byte{15}, shareSize) ) -//go:embed testdata/edsCustomTree.json -var edsCustomTree []byte - func TestComputeExtendedDataSquare(t *testing.T) { codec := NewLeoRSCodec() @@ -63,7 +59,7 @@ func TestComputeExtendedDataSquare(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - result, err := ComputeExtendedDataSquare(tc.data, codec, DefaultTreeName) + result, err := ComputeExtendedDataSquare(tc.data, codec, NewDefaultTree) assert.NoError(t, err) assert.Equal(t, tc.want, result.squareRow) }) @@ -71,7 +67,7 @@ func TestComputeExtendedDataSquare(t *testing.T) { t.Run("returns an error if chunkSize is not a multiple of 64", func(t *testing.T) { chunk := bytes.Repeat([]byte{1}, 65) - _, err := ComputeExtendedDataSquare([][]byte{chunk}, NewLeoRSCodec(), DefaultTreeName) + _, err := ComputeExtendedDataSquare([][]byte{chunk}, NewLeoRSCodec(), NewDefaultTree) assert.Error(t, err) }) } @@ -79,95 +75,101 @@ func TestComputeExtendedDataSquare(t *testing.T) { func TestImportExtendedDataSquare(t *testing.T) { t.Run("is able to import an EDS", func(t *testing.T) { eds := createExampleEds(t, shareSize) - got, err := ImportExtendedDataSquare(eds.Flattened(), NewLeoRSCodec(), DefaultTreeName) + got, err := ImportExtendedDataSquare(eds.Flattened(), NewLeoRSCodec(), NewDefaultTree) assert.NoError(t, err) assert.Equal(t, eds.Flattened(), got.Flattened()) }) t.Run("returns an error if chunkSize is not a multiple of 64", func(t *testing.T) { chunk := bytes.Repeat([]byte{1}, 65) - _, err := ImportExtendedDataSquare([][]byte{chunk}, NewLeoRSCodec(), DefaultTreeName) + _, err := ImportExtendedDataSquare([][]byte{chunk}, NewLeoRSCodec(), NewDefaultTree) assert.Error(t, err) }) } func TestMarshalJSON(t *testing.T) { - original, err := ComputeExtendedDataSquare([][]byte{ones, twos, threes, fours}, NewLeoRSCodec(), DefaultTreeName) - require.NoError(t, err) - - edsBytes, err := original.MarshalJSON() - require.NoError(t, err) + codec := NewLeoRSCodec() + result, err := ComputeExtendedDataSquare([][]byte{ + ones, twos, + threes, fours, + }, codec, NewDefaultTree) + if err != nil { + panic(err) + } - var got ExtendedDataSquare - err = json.Unmarshal(edsBytes, &got) - require.NoError(t, err) + edsBytes, err := json.Marshal(result) + if err != nil { + t.Errorf("failed to marshal EDS: %v", err) + } - assert.Equal(t, original.dataSquare.Flattened(), got.dataSquare.Flattened()) - assert.Equal(t, original.codec.Name(), got.codec.Name()) - assert.Equal(t, original.treeName, got.treeName) + var eds ExtendedDataSquare + err = json.Unmarshal(edsBytes, &eds) + if err != nil { + t.Errorf("failed to marshal EDS: %v", err) + } + if !reflect.DeepEqual(result.squareRow, eds.squareRow) { + t.Errorf("eds not equal after json marshal/unmarshal") + } } +// TestUnmarshalJSON test the UnmarshalJSON function. func TestUnmarshalJSON(t *testing.T) { - t.Run("throws an error when unmarshaling an unregistered custom tree", func(t *testing.T) { - var eds ExtendedDataSquare - err := eds.UnmarshalJSON(edsCustomTree) - - assert.Error(t, err) - assert.Contains(t, err.Error(), "custom-tree not registered yet") - }) + treeName := "testing_unmarshalJSON_tree" + treeConstructorFn := sudoConstructorFn + err := RegisterTree(treeName, treeConstructorFn) + require.NoError(t, err) - type testCase struct { - name string - original *ExtendedDataSquare - want *ExtendedDataSquare - wantErr bool + codec := NewLeoRSCodec() + result, err := ComputeExtendedDataSquare([][]byte{ + ones, twos, + threes, fours, + }, codec, treeConstructorFn) + if err != nil { + panic(err) } - defaultEDS := exampleEds(t, DefaultTreeName) - - // The tree name is intentionally set to empty to test whether the - // Unmarshal process appropriately falls back to the default tree - defaultEDSWithoutTreeName := exampleEds(t, DefaultTreeName) - defaultEDSWithoutTreeName.treeName = "" - - customTreeName := "custom-tree" - err := RegisterTree(customTreeName, sudoConstructorFn) - require.NoError(t, err) - defer cleanUp(customTreeName) - customEDS := exampleEds(t, customTreeName) - - testCases := []testCase{ - { - name: "can unmarshal the default EDS", - original: defaultEDS, - want: defaultEDS, - wantErr: false, - }, + tests := []struct { + name string + malleate func() + expectedTreeName string + cleanUp func() + }{ { - name: "can unmarshal the default EDS even if tree name is removed", - original: defaultEDSWithoutTreeName, - want: defaultEDS, - wantErr: false, + "Tree field exists", + func() {}, + treeName, + func() { + cleanUp(treeName) + }, }, { - name: "can unmarshal an EDS with a custom tree", - original: customEDS, - want: customEDS, - wantErr: false, + "Tree field missing", + func() { + // clear the tree name value in the eds before marshal + result.treeName = "" + }, + DefaultTreeName, + func() {}, }, } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.malleate() + edsBytes, err := json.Marshal(result) + if err != nil { + t.Errorf("failed to marshal EDS: %v", err) + } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - edsBytes, err := json.Marshal(tc.original) - assert.NoError(t, err) - - var got ExtendedDataSquare - err = got.UnmarshalJSON(edsBytes) - assert.NoError(t, err) + var eds ExtendedDataSquare + err = json.Unmarshal(edsBytes, &eds) + if err != nil { + t.Errorf("failed to unmarshal EDS: %v", err) + } + if !reflect.DeepEqual(result.squareRow, eds.squareRow) { + t.Errorf("eds not equal after json marshal/unmarshal") + } + require.Equal(t, test.expectedTreeName, eds.treeName) - assert.Equal(t, tc.want.dataSquare.Flattened(), got.dataSquare.Flattened()) - assert.Equal(t, tc.want.codec.Name(), got.codec.Name()) - assert.Equal(t, tc.want.treeName, got.treeName) + test.cleanUp() }) } } @@ -223,7 +225,7 @@ func TestImmutableRoots(t *testing.T) { result, err := ComputeExtendedDataSquare([][]byte{ ones, twos, threes, fours, - }, codec, DefaultTreeName) + }, codec, NewDefaultTree) if err != nil { panic(err) } @@ -258,7 +260,7 @@ func TestEDSRowColImmutable(t *testing.T) { result, err := ComputeExtendedDataSquare([][]byte{ ones, twos, threes, fours, - }, codec, DefaultTreeName) + }, codec, NewDefaultTree) if err != nil { panic(err) } @@ -281,7 +283,7 @@ func TestRowRoots(t *testing.T) { eds, err := ComputeExtendedDataSquare([][]byte{ ones, twos, threes, fours, - }, NewLeoRSCodec(), DefaultTreeName) + }, NewLeoRSCodec(), NewDefaultTree) require.NoError(t, err) rowRoots, err := eds.RowRoots() @@ -293,7 +295,7 @@ func TestRowRoots(t *testing.T) { eds, err := ComputeExtendedDataSquare([][]byte{ ones, twos, threes, fours, - }, NewLeoRSCodec(), DefaultTreeName) + }, NewLeoRSCodec(), NewDefaultTree) require.NoError(t, err) // set a cell to nil to make the EDS incomplete @@ -309,7 +311,7 @@ func TestColRoots(t *testing.T) { eds, err := ComputeExtendedDataSquare([][]byte{ ones, twos, threes, fours, - }, NewLeoRSCodec(), DefaultTreeName) + }, NewLeoRSCodec(), NewDefaultTree) require.NoError(t, err) colRoots, err := eds.ColRoots() @@ -321,7 +323,7 @@ func TestColRoots(t *testing.T) { eds, err := ComputeExtendedDataSquare([][]byte{ ones, twos, threes, fours, - }, NewLeoRSCodec(), DefaultTreeName) + }, NewLeoRSCodec(), NewDefaultTree) require.NoError(t, err) // set a cell to nil to make the EDS incomplete @@ -351,7 +353,7 @@ func BenchmarkExtensionEncoding(b *testing.B) { fmt.Sprintf("%s %dx%dx%d ODS", codecName, i, i, len(square[0])), func(b *testing.B) { for n := 0; n < b.N; n++ { - eds, err := ComputeExtendedDataSquare(square, codec, DefaultTreeName) + eds, err := ComputeExtendedDataSquare(square, codec, NewDefaultTree) if err != nil { b.Error(err) } @@ -378,7 +380,7 @@ func BenchmarkExtensionWithRoots(b *testing.B) { fmt.Sprintf("%s %dx%dx%d ODS", codecName, i, i, len(square[0])), func(b *testing.B) { for n := 0; n < b.N; n++ { - eds, err := ComputeExtendedDataSquare(square, codec, DefaultTreeName) + eds, err := ComputeExtendedDataSquare(square, codec, NewDefaultTree) if err != nil { b.Error(err) } @@ -457,7 +459,7 @@ func TestEquals(t *testing.T) { unequalChunkSize := createExampleEds(t, shareSize*2) - unequalEds, err := ComputeExtendedDataSquare([][]byte{ones}, NewLeoRSCodec(), DefaultTreeName) + unequalEds, err := ComputeExtendedDataSquare([][]byte{ones}, NewLeoRSCodec(), NewDefaultTree) require.NoError(t, err) testCases := []testCase{ @@ -492,7 +494,7 @@ func TestRoots(t *testing.T) { eds, err := ComputeExtendedDataSquare([][]byte{ ones, twos, threes, fours, - }, NewLeoRSCodec(), DefaultTreeName) + }, NewLeoRSCodec(), NewDefaultTree) require.NoError(t, err) roots, err := eds.Roots() @@ -519,7 +521,7 @@ func TestRoots(t *testing.T) { eds, err := ComputeExtendedDataSquare([][]byte{ ones, twos, threes, fours, - }, NewLeoRSCodec(), DefaultTreeName) + }, NewLeoRSCodec(), NewDefaultTree) require.NoError(t, err) // set a cell to nil to make the EDS incomplete @@ -540,13 +542,7 @@ func createExampleEds(t *testing.T, chunkSize int) (eds *ExtendedDataSquare) { threes, fours, } - eds, err := ComputeExtendedDataSquare(ods, NewLeoRSCodec(), DefaultTreeName) - require.NoError(t, err) - return eds -} - -func exampleEds(t *testing.T, treeName string) *ExtendedDataSquare { - eds, err := ComputeExtendedDataSquare([][]byte{ones, twos, threes, fours}, NewLeoRSCodec(), treeName) + eds, err := ComputeExtendedDataSquare(ods, NewLeoRSCodec(), NewDefaultTree) require.NoError(t, err) return eds } diff --git a/rsmt2d_test.go b/rsmt2d_test.go index 2561c7e..417ee89 100644 --- a/rsmt2d_test.go +++ b/rsmt2d_test.go @@ -35,7 +35,7 @@ func TestEdsRepairRoundtripSimple(t *testing.T) { threes, fours, }, tt.codec, - rsmt2d.DefaultTreeName, + rsmt2d.NewDefaultTree, ) if err != nil { t.Errorf("ComputeExtendedDataSquare failed: %v", err) @@ -56,7 +56,7 @@ func TestEdsRepairRoundtripSimple(t *testing.T) { flattened[12], flattened[13] = nil, nil // Re-import the data square. - eds, err = rsmt2d.ImportExtendedDataSquare(flattened, tt.codec, rsmt2d.DefaultTreeName) + eds, err = rsmt2d.ImportExtendedDataSquare(flattened, tt.codec, rsmt2d.NewDefaultTree) if err != nil { t.Errorf("ImportExtendedDataSquare failed: %v", err) } @@ -97,7 +97,7 @@ func TestEdsRepairTwice(t *testing.T) { threes, fours, }, tt.codec, - rsmt2d.DefaultTreeName, + rsmt2d.NewDefaultTree, ) if err != nil { t.Errorf("ComputeExtendedDataSquare failed: %v", err) @@ -120,7 +120,7 @@ func TestEdsRepairTwice(t *testing.T) { flattened[12], flattened[13] = nil, nil // Re-import the data square. - eds, err = rsmt2d.ImportExtendedDataSquare(flattened, tt.codec, rsmt2d.DefaultTreeName) + eds, err = rsmt2d.ImportExtendedDataSquare(flattened, tt.codec, rsmt2d.NewDefaultTree) if err != nil { t.Errorf("ImportExtendedDataSquare failed: %v", err) } @@ -139,7 +139,7 @@ func TestEdsRepairTwice(t *testing.T) { copy(flattened[1], missing) // Re-import the data square. - eds, err = rsmt2d.ImportExtendedDataSquare(flattened, tt.codec, rsmt2d.DefaultTreeName) + eds, err = rsmt2d.ImportExtendedDataSquare(flattened, tt.codec, rsmt2d.NewDefaultTree) if err != nil { t.Errorf("ImportExtendedDataSquare failed: %v", err) } @@ -205,7 +205,7 @@ func createExampleEds(t *testing.T, chunkSize int) (eds *rsmt2d.ExtendedDataSqua threes, fours, } - eds, err := rsmt2d.ComputeExtendedDataSquare(ods, rsmt2d.NewLeoRSCodec(), rsmt2d.DefaultTreeName) + eds, err := rsmt2d.ComputeExtendedDataSquare(ods, rsmt2d.NewLeoRSCodec(), rsmt2d.NewDefaultTree) require.NoError(t, err) return eds } diff --git a/testdata/edsCustomTree.json b/testdata/edsCustomTree.json deleted file mode 100644 index c6a23e3..0000000 --- a/testdata/edsCustomTree.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "data_square": [ - "AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=", - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI=", - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", - "AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM=", - "AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM=", - "BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ=", - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg=", - "Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8=", - "AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI=", - "CwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCws=", - "DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0=", - "BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ=", - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", - "DQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0=", - "BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU=", - "CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg=" - ], - "codec": "Leopard", - "tree": "custom-tree" -} diff --git a/tree.go b/tree.go index 1980f15..4523469 100644 --- a/tree.go +++ b/tree.go @@ -2,6 +2,7 @@ package rsmt2d import ( "fmt" + "reflect" "sync" ) @@ -56,3 +57,30 @@ func TreeFn(treeName string) (TreeConstructorFn, error) { func removeTreeFn(treeName string) { treeFns.Delete(treeName) } + +// Get the tree name by the tree constructor function from the global map registry +// TODO: this code is temporary until all breaking changes is handle here: https://github.com/celestiaorg/rsmt2d/pull/278 +func getTreeNameFromConstructorFn(treeConstructor TreeConstructorFn) string { + key := "" + treeFns.Range(func(k, v interface{}) bool { + keyString, ok := k.(string) + if !ok { + // continue checking other key, value + return true + } + treeFn, ok := v.(TreeConstructorFn) + if !ok { + // continue checking other key, value + return true + } + + if reflect.DeepEqual(reflect.ValueOf(treeFn), reflect.ValueOf(treeConstructor)) { + key = keyString + return false + } + + return true + }) + + return key +} diff --git a/tree_test.go b/tree_test.go index 5fddf52..b5fadc3 100644 --- a/tree_test.go +++ b/tree_test.go @@ -107,6 +107,89 @@ func TestTreeFn(t *testing.T) { } } +// TestGetTreeNameFromConstructorFn tests the GetTreeNameFromConstructorFn +// function which fetches tree name by it corresponding tree constructor function. +// +// TODO: When we handle all the breaking changes track in this PR: https://github.com/celestiaorg/rsmt2d/pull/278, should remove this test +func TestGetTreeNameFromConstructorFn(t *testing.T) { + treeName := "testing_get_tree_name_tree" + treeConstructorFn := sudoConstructorFn + invalidTreeName := struct{}{} + invalidCaseTreeName := "invalid_case_tree" + invalidTreeConstructorFn := "invalid constructor fn" + + tests := []struct { + name string + treeName string + treeFn TreeConstructorFn + malleate func() + expectGetKey bool + }{ + // The tree name is successfully fetched. + { + "get successfully", + treeName, + treeConstructorFn, + func() { + err := RegisterTree(treeName, treeConstructorFn) + require.NoError(t, err) + }, + true, + }, + // Unable to fetch an unregistered tree name. + { + "get unregisted tree name", + "unregisted_tree_name", + nil, + func() {}, + false, + }, + // Value (tree constructor function) from the global map iteration is an invalid + // value that cannot be type asserted into TreeConstructorFn type. + { + "get invalid interface value", + "", + nil, + func() { + // Seems like this case has low probability of happening + // since all register has been done through RegisterTree func + // which have strict type check as argument. + treeFns.Store(invalidCaseTreeName, invalidTreeConstructorFn) + }, + false, + }, + // Key (tree name) from the global map iteration is an invalid value that cannot + // be type asserted into string type. + { + "get invalid interface key", + "", + nil, + func() { + // Seems like this case has low probability of happening + // since all register has been done through RegisterTree func + // which have strict type check as argument. + treeFns.Store(invalidTreeName, treeConstructorFn) + }, + false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + test.malleate() + + key := getTreeNameFromConstructorFn(test.treeFn) + if !test.expectGetKey { + require.Equal(t, key, "") + } else { + require.Equal(t, test.treeName, key) + } + }) + + cleanUp(test.treeName) + } +} + // Avoid duplicate with default_tree treeConstructorFn // registered during init. func sudoConstructorFn(_ Axis, _ uint) Tree { From eaac7265dd86a5cb63259f8d46da4d766f30aaac Mon Sep 17 00:00:00 2001 From: Rootul Patel Date: Sat, 3 Feb 2024 12:31:24 -0500 Subject: [PATCH 2/2] Revert "fix!: UnmarshalJSON is limited to the default Tree bug (#277)" This reverts commit bb5e119c2e8571fc8eb7aff3b6bca4915ffb4b18. --- default_tree.go | 48 -------- extendeddatacrossword_test.go | 13 +-- extendeddatasquare.go | 36 +----- extendeddatasquare_test.go | 63 ----------- tree.go | 78 ++++--------- tree_test.go | 202 ---------------------------------- 6 files changed, 30 insertions(+), 410 deletions(-) delete mode 100644 default_tree.go delete mode 100644 tree_test.go diff --git a/default_tree.go b/default_tree.go deleted file mode 100644 index deb9224..0000000 --- a/default_tree.go +++ /dev/null @@ -1,48 +0,0 @@ -package rsmt2d - -import ( - "crypto/sha256" - "fmt" - - "github.com/celestiaorg/merkletree" -) - -var DefaultTreeName = "default-tree" - -func init() { - err := RegisterTree(DefaultTreeName, NewDefaultTree) - if err != nil { - panic(fmt.Sprintf("%s already registered", DefaultTreeName)) - } -} - -var _ Tree = &DefaultTree{} - -type DefaultTree struct { - *merkletree.Tree - leaves [][]byte - root []byte -} - -func NewDefaultTree(_ Axis, _ uint) Tree { - return &DefaultTree{ - Tree: merkletree.New(sha256.New()), - leaves: make([][]byte, 0, 128), - } -} - -func (d *DefaultTree) Push(data []byte) error { - // ignore the idx, as this implementation doesn't need that info - d.leaves = append(d.leaves, data) - return nil -} - -func (d *DefaultTree) Root() ([]byte, error) { - if d.root == nil { - for _, l := range d.leaves { - d.Tree.Push(l) - } - d.root = d.Tree.Root() - } - return d.root, nil -} diff --git a/extendeddatacrossword_test.go b/extendeddatacrossword_test.go index 5b15465..6266b79 100644 --- a/extendeddatacrossword_test.go +++ b/extendeddatacrossword_test.go @@ -390,14 +390,8 @@ func TestCorruptedEdsReturnsErrByzantineData_UnorderedShares(t *testing.T) { codec := NewLeoRSCodec() - edsWidth := 4 // number of shares per row/column in the extended data square - odsWidth := edsWidth / 2 // number of shares per row/column in the original data square - err := RegisterTree("testing-tree", newConstructor(uint64(odsWidth), nmt.NamespaceIDSize(namespaceSize))) - assert.NoError(t, err) - // 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) @@ -442,11 +436,10 @@ func createTestEdsWithNMT(t *testing.T, codec Codec, shareSize, namespaceSize in for i, shareValue := range sharesValue { shares[i] = bytes.Repeat([]byte{byte(shareValue)}, shareSize) } + edsWidth := 4 // number of shares per row/column in the extended data square + odsWidth := edsWidth / 2 // number of shares per row/column in the original data square - treeConstructorFn, err := TreeFn("testing-tree") - require.NoError(t, err) - - eds, err := ComputeExtendedDataSquare(shares, codec, treeConstructorFn) + eds, err := ComputeExtendedDataSquare(shares, codec, newConstructor(uint64(odsWidth), nmt.NamespaceIDSize(namespaceSize))) require.NoError(t, err) return eds diff --git a/extendeddatasquare.go b/extendeddatasquare.go index ec58197..d076dd1 100644 --- a/extendeddatasquare.go +++ b/extendeddatasquare.go @@ -15,7 +15,6 @@ import ( type ExtendedDataSquare struct { *dataSquare codec Codec - treeName string originalDataWidth uint } @@ -23,11 +22,9 @@ func (eds *ExtendedDataSquare) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { DataSquare [][]byte `json:"data_square"` Codec string `json:"codec"` - Tree string `json:"tree"` }{ DataSquare: eds.dataSquare.Flattened(), Codec: eds.codec.Name(), - Tree: eds.treeName, }) } @@ -35,25 +32,12 @@ func (eds *ExtendedDataSquare) UnmarshalJSON(b []byte) error { var aux struct { DataSquare [][]byte `json:"data_square"` Codec string `json:"codec"` - Tree string `json:"tree"` } - err := json.Unmarshal(b, &aux) - if err != nil { - return err - } - - var treeConstructor TreeConstructorFn - if aux.Tree == "" { - aux.Tree = DefaultTreeName - } - - treeConstructor, err = TreeFn(aux.Tree) - if err != nil { + if err := json.Unmarshal(b, &aux); err != nil { return err } - - importedEds, err := ImportExtendedDataSquare(aux.DataSquare, codecs[aux.Codec], treeConstructor) + importedEds, err := ImportExtendedDataSquare(aux.DataSquare, codecs[aux.Codec], NewDefaultTree) if err != nil { return err } @@ -77,18 +61,12 @@ func ComputeExtendedDataSquare( if err != nil { return nil, err } - ds, err := newDataSquare(data, treeCreatorFn, uint(chunkSize)) if err != nil { return nil, err } - treeName := getTreeNameFromConstructorFn(treeCreatorFn) - if treeName == "" { - return nil, errors.New("tree name not found") - } - - eds := ExtendedDataSquare{dataSquare: ds, codec: codec, treeName: treeName} + eds := ExtendedDataSquare{dataSquare: ds, codec: codec} err = eds.erasureExtendSquare(codec) if err != nil { return nil, err @@ -112,18 +90,12 @@ func ImportExtendedDataSquare( if err != nil { return nil, err } - ds, err := newDataSquare(data, treeCreatorFn, uint(chunkSize)) if err != nil { return nil, err } - treeName := getTreeNameFromConstructorFn(treeCreatorFn) - if treeName == "" { - return nil, errors.New("tree name not found") - } - - eds := ExtendedDataSquare{dataSquare: ds, codec: codec, treeName: treeName} + eds := ExtendedDataSquare{dataSquare: ds, codec: codec} err = validateEdsWidth(eds.width) if err != nil { return nil, err diff --git a/extendeddatasquare_test.go b/extendeddatasquare_test.go index 041aac4..057e78f 100644 --- a/extendeddatasquare_test.go +++ b/extendeddatasquare_test.go @@ -111,69 +111,6 @@ func TestMarshalJSON(t *testing.T) { } } -// TestUnmarshalJSON test the UnmarshalJSON function. -func TestUnmarshalJSON(t *testing.T) { - treeName := "testing_unmarshalJSON_tree" - treeConstructorFn := sudoConstructorFn - err := RegisterTree(treeName, treeConstructorFn) - require.NoError(t, err) - - codec := NewLeoRSCodec() - result, err := ComputeExtendedDataSquare([][]byte{ - ones, twos, - threes, fours, - }, codec, treeConstructorFn) - if err != nil { - panic(err) - } - - tests := []struct { - name string - malleate func() - expectedTreeName string - cleanUp func() - }{ - { - "Tree field exists", - func() {}, - treeName, - func() { - cleanUp(treeName) - }, - }, - { - "Tree field missing", - func() { - // clear the tree name value in the eds before marshal - result.treeName = "" - }, - DefaultTreeName, - func() {}, - }, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - test.malleate() - edsBytes, err := json.Marshal(result) - if err != nil { - t.Errorf("failed to marshal EDS: %v", err) - } - - var eds ExtendedDataSquare - err = json.Unmarshal(edsBytes, &eds) - if err != nil { - t.Errorf("failed to unmarshal EDS: %v", err) - } - if !reflect.DeepEqual(result.squareRow, eds.squareRow) { - t.Errorf("eds not equal after json marshal/unmarshal") - } - require.Equal(t, test.expectedTreeName, eds.treeName) - - test.cleanUp() - }) - } -} - func TestNewExtendedDataSquare(t *testing.T) { t.Run("returns an error if edsWidth is not even", func(t *testing.T) { edsWidth := uint(1) diff --git a/tree.go b/tree.go index 4523469..f8dcc66 100644 --- a/tree.go +++ b/tree.go @@ -1,9 +1,9 @@ package rsmt2d import ( - "fmt" - "reflect" - "sync" + "crypto/sha256" + + "github.com/celestiaorg/merkletree" ) // TreeConstructorFn creates a fresh Tree instance to be used as the Merkle tree @@ -22,65 +22,33 @@ type Tree interface { Root() ([]byte, error) } -// treeFns is a global map used for keeping track of registered tree constructors for JSON serialization -// The keys of this map should be kebab cased. E.g. "default-tree" -var treeFns = sync.Map{} - -// RegisterTree must be called in the init function -func RegisterTree(treeName string, treeConstructor TreeConstructorFn) error { - if _, ok := treeFns.Load(treeName); ok { - return fmt.Errorf("%s already registered", treeName) - } - - treeFns.Store(treeName, treeConstructor) +var _ Tree = &DefaultTree{} - return nil +type DefaultTree struct { + *merkletree.Tree + leaves [][]byte + root []byte } -// TreeFn get tree constructor function by tree name from the global map registry -func TreeFn(treeName string) (TreeConstructorFn, error) { - var treeFn TreeConstructorFn - v, ok := treeFns.Load(treeName) - if !ok { - return nil, fmt.Errorf("%s not registered yet", treeName) - } - treeFn, ok = v.(TreeConstructorFn) - if !ok { - return nil, fmt.Errorf("key %s has invalid interface", treeName) +func NewDefaultTree(_ Axis, _ uint) Tree { + return &DefaultTree{ + Tree: merkletree.New(sha256.New()), + leaves: make([][]byte, 0, 128), } - - return treeFn, nil } -// removeTreeFn removes a treeConstructorFn by treeName. -// Only use for test cleanup. Proceed with caution. -func removeTreeFn(treeName string) { - treeFns.Delete(treeName) +func (d *DefaultTree) Push(data []byte) error { + // ignore the idx, as this implementation doesn't need that info + d.leaves = append(d.leaves, data) + return nil } -// Get the tree name by the tree constructor function from the global map registry -// TODO: this code is temporary until all breaking changes is handle here: https://github.com/celestiaorg/rsmt2d/pull/278 -func getTreeNameFromConstructorFn(treeConstructor TreeConstructorFn) string { - key := "" - treeFns.Range(func(k, v interface{}) bool { - keyString, ok := k.(string) - if !ok { - // continue checking other key, value - return true - } - treeFn, ok := v.(TreeConstructorFn) - if !ok { - // continue checking other key, value - return true - } - - if reflect.DeepEqual(reflect.ValueOf(treeFn), reflect.ValueOf(treeConstructor)) { - key = keyString - return false +func (d *DefaultTree) Root() ([]byte, error) { + if d.root == nil { + for _, l := range d.leaves { + d.Tree.Push(l) } - - return true - }) - - return key + d.root = d.Tree.Root() + } + return d.root, nil } diff --git a/tree_test.go b/tree_test.go deleted file mode 100644 index b5fadc3..0000000 --- a/tree_test.go +++ /dev/null @@ -1,202 +0,0 @@ -package rsmt2d - -import ( - "fmt" - "reflect" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -// TestRegisterTree tests the RegisterTree function for adding -// a tree constructor function for a given tree name into treeFns -// global map. -func TestRegisterTree(t *testing.T) { - treeName := "testing_register_tree" - treeConstructorFn := sudoConstructorFn - - tests := []struct { - name string - expectErr error - }{ - // The tree has not been registered yet in the treeFns global map. - {"register successfully", nil}, - // The tree has already been registered in the treeFns global map. - {"register unsuccessfully", fmt.Errorf("%s already registered", treeName)}, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - err := RegisterTree(treeName, treeConstructorFn) - if test.expectErr != nil { - require.Equal(t, test.expectErr, err) - } - - treeFn, err := TreeFn(treeName) - require.NoError(t, err) - assert.True(t, reflect.DeepEqual(reflect.ValueOf(treeFn), reflect.ValueOf(treeConstructorFn))) - }) - } - - cleanUp(treeName) -} - -// TestTreeFn test the TreeFn function which fetches the -// tree constructor function from the treeFns golbal map. -func TestTreeFn(t *testing.T) { - treeName := "testing_treeFn_tree" - treeConstructorFn := sudoConstructorFn - invalidCaseTreeName := "testing_invalid_register_tree" - invalidTreeConstructorFn := "invalid constructor fn" - - tests := []struct { - name string - treeName string - malleate func() - expectErr error - }{ - // The tree constructor function is successfully fetched - // from the global map. - { - "get successfully", - treeName, - func() { - err := RegisterTree(treeName, treeConstructorFn) - require.NoError(t, err) - }, - nil, - }, - // Unable to fetch the tree constructor function for an - // unregisted tree name. - { - "get unregisted tree name", - "unregistered_tree", - func() {}, - fmt.Errorf("%s not registered yet", "unregistered_tree"), - }, - // Value returned from the global map is an invalid value that - // cannot be type asserted into TreeConstructorFn type. - { - "get invalid interface value", - invalidCaseTreeName, - func() { - // Seems like this case has low probability of happening - // since all register has been done through RegisterTree func - // which have strict type check as argument. - treeFns.Store(invalidCaseTreeName, invalidTreeConstructorFn) - }, - fmt.Errorf("key %s has invalid interface", invalidCaseTreeName), - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - test.malleate() - - treeFn, err := TreeFn(test.treeName) - if test.expectErr != nil { - require.Equal(t, test.expectErr, err) - } else { - require.NoError(t, err) - require.True(t, reflect.DeepEqual(reflect.ValueOf(treeFn), reflect.ValueOf(treeConstructorFn))) - } - }) - - cleanUp(test.treeName) - } -} - -// TestGetTreeNameFromConstructorFn tests the GetTreeNameFromConstructorFn -// function which fetches tree name by it corresponding tree constructor function. -// -// TODO: When we handle all the breaking changes track in this PR: https://github.com/celestiaorg/rsmt2d/pull/278, should remove this test -func TestGetTreeNameFromConstructorFn(t *testing.T) { - treeName := "testing_get_tree_name_tree" - treeConstructorFn := sudoConstructorFn - invalidTreeName := struct{}{} - invalidCaseTreeName := "invalid_case_tree" - invalidTreeConstructorFn := "invalid constructor fn" - - tests := []struct { - name string - treeName string - treeFn TreeConstructorFn - malleate func() - expectGetKey bool - }{ - // The tree name is successfully fetched. - { - "get successfully", - treeName, - treeConstructorFn, - func() { - err := RegisterTree(treeName, treeConstructorFn) - require.NoError(t, err) - }, - true, - }, - // Unable to fetch an unregistered tree name. - { - "get unregisted tree name", - "unregisted_tree_name", - nil, - func() {}, - false, - }, - // Value (tree constructor function) from the global map iteration is an invalid - // value that cannot be type asserted into TreeConstructorFn type. - { - "get invalid interface value", - "", - nil, - func() { - // Seems like this case has low probability of happening - // since all register has been done through RegisterTree func - // which have strict type check as argument. - treeFns.Store(invalidCaseTreeName, invalidTreeConstructorFn) - }, - false, - }, - // Key (tree name) from the global map iteration is an invalid value that cannot - // be type asserted into string type. - { - "get invalid interface key", - "", - nil, - func() { - // Seems like this case has low probability of happening - // since all register has been done through RegisterTree func - // which have strict type check as argument. - treeFns.Store(invalidTreeName, treeConstructorFn) - }, - false, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - test.malleate() - - key := getTreeNameFromConstructorFn(test.treeFn) - if !test.expectGetKey { - require.Equal(t, key, "") - } else { - require.Equal(t, test.treeName, key) - } - }) - - cleanUp(test.treeName) - } -} - -// Avoid duplicate with default_tree treeConstructorFn -// registered during init. -func sudoConstructorFn(_ Axis, _ uint) Tree { - return &DefaultTree{} -} - -// Clear tested tree constructor function in the global map. -func cleanUp(treeName string) { - removeTreeFn(treeName) -}