Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State sync support #5803

Closed
wants to merge 79 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
e75f206
Use local iavl module
erikgrinaker Mar 4, 2020
c6201ba
Added initial snapshot settings
erikgrinaker Mar 4, 2020
bd2af17
Initial functional snapshot/restore API
erikgrinaker Mar 5, 2020
2424a7d
Added compression and chunking
erikgrinaker Mar 5, 2020
383cf94
Code cleanups
erikgrinaker Mar 5, 2020
aabc422
Added benchmarks
erikgrinaker Mar 5, 2020
dcc7673
More benchmarks
erikgrinaker Mar 5, 2020
780dae5
Buffer snapshot writers
erikgrinaker Mar 9, 2020
e91f273
Minor tweaks
erikgrinaker Mar 11, 2020
6bcf763
Type fix
erikgrinaker Mar 11, 2020
ef46535
Ignore caches during export
erikgrinaker Mar 13, 2020
a939897
Use local tm-db as well
erikgrinaker Mar 13, 2020
4585f8e
Initial snapshot store
erikgrinaker Mar 13, 2020
88e5355
Simplified Snapshotter interface
erikgrinaker Mar 13, 2020
6aed0b1
Split chunk writer and reader to separate file
erikgrinaker Mar 13, 2020
d7a6dbe
Cleaned up multistore snapshot/restore
erikgrinaker Mar 13, 2020
672db15
Improved snapshotting
erikgrinaker Mar 13, 2020
cd1b2d8
Properly close exporters and importers
erikgrinaker Mar 13, 2020
11de242
Added snapshot loading
erikgrinaker Mar 13, 2020
11fb197
Added snapshot pruning
erikgrinaker Mar 13, 2020
ad61eb1
Added snapshot listing
erikgrinaker Mar 13, 2020
6eb2ffe
Use prefix db for snapshot store
erikgrinaker Mar 13, 2020
dd76cb7
Added auxiliary snapshot function for BaseApp
erikgrinaker Mar 17, 2020
bf8acad
Merge branch 'master' into erik/snapshot
erikgrinaker Mar 17, 2020
a257ff3
go.mod: remove local tm-db.
erikgrinaker Mar 17, 2020
4251e06
Moved rootmulti snapshot contents to separate store/types
erikgrinaker Mar 17, 2020
31f8eee
Moved snapshot store to separate package
erikgrinaker Mar 17, 2020
46a3941
Added format parameter for Snapshotter interface
erikgrinaker Mar 18, 2020
c7a7513
Removed unused snapshotFormat variable
erikgrinaker Mar 18, 2020
bf54794
Don't set up a snapshot store automatically
erikgrinaker Mar 18, 2020
08713b1
Added tests for snapshots.Store
erikgrinaker Mar 18, 2020
56fc9d9
Minor tweaks
erikgrinaker Mar 18, 2020
394e097
go.mod: use iavl 0.13.2
erikgrinaker Mar 19, 2020
316dace
Updated changelog
erikgrinaker Mar 19, 2020
a39974f
Appease linter
erikgrinaker Mar 19, 2020
e984eee
Merge branch 'master' into erik/snapshot
erikgrinaker Mar 19, 2020
d8d455d
Added snapshot options
erikgrinaker Mar 19, 2020
bef3c86
Fix nil dereferencing in chunkWriter.CloseWithError()
erikgrinaker Mar 19, 2020
c3528dc
Merge branch 'master' into erik/snapshot
erikgrinaker Mar 26, 2020
076865a
Protobuf formatting fix
erikgrinaker Mar 26, 2020
fe8c88b
Return chunk metadata as well in Store.LoadChunk()
erikgrinaker Mar 26, 2020
33fa307
Add snapshots.Restorer()
erikgrinaker Mar 26, 2020
a34e12c
Typo
erikgrinaker Mar 27, 2020
ba031f6
Use table-driven tests for rootmulti.Store snapshot/restore error tests
erikgrinaker Mar 28, 2020
e507801
use zlib compression for snapshots
erikgrinaker Mar 28, 2020
3df5b25
add checksum test for snapshot format stability
erikgrinaker Mar 28, 2020
09ff5c1
use larger generated dataset for snapshot checksum test
erikgrinaker Mar 28, 2020
2f7d969
simplify snapshot management for new ABCI interface
erikgrinaker Mar 29, 2020
67c0faa
bump snapshot chunk size to 10 MB
erikgrinaker Mar 29, 2020
828ae14
use sha256 hashes for snapshot chunks
erikgrinaker Mar 29, 2020
5714fed
Merge branch 'master' into erik/snapshot
erikgrinaker Apr 1, 2020
624c4f5
snapshots: added Store.GetLatest()
erikgrinaker Apr 1, 2020
d3afa8b
baseapp: check for newer snapshots, to avoid snapshotting during replay
erikgrinaker Apr 1, 2020
c46438e
baseapp: fix nil dereferencing
erikgrinaker Apr 1, 2020
5cac251
Implemented ABCI snapshot skeleton
erikgrinaker Mar 26, 2020
857b3dd
Ported Tendermint API changes
erikgrinaker Mar 26, 2020
7d0009c
Implement ABCI snapshot interface
erikgrinaker Mar 26, 2020
994b731
don't limit ListSnapshots to 100, caller can do this
erikgrinaker Mar 28, 2020
ab71bcb
updated with simplified ABCI interface
erikgrinaker Mar 29, 2020
a753a0e
update with new chunk size
erikgrinaker Mar 29, 2020
76b79b1
use sha-256 chunk hashes
erikgrinaker Mar 29, 2020
5afe4f4
update with TM rpc/client changes
erikgrinaker Apr 3, 2020
836fa5e
add snapshots.Manager, restructure code, and write tests
erikgrinaker Apr 3, 2020
8efccd5
reduce timeout
erikgrinaker Apr 4, 2020
679c2f0
add test for restoring empty IAVL stores
erikgrinaker Apr 4, 2020
7a81f0a
go.mod: bump iavl
erikgrinaker Apr 5, 2020
fb6580c
check for error when importing IAVL nodes
erikgrinaker Apr 14, 2020
f895ca1
handle empty keys and values via Protobuf
erikgrinaker Apr 14, 2020
94f1e44
Merge branch 'master' into erik/snapshot
erikgrinaker Apr 24, 2020
d2fb90e
change tmkv.Pair to abci.EventAttribute
erikgrinaker Apr 24, 2020
432ff4a
initial port to new state sync ABCI interface
erikgrinaker Apr 24, 2020
3c52b05
don't snapshot mem.Store stores
erikgrinaker Apr 24, 2020
e7cb0be
Merge branch 'master' into erik/snapshot
erikgrinaker Apr 29, 2020
5a9def7
minor tweaks
erikgrinaker May 6, 2020
0888800
handle chunk hash verification
erikgrinaker May 6, 2020
683bd35
use pruning options for config
erikgrinaker May 6, 2020
bf04df1
improve error handling
erikgrinaker May 6, 2020
963432f
remove snapshot flags
erikgrinaker May 6, 2020
4c3cdac
use new ABCI enums
erikgrinaker May 7, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,27 @@ func (app *BaseApp) Commit() (res abci.ResponseCommit) {
app.halt()
}

