wip refactoring basecoin
This commit is contained in:
committed by
Ethan Buchman
parent
44536faf08
commit
6681904af9
+32
-54
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
})
|
||||
|
||||
@@ -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
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user