init refactor uses genesis transaction now
This commit is contained in:
parent
12f20d160a
commit
b9477ecbbe
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
24
mock/app.go
24
mock/app.go
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
149
server/init.go
149
server/init.go
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue