Merge pull request #859 from cosmos/jae/fixrmssubstores

Support namespacing within RMS db
This commit is contained in:
Christopher Goes 2018-04-15 02:35:15 +02:00 committed by GitHub
commit b846559ac1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 152 additions and 197 deletions

View File

@ -2,18 +2,20 @@
## 0.15.0 (TBD)
FEATURES:
* Add CacheContext
* Add auto sequencing to client
BREAKING CHANGES
* Remove go-wire, use go-amino
* [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface
* [basecoin] NewBasecoinApp takes a `dbm.DB` and uses namespaced DBs for substores
FEATURES:
BUG FIXES
* Add CacheContext
FEATURES:
* Add auto sequencing to client
* MountStoreWithDB without providing a custom store works.
## 0.14.1 (April 9, 2018)

18
Gopkg.lock generated
View File

@ -215,8 +215,8 @@
[[projects]]
name = "github.com/spf13/pflag"
packages = ["."]
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
version = "v1.0.0"
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
version = "v1.0.1"
[[projects]]
name = "github.com/spf13/viper"
@ -342,8 +342,8 @@
"types/priv_validator",
"version"
]
revision = "dcd00b0e688f133b9634aee513f8bf856e659356"
version = "v0.19.0-rc4"
revision = "d0beaba7e8a5652506a34b5fab299cc2dc274c02"
version = "v0.19.0"
[[projects]]
name = "github.com/tendermint/tmlibs"
@ -360,8 +360,8 @@
"pubsub",
"pubsub/query"
]
revision = "2e24b64fc121dcdf1cabceab8dc2f7257675483c"
version = "v0.8.1"
revision = "737154202faf75c70437f59ba5303f2eb09f5636"
version = "0.8.2-rc1"
[[projects]]
branch = "master"
@ -377,7 +377,7 @@
"ripemd160",
"salsa20/salsa"
]
revision = "b2aa35443fbc700ab74c586ae79b81c171851023"
revision = "d6449816ce06963d9d136eee5a56fca5b0616e7e"
[[projects]]
branch = "master"
@ -424,7 +424,7 @@
branch = "master"
name = "google.golang.org/genproto"
packages = ["googleapis/rpc/status"]
revision = "ce84044298496ef4b54b4a0a0909ba593cc60e30"
revision = "51d0944304c3cbce4afe9e5247e21100037bff78"
[[projects]]
name = "google.golang.org/grpc"
@ -459,6 +459,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "ad499422ee60cf89fd9d61e232e33d0a17f7b43e0ff7aff0c0a22949901096e8"
inputs-digest = "b6b2d696a242e715ddb8b25c93b3c8f7e7cabc9292eab29dffe935eddbd35fb8"
solver-name = "gps-cdcl"
solver-version = 1

View File

@ -70,11 +70,11 @@
[[constraint]]
name = "github.com/tendermint/tendermint"
version = "0.19.0-rc4"
version = "0.19.0"
[[constraint]]
[[override]]
name = "github.com/tendermint/tmlibs"
version = "~0.8.1"
version = "~0.8.2-rc1"
[prune]
go-tests = true

View File

@ -71,21 +71,20 @@ func (app *BaseApp) Name() string {
}
// Mount a store to the provided key in the BaseApp multistore
// Broken until #532 is implemented.
func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) {
for _, key := range keys {
app.MountStore(key, sdk.StoreTypeIAVL)
}
}
// Mount a store to the provided key in the BaseApp multistore
// Mount a store to the provided key in the BaseApp multistore, using a specified DB
func (app *BaseApp) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) {
app.cms.MountStoreWithDB(key, typ, db)
}
// Mount a store to the provided key in the BaseApp multistore
// Mount a store to the provided key in the BaseApp multistore, using the default DB
func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) {
app.cms.MountStoreWithDB(key, typ, app.db)
app.cms.MountStoreWithDB(key, typ, nil)
}
// nolint - Set functions

View File