if app.snapshotInterval > 0 && uint64(header.Height)%app.snapshotInterval == 0 {
go func() {
app.logger.Info("Taking state snapshot", "height", header.Height)
err := app.snapshot(uint64(header.Height))
if err != nil {
app.logger.Error("Failed to take snapshot", "height", header.Height, "err", err.Error())
return
}
app.logger.Info("Finished taking state snapshot", "height", header.Height)
if app.snapshotRetention > 0 {
app.logger.Info("Pruning state snapshots")
pruned, err := app.snapshotStore.Prune(app.snapshotRetention)
erikgrinaker marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
app.logger.Error("Failed to prune snapshots", "err", err.Error())
return
}
app.logger.Info(fmt.Sprintf("Pruned %v state snapshots", pruned))
}
}()
}

return abci.ResponseCommit{
Data: commitID.Hash,
}
Expand Down
24 changes: 24 additions & 0 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/store"
"github.com/cosmos/cosmos-sdk/store/snapshot"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
Expand All @@ -26,6 +27,9 @@ const (

// MainStoreKey is the string representation of the main store
MainStoreKey = "main"

// snapshotFormat is the currently used snapshot format
snapshotFormat = 1
)

var (
Expand Down Expand Up @@ -70,6 +74,11 @@ type BaseApp struct { // nolint: maligned
idPeerFilter sdk.PeerFilter // filter peers by node ID
fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed.

// snapshot storage, i.e. dumps of app state at certain intervals
snapshotStore *snapshot.Store
snapshotInterval uint64 // interval (in blocks) between snapshots (0 to disable)
snapshotRetention uint32 // number of snapshots to keep (0 for all)

// volatile states:
//
// checkState is set on InitChain and reset on Commit
Expand Down Expand Up @@ -623,3 +632,18 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s
Events: events,
}, nil
}

