From bf5c8487ce9fe5ae7ce685ab9175edc651496dff Mon Sep 17 00:00:00 2001 From: rhuairahrighairigh Date: Mon, 18 Jun 2018 15:49:09 +0100 Subject: [PATCH] simplify WIP --- cmd/kvcli/main.go | 20 +-- cmd/kvd/main.go | 2 +- internal/app/app.go | 96 ++++++------ internal/app/genesis.go | 307 ++++++++++++++++++++++++++++++++++++++ internal/types/account.go | 40 ++--- 5 files changed, 391 insertions(+), 74 deletions(-) create mode 100644 internal/app/genesis.go diff --git a/cmd/kvcli/main.go b/cmd/kvcli/main.go index 371b1c32..1754403f 100644 --- a/cmd/kvcli/main.go +++ b/cmd/kvcli/main.go @@ -16,11 +16,11 @@ import ( "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" - stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" + //ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + //stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" "github.com/kava-labs/kava/internal/app" - "github.com/kava-labs/kava/internal/types" + //"github.com/kava-labs/kava/internal/types" ) // rootCmd is the entry point for this binary @@ -51,18 +51,18 @@ func main() { // add query/post commands (custom to binary) rootCmd.AddCommand( client.GetCommands( - authcmd.GetAccountCmd("acc", cdc, types.GetAccountDecoder(cdc)), + authcmd.GetAccountCmd("acc", cdc, authcmd.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(cdc), + //ibccmd.IBCTransferCmd(cdc), + //ibccmd.IBCRelayCmd(cdc), + //stakecmd.GetCmdCreateValidator(cdc), + //stakecmd.GetCmdEditValidator(cdc), + //stakecmd.GetCmdDelegate(cdc), + //stakecmd.GetCmdUnbond(cdc), )...) // add proxy, version and key info diff --git a/cmd/kvd/main.go b/cmd/kvd/main.go index 49cdb048..3231ce4d 100644 --- a/cmd/kvd/main.go +++ b/cmd/kvd/main.go @@ -26,7 +26,7 @@ func main() { PersistentPreRunE: server.PersistentPreRunEFn(ctx), } - server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, + server.AddCommands(ctx, cdc, rootCmd, app.CreateAppInit(), server.ConstructAppCreator(newApp, "kava"), server.ConstructAppExporter(exportAppStateAndTMValidators, "kava")) diff --git a/internal/app/app.go b/internal/app/app.go index 61b14ba9..e62665db 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -14,10 +14,9 @@ import ( "github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/ibc" - "github.com/cosmos/cosmos-sdk/x/slashing" - "github.com/cosmos/cosmos-sdk/x/stake" - + //"github.com/cosmos/cosmos-sdk/x/ibc" + //"github.com/cosmos/cosmos-sdk/x/slashing" + //"github.com/cosmos/cosmos-sdk/x/stake" "github.com/kava-labs/kava/internal/types" ) @@ -31,19 +30,19 @@ type KavaApp struct { cdc *wire.Codec // keys to access the substores - keyMain *sdk.KVStoreKey - keyAccount *sdk.KVStoreKey - keyIBC *sdk.KVStoreKey - keyStake *sdk.KVStoreKey - keySlashing *sdk.KVStoreKey + keyMain *sdk.KVStoreKey + keyAccount *sdk.KVStoreKey + //keyIBC *sdk.KVStoreKey + //keyStake *sdk.KVStoreKey + //keySlashing *sdk.KVStoreKey // Manage getting and setting accounts accountMapper auth.AccountMapper feeCollectionKeeper auth.FeeCollectionKeeper coinKeeper bank.Keeper - ibcMapper ibc.Mapper - stakeKeeper stake.Keeper - slashingKeeper slashing.Keeper + //ibcMapper ibc.Mapper + //stakeKeeper stake.Keeper + //slashingKeeper slashing.Keeper } func NewKavaApp(logger log.Logger, db dbm.DB) *KavaApp { @@ -53,41 +52,41 @@ func NewKavaApp(logger log.Logger, db dbm.DB) *KavaApp { // Create your application object. var app = &KavaApp{ - BaseApp: bam.NewBaseApp(appName, cdc, logger, db), - cdc: cdc, - keyMain: sdk.NewKVStoreKey("main"), - keyAccount: sdk.NewKVStoreKey("acc"), - keyIBC: sdk.NewKVStoreKey("ibc"), - keyStake: sdk.NewKVStoreKey("stake"), - keySlashing: sdk.NewKVStoreKey("slashing"), + BaseApp: bam.NewBaseApp(appName, cdc, logger, db), + cdc: cdc, + keyMain: sdk.NewKVStoreKey("main"), + keyAccount: sdk.NewKVStoreKey("acc"), + //keyIBC: sdk.NewKVStoreKey("ibc"), + //keyStake: sdk.NewKVStoreKey("stake"), + //keySlashing: sdk.NewKVStoreKey("slashing"), } // Define the accountMapper. app.accountMapper = auth.NewAccountMapper( cdc, - app.keyAccount, // target store - &types.AppAccount{}, // prototype + app.keyAccount, // target store + &auth.BaseAccount{}, ) // add accountMapper/handlers app.coinKeeper = bank.NewKeeper(app.accountMapper) - app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace)) - app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) - app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.RegisterCodespace(slashing.DefaultCodespace)) + //app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace)) + //app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) + //app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.RegisterCodespace(slashing.DefaultCodespace)) // register message routes app.Router(). AddRoute("auth", auth.NewHandler(app.accountMapper)). - AddRoute("bank", bank.NewHandler(app.coinKeeper)). - AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). - AddRoute("stake", stake.NewHandler(app.stakeKeeper)) + AddRoute("bank", bank.NewHandler(app.coinKeeper)) + //AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)). + //AddRoute("stake", stake.NewHandler(app.stakeKeeper)) // Initialize BaseApp. app.SetInitChainer(app.initChainer) app.SetBeginBlocker(app.BeginBlocker) app.SetEndBlocker(app.EndBlocker) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) - app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing) + app.MountStoresIAVL(app.keyMain, app.keyAccount) //, app.keyIBC, app.keyStake, app.keySlashing) err := app.LoadLatestVersion(app.keyMain) if err != nil { cmn.Exit(err.Error()) @@ -101,35 +100,38 @@ func MakeCodec() *wire.Codec { wire.RegisterCrypto(cdc) // Register crypto. sdk.RegisterWire(cdc) // Register Msgs bank.RegisterWire(cdc) - stake.RegisterWire(cdc) - slashing.RegisterWire(cdc) - ibc.RegisterWire(cdc) + //stake.RegisterWire(cdc) + //slashing.RegisterWire(cdc) + //ibc.RegisterWire(cdc) + auth.RegisterWire(cdc) // register custom AppAccount - cdc.RegisterInterface((*auth.Account)(nil), nil) - cdc.RegisterConcrete(&types.AppAccount{}, "basecoin/Account", nil) + //cdc.RegisterInterface((*auth.Account)(nil), nil) + //cdc.RegisterConcrete(&types.BaseAccount{}, "kava/Account", nil) return cdc } // application updates every end block func (app *KavaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper) + //tags := slashing.BeginBlocker(ctx, req, app.slashingKeeper) - return abci.ResponseBeginBlock{ - Tags: tags.ToKVPairs(), - } + //return abci.ResponseBeginBlock{ + // Tags: tags.ToKVPairs(), + //} + return abci.ResponseBeginBlock{} } // application updates every end block func (app *KavaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { - validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper) + //validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper) - return abci.ResponseEndBlock{ - ValidatorUpdates: validatorUpdates, - } + //return abci.ResponseEndBlock{ + // ValidatorUpdates: validatorUpdates, + //} + return abci.ResponseEndBlock{} } -// Custom logic for basecoin initialization +// Custom logic for initialization func (app *KavaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { stateJSON := req.AppStateBytes @@ -151,7 +153,7 @@ func (app *KavaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci } // load the initial stake information - stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) + //stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) return abci.ResponseInitChain{} } @@ -161,9 +163,9 @@ func (app *KavaApp) ExportAppStateAndValidators() (appState json.RawMessage, val ctx := app.NewContext(true, abci.Header{}) // iterate to get the accounts - accounts := []*types.GenesisAccount{} + accounts := []types.GenesisAccount{} appendAccount := func(acc auth.Account) (stop bool) { - account := &types.GenesisAccount{ + account := types.GenesisAccount{ Address: acc.GetAddress(), Coins: acc.GetCoins(), } @@ -179,6 +181,8 @@ func (app *KavaApp) ExportAppStateAndValidators() (appState json.RawMessage, val if err != nil { return nil, nil, err } - validators = stake.WriteValidators(ctx, app.stakeKeeper) + + validators = make([]tmtypes.GenesisValidator, 0) // TODO export the actual validators + return appState, validators, err } diff --git a/internal/app/genesis.go b/internal/app/genesis.go new file mode 100644 index 00000000..2d58b23b --- /dev/null +++ b/internal/app/genesis.go @@ -0,0 +1,307 @@ +package app + +import ( + "encoding/json" + "errors" + + //"github.com/spf13/pflag" + //"github.com/spf13/viper" + crypto "github.com/tendermint/go-crypto" + tmtypes "github.com/tendermint/tendermint/types" + + "github.com/cosmos/cosmos-sdk/server" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" + //"github.com/cosmos/cosmos-sdk/x/stake" + + "github.com/kava-labs/kava/internal/types" +) + +// I want to be able to create a genesis.json with the initial state of the kava network. +// This is done by creating a custom AppInit object to be handed to the server when it creates commands. +// When `kvd init` is run, a genesis tx is created. Then, from that, an initial app state. + +func CreateAppInit() server.AppInit { + return server.AppInit{ + AppGenTx: KavaAppGenTx, + AppGenState: KavaAppGenState, + } +} + +func KavaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { + + // Generate address and secret key for the validator + var addr sdk.Address + var secret string + addr, secret, err = server.GenerateCoinKey() + if err != nil { + return + } + + // Generate appGenTx ------------- + var bz []byte + genTx := types.GenTx{ + Address: addr, + PubKey: pk, + } + bz, err = wire.MarshalJSONIndent(cdc, genTx) + if err != nil { + return + } + appGenTx = json.RawMessage(bz) + + // cliPrint ------------- + mm := map[string]string{"secret": secret} + bz, err = cdc.MarshalJSON(mm) + if err != nil { + return + } + cliPrint = json.RawMessage(bz) + + // validator ----------- + validator = tmtypes.GenesisValidator{ + PubKey: pk, + Power: 10, + } + + return +} + +func KavaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { + + if len(appGenTxs) == 0 { + err = errors.New("must provide at least 1 genesis transaction") + return + } + + genaccs := make([]types.GenesisAccount, len(appGenTxs)) + for i, appGenTx := range appGenTxs { + + var genTx types.GenTx + err = cdc.UnmarshalJSON(appGenTx, &genTx) + if err != nil { + return + } + + // create the genesis account + accAuth := auth.NewBaseAccountWithAddress(genTx.Address) + accAuth.Coins = sdk.Coins{ + {"KVA", 10000000000}, + } + accAuth.PubKey = genTx.PubKey + acc := types.NewGenesisAccount(&accAuth) + genaccs[i] = acc + } + + // create the final app state + genesisState := types.GenesisState{ + Accounts: genaccs, + } + appState, err = wire.MarshalJSONIndent(cdc, genesisState) + + return +} + +/* + +// --------------------- default init -------------------------- + +// simple default application init +var DefaultAppInit = AppInit{ + AppGenTx: SimpleAppGenTx, + AppGenState: SimpleAppGenState, +} + +// simple genesis tx +type SimpleGenTx struct { + Addr sdk.Address `json:"addr"` +} + +// Generate a genesis transaction +func SimpleAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { + + var addr sdk.Address + var secret string + addr, secret, err = GenerateCoinKey() + if err != nil { + return + } + + var bz []byte + simpleGenTx := SimpleGenTx{addr} + bz, err = cdc.MarshalJSON(simpleGenTx) + if err != nil { + return + } + appGenTx = json.RawMessage(bz) + + mm := map[string]string{"secret": secret} + bz, err = cdc.MarshalJSON(mm) + if err != nil { + return + } + cliPrint = json.RawMessage(bz) + + validator = tmtypes.GenesisValidator{ + PubKey: pk, + Power: 10, + } + return +} + +// create the genesis app state +func SimpleAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { + + if len(appGenTxs) != 1 { + err = errors.New("must provide a single genesis transaction") + return + } + + var genTx SimpleGenTx + err = cdc.UnmarshalJSON(appGenTxs[0], &genTx) + if err != nil { + return + } + + appState = json.RawMessage(fmt.Sprintf(`{ + "accounts": [{ + "address": "%s", + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ] + }] +}`, genTx.Addr.String())) + return +} + + +// -------------------- gaia init ---------------------- + +// simple genesis tx +type GaiaGenTx struct { + Name string `json:"name"` + Address sdk.Address `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` +} + +// Generate a gaia genesis transaction with flags +func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { + clientRoot := viper.GetString(flagClientHome) + overwrite := viper.GetBool(flagOWK) + name := viper.GetString(flagName) + if name == "" { + return nil, nil, tmtypes.GenesisValidator{}, errors.New("Must specify --name (validator moniker)") + } + + var addr sdk.Address + var secret string + addr, secret, err = server.GenerateSaveCoinKey(clientRoot, name, "1234567890", overwrite) + if err != nil { + return + } + mm := map[string]string{"secret": secret} + var bz []byte + bz, err = cdc.MarshalJSON(mm) + if err != nil { + return + } + cliPrint = json.RawMessage(bz) + appGenTx,_,validator,err = GaiaAppGenTxNF(cdc, pk, addr, name, overwrite) + return +} + +// Generate a gaia genesis transaction without flags +func GaiaAppGenTxNF(cdc *wire.Codec, pk crypto.PubKey, addr sdk.Address, name string, overwrite bool) ( + appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { + + var bz []byte + gaiaGenTx := GaiaGenTx{ + Name: name, + Address: addr, + PubKey: pk, + } + bz, err = wire.MarshalJSONIndent(cdc, gaiaGenTx) + if err != nil { + return + } + appGenTx = json.RawMessage(bz) + + validator = tmtypes.GenesisValidator{ + PubKey: pk, + Power: freeFermionVal, + } + return +} + +// Create the core parameters for genesis initialization for gaia +// note that the pubkey input is this machines pubkey +func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState GenesisState, err error) { + + if len(appGenTxs) == 0 { + err = errors.New("must provide at least genesis transaction") + return + } + + // start with the default staking genesis state + stakeData := stake.DefaultGenesisState() + + // get genesis flag account information + genaccs := make([]GenesisAccount, len(appGenTxs)) + for i, appGenTx := range appGenTxs { + + var genTx GaiaGenTx + err = cdc.UnmarshalJSON(appGenTx, &genTx) + if err != nil { + return + } + + // create the genesis account, give'm few steaks and a buncha token with there name + accAuth := auth.NewBaseAccountWithAddress(genTx.Address) + accAuth.Coins = sdk.Coins{ + {genTx.Name + "Token", 1000}, + {"steak", freeFermionsAcc}, + } + acc := NewGenesisAccount(&accAuth) + genaccs[i] = acc + stakeData.Pool.LooseUnbondedTokens += freeFermionsAcc // increase the supply + + // add the validator + if len(genTx.Name) > 0 { + desc := stake.NewDescription(genTx.Name, "", "", "") + validator := stake.NewValidator(genTx.Address, genTx.PubKey, desc) + validator.PoolShares = stake.NewBondedShares(sdk.NewRat(freeFermionVal)) + stakeData.Validators = append(stakeData.Validators, validator) + + // pool logic + stakeData.Pool.BondedTokens += freeFermionVal + stakeData.Pool.BondedShares = sdk.NewRat(stakeData.Pool.BondedTokens) + } + } + + // create the final app state + genesisState = GenesisState{ + Accounts: genaccs, + StakeData: stakeData, + } + return +} + +// GaiaAppGenState but with JSON +func GaiaAppGenStateJSON(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) { + + // create the final app state + genesisState, err := GaiaAppGenState(cdc, appGenTxs) + if err != nil { + return nil, err + } + appState, err = wire.MarshalJSONIndent(cdc, genesisState) + return +} +*/ diff --git a/internal/types/account.go b/internal/types/account.go index 43a8e2e3..44f3b5ed 100644 --- a/internal/types/account.go +++ b/internal/types/account.go @@ -2,11 +2,13 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/wire" + crypto "github.com/tendermint/go-crypto" + //"github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/stake" + //"github.com/cosmos/cosmos-sdk/x/stake" ) +/* var _ auth.Account = (*AppAccount)(nil) // Custom extensions for this application. This is just an example of @@ -37,38 +39,42 @@ func GetAccountDecoder(cdc *wire.Codec) auth.AccountDecoder { return acct, err } } - +*/ //___________________________________________________________________________________ +type GenTx struct { + Address sdk.Address `json:"address"` + PubKey crypto.PubKey `json:"pub_key"` +} + // State to Unmarshal type GenesisState struct { - Accounts []*GenesisAccount `json:"accounts"` - StakeData stake.GenesisState `json:"stake"` + Accounts []GenesisAccount `json:"accounts"` + //StakeData stake.GenesisState `json:"stake"` } // GenesisAccount doesn't need pubkey or sequence type GenesisAccount struct { - Name string `json:"name"` - Address sdk.Address `json:"address"` - Coins sdk.Coins `json:"coins"` + //Name string `json:"name"` + Address sdk.Address `json:"address"` + Coins sdk.Coins `json:"coins"` + PubKey crypto.PubKey `json:"pub_key"` //add in pub key so I can send coins? } -func NewGenesisAccount(aa *AppAccount) *GenesisAccount { - return &GenesisAccount{ - Name: aa.Name, +func NewGenesisAccount(aa *auth.BaseAccount) GenesisAccount { + return GenesisAccount{ + //Name: aa.Name, Address: aa.Address, Coins: aa.Coins.Sort(), + PubKey: aa.PubKey, // add in pub key } } // convert GenesisAccount to AppAccount -func (ga *GenesisAccount) ToAppAccount() (acc *AppAccount, err error) { - baseAcc := auth.BaseAccount{ +func (ga *GenesisAccount) ToAppAccount() (acc *auth.BaseAccount, err error) { + return &auth.BaseAccount{ Address: ga.Address, Coins: ga.Coins.Sort(), - } - return &AppAccount{ - BaseAccount: baseAcc, - Name: ga.Name, + PubKey: ga.PubKey, // add in pub key }, nil }