@ -35,15 +35,12 @@ func TestMountStores(t *testing.T) {
// make some cap keys
capKey1 := sdk.NewKVStoreKey("key1")
db1 := dbm.NewMemDB()
capKey2 := sdk.NewKVStoreKey("key2")
db2 := dbm.NewMemDB()
// no stores are mounted
assert.Panics(t, func() { app.LoadLatestVersion(capKey1) })
app.MountStoreWithDB(capKey1, sdk.StoreTypeIAVL, db1)
app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2)
app.MountStoresIAVL(capKey1, capKey2)
// stores are mounted
err := app.LoadLatestVersion(capKey1)
@ -155,11 +152,8 @@ func TestInitChainer(t *testing.T) {
// NOTE/TODO: mounting multiple stores is broken
// see https://github.com/cosmos/cosmos-sdk/issues/532
capKey := sdk.NewKVStoreKey("main")
db1 := dbm.NewMemDB()
capKey2 := sdk.NewKVStoreKey("key2")
db2 := dbm.NewMemDB()
app.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db1)
app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2)
app.MountStoresIAVL(capKey, capKey2)
err := app.LoadLatestVersion(capKey) // needed to make stores non-nil
assert.Nil(t, err)
@ -191,8 +185,7 @@ func TestInitChainer(t *testing.T) {
// reload app
app = NewBaseApp(name, logger, db)
app.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db1)
app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2)
app.MountStoresIAVL(capKey, capKey2)
err = app.LoadLatestVersion(capKey) // needed to make stores non-nil
assert.Nil(t, err)
app.SetInitChainer(initChainer)

View File

@ -333,13 +333,8 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
// logger = log.NewFilter(logger, log.AllowError())
privValidatorFile := config.PrivValidatorFile()
privVal := pvm.LoadOrGenFilePV(privValidatorFile)
dbs := map[string]dbm.DB{
"main": dbm.NewMemDB(),
"acc": dbm.NewMemDB(),
"ibc": dbm.NewMemDB(),
"staking": dbm.NewMemDB(),
}
app := bapp.NewBasecoinApp(logger, dbs)
db := dbm.NewMemDB()
app := bapp.NewBasecoinApp(logger, db)
cdc = bapp.MakeCodec() // XXX
genesisFile := config.GenesisFile()

View File

@ -64,7 +64,7 @@ func GetChainHeight() (int64, error) {
if err != nil {
return -1, err
}
height := status.LatestBlockHeight
height := status.SyncInfo.LatestBlockHeight
return height, nil
}

View File

@ -77,7 +77,7 @@ func NodeSyncingRequestHandler(w http.ResponseWriter, r *http.Request) {
return
}
syncing := status.Syncing
syncing := status.SyncInfo.Syncing
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))

View File

@ -28,29 +28,11 @@ var (
// TODO: distinguish from basecoin
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
dataDir := filepath.Join(rootDir, "data")
dbMain, err := dbm.NewGoLevelDB("gaia", dataDir)
db, err := dbm.NewGoLevelDB("gaia", dataDir)
if err != nil {
return nil, err
}
dbAcc, err := dbm.NewGoLevelDB("gaia-acc", dataDir)
if err != nil {
return nil, err
}
dbIBC, err := dbm.NewGoLevelDB("gaia-ibc", dataDir)
if err != nil {
return nil, err
}
dbStaking, err := dbm.NewGoLevelDB("gaia-staking", dataDir)
if err != nil {
return nil, err
}
dbs := map[string]dbm.DB{
"main": dbMain,
"acc": dbAcc,
"ibc": dbIBC,
"staking": dbStaking,
}
bapp := app.NewBasecoinApp(logger, dbs)
bapp := app.NewBasecoinApp(logger, db)
return bapp, nil
}

View File

