wip refactoring basecoin

This commit is contained in:
rigelrozanski
2018-02-17 16:32:30 -05:00
committed by Ethan Buchman
parent 44536faf08
commit 6681904af9
9 changed files with 110 additions and 117 deletions
+32 -54
View File
@@ -16,30 +16,28 @@ import (
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
)
var mainHeaderKey = []byte("header")
// The ABCI application
type BaseApp struct {
logger log.Logger
name string // application name from abci.Info
db dbm.DB // common DB backend
cms sdk.CommitMultiStore // Main (uncached) state
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
InitStater sdk.InitStater // TODO unexpose
defaultAnteHandler sdk.AnteHandler // ante handler for fee and auth
router Router // handle any kind of message
logger log.Logger
name string // application name from abci.Info
db dbm.DB // common DB backend
cms sdk.CommitMultiStore // Main (uncached) state
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
InitStater sdk.InitStater // TODO unexpose
anteHandler sdk.AnteHandler // ante handler for fee and auth
router Router // handle any kind of message
//--------------------
// Volatile
accountMapper sdk.AccountMapper // Manage getting and setting accounts
msCheck sdk.CacheMultiStore // CheckTx state, a cache-wrap of `.cms`
msDeliver sdk.CacheMultiStore // DeliverTx state, a cache-wrap of `.cms`
header *abci.Header // current block header
valUpdates []abci.Validator // cached validator changes from DeliverTx
msCheck sdk.CacheMultiStore // CheckTx state, a cache-wrap of `.cms`
msDeliver sdk.CacheMultiStore // DeliverTx state, a cache-wrap of `.cms`
header *abci.Header // current block header
valUpdates []abci.Validator // cached validator changes from DeliverTx
}
var _ abci.Application = &BaseApp{}
@@ -59,40 +57,6 @@ func NewBaseApp(name string) *BaseApp {
return baseapp
}
// Create and name new BaseApp
func NewBaseAppExpanded(name string, accountMapper sdk.AccountMapper, keys []*sdk.KVStoreKey) *BaseApp {
var baseapp = &BaseApp{
logger: makeDefaultLogger(),
name: name,
db: nil,
cms: nil,
defaultAnteHandler: auth.NewAnteHandler(app.AccountMapper()),
router: NewRouter(),
accountMapper: accountMapper,
}
baseapp.initDB()
baseapp.initMultiStore()
baseapp.initAccountMapper()
for _, key := range keys {
baseApp.MountStore(key, sdk.StoreTypeIAVL)
}
return baseapp
}
// Initialize the AccountMapper.
func (app *BaseApp) initAccountMapper() {
// Register all interfaces and concrete types that
// implement those interfaces, here.
cdc := accountMapper.WireCodec()
auth.RegisterWireBaseAccount(cdc)
// Make accountMapper's WireCodec() inaccessible.
app.accountMapper = accountMapper.Seal()
}
// Create the underlying leveldb datastore which will
// persist the Merkle tree inner & leaf nodes.
func (app *BaseApp) initDB() {
@@ -114,6 +78,13 @@ func (app *BaseApp) Name() string {
return app.name
}
// Mount a store to the provided key in the BaseApp multistore
func (app *BaseApp) MountStoresIAVL(keys ...*sdk.KVStoreKey) {
for _, key := range keys {
app.MountStore(key, sdk.StoreTypeIAVL)
}
}
// Mount a store to the provided key in the BaseApp multistore
func (app *BaseApp) MountStore(key sdk.StoreKey, typ sdk.StoreType) {
app.cms.MountStoreWithDB(key, typ, app.db)
@@ -126,14 +97,13 @@ func (app *BaseApp) SetTxDecoder(txDecoder sdk.TxDecoder) {
func (app *BaseApp) SetInitStater(initStater sdk.InitStater) {
app.InitStater = initStater
}
func (app *BaseApp) SetDefaultAnteHandler(ah sdk.AnteHandler) {
func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) {
// deducts fee from payer, verifies signatures and nonces, sets Signers to ctx.
app.defaultAnteHandler = ah
app.anteHandler = ah
}
// nolint - Get functions
func (app *BaseApp) Router() Router { return app.router }
func (app *BaseApp) AccountMapper() sdk.AccountMapper { return app.accountMapper }
func (app *BaseApp) Router() Router { return app.router }
/* TODO consider:
func (app *BaseApp) SetBeginBlocker(...) {}
@@ -224,7 +194,15 @@ func (app *BaseApp) SetOption(req abci.RequestSetOption) (res abci.ResponseSetOp
// Implements ABCI
func (app *BaseApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) {
// TODO: Use req.Validators
// TODO: Use req.AppState
// TODO: Use req.AppState in InitStater
app.msDeliver = app.cms.CacheMultiStore()
ctx := app.GenesisContext(nil)
err := app.InitStater(ctx, nil)
if err != nil {
cmn.Exit(fmt.Sprintf("error initializing application genesis state: %v", err))
}
return
}
@@ -338,7 +316,7 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
// TODO: override default ante handler w/ custom ante handler.
// Run the ante handler.
newCtx, result, abort := app.defaultAnteHandler(ctx, tx)
newCtx, result, abort := app.anteHandler(ctx, tx)
if isCheckTx || abort {
return result
}
+1 -1
View File
@@ -44,7 +44,7 @@ func TestBasic(t *testing.T) {
return ttx, nil
})
app.SetDefaultAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
app.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx) (newCtx sdk.Context, res sdk.Result, abort bool) { return })
app.Router().AddRoute(msgType, func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
// TODO
return sdk.Result{}
+11 -8
View File
@@ -2,6 +2,7 @@ package baseapp
import (
sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/abci/types"
)
// NewContext returns a new Context suitable for AnteHandler (and indirectly Handler) processing.
@@ -22,12 +23,14 @@ func (app *BaseApp) NewContext(isCheckTx bool, txBytes []byte) sdk.Context {
panic("BaseApp.NewContext() requires BeginBlock(): missing header")
}
// Initialize arguments to Handler.
var ctx = sdk.NewContext(
store,
*app.header,
isCheckTx,
txBytes,
)
return ctx
return sdk.NewContext(store, *app.header, isCheckTx, txBytes)
}
// context used during genesis
func (app *BaseApp) GenesisContext(txBytes []byte) sdk.Context {
store := app.msDeliver
if store == nil {
panic("BaseApp.NewContext() requires BeginBlock(): missing store")
}
return sdk.NewContext(store, abci.Header{}, false, txBytes)
}
+1 -1
View File
@@ -13,7 +13,7 @@ type GenesisDoc struct {
}
// GenesisDocFromFile reads JSON data from a file and unmarshalls it into a GenesisDoc.
func ReadGenesisAppState(genesisPath string) (state json.RawMessage, err error) {
func LoadGenesisAppState(genesisPath string) (state json.RawMessage, err error) {
if genesisPath == "" {
return
}
@@ -1,23 +1,24 @@
package baseapp
package testapp
import (
abci "github.com/tendermint/abci/types"
"github.com/tendermint/go-crypto"
bam "github.com/cosmos/cosmos-sdk/baseapp"
x "github.com/cosmos/cosmos-sdk/baseapp/testapp/x"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// TestApp wraps BaseApp with helper methods,
// and exposes more functionality than otherwise needed.
type TestApp struct {
*BaseApp
*bam.BaseApp
// These get set as we receive them.
*abci.ResponseBeginBlock
*abci.ResponseEndBlock
}
func NewTestApp(bapp *BaseApp) *TestApp {
func NewTestApp(bapp *bam.BaseApp) *TestApp {
app := &TestApp{
BaseApp: bapp,
}
@@ -75,16 +76,16 @@ func (tapp *TestApp) RunDeliverTx(tx sdk.Tx) sdk.Result {
}
// run tx through CheckTx of TestApp
// NOTE: Skips authentication by wrapping msg in testTx{}.
// NOTE: Skips authentication by wrapping msg in TestTx{}.
func (tapp *TestApp) RunCheckMsg(msg sdk.Msg) sdk.Result {
var tx = testTx{msg}
var tx = x.TestTx{msg}
return tapp.RunCheckTx(tx)
}
// run tx through DeliverTx of TestApp
// NOTE: Skips authentication by wrapping msg in testTx{}.
// NOTE: Skips authentication by wrapping msg in TestTx{}.
func (tapp *TestApp) RunDeliverMsg(msg sdk.Msg) sdk.Result {
var tx = testTx{msg}
var tx = x.TestTx{msg}
return tapp.RunDeliverTx(tx)
}
@@ -102,20 +103,3 @@ func (tapp *TestApp) MultiStoreCheck() sdk.MultiStore {
func (tapp *TestApp) MultiStoreDeliver() sdk.MultiStore {
return tapp.BaseApp.msDeliver
}
//----------------------------------------
// testTx
type testTx struct {
sdk.Msg
}
// nolint
func (tx testTx) GetMsg() sdk.Msg { return tx.Msg }
func (tx testTx) GetSigners() []crypto.Address { return nil }
func (tx testTx) GetFeePayer() crypto.Address { return nil }
func (tx testTx) GetSignatures() []sdk.StdSignature { return nil }
func IsTestAppTx(tx sdk.Tx) bool {
_, ok := tx.(testTx)
return ok
}
+22
View File
@@ -0,0 +1,22 @@
package baseapp
import (
"github.com/tendermint/go-crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// testing transaction
type TestTx struct {
sdk.Msg
}
// nolint
func (tx TestTx) GetMsg() sdk.Msg { return tx.Msg }
func (tx TestTx) GetSigners() []crypto.Address { return nil }
func (tx TestTx) GetFeePayer() crypto.Address { return nil }
func (tx TestTx) GetSignatures() []sdk.StdSignature { return nil }
func IsTestAppTx(tx sdk.Tx) bool {
_, ok := tx.(TestTx)
return ok
}
+28 -22
View File
@@ -11,7 +11,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/sketchy"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/go-wire"
cmn "github.com/tendermint/tmlibs/common"
@@ -27,27 +26,43 @@ type BasecoinApp struct {
// keys to access the substores
capKeyMainStore *sdk.KVStoreKey
capKeyIBCStore *sdk.KVStoreKey
// Manage getting and setting accounts
accountMapper sdk.AccountMapper
}
func NewBasecoinApp(genesisPath string) *BasecoinApp {
var app = &BasecoinApp{
cdc: makeCodex(),
capKeyMainStore: sdk.NewKVStoreKey("main"),
capKeyIBCStore: sdk.NewKVStoreKey("ibc"),
}
// define some keys
mainKey := sdk.NewKVStoreKey("main")
ibcKey := sdk.NewKVStoreKey("ibc")
var accMapper = auth.NewAccountMapper(
app.capKeyMainStore, // target store
// define a mapper
accountMapper := auth.NewAccountMapper(
mainKey, // target store
&types.AppAccount{}, // prototype
)
cdc := accountMapper.WireCodec()
auth.RegisterWireBaseAccount(cdc)
// Make accountMapper's WireCodec() inaccessible.
app.accountMapper = accountMapper.Seal()
// create your application object
var app = &BasecoinApp{
BaseApp: bam.NewBaseApp(appName, accountMapper),
cdc: makeTxCodec(),
capKeyMainStore: mainKey,
capKeyIBCStore: ibcKey,
}
app.BaseApp = bam.NewBaseAppExpanded(appName, accMapper)
app.initBaseAppTxDecoder()
app.initBaseAppInitStater(genesisPath)
// Add the handlers
app.Router().AddRoute("bank", bank.NewHandler(bank.NewCoinKeeper(app.AccountMapper())))
app.MountStoresIAVL(app.capKeyMainStore, app.capKeyIBCStore)
// add handlers
app.SetAnteHandler(auth.NewAnteHandler(accountMapper))
app.Router().AddRoute("bank", bank.NewHandler(bank.NewCoinKeeper(accountMapper)))
app.Router().AddRoute("sketchy", sketchy.NewHandler())
// load the stores
@@ -89,20 +104,11 @@ func (app *BasecoinApp) initBaseAppTxDecoder() {
// define the custom logic for basecoin initialization
func (app *BasecoinApp) initBaseAppInitStater(genesisPath string) {
genesisAppState, err := bam.ReadGenesisAppState(genesisPath)
genesisAppState, err := bam.LoadGenesisAppState(genesisPath)
if err != nil {
panic(fmt.Errorf("error loading genesis state: %v", err))
}
// set up the cache store for ctx, get ctx
// TODO: combine with InitChain and let tendermint invoke it.
app.BaseApp.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{}})
ctx := app.BaseApp.NewContext(false, nil) // context for DeliverTx
err = app.BaseApp.InitStater(ctx, genesisAppState)
if err != nil {
cmn.Exit(fmt.Sprintf("error initializing application genesis state: %v", err))
}
app.BaseApp.SetInitStater(func(ctx sdk.Context, state json.RawMessage) sdk.Error {
if state == nil {
return nil
@@ -119,7 +125,7 @@ func (app *BasecoinApp) initBaseAppInitStater(genesisPath string) {
if err != nil {
return sdk.ErrGenesisParse("").TraceCause(err, "")
}
app.AccountMapper().SetAccount(ctx, acc)
app.accountMapper.SetAccount(ctx, acc)
}
return nil
})
+1 -1
View File
@@ -26,7 +26,7 @@ func newTestBasecoinApp() *testBasecoinApp {
tba := &testBasecoinApp{
BasecoinApp: app,
}
tba.TestApp = bam.NewTestApp(app.BaseApp)
tba.TestApp = testapp.NewTestApp(app.BaseApp)
return tba
}
+5 -5
View File
@@ -1,7 +1,7 @@
package auth
import (
bam "github.com/cosmos/cosmos-sdk/baseapp"
tax "github.com/cosmos/cosmos-sdk/baseapp/testapp/x"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@@ -25,14 +25,14 @@ func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
// TODO: accountMapper.SetAccount(ctx, payerAddr)
} else {
// TODO: Ensure that some other spam prevention is used.
// NOTE: bam.TestApp.RunDeliverMsg/RunCheckMsg will
// create a Tx with no payer.
// NOTE: testapp.TestApp.RunDeliverMsg/RunCheckMsg will
// create a Tx with no payer.
}
var sigs = tx.GetSignatures()
// Assert that there are signatures.
if !bam.IsTestAppTx(tx) {
if !tax.IsTestAppTx(tx) {
if len(sigs) == 0 {
return ctx,
sdk.ErrUnauthorized("no signers").Result(),
@@ -46,7 +46,7 @@ func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
var signerAccs = make([]sdk.Account, len(signerAddrs))
// Assert that number of signatures is correct.
if !bam.IsTestAppTx(tx) {
if !tax.IsTestAppTx(tx) {
if len(sigs) != len(signerAddrs) {
return ctx,
sdk.ErrUnauthorized("wrong number of signers").Result(),