2017-12-12 20:13:51 -08:00
|
|
|
package store
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2018-01-15 17:10:46 -08:00
|
|
|
|
2017-12-12 20:13:51 -08:00
|
|
|
dbm "github.com/tendermint/tmlibs/db"
|
|
|
|
"github.com/tendermint/tmlibs/merkle"
|
2018-01-15 17:10:46 -08:00
|
|
|
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2017-12-12 20:13:51 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestMultistoreCommitLoad(t *testing.T) {
|
|
|
|
db := dbm.NewMemDB()
|
|
|
|
store := newMultiStoreWithLoaders(db)
|
|
|
|
err := store.LoadLatestVersion()
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
// new store has empty last commit
|
|
|
|
commitID := CommitID{}
|
|
|
|
checkStore(t, store, commitID, commitID)
|
|
|
|
|
|
|
|
// make a few commits and check them
|
|
|
|
nCommits := int64(3)
|
|
|
|
for i := int64(0); i < nCommits; i++ {
|
|
|
|
commitID = store.Commit()
|
|
|
|
expectedCommitID := getExpectedCommitID(store, i+1)
|
|
|
|
checkStore(t, store, expectedCommitID, commitID)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load the latest multistore again and check version
|
|
|
|
store = newMultiStoreWithLoaders(db)
|
|
|
|
err = store.LoadLatestVersion()
|
|
|
|
assert.Nil(t, err)
|
|
|
|
commitID = getExpectedCommitID(store, nCommits)
|
|
|
|
checkStore(t, store, commitID, commitID)
|
|
|
|
|
|
|
|
// commit and check version
|
|
|
|
commitID = store.Commit()
|
|
|
|
expectedCommitID := getExpectedCommitID(store, nCommits+1)
|
|
|
|
checkStore(t, store, expectedCommitID, commitID)
|
|
|
|
|
|
|
|
// Load an older multistore and check version
|
|
|
|
ver := nCommits - 1
|
|
|
|
store = newMultiStoreWithLoaders(db)
|
|
|
|
err = store.LoadVersion(ver)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
commitID = getExpectedCommitID(store, ver)
|
|
|
|
checkStore(t, store, commitID, commitID)
|
|
|
|
|
|
|
|
// XXX: commit this older version
|
|
|
|
commitID = store.Commit()
|
|
|
|
expectedCommitID = getExpectedCommitID(store, ver+1)
|
|
|
|
checkStore(t, store, expectedCommitID, commitID)
|
|
|
|
|
|
|
|
// XXX: confirm old commit is overwritten and
|
|
|
|
// we have rolled back LatestVersion
|
|
|
|
store = newMultiStoreWithLoaders(db)
|
|
|
|
err = store.LoadLatestVersion()
|
|
|
|
assert.Nil(t, err)
|
|
|
|
commitID = getExpectedCommitID(store, ver+1)
|
|
|
|
checkStore(t, store, commitID, commitID)
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
// utils
|
|
|
|
|
|
|
|
func newMultiStoreWithLoaders(db dbm.DB) *rootMultiStore {
|
2018-01-06 12:53:31 -08:00
|
|
|
store := NewCommitMultiStore(db)
|
2018-01-15 17:10:46 -08:00
|
|
|
storeLoaders := map[SubstoreKey]CommitStoreLoader{
|
|
|
|
sdk.NewKVStoreKey("store1"): newMockCommitStore,
|
|
|
|
sdk.NewKVStoreKey("store2"): newMockCommitStore,
|
|
|
|
sdk.NewKVStoreKey("store3"): newMockCommitStore,
|
2017-12-12 20:13:51 -08:00
|
|
|
}
|
2018-01-15 17:10:46 -08:00
|
|
|
for key, loader := range storeLoaders {
|
|
|
|
store.SetSubstoreLoader(key, loader)
|
2017-12-12 20:13:51 -08:00
|
|
|
}
|
|
|
|
return store
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkStore(t *testing.T, store *rootMultiStore, expect, got CommitID) {
|
2017-12-19 21:23:51 -08:00
|
|
|
assert.EqualValues(t, expect.Version+1, store.NextVersion())
|
2017-12-12 20:13:51 -08:00
|
|
|
assert.Equal(t, expect, got)
|
|
|
|
assert.Equal(t, expect, store.LastCommitID())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func getExpectedCommitID(store *rootMultiStore, ver int64) CommitID {
|
|
|
|
return CommitID{
|
|
|
|
Version: ver,
|
|
|
|
Hash: hashStores(store.substores),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-15 17:10:46 -08:00
|
|
|
func hashStores(stores map[SubstoreKey]CommitStore) []byte {
|
2017-12-12 20:13:51 -08:00
|
|
|
m := make(map[string]interface{}, len(stores))
|
2018-01-15 17:10:46 -08:00
|
|
|
for key, store := range stores {
|
|
|
|
name := key.Name()
|
2017-12-12 20:13:51 -08:00
|
|
|
m[name] = substore{
|
|
|
|
Name: name,
|
|
|
|
substoreCore: substoreCore{
|
|
|
|
CommitID: store.Commit(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return merkle.SimpleHashFromMap(m)
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------
|
|
|
|
// mockCommitStore
|
|
|
|
|
|
|
|
var _ CommitStore = (*mockCommitStore)(nil)
|
|
|
|
|
|
|
|
type mockCommitStore struct {
|
|
|
|
id CommitID
|
|
|
|
}
|
|
|
|
|
|
|
|
func newMockCommitStore(id CommitID) (CommitStore, error) {
|
|
|
|
return &mockCommitStore{id}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cs *mockCommitStore) Commit() CommitID {
|
|
|
|
return cs.id
|
|
|
|
}
|
|
|
|
func (cs *mockCommitStore) CacheWrap() CacheWrap {
|
|
|
|
cs2 := *cs
|
|
|
|
return &cs2
|
|
|
|
}
|
|
|
|
func (cs *mockCommitStore) Write() {}
|