Skip to content

Commit

Permalink
New genesis workflow
Browse files Browse the repository at this point in the history
* `gaiad init` is now used to generate an empty `genesis.json`.
* Genesis accounts need to be populated manually before running
  `gaiad collect-gentxs`.
* This should support starfish too, see #2615 for more info.

Closes: #2596 #2615
  • Loading branch information
Alessio Treglia committed Nov 2, 2018
1 parent 0d5ebd2 commit 34a64c3
Show file tree
Hide file tree
Showing 15 changed files with 339 additions and 262 deletions.
11 changes: 10 additions & 1 deletion client/lcd/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func InitializeTestLCD(
genTxs := []json.RawMessage{}

// append any additional (non-proposing) validators
var accs []gapp.GenesisAccount
for i := 0; i < nValidators; i++ {
operPrivKey := secp256k1.GenPrivKey()
operAddr := operPrivKey.PubKey().Address()
Expand Down Expand Up @@ -242,9 +243,17 @@ func InitializeTestLCD(
genTxs = append(genTxs, txBytes)
valConsPubKeys = append(valConsPubKeys, pubKey)
valOperAddrs = append(valOperAddrs, sdk.ValAddress(operAddr))

accAuth := auth.NewBaseAccountWithAddress(sdk.AccAddress(operAddr))
accAuth.Coins = sdk.Coins{sdk.NewInt64Coin("steak", 150)}
accs = append(accs, gapp.NewGenesisAccount(&accAuth))
}

genesisState, err := gapp.GaiaAppGenState(cdc, genTxs)
appGenState := gapp.DefaultGenesisState()
appGenState.Accounts = accs
genDoc.AppState, err = cdc.MarshalJSON(appGenState)
require.NoError(t, err)
genesisState, err := gapp.GaiaAppGenState(cdc, *genDoc, genTxs)
require.NoError(t, err)

// add some tokens to init accounts
Expand Down
77 changes: 36 additions & 41 deletions cmd/gaia/app/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,21 @@ func GaiaAppInit() server.AppInit {

// Create the core parameters for genesis initialization for gaia
// note that the pubkey input is this machines pubkey
func GaiaAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (genesisState GenesisState, err error) {
if len(appGenTxs) == 0 {
err = errors.New("must provide at least genesis transaction")
func GaiaAppGenState(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
genesisState GenesisState, err error) {

if err = cdc.UnmarshalJSON(genDoc.AppState, &genesisState); err != nil {
return
}

// start with the default staking genesis state
stakeData := stake.DefaultGenesisState()
slashingData := slashing.DefaultGenesisState()

// get genesis flag account information
genaccs := make([]GenesisAccount, len(appGenTxs))
// if there are no gen txs to be processed, return the default empty state
if len(appGenTxs) == 0 {
err = errors.New("there must be at least one genesis tx")
return
}

for i, genTx := range appGenTxs {
stakeData := genesisState.StakeData
for _, genTx := range appGenTxs {
var tx auth.StdTx
err = cdc.UnmarshalJSON(genTx, &tx)
if err != nil {
Expand All @@ -114,34 +115,34 @@ func GaiaAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (genesisStat
err = errors.New("must provide genesis StdTx with exactly 1 CreateValidator message")
return
}
msg := msgs[0].(stake.MsgCreateValidator)
_ = msgs[0].(stake.MsgCreateValidator)
}

for _, acc := range genesisState.Accounts {
// create the genesis account, give'm few steaks and a buncha token with there name
genaccs[i] = genesisAccountFromMsgCreateValidator(msg, freeFermionsAcc)
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
for _, coin := range acc.Coins {
if coin.Denom == "steak" {
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.
Add(sdk.NewDecFromInt(coin.Amount)) // increase the supply
}
}
}
genesisState.StakeData = stakeData
genesisState.GenTxs = appGenTxs
return genesisState, nil
}

// create the final app state
genesisState = GenesisState{
Accounts: genaccs,
StakeData: stakeData,
// DefaultGenesisState generates the default state for gaia.
func DefaultGenesisState() GenesisState {
return GenesisState{
Accounts: nil,
StakeData: stake.DefaultGenesisState(),
MintData: mint.DefaultGenesisState(),
DistrData: distr.DefaultGenesisState(),
GovData: gov.DefaultGenesisState(),
SlashingData: slashingData,
GenTxs: appGenTxs,
SlashingData: slashing.DefaultGenesisState(),
GenTxs: nil,
}

return
}

func genesisAccountFromMsgCreateValidator(msg stake.MsgCreateValidator, amount sdk.Int) GenesisAccount {
accAuth := auth.NewBaseAccountWithAddress(sdk.AccAddress(msg.ValidatorAddr))
accAuth.Coins = []sdk.Coin{
{msg.Description.Moniker + "Token", sdk.NewInt(1000)},
{"steak", amount},
}
return NewGenesisAccount(&accAuth)
}

// GaiaValidateGenesisState ensures that the genesis state obeys the expected invariants
Expand Down Expand Up @@ -175,20 +176,20 @@ func validateGenesisStateAccounts(accs []GenesisAccount) (err error) {
}

// GaiaAppGenState but with JSON
func GaiaAppGenStateJSON(cdc *codec.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
func GaiaAppGenStateJSON(cdc *codec.Codec, genDoc tmtypes.GenesisDoc, appGenTxs []json.RawMessage) (
appState json.RawMessage, err error) {
// create the final app state
genesisState, err := GaiaAppGenState(cdc, appGenTxs)
genesisState, err := GaiaAppGenState(cdc, genDoc, appGenTxs)
if err != nil {
return nil, err
}
appState, err = codec.MarshalJSONIndent(cdc, genesisState)
return
return codec.MarshalJSONIndent(cdc, genesisState)
}

// CollectStdTxs processes and validates application's genesis StdTxs and returns the list of validators,
// appGenTxs, and persistent peers required to generate genesis.json.
func CollectStdTxs(moniker string, genTxsDir string, cdc *codec.Codec) (
validators []tmtypes.GenesisValidator, appGenTxs []auth.StdTx, persistentPeers string, err error) {
appGenTxs []auth.StdTx, persistentPeers string, err error) {
var fos []os.FileInfo
fos, err = ioutil.ReadDir(genTxsDir)
if err != nil {
Expand Down Expand Up @@ -230,12 +231,6 @@ func CollectStdTxs(moniker string, genTxsDir string, cdc *codec.Codec) (
// TODO: this could be decoupled from stake.MsgCreateValidator
// TODO: and we likely want to do it for real world Gaia
msg := msgs[0].(stake.MsgCreateValidator)
validators = append(validators, tmtypes.GenesisValidator{
PubKey: msg.PubKey,
Power: freeFermionVal,
Name: msg.Description.Moniker,
})

// exclude itself from persistent peers
if msg.Description.Moniker != moniker {
addresses = append(addresses, nodeAddr)
Expand Down
18 changes: 8 additions & 10 deletions cmd/gaia/app/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/stake"
stakeTypes "github.com/cosmos/cosmos-sdk/x/stake/types"
"github.com/stretchr/testify/require"
Expand All @@ -27,25 +26,24 @@ var (

func makeGenesisState(t *testing.T, genTxs []auth.StdTx) GenesisState {
// start with the default staking genesis state
stakeData := stake.DefaultGenesisState()
appState := DefaultGenesisState()
stakeData := appState.StakeData
genAccs := make([]GenesisAccount, len(genTxs))

for i, genTx := range genTxs {
msgs := genTx.GetMsgs()
require.Equal(t, 1, len(msgs))
msg := msgs[0].(stake.MsgCreateValidator)

// get genesis flag account information
genAccs[i] = genesisAccountFromMsgCreateValidator(msg, freeFermionsAcc)
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDecFromInt(freeFermionsAcc)) // increase the supply
acc := auth.NewBaseAccountWithAddress(sdk.AccAddress(msg.ValidatorAddr))
acc.Coins = sdk.Coins{sdk.NewInt64Coin("steak", 150)}
genAccs[i] = NewGenesisAccount(&acc)
stakeData.Pool.LooseTokens = stakeData.Pool.LooseTokens.Add(sdk.NewDec(150)) // increase the supply
}

// create the final app state
return GenesisState{
Accounts: genAccs,
StakeData: stakeData,
GovData: gov.DefaultGenesisState(),
}
appState.Accounts = genAccs
return appState
}

func TestToAccount(t *testing.T) {
Expand Down
41 changes: 35 additions & 6 deletions cmd/gaia/cli_test/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ package clitest
import (
"encoding/json"
"fmt"
"github.com/tendermint/tendermint/types"
"io/ioutil"
"os"
"path"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -207,7 +209,7 @@ func TestGaiaCLIGasAuto(t *testing.T) {

func TestGaiaCLICreateValidator(t *testing.T) {
chainID, servAddr, port := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)
flags := fmt.Sprintf("--home=%s --chain-id=%v --node=%s", gaiacliHome, chainID, servAddr)

// start gaiad server
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))
Expand Down Expand Up @@ -544,7 +546,7 @@ func TestGaiaCLIConfig(t *testing.T) {
servAddr, port, err := server.FreeTCPAddr()
require.NoError(t, err)
node := fmt.Sprintf("%s:%s", servAddr, port)
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --moniker=foo --home=%s", gaiadHome))
executeWrite(t, fmt.Sprintf("gaiacli --home=%s config", gaiadHome), gaiacliHome, node, "y")
config, err := ioutil.ReadFile(path.Join(gaiacliHome, "config", "config.toml"))
require.NoError(t, err)
Expand Down Expand Up @@ -594,12 +596,27 @@ func initializeFixtures(t *testing.T) (chainID, servAddr, port string) {
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe-reset-all", gaiadHome), "")
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass)

chainID = executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome))
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s foo", gaiacliHome), app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass)

fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf(
"gaiacli keys show foo --output=json --home=%s", gaiacliHome))
chainID = executeInit(t, fmt.Sprintf("gaiad init -o --moniker=foo --home=%s", gaiadHome))
genFile := filepath.Join(gaiadHome, "config", "genesis.json")
genDoc := readGenesisFile(t, genFile)
var appState app.GenesisState
err := codec.Cdc.UnmarshalJSON(genDoc.AppState, &appState)
require.NoError(t, err)
appState.Accounts = []app.GenesisAccount{app.NewDefaultGenesisAccount(fooAddr)}
appStateJSON, err := codec.Cdc.MarshalJSON(appState)
require.NoError(t, err)
genDoc.AppState = appStateJSON
genDoc.SaveAs(genFile)
executeWrite(t, fmt.Sprintf(
"gaiad gentx --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome),
app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiad collect-gentxs --home=%s", gaiadHome), app.DefaultKeyPass)
// get a free port, also setup some common flags
servAddr, port, err := server.FreeTCPAddr()
servAddr, port, err = server.FreeTCPAddr()
require.NoError(t, err)
return
}
Expand All @@ -618,6 +635,18 @@ func writeToNewTempFile(t *testing.T, s string) *os.File {
return fp
}

func readGenesisFile(t *testing.T, genFile string) types.GenesisDoc {
var genDoc types.GenesisDoc
fp, err := os.Open(genFile)
require.NoError(t, err)
fileContents, err := ioutil.ReadAll(fp)
require.NoError(t, err)
defer fp.Close()
err = codec.Cdc.UnmarshalJSON(fileContents, &genDoc)
require.NoError(t, err)
return genDoc
}

//___________________________________________________________________________________
// executors

Expand Down
3 changes: 2 additions & 1 deletion cmd/gaia/cmd/gaiad/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ func main() {
}
appInit := app.GaiaAppInit()
rootCmd.AddCommand(gaiaInit.InitCmd(ctx, cdc, appInit))
rootCmd.AddCommand(gaiaInit.TestnetFilesCmd(ctx, cdc, appInit))
rootCmd.AddCommand(gaiaInit.CollectGenTxsCmd(ctx, cdc))
rootCmd.AddCommand(gaiaInit.TestnetFilesCmd(ctx, cdc, server.AppInit{}))
rootCmd.AddCommand(gaiaInit.GenTxCmd(ctx, cdc))

server.AddCommands(ctx, cdc, rootCmd, appInit,
Expand Down
Loading

0 comments on commit 34a64c3

Please sign in to comment.