Substore->Store; BaseApp has db; Mapper
This commit is contained in:
parent
b4e4881261
commit
be665d53fe
@ -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{}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
|
||||
1
baseapp/data/TestBasic.db/CURRENT
Normal file
1
baseapp/data/TestBasic.db/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000093
|
||||
0
baseapp/data/TestBasic.db/LOCK
Normal file
0
baseapp/data/TestBasic.db/LOCK
Normal file
420
baseapp/data/TestBasic.db/LOG
Normal file
420
baseapp/data/TestBasic.db/LOG
Normal 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
|
||||
BIN
baseapp/data/TestBasic.db/MANIFEST-000093
Normal file
BIN
baseapp/data/TestBasic.db/MANIFEST-000093
Normal file
Binary file not shown.
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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")
|
||||
|
||||
}
|
||||
|
||||
@ -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))
|
||||
}
|
||||
|
||||
@ -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()
|
||||
}
|
||||
|
||||
@ -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
4
glide.lock
generated
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
23
store/dbstoreadapter.go
Normal 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)}
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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() {}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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{}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
154
x/auth/mapper.go
Normal 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")
|
||||
}
|
||||
154
x/auth/store.go
154
x/auth/store.go
@ -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")
|
||||
}
|
||||
@ -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")
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user