cosmos-sdk/examples/basecoin/app/app.go

190 lines
5.8 KiB
Go
Raw Normal View History

package app
import (
2018-04-27 17:36:11 -07:00
"encoding/json"
"os"
2018-04-27 17:36:11 -07:00
bam "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/examples/basecoin/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
2018-03-15 07:07:01 -07:00
"github.com/cosmos/cosmos-sdk/x/ibc"
abci "github.com/tendermint/tendermint/abci/types"
cmn "github.com/tendermint/tendermint/libs/common"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
tmtypes "github.com/tendermint/tendermint/types"
)
const (
appName = "BasecoinApp"
)
// default home directories for expected binaries
var (
DefaultCLIHome = os.ExpandEnv("$HOME/.basecli")
DefaultNodeHome = os.ExpandEnv("$HOME/.basecoind")
)
// BasecoinApp implements an extended ABCI application. It contains a BaseApp,
// a codec for serialization, KVStore keys for multistore state management, and
// various mappers and keepers to manage getting, setting, and serializing the
// integral app types.
type BasecoinApp struct {
*bam.BaseApp
cdc *codec.Codec
// keys to access the multistore
keyMain *sdk.KVStoreKey
keyAccount *sdk.KVStoreKey
keyIBC *sdk.KVStoreKey
2018-02-14 17:09:00 -08:00
// manage getting and setting accounts
accountKeeper auth.AccountKeeper
2018-05-25 20:29:40 -07:00
feeCollectionKeeper auth.FeeCollectionKeeper
bankKeeper bank.Keeper
2018-05-25 20:29:40 -07:00
ibcMapper ibc.Mapper
}
// NewBasecoinApp returns a reference to a new BasecoinApp given a logger and
// database. Internally, a codec is created along with all the necessary keys.
// In addition, all necessary mappers and keepers are created, routes
// registered, and finally the stores being mounted along with any necessary
// chain initialization.
2018-07-12 18:20:26 -07:00
func NewBasecoinApp(logger log.Logger, db dbm.DB, baseAppOptions ...func(*bam.BaseApp)) *BasecoinApp {
// create and register app-level codec for TXs and accounts
cdc := MakeCodec()
2018-04-07 00:02:00 -07:00
// create your application type
2018-02-14 17:09:00 -08:00
var app = &BasecoinApp{
cdc: cdc,
2018-07-18 16:24:16 -07:00
BaseApp: bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc), baseAppOptions...),
keyMain: sdk.NewKVStoreKey("main"),
keyAccount: sdk.NewKVStoreKey("acc"),
keyIBC: sdk.NewKVStoreKey("ibc"),
2018-02-14 17:09:00 -08:00
}
2018-02-14 11:14:22 -08:00
// define and attach the mappers and keepers
app.accountKeeper = auth.NewAccountKeeper(
2018-04-07 00:02:00 -07:00
cdc,
app.keyAccount, // target store
func() auth.Account {
2018-08-08 08:32:33 -07:00
return &types.AppAccount{}
},
2018-04-22 23:36:15 -07:00
)
app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper)
app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace))
2018-02-14 11:14:22 -08:00
// register message routes
app.Router().
AddRoute("bank", bank.NewHandler(app.bankKeeper)).
AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.bankKeeper))
// perform initialization logic
app.SetInitChainer(app.initChainer)
app.SetBeginBlocker(app.BeginBlocker)
app.SetEndBlocker(app.EndBlocker)
app.SetAnteHandler(auth.NewAnteHandler(app.accountKeeper, app.feeCollectionKeeper))
// mount the multistore and load the latest state
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC)
err := app.LoadLatestVersion(app.keyMain)
2018-02-15 08:00:57 -08:00
if err != nil {
2018-02-14 11:14:22 -08:00
cmn.Exit(err.Error())
}
app.Seal()
2018-02-14 11:14:22 -08:00
return app
2018-02-14 08:16:06 -08:00
}
// MakeCodec creates a new codec codec and registers all the necessary types
// with the codec.
func MakeCodec() *codec.Codec {
cdc := codec.New()
codec.RegisterCrypto(cdc)
sdk.RegisterCodec(cdc)
bank.RegisterCodec(cdc)
ibc.RegisterCodec(cdc)
auth.RegisterCodec(cdc)
2018-03-02 01:24:07 -08:00
2018-08-08 08:32:33 -07:00
// register custom type
2018-04-06 16:20:14 -07:00
cdc.RegisterConcrete(&types.AppAccount{}, "basecoin/Account", nil)
cdc.Seal()
2018-02-15 08:00:57 -08:00
return cdc
2018-02-14 08:16:06 -08:00
}
// BeginBlocker reflects logic to run before any TXs application are processed
// by the application.
func (app *BasecoinApp) BeginBlocker(_ sdk.Context, _ abci.RequestBeginBlock) abci.ResponseBeginBlock {
return abci.ResponseBeginBlock{}
}
// EndBlocker reflects logic to run after all TXs are processed by the
// application.
func (app *BasecoinApp) EndBlocker(_ sdk.Context, _ abci.RequestEndBlock) abci.ResponseEndBlock {
return abci.ResponseEndBlock{}
}
// initChainer implements the custom application logic that the BaseApp will
// invoke upon initialization. In this case, it will take the application's
// state provided by 'req' and attempt to deserialize said state. The state
// should contain all the genesis accounts. These accounts will be added to the
// application's account mapper.
func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
2018-06-04 16:42:01 -07:00
stateJSON := req.AppStateBytes
2018-02-14 08:16:06 -08:00
genesisState := new(types.GenesisState)
2018-04-23 17:05:58 -07:00
err := app.cdc.UnmarshalJSON(stateJSON, genesisState)
if err != nil {
// TODO: https://github.com/cosmos/cosmos-sdk/issues/468
panic(err)
}
2018-02-14 08:16:06 -08:00
for _, gacc := range genesisState.Accounts {
acc, err := gacc.ToAppAccount()
if err != nil {
// TODO: https://github.com/cosmos/cosmos-sdk/issues/468
panic(err)
2018-02-14 08:16:06 -08:00
}
acc.AccountNumber = app.accountKeeper.GetNextAccountNumber(ctx)
app.accountKeeper.SetAccount(ctx, acc)
}
return abci.ResponseInitChain{}
2018-02-14 08:16:06 -08:00
}
2018-04-26 08:53:07 -07:00
// ExportAppStateAndValidators implements custom application logic that exposes
// various parts of the application's state and set of validators. An error is
// returned if any step getting the state or set of validators fails.
func (app *BasecoinApp) ExportAppStateAndValidators() (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) {
2018-04-27 07:59:47 -07:00
ctx := app.NewContext(true, abci.Header{})
accounts := []*types.GenesisAccount{}
appendAccountsFn := func(acc auth.Account) bool {
2018-04-27 17:47:35 -07:00
account := &types.GenesisAccount{
Address: acc.GetAddress(),
Coins: acc.GetCoins(),
}
2018-04-27 17:47:35 -07:00
accounts = append(accounts, account)
2018-04-27 07:59:47 -07:00
return false
2018-04-27 17:47:35 -07:00
}
app.accountKeeper.IterateAccounts(ctx, appendAccountsFn)
genState := types.GenesisState{Accounts: accounts}
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
if err != nil {
return nil, nil, err
}
return appState, validators, err
2018-04-26 08:53:07 -07:00
}