Skip to content

Commit f665c40

Browse files
mergify[bot]chillyveetac0turtle
authored andcommitted
fix: Prevent newExporter crash if tree.ndb is nil (backport cosmos#622) (cosmos#631)
Co-authored-by: Chill Validation <92176880+chillyvee@users.noreply.github.com> Co-authored-by: Marko Baricevic <marbar3778@yahoo.com>
1 parent 35ef923 commit f665c40

7 files changed

Lines changed: 33 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
### Breaking Changes
4+
5+
- [#622](https://github.com/cosmos/iavl/pull/622) `export/newExporter()` and `ImmutableTree.Export()` returns error for nil arguements
6+
37
## Unreleased
48

59
- [#640](https://github.com/cosmos/iavl/pull/640) commit `NodeDB` batch in `LoadVersionForOverwriting`.

Makefile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ all: lint test install
1515
install:
1616
ifeq ($(COLORS_ON),)
1717
go install ./cmd/iaviewer
18-
go install ./cmd/iavlserver
1918
else
2019
go install $(CMDFLAGS) ./cmd/iaviewer
21-
go install $(CMDFLAGS) ./cmd/iavlserver
2220
endif
2321
.PHONY: install
2422

benchmarks/cosmos-exim/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@ func runExport(dbPath string) (int64, map[string][]*iavl.ExportNode, error) {
128128
return 0, nil, err
129129
}
130130
start := time.Now().UTC()
131-
exporter := itree.Export()
131+
exporter, err := itree.Export()
132+
if err != nil {
133+
return 0, nil, err
134+
}
132135
defer exporter.Close()
133136
for {
134137
node, err := exporter.Next()

export.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ package iavl
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
6-
7-
"github.com/pkg/errors"
87
)
98

109
// exportBufferSize is the number of nodes to buffer in the exporter. It improves throughput by
@@ -16,6 +15,9 @@ const exportBufferSize = 32
1615
// nolint:revive
1716
var ExportDone = errors.New("export is complete") // nolint:golint
1817

18+
// ErrNotInitalizedTree when chains introduce a store without initializing data
19+
var ErrNotInitalizedTree = errors.New("iavl/export newExporter failed to create")
20+
1921
// ExportNode contains exported node data.
2022
type ExportNode struct {
2123
Key []byte
@@ -36,9 +38,13 @@ type Exporter struct {
3638
}
3739

3840
// NewExporter creates a new Exporter. Callers must call Close() when done.
39-
func newExporter(tree *ImmutableTree) *Exporter {
41+
func newExporter(tree *ImmutableTree) (*Exporter, error) {
4042
if tree == nil {
41-
return nil
43+
return nil, fmt.Errorf("tree is nil: %w", ErrNotInitalizedTree)
44+
}
45+
// CV Prevent crash on incrVersionReaders if tree.ndb == nil
46+
if tree.ndb == nil {
47+
return nil, fmt.Errorf("tree.ndb is nil: %w", ErrNotInitalizedTree)
4248
}
4349

4450
ctx, cancel := context.WithCancel(context.Background())
@@ -56,7 +62,7 @@ func newExporter(tree *ImmutableTree) *Exporter {
5662
}
5763
go exporter.export(ctx)
5864

59-
return exporter
65+
return exporter, nil
6066
}
6167

6268
// export exports nodes

export_test.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ func TestExporter(t *testing.T) {
160160
}
161161

162162
actual := make([]*ExportNode, 0, len(expect))
163-
exporter := tree.Export()
163+
exporter, err := tree.Export()
164+
require.NoError(t, err)
164165
defer exporter.Close()
165166
for {
166167
node, err := exporter.Next()
@@ -189,7 +190,8 @@ func TestExporter_Import(t *testing.T) {
189190
t.Run(desc, func(t *testing.T) {
190191
t.Parallel()
191192

192-
exporter := tree.Export()
193+
exporter, err := tree.Export()
194+
require.NoError(t, err)
193195
defer exporter.Close()
194196

195197
newTree, err := NewMutableTree(db.NewMemDB(), 0, false)
@@ -234,7 +236,8 @@ func TestExporter_Import(t *testing.T) {
234236

235237
func TestExporter_Close(t *testing.T) {
236238
tree := setupExportTreeSized(t, 4096)
237-
exporter := tree.Export()
239+
exporter, err := tree.Export()
240+
require.NoError(t, err)
238241

239242
node, err := exporter.Next()
240243
require.NoError(t, err)
@@ -273,7 +276,8 @@ func TestExporter_DeleteVersionErrors(t *testing.T) {
273276

274277
itree, err := tree.GetImmutable(2)
275278
require.NoError(t, err)
276-
exporter := itree.Export()
279+
exporter, err := itree.Export()
280+
require.NoError(t, err)
277281
defer exporter.Close()
278282

279283
err = tree.DeleteVersion(2)
@@ -291,7 +295,8 @@ func BenchmarkExport(b *testing.B) {
291295
tree := setupExportTreeSized(b, 4096)
292296
b.StartTimer()
293297
for n := 0; n < b.N; n++ {
294-
exporter := tree.Export()
298+
exporter, err := tree.Export()
299+
require.NoError(b, err)
295300
for {
296301
_, err := exporter.Next()
297302
if err == ExportDone {

immutable_tree.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func (t *ImmutableTree) Hash() ([]byte, error) {
155155

156156
// Export returns an iterator that exports tree nodes as ExportNodes. These nodes can be
157157
// imported with MutableTree.Import() to recreate an identical tree.
158-
func (t *ImmutableTree) Export() *Exporter {
158+
func (t *ImmutableTree) Export() (*Exporter, error) {
159159
return newExporter(t)
160160
}
161161

import_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func ExampleImporter() {
2727
if err != nil {
2828
// handle err
2929
}
30-
exporter := itree.Export()
30+
exporter, err := itree.Export()
3131
defer exporter.Close()
3232
exported := []*ExportNode{}
3333
for {
@@ -218,7 +218,8 @@ func BenchmarkImport(b *testing.B) {
218218
b.StopTimer()
219219
tree := setupExportTreeSized(b, 4096)
220220
exported := make([]*ExportNode, 0, 4096)
221-
exporter := tree.Export()
221+
exporter, err := tree.Export()
222+
require.NoError(b, err)
222223
for {
223224
item, err := exporter.Next()
224225
if err == ExportDone {

0 commit comments

Comments
 (0)