Skip to content

Commit 2777659

Browse files
fix: Prevent newExporter crash if tree.ndb is nil (#622)
Co-authored-by: Marko <marbar3778@yahoo.com>
1 parent da766a3 commit 2777659

File tree

7 files changed

+36
-13
lines changed

7 files changed

+36
-13
lines changed

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
- [#586](https://github.com/cosmos/iavl/pull/586) Remove the `RangeProof` and refactor the ics23_proof to use the internal methods.

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
@@ -127,7 +127,10 @@ func runExport(dbPath string) (int64, map[string][]*iavl.ExportNode, error) {
127127
return 0, nil, err
128128
}
129129
start := time.Now().UTC()
130-
exporter := itree.Export()
130+
exporter, err := itree.Export()
131+
if err != nil {
132+
return 0, nil, err
133+
}
131134
defer exporter.Close()
132135
for {
133136
node, err := exporter.Next()

export.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package iavl
33
import (
44
"context"
55
"errors"
6+
"fmt"
67
)
78

89
// exportBufferSize is the number of nodes to buffer in the exporter. It improves throughput by
@@ -13,6 +14,9 @@ const exportBufferSize = 32
1314
// ErrorExportDone is returned by Exporter.Next() when all items have been exported.
1415
var ErrorExportDone = errors.New("export is complete")
1516

17+
// ErrNotInitalizedTree when chains introduce a store without initializing data
18+
var ErrNotInitalizedTree = errors.New("iavl/export newExporter failed to create")
19+
1620
// ExportNode contains exported node data.
1721
type ExportNode struct {
1822
Key []byte
@@ -33,7 +37,15 @@ type Exporter struct {
3337
}
3438

3539
// NewExporter creates a new Exporter. Callers must call Close() when done.
36-
func newExporter(tree *ImmutableTree) *Exporter {
40+
func newExporter(tree *ImmutableTree) (*Exporter, error) {
41+
if tree == nil {
42+
return nil, fmt.Errorf("tree is nil: %w", ErrNotInitalizedTree)
43+
}
44+
// CV Prevent crash on incrVersionReaders if tree.ndb == nil
45+
if tree.ndb == nil {
46+
return nil, fmt.Errorf("tree.ndb is nil: %w", ErrNotInitalizedTree)
47+
}
48+
3749
ctx, cancel := context.WithCancel(context.Background())
3850
exporter := &Exporter{
3951
tree: tree,
@@ -44,7 +56,7 @@ func newExporter(tree *ImmutableTree) *Exporter {
4456
tree.ndb.incrVersionReaders(tree.version)
4557
go exporter.export(ctx)
4658

47-
return exporter
59+
return exporter, nil
4860
}
4961

5062
// 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 == ErrorExportDone {

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 == ErrorExportDone {

0 commit comments

Comments
 (0)