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)
|
||||
|
||||
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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -64,7 +64,7 @@ func GetChainHeight() (int64, error) {
|
|||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
height := status.LatestBlockHeight
|
||||
height := status.SyncInfo.LatestBlockHeight
|
||||
return height, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 = ""
|
||||
|
|
Loading…
Reference in New Issue