Merge pull request #859 from cosmos/jae/fixrmssubstores
Support namespacing within RMS db
This commit is contained in:
commit
b846559ac1
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -2,18 +2,20 @@
|
||||||
|
|
||||||
## 0.15.0 (TBD)
|
## 0.15.0 (TBD)
|
||||||
|
|
||||||
|
FEATURES:
|
||||||
|
|
||||||
|
* Add CacheContext
|
||||||
|
* Add auto sequencing to client
|
||||||
|
|
||||||
BREAKING CHANGES
|
BREAKING CHANGES
|
||||||
|
|
||||||
* Remove go-wire, use go-amino
|
* Remove go-wire, use go-amino
|
||||||
* [store] Add `SubspaceIterator` and `ReverseSubspaceIterator` to `KVStore` interface
|
* [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
|
* MountStoreWithDB without providing a custom store works.
|
||||||
|
|
||||||
FEATURES:
|
|
||||||
|
|
||||||
* Add auto sequencing to client
|
|
||||||
|
|
||||||
## 0.14.1 (April 9, 2018)
|
## 0.14.1 (April 9, 2018)
|
||||||
|
|
||||||
|
|
|
@ -215,8 +215,8 @@
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/spf13/pflag"
|
name = "github.com/spf13/pflag"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
|
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
|
||||||
version = "v1.0.0"
|
version = "v1.0.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/spf13/viper"
|
name = "github.com/spf13/viper"
|
||||||
|
@ -342,8 +342,8 @@
|
||||||
"types/priv_validator",
|
"types/priv_validator",
|
||||||
"version"
|
"version"
|
||||||
]
|
]
|
||||||
revision = "dcd00b0e688f133b9634aee513f8bf856e659356"
|
revision = "d0beaba7e8a5652506a34b5fab299cc2dc274c02"
|
||||||
version = "v0.19.0-rc4"
|
version = "v0.19.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/tendermint/tmlibs"
|
name = "github.com/tendermint/tmlibs"
|
||||||
|
@ -360,8 +360,8 @@
|
||||||
"pubsub",
|
"pubsub",
|
||||||
"pubsub/query"
|
"pubsub/query"
|
||||||
]
|
]
|
||||||
revision = "2e24b64fc121dcdf1cabceab8dc2f7257675483c"
|
revision = "737154202faf75c70437f59ba5303f2eb09f5636"
|
||||||
version = "v0.8.1"
|
version = "0.8.2-rc1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -377,7 +377,7 @@
|
||||||
"ripemd160",
|
"ripemd160",
|
||||||
"salsa20/salsa"
|
"salsa20/salsa"
|
||||||
]
|
]
|
||||||
revision = "b2aa35443fbc700ab74c586ae79b81c171851023"
|
revision = "d6449816ce06963d9d136eee5a56fca5b0616e7e"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -424,7 +424,7 @@
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "google.golang.org/genproto"
|
name = "google.golang.org/genproto"
|
||||||
packages = ["googleapis/rpc/status"]
|
packages = ["googleapis/rpc/status"]
|
||||||
revision = "ce84044298496ef4b54b4a0a0909ba593cc60e30"
|
revision = "51d0944304c3cbce4afe9e5247e21100037bff78"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "google.golang.org/grpc"
|
name = "google.golang.org/grpc"
|
||||||
|
@ -459,6 +459,6 @@
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "ad499422ee60cf89fd9d61e232e33d0a17f7b43e0ff7aff0c0a22949901096e8"
|
inputs-digest = "b6b2d696a242e715ddb8b25c93b3c8f7e7cabc9292eab29dffe935eddbd35fb8"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
|
|
@ -70,11 +70,11 @@
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/tendermint/tendermint"
|
name = "github.com/tendermint/tendermint"
|
||||||
version = "0.19.0-rc4"
|
version = "0.19.0"
|
||||||
|
|
||||||
[[constraint]]
|
[[override]]
|
||||||
name = "github.com/tendermint/tmlibs"
|
name = "github.com/tendermint/tmlibs"
|
||||||
version = "~0.8.1"
|
version = "~0.8.2-rc1"
|
||||||
|
|
||||||
[prune]
|
[prune]
|
||||||
go-tests = true
|
go-tests = true
|
||||||
|
|
|
@ -71,21 +71,20 @@ func (app *BaseApp) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mount a store to the provided key in the BaseApp multistore
|
// Mount a store to the provided key in the BaseApp multistore
|
||||||
// Broken until #532 is implemented.
|
|
||||||
func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) {
|
func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) {
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
app.MountStore(key, sdk.StoreTypeIAVL)
|
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) {
|
func (app *BaseApp) MountStoreWithDB(key sdk.StoreKey, typ sdk.StoreType, db dbm.DB) {
|
||||||
app.cms.MountStoreWithDB(key, typ, 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) {
|
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
|
// nolint - Set functions
|
||||||
|
|
|
@ -35,15 +35,12 @@ func TestMountStores(t *testing.T) {
|
||||||
|
|
||||||
// make some cap keys
|
// make some cap keys
|
||||||
capKey1 := sdk.NewKVStoreKey("key1")
|
capKey1 := sdk.NewKVStoreKey("key1")
|
||||||
db1 := dbm.NewMemDB()
|
|
||||||
capKey2 := sdk.NewKVStoreKey("key2")
|
capKey2 := sdk.NewKVStoreKey("key2")
|
||||||
db2 := dbm.NewMemDB()
|
|
||||||
|
|
||||||
// no stores are mounted
|
// no stores are mounted
|
||||||
assert.Panics(t, func() { app.LoadLatestVersion(capKey1) })
|
assert.Panics(t, func() { app.LoadLatestVersion(capKey1) })
|
||||||
|
|
||||||
app.MountStoreWithDB(capKey1, sdk.StoreTypeIAVL, db1)
|
app.MountStoresIAVL(capKey1, capKey2)
|
||||||
app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2)
|
|
||||||
|
|
||||||
// stores are mounted
|
// stores are mounted
|
||||||
err := app.LoadLatestVersion(capKey1)
|
err := app.LoadLatestVersion(capKey1)
|
||||||
|
@ -155,11 +152,8 @@ func TestInitChainer(t *testing.T) {
|
||||||
// NOTE/TODO: mounting multiple stores is broken
|
// NOTE/TODO: mounting multiple stores is broken
|
||||||
// see https://github.com/cosmos/cosmos-sdk/issues/532
|
// see https://github.com/cosmos/cosmos-sdk/issues/532
|
||||||
capKey := sdk.NewKVStoreKey("main")
|
capKey := sdk.NewKVStoreKey("main")
|
||||||
db1 := dbm.NewMemDB()
|
|
||||||
capKey2 := sdk.NewKVStoreKey("key2")
|
capKey2 := sdk.NewKVStoreKey("key2")
|
||||||
db2 := dbm.NewMemDB()
|
app.MountStoresIAVL(capKey, capKey2)
|
||||||
app.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db1)
|
|
||||||
app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2)
|
|
||||||
err := app.LoadLatestVersion(capKey) // needed to make stores non-nil
|
err := app.LoadLatestVersion(capKey) // needed to make stores non-nil
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
@ -191,8 +185,7 @@ func TestInitChainer(t *testing.T) {
|
||||||
|
|
||||||
// reload app
|
// reload app
|
||||||
app = NewBaseApp(name, logger, db)
|
app = NewBaseApp(name, logger, db)
|
||||||
app.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db1)
|
app.MountStoresIAVL(capKey, capKey2)
|
||||||
app.MountStoreWithDB(capKey2, sdk.StoreTypeIAVL, db2)
|
|
||||||
err = app.LoadLatestVersion(capKey) // needed to make stores non-nil
|
err = app.LoadLatestVersion(capKey) // needed to make stores non-nil
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
app.SetInitChainer(initChainer)
|
app.SetInitChainer(initChainer)
|
||||||
|
|
|
@ -333,13 +333,8 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
|
||||||
// logger = log.NewFilter(logger, log.AllowError())
|
// logger = log.NewFilter(logger, log.AllowError())
|
||||||
privValidatorFile := config.PrivValidatorFile()
|
privValidatorFile := config.PrivValidatorFile()
|
||||||
privVal := pvm.LoadOrGenFilePV(privValidatorFile)
|
privVal := pvm.LoadOrGenFilePV(privValidatorFile)
|
||||||
dbs := map[string]dbm.DB{
|
db := dbm.NewMemDB()
|
||||||
"main": dbm.NewMemDB(),
|
app := bapp.NewBasecoinApp(logger, db)
|
||||||
"acc": dbm.NewMemDB(),
|
|
||||||
"ibc": dbm.NewMemDB(),
|
|
||||||
"staking": dbm.NewMemDB(),
|
|
||||||
}
|
|
||||||
app := bapp.NewBasecoinApp(logger, dbs)
|
|
||||||
cdc = bapp.MakeCodec() // XXX
|
cdc = bapp.MakeCodec() // XXX
|
||||||
|
|
||||||
genesisFile := config.GenesisFile()
|
genesisFile := config.GenesisFile()
|
||||||
|
|
|
@ -64,7 +64,7 @@ func GetChainHeight() (int64, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
height := status.LatestBlockHeight
|
height := status.SyncInfo.LatestBlockHeight
|
||||||
return height, nil
|
return height, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ func NodeSyncingRequestHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
syncing := status.Syncing
|
syncing := status.SyncInfo.Syncing
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(500)
|
w.WriteHeader(500)
|
||||||
w.Write([]byte(err.Error()))
|
w.Write([]byte(err.Error()))
|
||||||
|
|
|
@ -28,29 +28,11 @@ var (
|
||||||
// TODO: distinguish from basecoin
|
// TODO: distinguish from basecoin
|
||||||
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
||||||
dataDir := filepath.Join(rootDir, "data")
|
dataDir := filepath.Join(rootDir, "data")
|
||||||
dbMain, err := dbm.NewGoLevelDB("gaia", dataDir)
|
db, err := dbm.NewGoLevelDB("gaia", dataDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dbAcc, err := dbm.NewGoLevelDB("gaia-acc", dataDir)
|
bapp := app.NewBasecoinApp(logger, db)
|
||||||
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)
|
|
||||||
return bapp, nil
|
return bapp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ The SDK distinguishes between transactions (Tx) and messages
|
||||||
Users can create messages containing arbitrary information by
|
Users can create messages containing arbitrary information by
|
||||||
implementing the `Msg` interface:
|
implementing the `Msg` interface:
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
type Msg interface {
|
type Msg interface {
|
||||||
|
|
||||||
// Return the message type.
|
// 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`:
|
For instance, the `Basecoin` message types are defined in `x/bank/tx.go`:
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
type SendMsg struct {
|
type SendMsg struct {
|
||||||
Inputs []Input `json:"inputs"`
|
Inputs []Input `json:"inputs"`
|
||||||
Outputs []Output `json:"outputs"`
|
Outputs []Output `json:"outputs"`
|
||||||
|
@ -82,7 +82,7 @@ type IssueMsg struct {
|
||||||
|
|
||||||
Each specifies the addresses that must sign the message:
|
Each specifies the addresses that must sign the message:
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
func (msg SendMsg) GetSigners() []sdk.Address {
|
func (msg SendMsg) GetSigners() []sdk.Address {
|
||||||
addrs := make([]sdk.Address, len(msg.Inputs))
|
addrs := make([]sdk.Address, len(msg.Inputs))
|
||||||
for i, in := range 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:
|
A transaction is a message with additional information for authentication:
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
type Tx interface {
|
type Tx interface {
|
||||||
|
|
||||||
GetMsg() Msg
|
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
|
the list of addresses returned by `tx.Msg.GetSigners()`. The signatures come in
|
||||||
a standard form:
|
a standard form:
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
type StdSignature struct {
|
type StdSignature struct {
|
||||||
crypto.PubKey // optional
|
crypto.PubKey // optional
|
||||||
crypto.Signature
|
crypto.Signature
|
||||||
|
@ -146,7 +146,7 @@ to return this.
|
||||||
|
|
||||||
The standard way to create a transaction from a message is to use the `StdTx`:
|
The standard way to create a transaction from a message is to use the `StdTx`:
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
type StdTx struct {
|
type StdTx struct {
|
||||||
Msg
|
Msg
|
||||||
Signatures []StdSignature
|
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
|
function which determines how an arbitrary byte array should be unmarshalled
|
||||||
into a `Tx`:
|
into a `Tx`:
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
type TxDecoder func(txBytes []byte) (Tx, error)
|
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`
|
For instance, in `Basecoin`, we wish to register the `SendMsg` and `IssueMsg`
|
||||||
types:
|
types:
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
||||||
cdc.RegisterConcrete(bank.SendMsg{}, "cosmos-sdk/SendMsg", nil)
|
cdc.RegisterConcrete(bank.SendMsg{}, "cosmos-sdk/SendMsg", nil)
|
||||||
cdc.RegisterConcrete(bank.IssueMsg{}, "cosmos-sdk/IssueMsg", 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).
|
details, see the [go-amino documentation](https://github.com/tendermint/go-amino/blob/develop).
|
||||||
|
|
||||||
|
|
||||||
## MultiStore
|
## Storage
|
||||||
|
|
||||||
### MultiStore is like a filesystem
|
### MultiStore
|
||||||
### Mounting an IAVLStore
|
|
||||||
|
|
||||||
|
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.
|
In the example above, all IAVL nodes (inner and leaf) will be stored
|
||||||
- supports iteration.
|
in mainDB with the prefix of "s/k:foo/" and "s/k:bar/" respectively,
|
||||||
- MultiStore: multiple Merkle tree backends in a single store
|
thus sharing the mainDB. All IAVL nodes (inner and leaf) for the
|
||||||
- allows using Ethereum Patricia Trie and Tendermint IAVL in same app
|
cat KVStore are stored separately in catDB with the prefix of
|
||||||
- Provide caching for intermediate state during execution of blocks and transactions (including for iteration)
|
"s/\_/". The "s/k:KEY/" and "s/\_/" prefixes are there to
|
||||||
- Historical state pruning and snapshotting.
|
disambiguate store items from other items of non-storage concern.
|
||||||
- Query proofs (existence, absence, range, etc.) on current and retained historical state.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Context
|
## 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:
|
Transaction processing in the SDK is defined through `Handler` functions:
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
type Handler func(ctx Context, tx Tx) Result
|
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
|
capabilities keys and mappers. When a handler is initialized, it is passed a
|
||||||
key or mapper that gives it access to the relevant stores.
|
key or mapper that gives it access to the relevant stores.
|
||||||
|
|
||||||
```golang
|
```go
|
||||||
// File: cosmos-sdk/examples/basecoin/app/init_stores.go
|
// File: cosmos-sdk/examples/basecoin/app/init_stores.go
|
||||||
app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL)
|
app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL)
|
||||||
app.accountMapper = auth.NewAccountMapper(
|
app.accountMapper = auth.NewAccountMapper(
|
||||||
|
|
|
@ -38,14 +38,14 @@ type BasecoinApp struct {
|
||||||
accountMapper sdk.AccountMapper
|
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.
|
// Create app-level codec for txs and accounts.
|
||||||
var cdc = MakeCodec()
|
var cdc = MakeCodec()
|
||||||
|
|
||||||
// Create your application object.
|
// Create your application object.
|
||||||
var app = &BasecoinApp{
|
var app = &BasecoinApp{
|
||||||
BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]),
|
BaseApp: bam.NewBaseApp(appName, logger, db),
|
||||||
cdc: cdc,
|
cdc: cdc,
|
||||||
capKeyMainStore: sdk.NewKVStoreKey("main"),
|
capKeyMainStore: sdk.NewKVStoreKey("main"),
|
||||||
capKeyAccountStore: sdk.NewKVStoreKey("acc"),
|
capKeyAccountStore: sdk.NewKVStoreKey("acc"),
|
||||||
|
@ -72,12 +72,7 @@ func NewBasecoinApp(logger log.Logger, dbs map[string]dbm.DB) *BasecoinApp {
|
||||||
// Initialize BaseApp.
|
// Initialize BaseApp.
|
||||||
app.SetTxDecoder(app.txDecoder)
|
app.SetTxDecoder(app.txDecoder)
|
||||||
app.SetInitChainer(app.initChainer)
|
app.SetInitChainer(app.initChainer)
|
||||||
app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"])
|
app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyIBCStore, app.capKeyStakingStore)
|
||||||
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.SetAnteHandler(auth.NewAnteHandler(app.accountMapper))
|
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper))
|
||||||
err := app.LoadLatestVersion(app.capKeyMainStore)
|
err := app.LoadLatestVersion(app.capKeyMainStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -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")
|
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
|
||||||
dbs := map[string]dbm.DB{
|
db := dbm.NewMemDB()
|
||||||
"main": dbm.NewMemDB(),
|
return logger, db
|
||||||
"acc": dbm.NewMemDB(),
|
|
||||||
"ibc": dbm.NewMemDB(),
|
|
||||||
"staking": dbm.NewMemDB(),
|
|
||||||
}
|
|
||||||
return logger, dbs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBasecoinApp() *BasecoinApp {
|
func newBasecoinApp() *BasecoinApp {
|
||||||
logger, dbs := loggerAndDBs()
|
logger, db := loggerAndDB()
|
||||||
return NewBasecoinApp(logger, dbs)
|
return NewBasecoinApp(logger, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setGenesisAccounts(bapp *BasecoinApp, accs ...auth.BaseAccount) error {
|
func setGenesisAccounts(bapp *BasecoinApp, accs ...auth.BaseAccount) error {
|
||||||
|
@ -142,8 +137,8 @@ func TestMsgs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSortGenesis(t *testing.T) {
|
func TestSortGenesis(t *testing.T) {
|
||||||
logger, dbs := loggerAndDBs()
|
logger, db := loggerAndDB()
|
||||||
bapp := NewBasecoinApp(logger, dbs)
|
bapp := NewBasecoinApp(logger, db)
|
||||||
|
|
||||||
// Note the order: the coins are unsorted!
|
// Note the order: the coins are unsorted!
|
||||||
coinDenom1, coinDenom2 := "foocoin", "barcoin"
|
coinDenom1, coinDenom2 := "foocoin", "barcoin"
|
||||||
|
@ -184,8 +179,8 @@ func TestSortGenesis(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenesis(t *testing.T) {
|
func TestGenesis(t *testing.T) {
|
||||||
logger, dbs := loggerAndDBs()
|
logger, db := loggerAndDB()
|
||||||
bapp := NewBasecoinApp(logger, dbs)
|
bapp := NewBasecoinApp(logger, db)
|
||||||
|
|
||||||
// Construct some genesis bytes to reflect basecoin/types/AppAccount
|
// Construct some genesis bytes to reflect basecoin/types/AppAccount
|
||||||
pk := crypto.GenPrivKeyEd25519().PubKey()
|
pk := crypto.GenPrivKeyEd25519().PubKey()
|
||||||
|
@ -207,7 +202,7 @@ func TestGenesis(t *testing.T) {
|
||||||
assert.Equal(t, acc, res1)
|
assert.Equal(t, acc, res1)
|
||||||
|
|
||||||
// reload app and ensure the account is still there
|
// reload app and ensure the account is still there
|
||||||
bapp = NewBasecoinApp(logger, dbs)
|
bapp = NewBasecoinApp(logger, db)
|
||||||
ctx = bapp.BaseApp.NewContext(true, abci.Header{})
|
ctx = bapp.BaseApp.NewContext(true, abci.Header{})
|
||||||
res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address)
|
res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address)
|
||||||
assert.Equal(t, acc, res1)
|
assert.Equal(t, acc, res1)
|
||||||
|
|
|
@ -27,29 +27,11 @@ var (
|
||||||
|
|
||||||
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
func generateApp(rootDir string, logger log.Logger) (abci.Application, error) {
|
||||||
dataDir := filepath.Join(rootDir, "data")
|
dataDir := filepath.Join(rootDir, "data")
|
||||||
dbMain, err := dbm.NewGoLevelDB("basecoin", dataDir)
|
db, err := dbm.NewGoLevelDB("basecoin", dataDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dbAcc, err := dbm.NewGoLevelDB("basecoin-acc", dataDir)
|
bapp := app.NewBasecoinApp(logger, db)
|
||||||
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)
|
|
||||||
return bapp, nil
|
return bapp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,14 +42,14 @@ type DemocoinApp struct {
|
||||||
accountMapper sdk.AccountMapper
|
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.
|
// Create app-level codec for txs and accounts.
|
||||||
var cdc = MakeCodec()
|
var cdc = MakeCodec()
|
||||||
|
|
||||||
// Create your application object.
|
// Create your application object.
|
||||||
var app = &DemocoinApp{
|
var app = &DemocoinApp{
|
||||||
BaseApp: bam.NewBaseApp(appName, logger, dbs["main"]),
|
BaseApp: bam.NewBaseApp(appName, logger, db),
|
||||||
cdc: cdc,
|
cdc: cdc,
|
||||||
capKeyMainStore: sdk.NewKVStoreKey("main"),
|
capKeyMainStore: sdk.NewKVStoreKey("main"),
|
||||||
capKeyAccountStore: sdk.NewKVStoreKey("acc"),
|
capKeyAccountStore: sdk.NewKVStoreKey("acc"),
|
||||||
|
@ -82,13 +82,7 @@ func NewDemocoinApp(logger log.Logger, dbs map[string]dbm.DB) *DemocoinApp {
|
||||||
// Initialize BaseApp.
|
// Initialize BaseApp.
|
||||||
app.SetTxDecoder(app.txDecoder)
|
app.SetTxDecoder(app.txDecoder)
|
||||||
app.SetInitChainer(app.initChainerFn(coolKeeper, powKeeper))
|
app.SetInitChainer(app.initChainerFn(coolKeeper, powKeeper))
|
||||||
app.MountStoreWithDB(app.capKeyMainStore, sdk.StoreTypeIAVL, dbs["main"])
|
app.MountStoresIAVL(app.capKeyMainStore, app.capKeyAccountStore, app.capKeyPowStore, app.capKeyIBCStore, app.capKeyStakingStore)
|
||||||
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.SetAnteHandler(auth.NewAnteHandler(app.accountMapper))
|
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper))
|
||||||
err := app.LoadLatestVersion(app.capKeyMainStore)
|
err := app.LoadLatestVersion(app.capKeyMainStore)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -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")
|
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
|
||||||
dbs := map[string]dbm.DB{
|
db := dbm.NewMemDB()
|
||||||
"main": dbm.NewMemDB(),
|
return logger, db
|
||||||
"acc": dbm.NewMemDB(),
|
|
||||||
"pow": dbm.NewMemDB(),
|
|
||||||
"ibc": dbm.NewMemDB(),
|
|
||||||
"staking": dbm.NewMemDB(),
|
|
||||||
}
|
|
||||||
return logger, dbs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDemocoinApp() *DemocoinApp {
|
func newDemocoinApp() *DemocoinApp {
|
||||||
logger, dbs := loggerAndDBs()
|
logger, db := loggerAndDB()
|
||||||
return NewDemocoinApp(logger, dbs)
|
return NewDemocoinApp(logger, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
//_______________________________________________________________________
|
//_______________________________________________________________________
|
||||||
|
@ -123,8 +117,8 @@ func TestMsgs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenesis(t *testing.T) {
|
func TestGenesis(t *testing.T) {
|
||||||
logger, dbs := loggerAndDBs()
|
logger, db := loggerAndDB()
|
||||||
bapp := NewDemocoinApp(logger, dbs)
|
bapp := NewDemocoinApp(logger, db)
|
||||||
|
|
||||||
// Construct some genesis bytes to reflect democoin/types/AppAccount
|
// Construct some genesis bytes to reflect democoin/types/AppAccount
|
||||||
pk := crypto.GenPrivKeyEd25519().PubKey()
|
pk := crypto.GenPrivKeyEd25519().PubKey()
|
||||||
|
@ -157,7 +151,7 @@ func TestGenesis(t *testing.T) {
|
||||||
assert.Equal(t, acc, res1)
|
assert.Equal(t, acc, res1)
|
||||||
|
|
||||||
// reload app and ensure the account is still there
|
// reload app and ensure the account is still there
|
||||||
bapp = NewDemocoinApp(logger, dbs)
|
bapp = NewDemocoinApp(logger, db)
|
||||||
ctx = bapp.BaseApp.NewContext(true, abci.Header{})
|
ctx = bapp.BaseApp.NewContext(true, abci.Header{})
|
||||||
res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address)
|
res1 = bapp.accountMapper.GetAccount(ctx, baseAcc.Address)
|
||||||
assert.Equal(t, acc, res1)
|
assert.Equal(t, acc, res1)
|
||||||
|
|
|
@ -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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dbAcc, err := dbm.NewGoLevelDB("democoin-acc", filepath.Join(rootDir, "data"))
|
bapp := app.NewDemocoinApp(logger, db)
|
||||||
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)
|
|
||||||
return bapp, nil
|
return bapp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,9 @@ func (rs *rootMultiStore) MountStoreWithDB(key StoreKey, typ StoreType, db dbm.D
|
||||||
panic(fmt.Sprintf("rootMultiStore duplicate store key %v", key))
|
panic(fmt.Sprintf("rootMultiStore duplicate store key %v", key))
|
||||||
}
|
}
|
||||||
rs.storesParams[key] = storeParams{
|
rs.storesParams[key] = storeParams{
|
||||||
db: db,
|
key: key,
|
||||||
typ: typ,
|
typ: typ,
|
||||||
|
db: db,
|
||||||
}
|
}
|
||||||
rs.keysByName[key.Name()] = key
|
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) {
|
func (rs *rootMultiStore) loadCommitStoreFromParams(id CommitID, params storeParams) (store CommitStore, err error) {
|
||||||
db := rs.db
|
var db dbm.DB
|
||||||
if params.db != nil {
|
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 {
|
switch params.typ {
|
||||||
case sdk.StoreTypeMulti:
|
case sdk.StoreTypeMulti:
|
||||||
|
@ -276,6 +279,7 @@ func (rs *rootMultiStore) nameToKey(name string) StoreKey {
|
||||||
// storeParams
|
// storeParams
|
||||||
|
|
||||||
type storeParams struct {
|
type storeParams struct {
|
||||||
|
key StoreKey
|
||||||
db dbm.DB
|
db dbm.DB
|
||||||
typ StoreType
|
typ StoreType
|
||||||
}
|
}
|
||||||
|
@ -375,10 +379,11 @@ func commitStores(version int64, storeMap map[StoreKey]CommitStore) commitInfo {
|
||||||
storeInfos = append(storeInfos, si)
|
storeInfos = append(storeInfos, si)
|
||||||
}
|
}
|
||||||
|
|
||||||
return commitInfo{
|
ci := commitInfo{
|
||||||
Version: version,
|
Version: version,
|
||||||
StoreInfos: storeInfos,
|
StoreInfos: storeInfos,
|
||||||
}
|
}
|
||||||
|
return ci
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets commitInfo from disk.
|
// Gets commitInfo from disk.
|
||||||
|
|
|
@ -11,17 +11,22 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const useDebugDB = false
|
||||||
|
|
||||||
func TestMultistoreCommitLoad(t *testing.T) {
|
func TestMultistoreCommitLoad(t *testing.T) {
|
||||||
db := dbm.NewMemDB()
|
var db dbm.DB = dbm.NewMemDB()
|
||||||
|
if useDebugDB {
|
||||||
|
db = dbm.NewDebugDB("CMS", db)
|
||||||
|
}
|
||||||
store := newMultiStoreWithMounts(db)
|
store := newMultiStoreWithMounts(db)
|
||||||
err := store.LoadLatestVersion()
|
err := store.LoadLatestVersion()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
// new store has empty last commit
|
// New store has empty last commit.
|
||||||
commitID := CommitID{}
|
commitID := CommitID{}
|
||||||
checkStore(t, store, 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")
|
s1 := store.getStoreByName("store1")
|
||||||
assert.NotNil(t, s1)
|
assert.NotNil(t, s1)
|
||||||
s3 := store.getStoreByName("store3")
|
s3 := store.getStoreByName("store3")
|
||||||
|
@ -29,7 +34,7 @@ func TestMultistoreCommitLoad(t *testing.T) {
|
||||||
s77 := store.getStoreByName("store77")
|
s77 := store.getStoreByName("store77")
|
||||||
assert.Nil(t, s77)
|
assert.Nil(t, s77)
|
||||||
|
|
||||||
// make a few commits and check them
|
// Make a few commits and check them.
|
||||||
nCommits := int64(3)
|
nCommits := int64(3)
|
||||||
for i := int64(0); i < nCommits; i++ {
|
for i := int64(0); i < nCommits; i++ {
|
||||||
commitID = store.Commit()
|
commitID = store.Commit()
|
||||||
|
@ -37,19 +42,19 @@ func TestMultistoreCommitLoad(t *testing.T) {
|
||||||
checkStore(t, store, expectedCommitID, commitID)
|
checkStore(t, store, expectedCommitID, commitID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the latest multistore again and check version
|
// Load the latest multistore again and check version.
|
||||||
store = newMultiStoreWithMounts(db)
|
store = newMultiStoreWithMounts(db)
|
||||||
err = store.LoadLatestVersion()
|
err = store.LoadLatestVersion()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
commitID = getExpectedCommitID(store, nCommits)
|
commitID = getExpectedCommitID(store, nCommits)
|
||||||
checkStore(t, store, commitID, commitID)
|
checkStore(t, store, commitID, commitID)
|
||||||
|
|
||||||
// commit and check version
|
// Commit and check version.
|
||||||
commitID = store.Commit()
|
commitID = store.Commit()
|
||||||
expectedCommitID := getExpectedCommitID(store, nCommits+1)
|
expectedCommitID := getExpectedCommitID(store, nCommits+1)
|
||||||
checkStore(t, store, expectedCommitID, commitID)
|
checkStore(t, store, expectedCommitID, commitID)
|
||||||
|
|
||||||
// Load an older multistore and check version
|
// Load an older multistore and check version.
|
||||||
ver := nCommits - 1
|
ver := nCommits - 1
|
||||||
store = newMultiStoreWithMounts(db)
|
store = newMultiStoreWithMounts(db)
|
||||||
err = store.LoadVersion(ver)
|
err = store.LoadVersion(ver)
|
||||||
|
@ -62,8 +67,8 @@ func TestMultistoreCommitLoad(t *testing.T) {
|
||||||
expectedCommitID = getExpectedCommitID(store, ver+1)
|
expectedCommitID = getExpectedCommitID(store, ver+1)
|
||||||
checkStore(t, store, expectedCommitID, commitID)
|
checkStore(t, store, expectedCommitID, commitID)
|
||||||
|
|
||||||
// XXX: confirm old commit is overwritten and
|
// XXX: confirm old commit is overwritten and we have rolled back
|
||||||
// we have rolled back LatestVersion
|
// LatestVersion
|
||||||
store = newMultiStoreWithMounts(db)
|
store = newMultiStoreWithMounts(db)
|
||||||
err = store.LoadLatestVersion()
|
err = store.LoadLatestVersion()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
@ -104,23 +109,23 @@ func TestMultiStoreQuery(t *testing.T) {
|
||||||
|
|
||||||
cid := multi.Commit()
|
cid := multi.Commit()
|
||||||
|
|
||||||
// make sure we can get by name
|
// Make sure we can get by name.
|
||||||
garbage := multi.getStoreByName("bad-name")
|
garbage := multi.getStoreByName("bad-name")
|
||||||
assert.Nil(t, garbage)
|
assert.Nil(t, garbage)
|
||||||
|
|
||||||
// set and commit data in one store
|
// Set and commit data in one store.
|
||||||
store1 := multi.getStoreByName("store1").(KVStore)
|
store1 := multi.getStoreByName("store1").(KVStore)
|
||||||
store1.Set(k, v)
|
store1.Set(k, v)
|
||||||
|
|
||||||
// and another
|
// ... and another.
|
||||||
store2 := multi.getStoreByName("store2").(KVStore)
|
store2 := multi.getStoreByName("store2").(KVStore)
|
||||||
store2.Set(k2, v2)
|
store2.Set(k2, v2)
|
||||||
|
|
||||||
// commit the multistore
|
// Commit the multistore.
|
||||||
cid = multi.Commit()
|
cid = multi.Commit()
|
||||||
ver := cid.Version
|
ver := cid.Version
|
||||||
|
|
||||||
// bad path
|
// Test bad path.
|
||||||
query := abci.RequestQuery{Path: "/key", Data: k, Height: ver}
|
query := abci.RequestQuery{Path: "/key", Data: k, Height: ver}
|
||||||
qres := multi.Query(query)
|
qres := multi.Query(query)
|
||||||
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
|
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
|
||||||
|
@ -129,25 +134,25 @@ func TestMultiStoreQuery(t *testing.T) {
|
||||||
qres = multi.Query(query)
|
qres = multi.Query(query)
|
||||||
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
|
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
|
||||||
|
|
||||||
// invalid store name
|
// Test invalid store name.
|
||||||
query.Path = "/garbage/key"
|
query.Path = "/garbage/key"
|
||||||
qres = multi.Query(query)
|
qres = multi.Query(query)
|
||||||
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
|
assert.Equal(t, uint32(sdk.CodeUnknownRequest), qres.Code)
|
||||||
|
|
||||||
// valid query with data
|
// Test valid query with data.
|
||||||
query.Path = "/store1/key"
|
query.Path = "/store1/key"
|
||||||
qres = multi.Query(query)
|
qres = multi.Query(query)
|
||||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||||
assert.Equal(t, v, qres.Value)
|
assert.Equal(t, v, qres.Value)
|
||||||
|
|
||||||
// valid but empty
|
// Test valid but empty query.
|
||||||
query.Path = "/store2/key"
|
query.Path = "/store2/key"
|
||||||
query.Prove = true
|
query.Prove = true
|
||||||
qres = multi.Query(query)
|
qres = multi.Query(query)
|
||||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||||
assert.Nil(t, qres.Value)
|
assert.Nil(t, qres.Value)
|
||||||
|
|
||||||
// store2 data
|
// Test store2 data.
|
||||||
query.Data = k2
|
query.Data = k2
|
||||||
qres = multi.Query(query)
|
qres = multi.Query(query)
|
||||||
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
assert.Equal(t, uint32(sdk.CodeOK), qres.Code)
|
||||||
|
|
|
@ -9,7 +9,7 @@ const Maj = "0"
|
||||||
const Min = "15"
|
const Min = "15"
|
||||||
const Fix = "0"
|
const Fix = "0"
|
||||||
|
|
||||||
const Version = "0.15.0-rc1"
|
const Version = "0.15.0-rc0"
|
||||||
|
|
||||||
// GitCommit set by build flags
|
// GitCommit set by build flags
|
||||||
var GitCommit = ""
|
var GitCommit = ""
|
||||||
|
|
Loading…
Reference in New Issue