@ -22,7 +22,7 @@ The SDK distinguishes between transactions (Tx) and messages
Users can create messages containing arbitrary information by
implementing the `Msg` interface:
```golang
```go
type Msg interface {
// Return the message type.
@ -68,7 +68,7 @@ but this is mostly for convenience and not type-safe.
For instance, the `Basecoin` message types are defined in `x/bank/tx.go`:
```golang
```go
type SendMsg struct {
Inputs []Input `json:"inputs"`
Outputs []Output `json:"outputs"`
@ -82,7 +82,7 @@ type IssueMsg struct {
Each specifies the addresses that must sign the message:
```golang
```go
func (msg SendMsg) GetSigners() []sdk.Address {
addrs := make([]sdk.Address, len(msg.Inputs))
for i, in := range msg.Inputs {
@ -100,7 +100,7 @@ func (msg IssueMsg) GetSigners() []sdk.Address {
A transaction is a message with additional information for authentication:
```golang
```go
type Tx interface {
GetMsg() Msg
@ -120,7 +120,7 @@ The `tx.GetSignatures()` method returns a list of signatures, which must match
the list of addresses returned by `tx.Msg.GetSigners()`. The signatures come in
a standard form:
```golang
```go
type StdSignature struct {
crypto.PubKey // optional
crypto.Signature
@ -146,7 +146,7 @@ to return this.
The standard way to create a transaction from a message is to use the `StdTx`:
```golang
```go
type StdTx struct {
Msg
Signatures []StdSignature
@ -164,7 +164,7 @@ When initializing an application, a developer must specify a `TxDecoder`
function which determines how an arbitrary byte array should be unmarshalled
into a `Tx`:
```golang
```go
type TxDecoder func(txBytes []byte) (Tx, error)
```
@ -177,7 +177,7 @@ relevant types to be registered ahead of type. Registration happens on a
For instance, in `Basecoin`, we wish to register the `SendMsg` and `IssueMsg`
types:
```golang
```go
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
cdc.RegisterConcrete(bank.SendMsg{}, "cosmos-sdk/SendMsg", nil)
cdc.RegisterConcrete(bank.IssueMsg{}, "cosmos-sdk/IssueMsg", nil)
@ -189,21 +189,58 @@ same prefix-bytes, regardless of what interface it is satisfying. For more
details, see the [go-amino documentation](https://github.com/tendermint/go-amino/blob/develop).
## MultiStore
## Storage
### MultiStore is like a filesystem
### Mounting an IAVLStore
### MultiStore
MultiStore is like a root filesystem of an operating system, except
all the entries are fully Merkleized. You mount onto a MultiStore
any number of Stores. Currently only KVStores are supported, but in
the future we may support more kinds of stores, such as a HeapStore
or a NDStore for multidimensional storage.
The MultiStore as well as all mounted stores provide caching (aka
cache-wrapping) for intermediate state (aka software transactional
memory) during the execution of transactions. In the case of the
KVStore, this also works for iterators. For example, after running
the app's AnteHandler, the MultiStore is cache-wrapped (and each
store is also cache-wrapped) so that should processing of the
transaction fail, at least the transaction fees are paid and
sequence incremented.
The MultiStore as well as all stores support (or will support)
historical state pruning and snapshotting and various kinds of
queries with proofs.
### KVStore
Here we'll focus on the IAVLStore, which is a kind of KVStore.
IAVLStore is a fast balanced dynamic Merkle store that also supports
iteration, and of course cache-wrapping, state pruning, and various
queries with proofs, such as proofs of existence, absence, range,
and so on.
Here's how you mount them to a MultiStore.
```go
mainDB, catDB := dbm.NewMemDB(), dbm.NewMemDB()
fooKey := sdk.NewKVStoreKey("foo")
barKey := sdk.NewKVStoreKey("bar")
catKey := sdk.NewKVStoreKey("cat")
ms := NewCommitMultiStore(mainDB)
ms.MountStoreWithDB(fooKey, sdk.StoreTypeIAVL, nil)
ms.MountStoreWithDB(barKey, sdk.StoreTypeIAVL, nil)
ms.MountStoreWithDB(catKey, sdk.StoreTypeIAVL, catDB)
```
TODO:
- IAVLStore: Fast balanced dynamic Merkle store.
- supports iteration.
- MultiStore: multiple Merkle tree backends in a single store
- allows using Ethereum Patricia Trie and Tendermint IAVL in same app
- Provide caching for intermediate state during execution of blocks and transactions (including for iteration)
- Historical state pruning and snapshotting.
- Query proofs (existence, absence, range, etc.) on current and retained historical state.
```
In the example above, all IAVL nodes (inner and leaf) will be stored
in mainDB with the prefix of "s/k:foo/" and "s/k:bar/" respectively,
thus sharing the mainDB. All IAVL nodes (inner and leaf) for the
cat KVStore are stored separately in catDB with the prefix of
"s/\_/". The "s/k:KEY/" and "s/\_/" prefixes are there to
disambiguate store items from other items of non-storage concern.
## Context
@ -223,7 +260,7 @@ Many methods on SDK objects receive a context as the first argument.
Transaction processing in the SDK is defined through `Handler` functions:
```golang
```go
type Handler func(ctx Context, tx Tx) Result
```
@ -237,7 +274,7 @@ to a particular store (or two or more). Access to stores is managed using
capabilities keys and mappers. When a handler is initialized, it is passed a
key or mapper that gives it access to the relevant stores.
```golang
```go
// File: cosmos-sdk/examples/basecoin/app/init_stores.go
app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL)
app.accountMapper = auth.NewAccountMapper(

View File

@ -38,14 +38,14 @@ type BasecoinApp struct {
accountMapper sdk.AccountMapper
}
func NewBasecoinApp(logger log.Logger, dbs map[string]dbm.DB) *BasecoinApp {
func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp {
// Create app-level codec for txs and accounts.
var cdc = MakeCodec()
// Create your application object.
var app = &BasecoinApp{
BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]),
BaseApp: bam.NewBaseApp(appName, logger, db),
cdc: cdc,
capKeyMainStore: sdk.NewKVStoreKey("main"),
capKeyAccountStore: sdk.NewKVStoreKey("acc"),
@ -72,12 +72,7 @@ func NewBasecoinApp(logger log.Logger, dbs map[string]dbm.DB) *BasecoinApp {
// Initialize BaseApp.
app.SetTxDecoder(app.txDecoder)
app.SetInitChainer(app.initChainer)
app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"])
app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"])
app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"])
app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbs["staking"])
// NOTE: Broken until #532 lands
//app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore)
app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyIBCStore, app.capKeyStakingStore)
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper))
err := app.LoadLatestVersion(app.capKeyMainStore)
if err != nil {

View File

@ -85,20 +85,15 @@ var (
}
)
func loggerAndDBs() (log.Logger, map[string]dbm.DB) {
func loggerAndDB() (log.Logger, dbm.DB) {
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
dbs := map[string]dbm.DB{
"main": dbm.NewMemDB(),
"acc": dbm.NewMemDB(),
"ibc": dbm.NewMemDB(),
"staking": dbm.NewMemDB(),
}
return logger, dbs
db := dbm.NewMemDB()
return logger, db
}
func newBasecoinApp() *BasecoinApp {
logger, dbs := loggerAndDBs()
return NewBasecoinApp(logger, dbs)
logger, db := loggerAndDB()
return NewBasecoinApp(logger, db)
}
func setGenesisAccounts(bapp *BasecoinApp, accs ...auth.BaseAccount) error {
@ -142,8 +137,8 @@ func TestMsgs(t *testing.T) {
}
func TestSortGenesis(t *testing.T) {
logger, dbs := loggerAndDBs()
bapp := NewBasecoinApp(logger, dbs)
logger, db := loggerAndDB()
bapp := NewBasecoinApp(logger, db)
// Note the order: the coins are unsorted!
coinDenom1, coinDenom2 := "foocoin", "barcoin"
@ -184,8 +179,8 @@ func TestSortGenesis(t *testing.T) {
}
func TestGenesis(t *testing.T) {
logger, dbs := loggerAndDBs()
bapp := NewBasecoinApp(logger, dbs)
logger, db := loggerAndDB()
bapp := NewBasecoinApp(logger, db)
// Construct some genesis bytes to reflect basecoin/types/AppAccount
pk := crypto.GenPrivKeyEd25519().PubKey()
@ -207,7 +202,7 @@ func TestGenesis(t *testing.T) {
assert.Equal(t, acc, res1)
// reload app and ensure the account is still there
bapp = NewBasecoinApp(logger, dbs)
bapp = NewBasecoinApp(logger, db)
ctx = bapp.BaseApp.NewContext(true, abci.Header{})
res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address)
assert.Equal(t, acc, res1)

View File

@ -27,29 +27,11 @@ var (
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
dataDir := filepath.Join(rootDir, "data")
dbMain, err := dbm.NewGoLevelDB("basecoin", dataDir)
db, err := dbm.NewGoLevelDB("basecoin", dataDir)
if err != nil {
return nil, err
}
dbAcc, err := dbm.NewGoLevelDB("basecoin-acc", dataDir)
if err != nil {
return nil, err
}
dbIBC, err := dbm.NewGoLevelDB("basecoin-ibc", dataDir)
if err != nil {
return nil, err
}
dbStaking, err := dbm.NewGoLevelDB("basecoin-staking", dataDir)
if err != nil {
return nil, err
}
dbs := map[string]dbm.DB{
"main": dbMain,
"acc": dbAcc,
"ibc": dbIBC,
"staking": dbStaking,
}
bapp := app.NewBasecoinApp(logger, dbs)
bapp := app.NewBasecoinApp(logger, db)
return bapp, nil
}

View File

@ -42,14 +42,14 @@ type DemocoinApp struct {
accountMapper sdk.AccountMapper
}
func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp {
func NewDemocoinApp(logger log.Logger, db dbm.DB) *DemocoinApp {
// Create app-level codec for txs and accounts.
var cdc = MakeCodec()
// Create your application object.
var app = &DemocoinApp{
BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]),
BaseApp: bam.NewBaseApp(appName, logger, db),
cdc: cdc,
capKeyMainStore: sdk.NewKVStoreKey("main"),
capKeyAccountStore: sdk.NewKVStoreKey("acc"),
@ -82,13 +82,7 @@ func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp {
// Initialize BaseApp.
app.SetTxDecoder(app.txDecoder)
app.SetInitChainer(app.initChainerFn(coolKeeper, powKeeper))
app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"])
app.MountStoreWithDB(app.capKeyAccountStore, sdk.StoreTypeIAVL, dbs["acc"])
app.MountStoreWithDB(app.capKeyPowStore, sdk.StoreTypeIAVL, dbs["pow"])
app.MountStoreWithDB(app.capKeyIBCStore, sdk.StoreTypeIAVL, dbs["ibc"])
app.MountStoreWithDB(app.capKeyStakingStore, sdk.StoreTypeIAVL, dbs["staking"])
// NOTE: Broken until #532 lands
//app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore, app.capKeyStakingStore)
app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore)
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper))
err := app.LoadLatestVersion(app.capKeyMainStore)
if err != nil {

View File

@ -67,21 +67,15 @@ var (
}
)
func loggerAndDBs() (log.Logger, map[string]dbm.DB) {
func loggerAndDB() (log.Logger, dbm.DB) {
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
dbs := map[string]dbm.DB{
"main": dbm.NewMemDB(),
"acc": dbm.NewMemDB(),
"pow": dbm.NewMemDB(),
"ibc": dbm.NewMemDB(),
"staking": dbm.NewMemDB(),
}
return logger, dbs
db := dbm.NewMemDB()
return logger, db
}
func newDemocoinApp() *DemocoinApp {
logger, dbs := loggerAndDBs()
return NewDemocoinApp(logger, dbs)
logger, db := loggerAndDB()
return NewDemocoinApp(logger, db)
}
//_______________________________________________________________________
@ -123,8 +117,8 @@ func TestMsgs(t *testing.T) {
}
func TestGenesis(t *testing.T) {
logger, dbs := loggerAndDBs()
bapp := NewDemocoinApp(logger, dbs)
logger, db := loggerAndDB()
bapp := NewDemocoinApp(logger, db)
// Construct some genesis bytes to reflect democoin/types/AppAccount
pk := crypto.GenPrivKeyEd25519().PubKey()
@ -157,7 +151,7 @@ func TestGenesis(t *testing.T) {
assert.Equal(t, acc, res1)
// reload app and ensure the account is still there
bapp = NewDemocoinApp(logger, dbs)
bapp = NewDemocoinApp(logger, db)
ctx = bapp.BaseApp.NewContext(true, abci.Header{})
res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address)
assert.Equal(t, acc, res1)

View File

@ -47,34 +47,11 @@ func defaultAppState(args []string, addr sdk.Address, coinDenom string) (json.Ra
}
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
dbMain, err := dbm.NewGoLevelDB("democoin", filepath.Join(rootDir, "data"))
db, err := dbm.NewGoLevelDB("democoin", filepath.Join(rootDir, "data"))
if err != nil {
return nil, err
}
dbAcc, err := dbm.NewGoLevelDB("democoin-acc", filepath.Join(rootDir, "data"))
if err != nil {
return nil, err
}
dbPow, err := dbm.NewGoLevelDB("democoin-pow", filepath.Join(rootDir, "data"))
if err != nil {
return nil, err
}
dbIBC, err := dbm.NewGoLevelDB("democoin-ibc", filepath.Join(rootDir, "data"))
if err != nil {
return nil, err
}
dbStaking, err := dbm.NewGoLevelDB("democoin-staking", filepath.Join(rootDir, "data"))
if err != nil {
return nil, err
}
dbs := map[string]dbm.DB{
"main": dbMain,
"acc": dbAcc,
"pow": dbPow,
"ibc": dbIBC,
"staking": dbStaking,
}
bapp := app.NewDemocoinApp(logger, dbs)
bapp := app.NewDemocoinApp(logger, db)
return bapp, nil
}

View File

@ -56,8 +56,9 @@ func (rs *rootMultiStore) MountStoreWithDB(key StoreKey, typ StoreType, db dbm.D
panic(fmt.Sprintf("rootMultiStore duplicate store key %v", key))
}
rs.storesParams[key] = storeParams{
db: db,
key: key,
typ: typ,
db: db,
}
rs.keysByName[key.Name()] = key
}
@ -244,9 +245,11 @@ func parsePath(path string) (storeName string, subpath string, err sdk.Error) {
//----------------------------------------
func (rs *rootMultiStore) loadCommitStoreFromParams(id CommitID, params storeParams) (store CommitStore, err error) {
db := rs.db
var db dbm.DB
if params.db != nil {
db = params.db
db = dbm.NewPrefixDB(params.db, []byte("s/_/"))
} else {
db = dbm.NewPrefixDB(rs.db, []byte("s/k:"+params.key.Name()+"/"))
}
switch params.typ {
case sdk.StoreTypeMulti:
@ -276,6 +279,7 @@ func (rs *rootMultiStore) nameToKey(name string) StoreKey {
// storeParams
type storeParams struct {
key StoreKey
db dbm.DB
typ StoreType
}
@ -375,10 +379,11 @@ func commitStores(version int64, storeMap map[StoreKey]CommitStore) commitInfo {
storeInfos = append(storeInfos, si)
}
return commitInfo{
ci := commitInfo{
Version: version,
StoreInfos: storeInfos,
}
return ci
}
// Gets commitInfo from disk.

View File

@ -11,17 +11,22 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
const useDebugDB = false
func TestMultistoreCommitLoad(t *testing.T) {
db := dbm.NewMemDB()
var db dbm.DB = dbm.NewMemDB()
if useDebugDB {
db = dbm.NewDebugDB("CMS", db)
}
store := newMultiStoreWithMounts(db)
err := store.LoadLatestVersion()
assert.Nil(t, err)
// new store has empty last commit
// New store has empty last commit.
commitID := CommitID{}
checkStore(t, store, commitID, commitID)
// make sure we can get stores by name
// Make sure we can get stores by name.
s1 := store.getStoreByName("store1")
assert.NotNil(t, s1)
s3 := store.getStoreByName("store3")
@ -29,7 +34,7 @@ func TestMultistoreCommitLoad(t *testing.T) {
s77 := store.getStoreByName("store77")
assert.Nil(t, s77)
// make a few commits and check them
// Make a few commits and check them.
nCommits := int64(3)
for i := int64(0); i < nCommits; i++ {
commitID = store.Commit()
@ -37,19 +42,19 @@ func TestMultistoreCommitLoad(t *testing.T) {
checkStore(t, store, expectedCommitID, commitID)
}
// Load the latest multistore again and check version
// Load the latest multistore again and check version.
store = newMultiStoreWithMounts(db)
err = store.LoadLatestVersion()
assert.Nil(t, err)
commitID = getExpectedCommitID(store, nCommits)
checkStore(t, store, commitID, commitID)
// commit and check version
// Commit and check version.
commitID = store.Commit()
expectedCommitID := getExpectedCommitID(store, nCommits+1)
checkStore(t, store, expectedCommitID, commitID)
// Load an older multistore and check version
// Load an older multistore and check version.
ver := nCommits - 1
store = newMultiStoreWithMounts(db)
err = store.LoadVersion(ver)
@ -62,8 +67,8 @@ func TestMultistoreCommitLoad(t *testing.T) {
expectedCommitID = getExpectedCommitID(store, ver+1)
checkStore(t, store, expectedCommitID, commitID)
// XXX: confirm old commit is overwritten and
// we have rolled back LatestVersion
// XXX: confirm old commit is overwritten and we have rolled back
// LatestVersion
store = newMultiStoreWithMounts(db)
err = store.LoadLatestVersion()
assert.Nil(t, err)
@ -104,23 +109,23 @@ func TestMultiStoreQuery(t *testing.T) {
cid := multi.Commit()
// make sure we can get by name
// Make sure we can get by name.
garbage := multi.getStoreByName("bad-name")
assert.Nil(t, garbage)
// set and commit data in one store
// Set and commit data in one store.
store1 := multi.getStoreByName("store1").(KVStore)
store1.Set(k, v)
// and another
// ... and another.
store2 := multi.getStoreByName("store2").(KVStore)
store2.Set(k2, v2)
// commit the multistore
// Commit the multistore.
cid = multi.Commit()
ver := cid.Version
// bad path
// Test bad path.
query := abci.RequestQuery{Path: "/key", Data: k, Height: ver}
qres := multi.Query(query)
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
@ -129,25 +134,25 @@ func TestMultiStoreQuery(t *testing.T) {
qres = multi.Query(query)
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
// invalid store name
// Test invalid store name.
query.Path = "/garbage/key"
qres = multi.Query(query)
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
// valid query with data
// Test valid query with data.
query.Path = "/store1/key"
qres = multi.Query(query)
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
assert.Equal(t, v, qres.Value)
// valid but empty
// Test valid but empty query.
query.Path = "/store2/key"
query.Prove = true
qres = multi.Query(query)
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
assert.Nil(t, qres.Value)
// store2 data
// Test store2 data.
query.Data = k2
qres = multi.Query(query)
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)

View File

@ -9,7 +9,7 @@ const Maj = "0"
const Min = "15"
const Fix = "0"
const Version = "0.15.0-rc1"
const Version = "0.15.0-rc0"
// GitCommit set by build flags
var GitCommit = ""