// snapshot takes a snapshot
func (app *BaseApp) snapshot(height uint64) error {
if app.snapshotStore == nil {
return errors.New("no snapshot store configured")
}
if app.snapshotStore.Active() {
return errors.New("a snapshot is already in progress")
}
chunks, err := app.cms.Snapshot(height)
if err != nil {
return err
}
return app.snapshotStore.Save(height, snapshotFormat, chunks)
}
29 changes: 29 additions & 0 deletions baseapp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/store"
"github.com/cosmos/cosmos-sdk/store/snapshot"
sdk "github.com/cosmos/cosmos-sdk/types"
)

Expand Down Expand Up @@ -44,6 +45,16 @@ func SetInterBlockCache(cache sdk.MultiStorePersistentCache) func(*BaseApp) {
return func(app *BaseApp) { app.setInterBlockCache(cache) }
}

// SetSnapshotDB sets the snapshot store.
func SetSnapshotStore(s *snapshot.Store) func(*BaseApp) {
return func(app *BaseApp) { app.SetSnapshotStore(s) }
}

// SetSnapshotPolicy sets the snapshot policy.
func SetSnapshotPolicy(interval uint64, retention uint32) func(*BaseApp) {
return func(app *BaseApp) { app.SetSnapshotPolicy(interval, retention) }
}

