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 1 commit
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
Prev Previous commit
Next Next commit
fix build
  • Loading branch information
yihuang committed Apr 14, 2023
commit 82b3dc65dcfa741e06caedc562b2cd57017a7ada
30 changes: 20 additions & 10 deletions memiavl/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,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 @@ -234,7 +232,7 @@ func (db *DB) RewriteSnapshot() error {
if err := db.WriteSnapshot(snapshotDir); err != nil {
return err
}
tmpLink := filepath.Join(db.dir, "current-tmp")
tmpLink := currentTmpPath(db.dir)
if err := os.Symlink(snapshotDir, tmpLink); err != nil {
return err
}
Expand All @@ -256,7 +254,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 @@ -316,6 +318,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 @@ -335,5 +341,9 @@ func initEmptyDB(dir string, initialVersion uint32) error {
if err := tmp.WriteSnapshot(snapshotDir); err != nil {
return err
}
return os.Symlink(snapshotDir, currentPath(dir))
tmpPath := currentTmpPath(dir)
if err := os.Symlink(snapshotDir, tmpPath); err != nil {
return err
}
return os.Rename(tmpPath, currentPath(dir))
mmsqe marked this conversation as resolved.
Show resolved Hide resolved
}
30 changes: 21 additions & 9 deletions memiavl/multitree.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (

const MetadataFileName = "__metadata"

type namedTree struct {
type NamedTree struct {
tree *Tree
name string
}
Expand All @@ -45,7 +45,7 @@ type MultiTree struct {
// it always corresponds to the wal entry with index 1.
initialVersion uint32

trees []namedTree
trees []NamedTree
treesByName map[string]int // reversed index of the trees
lastCommitInfo storetypes.CommitInfo
}
Expand Down Expand Up @@ -96,11 +96,11 @@ func LoadMultiTree(dir string) (*MultiTree, error) {

sort.Strings(treeNames)

trees := make([]namedTree, len(treeNames))
trees := make([]NamedTree, len(treeNames))
treesByName := make(map[string]int, len(trees))
for i, name := range treeNames {
tree := treeMap[name]
trees[i] = namedTree{tree: tree, name: name}
trees[i] = NamedTree{tree: tree, name: name}
treesByName[name] = i
}

Expand All @@ -114,6 +114,14 @@ func LoadMultiTree(dir string) (*MultiTree, error) {
return mtree, nil
}

func (t *MultiTree) Trees() []NamedTree {
return t.trees
}

func (t *MultiTree) TreeByName(name string) *Tree {
return t.trees[t.treesByName[name]].tree
}

func (t *MultiTree) SetInitialVersion(initialVersion int64) error {
if initialVersion >= math.MaxUint32 {
return fmt.Errorf("version overflows uint32: %d", initialVersion)
Expand Down Expand Up @@ -142,11 +150,11 @@ func (t *MultiTree) setInitialVersion(initialVersion int64) {

// Copy returns a snapshot of the tree which won't be corrupted by further modifications on the main tree.
func (t *MultiTree) Copy() *MultiTree {
trees := make([]namedTree, len(t.trees))
trees := make([]NamedTree, len(t.trees))
treesByName := make(map[string]int, len(t.trees))
for i, entry := range t.trees {
tree := entry.tree.Copy()
trees[i] = namedTree{tree: tree, name: entry.name}
trees[i] = NamedTree{tree: tree, name: entry.name}
treesByName[entry.name] = i
}

Expand All @@ -164,6 +172,10 @@ func (t *MultiTree) Version() int64 {
return t.lastCommitInfo.Version
}

func (t *MultiTree) LastCommitInfo() storetypes.CommitInfo {
return t.lastCommitInfo
}

// ApplyUpgrades store name upgrades
func (t *MultiTree) ApplyUpgrades(upgrades []*TreeNameUpgrade) error {
if len(upgrades) == 0 {
Expand All @@ -175,7 +187,7 @@ func (t *MultiTree) ApplyUpgrades(upgrades []*TreeNameUpgrade) error {
for _, upgrade := range upgrades {
switch {
case upgrade.Delete:
i := slices.IndexFunc(t.trees, func(entry namedTree) bool {
i := slices.IndexFunc(t.trees, func(entry NamedTree) bool {
return entry.name == upgrade.Name
})
if i < 0 {
Expand All @@ -186,7 +198,7 @@ func (t *MultiTree) ApplyUpgrades(upgrades []*TreeNameUpgrade) error {
t.trees = t.trees[:len(t.trees)-1]
case upgrade.RenameFrom != "":
// rename tree
i := slices.IndexFunc(t.trees, func(entry namedTree) bool {
i := slices.IndexFunc(t.trees, func(entry NamedTree) bool {
return entry.name == upgrade.RenameFrom
})
if i < 0 {
Expand All @@ -196,7 +208,7 @@ func (t *MultiTree) ApplyUpgrades(upgrades []*TreeNameUpgrade) error {
default:
// add tree
tree := NewWithInitialVersion(uint32(nextVersion(t.Version(), t.initialVersion)))
t.trees = append(t.trees, namedTree{tree: tree, name: upgrade.Name})
t.trees = append(t.trees, NamedTree{tree: tree, name: upgrade.Name})
}
}

Expand Down
21 changes: 0 additions & 21 deletions memiavl/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"crypto/sha256"
"errors"
"math"
"os"

"github.com/cosmos/iavl"
dbm "github.com/tendermint/tm-db"
Expand Down Expand Up @@ -72,26 +71,6 @@ func (t *Tree) Copy() *Tree {
return &newTree
}

// Load try to load an existing memiavl tree at the directory,
// if the directory don't exists, creates an empty tree with the provided initial version.
func Load(dir string, initialVersion int64) (*Tree, error) {
snapshot, err := OpenSnapshot(dir)
if err != nil {
if os.IsNotExist(err) {
return NewWithInitialVersion(initialVersion), nil
}
return nil, err
}
return NewFromSnapshot(snapshot), nil
}

func (t *Tree) SetInitialVersion(version int64) {
if version >= int64(math.MaxUint32) {
panic("version overflows uint32")
}
t.initialVersion = uint32(version)
}

// ApplyChangeSet apply the change set of a whole version, and update hashes.
func (t *Tree) ApplyChangeSet(changeSet iavl.ChangeSet, updateHash bool) ([]byte, int64, error) {
for _, pair := range changeSet.Pairs {
Expand Down
4 changes: 2 additions & 2 deletions store/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/ledgerwatch/erigon-lib v0.0.0-20230210071639-db0e7ed11263 h1:LGEzZvf33Y1NhuP5+jI/ni9l1TFS6oYPDilgy74NusM=
github.com/ledgerwatch/erigon-lib v0.0.0-20230210071639-db0e7ed11263/go.mod h1:OXgMDuUo2lZ3NpH29ZvMYbk+LxFd5ffDl2Z2mGMuY/I=
github.com/ledgerwatch/log/v3 v3.7.0 h1:aFPEZdwZx4jzA3+/Pf8wNDN5tCI0cIolq/kfvgcM+og=
Expand Down
34 changes: 14 additions & 20 deletions store/memiavlstore/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,18 @@ var (

// Store Implements types.KVStore and CommitKVStore.
type Store struct {
tree memiavl.Tree
tree *memiavl.Tree
logger log.Logger

changeSet iavl.ChangeSet
}

func LoadStoreWithInitialVersion(dir string, logger log.Logger, initialVersion int64) (types.CommitKVStore, error) {
tree, err := memiavl.Load(dir, initialVersion)
if err != nil {
return nil, err
}
return &Store{tree: *tree, logger: logger}, nil
func New(tree *memiavl.Tree, logger log.Logger) *Store {
return &Store{tree: tree, logger: logger}
}

func (st *Store) Commit() types.CommitID {
hash, version, err := st.tree.ApplyChangeSet(&st.changeSet, true)
if err != nil {
panic(err)
}
st.changeSet.Pairs = st.changeSet.Pairs[:0]

return types.CommitID{
Version: version,
Hash: hash,
}
panic("memiavl store is not supposed to be committed alone")
}

func (st *Store) LastCommitID() types.CommitID {
Expand Down Expand Up @@ -87,7 +74,7 @@ func (st *Store) CacheWrapWithTrace(w io.Writer, tc types.TraceContext) types.Ca
//
// we assume Set is only called in `Commit`, so the written state is only visible after commit.
func (st *Store) Set(key, value []byte) {
st.changeSet.Pairs = append(st.changeSet.Pairs, iavl.KVPair{
st.changeSet.Pairs = append(st.changeSet.Pairs, &iavl.KVPair{
Key: key, Value: value,
})
}
Expand All @@ -106,7 +93,7 @@ func (st *Store) Has(key []byte) bool {
//
// we assume Delete is only called in `Commit`, so the written state is only visible after commit.
func (st *Store) Delete(key []byte) {
st.changeSet.Pairs = append(st.changeSet.Pairs, iavl.KVPair{
st.changeSet.Pairs = append(st.changeSet.Pairs, &iavl.KVPair{
Key: key, Delete: true,
})
}
Expand All @@ -123,5 +110,12 @@ func (st *Store) ReverseIterator(start, end []byte) types.Iterator {
// starting a new chain at an arbitrary height.
// implements interface StoreWithInitialVersion
func (st *Store) SetInitialVersion(version int64) {
st.tree.SetInitialVersion(version)
panic("memiavl store's SetInitialVersion is not supposed to be called directly")
}

// PopChangeSet returns the change set and clear it
func (st *Store) PopChangeSet() iavl.ChangeSet {
cs := st.changeSet
st.changeSet = iavl.ChangeSet{}
return cs
}
Loading