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

feat: add the snapshot sync for v2 store #18

Closed
wants to merge 49 commits into from
Closed
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
0b732a4
add store/v2 types, RootStore
roysc Aug 30, 2021
2ffea14
store/v2 dbadapter
roysc Sep 6, 2021
66aec81
store/v2 mem & transient stores
roysc Sep 14, 2021
4d1735d
db iterator adapter
roysc Sep 6, 2021
5f8d494
flat store additions
roysc Oct 14, 2021
4afd095
add RootStore implementation
roysc Oct 25, 2021
3b3f63e
rename Merkle* to StateCommitment*
roysc Nov 12, 2021
792e93f
move store/v2/flat.* => store/v2/root.*
roysc Nov 12, 2021
46bf6a3
update docs
roysc Nov 12, 2021
65105e7
rm StoreTypeDecoupled
roysc Nov 16, 2021
77effa4
smt.Store - raise smt.InvalidKeyError
roysc Nov 17, 2021
2ada818
Combine root/store & root/root_store
roysc Nov 12, 2021
fa85a72
RootStore uses per-substore SMTs
roysc Nov 16, 2021
d889e07
docs + changelog
roysc Nov 17, 2021
b2007bf
Revert changes to prefix store
roysc Nov 18, 2021
f1caf0f
try to fix rocksdb test case for CI
roysc Nov 18, 2021
d2f0ada
add checks to testcase
roysc Nov 18, 2021
2ae149f
nit
roysc Nov 18, 2021
62f1fc7
rootstore cleanup
roysc Nov 18, 2021
2677b2a
cleanup, comments
roysc Nov 24, 2021
0d5c769
PR revisions - godoc, cleanup
roysc Nov 25, 2021
35843aa
tests + mocks for v2/dbadapter
roysc Nov 25, 2021
5c9eb81
PR revisions
roysc Nov 26, 2021
21e3745
godoc, comments
roysc Nov 29, 2021
5f6b355
test commit - failed revert recovery
roysc Dec 1, 2021
856b5fa
update docs
roysc Dec 1, 2021
d28890b
cleanup
roysc Dec 1, 2021
f568704
godoc & code comments
roysc Dec 1, 2021
5a53647
PR revisions
roysc Dec 1, 2021
1432859
fix v2 mem & tran stores
roysc Dec 1, 2021
b046e20
rm npSubstoreCache
roysc Dec 1, 2021
1648aa6
impl, test trace & listen on rootstore
roysc Dec 1, 2021
91581f8
test fix
roysc Dec 1, 2021
282ea90
rename RootStore => MultiStore
roysc Dec 1, 2021
40584b7
make: don't build rocksdb unless ENABLE_ROCKSDB=true
roysc Dec 2, 2021
f4edb06
set rocksdb_build tag in CI submodule tests
roysc Dec 2, 2021
ad227e0
Update gorocksdb replace directive to use cosmos fork
roysc Dec 2, 2021
15b9b5c
Merge branch 'master' into roysc/adr-040-create-rootstore
roysc Dec 6, 2021
c4d6e42
feat: add the snapshot sync for v2 store
Dec 8, 2021
9eda661
address the pr comments
Dec 9, 2021
551dd3b
address the pr comments
Dec 11, 2021
8f68ced
removed prefix registry from restore
Dec 13, 2021
b024b20
addressed the pr comments
Dec 13, 2021
4284df5
test: add test cases for snapshot for v2 store
Dec 13, 2021
db80903
test: add test for checking restore for non-empty store
Dec 14, 2021
58e4795
test: add test for checking restore for store with existed schema
Dec 14, 2021
21715e9
address the pr comments
Dec 14, 2021
3431130
address the pr comments
Dec 14, 2021
59a7cbb
Merge the master
Dec 16, 2021
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#10379](https://github.com/cosmos/cosmos-sdk/pull/10379) Add validation to `x/upgrade` CLI `software-upgrade` command `--plan-info` value.
* [\#10561](https://github.com/cosmos/cosmos-sdk/pull/10561) Add configurable IAVL cache size to app.toml
* [\10507](https://github.com/cosmos/cosmos-sdk/pull/10507) Add middleware for tx priority.
* [\#10430](https://github.com/cosmos/cosmos-sdk/pull/10430) ADR-040: Add store/v2 `MultiStore` implementation

### Improvements

Expand Down
32 changes: 24 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ HTTPS_GIT := https://github.com/cosmos/cosmos-sdk.git
DOCKER := $(shell which docker)
DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf:1.0.0-rc8
PROJECT_NAME = $(shell git remote get-url origin | xargs basename -s .git)
# RocksDB is a native dependency, so we don't assume the library is installed.
# Instead, it must be explicitly enabled and we warn when it is not.
ENABLE_ROCKSDB ?= false

export GO111MODULE = on

Expand Down Expand Up @@ -61,6 +64,13 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=sim \
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \
-X github.com/tendermint/tendermint/version.TMCoreSemVer=$(TMVERSION)

ifeq ($(ENABLE_ROCKSDB),true)
BUILD_TAGS += rocksdb_build
test_tags += rocksdb_build
else
$(warning RocksDB support is disabled; to build and test with RocksDB support, set ENABLE_ROCKSDB=true)
endif

# DB backend selection
ifeq (cleveldb,$(findstring cleveldb,$(COSMOS_BUILD_OPTIONS)))
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
Expand All @@ -71,6 +81,9 @@ ifeq (badgerdb,$(findstring badgerdb,$(COSMOS_BUILD_OPTIONS)))
endif
# handle rocksdb
ifeq (rocksdb,$(findstring rocksdb,$(COSMOS_BUILD_OPTIONS)))
ifneq ($(ENABLE_ROCKSDB),true)
$(error Cannot use RocksDB backend unless ENABLE_ROCKSDB=true)
endif
CGO_ENABLED=1
BUILD_TAGS += rocksdb
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=rocksdb
Expand Down Expand Up @@ -132,6 +145,7 @@ mockgen_cmd=go run github.com/golang/mock/mockgen
mocks: $(MOCKS_DIR)
$(mockgen_cmd) -source=client/account_retriever.go -package mocks -destination tests/mocks/account_retriever.go
$(mockgen_cmd) -package mocks -destination tests/mocks/tendermint_tm_db_DB.go github.com/tendermint/tm-db DB
$(mockgen_cmd) -source db/types.go -package mocks -destination tests/mocks/db/types.go
$(mockgen_cmd) -source=types/module/module.go -package mocks -destination tests/mocks/types_module_module.go
$(mockgen_cmd) -source=types/invariant.go -package mocks -destination tests/mocks/types_invariant.go
$(mockgen_cmd) -source=types/router.go -package mocks -destination tests/mocks/types_router.go
Expand Down Expand Up @@ -204,22 +218,24 @@ TEST_TARGETS := test-unit test-unit-amino test-unit-proto test-ledger-mock test-
# Test runs-specific rules. To add a new test target, just add
# a new rule, customise ARGS or TEST_PACKAGES ad libitum, and
# append the new rule to the TEST_TARGETS list.
test-unit: ARGS=-tags='cgo ledger test_ledger_mock norace'
test-unit-amino: ARGS=-tags='ledger test_ledger_mock test_amino norace'
test-ledger: ARGS=-tags='cgo ledger norace'
test-ledger-mock: ARGS=-tags='ledger test_ledger_mock norace'
test-race: ARGS=-race -tags='cgo ledger test_ledger_mock'
test-unit: test_tags += cgo ledger test_ledger_mock norace
test-unit-amino: test_tags += ledger test_ledger_mock test_amino norace
test-ledger: test_tags += cgo ledger norace
test-ledger-mock: test_tags += ledger test_ledger_mock norace
test-race: test_tags += cgo ledger test_ledger_mock
test-race: ARGS=-race
test-race: TEST_PACKAGES=$(PACKAGES_NOSIMULATION)
$(TEST_TARGETS): run-tests

# check-* compiles and collects tests without running them
# note: go test -c doesn't support multiple packages yet (https://github.com/golang/go/issues/15513)
CHECK_TEST_TARGETS := check-test-unit check-test-unit-amino
check-test-unit: ARGS=-tags='cgo ledger test_ledger_mock norace'
check-test-unit-amino: ARGS=-tags='ledger test_ledger_mock test_amino norace'
check-test-unit: test_tags += cgo ledger test_ledger_mock norace
check-test-unit-amino: test_tags += ledger test_ledger_mock test_amino norace
$(CHECK_TEST_TARGETS): EXTRA_ARGS=-run=none
$(CHECK_TEST_TARGETS): run-tests

ARGS += -tags "$(test_tags)"
SUB_MODULES = $(shell find . -type f -name 'go.mod' -print0 | xargs -0 -n1 dirname | sort)
CURRENT_DIR = $(shell pwd)
run-tests:
Expand Down Expand Up @@ -484,7 +500,7 @@ localnet-build-dlv:

localnet-build-nodes:
$(DOCKER) run --rm -v $(CURDIR)/.testnets:/data cosmossdk/simd \
testnet init-files --v 4 --starting-ip-address 192.168.10.2 --keyring-backend=test
testnet init-files --v 4 --starting-ip-address 192.168.10.2 --keyring-backend=test
docker-compose up -d

localnet-stop:
Expand Down
4 changes: 2 additions & 2 deletions db/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

// FIXME: gorocksdb bindings for OptimisticTransactionDB are not merged upstream, so we use a fork
// Note: gorocksdb bindings for OptimisticTransactionDB are not merged upstream, so we use a fork
// See https://github.com/tecbot/gorocksdb/pull/216
replace github.com/tecbot/gorocksdb => github.com/roysc/gorocksdb v1.1.1
replace github.com/tecbot/gorocksdb => github.com/cosmos/gorocksdb v1.1.1
4 changes: 2 additions & 2 deletions db/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cosmos/gorocksdb v1.1.1 h1:N0OqpEKXgsi2qtDm8T1+AlNMXkTm6s1jowYf7/4pH5I=
github.com/cosmos/gorocksdb v1.1.1/go.mod h1:b/U29r/CtguX3TF7mKG1Jjn4APDqh4wECshxXdiWHpA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down Expand Up @@ -99,8 +101,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/roysc/gorocksdb v1.1.1 h1:5qKNwi7V/AchRMjyVf5TMCcZP70ro+VyaRmQxzpRvd4=
github.com/roysc/gorocksdb v1.1.1/go.mod h1:b/U29r/CtguX3TF7mKG1Jjn4APDqh4wECshxXdiWHpA=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
Expand Down
4 changes: 3 additions & 1 deletion db/memdb/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ const (
//
// Versioning is implemented by maintaining references to copy-on-write clones of the backing btree.
//
// TODO: Currently transactions do not detect write conflicts, so writers cannot be used concurrently.
// Note: Currently, transactions do not detect write conflicts, so multiple writers cannot be
// safely committed to overlapping domains. Because of this, the number of open writers is
// limited to 1.
type MemDB struct {
btree *btree.BTree // Main contents
mtx sync.RWMutex // Guards version history
Expand Down
60 changes: 55 additions & 5 deletions db/prefix/prefix.go
Original file line number Diff line number Diff line change
@@ -1,39 +1,62 @@
// Prefixed DB reader/writer types let you namespace multiple DBs within a single DB.

package prefix

import (
dbm "github.com/cosmos/cosmos-sdk/db"
)

// Prefix Reader/Writer lets you namespace multiple DBs within a single DB.
// prefixed Reader
type prefixR struct {
db dbm.DBReader
prefix []byte
}

// prefixed ReadWriter
type prefixRW struct {
db dbm.DBReadWriter
prefix []byte
}

// prefixed Writer
type prefixW struct {
db dbm.DBWriter
prefix []byte
}

var _ dbm.DBReader = (*prefixR)(nil)
var _ dbm.DBReadWriter = (*prefixRW)(nil)
var _ dbm.DBWriter = (*prefixW)(nil)

// NewPrefixReader returns a DBReader that only has access to the subset of DB keys
// that contain the given prefix.
func NewPrefixReader(db dbm.DBReader, prefix []byte) prefixR {
return prefixR{
prefix: prefix,
db: db,
}
}

// NewPrefixReadWriter returns a DBReader that only has access to the subset of DB keys
// that contain the given prefix.
func NewPrefixReadWriter(db dbm.DBReadWriter, prefix []byte) prefixRW {
return prefixRW{
prefix: prefix,
db: db,
}
}

// NewPrefixWriter returns a DBWriter that reads/writes only from the subset of DB keys
// that contain the given prefix
func NewPrefixWriter(db dbm.DBWriter, prefix []byte) prefixW {
return prefixW{
prefix: prefix,
db: db,
}
}

func prefixed(prefix, key []byte) []byte {
return append(prefix, key...)
return append(cp(prefix), key...)
}

// Get implements DBReader.
Expand Down Expand Up @@ -135,15 +158,42 @@ func (pdb prefixRW) Commit() error { return pdb.db.Commit() }
// Discard implements DBReadWriter.
func (pdb prefixRW) Discard() error { return pdb.db.Discard() }

// Returns a slice of the same length (big endian), but incremented by one.
// Set implements DBReadWriter.
func (pdb prefixW) Set(key []byte, value []byte) error {
if len(key) == 0 {
return dbm.ErrKeyEmpty
}
return pdb.db.Set(prefixed(pdb.prefix, key), value)
}

// Delete implements DBWriter.
func (pdb prefixW) Delete(key []byte) error {
if len(key) == 0 {
return dbm.ErrKeyEmpty
}
return pdb.db.Delete(prefixed(pdb.prefix, key))
}

// Close implements DBWriter.
func (pdb prefixW) Commit() error { return pdb.db.Commit() }

// Discard implements DBReadWriter.
func (pdb prefixW) Discard() error { return pdb.db.Discard() }

func cp(bz []byte) (ret []byte) {
ret = make([]byte, len(bz))
copy(ret, bz)
return ret
}

// Returns a new slice of the same length (big endian), but incremented by one.
// Returns nil on overflow (e.g. if bz bytes are all 0xFF)
// CONTRACT: len(bz) > 0
func cpIncr(bz []byte) (ret []byte) {
if len(bz) == 0 {
panic("cpIncr expects non-zero bz length")
}
ret = make([]byte, len(bz))
copy(ret, bz)
ret = cp(bz)
for i := len(bz) - 1; i >= 0; i-- {
if ret[i] < byte(0xFF) {
ret[i]++
Expand Down
2 changes: 2 additions & 0 deletions db/rocksdb/batch.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build rocksdb_build

package rocksdb

import (
Expand Down
2 changes: 2 additions & 0 deletions db/rocksdb/db.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build rocksdb_build

package rocksdb

import (
Expand Down
24 changes: 19 additions & 5 deletions db/rocksdb/db_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//go:build rocksdb_build

package rocksdb

import (
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -46,18 +49,29 @@ func TestRevertRecovery(t *testing.T) {
dir := t.TempDir()
db, err := NewDB(dir)
require.NoError(t, err)
_, err = db.SaveNextVersion()
require.NoError(t, err)
txn := db.Writer()
require.NoError(t, txn.Set([]byte{1}, []byte{1}))
require.NoError(t, txn.Commit())
_, err = db.SaveNextVersion()
require.NoError(t, err)
txn = db.Writer()
require.NoError(t, txn.Set([]byte{2}, []byte{2}))
require.NoError(t, txn.Commit())

// make checkpoints dir temporarily unreadable to trigger an error
require.NoError(t, os.Chmod(db.checkpointsDir(), 0000))
// move checkpoints dir temporarily to trigger an error
hideDir := filepath.Join(dir, "hide_checkpoints")
require.NoError(t, os.Rename(db.checkpointsDir(), hideDir))
require.Error(t, db.Revert())
require.NoError(t, os.Rename(hideDir, db.checkpointsDir()))

require.NoError(t, os.Chmod(db.checkpointsDir(), 0755))
db, err = NewDB(dir)
require.NoError(t, err)
view := db.Reader()
val, err := view.Get([]byte{1})
require.NoError(t, err)
require.Equal(t, []byte{1}, val)
val, err = view.Get([]byte{2})
require.NoError(t, err)
require.Nil(t, val)
view.Discard()
}
2 changes: 2 additions & 0 deletions db/rocksdb/iterator.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build rocksdb_build

package rocksdb

import (
Expand Down
Loading