Skip to content

Commit

Permalink
Problem: memiavl result is different when replaying write-ahead-log (#…
Browse files Browse the repository at this point in the history
…1088)

if there are empty values, because protobuf decodes empty value as `nil`.

Solution:
- make sure empty value is represented as empty slice instead of nil in set operation.
  • Loading branch information
yihuang authored Jul 1, 2023
1 parent d75ed1a commit 91fbcb4
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- [#1075](https://github.com/crypto-org-chain/cronos/pull/1075) Add missing close in memiavl to avoid resource leaks.
- [#1073](https://github.com/crypto-org-chain/cronos/pull/1073) memiavl automatically truncate corrupted wal tail.
- [#1087](https://github.com/crypto-org-chain/cronos/pull/1087) memiavl fix LastCommitID when memiavl db not loaded.
- [#1088](https://github.com/crypto-org-chain/cronos/pull/1088) memiavl fix empty value in write-ahead-log replaying.

### Features

Expand Down
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -999,7 +999,7 @@ func VerifyAddressFormat(bz []byte) error {
// Close will be called in graceful shutdown in start cmd
func (app *App) Close() error {
if cms, ok := app.CommitMultiStore().(*memiavlrootmulti.Store); ok {
return cms.WaitAsyncCommit()
return cms.Close()
}

return nil
Expand Down
15 changes: 5 additions & 10 deletions memiavl/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,10 @@ func (db *DB) WaitAsyncCommit() error {
db.mtx.Lock()
defer db.mtx.Unlock()

return db.waitAsyncCommit()
}

func (db *DB) waitAsyncCommit() error {
if db.walChan == nil {
return nil
}
Expand Down Expand Up @@ -547,16 +551,7 @@ func (db *DB) Close() error {
db.mtx.Lock()
defer db.mtx.Unlock()

var walErr error
if db.walChan != nil {
close(db.walChan)
walErr = <-db.walQuit

db.walChan = nil
db.walQuit = nil
}

return errors.Join(db.MultiTree.Close(), db.wal.Close(), walErr)
return errors.Join(db.waitAsyncCommit(), db.MultiTree.Close(), db.wal.Close())
}

// TreeByName wraps MultiTree.TreeByName to add a lock.
Expand Down
30 changes: 30 additions & 0 deletions memiavl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,3 +283,33 @@ func TestWalIndexConversion(t *testing.T) {
require.Equal(t, tc.version, walVersion(tc.index, tc.initialVersion))
}
}

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

_, _, err = db.Commit([]*NamedChangeSet{
{Name: "test", Changeset: iavl.ChangeSet{
Pairs: []*iavl.KVPair{
{Key: []byte("hello1"), Value: []byte("")},
{Key: []byte("hello2"), Value: []byte("")},
{Key: []byte("hello3"), Value: []byte("")},
},
}},
})
require.NoError(t, err)
hash, version, err := db.Commit([]*NamedChangeSet{
{Name: "test", Changeset: iavl.ChangeSet{
Pairs: []*iavl.KVPair{{Key: []byte("hello1"), Delete: true}},
}},
})
require.NoError(t, err)

require.NoError(t, db.Close())

db, err = Load(dir, Options{ZeroCopy: true})
require.NoError(t, err)
require.Equal(t, version, db.Version())
require.Equal(t, hash, db.LastCommitInfo().CommitID().Hash)
}
4 changes: 4 additions & 0 deletions memiavl/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ func (t *Tree) ApplyChangeSet(changeSet iavl.ChangeSet, updateHash bool) ([]byte
}

func (t *Tree) set(key, value []byte) {
if value == nil {
// the value could be nil when replaying changes from write-ahead-log because of protobuf decoding
value = []byte{}
}
t.root, _ = setRecursive(t.root, key, value, t.version+1, t.cowVersion)
t.cache.Add(&cacheNode{key, value})
}
Expand Down
4 changes: 2 additions & 2 deletions store/rootmulti/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ func (rs *Store) Commit() types.CommitID {
return rs.lastCommitInfo.CommitID()
}

func (rs *Store) WaitAsyncCommit() error {
return rs.db.WaitAsyncCommit()
func (rs *Store) Close() error {
return rs.db.Close()
}

// Implements interface Committer
Expand Down

0 comments on commit 91fbcb4

Please sign in to comment.