init refactor uses genesis transaction now

This commit is contained in:
rigelrozanski 2018-04-25 16:12:14 -04:00
parent 12f20d160a
commit b9477ecbbe
8 changed files with 237 additions and 203 deletions

View File

@ -3,7 +3,6 @@ package app
import (
"encoding/json"
"errors"
"strings"
"github.com/spf13/pflag"
"github.com/spf13/viper"
@ -185,141 +184,123 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) {
}
var (
flagAccounts = "accounts"
flagChainID = "chain-id"
flagOWK = "overwrite-keys"
flagName = "name"
//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.String(flagChainID, "", "genesis file chain-id, if left blank will be randomly created")
fs.BoolP(flagOWK, "k", false, "overwrite the for the accounts created, if false and key exists init will fail")
fsAppGenState := pflag.NewFlagSet("", pflag.ContinueOnError)
//fsAppGenState.BoolP(flagOWK, "k", false, "overwrite the for the accounts created, if false and key exists init will fail")
fsAppGenTx := pflag.NewFlagSet("", pflag.ContinueOnError)
fsAppGenTx.String(flagName, "", "validator moniker, if left blank, do not add validator")
return server.AppInit{
Flags: fs,
GenAppParams: GaiaGenAppParams,
AppendAppState: GaiaAppendAppState,
FlagsAppGenState: fsAppGenState,
FlagsAppGenTx: fsAppGenTx,
AppGenState: GaiaAppGenState,
AppGenTx: GaiaAppGenTx,
}
}
// simple genesis tx
type GaiaGenTx struct {
Name string `json:"name"`
Address sdk.Address `json:"address"`
PubKey crypto.PubKey `json:"pub_key"`
}
// power given to validators in gaia init functions
var FreePower = int64(100)
// 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) {
func GaiaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
printMap := make(map[string]string)
var candidates []stake.Candidate
poolAssets := int64(0)
chainID = viper.GetString(flagChainID)
if len(chainID) == 0 {
chainID = cmn.Fmt("test-chain-%v", cmn.RandStr(6))
if len(appGenTxs) == 0 {
err = errors.New("must provide at least genesis transaction")
return
}
// start with the default staking genesis state
stakeData := stake.GetDefaultGenesisState()
// 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
}
genaccs := make([]GenesisAccount, len(appGenTxs))
for i, appGenTx := range appGenTxs {
var addr sdk.Address
var secret string
addr, secret, err = server.GenerateCoinKey()
var genTx GaiaGenTx
err = cdc.UnmarshalJSON(appGenTx, &genTx)
if err != nil {
return
}
printMap["secret-"+name] = secret
// create the genesis account
accAuth := auth.NewBaseAccountWithAddress(addr)
accAuth.Coins = coins
// create the genesis account, give'm few fermions and a buncha token with there name
accAuth := auth.NewBaseAccountWithAddress(genTx.Address)
accAuth.Coins = sdk.Coins{
{genTx.Name + "Token", 1000},
{"fermion", 50},
}
acc := NewGenesisAccount(&accAuth)
genaccs[i] = acc
// add the validator
if isValidator {
if len(genTx.Name) > 0 {
desc := stake.NewDescription(genTx.Name, "", "", "")
candidate := stake.NewCandidate(genTx.Address, genTx.PubKey, desc)
candidate.Assets = sdk.NewRat(FreePower)
stakeData.Candidates = append(stakeData.Candidates, candidate)
// 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)
// pool logic
stakeData.Pool.TotalSupply += FreePower
stakeData.Pool.BondedPool += FreePower
stakeData.Pool.BondedShares = sdk.NewRat(stakeData.Pool.BondedPool)
}
}
// create the print message
bz, err := cdc.MarshalJSON(printMap)
cliPrint = json.RawMessage(bz)
stakeData := stake.GetDefaultGenesisState()
stakeData.Candidates = candidates
// assume everything is bonded from the get-go
stakeData.Pool.TotalSupply = poolAssets
stakeData.Pool.BondedPool = poolAssets
stakeData.Pool.BondedShares = sdk.NewRat(poolAssets)
// create the final app state
genesisState := GenesisState{
Accounts: genaccs,
StakeData: stakeData,
}
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...)
genState1.StakeData.Candidates = append(genState1.StakeData.Candidates, genState2.StakeData.Candidates...)
// Generate a gaia genesis transaction
func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey) (
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) {
// pool logic
CombinedSupply := genState1.StakeData.Pool.TotalSupply + genState2.StakeData.Pool.TotalSupply
CombinedBondedPool := genState1.StakeData.Pool.BondedPool + genState2.StakeData.Pool.BondedPool
CombinedBondedShares := genState1.StakeData.Pool.BondedShares.Add(genState2.StakeData.Pool.BondedShares)
genState1.StakeData.Pool.TotalSupply = CombinedSupply
genState1.StakeData.Pool.BondedPool = CombinedBondedPool
genState1.StakeData.Pool.BondedShares = CombinedBondedShares
var addr sdk.Address
var secret string
addr, secret, err = server.GenerateCoinKey()
if err != nil {
return
}
return cdc.MarshalJSON(genState1)
var bz []byte
gaiaGenTx := GaiaGenTx{
Name: viper.GetString(flagName),
Address: addr,
PubKey: pk,
}
bz, err = wire.MarshalJSONIndent(cdc, gaiaGenTx)
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: FreePower,
}
return
}

