Skip to content

Commit

Permalink
stake init overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
rigelrozanski committed Apr 26, 2018
1 parent c8f5fcb commit 2019089
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 64 deletions.
140 changes: 113 additions & 27 deletions cmd/gaia/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ package app

import (
"encoding/json"
"errors"
"strings"

"github.com/spf13/pflag"
"github.com/spf13/viper"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
tmtypes "github.com/tendermint/tendermint/types"
Expand Down Expand Up @@ -133,7 +137,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
stateJSON := req.AppStateBytes

genesisState := new(GenesisState)
err := json.Unmarshal(stateJSON, genesisState)
err := app.cdc.UnmarshalJSON(stateJSON, genesisState)
if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
// return sdk.ErrGenesisParse("").TraceCause(err, "")
Expand All @@ -151,7 +155,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
return abci.ResponseInitChain{}
}

//__________________________________________________________
//________________________________________________________________________________________

// State to Unmarshal
type GenesisState struct {
Expand All @@ -172,52 +176,134 @@ func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount {
}
}

// convert GenesisAccount to GaiaAccount
// convert GenesisAccount to auth.BaseAccount
func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) {
return &auth.BaseAccount{
Address: ga.Address,
Coins: ga.Coins.Sort(),
}
}

// XXX func AddPiece
var (
flagAccounts = "accounts"
flagOWK = "overwrite-keys"
)

// get app init parameters for server init command
func GaiaAppInit() server.AppInit {
fs := pflag.NewFlagSet("", pflag.ContinueOnError)
fs.String(flagAccounts, "foobar-10fermion,10baz-true", "genesis accounts in form: name1-coins-isval;name2-coins-isval;...")
fs.BoolP(flagOWK, "k", false, "overwrite the for the accounts created, if false and key exists init will fail")
return server.AppInit{
Flags: fs,
GenAppParams: GaiaGenAppParams,
AppendAppState: GaiaAppendAppState,
}
}

// Create the core parameters for genesis initialization for gaia
// note that the pubkey input is this machines pubkey
func GaiaGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) {

// XXX what's the best way to pass around this information? have special flagset defined here?
// add keys to accounts (flag)
// generate X accounts each with X money
// generate X number of validators each bonded with X amount of token
printMap := make(map[string]string)
var candidates []stake.Candidate
poolAssets := int64(0)
chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6))

var addr sdk.Address
var secret string
addr, secret, err = server.GenerateCoinKey()
if err != nil {
return
// get genesis flag account information
accountsStr := viper.GetString(flagAccounts)
accounts := strings.Split(accountsStr, ";")
genaccs := make([]GenesisAccount, len(accounts))
for i, account := range accounts {
p := strings.Split(account, "-")
if len(p) != 3 {
err = errors.New("input account has bad form, each account must be in form name-coins-isval, for example: foobar-10fermion,10baz-true")
return
}
name := p[0]
var coins sdk.Coins
coins, err = sdk.ParseCoins(p[1])
if err != nil {
return
}
isValidator := false
if p[2] == "true" {
isValidator = true
}

var addr sdk.Address
var secret string
addr, secret, err = server.GenerateCoinKey()
if err != nil {
return
}

printMap["secret-"+name] = secret

// create the genesis account
accAuth := auth.NewBaseAccountWithAddress(addr)
accAuth.Coins = coins
acc := NewGenesisAccount(&accAuth)
genaccs[i] = acc

// add the validator
if isValidator {

// only use this machines pubkey the first time, all others are dummies
var pk crypto.PubKey
if i == 0 {
pk = pubKey
} else {
pk = crypto.GenPrivKeyEd25519().PubKey()
}

freePower := int64(100)
validator := tmtypes.GenesisValidator{
PubKey: pk,
Power: freePower,
}
desc := stake.NewDescription(name, "", "", "")
candidate := stake.NewCandidate(addr, pk, desc)
candidate.Assets = sdk.NewRat(freePower)
poolAssets += freePower
validators = append(validators, validator)
candidates = append(candidates, candidate)
}
}

mm := map[string]string{"secret": secret}
bz, err := cdc.MarshalJSON(mm)
// create the print message
bz, err := cdc.MarshalJSON(printMap)
cliPrint = json.RawMessage(bz)

chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6))

validators = []tmtypes.GenesisValidator{{
PubKey: pubKey,
Power: 10,
}}
stakeData := stake.GetDefaultGenesisState()
stakeData.Candidates = candidates

accAuth := auth.NewBaseAccountWithAddress(addr)
accAuth.Coins = sdk.Coins{{"fermion", 100000}}
acc := NewGenesisAccount(&accAuth)
genaccs := []GenesisAccount{acc}
// assume everything is bonded from the get-go
stakeData.Pool.TotalSupply = poolAssets
stakeData.Pool.BondedShares = sdk.NewRat(poolAssets)

genesisState := GenesisState{
Accounts: genaccs,
StakeData: stake.GetDefaultGenesisState(),
StakeData: stakeData,
}

appState, err = json.MarshalIndent(genesisState, "", "\t")
appState, err = wire.MarshalJSONIndent(cdc, genesisState)
return
}

