Substore->Store; BaseApp has db; Mapper

This commit is contained in:
Jae Kwon 2018-01-22 05:44:24 -08:00
parent b4e4881261
commit be665d53fe
31 changed files with 1012 additions and 566 deletions

View File

@ -9,8 +9,10 @@ import (
"github.com/pkg/errors"
abci "github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -23,6 +25,9 @@ type BaseApp struct {
// Application name from abci.Info
name string
// Common DB backend
db dbm.DB
// Main (uncached) state
ms sdk.CommitMultiStore
@ -53,19 +58,43 @@ type BaseApp struct {
var _ abci.Application = &BaseApp{}
func NewBaseApp(name string, ms sdk.CommitMultiStore) *BaseApp {
return &BaseApp{
func NewBaseApp(name string) *BaseApp {
var baseapp = &BaseApp{
logger: makeDefaultLogger(),
name: name,
ms: ms,
db: nil,
ms: nil,
router: NewRouter(),
}
baseapp.initDB()
baseapp.initMultiStore()
return baseapp
}
// Create the underlying leveldb datastore which will
// persist the Merkle tree inner & leaf nodes.
func (app *BaseApp) initDB() {
db, err := dbm.NewGoLevelDB(app.name, "data")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
app.db = db
}
func (app *BaseApp) initMultiStore() {
ms := store.NewCommitMultiStore(app.db)
app.ms = ms
}
func (app *BaseApp) Name() string {
return app.name
}
func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) {
app.ms.MountStoreWithDB(key, typ, app.db)
}
func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) {
app.txDecoder = txDecoder
}
@ -84,12 +113,12 @@ func (app *BaseApp) SetEndBlocker(...) {}
func (app *BaseApp) SetInitStater(...) {}
*/
func (app *BaseApp) LoadLatestVersion(mainKey sdk.SubstoreKey) error {
func (app *BaseApp) LoadLatestVersion(mainKey sdk.StoreKey) error {
app.ms.LoadLatestVersion()
return app.initFromStore(mainKey)
}
func (app *BaseApp) LoadVersion(version int64, mainKey sdk.SubstoreKey) error {
func (app *BaseApp) LoadVersion(version int64, mainKey sdk.StoreKey) error {
app.ms.LoadVersion(version)
return app.initFromStore(mainKey)
}
@ -105,7 +134,7 @@ func (app *BaseApp) LastBlockHeight() int64 {
}
// Initializes the remaining logic from app.ms.
func (app *BaseApp) initFromStore(mainKey sdk.SubstoreKey) error {
func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
lastCommitID := app.ms.LastCommitID()
main := app.ms.GetKVStore(mainKey)
header := abci.Header{}

View File

@ -13,7 +13,6 @@ import (
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@ -34,10 +33,10 @@ func (tx testTx) GetFeePayer() crypto.Address { return nil }
func (tx testTx) GetSignatures() []sdk.StdSignature { return nil }
func TestBasic(t *testing.T) {
store, storeKeys := newCommitMultiStore()
// Create app.
app := NewBaseApp(t.Name(), store)
app := NewBaseApp(t.Name())
storeKeys := createMounts(app.ms)
app.SetTxDecoder(func(txBytes []byte) (sdk.Tx, error) {
var ttx testTx
fromJSON(txBytes, &ttx)
@ -161,16 +160,15 @@ func fromJSON(bz []byte, ptr interface{}) {
}
}
// Creates a sample CommitMultiStore
func newCommitMultiStore() (sdk.CommitMultiStore, map[string]sdk.SubstoreKey) {
// Mounts stores to CommitMultiStore and returns a map of keys.
func createMounts(ms sdk.CommitMultiStore) map[string]sdk.StoreKey {
dbMain := dbm.NewMemDB()
dbXtra := dbm.NewMemDB()
keyMain := sdk.NewKVStoreKey("main")
keyXtra := sdk.NewKVStoreKey("xtra")
ms := store.NewCommitMultiStore(dbMain) // Also store rootMultiStore metadata here (it shouldn't clash)
ms.SetSubstoreLoader(keyMain, store.NewIAVLStoreLoader(dbMain, 0, 0))
ms.SetSubstoreLoader(keyXtra, store.NewIAVLStoreLoader(dbXtra, 0, 0))
return ms, map[string]sdk.SubstoreKey{
ms.MountStoreWithDB(keyMain, sdk.StoreTypeIAVL, dbMain)
ms.MountStoreWithDB(keyXtra, sdk.StoreTypeIAVL, dbXtra)
return map[string]sdk.StoreKey{
"main": keyMain,
"xtra": keyXtra,
}

View File

@ -0,0 +1 @@
MANIFEST-000093

View File

View File

@ -0,0 +1,420 @@
=============== Jan 22, 2018 (PST) ===============
02:20:20.667917 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
02:20:20.669178 db@open opening
02:20:20.670364 version@stat F·[] S·0B[] Sc·[]
02:20:20.671142 db@janitor F·2 G·0
02:20:20.671220 db@open done T·2.00865ms
=============== Jan 22, 2018 (PST) ===============
02:27:52.315693 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
02:27:52.318778 version@stat F·[] S·0B[] Sc·[]
02:27:52.318804 db@open opening
02:27:52.318899 journal@recovery F·1
02:27:52.319610 journal@recovery recovering @1
02:27:52.320363 version@stat F·[] S·0B[] Sc·[]
02:27:52.325449 db@janitor F·2 G·0
02:27:52.325491 db@open done T·6.669068ms
=============== Jan 22, 2018 (PST) ===============
02:39:24.323804 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
02:39:24.327668 version@stat F·[] S·0B[] Sc·[]
02:39:24.327701 db@open opening
02:39:24.327808 journal@recovery F·1
02:39:24.328648 journal@recovery recovering @2
02:39:24.329207 version@stat F·[] S·0B[] Sc·[]
02:39:24.330194 db@janitor F·2 G·0
02:39:24.330239 db@open done T·2.516353ms
=============== Jan 22, 2018 (PST) ===============
02:41:39.198692 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
02:41:39.203178 version@stat F·[] S·0B[] Sc·[]
02:41:39.203249 db@open opening
02:41:39.203444 journal@recovery F·1
02:41:39.204117 journal@recovery recovering @4
02:41:39.205805 version@stat F·[] S·0B[] Sc·[]
02:41:39.206992 db@janitor F·2 G·0
02:41:39.207042 db@open done T·3.766041ms
=============== Jan 22, 2018 (PST) ===============
02:57:12.571189 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
02:57:12.573329 version@stat F·[] S·0B[] Sc·[]
02:57:12.573380 db@open opening
02:57:12.573519 journal@recovery F·1
02:57:12.574112 journal@recovery recovering @6
02:57:12.574817 version@stat F·[] S·0B[] Sc·[]
02:57:12.578908 db@janitor F·2 G·0
02:57:12.578955 db@open done T·5.556429ms
=============== Jan 22, 2018 (PST) ===============
02:58:51.899628 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
02:58:51.902315 version@stat F·[] S·0B[] Sc·[]
02:58:51.902351 db@open opening
02:58:51.902471 journal@recovery F·1
02:58:51.904243 journal@recovery recovering @8
02:58:51.904941 version@stat F·[] S·0B[] Sc·[]
02:58:51.905884 db@janitor F·2 G·0
02:58:51.905916 db@open done T·3.55323ms
=============== Jan 22, 2018 (PST) ===============
03:00:17.452727 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:00:17.453633 version@stat F·[] S·0B[] Sc·[]
03:00:17.453654 db@open opening
03:00:17.453738 journal@recovery F·1
03:00:17.454316 journal@recovery recovering @10
03:00:17.455239 version@stat F·[] S·0B[] Sc·[]
03:00:17.456169 db@janitor F·2 G·0
03:00:17.456208 db@open done T·2.537364ms
=============== Jan 22, 2018 (PST) ===============
03:00:57.872703 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:00:57.873215 version@stat F·[] S·0B[] Sc·[]
03:00:57.873238 db@open opening
03:00:57.873328 journal@recovery F·1
03:00:57.873907 journal@recovery recovering @12
03:00:57.874695 version@stat F·[] S·0B[] Sc·[]
03:00:57.876608 db@janitor F·2 G·0
03:00:57.876666 db@open done T·3.402072ms
=============== Jan 22, 2018 (PST) ===============
03:01:36.381066 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:01:36.381545 version@stat F·[] S·0B[] Sc·[]
03:01:36.381564 db@open opening
03:01:36.381635 journal@recovery F·1
03:01:36.382594 journal@recovery recovering @14
03:01:36.383313 version@stat F·[] S·0B[] Sc·[]
03:01:36.384570 db@janitor F·2 G·0
03:01:36.384605 db@open done T·3.029926ms
=============== Jan 22, 2018 (PST) ===============
03:01:50.485546 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:01:50.486053 version@stat F·[] S·0B[] Sc·[]
03:01:50.486077 db@open opening
03:01:50.486165 journal@recovery F·1
03:01:50.486683 journal@recovery recovering @16
03:01:50.487657 version@stat F·[] S·0B[] Sc·[]
03:01:50.489725 db@janitor F·2 G·0
03:01:50.489769 db@open done T·3.678486ms
=============== Jan 22, 2018 (PST) ===============
03:03:21.912077 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:03:21.912536 version@stat F·[] S·0B[] Sc·[]
03:03:21.912555 db@open opening
03:03:21.912621 journal@recovery F·1
03:03:21.913109 journal@recovery recovering @18
03:03:21.913875 version@stat F·[] S·0B[] Sc·[]
03:03:21.914859 db@janitor F·2 G·0
03:03:21.914893 db@open done T·2.321933ms
=============== Jan 22, 2018 (PST) ===============
03:03:38.788932 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:03:38.789374 version@stat F·[] S·0B[] Sc·[]
03:03:38.789394 db@open opening
03:03:38.789469 journal@recovery F·1
03:03:38.790271 journal@recovery recovering @20
03:03:38.791021 version@stat F·[] S·0B[] Sc·[]
03:03:38.794175 db@janitor F·2 G·0
03:03:38.794214 db@open done T·4.8086ms
=============== Jan 22, 2018 (PST) ===============
03:05:02.619429 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:05:02.624450 version@stat F·[] S·0B[] Sc·[]
03:05:02.624479 db@open opening
03:05:02.624587 journal@recovery F·1
03:05:02.625197 journal@recovery recovering @22
03:05:02.625703 version@stat F·[] S·0B[] Sc·[]
03:05:02.628444 db@janitor F·2 G·0
03:05:02.628485 db@open done T·3.985771ms
=============== Jan 22, 2018 (PST) ===============
03:07:58.079511 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:07:58.081652 version@stat F·[] S·0B[] Sc·[]
03:07:58.081683 db@open opening
03:07:58.081791 journal@recovery F·1
03:07:58.082336 journal@recovery recovering @24
03:07:58.083090 version@stat F·[] S·0B[] Sc·[]
03:07:58.084133 db@janitor F·2 G·0
03:07:58.084183 db@open done T·2.477889ms
=============== Jan 22, 2018 (PST) ===============
03:11:36.208112 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:11:36.209248 version@stat F·[] S·0B[] Sc·[]
03:11:36.209277 db@open opening
03:11:36.209375 journal@recovery F·1
03:11:36.209819 journal@recovery recovering @26
03:11:36.210667 version@stat F·[] S·0B[] Sc·[]
03:11:36.212096 db@janitor F·2 G·0
03:11:36.212146 db@open done T·2.854122ms
=============== Jan 22, 2018 (PST) ===============
03:14:28.381204 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:14:28.381597 version@stat F·[] S·0B[] Sc·[]
03:14:28.381614 db@open opening
03:14:28.381679 journal@recovery F·1
03:14:28.382166 journal@recovery recovering @28
03:14:28.382925 version@stat F·[] S·0B[] Sc·[]
03:14:28.384890 db@janitor F·2 G·0
03:14:28.384938 db@open done T·3.305166ms
=============== Jan 22, 2018 (PST) ===============
03:16:57.807253 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:16:57.809148 version@stat F·[] S·0B[] Sc·[]
03:16:57.809176 db@open opening
03:16:57.809276 journal@recovery F·1
03:16:57.809798 journal@recovery recovering @30
03:16:57.810708 version@stat F·[] S·0B[] Sc·[]
03:16:57.811999 db@janitor F·2 G·0
03:16:57.812056 db@open done T·2.854877ms
=============== Jan 22, 2018 (PST) ===============
03:19:27.065541 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:19:27.065963 version@stat F·[] S·0B[] Sc·[]
03:19:27.065982 db@open opening
03:19:27.066064 journal@recovery F·1
03:19:27.066462 journal@recovery recovering @32
03:19:27.067345 version@stat F·[] S·0B[] Sc·[]
03:19:27.070968 db@janitor F·2 G·0
03:19:27.071015 db@open done T·5.013804ms
=============== Jan 22, 2018 (PST) ===============
03:19:52.706551 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:19:52.707024 version@stat F·[] S·0B[] Sc·[]
03:19:52.707047 db@open opening
03:19:52.707126 journal@recovery F·1
03:19:52.707560 journal@recovery recovering @34
03:19:52.708117 version@stat F·[] S·0B[] Sc·[]
03:19:52.711284 db@janitor F·2 G·0
03:19:52.711329 db@open done T·4.267678ms
=============== Jan 22, 2018 (PST) ===============
03:26:24.468105 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:26:24.468552 version@stat F·[] S·0B[] Sc·[]
03:26:24.468575 db@open opening
03:26:24.468656 journal@recovery F·1
03:26:24.469267 journal@recovery recovering @36
03:26:24.469846 version@stat F·[] S·0B[] Sc·[]
03:26:24.474595 db@janitor F·2 G·0
03:26:24.474636 db@open done T·6.04411ms
=============== Jan 22, 2018 (PST) ===============
03:51:35.032653 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
03:51:35.042632 version@stat F·[] S·0B[] Sc·[]
03:51:35.042659 db@open opening
03:51:35.042744 journal@recovery F·1
03:51:35.043196 journal@recovery recovering @38
03:51:35.043841 version@stat F·[] S·0B[] Sc·[]
03:51:35.050746 db@janitor F·2 G·0
03:51:35.050789 db@open done T·8.116551ms
=============== Jan 22, 2018 (PST) ===============
04:00:26.747278 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:00:26.752301 version@stat F·[] S·0B[] Sc·[]
04:00:26.752343 db@open opening
04:00:26.752454 journal@recovery F·1
04:00:26.752901 journal@recovery recovering @40
04:00:26.753349 version@stat F·[] S·0B[] Sc·[]
04:00:26.757743 db@janitor F·2 G·0
04:00:26.757778 db@open done T·5.422834ms
=============== Jan 22, 2018 (PST) ===============
04:01:46.178175 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:01:46.178655 version@stat F·[] S·0B[] Sc·[]
04:01:46.178674 db@open opening
04:01:46.178775 journal@recovery F·1
04:01:46.179347 journal@recovery recovering @42
04:01:46.180154 version@stat F·[] S·0B[] Sc·[]
04:01:46.182310 db@janitor F·2 G·0
04:01:46.182338 db@open done T·3.652952ms
=============== Jan 22, 2018 (PST) ===============
04:04:19.070666 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:04:19.072779 version@stat F·[] S·0B[] Sc·[]
04:04:19.072810 db@open opening
04:04:19.072914 journal@recovery F·1
04:04:19.073398 journal@recovery recovering @44
04:04:19.074134 version@stat F·[] S·0B[] Sc·[]
04:04:19.075029 db@janitor F·2 G·0
04:04:19.075068 db@open done T·2.240164ms
=============== Jan 22, 2018 (PST) ===============
04:05:59.580740 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:05:59.581283 version@stat F·[] S·0B[] Sc·[]
04:05:59.581301 db@open opening
04:05:59.581379 journal@recovery F·1
04:05:59.582237 journal@recovery recovering @46
04:05:59.583953 version@stat F·[] S·0B[] Sc·[]
04:05:59.585436 db@janitor F·2 G·0
04:05:59.585473 db@open done T·4.160567ms
=============== Jan 22, 2018 (PST) ===============
04:08:47.738599 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:08:47.739083 version@stat F·[] S·0B[] Sc·[]
04:08:47.739105 db@open opening
04:08:47.739183 journal@recovery F·1
04:08:47.739692 journal@recovery recovering @48
04:08:47.740466 version@stat F·[] S·0B[] Sc·[]
04:08:47.741410 db@janitor F·2 G·0
04:08:47.741444 db@open done T·2.3276ms
=============== Jan 22, 2018 (PST) ===============
04:10:08.775252 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:10:08.775687 version@stat F·[] S·0B[] Sc·[]
04:10:08.775705 db@open opening
04:10:08.775773 journal@recovery F·1
04:10:08.776486 journal@recovery recovering @50
04:10:08.777122 version@stat F·[] S·0B[] Sc·[]
04:10:08.778919 db@janitor F·2 G·0
04:10:08.778961 db@open done T·3.245071ms
=============== Jan 22, 2018 (PST) ===============
04:14:32.971220 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:14:32.971922 version@stat F·[] S·0B[] Sc·[]
04:14:32.971962 db@open opening
04:14:32.972095 journal@recovery F·1
04:14:32.973033 journal@recovery recovering @52
04:14:32.973725 version@stat F·[] S·0B[] Sc·[]
04:14:32.976332 db@janitor F·2 G·0
04:14:32.976389 db@open done T·4.40961ms
=============== Jan 22, 2018 (PST) ===============
04:16:46.446923 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:16:46.447439 version@stat F·[] S·0B[] Sc·[]
04:16:46.447465 db@open opening
04:16:46.447546 journal@recovery F·1
04:16:46.448532 journal@recovery recovering @54
04:16:46.449082 version@stat F·[] S·0B[] Sc·[]
04:16:46.451474 db@janitor F·2 G·0
04:16:46.451531 db@open done T·4.048125ms
=============== Jan 22, 2018 (PST) ===============
04:19:13.453357 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:19:13.453932 version@stat F·[] S·0B[] Sc·[]
04:19:13.453978 db@open opening
04:19:13.454085 journal@recovery F·1
04:19:13.454789 journal@recovery recovering @56
04:19:13.455675 version@stat F·[] S·0B[] Sc·[]
04:19:13.456803 db@janitor F·2 G·0
04:19:13.456844 db@open done T·2.844553ms
=============== Jan 22, 2018 (PST) ===============
04:20:33.271529 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:20:33.271936 version@stat F·[] S·0B[] Sc·[]
04:20:33.271954 db@open opening
04:20:33.272022 journal@recovery F·1
04:20:33.272647 journal@recovery recovering @58
04:20:33.273143 version@stat F·[] S·0B[] Sc·[]
04:20:33.274043 db@janitor F·2 G·0
04:20:33.274078 db@open done T·2.113985ms
=============== Jan 22, 2018 (PST) ===============
04:25:19.055938 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:25:19.056763 version@stat F·[] S·0B[] Sc·[]
04:25:19.056786 db@open opening
04:25:19.056865 journal@recovery F·1
04:25:19.057455 journal@recovery recovering @60
04:25:19.058377 version@stat F·[] S·0B[] Sc·[]
04:25:19.059353 db@janitor F·2 G·0
04:25:19.059392 db@open done T·2.591721ms
=============== Jan 22, 2018 (PST) ===============
04:26:26.431263 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:26:26.431696 version@stat F·[] S·0B[] Sc·[]
04:26:26.431717 db@open opening
04:26:26.431796 journal@recovery F·1
04:26:26.432411 journal@recovery recovering @62
04:26:26.433010 version@stat F·[] S·0B[] Sc·[]
04:26:26.434881 db@janitor F·2 G·0
04:26:26.434916 db@open done T·3.187393ms
=============== Jan 22, 2018 (PST) ===============
04:28:19.118769 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:28:19.122566 version@stat F·[] S·0B[] Sc·[]
04:28:19.122603 db@open opening
04:28:19.122690 journal@recovery F·1
04:28:19.123248 journal@recovery recovering @64
04:28:19.124085 version@stat F·[] S·0B[] Sc·[]
04:28:19.126908 db@janitor F·2 G·0
04:28:19.126954 db@open done T·4.333898ms
=============== Jan 22, 2018 (PST) ===============
04:32:40.558885 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:32:40.561056 version@stat F·[] S·0B[] Sc·[]
04:32:40.561082 db@open opening
04:32:40.561204 journal@recovery F·1
04:32:40.561690 journal@recovery recovering @66
04:32:40.562239 version@stat F·[] S·0B[] Sc·[]
04:32:40.563112 db@janitor F·2 G·0
04:32:40.563144 db@open done T·2.049673ms
=============== Jan 22, 2018 (PST) ===============
04:37:25.167274 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:37:25.167662 version@stat F·[] S·0B[] Sc·[]
04:37:25.167681 db@open opening
04:37:25.167752 journal@recovery F·1
04:37:25.168247 journal@recovery recovering @68
04:37:25.168861 version@stat F·[] S·0B[] Sc·[]
04:37:25.172909 db@janitor F·2 G·0
04:37:25.172941 db@open done T·5.247885ms
=============== Jan 22, 2018 (PST) ===============
04:54:28.500444 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
04:54:28.502945 version@stat F·[] S·0B[] Sc·[]
04:54:28.502974 db@open opening
04:54:28.503070 journal@recovery F·1
04:54:28.503627 journal@recovery recovering @70
04:54:28.504124 version@stat F·[] S·0B[] Sc·[]
04:54:28.505062 db@janitor F·2 G·0
04:54:28.505094 db@open done T·2.108477ms
=============== Jan 22, 2018 (PST) ===============
05:01:19.593801 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:01:19.594788 version@stat F·[] S·0B[] Sc·[]
05:01:19.594816 db@open opening
05:01:19.594915 journal@recovery F·1
05:01:19.595496 journal@recovery recovering @72
05:01:19.596370 version@stat F·[] S·0B[] Sc·[]
05:01:19.597244 db@janitor F·2 G·0
05:01:19.597282 db@open done T·2.449363ms
=============== Jan 22, 2018 (PST) ===============
05:04:29.471458 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:04:29.472662 version@stat F·[] S·0B[] Sc·[]
05:04:29.472713 db@open opening
05:04:29.472793 journal@recovery F·1
05:04:29.473425 journal@recovery recovering @74
05:04:29.474375 version@stat F·[] S·0B[] Sc·[]
05:04:29.475638 db@janitor F·2 G·0
05:04:29.475673 db@open done T·2.942159ms
=============== Jan 22, 2018 (PST) ===============
05:05:42.278156 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:05:42.280920 version@stat F·[] S·0B[] Sc·[]
05:05:42.280947 db@open opening
05:05:42.281037 journal@recovery F·1
05:05:42.281647 journal@recovery recovering @76
05:05:42.282651 version@stat F·[] S·0B[] Sc·[]
05:05:42.283610 db@janitor F·2 G·0
05:05:42.283651 db@open done T·2.681388ms
=============== Jan 22, 2018 (PST) ===============
05:08:45.319211 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:08:45.321023 version@stat F·[] S·0B[] Sc·[]
05:08:45.321052 db@open opening
05:08:45.321146 journal@recovery F·1
05:08:45.321705 journal@recovery recovering @78
05:08:45.322648 version@stat F·[] S·0B[] Sc·[]
05:08:45.323706 db@janitor F·2 G·0
05:08:45.323745 db@open done T·2.679774ms
=============== Jan 22, 2018 (PST) ===============
05:11:06.661289 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:11:06.663188 version@stat F·[] S·0B[] Sc·[]
05:11:06.663212 db@open opening
05:11:06.663295 journal@recovery F·1
05:11:06.663847 journal@recovery recovering @80
05:11:06.665202 version@stat F·[] S·0B[] Sc·[]
05:11:06.666547 db@janitor F·2 G·0
05:11:06.666578 db@open done T·3.354587ms
=============== Jan 22, 2018 (PST) ===============
05:22:20.522602 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:22:20.523062 version@stat F·[] S·0B[] Sc·[]
05:22:20.523085 db@open opening
05:22:20.523167 journal@recovery F·1
05:22:20.523757 journal@recovery recovering @82
05:22:20.524506 version@stat F·[] S·0B[] Sc·[]
05:22:20.527683 db@janitor F·2 G·0
05:22:20.527721 db@open done T·4.623285ms
=============== Jan 22, 2018 (PST) ===============
05:30:31.524125 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:30:31.532140 version@stat F·[] S·0B[] Sc·[]
05:30:31.532175 db@open opening
05:30:31.532272 journal@recovery F·1
05:30:31.532768 journal@recovery recovering @84
05:30:31.534159 version@stat F·[] S·0B[] Sc·[]
05:30:31.547317 db@janitor F·2 G·0
05:30:31.547374 db@open done T·15.185802ms
=============== Jan 22, 2018 (PST) ===============
05:40:55.450366 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:40:55.453870 version@stat F·[] S·0B[] Sc·[]
05:40:55.453918 db@open opening
05:40:55.454007 journal@recovery F·1
05:40:55.454895 journal@recovery recovering @86
05:40:55.455571 version@stat F·[] S·0B[] Sc·[]
05:40:55.456543 db@janitor F·2 G·0
05:40:55.456633 db@open done T·2.696868ms
=============== Jan 22, 2018 (PST) ===============
05:41:38.813921 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:41:38.814486 version@stat F·[] S·0B[] Sc·[]
05:41:38.814507 db@open opening
05:41:38.814578 journal@recovery F·1
05:41:38.815205 journal@recovery recovering @88
05:41:38.816356 version@stat F·[] S·0B[] Sc·[]
05:41:38.817324 db@janitor F·2 G·0
05:41:38.817368 db@open done T·2.839844ms
=============== Jan 22, 2018 (PST) ===============
05:42:55.588810 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed
05:42:55.590533 version@stat F·[] S·0B[] Sc·[]
05:42:55.590560 db@open opening
05:42:55.590659 journal@recovery F·1
05:42:55.591190 journal@recovery recovering @90
05:42:55.592176 version@stat F·[] S·0B[] Sc·[]
05:42:55.593166 db@janitor F·2 G·0
05:42:55.593205 db@open done T·2.623485ms

Binary file not shown.

View File

@ -19,11 +19,11 @@ type BasecoinApp struct {
multiStore sdk.CommitMultiStore
// The key to access the substores.
mainStoreKey *sdk.KVStoreKey
ibcStoreKey *sdk.KVStoreKey
capKeyMainStore *sdk.KVStoreKey
capKeyIBCStore *sdk.KVStoreKey
// Additional stores:
accStore sdk.AccountStore
// Object mappers :
accountMapper sdk.AccountMapper
}
// TODO: This should take in more configuration options.
@ -32,8 +32,8 @@ func NewBasecoinApp() *BasecoinApp {
// Create and configure app.
var app = &BasecoinApp{}
app.initCapKeys() // ./init_capkeys.go
app.initStores() // ./init_stores.go
app.initBaseApp() // ./init_baseapp.go
app.initStores() // ./init_stores.go
app.initRoutes() // ./init_routes.go
// TODO: Load genesis
@ -65,7 +65,7 @@ func (app *BasecoinApp) RunForever() {
// Load the stores.
func (app *BasecoinApp) loadStores() {
if err := app.LoadLatestVersion(app.mainStoreKey); err != nil {
if err := app.LoadLatestVersion(app.capKeyMainStore); err != nil {
fmt.Println(err)
os.Exit(1)
}

View File

@ -6,10 +6,9 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth"
)
// initBaseApp() happens after initCapKeys() and initStores().
// initBaseApp() happens before initRoutes().
// initCapKeys, initBaseApp, initStores, initRoutes.
func (app *BasecoinApp) initBaseApp() {
app.BaseApp = baseapp.NewBaseApp(appName, app.multiStore)
app.BaseApp = baseapp.NewBaseApp(appName)
app.initBaseAppTxDecoder()
app.initBaseAppAnteHandler()
}
@ -24,6 +23,6 @@ func (app *BasecoinApp) initBaseAppTxDecoder() {
}
func (app *BasecoinApp) initBaseAppAnteHandler() {
var authAnteHandler = auth.NewAnteHandler(app.accStore)
var authAnteHandler = auth.NewAnteHandler(app.accountMapper)
app.BaseApp.SetDefaultAnteHandler(authAnteHandler)
}

View File

@ -4,13 +4,13 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// initCapKeys() happens before initStores(), initSDKApp(), and initRoutes().
// initCapKeys, initBaseApp, initStores, initRoutes.
func (app *BasecoinApp) initCapKeys() {
// All top-level capabilities keys
// should be constructed here.
// For more information, see http://www.erights.org/elib/capability/ode/ode.pdf.
app.mainStoreKey = sdk.NewKVStoreKey("main")
app.ibcStoreKey = sdk.NewKVStoreKey("ibc")
app.capKeyMainStore = sdk.NewKVStoreKey("main")
app.capKeyIBCStore = sdk.NewKVStoreKey("ibc")
}

View File

@ -4,12 +4,12 @@ import (
"github.com/cosmos/cosmos-sdk/x/bank"
)
// initRoutes() happens after initCapKeys(), initStores(), and initSDKApp().
// initCapKeys, initBaseApp, initStores, initRoutes.
func (app *BasecoinApp) initRoutes() {
var router = app.BaseApp.Router()
var accStore = app.accStore
var accountMapper = app.accountMapper
// All handlers must be added here.
// The order matters.
router.AddRoute("bank", bank.NewHandler(accStore))
router.AddRoute("bank", bank.NewHandler(accountMapper))
}

View File

@ -1,61 +1,38 @@
package app
import (
"fmt"
"os"
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
dbm "github.com/tendermint/tmlibs/db"
)
// initStores() happens after initCapKeys(), but before initSDKApp() and initRoutes().
// initCapKeys, initBaseApp, initStores, initRoutes.
func (app *BasecoinApp) initStores() {
app.initMultiStore()
app.initAccountStore()
app.mountStores()
app.initAccountMapper()
}
// Initialize root MultiStore.
func (app *BasecoinApp) initMultiStore() {
// Initialize root stores.
func (app *BasecoinApp) mountStores() {
// Create the underlying leveldb datastore which will
// persist the Merkle tree inner & leaf nodes.
db, err := dbm.NewGoLevelDB("basecoin", "basecoin-data")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Create CommitStoreLoader.
cacheSize := 10000
numHistory := int64(100)
mainLoader := store.NewIAVLStoreLoader(db, cacheSize, numHistory)
ibcLoader := store.NewIAVLStoreLoader(db, cacheSize, numHistory)
// Create MultiStore
multiStore := store.NewCommitMultiStore(db)
multiStore.SetSubstoreLoader(app.mainStoreKey, mainLoader)
multiStore.SetSubstoreLoader(app.ibcStoreKey, ibcLoader)
// Finally,
app.multiStore = multiStore
// Create MultiStore mounts.
app.BaseApp.MountStore(app.capKeyMainStore, sdk.StoreTypeIAVL)
app.BaseApp.MountStore(app.capKeyIBCStore, sdk.StoreTypeIAVL)
}
// Initialize the AccountStore, which accesses the MultiStore.
func (app *BasecoinApp) initAccountStore() {
accStore := auth.NewAccountStore(
// where accounts are persisted in the MultiStore.
app.mainStoreKey,
// prototype sdk.Account.
&types.AppAccount{},
// Initialize the AccountMapper.
func (app *BasecoinApp) initAccountMapper() {
var accountMapper = auth.NewAccountMapper(
app.capKeyMainStore, // target store
&types.AppAccount{}, // prototype
)
// If there are additional interfaces & concrete types that
// need to be registered w/ wire.Codec, they can be registered
// here before the accStore is sealed.
cdc := accStore.WireCodec()
// Register all interfaces and concrete types that
// implement those interfaces, here.
cdc := accountMapper.WireCodec()
auth.RegisterWireBaseAccount(cdc)
app.accStore = accStore.Seal()
// Make accountMapper's WireCodec() inaccessible.
app.accountMapper = accountMapper.Seal()
}

View File

@ -8,42 +8,30 @@ import (
"github.com/tendermint/abci/server"
crypto "github.com/tendermint/go-crypto"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
bam "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func main() {
db, err := dbm.NewGoLevelDB("dummy", "dummy-data")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Capabilities key to access the main KVStore.
var capKeyMainStore = sdk.NewKVStoreKey("main")
// create CommitStoreLoader
cacheSize := 10000
numHistory := int64(100)
loader := store.NewIAVLStoreLoader(db, cacheSize, numHistory)
// Create BaseApp.
var baseApp = bam.NewBaseApp("dummy")
// key to access the main KVStore
var mainStoreKey = sdk.NewKVStoreKey("main")
// Create MultiStore
multiStore := store.NewCommitMultiStore(db)
multiStore.SetSubstoreLoader(mainStoreKey, loader)
// Set everything on the baseApp and load latest
baseApp := bam.NewBaseApp("dummy", multiStore)
// Set mounts for BaseApp's MultiStore.
baseApp.MountStore(capKeyMainStore, sdk.StoreTypeIAVL)
// Set Tx decoder
baseApp.SetTxDecoder(decodeTx)
baseApp.Router().AddRoute("dummy", DummyHandler(mainStoreKey))
// Set a handler Route.
baseApp.Router().AddRoute("dummy", DummyHandler(capKeyMainStore))
if err := baseApp.LoadLatestVersion(mainStoreKey); err != nil {
// Load latest version.
if err := baseApp.LoadLatestVersion(capKeyMainStore); err != nil {
fmt.Println(err)
os.Exit(1)
}
@ -126,7 +114,7 @@ func decodeTx(txBytes []byte) (sdk.Tx, error) {
return tx, nil
}
func DummyHandler(storeKey sdk.SubstoreKey) sdk.Handler {
func DummyHandler(storeKey sdk.StoreKey) sdk.Handler {
return func(ctx sdk.Context, tx sdk.Tx) sdk.Result {
// tx is already unmarshalled
key := tx.Get("key").([]byte)

4
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: e8435271aa9fdfc49efff9016427eca1fd6b43093a17187619360edda9f265e6
updated: 2018-01-21T19:17:17.451995428-08:00
updated: 2018-01-21T20:59:37.606138723-08:00
imports:
- name: github.com/btcsuite/btcd
version: 2e60448ffcc6bf78332d1fe590260095f554dd78
@ -91,7 +91,7 @@ imports:
subpackages:
- keys
- name: github.com/tendermint/go-wire
version: 0cce10e82786f2d501827fbe158747dbc4ceeb43
version: c7801c1586f51bb28028cd420c599516d7ac9c36
subpackages:
- data
- name: github.com/tendermint/iavl

View File

@ -35,6 +35,12 @@ func NewCacheKVStore(parent KVStore) *cacheKVStore {
return ci
}
// Implements Store.
func (ci *cacheKVStore) GetStoreType() StoreType {
return ci.parent.GetStoreType()
}
// Implements KVStore.
func (ci *cacheKVStore) Get(key []byte) (value []byte) {
ci.mtx.Lock()
defer ci.mtx.Unlock()
@ -51,6 +57,7 @@ func (ci *cacheKVStore) Get(key []byte) (value []byte) {
return value
}
// Implements KVStore.
func (ci *cacheKVStore) Set(key []byte, value []byte) {
ci.mtx.Lock()
defer ci.mtx.Unlock()
@ -59,11 +66,13 @@ func (ci *cacheKVStore) Set(key []byte, value []byte) {
ci.setCacheValue(key, value, false, true)
}
// Implements KVStore.
func (ci *cacheKVStore) Has(key []byte) bool {
value := ci.Get(key)
return value != nil
}
// Implements KVStore.
func (ci *cacheKVStore) Delete(key []byte) {
ci.mtx.Lock()
defer ci.mtx.Unlock()
@ -72,7 +81,7 @@ func (ci *cacheKVStore) Delete(key []byte) {
ci.setCacheValue(key, nil, true, true)
}
// Write writes pending updates to the parent database and clears the cache.
// Implements CacheKVStore.
func (ci *cacheKVStore) Write() {
ci.mtx.Lock()
defer ci.mtx.Unlock()
@ -107,6 +116,7 @@ func (ci *cacheKVStore) Write() {
//----------------------------------------
// To cache-wrap this cacheKVStore further.
// Implements CacheWrapper.
func (ci *cacheKVStore) CacheWrap() CacheWrap {
return NewCacheKVStore(ci)
}
@ -114,10 +124,12 @@ func (ci *cacheKVStore) CacheWrap() CacheWrap {
//----------------------------------------
// Iteration
// Implements KVStore.
func (ci *cacheKVStore) Iterator(start, end []byte) Iterator {
return ci.iterator(start, end, true)
}
// Implements KVStore.
func (ci *cacheKVStore) ReverseIterator(start, end []byte) Iterator {
return ci.iterator(start, end, false)
}

View File

@ -10,7 +10,7 @@ import (
)
func newCacheKVStore() CacheKVStore {
mem := dbm.NewMemDB()
mem := dbStoreAdapter{dbm.NewMemDB()}
return NewCacheKVStore(mem)
}
@ -18,7 +18,7 @@ func keyFmt(i int) []byte { return bz(cmn.Fmt("key%0.8d", i)) }
func valFmt(i int) []byte { return bz(cmn.Fmt("value%0.8d", i)) }
func TestCacheKVStore(t *testing.T) {
mem := dbm.NewMemDB()
mem := dbStoreAdapter{dbm.NewMemDB()}
st := NewCacheKVStore(mem)
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
@ -61,7 +61,7 @@ func TestCacheKVStore(t *testing.T) {
}
func TestCacheKVStoreNested(t *testing.T) {
mem := dbm.NewMemDB()
mem := dbStoreAdapter{dbm.NewMemDB()}
st := NewCacheKVStore(mem)
// set. check its there on st and not on mem.

View File

@ -1,5 +1,9 @@
package store
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
//----------------------------------------
// cacheMultiStore
@ -7,20 +11,18 @@ package store
// Implements MultiStore.
type cacheMultiStore struct {
db CacheKVStore
nextVersion int64
lastCommitID CommitID
substores map[SubstoreKey]CacheWrap
stores map[StoreKey]CacheWrap
}
func newCacheMultiStoreFromRMS(rms *rootMultiStore) cacheMultiStore {
cms := cacheMultiStore{
db: NewCacheKVStore(rms.db),
nextVersion: rms.nextVersion,
db: NewCacheKVStore(dbStoreAdapter{rms.db}),
lastCommitID: rms.lastCommitID,
substores: make(map[SubstoreKey]CacheWrap, len(rms.substores)),
stores: make(map[StoreKey]CacheWrap, len(rms.stores)),
}
for key, substore := range rms.substores {
cms.substores[key] = substore.CacheWrap()
for key, store := range rms.stores {
cms.stores[key] = store.CacheWrap()
}
return cms
}
@ -28,50 +30,49 @@ func newCacheMultiStoreFromRMS(rms *rootMultiStore) cacheMultiStore {
func newCacheMultiStoreFromCMS(cms cacheMultiStore) cacheMultiStore {
cms2 := cacheMultiStore{
db: NewCacheKVStore(cms.db),
nextVersion: cms.nextVersion,
lastCommitID: cms.lastCommitID,
substores: make(map[SubstoreKey]CacheWrap, len(cms.substores)),
stores: make(map[StoreKey]CacheWrap, len(cms.stores)),
}
for key, substore := range cms.substores {
cms2.substores[key] = substore.CacheWrap()
for key, store := range cms.stores {
cms2.stores[key] = store.CacheWrap()
}
return cms2
}
// Implements CacheMultiStore
// Implements Store.
func (cms cacheMultiStore) GetStoreType() StoreType {
return sdk.StoreTypeMulti
}
// Implements MultiStore.
func (cms cacheMultiStore) LastCommitID() CommitID {
return cms.lastCommitID
}
// Implements CacheMultiStore
func (cms cacheMultiStore) NextVersion() int64 {
return cms.nextVersion
}
// Implements CacheMultiStore
// Implements CacheMultiStore.
func (cms cacheMultiStore) Write() {
cms.db.Write()
for _, substore := range cms.substores {
substore.Write()
for _, store := range cms.stores {
store.Write()
}
}
// Implements CacheMultiStore
// Implements CacheWrapper.
func (cms cacheMultiStore) CacheWrap() CacheWrap {
return cms.CacheMultiStore().(CacheWrap)
}
// Implements CacheMultiStore
// Implements MultiStore.
func (cms cacheMultiStore) CacheMultiStore() CacheMultiStore {
return newCacheMultiStoreFromCMS(cms)
}
// Implements CacheMultiStore
func (cms cacheMultiStore) GetStore(key SubstoreKey) interface{} {
return cms.substores[key]
// Implements MultiStore.
func (cms cacheMultiStore) GetStore(key StoreKey) Store {
return cms.stores[key].(Store)
}
// Implements CacheMultiStore
func (cms cacheMultiStore) GetKVStore(key SubstoreKey) KVStore {
return cms.substores[key].(KVStore)
// Implements MultiStore.
func (cms cacheMultiStore) GetKVStore(key StoreKey) KVStore {
return cms.stores[key].(KVStore)
}

23
store/dbstoreadapter.go Normal file
View File

@ -0,0 +1,23 @@
package store
import (
sdk "github.com/cosmos/cosmos-sdk/types"
dbm "github.com/tendermint/tmlibs/db"
)
type dbStoreAdapter struct {
dbm.DB
}
// Implements Store.
func (_ dbStoreAdapter) GetStoreType() StoreType {
return sdk.StoreTypeDB
}
// Implements KVStore.
func (dsa dbStoreAdapter) CacheWrap() CacheWrap {
return NewCacheKVStore(dsa)
}
// dbm.DB implements KVStore so we can CacheKVStore it.
var _ KVStore = dbStoreAdapter{dbm.DB(nil)}

View File

@ -1,38 +1,29 @@
package store
import (
"fmt"
"sync"
"github.com/tendermint/iavl"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// iavlStoreLoader contains info on what store we want to load from
type iavlStoreLoader struct {
db dbm.DB
cacheSize int
numHistory int64
}
const (
defaultIAVLCacheSize = 10000
defaultIAVLNumHistory = 1<<53 - 1 // DEPRECATED
)
// NewIAVLStoreLoader returns a CommitStoreLoader that returns an iavlStore
func NewIAVLStoreLoader(db dbm.DB, cacheSize int, numHistory int64) CommitStoreLoader {
l := iavlStoreLoader{
db: db,
cacheSize: cacheSize,
numHistory: numHistory,
}
return l.Load
}
// Load implements CommitLoader.
func (isl iavlStoreLoader) Load(id CommitID) (CommitStore, error) {
tree := iavl.NewVersionedTree(isl.db, isl.cacheSize)
err := tree.Load()
func LoadIAVLStore(db dbm.DB, id CommitID) (CommitStore, error) {
tree := iavl.NewVersionedTree(db, defaultIAVLCacheSize)
fmt.Println("LoadIAVLStore Version ", id.Version)
err := tree.LoadVersion(id.Version)
if err != nil {
return nil, err
}
store := newIAVLStore(tree, isl.numHistory)
store := newIAVLStore(tree, defaultIAVLNumHistory)
return store, nil
}
@ -61,7 +52,7 @@ func newIAVLStore(tree *iavl.VersionedTree, numHistory int64) *iavlStore {
return st
}
// Commit persists the store.
// Implements Committer.
func (st *iavlStore) Commit() CommitID {
// Save a new version.
@ -83,45 +74,58 @@ func (st *iavlStore) Commit() CommitID {
}
}
// CacheWrap implements KVStore.
// Implements Committer.
func (st *iavlStore) LastCommitID() CommitID {
return CommitID{
Version: st.tree.Version64(),
Hash: st.tree.Hash(),
}
}
// Implements Store.
func (st *iavlStore) GetStoreType() StoreType {
return sdk.StoreTypeIAVL
}
// Implements Store.
func (st *iavlStore) CacheWrap() CacheWrap {
return NewCacheKVStore(st)
}
// Set implements KVStore.
// Implements KVStore.
func (st *iavlStore) Set(key, value []byte) {
st.tree.Set(key, value)
}
// Get implements KVStore.
// Implements KVStore.
func (st *iavlStore) Get(key []byte) (value []byte) {
_, v := st.tree.Get(key)
return v
}
// Has implements KVStore.
// Implements KVStore.
func (st *iavlStore) Has(key []byte) (exists bool) {
return st.tree.Has(key)
}
// Delete implements KVStore.
// Implements KVStore.
func (st *iavlStore) Delete(key []byte) {
st.tree.Remove(key)
}
// Iterator implements KVStore.
// Implements KVStore.
func (st *iavlStore) Iterator(start, end []byte) Iterator {
return newIAVLIterator(st.tree.Tree(), start, end, true)
}
// ReverseIterator implements IterKVStore.
// Implements IterKVStore.
func (st *iavlStore) ReverseIterator(start, end []byte) Iterator {
return newIAVLIterator(st.tree.Tree(), start, end, false)
}
//----------------------------------------
// Implements Iterator
// Implements Iterator.
type iavlIterator struct {
// Underlying store
tree *iavl.Tree
@ -192,12 +196,12 @@ func (iter *iavlIterator) initRoutine() {
close(iter.initCh)
}
// Domain implements Iterator
// Implements Iterator.
func (iter *iavlIterator) Domain() (start, end []byte) {
return iter.start, iter.end
}
// Valid implements Iterator
// Implements Iterator.
func (iter *iavlIterator) Valid() bool {
iter.waitInit()
iter.mtx.Lock()
@ -206,7 +210,7 @@ func (iter *iavlIterator) Valid() bool {
return !iter.invalid
}
// Next implements Iterator
// Implements Iterator.
func (iter *iavlIterator) Next() {
iter.waitInit()
iter.mtx.Lock()
@ -216,7 +220,7 @@ func (iter *iavlIterator) Next() {
iter.receiveNext()
}
// Key implements Iterator
// Implements Iterator.
func (iter *iavlIterator) Key() []byte {
iter.waitInit()
iter.mtx.Lock()
@ -226,7 +230,7 @@ func (iter *iavlIterator) Key() []byte {
return iter.key
}
// Value implements Iterator
// Implements Iterator.
func (iter *iavlIterator) Value() []byte {
iter.waitInit()
iter.mtx.Lock()
@ -236,7 +240,7 @@ func (iter *iavlIterator) Value() []byte {
return iter.value
}
// Close implements Iterator
// Implements Iterator.
func (iter *iavlIterator) Close() {
close(iter.quitCh)
}

View File

@ -40,20 +40,6 @@ func newTree(t *testing.T, db dbm.DB) (*iavl.VersionedTree, CommitID) {
return tree, CommitID{ver, hash}
}
func TestIAVLStoreLoader(t *testing.T) {
db := dbm.NewMemDB()
_, id := newTree(t, db)
iavlLoader := NewIAVLStoreLoader(db, cacheSize, numHistory)
commitStore, err := iavlLoader(id)
assert.Nil(t, err)
id2 := commitStore.Commit()
assert.Equal(t, id.Hash, id2.Hash)
assert.Equal(t, id.Version+1, id2.Version)
}
func TestIAVLStoreGetSetHasDelete(t *testing.T) {
db := dbm.NewMemDB()
tree, _ := newTree(t, db)

View File

@ -6,11 +6,13 @@ import (
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/merkle"
"golang.org/x/crypto/ripemd160"
sdk "github.com/cosmos/cosmos-sdk/types"
)
const (
latestVersionKey = "s/latest"
commitStateKeyFmt = "s/%d" // s/<version>
latestVersionKey = "s/latest"
commitInfoKeyFmt = "s/%d" // s/<version>
)
// rootMultiStore is composed of many CommitStores.
@ -19,10 +21,9 @@ const (
// Implements MultiStore.
type rootMultiStore struct {
db dbm.DB
nextVersion int64
lastCommitID CommitID
storeLoaders map[SubstoreKey]CommitStoreLoader
substores map[SubstoreKey]CommitStore
storesParams map[StoreKey]storeParams
stores map[StoreKey]CommitStore
}
var _ CommitMultiStore = (*rootMultiStore)(nil)
@ -30,26 +31,33 @@ var _ CommitMultiStore = (*rootMultiStore)(nil)
func NewCommitMultiStore(db dbm.DB) *rootMultiStore {
return &rootMultiStore{
db: db,
nextVersion: 0,
storeLoaders: make(map[SubstoreKey]CommitStoreLoader),
substores: make(map[SubstoreKey]CommitStore),
storesParams: make(map[StoreKey]storeParams),
stores: make(map[StoreKey]CommitStore),
}
}
// Implements Store.
func (rs *rootMultiStore) GetStoreType() StoreType {
return sdk.StoreTypeMulti
}
// Implements CommitMultiStore.
func (rs *rootMultiStore) SetSubstoreLoader(key SubstoreKey, loader CommitStoreLoader) {
func (rs *rootMultiStore) MountStoreWithDB(key StoreKey, typ StoreType, db dbm.DB) {
if key == nil {
panic("SetSubstoreLoader() key cannot be nil")
panic("MountIAVLStore() key cannot be nil")
}
if _, ok := rs.storeLoaders[key]; ok {
panic(fmt.Sprintf("rootMultiStore duplicate substore key", key))
if _, ok := rs.storesParams[key]; ok {
panic(fmt.Sprintf("rootMultiStore duplicate store key", key))
}
rs.storesParams[key] = storeParams{
db: db,
typ: typ,
}
rs.storeLoaders[key] = loader
}
// Implements CommitMultiStore.
func (rs *rootMultiStore) GetSubstore(key SubstoreKey) CommitStore {
return rs.substores[key]
func (rs *rootMultiStore) GetCommitStore(key StoreKey) CommitStore {
return rs.stores[key]
}
// Implements CommitMultiStore.
@ -63,85 +71,71 @@ func (rs *rootMultiStore) LoadVersion(ver int64) error {
// Special logic for version 0
if ver == 0 {
for key, storeLoader := range rs.storeLoaders {
store, err := storeLoader(CommitID{})
for key, storeParams := range rs.storesParams {
id := CommitID{}
store, err := rs.loadCommitStoreFromParams(id, storeParams)
if err != nil {
return fmt.Errorf("Failed to load rootMultiStore: %v", err)
}
rs.substores[key] = store
rs.stores[key] = store
}
rs.nextVersion = 1
rs.lastCommitID = CommitID{}
return nil
}
// Otherwise, version is 1 or greater
// Get commitState
state, err := getCommitState(rs.db, ver)
// Get commitInfo
cInfo, err := getCommitInfo(rs.db, ver)
if err != nil {
return err
}
// Load each Substore
var newSubstores = make(map[SubstoreKey]CommitStore)
for _, store := range state.Substores {
key, commitID := rs.nameToKey(store.Name), store.CommitID
storeLoader := rs.storeLoaders[key]
if storeLoader == nil {
return fmt.Errorf("Failed to load rootMultiStore substore %v for commitID %v: %v", key, commitID, err)
}
store, err := storeLoader(commitID)
// Load each Store
var newStores = make(map[StoreKey]CommitStore)
for _, storeInfo := range cInfo.StoreInfos {
key, commitID := rs.nameToKey(storeInfo.Name), storeInfo.Core.CommitID
storeParams := rs.storesParams[key]
store, err := rs.loadCommitStoreFromParams(commitID, storeParams)
if err != nil {
return fmt.Errorf("Failed to load rootMultiStore: %v", err)
}
newSubstores[key] = store
newStores[key] = store
}
// If any CommitStoreLoaders were not used, return error.
for key := range rs.storeLoaders {
if _, ok := newSubstores[key]; !ok {
for key := range rs.storesParams {
if _, ok := newStores[key]; !ok {
return fmt.Errorf("Unused CommitStoreLoader: %v", key)
}
}
// Success.
rs.nextVersion = ver + 1
rs.lastCommitID = state.CommitID()
rs.substores = newSubstores
rs.lastCommitID = cInfo.CommitID()
rs.stores = newStores
return nil
}
func (rs *rootMultiStore) nameToKey(name string) SubstoreKey {
for key, _ := range rs.storeLoaders {
if key.Name() == name {
return key
}
}
panic("Unknown name " + name)
}
//----------------------------------------
// +CommitStore
// Implements CommitStore.
func (rs *rootMultiStore) Commit() CommitID {
// Commit substores.
version := rs.nextVersion
state := commitSubstores(version, rs.substores)
// Commit stores.
version := rs.lastCommitID.Version + 1
commitInfo := commitStores(version, rs.stores)
// Need to update self state atomically.
// Need to update atomically.
batch := rs.db.NewBatch()
setCommitState(batch, version, state)
setCommitInfo(batch, version, commitInfo)
setLatestVersion(batch, version)
batch.Write()
// Prepare for next version.
rs.nextVersion = version + 1
commitID := CommitID{
Version: version,
Hash: state.Hash(),
Hash: commitInfo.Hash(),
}
rs.lastCommitID = commitID
return commitID
@ -160,77 +154,112 @@ func (rs *rootMultiStore) LastCommitID() CommitID {
return rs.lastCommitID
}
// Implements MultiStore.
// NOTE: Returns 0 unless LoadVersion() or LoadLatestVersion() is called.
func (rs *rootMultiStore) NextVersion() int64 {
return rs.nextVersion
}
// Implements MultiStore.
func (rs *rootMultiStore) CacheMultiStore() CacheMultiStore {
return newCacheMultiStoreFromRMS(rs)
}
// Implements MultiStore.
func (rs *rootMultiStore) GetStore(key SubstoreKey) interface{} {
return rs.substores[key]
func (rs *rootMultiStore) GetStore(key StoreKey) Store {
return rs.stores[key]
}
// Implements MultiStore.
func (rs *rootMultiStore) GetKVStore(key SubstoreKey) KVStore {
return rs.substores[key].(KVStore)
func (rs *rootMultiStore) GetKVStore(key StoreKey) KVStore {
return rs.stores[key].(KVStore)
}
//----------------------------------------
// commitState
// NOTE: Keep commitState a simple immutable struct.
type commitState struct {
func (rs *rootMultiStore) loadCommitStoreFromParams(id CommitID, params storeParams) (store CommitStore, err error) {
db := rs.db
if params.db != nil {
db = params.db
}
switch params.typ {
case sdk.StoreTypeMulti:
panic("recursive MultiStores not yet supported")
// TODO: id?
// return NewCommitMultiStore(db, id)
case sdk.StoreTypeIAVL:
store, err = LoadIAVLStore(db, id)
return
case sdk.StoreTypeDB:
panic("dbm.DB is not a CommitStore")
default:
panic(fmt.Sprintf("unrecognized store type %v", params.typ))
}
}
func (rs *rootMultiStore) nameToKey(name string) StoreKey {
for key, _ := range rs.storesParams {
if key.Name() == name {
return key
}
}
panic("Unknown name " + name)
}
//----------------------------------------
// storeParams
type storeParams struct {
db dbm.DB
typ StoreType
}
//----------------------------------------
// commitInfo
// NOTE: Keep commitInfo a simple immutable struct.
type commitInfo struct {
// Version
Version int64
// Substore info for
Substores []substore
// Store info for
StoreInfos []storeInfo
}
// Hash returns the simple merkle root hash of the substores sorted by name.
func (cs commitState) Hash() []byte {
// TODO cache to cs.hash []byte
m := make(map[string]merkle.Hasher, len(cs.Substores))
for _, substore := range cs.Substores {
m[substore.Name] = substore
// Hash returns the simple merkle root hash of the stores sorted by name.
func (ci commitInfo) Hash() []byte {
// TODO cache to ci.hash []byte
m := make(map[string]merkle.Hasher, len(ci.StoreInfos))
for _, storeInfo := range ci.StoreInfos {
m[storeInfo.Name] = storeInfo
}
return merkle.SimpleHashFromMap(m)
}
func (cs commitState) CommitID() CommitID {
func (ci commitInfo) CommitID() CommitID {
return CommitID{
Version: cs.Version,
Hash: cs.Hash(),
Version: ci.Version,
Hash: ci.Hash(),
}
}
//----------------------------------------
// substore state
// storeInfo
// substore contains the name and core reference for an underlying store.
// It is the leaf of the rootMultiStores top level simple merkle tree.
type substore struct {
// storeInfo contains the name and core reference for an
// underlying store. It is the leaf of the rootMultiStores top
// level simple merkle tree.
type storeInfo struct {
Name string
substoreCore
Core storeCore
}
type substoreCore struct {
type storeCore struct {
// StoreType StoreType
CommitID CommitID
// ... maybe add more state
}
// Implements merkle.Hasher.
func (sw substore) Hash() []byte {
func (si storeInfo) Hash() []byte {
// Doesn't write Name, since merkle.SimpleHashFromMap() will
// include them via the keys.
bz, _ := cdc.MarshalBinary(sw.substoreCore) // Does not error
bz, _ := cdc.MarshalBinary(si.Core) // Does not error
hasher := ripemd160.New()
hasher.Write(bz)
return hasher.Sum(nil)
@ -258,52 +287,53 @@ func setLatestVersion(batch dbm.Batch, version int64) {
batch.Set([]byte(latestVersionKey), latestBytes)
}
// Commits each substore and returns a new commitState.
func commitSubstores(version int64, substoresMap map[SubstoreKey]CommitStore) commitState {
substores := make([]substore, 0, len(substoresMap))
// Commits each store and returns a new commitInfo.
func commitStores(version int64, storeMap map[StoreKey]CommitStore) commitInfo {
storeInfos := make([]storeInfo, 0, len(storeMap))
for key, store := range substoresMap {
for key, store := range storeMap {
// Commit
commitID := store.Commit()
// Record CommitID
substore := substore{}
substore.Name = key.Name()
substore.CommitID = commitID
substores = append(substores, substore)
si := storeInfo{}
si.Name = key.Name()
si.Core.CommitID = commitID
// si.Core.StoreType = store.GetStoreType()
storeInfos = append(storeInfos, si)
}
return commitState{
Version: version,
Substores: substores,
return commitInfo{
Version: version,
StoreInfos: storeInfos,
}
}
// Gets commitState from disk.
func getCommitState(db dbm.DB, ver int64) (commitState, error) {
// Gets commitInfo from disk.
func getCommitInfo(db dbm.DB, ver int64) (commitInfo, error) {
// Get from DB.
commitStateKey := fmt.Sprintf(commitStateKeyFmt, ver)
stateBytes := db.Get([]byte(commitStateKey))
if stateBytes == nil {
return commitState{}, fmt.Errorf("Failed to get rootMultiStore: no data")
cInfoKey := fmt.Sprintf(commitInfoKeyFmt, ver)
cInfoBytes := db.Get([]byte(cInfoKey))
if cInfoBytes == nil {
return commitInfo{}, fmt.Errorf("Failed to get rootMultiStore: no data")
}
// Parse bytes.
var state commitState
err := cdc.UnmarshalBinary(stateBytes, &state)
var cInfo commitInfo
err := cdc.UnmarshalBinary(cInfoBytes, &cInfo)
if err != nil {
return commitState{}, fmt.Errorf("Failed to get rootMultiStore: %v", err)
return commitInfo{}, fmt.Errorf("Failed to get rootMultiStore: %v", err)
}
return state, nil
return cInfo, nil
}
// Set a commit state for given version.
func setCommitState(batch dbm.Batch, version int64, state commitState) {
stateBytes, err := cdc.MarshalBinary(state)
// Set a commitInfo for given version.
func setCommitInfo(batch dbm.Batch, version int64, cInfo commitInfo) {
cInfoBytes, err := cdc.MarshalBinary(cInfo)
if err != nil {
panic(err)
}
commitStateKey := fmt.Sprintf(commitStateKeyFmt, version)
batch.Set([]byte(commitStateKey), stateBytes)
cInfoKey := fmt.Sprintf(commitInfoKeyFmt, version)
batch.Set([]byte(cInfoKey), cInfoBytes)
}

View File

@ -4,7 +4,6 @@ import (
"testing"
"github.com/stretchr/testify/assert"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/merkle"
@ -13,7 +12,7 @@ import (
func TestMultistoreCommitLoad(t *testing.T) {
db := dbm.NewMemDB()
store := newMultiStoreWithLoaders(db)
store := newMultiStoreWithMounts(db)
err := store.LoadLatestVersion()
assert.Nil(t, err)
@ -30,7 +29,7 @@ func TestMultistoreCommitLoad(t *testing.T) {
}
// Load the latest multistore again and check version
store = newMultiStoreWithLoaders(db)
store = newMultiStoreWithMounts(db)
err = store.LoadLatestVersion()
assert.Nil(t, err)
commitID = getExpectedCommitID(store, nCommits)
@ -43,7 +42,7 @@ func TestMultistoreCommitLoad(t *testing.T) {
// Load an older multistore and check version
ver := nCommits - 1
store = newMultiStoreWithLoaders(db)
store = newMultiStoreWithMounts(db)
err = store.LoadVersion(ver)
assert.Nil(t, err)
commitID = getExpectedCommitID(store, ver)
@ -56,7 +55,7 @@ func TestMultistoreCommitLoad(t *testing.T) {
// XXX: confirm old commit is overwritten and
// we have rolled back LatestVersion
store = newMultiStoreWithLoaders(db)
store = newMultiStoreWithMounts(db)
err = store.LoadLatestVersion()
assert.Nil(t, err)
commitID = getExpectedCommitID(store, ver+1)
@ -66,21 +65,18 @@ func TestMultistoreCommitLoad(t *testing.T) {
//-----------------------------------------------------------------------
// utils
func newMultiStoreWithLoaders(db dbm.DB) *rootMultiStore {
func newMultiStoreWithMounts(db dbm.DB) *rootMultiStore {
store := NewCommitMultiStore(db)
storeLoaders := map[SubstoreKey]CommitStoreLoader{
sdk.NewKVStoreKey("store1"): newMockCommitStore,
sdk.NewKVStoreKey("store2"): newMockCommitStore,
sdk.NewKVStoreKey("store3"): newMockCommitStore,
}
for key, loader := range storeLoaders {
store.SetSubstoreLoader(key, loader)
}
store.MountStoreWithDB(
sdk.NewKVStoreKey("store1"), sdk.StoreTypeIAVL, db)
store.MountStoreWithDB(
sdk.NewKVStoreKey("store2"), sdk.StoreTypeIAVL, db)
store.MountStoreWithDB(
sdk.NewKVStoreKey("store3"), sdk.StoreTypeIAVL, db)
return store
}
func checkStore(t *testing.T, store *rootMultiStore, expect, got CommitID) {
assert.EqualValues(t, expect.Version+1, store.NextVersion())
assert.Equal(t, expect, got)
assert.Equal(t, expect, store.LastCommitID())
@ -89,42 +85,21 @@ func checkStore(t *testing.T, store *rootMultiStore, expect, got CommitID) {
func getExpectedCommitID(store *rootMultiStore, ver int64) CommitID {
return CommitID{
Version: ver,
Hash: hashStores(store.substores),
Hash: hashStores(store.stores),
}
}
func hashStores(stores map[SubstoreKey]CommitStore) []byte {
func hashStores(stores map[StoreKey]CommitStore) []byte {
m := make(map[string]merkle.Hasher, len(stores))
for key, store := range stores {
name := key.Name()
m[name] = substore{
m[name] = storeInfo{
Name: name,
substoreCore: substoreCore{
CommitID: store.Commit(),
Core: storeCore{
CommitID: store.LastCommitID(),
// StoreType: store.GetStoreType(),
},
}
}
return merkle.SimpleHashFromMap(m)
}
//-----------------------------------------------------------------------
// mockCommitStore
var _ CommitStore = (*mockCommitStore)(nil)
type mockCommitStore struct {
id CommitID
}
func newMockCommitStore(id CommitID) (CommitStore, error) {
return &mockCommitStore{id}, nil
}
func (cs *mockCommitStore) Commit() CommitID {
return cs.id
}
func (cs *mockCommitStore) CacheWrap() CacheWrap {
cs2 := *cs
return &cs2
}
func (cs *mockCommitStore) Write() {}

View File

@ -5,16 +5,17 @@ import (
)
// Import cosmos-sdk/types/store.go for convenience.
type Store = types.Store
type MultiStore = types.MultiStore
type CacheMultiStore = types.CacheMultiStore
type CommitStore = types.CommitStore
type Committer = types.Committer
type CommitMultiStore = types.CommitMultiStore
type CommitStoreLoader = types.CommitStoreLoader
type KVStore = types.KVStore
type Iterator = types.Iterator
type CacheKVStore = types.CacheKVStore
type CacheWrapper = types.CacheWrapper
type CacheWrap = types.CacheWrap
type CommitID = types.CommitID
type SubstoreKey = types.SubstoreKey
type StoreKey = types.StoreKey
type StoreType = types.StoreType

View File

@ -23,12 +23,10 @@ type Account interface {
Set(key interface{}, value interface{}) error
}
// AccountStore indexes accounts by address.
type AccountStore interface {
// AccountMapper stores and retrieves accounts from stores
// retrieved from the context.
type AccountMapper interface {
NewAccountWithAddress(ctx Context, addr crypto.Address) Account
GetAccount(ctx Context, addr crypto.Address) Account
SetAccount(ctx Context, acc Account)
}
// new(AccountStoreKey) is a capabilities key.
type AccountStoreKey struct{}

View File

@ -60,7 +60,7 @@ func (c Context) Value(key interface{}) interface{} {
}
// KVStore fetches a KVStore from the MultiStore.
func (c Context) KVStore(key SubstoreKey) KVStore {
func (c Context) KVStore(key StoreKey) KVStore {
return c.multiStore().GetKVStore(key)
}
@ -83,7 +83,7 @@ func (c Context) WithProtoMsg(key interface{}, value proto.Message) Context {
return c.withValue(key, value)
}
func (c Context) WithMultiStore(key SubstoreKey, ms MultiStore) Context {
func (c Context) WithMultiStore(key StoreKey, ms MultiStore) Context {
return c.withValue(key, ms)
}

View File

@ -8,18 +8,28 @@ import (
// NOTE: These are implemented in cosmos-sdk/store.
type Store interface {
GetStoreType() StoreType
CacheWrapper
}
// Something that can persist to disk.
type Committer interface {
Commit() CommitID
LastCommitID() CommitID
}
// Stores of MultiStore must implement CommitStore.
type CommitStore interface {
Committer
Store
}
//----------------------------------------
// MultiStore
type MultiStore interface {
// Last commit, or the zero CommitID.
// If not zero, CommitID.Version is NextVersion()-1.
LastCommitID() CommitID
// Current version being worked on now, not yet committed.
// Should be greater than 0.
NextVersion() int64
Store
// Cache wrap MultiStore.
// NOTE: Caller should probably not call .Write() on each, but
@ -27,8 +37,8 @@ type MultiStore interface {
CacheMultiStore() CacheMultiStore
// Convenience for fetching substores.
GetStore(SubstoreKey) interface{}
GetKVStore(SubstoreKey) KVStore
GetStore(StoreKey) Store
GetKVStore(StoreKey) KVStore
}
// From MultiStore.CacheMultiStore()....
@ -37,50 +47,34 @@ type CacheMultiStore interface {
Write() // Writes operations to underlying KVStore
}
// Substores of MultiStore must implement CommitStore.
type CommitStore interface {
Committer
CacheWrapper
}
// A non-cache store that can commit (persist) and get a Merkle root.
type Committer interface {
Commit() CommitID
}
// A non-cache MultiStore.
type CommitMultiStore interface {
CommitStore
Committer
MultiStore
// Add a substore loader.
// Panics on a nil key.
SetSubstoreLoader(key SubstoreKey, loader CommitStoreLoader)
// Mount a store of type.
MountStoreWithDB(key StoreKey, typ StoreType, db dbm.DB)
// Gets the substore, which is a CommitSubstore.
// Panics on a nil key.
GetSubstore(key SubstoreKey) CommitStore
GetCommitStore(key StoreKey) CommitStore
// Load the latest persisted version.
// Called once after all calls to SetSubstoreLoader are complete.
// Load the latest persisted version. Called once after all
// calls to Mount*Store() are complete.
LoadLatestVersion() error
// Load a specific persisted version. When you load an old version, or
// when the last commit attempt didn't complete, the next commit after
// loading must be idempotent (return the same commit id). Otherwise the
// behavior is undefined.
// Load a specific persisted version. When you load an old
// version, or when the last commit attempt didn't complete,
// the next commit after loading must be idempotent (return the
// same commit id). Otherwise the behavior is undefined.
LoadVersion(ver int64) error
}
// These must be added to the MultiStore before calling LoadVersion() or
// LoadLatest().
type CommitStoreLoader func(id CommitID) (CommitStore, error)
//----------------------------------------
// KVStore
// KVStore is a simple interface to get/set data
type KVStore interface {
Store
// Get returns nil iff key doesn't exist. Panics on nil key.
Get(key []byte) []byte
@ -112,17 +106,17 @@ type KVStore interface {
}
// dbm.DB implements KVStore so we can CacheKVStore it.
var _ KVStore = dbm.DB(nil)
// Alias iterator to db's Iterator for convenience.
type Iterator = dbm.Iterator
// CacheKVStore cache-wraps a KVStore. After calling .Write() on the
// CacheKVStore, all previously created CacheKVStores on the object expire.
// CacheKVStore cache-wraps a KVStore. After calling .Write() on
// the CacheKVStore, all previously created CacheKVStores on the
// object expire.
type CacheKVStore interface {
KVStore
Write() // Writes operations to underlying KVStore
// Writes operations to underlying KVStore
Write()
}
//----------------------------------------
@ -166,13 +160,23 @@ func (cid CommitID) String() string {
return fmt.Sprintf("CommitID{%v:%X}", cid.Hash, cid.Version)
}
//----------------------------------------
// Store types
type StoreType int
const (
StoreTypeMulti StoreType = iota
StoreTypeDB
StoreTypeIAVL
)
//----------------------------------------
// Keys for accessing substores
// SubstoreKey is a key used to index substores.
type SubstoreKey interface {
// StoreKey is a key used to index stores in a MultiStore.
type StoreKey interface {
Name() string
String() string
}

View File

@ -4,7 +4,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
func NewAnteHandler(store sdk.AccountStore) sdk.AnteHandler {
func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
return func(
ctx sdk.Context, tx sdk.Tx,
) (newCtx sdk.Context, res sdk.Result, abort bool) {
@ -13,7 +13,7 @@ func NewAnteHandler(store sdk.AccountStore) sdk.AnteHandler {
// This is done first because it only
// requires fetching 1 account.
payerAddr := tx.GetFeePayer()
payerAcc := store.GetAccount(ctx, payerAddr)
payerAcc := accountMapper.GetAccount(ctx, payerAddr)
if payerAcc == nil {
return ctx, sdk.Result{
Code: 1, // TODO
@ -42,7 +42,7 @@ func NewAnteHandler(store sdk.AccountStore) sdk.AnteHandler {
// Check each nonce and sig.
for i, sig := range signatures {
var signerAcc = store.GetAccount(ctx, signerAddrs[i])
var signerAcc = accountMapper.GetAccount(ctx, signerAddrs[i])
signerAccs[i] = signerAcc
// If no pubkey, set pubkey.
@ -72,7 +72,7 @@ func NewAnteHandler(store sdk.AccountStore) sdk.AnteHandler {
}
// Save the account.
store.SetAccount(ctx, signerAcc)
accountMapper.SetAccount(ctx, signerAcc)
}
ctx = WithSigners(ctx, signerAccs)

View File

@ -8,13 +8,13 @@ import (
Usage:
var accountStore types.AccountStore
var accounts types.AccountMapper
// Fetch all signer accounts.
addrs := tx.GetSigners()
signers := make([]types.Account, len(addrs))
for i, addr := range addrs {
acc := accountStore.GetAccount(ctx)
acc := accounts.GetAccount(ctx)
signers[i] = acc
}
ctx = auth.SetSigners(ctx, signers)

154
x/auth/mapper.go Normal file
View File

@ -0,0 +1,154 @@
package auth
import (
"fmt"
"reflect"
crypto "github.com/tendermint/go-crypto"
wire "github.com/tendermint/go-wire"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Implements sdk.AccountMapper.
// This AccountMapper encodes/decodes accounts using the
// go-wire (binary) encoding/decoding library.
type accountMapper struct {
// The (unexposed) key used to access the store from the Context.
key sdk.StoreKey
// The prototypical sdk.Account concrete type.
proto sdk.Account
// The wire codec for binary encoding/decoding of accounts.
cdc *wire.Codec
}
// NewAccountMapper returns a new sdk.AccountMapper that
// uses go-wire to (binary) encode and decode concrete sdk.Accounts.
func NewAccountMapper(key sdk.StoreKey, proto sdk.Account) accountMapper {
cdc := wire.NewCodec()
return accountMapper{
key: key,
proto: proto,
cdc: cdc,
}
}
// Returns the go-wire codec. You may need to register interfaces
// and concrete types here, if your app's sdk.Account
// implementation includes interface fields.
// NOTE: It is not secure to expose the codec, so check out
// .Seal().
func (am accountMapper) WireCodec() *wire.Codec {
return am.cdc
}
// Returns a "sealed" accountMapper.
// The codec is not accessible from a sealedAccountMapper.
func (am accountMapper) Seal() sealedAccountMapper {
return sealedAccountMapper{am}
}
// Implements sdk.AccountMapper.
func (am accountMapper) NewAccountWithAddress(ctx sdk.Context, addr crypto.Address) sdk.Account {
acc := am.clonePrototype()
acc.SetAddress(addr)
return acc
}
// Implements sdk.AccountMapper.
func (am accountMapper) GetAccount(ctx sdk.Context, addr crypto.Address) sdk.Account {
store := ctx.KVStore(am.key)
bz := store.Get(addr)
if bz == nil {
return nil
}
acc := am.decodeAccount(bz)
return acc
}
// Implements sdk.AccountMapper.
func (am accountMapper) SetAccount(ctx sdk.Context, acc sdk.Account) {
addr := acc.GetAddress()
store := ctx.KVStore(am.key)
bz := am.encodeAccount(acc)
store.Set(addr, bz)
}
//----------------------------------------
// misc.
func (am accountMapper) clonePrototypePtr() interface{} {
protoRt := reflect.TypeOf(am.proto)
if protoRt.Kind() == reflect.Ptr {
protoErt := protoRt.Elem()
if protoErt.Kind() != reflect.Struct {
panic("accountMapper requires a struct proto sdk.Account, or a pointer to one")
}
protoRv := reflect.New(protoErt)
return protoRv.Interface()
} else {
protoRv := reflect.New(protoRt)
return protoRv.Interface()
}
}
// Creates a new struct (or pointer to struct) from am.proto.
func (am accountMapper) clonePrototype() sdk.Account {
protoRt := reflect.TypeOf(am.proto)
if protoRt.Kind() == reflect.Ptr {
protoCrt := protoRt.Elem()
if protoCrt.Kind() != reflect.Struct {
panic("accountMapper requires a struct proto sdk.Account, or a pointer to one")
}
protoRv := reflect.New(protoCrt)
clone, ok := protoRv.Interface().(sdk.Account)
if !ok {
panic(fmt.Sprintf("accountMapper requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt))
}
return clone
} else {
protoRv := reflect.New(protoRt).Elem()
clone, ok := protoRv.Interface().(sdk.Account)
if !ok {
panic(fmt.Sprintf("accountMapper requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt))
}
return clone
}
}
func (am accountMapper) encodeAccount(acc sdk.Account) []byte {
bz, err := am.cdc.MarshalBinary(acc)
if err != nil {
panic(err)
}
return bz
}
func (am accountMapper) decodeAccount(bz []byte) sdk.Account {
accPtr := am.clonePrototypePtr()
err := am.cdc.UnmarshalBinary(bz, accPtr)
if err != nil {
panic(err)
}
if reflect.ValueOf(am.proto).Kind() == reflect.Ptr {
return reflect.ValueOf(accPtr).Interface().(sdk.Account)
} else {
return reflect.ValueOf(accPtr).Elem().Interface().(sdk.Account)
}
}
//----------------------------------------
// sealedAccountMapper
type sealedAccountMapper struct {
accountMapper
}
// There's no way for external modules to mutate the
// sam.accountMapper.ctx from here, even with reflection.
func (sam sealedAccountMapper) WireCodec() *wire.Codec {
panic("accountMapper is sealed")
}

View File

@ -1,154 +0,0 @@
package auth
import (
"fmt"
"reflect"
crypto "github.com/tendermint/go-crypto"
wire "github.com/tendermint/go-wire"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Implements sdk.AccountStore.
// This AccountStore encodes/decodes accounts using the
// go-wire (binary) encoding/decoding library.
type accountStore struct {
// The (unexposed) key used to access the store from the Context.
key sdk.SubstoreKey
// The prototypical sdk.Account concrete type.
proto sdk.Account
// The wire codec for binary encoding/decoding of accounts.
cdc *wire.Codec
}
// NewAccountStore returns a new sdk.AccountStore that
// uses go-wire to (binary) encode and decode concrete sdk.Accounts.
func NewAccountStore(key sdk.SubstoreKey, proto sdk.Account) accountStore {
cdc := wire.NewCodec()
return accountStore{
key: key,
proto: proto,
cdc: cdc,
}
}
// Returns the go-wire codec. You may need to register interfaces
// and concrete types here, if your app's sdk.Account
// implementation includes interface fields.
// NOTE: It is not secure to expose the codec, so check out
// .Seal().
func (as accountStore) WireCodec() *wire.Codec {
return as.cdc
}
// Returns a "sealed" accountStore.
// The codec is not accessible from a sealedAccountStore
func (as accountStore) Seal() sealedAccountStore {
return sealedAccountStore{as}
}
// Implements sdk.AccountStore.
func (as accountStore) NewAccountWithAddress(ctx sdk.Context, addr crypto.Address) sdk.Account {
acc := as.clonePrototype()
acc.SetAddress(addr)
return acc
}
// Implements sdk.AccountStore.
func (as accountStore) GetAccount(ctx sdk.Context, addr crypto.Address) sdk.Account {
store := ctx.KVStore(as.key)
bz := store.Get(addr)
if bz == nil {
return nil
}
acc := as.decodeAccount(bz)
return acc
}
// Implements sdk.AccountStore.
func (as accountStore) SetAccount(ctx sdk.Context, acc sdk.Account) {
addr := acc.GetAddress()
store := ctx.KVStore(as.key)
bz := as.encodeAccount(acc)
store.Set(addr, bz)
}
//----------------------------------------
// misc.
func (as accountStore) clonePrototypePtr() interface{} {
protoRt := reflect.TypeOf(as.proto)
if protoRt.Kind() == reflect.Ptr {
protoErt := protoRt.Elem()
if protoErt.Kind() != reflect.Struct {
panic("AccountStore requires a struct proto sdk.Account, or a pointer to one")
}
protoRv := reflect.New(protoErt)
return protoRv.Interface()
} else {
protoRv := reflect.New(protoRt)
return protoRv.Interface()
}
}
// Creates a new struct (or pointer to struct) from as.proto.
func (as accountStore) clonePrototype() sdk.Account {
protoRt := reflect.TypeOf(as.proto)
if protoRt.Kind() == reflect.Ptr {
protoCrt := protoRt.Elem()
if protoCrt.Kind() != reflect.Struct {
panic("AccountStore requires a struct proto sdk.Account, or a pointer to one")
}
protoRv := reflect.New(protoCrt)
clone, ok := protoRv.Interface().(sdk.Account)
if !ok {
panic(fmt.Sprintf("AccountStore requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt))
}
return clone
} else {
protoRv := reflect.New(protoRt).Elem()
clone, ok := protoRv.Interface().(sdk.Account)
if !ok {
panic(fmt.Sprintf("AccountStore requires a proto sdk.Account, but %v doesn't implement sdk.Account", protoRt))
}
return clone
}
}
func (as accountStore) encodeAccount(acc sdk.Account) []byte {
bz, err := as.cdc.MarshalBinary(acc)
if err != nil {
panic(err)
}
return bz
}
func (as accountStore) decodeAccount(bz []byte) sdk.Account {
accPtr := as.clonePrototypePtr()
err := as.cdc.UnmarshalBinary(bz, accPtr)
if err != nil {
panic(err)
}
if reflect.ValueOf(as.proto).Kind() == reflect.Ptr {
return reflect.ValueOf(accPtr).Interface().(sdk.Account)
} else {
return reflect.ValueOf(accPtr).Elem().Interface().(sdk.Account)
}
}
//----------------------------------------
// sealedAccountStore
type sealedAccountStore struct {
accountStore
}
// There's no way for external modules to mutate the
// sas.accountStore.ctx from here, even with reflection.
func (sas sealedAccountStore) WireCodec() *wire.Codec {
panic("accountStore is sealed")
}

View File

@ -6,16 +6,16 @@ import (
)
// Handle all "bank" type messages.
func NewHandler(accStore sdk.AccountStore) sdk.Handler {
func NewHandler(am sdk.AccountMapper) sdk.Handler {
return func(ctx sdk.Context, tx sdk.Tx) sdk.Result {
cs := CoinStore{accStore}
cm := CoinMapper{am}
msg := tx.(sdk.Msg)
switch msg := msg.(type) {
case SendMsg:
return handleSendMsg(ctx, cs, msg)
return handleSendMsg(ctx, cm, msg)
case IssueMsg:
return handleIssueMsg(ctx, cs, msg)
return handleIssueMsg(ctx, cm, msg)
default:
return sdk.Result{
Code: 1, // TODO
@ -27,11 +27,11 @@ func NewHandler(accStore sdk.AccountStore) sdk.Handler {
}
// Handle SendMsg.
func handleSendMsg(ctx sdk.Context, cs CoinStore, msg SendMsg) sdk.Result {
func handleSendMsg(ctx sdk.Context, cm CoinMapper, msg SendMsg) sdk.Result {
// NOTE: totalIn == totalOut should already have been checked
for _, in := range msg.Inputs {
_, err := cs.SubtractCoins(ctx, in.Address, in.Coins)
_, err := cm.SubtractCoins(ctx, in.Address, in.Coins)
if err != nil {
return sdk.Result{
Code: 1, // TODO
@ -40,7 +40,7 @@ func handleSendMsg(ctx sdk.Context, cs CoinStore, msg SendMsg) sdk.Result {
}
for _, out := range msg.Outputs {
_, err := cs.AddCoins(ctx, out.Address, out.Coins)
_, err := cm.AddCoins(ctx, out.Address, out.Coins)
if err != nil {
return sdk.Result{
Code: 1, // TODO
@ -52,6 +52,6 @@ func handleSendMsg(ctx sdk.Context, cs CoinStore, msg SendMsg) sdk.Result {
}
// Handle IssueMsg.
func handleIssueMsg(ctx sdk.Context, cs CoinStore, msg IssueMsg) sdk.Result {
func handleIssueMsg(ctx sdk.Context, cm CoinMapper, msg IssueMsg) sdk.Result {
panic("not implemented yet")
}

View File

@ -7,14 +7,14 @@ import (
crypto "github.com/tendermint/go-crypto"
)
// CoinStore manages transfers between accounts
type CoinStore struct {
store sdk.AccountStore
// CoinMapper manages transfers between accounts
type CoinMapper struct {
am sdk.AccountMapper
}
// SubtractCoins subtracts amt from the coins at the addr.
func (cs CoinStore) SubtractCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, error) {
acc := cs.store.GetAccount(ctx, addr)
func (cm CoinMapper) SubtractCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, error) {
acc := cm.am.GetAccount(ctx, addr)
if acc == nil {
return amt, fmt.Errorf("Sending account (%s) does not exist", addr)
}
@ -26,21 +26,21 @@ func (cs CoinStore) SubtractCoins(ctx sdk.Context, addr crypto.Address, amt sdk.
}
acc.SetCoins(newCoins)
cs.store.SetAccount(ctx, acc)
cm.am.SetAccount(ctx, acc)
return newCoins, nil
}
// AddCoins adds amt to the coins at the addr.
func (cs CoinStore) AddCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, error) {
acc := cs.store.GetAccount(ctx, addr)
func (cm CoinMapper) AddCoins(ctx sdk.Context, addr crypto.Address, amt sdk.Coins) (sdk.Coins, error) {
acc := cm.am.GetAccount(ctx, addr)
if acc == nil {
acc = cs.store.NewAccountWithAddress(ctx, addr)
acc = cm.am.NewAccountWithAddress(ctx, addr)
}
coins := acc.GetCoins()
newCoins := coins.Plus(amt)
acc.SetCoins(newCoins)
cs.store.SetAccount(ctx, acc)
cm.am.SetAccount(ctx, acc)
return newCoins, nil
}