View File

@ -23,8 +23,7 @@ func TestGaiaCLISend(t *testing.T) {
pass := "1234567890"
executeWrite(t, "gaiacli keys delete foo", pass)
executeWrite(t, "gaiacli keys delete bar", pass)
keys, chainID := executeInit(t, "gaiad init -o --accounts=foo-100000fermion-true", "foo")
require.Equal(t, 1, len(keys))
key, chainID := executeInit(t, "gaiad init -o --name=foo")
// get a free port, also setup some common flags
servAddr := server.FreeTCPAddr(t)
@ -34,14 +33,14 @@ 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, keys[0])
executeWrite(t, "gaiacli keys add foo --recover", pass, key)
executeWrite(t, "gaiacli keys add bar", pass)
fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json")
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion"))
assert.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("fermion"))
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10fermion --to=%v --name=foo", flags, barAddr), pass)
time.Sleep(time.Second * 3) // waiting for some blocks to pass
@ -49,7 +48,7 @@ func TestGaiaCLISend(t *testing.T) {
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags))
assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion"))
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
assert.Equal(t, int64(99990), fooAcc.GetCoins().AmountOf("fermion"))
assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("fermion"))
}
func TestGaiaCLIDeclareCandidacy(t *testing.T) {
@ -57,8 +56,7 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) {
tests.ExecuteT(t, "gaiad unsafe_reset_all", 1)
pass := "1234567890"
executeWrite(t, "gaiacli keys delete foo", pass)
keys, chainID := executeInit(t, "gaiad init -o --accounts=bar-100000fermion-true:foo-100000fermion-false", "bar", "foo")
require.Equal(t, 2, len(keys))
key, chainID := executeInit(t, "gaiad init -o --name=foo")
// get a free port, also setup some common flags
servAddr := server.FreeTCPAddr(t)
@ -68,41 +66,46 @@ 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, keys[1])
fooAddr, fooPubKey := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
executeWrite(t, "gaiacli keys add foo --recover", pass, key)
executeWrite(t, "gaiacli keys add bar", pass)
fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
barAddr, barPubKey := executeGetAddrPK(t, "gaiacli keys show bar --output=json")
time.Sleep(time.Second * 3) // waiting for some blocks to pass
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags))
assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("fermion"))
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
assert.Equal(t, int64(100000), fooAcc.GetCoins().AmountOf("fermion"))
assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("fermion"))
// declare candidacy
declStr := fmt.Sprintf("gaiacli declare-candidacy %v", flags)
declStr += fmt.Sprintf(" --name=%v", "foo")
declStr += fmt.Sprintf(" --address-candidate=%v", fooAddr)
declStr += fmt.Sprintf(" --pubkey=%v", fooPubKey)
declStr += fmt.Sprintf(" --name=%v", "bar")
declStr += fmt.Sprintf(" --address-candidate=%v", barAddr)
declStr += fmt.Sprintf(" --pubkey=%v", barPubKey)
declStr += fmt.Sprintf(" --amount=%v", "3fermion")
declStr += fmt.Sprintf(" --moniker=%v", "foo-vally")
declStr += fmt.Sprintf(" --moniker=%v", "bar-vally")
fmt.Printf("debug declStr: %v\n", declStr)
executeWrite(t, declStr, pass)
time.Sleep(time.Second * 3) // waiting for some blocks to pass
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
assert.Equal(t, int64(99997), fooAcc.GetCoins().AmountOf("fermion"))
candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr))
assert.Equal(t, candidate.Address.String(), fooAddr)
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags))
assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("fermion"))
candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr))
assert.Equal(t, candidate.Address.String(), barAddr)
assert.Equal(t, int64(3), candidate.Assets.Evaluate())
// TODO timeout issues if not connected to the internet
// unbond a single share
//unbondStr := fmt.Sprintf("gaiacli unbond %v", flags)
//unbondStr += fmt.Sprintf(" --name=%v", "foo")
//unbondStr += fmt.Sprintf(" --address-candidate=%v", fooAddr)
//unbondStr += fmt.Sprintf(" --address-delegator=%v", fooAddr)
//unbondStr += fmt.Sprintf(" --name=%v", "bar")
//unbondStr += fmt.Sprintf(" --address-candidate=%v", barAddr)
//unbondStr += fmt.Sprintf(" --address-delegator=%v", barAddr)
//unbondStr += fmt.Sprintf(" --shares=%v", "1")
//unbondStr += fmt.Sprintf(" --sequence=%v", "1")
//fmt.Printf("debug unbondStr: %v\n", unbondStr)
//executeWrite(t, unbondStr, pass)
//time.Sleep(time.Second * 3) // waiting for some blocks to pass
//fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooAddr, flags))
//assert.Equal(t, int64(99998), fooAcc.GetCoins().AmountOf("fermion"))
//candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, fooAddr))
//barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags))
//assert.Equal(t, int64(99998), barAcc.GetCoins().AmountOf("fermion"))
//candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr))
//assert.Equal(t, int64(2), candidate.Assets.Evaluate())
}
@ -130,7 +133,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, names ...string) (keys []string, chainID string) {
func executeInit(t *testing.T, cmdStr string) (key, chainID string) {
out := tests.ExecuteT(t, cmdStr, 1)
var initRes map[string]json.RawMessage
@ -144,12 +147,8 @@ func executeInit(t *testing.T, cmdStr string, names ...string) (keys []string, c
err = json.Unmarshal(initRes["app_message"], &appMessageRes)
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)
}
err = json.Unmarshal(appMessageRes["secret"], &key)
require.NoError(t, err)
return
}