// append gaia app_state together, stitch the accounts together take the
// staking parameters from the first appState
func GaiaAppendAppState(cdc *wire.Codec, appState1, appState2 json.RawMessage) (appState json.RawMessage, err error) {
var genState1, genState2 GenesisState
err = cdc.UnmarshalJSON(appState1, &genState1)
if err != nil {
panic(err)
}
err = cdc.UnmarshalJSON(appState2, &genState2)
if err != nil {
panic(err)
}
genState1.Accounts = append(genState1.Accounts, genState2.Accounts...)

return cdc.MarshalJSON(genState1)
}
21 changes: 14 additions & 7 deletions cmd/gaia/cli_test/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ func TestGaiaCLISend(t *testing.T) {
pass := "1234567890"
executeWrite(t, "gaiacli keys delete foo", pass)
executeWrite(t, "gaiacli keys delete bar", pass)
masterKey, chainID := executeInit(t, "gaiad init -o")
keys, chainID := executeInit(t, "gaiad init -o --accounts=foo-100000fermion-true", "foo")
require.Equal(t, 1, len(keys))

// get a free port, also setup some common flags
servAddr := server.FreeTCPAddr(t)
Expand All @@ -33,7 +34,7 @@ func TestGaiaCLISend(t *testing.T) {
cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
defer cmd.Process.Kill()

executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey)
executeWrite(t, "gaiacli keys add foo --recover", pass, keys[0])
executeWrite(t, "gaiacli keys add bar", pass)

fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
Expand All @@ -56,7 +57,8 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) {
tests.ExecuteT(t, "gaiad unsafe_reset_all", 1)
pass := "1234567890"
executeWrite(t, "gaiacli keys delete foo", pass)
masterKey, chainID := executeInit(t, "gaiad init -o")
keys, chainID := executeInit(t, "gaiad init -o --accounts=bar-100000fermion-true;foo-100000fermion-true", "bar", "foo")
require.Equal(t, 2, len(keys))

// get a free port, also setup some common flags
servAddr := server.FreeTCPAddr(t)
Expand All @@ -66,7 +68,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) {
cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
defer cmd.Process.Kill()

executeWrite(t, "gaiacli keys add foo --recover", pass, masterKey)
executeWrite(t, "gaiacli keys add foo --recover", pass, keys[1])
fooAddr, fooPubKey := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion"))
Expand Down Expand Up @@ -128,7 +130,7 @@ func executeWritePrint(t *testing.T, cmdStr string, writes ...string) {
fmt.Printf("debug read: %v\n", string(bz))
}

func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) {
func executeInit(t *testing.T, cmdStr string, names ...string) (keys []string, chainID string) {
out := tests.ExecuteT(t, cmdStr, 1)

var initRes map[string]json.RawMessage
Expand All @@ -142,8 +144,13 @@ func executeInit(t *testing.T, cmdStr string) (masterKey, chainID string) {
err = json.Unmarshal(initRes["app_message"], &appMessageRes)
require.NoError(t, err)

err = json.Unmarshal(appMessageRes["secret"], &masterKey)
require.NoError(t, err)
for _, name := range names {
var key string
err = json.Unmarshal(appMessageRes["secret-"+name], &key)
require.NoError(t, err)
keys = append(keys, key)
}

return
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/gaia/cmd/gaiad/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func main() {
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
}

server.AddCommands(ctx, cdc, rootCmd, app.GaiaGenAppParams, generateApp)
server.AddCommands(ctx, cdc, rootCmd, app.GaiaAppInit(), generateApp)

// prepare and add flags
rootDir := os.ExpandEnv("$HOME/.gaiad")
Expand Down
4 changes: 1 addition & 3 deletions examples/basecoin/app/app.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package app

import (
"encoding/json"

abci "github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
Expand Down Expand Up @@ -133,7 +131,7 @@ func (app *BasecoinApp) initChainer(ctx sdk.Context, req abci.RequestInitChain)
stateJSON := req.AppStateBytes

genesisState := new(types.GenesisState)
err := json.Unmarshal(stateJSON, genesisState)
err := app.cdc.UnmarshalJSON(stateJSON, genesisState)
if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
// return sdk.ErrGenesisParse("").TraceCause(err, "")
Expand Down
2 changes: 1 addition & 1 deletion examples/basecoin/cmd/basecoind/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func main() {
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
}

server.AddCommands(ctx, cdc, rootCmd, server.SimpleGenAppParams, generateApp)
server.AddCommands(ctx, cdc, rootCmd, server.DefaultAppInit, generateApp)

// prepare and add flags
rootDir := os.ExpandEnv("$HOME/.basecoind")
Expand Down
4 changes: 1 addition & 3 deletions examples/democoin/app/app.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package app

import (
"encoding/json"

abci "github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
Expand Down Expand Up @@ -147,7 +145,7 @@ func (app *DemocoinApp) initChainerFn(coolKeeper cool.Keeper, powKeeper pow.Keep
stateJSON := req.AppStateBytes

genesisState := new(types.GenesisState)
err := json.Unmarshal(stateJSON, genesisState)
err := app.cdc.UnmarshalJSON(stateJSON, genesisState)
if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
// return sdk.ErrGenesisParse("").TraceCause(err, "")
Expand Down
7 changes: 6 additions & 1 deletion examples/democoin/cmd/democoind/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ import (
"github.com/cosmos/cosmos-sdk/wire"
)

// init parameters
var CoolAppInit = server.AppInit{
GenAppParams: CoolGenAppParams,
}

// coolGenAppParams sets up the app_state and appends the cool app state
func CoolGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) {
chainID, validators, appState, cliPrint, err = server.SimpleGenAppParams(cdc, pubKey)
Expand Down Expand Up @@ -52,7 +57,7 @@ func main() {
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
}

server.AddCommands(ctx, cdc, rootCmd, CoolGenAppParams, generateApp)
server.AddCommands(ctx, cdc, rootCmd, CoolAppInit, generateApp)

// prepare and add flags
rootDir := os.ExpandEnv("$HOME/.democoind")
Expand Down
Loading

0 comments on commit 2019089

Please sign in to comment.