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:
gamarin2
2018-11-14 11:44:17 -08:00
committed by Jack Zampolin
parent 6feab55e1e
commit addcfbf5cb
156 changed files with 664 additions and 5897 deletions
+189
View File
@@ -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
}
+81
View File
@@ -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)
}
@@ -0,0 +1,55 @@
package clitest
import (
"encoding/json"
"fmt"
"os"
"testing"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/stretchr/testify/require"
)
var (
basecoindHome = ""
basecliHome = ""
)
func init() {
basecoindHome, basecliHome = getTestingHomeDirs()
}
func TestInitStartSequence(t *testing.T) {
os.RemoveAll(basecoindHome)
servAddr, port, err := server.FreeTCPAddr()
require.NoError(t, err)
executeInit(t)
executeStart(t, servAddr, port)
}
func executeInit(t *testing.T) {
var (
chainID string
initRes map[string]json.RawMessage
)
_, stderr := tests.ExecuteT(t, fmt.Sprintf("basecoind --home=%s --home-client=%s init --name=test", basecoindHome, basecliHome), app.DefaultKeyPass)
err := json.Unmarshal([]byte(stderr), &initRes)
require.NoError(t, err)
err = json.Unmarshal(initRes["chain_id"], &chainID)
require.NoError(t, err)
}
func executeStart(t *testing.T, servAddr, port string) {
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("basecoind start --home=%s --rpc.laddr=%v", basecoindHome, servAddr))
defer proc.Stop(false)
tests.WaitForTMStart(port)
}
func getTestingHomeDirs() (string, string) {
tmpDir := os.TempDir()
basecoindHome := fmt.Sprintf("%s%s.test_basecoind", tmpDir, string(os.PathSeparator))
basecliHome := fmt.Sprintf("%s%s.test_basecli", tmpDir, string(os.PathSeparator))
return basecoindHome, basecliHome
}
@@ -0,0 +1,99 @@
package main
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/lcd"
_ "github.com/cosmos/cosmos-sdk/client/lcd/statik"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/docs/examples/basecoin/app"
"github.com/cosmos/cosmos-sdk/docs/examples/basecoin/types"
"github.com/cosmos/cosmos-sdk/version"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli"
slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli"
"github.com/spf13/cobra"
"github.com/tendermint/tendermint/libs/cli"
)
// rootCmd is the entry point for this binary
var (
rootCmd = &cobra.Command{
Use: "basecli",
Short: "Basecoin light-client",
}
)
func main() {
// disable sorting
cobra.EnableCommandSorting = false
// get the codec
cdc := app.MakeCodec()
// TODO: Setup keybase, viper object, etc. to be passed into
// the below functions and eliminate global vars, like we do
// with the cdc.
// add standard rpc, and tx commands
rootCmd.AddCommand(
rpc.InitClientCommand(),
rpc.StatusCommand(),
client.LineBreak,
tx.SearchTxCmd(cdc),
tx.QueryTxCmd(cdc),
client.LineBreak,
)
// add query/post commands (custom to binary)
rootCmd.AddCommand(
client.GetCommands(
stakecmd.GetCmdQueryValidator("stake", cdc),
stakecmd.GetCmdQueryValidators("stake", cdc),
stakecmd.GetCmdQueryValidatorUnbondingDelegations("stake", cdc),
stakecmd.GetCmdQueryValidatorRedelegations("stake", cdc),
stakecmd.GetCmdQueryDelegation("stake", cdc),
stakecmd.GetCmdQueryDelegations("stake", cdc),
stakecmd.GetCmdQueryPool("stake", cdc),
stakecmd.GetCmdQueryParams("stake", cdc),
stakecmd.GetCmdQueryUnbondingDelegation("stake", cdc),
stakecmd.GetCmdQueryUnbondingDelegations("stake", cdc),
stakecmd.GetCmdQueryRedelegation("stake", cdc),
stakecmd.GetCmdQueryRedelegations("stake", cdc),
slashingcmd.GetCmdQuerySigningInfo("slashing", cdc),
authcmd.GetAccountCmd("acc", cdc, types.GetAccountDecoder(cdc)),
)...)
rootCmd.AddCommand(
client.PostCommands(
bankcmd.SendTxCmd(cdc),
ibccmd.IBCTransferCmd(cdc),
ibccmd.IBCRelayCmd(cdc),
stakecmd.GetCmdCreateValidator(cdc),
stakecmd.GetCmdEditValidator(cdc),
stakecmd.GetCmdDelegate(cdc),
stakecmd.GetCmdUnbond("stake", cdc),
stakecmd.GetCmdRedelegate("stake", cdc),
slashingcmd.GetCmdUnjail(cdc),
)...)
// add proxy, version and key info
rootCmd.AddCommand(
client.LineBreak,
lcd.ServeCommand(cdc),
keys.Commands(),
client.LineBreak,
version.VersionCmd,
)
// prepare and add flags
executor := cli.PrepareMainCmd(rootCmd, "BC", app.DefaultCLIHome)
err := executor.Execute()
if err != nil {
// Note: Handle with #870
panic(err)
}
}
@@ -0,0 +1,133 @@
package main
import (
"encoding/json"
"fmt"
"io"
"os"
"github.com/tendermint/tendermint/p2p"
"github.com/cosmos/cosmos-sdk/baseapp"
gaiaInit "github.com/cosmos/cosmos-sdk/cmd/gaia/init"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/docs/examples/basecoin/app"
"github.com/cosmos/cosmos-sdk/server"
"github.com/spf13/cobra"
"github.com/spf13/viper"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/cli"
"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 (
flagClientHome = "home-client"
)
func main() {
cdc := app.MakeCodec()
ctx := server.NewDefaultContext()
rootCmd := &cobra.Command{
Use: "basecoind",
Short: "Basecoin Daemon (server)",
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
}
appInit := server.DefaultAppInit
rootCmd.AddCommand(InitCmd(ctx, cdc, appInit))
server.AddCommands(ctx, cdc, rootCmd, appInit,
newApp, exportAppStateAndTMValidators)
// prepare and add flags
rootDir := os.ExpandEnv("$HOME/.basecoind")
executor := cli.PrepareBaseCmd(rootCmd, "BC", rootDir)
err := executor.Execute()
if err != nil {
// Note: Handle with #870
panic(err)
}
}
// get cmd to initialize all files for tendermint and application
// nolint: errcheck
func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cobra.Command {
cmd := &cobra.Command{
Use: "init",
Short: "Initialize genesis config, priv-validator file, and p2p-node file",
Args: cobra.NoArgs,
RunE: func(_ *cobra.Command, _ []string) error {
config := ctx.Config
config.SetRoot(viper.GetString(cli.HomeFlag))
chainID := viper.GetString(client.FlagChainID)
if chainID == "" {
chainID = fmt.Sprintf("test-chain-%v", common.RandStr(6))
}
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
if err != nil {
return err
}
nodeID := string(nodeKey.ID())
pk := gaiaInit.ReadOrCreatePrivValidator(config.PrivValidatorFile())
genTx, appMessage, validator, err := server.SimpleAppGenTx(cdc, pk)
if err != nil {
return err
}
appState, err := appInit.AppGenState(
cdc, tmtypes.GenesisDoc{}, []json.RawMessage{genTx})
if err != nil {
return err
}
appStateJSON, err := cdc.MarshalJSON(appState)
if err != nil {
return err
}
toPrint := struct {
ChainID string `json:"chain_id"`
NodeID string `json:"node_id"`
AppMessage json.RawMessage `json:"app_message"`
}{
chainID,
nodeID,
appMessage,
}
out, err := codec.MarshalJSONIndent(cdc, toPrint)
if err != nil {
return err
}
fmt.Fprintf(os.Stderr, "%s\n", string(out))
return gaiaInit.ExportGenesisFile(config.GenesisFile(), chainID,
[]tmtypes.GenesisValidator{validator}, appStateJSON)
},
}
cmd.Flags().String(cli.HomeFlag, app.DefaultNodeHome, "node's home directory")
cmd.Flags().String(flagClientHome, app.DefaultCLIHome, "client's home directory")
cmd.Flags().String(client.FlagChainID, "",
"genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(client.FlagName, "", "validator's moniker")
cmd.MarkFlagRequired(client.FlagName)
return cmd
}
func newApp(logger log.Logger, db dbm.DB, storeTracer io.Writer) abci.Application {
return app.NewBasecoinApp(logger, db, baseapp.SetPruning(viper.GetString("pruning")))
}
func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB, storeTracer io.Writer) (
json.RawMessage, []tmtypes.GenesisValidator, error) {
bapp := app.NewBasecoinApp(logger, db)
return bapp.ExportAppStateAndValidators()
}
+81
View File
@@ -0,0 +1,81 @@
package types
import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
)
var _ auth.Account = (*AppAccount)(nil)
// AppAccount is a custom extension for this application. It is an example of
// extending auth.BaseAccount with custom fields. It is compatible with the
// stock auth.AccountKeeper, since auth.AccountKeeper uses the flexible go-amino
// library.
type AppAccount struct {
auth.BaseAccount
Name string `json:"name"`
}
// nolint
func (acc AppAccount) GetName() string { return acc.Name }
func (acc *AppAccount) SetName(name string) { acc.Name = name }
// NewAppAccount returns a reference to a new AppAccount given a name and an
// auth.BaseAccount.
func NewAppAccount(name string, baseAcct auth.BaseAccount) *AppAccount {
return &AppAccount{BaseAccount: baseAcct, Name: name}
}
// GetAccountDecoder returns the AccountDecoder function for the custom
// AppAccount.
func GetAccountDecoder(cdc *codec.Codec) auth.AccountDecoder {
return func(accBytes []byte) (auth.Account, error) {
if len(accBytes) == 0 {
return nil, sdk.ErrTxDecode("accBytes are empty")
}
acct := new(AppAccount)
err := cdc.UnmarshalBinaryBare(accBytes, &acct)
if err != nil {
panic(err)
}
return acct, err
}
}
// GenesisState reflects the genesis state of the application.
type GenesisState struct {
Accounts []*GenesisAccount `json:"accounts"`
}
// GenesisAccount reflects a genesis account the application expects in it's
// genesis state.
type GenesisAccount struct {
Name string `json:"name"`
Address sdk.AccAddress `json:"address"`
Coins sdk.Coins `json:"coins"`
}
// NewGenesisAccount returns a reference to a new GenesisAccount given an
// AppAccount.
func NewGenesisAccount(aa *AppAccount) *GenesisAccount {
return &GenesisAccount{
Name: aa.Name,
Address: aa.Address,
Coins: aa.Coins.Sort(),
}
}
// ToAppAccount converts a GenesisAccount to an AppAccount.
func (ga *GenesisAccount) ToAppAccount() (acc *AppAccount, err error) {
return &AppAccount{
Name: ga.Name,
BaseAccount: auth.BaseAccount{
Address: ga.Address,
Coins: ga.Coins.Sort(),
},
}, nil
}