Co-authored-by: mmsqe <mavis@crypto.com> Co-authored-by: Marko <marko@baricevic.me> Co-authored-by: marbar3778 <marbar3778@yahoo.com>
151 lines
4.6 KiB
Go
151 lines
4.6 KiB
Go
package root
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
corestore "cosmossdk.io/core/store"
|
|
coretesting "cosmossdk.io/core/testing"
|
|
"cosmossdk.io/log"
|
|
"cosmossdk.io/store/v2"
|
|
"cosmossdk.io/store/v2/commitment"
|
|
"cosmossdk.io/store/v2/commitment/iavl"
|
|
dbm "cosmossdk.io/store/v2/db"
|
|
"cosmossdk.io/store/v2/pruning"
|
|
)
|
|
|
|
var storeKeys = []string{"store1", "store2", "store3"}
|
|
|
|
type MigrateStoreTestSuite struct {
|
|
suite.Suite
|
|
|
|
rootStore store.RootStore
|
|
}
|
|
|
|
func TestMigrateStoreTestSuite(t *testing.T) {
|
|
suite.Run(t, &MigrateStoreTestSuite{})
|
|
}
|
|
|
|
func (s *MigrateStoreTestSuite) SetupTest() {
|
|
testLog := log.NewTestLogger(s.T())
|
|
nopLog := coretesting.NewNopLogger()
|
|
|
|
mdb := dbm.NewMemDB()
|
|
multiTrees := make(map[string]commitment.Tree)
|
|
for _, storeKey := range storeKeys {
|
|
prefixDB := dbm.NewPrefixDB(mdb, []byte(storeKey))
|
|
multiTrees[storeKey] = iavl.NewIavlTree(prefixDB, nopLog, iavl.DefaultConfig())
|
|
}
|
|
orgSC, err := commitment.NewCommitStore(multiTrees, nil, mdb, testLog)
|
|
s.Require().NoError(err)
|
|
|
|
// apply changeset against the original store
|
|
toVersion := uint64(200)
|
|
keyCount := 10
|
|
for version := uint64(1); version <= toVersion; version++ {
|
|
cs := corestore.NewChangeset(version)
|
|
for _, storeKey := range storeKeys {
|
|
for i := 0; i < keyCount; i++ {
|
|
cs.Add([]byte(storeKey), []byte(fmt.Sprintf("key-%d-%d", version, i)), []byte(fmt.Sprintf("value-%d-%d", version, i)), false)
|
|
}
|
|
}
|
|
s.Require().NoError(orgSC.WriteChangeset(cs))
|
|
_, err = orgSC.Commit(version)
|
|
s.Require().NoError(err)
|
|
}
|
|
|
|
multiTrees1 := make(map[string]commitment.Tree)
|
|
for _, storeKey := range storeKeys {
|
|
multiTrees1[storeKey] = iavl.NewIavlTree(dbm.NewMemDB(), nopLog, iavl.DefaultConfig())
|
|
}
|
|
sc, err := commitment.NewCommitStore(multiTrees1, nil, dbm.NewMemDB(), testLog)
|
|
s.Require().NoError(err)
|
|
|
|
pm := pruning.NewManager(sc, nil)
|
|
|
|
// assume no storage store, simulate the migration process
|
|
s.rootStore, err = New(dbm.NewMemDB(), testLog, orgSC, pm, nil)
|
|
s.Require().NoError(err)
|
|
}
|
|
|
|
func (s *MigrateStoreTestSuite) TestMigrateState() {
|
|
err := s.rootStore.LoadLatestVersion()
|
|
s.Require().NoError(err)
|
|
originalLatestVersion, err := s.rootStore.GetLatestVersion()
|
|
s.Require().NoError(err)
|
|
|
|
// check if the Query fallback to the original SC
|
|
for version := uint64(1); version <= originalLatestVersion; version++ {
|
|
for _, storeKey := range storeKeys {
|
|
for i := 0; i < 10; i++ {
|
|
res, err := s.rootStore.Query([]byte(storeKey), version, []byte(fmt.Sprintf("key-%d-%d", version, i)), true)
|
|
s.Require().NoError(err)
|
|
s.Require().Equal([]byte(fmt.Sprintf("value-%d-%d", version, i)), res.Value)
|
|
}
|
|
}
|
|
}
|
|
|
|
// continue to apply changeset against the original store
|
|
latestVersion := originalLatestVersion + 1
|
|
keyCount := 10
|
|
for ; latestVersion < 2*originalLatestVersion; latestVersion++ {
|
|
cs := corestore.NewChangeset(latestVersion)
|
|
for _, storeKey := range storeKeys {
|
|
for i := 0; i < keyCount; i++ {
|
|
cs.Add([]byte(storeKey), []byte(fmt.Sprintf("key-%d-%d", latestVersion, i)), []byte(fmt.Sprintf("value-%d-%d", latestVersion, i)), false)
|
|
}
|
|
}
|
|
_, err = s.rootStore.Commit(cs)
|
|
s.Require().NoError(err)
|
|
|
|
// check if the migration is completed
|
|
ver, err := s.rootStore.GetLatestVersion()
|
|
s.Require().NoError(err)
|
|
if ver == latestVersion {
|
|
break
|
|
}
|
|
|
|
// add some delay to simulate the consensus process
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
|
|
// check if the migration is successful
|
|
version, err := s.rootStore.GetLatestVersion()
|
|
s.Require().NoError(err)
|
|
s.Require().Equal(latestVersion, version)
|
|
|
|
// query against the migrated store
|
|
for version := uint64(1); version <= latestVersion; version++ {
|
|
for _, storeKey := range storeKeys {
|
|
for i := 0; i < keyCount; i++ {
|
|
targetVersion := version
|
|
if version < originalLatestVersion {
|
|
targetVersion = originalLatestVersion
|
|
}
|
|
res, err := s.rootStore.Query([]byte(storeKey), targetVersion, []byte(fmt.Sprintf("key-%d-%d", version, i)), true)
|
|
s.Require().NoError(err)
|
|
s.Require().Equal([]byte(fmt.Sprintf("value-%d-%d", version, i)), res.Value)
|
|
}
|
|
}
|
|
}
|
|
|
|
// apply changeset against the migrated store
|
|
for version := latestVersion + 1; version <= latestVersion+10; version++ {
|
|
cs := corestore.NewChangeset(version)
|
|
for _, storeKey := range storeKeys {
|
|
for i := 0; i < keyCount; i++ {
|
|
cs.Add([]byte(storeKey), []byte(fmt.Sprintf("key-%d-%d", version, i)), []byte(fmt.Sprintf("value-%d-%d", version, i)), false)
|
|
}
|
|
}
|
|
_, err = s.rootStore.Commit(cs)
|
|
s.Require().NoError(err)
|
|
}
|
|
|
|
version, err = s.rootStore.GetLatestVersion()
|
|
s.Require().NoError(err)
|
|
s.Require().Equal(latestVersion+10, version)
|
|
}
|