Documentation Structure Change and Cleanup (#2808)
* Update docs/sdk/clients.md * organize ADR directory like tendermint * docs: move spec-proposals into spec/ * remove lotion, moved to website repo * move getting-started to cosmos-hub, and voyager to website * docs: move lite/ into clients/lite/ * move introduction/ content to website repo * move resources/ content to website repo * mv sdk/clients.md to clients/clients.md * mv validators to cosmos-hub/validators * move deprecated sdk/ content to _attic * sdk/modules.md is duplicate with modules/README.md * consolidate remianing sdk/ files into a single sdk.md * move examples/ to docs/examples/ * mv docs/cosmos-hub to docs/gaia * Add keys/accounts section to localnet docs
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/docs/examples/basecoin/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
"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
|
||||
|
||||
// manage getting and setting accounts
|
||||
accountKeeper auth.AccountKeeper
|
||||
feeCollectionKeeper auth.FeeCollectionKeeper
|
||||
bankKeeper bank.Keeper
|
||||
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.
|
||||
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()
|
||||
|
||||
// create your application type
|
||||
var app = &BasecoinApp{
|
||||
cdc: cdc,
|
||||
BaseApp: bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc), baseAppOptions...),
|
||||
keyMain: sdk.NewKVStoreKey("main"),
|
||||
keyAccount: sdk.NewKVStoreKey("acc"),
|
||||
keyIBC: sdk.NewKVStoreKey("ibc"),
|
||||
}
|
||||
|
||||
// define and attach the mappers and keepers
|
||||
app.accountKeeper = auth.NewAccountKeeper(
|
||||
cdc,
|
||||
app.keyAccount, // target store
|
||||
func() auth.Account {
|
||||
return &types.AppAccount{}
|
||||
},
|
||||
)
|
||||
app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper)
|
||||
app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace))
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
cmn.Exit(err.Error())
|
||||
}
|
||||
|
||||
app.Seal()
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
// register custom type
|
||||
cdc.RegisterConcrete(&types.AppAccount{}, "basecoin/Account", nil)
|
||||
|
||||
cdc.Seal()
|
||||
|
||||
return cdc
|
||||
}
|
||||
|
||||
// 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 {
|
||||
stateJSON := req.AppStateBytes
|
||||
|
||||
genesisState := new(types.GenesisState)
|
||||
err := app.cdc.UnmarshalJSON(stateJSON, genesisState)
|
||||
if err != nil {
|
||||
// TODO: https://github.com/cosmos/cosmos-sdk/issues/468
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, gacc := range genesisState.Accounts {
|
||||
acc, err := gacc.ToAppAccount()
|
||||
if err != nil {
|
||||
// TODO: https://github.com/cosmos/cosmos-sdk/issues/468
|
||||
panic(err)
|
||||
}
|
||||
|
||||
acc.AccountNumber = app.accountKeeper.GetNextAccountNumber(ctx)
|
||||
app.accountKeeper.SetAccount(ctx, acc)
|
||||
}
|
||||
|
||||
return abci.ResponseInitChain{}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
ctx := app.NewContext(true, abci.Header{})
|
||||
accounts := []*types.GenesisAccount{}
|
||||
|
||||
appendAccountsFn := func(acc auth.Account) bool {
|
||||
account := &types.GenesisAccount{
|
||||
Address: acc.GetAddress(),
|
||||
Coins: acc.GetCoins(),
|
||||
}
|
||||
|
||||
accounts = append(accounts, account)
|
||||
return false
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/docs/examples/basecoin/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
)
|
||||
|
||||
func setGenesis(baseApp *BasecoinApp, accounts ...*types.AppAccount) (types.GenesisState, error) {
|
||||
genAccts := make([]*types.GenesisAccount, len(accounts))
|
||||
for i, appAct := range accounts {
|
||||
genAccts[i] = types.NewGenesisAccount(appAct)
|
||||
}
|
||||
|
||||
genesisState := types.GenesisState{Accounts: genAccts}
|
||||
stateBytes, err := codec.MarshalJSONIndent(baseApp.cdc, genesisState)
|
||||
if err != nil {
|
||||
return types.GenesisState{}, err
|
||||
}
|
||||
|
||||
// initialize and commit the chain
|
||||
baseApp.InitChain(abci.RequestInitChain{
|
||||
Validators: []abci.ValidatorUpdate{}, AppStateBytes: stateBytes,
|
||||
})
|
||||
baseApp.Commit()
|
||||
|
||||
return genesisState, nil
|
||||
}
|
||||
|
||||
func TestGenesis(t *testing.T) {
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app")
|
||||
db := dbm.NewMemDB()
|
||||
baseApp := NewBasecoinApp(logger, db)
|
||||
|
||||
// construct a pubkey and an address for the test account
|
||||
pubkey := ed25519.GenPrivKey().PubKey()
|
||||
addr := sdk.AccAddress(pubkey.Address())
|
||||
|
||||
// construct some test coins
|
||||
coins, err := sdk.ParseCoins("77foocoin,99barcoin")
|
||||
require.Nil(t, err)
|
||||
|
||||
// create an auth.BaseAccount for the given test account and set it's coins
|
||||
baseAcct := auth.NewBaseAccountWithAddress(addr)
|
||||
err = baseAcct.SetCoins(coins)
|
||||
require.Nil(t, err)
|
||||
|
||||
// create a new test AppAccount with the given auth.BaseAccount
|
||||
appAcct := types.NewAppAccount("foobar", baseAcct)
|
||||
genState, err := setGenesis(baseApp, appAcct)
|
||||
require.Nil(t, err)
|
||||
|
||||
// create a context for the BaseApp
|
||||
ctx := baseApp.BaseApp.NewContext(true, abci.Header{})
|
||||
res := baseApp.accountKeeper.GetAccount(ctx, baseAcct.Address)
|
||||
require.Equal(t, appAcct, res)
|
||||
|
||||
// reload app and ensure the account is still there
|
||||
baseApp = NewBasecoinApp(logger, db)
|
||||
|
||||
stateBytes, err := codec.MarshalJSONIndent(baseApp.cdc, genState)
|
||||
require.Nil(t, err)
|
||||
|
||||
// initialize the chain with the expected genesis state
|
||||
baseApp.InitChain(abci.RequestInitChain{
|
||||
Validators: []abci.ValidatorUpdate{}, AppStateBytes: stateBytes,
|
||||
})
|
||||
|
||||
ctx = baseApp.BaseApp.NewContext(true, abci.Header{})
|
||||
res = baseApp.accountKeeper.GetAccount(ctx, baseAcct.Address)
|
||||
require.Equal(t, appAcct, res)
|
||||
}
|
||||
Reference in New Issue
Block a user