func (app *BaseApp) SetName(name string) {
if app.sealed {
panic("SetName() on sealed BaseApp")
Expand Down Expand Up @@ -143,3 +154,21 @@ func (app *BaseApp) SetRouter(router sdk.Router) {
}
app.router = router
}

// SetSnapshotDB sets the snapshot database and data directory. This database must
// be independent of the app state.
func (app *BaseApp) SetSnapshotStore(s *snapshot.Store) {
if app.sealed {
panic("SetSnapshotDB() on sealed BaseApp")
}
app.snapshotStore = s
}

// SetSnapshotPolicy sets the snapshotting policy. 0 disables snapshotting.
func (app *BaseApp) SetSnapshotPolicy(interval uint64, retention uint32) {
if app.sealed {
panic("SetSnapshotPolicy on sealed BaseApp")
}
app.snapshotInterval = interval
app.snapshotRetention = retention
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ require (

replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.1

// FIXME Use local iavl with export/import API
replace github.com/tendermint/iavl => ../iavl

replace github.com/tendermint/tm-db => ../tm-db

go 1.14
9 changes: 4 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,14 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
Expand Down Expand Up @@ -388,7 +390,6 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=
github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
Expand All @@ -408,8 +409,6 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs=
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
github.com/tecbot/gorocksdb v0.0.0-20191017175515-d217d93fd4c5 h1:gVwAW5OwaZlDB5/CfqcGFM9p9C+KxvQKyNOltQ8orj0=
github.com/tecbot/gorocksdb v0.0.0-20191017175515-d217d93fd4c5/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok=
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s=
Expand All @@ -419,9 +418,9 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM
github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso=
github.com/tendermint/go-amino v0.15.1 h1:D2uk35eT4iTsvJd9jWIetzthE5C0/k2QmMFkCN+4JgQ=
github.com/tendermint/go-amino v0.15.1/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
github.com/tendermint/iavl v0.13.0 h1:r2sINvNFlJsLlLhGoqlqPlREWYkuK26BvMfkBt+XQnA=
github.com/tendermint/iavl v0.13.0/go.mod h1:7nSUPdrsHEZ2nNZa+9gaIrcJciWd1jCQZXtcyARU82k=
github.com/tendermint/tendermint v0.33.0/go.mod h1:s5UoymnPIY+GcA3mMte4P9gpMP8vS7UH7HBXikT1pHI=
github.com/tendermint/tendermint v0.33.1 h1:8f68LUBz8yhISZvaLFP4siXXrLWsWeoYfelbdNtmvm4=
github.com/tendermint/tendermint v0.33.1/go.mod h1:fBOKyrlXOETqQ+heL8x/TZgSdmItON54csyabvktBp0=
github.com/tendermint/tendermint v0.33.2 h1:NzvRMTuXJxqSsFed2J7uHmMU5N1CVzSpfi3nCc882KY=
github.com/tendermint/tendermint v0.33.2/go.mod h1:25DqB7YvV1tN3tHsjWoc2vFtlwICfrub9XO6UBO+4xk=
github.com/tendermint/tm-db v0.4.0 h1:iPbCcLbf4nwDFhS39Zo1lpdS1X/cT9CkTlUx17FHQgA=
Expand Down
9 changes: 8 additions & 1 deletion server/constructors.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import (
tmtypes "github.com/tendermint/tendermint/types"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/store/snapshot"
sdk "github.com/cosmos/cosmos-sdk/types"
)

type (
// AppCreator is a function that allows us to lazily initialize an
// application using various configurations.
AppCreator func(log.Logger, dbm.DB, io.Writer) abci.Application
AppCreator func(log.Logger, dbm.DB, *snapshot.Store, io.Writer) abci.Application
erikgrinaker marked this conversation as resolved.
Show resolved Hide resolved

// AppExporter is a function that dumps all app state to
// JSON-serializable structure and returns the current validator set.
Expand All @@ -30,6 +31,12 @@ func openDB(rootDir string) (dbm.DB, error) {
return db, err
}

func openSnapshotStore(db dbm.DB, rootDir string) (*snapshot.Store, error) {
db = dbm.NewPrefixDB(db, []byte("s/_snapshots/"))
dir := filepath.Join(rootDir, "data", "snapshots")
return snapshot.New(db, dir)
}

func openTraceWriter(traceWriterFile string) (w io.Writer, err error) {
if traceWriterFile != "" {
w, err = os.OpenFile(
Expand Down
8 changes: 8 additions & 0 deletions server/mock/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ func (ms multiStore) SetInterBlockCache(_ sdk.MultiStorePersistentCache) {
panic("not implemented")
}

func (kv multiStore) Snapshot(height uint64) (<-chan io.ReadCloser, error) {
panic("not implemented")
}

func (kv multiStore) Restore(height uint64, chunks <-chan io.ReadCloser) error {
panic("not implemented")
}

var _ sdk.KVStore = kvStore{}

type kvStore struct {
Expand Down
14 changes: 12 additions & 2 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,17 @@ func startStandAlone(ctx *Context, appCreator AppCreator) error {
if err != nil {
return err
}
ss, err := openSnapshotStore(db, home)
if err != nil {
return err
}

traceWriter, err := openTraceWriter(traceWriterFile)
if err != nil {
return err
}

app := appCreator(ctx.Logger, db, traceWriter)
app := appCreator(ctx.Logger, db, ss, traceWriter)

svr, err := server.NewServer(addr, "socket", app)
if err != nil {
Expand Down Expand Up @@ -180,12 +185,17 @@ func startInProcess(ctx *Context, appCreator AppCreator) (*node.Node, error) {
return nil, err
}

ss, err := openSnapshotStore(db, home)
if err != nil {
return nil, err
}

traceWriter, err := openTraceWriter(traceWriterFile)
if err != nil {
return nil, err
}

app := appCreator(ctx.Logger, db, traceWriter)
app := appCreator(ctx.Logger, db, ss, traceWriter)

nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile())
if err != nil {
Expand Down
22 changes: 22 additions & 0 deletions store/iavl/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,28 @@ func (st *Store) ReverseIterator(start, end []byte) types.Iterator {
return newIAVLIterator(iTree, start, end, false)
}

// Exports the IAVL store at the given version, returning an iavl.Exporter for the tree.
func (st *Store) Export(version int64) (*iavl.Exporter, error) {
istore, err := st.GetImmutable(version)
if err != nil {
return nil, fmt.Errorf("iavl export failed for version %v: %w", version, err)
}
tree, ok := istore.tree.(*immutableTree)
if !ok || tree == nil {
return nil, fmt.Errorf("iavl export failed: unable to fetch tree for version %v", version)
}
return tree.Export(), nil
}

// Import imports an IAVL tree at the given version, returning an iavl.Importer for importing.
func (st *Store) Import(version int64) (*iavl.Importer, error) {
tree, ok := st.tree.(*iavl.MutableTree)
if !ok {
return nil, errors.New("iavl import failed: unable to find mutable tree")
}
return tree.Import(version)
}

// Handle gatest the latest height, if height is 0
func getHeight(tree Tree, req abci.RequestQuery) int64 {
height := req.Height
Expand Down
Loading