View File

@ -8,8 +8,6 @@ import (
"github.com/spf13/cobra"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/tendermint/tmlibs/cli"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
@ -21,12 +19,13 @@ import (
// init parameters
var CoolAppInit = server.AppInit{
GenAppParams: CoolGenAppParams,
AppGenState: CoolAppGenState,
AppGenTx: server.SimpleAppGenTx,
}
// 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)
func CoolAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
appState, err = server.SimpleAppGenState(cdc, appGenTxs)
if err != nil {
return
}

View File

@ -8,7 +8,6 @@ import (
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
tmtypes "github.com/tendermint/tendermint/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
@ -106,17 +105,9 @@ func InitChainer(key sdk.StoreKey) func(sdk.Context, abci.RequestInitChain) abci
}
}
// GenAppParams can be passed into InitCmd, returns a static string of a few
// AppGenState can be passed into InitCmd, returns a static string of a few
// key-values that can be parsed by InitChainer
func GenAppParams(_ *wire.Codec, pubKey crypto.PubKey) (chainID string, validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) {
chainID = fmt.Sprintf("test-chain-%v", cmn.RandStr(6))
validators = []tmtypes.GenesisValidator{{
PubKey: pubKey,
Power: 10,
}}
func AppGenState(_ *wire.Codec, _ []json.RawMessage) (appState json.RawMessage, err error) {
appState = json.RawMessage(`{
"values": [
{
@ -131,3 +122,14 @@ func GenAppParams(_ *wire.Codec, pubKey crypto.PubKey) (chainID string, validato
}`)
return
}
// Return a validator, not much else
func AppGenTx(_ *wire.Codec, pk crypto.PubKey) (
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) {
validator = tmtypes.GenesisValidator{
PubKey: pk,
Power: 10,
}
return
}

View File

@ -7,7 +7,6 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
)
// TestInitApp makes sure we can initialize this thing without an error
@ -22,9 +21,9 @@ func TestInitApp(t *testing.T) {
require.NoError(t, err)
// initialize it future-way
pubKey := crypto.GenPrivKeyEd25519().PubKey()
_, _, appState, _, err := GenAppParams(nil, pubKey)
appState, err := AppGenState(nil, nil)
require.NoError(t, err)
//TODO test validators in the init chain?
req := abci.RequestInitChain{
AppStateBytes: appState,

View File

@ -4,11 +4,13 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
@ -30,13 +32,14 @@ type GenesisTx struct {
IP string `json:"ip"`
Validator tmtypes.GenesisValidator `json:"validator"`
AppGenTx json.RawMessage `json:"app_gen_tx"`
CLIPrint json.RawMessage `json:"cli_print"`
}
var (
flagOverwrite = "overwrite"
flagGenTxs = "gen-txs"
flagIP = "ip"
flagChainID = "ip"
flagChainID = "chain-id"
)
// get cmd to initialize all files for tendermint and application
@ -55,7 +58,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command {
nodeID := string(nodeKey.ID())
pubKey := ReadOrCreatePrivValidator(config)
appGenTx, toPrint, validator, err := appInit.GenAppTx(cdc, pubKey)
appGenTx, cliPrint, validator, err := appInit.AppGenTx(cdc, pubKey)
if err != nil {
return err
}
@ -73,6 +76,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command {
IP: ip,
Validator: validator,
AppGenTx: appGenTx,
CLIPrint: cliPrint,
}
bz, err := wire.MarshalJSONIndent(cdc, tx)
if err != nil {
@ -85,7 +89,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command {
err = cmn.WriteFile(file, bz, 0644)
}
out, err := wire.MarshalJSONIndent(cdc, toPrint)
out, err := wire.MarshalJSONIndent(cdc, cliPrint)
if err != nil {
return err
}
@ -94,7 +98,7 @@ func GenTxCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command {
},
}
cmd.Flags().String(flagIP, "", "external facing IP to use if left blank IP will be retrieved from this machine")
cmd.Flags().AddFlagSet(appInit.FlagsAppTx)
cmd.Flags().AddFlagSet(appInit.FlagsAppGenTx)
return cmd
}
@ -125,26 +129,31 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command {
}
// process genesis transactions, or otherwise create one for defaults
var appGenTxs, cliPrints []json.RawMessage
var appMessage json.RawMessage
var appGenTxs []json.RawMessage
var validators []tmtypes.GenesisValidator
var persistentPeers string
genTxsDir := viper.GetString(flagGenTxs)
if genTxsDir != "" {
validators, persistentPeers, appGenTxs, cliPrints = processGenTxs(genTxsDir, cdc, appInit)
validators, appGenTxs, persistentPeers, err = processGenTxs(genTxsDir, cdc, appInit)
if err != nil {
return err
}
config.P2P.PersistentPeers = persistentPeers
configFilePath := filepath.Join(viper.GetString("home"), "config", "config.toml") //TODO this is annoying should be easier to get
cfg.WriteConfigFile(configFilePath, config)
} else {
appTx, cliPrint, validator, err := appInit.GenAppTx(cdc, pubKey)
appGenTx, am, validator, err := appInit.AppGenTx(cdc, pubKey)
appMessage = am
if err != nil {
return err
}
validators = []tmtypes.GenesisValidator{validator}
appGenTxs = []json.RawMessage{appTx}
cliPrints = []json.RawMessage{cliPrint}
appGenTxs = []json.RawMessage{appGenTx}
}
appState, err := appInit.GenAppParams(cdc, appGenTxs)
appState, err := appInit.AppGenState(cdc, appGenTxs)
if err != nil {
return err
}
@ -156,13 +165,13 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command {
// print out some key information
toPrint := struct {
ChainID string `json:"chain_id"`
NodeID string `json:"node_id"`
AppMessage []json.RawMessage `json:"app_messages"`
ChainID string `json:"chain_id"`
NodeID string `json:"node_id"`
AppMessage json.RawMessage `json:"app_message"`
}{
chainID,
nodeID,
cliPrints,
appMessage,
}
out, err := wire.MarshalJSONIndent(cdc, toPrint)
if err != nil {
@ -174,47 +183,55 @@ func InitCmd(ctx *Context, cdc *wire.Codec, appInit AppInit) *cobra.Command {
},
}
cmd.Flags().BoolP(flagOverwrite, "o", false, "overwrite the genesis.json file")
cmd.Flags().String(flagChainID, "", "designated chain-id for the genesis")
cmd.Flags().AddFlagSet(appInit.FlagsAppParams)
cmd.Flags().String(flagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(flagGenTxs, "", "directory containing the genesis transactions")
cmd.Flags().AddFlagSet(appInit.FlagsAppGenState)
cmd.Flags().AddFlagSet(appInit.FlagsAppGenTx) // need to add this flagset for when no GenTx's provided
cmd.AddCommand(GenTxCmd(ctx, cdc, appInit))
return cmd
}
// append a genesis-piece
func processGenTxs(genTxsDir string, cdc *wire.Codec, appInit AppInit) (
validators []tmtypes.GenesisValidator, appGenTxs, cliPrints []json.RawMessage, persistentPeers string, err error) {
validators []tmtypes.GenesisValidator, appGenTxs []json.RawMessage, persistentPeers string, err error) {
fos, err := ioutil.ReadDir(genTxsDir)
// XXX sort the files by contents just incase people renamed their files
var fos []os.FileInfo
fos, err = ioutil.ReadDir(genTxsDir)
if err != nil {
return
}
for _, fo := range fos {
filename := fo.Name()
if !fo.IsDir() && (path.Ext(filename) != ".json") {
return nil
return
}
// get the genTx
bz, err := ioutil.ReadFile(filename)
var bz []byte
bz, err = ioutil.ReadFile(filename)
if err != nil {
return err
return
}
var genTx GenesisTx
err = cdc.UnmarshalJSON(bz, &genTx)
if err != nil {
return err
return
}
// combine some stuff
validators = append(validators, genTx.Validator)
appGenTxs = append(appGenTxs, genTx.AppGenTxs)
cliPrints = append(cliPrints, genTx.CliPrints)
appGenTxs = append(appGenTxs, genTx.AppGenTx)
// Add a persistent peer
comma := ","
if len(persistentPeers) == 0 {
comma = ""
}
persistentPeers += fmt.Sprintf("%s%s@%s:46656", comma, piece.NodeID, piece.IP)
persistentPeers += fmt.Sprintf("%s%s@%s:46656", comma, genTx.NodeID, genTx.IP)
}
return nil
return
}
//________________________________________________________________________________________
@ -267,43 +284,44 @@ func addAppStateToGenesis(cdc *wire.Codec, genesisConfigPath string, appState js
type AppInit struct {
// flags required for application init functions
FlagsAppParams *pflag.FlagSet
FlagsAppTx *pflag.FlagSet
FlagsAppGenState *pflag.FlagSet
FlagsAppGenTx *pflag.FlagSet
// GenAppParams creates the core parameters initialization. It takes in a
// AppGenState creates the core parameters initialization. It takes in a
// pubkey meant to represent the pubkey of the validator of this machine.
GenAppParams func(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error)
AppGenState func(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error)
// create the application genesis tx
GenAppTx func(cdc *wire.Codec, pk crypto.PubKey) (
appTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error)
AppGenTx func(cdc *wire.Codec, pk crypto.PubKey) (
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error)
}
//_____________________________________________________________________
// simple default application init
var DefaultAppInit = AppInit{
GenAppParams: SimpleGenAppParams,
AppGenState: SimpleAppGenState,
AppGenTx: SimpleAppGenTx,
}
// Create one account with a whole bunch of mycoin in it
func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey, _ json.RawMessage) (
validators []tmtypes.GenesisValidator, appState, cliPrint json.RawMessage, err error) {
// simple genesis tx
type SimpleGenTx struct {
Addr sdk.Address `json:"addr"`
}
var addr sdk.Address
// create the genesis app state
func SimpleAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
var secret string
addr, secret, err = GenerateCoinKey()
if err != nil {
if len(appGenTxs) != 1 {
err = errors.New("must provide a single genesis transaction")
return
}
mm := map[string]string{"secret": secret}
bz, err := cdc.MarshalJSON(mm)
cliPrint = json.RawMessage(bz)
validators = []tmtypes.GenesisValidator{{
PubKey: pubKey,
Power: 10,
}}
var genTx SimpleGenTx
err = cdc.UnmarshalJSON(appGenTxs[0], &genTx)
if err != nil {
return
}
appState = json.RawMessage(fmt.Sprintf(`{
"accounts": [{
@ -315,7 +333,40 @@ func SimpleGenAppParams(cdc *wire.Codec, pubKey crypto.PubKey, _ json.RawMessage
}
]
}]
}`, addr.String()))
}`, genTx.Addr.String()))
return
}
// 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
}

View File

@ -21,7 +21,8 @@ func TestInit(t *testing.T) {
ctx := NewContext(cfg, logger)
cdc := wire.NewCodec()
appInit := AppInit{
GenAppParams: mock.GenAppParams,
AppGenState: mock.AppGenState,
AppGenTx: mock.AppGenTx,
}
cmd := InitCmd(ctx, cdc, appInit)
err = cmd.RunE(nil, nil)

View File

@ -28,7 +28,8 @@ func TestStartStandAlone(t *testing.T) {
ctx := NewContext(cfg, logger)
cdc := wire.NewCodec()
appInit := AppInit{
GenAppParams: mock.GenAppParams,
AppGenState: mock.AppGenState,
AppGenTx: mock.AppGenTx,
}
initCmd := InitCmd(ctx, cdc, appInit)
err = initCmd.RunE(nil, nil)
@ -58,7 +59,8 @@ func TestStartWithTendermint(t *testing.T) {
ctx := NewContext(cfg, logger)
cdc := wire.NewCodec()
appInit := AppInit{
GenAppParams: mock.GenAppParams,
AppGenState: mock.AppGenState,
AppGenTx: mock.AppGenTx,
}
initCmd := InitCmd(ctx, cdc, appInit)
err = initCmd.RunE(nil, nil)