Merge branch 'develop' into sunny/get_all_delegations_validator_querier
This commit is contained in:
+20
-12
@@ -210,9 +210,6 @@ func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.R
|
||||
tags := gov.EndBlocker(ctx, app.govKeeper)
|
||||
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
|
||||
|
||||
// Add these new validators to the addr -> pubkey map.
|
||||
app.slashingKeeper.AddValidators(ctx, validatorUpdates)
|
||||
|
||||
return abci.ResponseEndBlock{
|
||||
ValidatorUpdates: validatorUpdates,
|
||||
Tags: tags,
|
||||
@@ -231,6 +228,10 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||
// return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||
}
|
||||
|
||||
// sort by account number to maintain consistency
|
||||
sort.Slice(genesisState.Accounts, func(i, j int) bool {
|
||||
return genesisState.Accounts[i].AccountNumber < genesisState.Accounts[j].AccountNumber
|
||||
})
|
||||
// load the accounts
|
||||
for _, gacc := range genesisState.Accounts {
|
||||
acc := gacc.ToAccount()
|
||||
@@ -244,7 +245,8 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||
panic(err) // TODO find a way to do this w/o panics
|
||||
}
|
||||
|
||||
// load the address to pubkey map
|
||||
// initialize module-specific stores
|
||||
auth.InitGenesis(ctx, app.feeCollectionKeeper, genesisState.AuthData)
|
||||
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.SlashingData, genesisState.StakeData)
|
||||
gov.InitGenesis(ctx, app.govKeeper, genesisState.GovData)
|
||||
mint.InitGenesis(ctx, app.mintKeeper, genesisState.MintData)
|
||||
@@ -270,7 +272,6 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||
|
||||
validators = app.stakeKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
}
|
||||
app.slashingKeeper.AddValidators(ctx, validators)
|
||||
|
||||
// sanity check
|
||||
if len(req.Validators) > 0 {
|
||||
@@ -306,11 +307,12 @@ func (app *GaiaApp) ExportAppStateAndValidators() (appState json.RawMessage, val
|
||||
app.accountKeeper.IterateAccounts(ctx, appendAccount)
|
||||
genState := NewGenesisState(
|
||||
accounts,
|
||||
stake.WriteGenesis(ctx, app.stakeKeeper),
|
||||
mint.WriteGenesis(ctx, app.mintKeeper),
|
||||
distr.WriteGenesis(ctx, app.distrKeeper),
|
||||
gov.WriteGenesis(ctx, app.govKeeper),
|
||||
slashing.GenesisState{}, // TODO create write methods
|
||||
auth.ExportGenesis(ctx, app.feeCollectionKeeper),
|
||||
stake.ExportGenesis(ctx, app.stakeKeeper),
|
||||
mint.ExportGenesis(ctx, app.mintKeeper),
|
||||
distr.ExportGenesis(ctx, app.distrKeeper),
|
||||
gov.ExportGenesis(ctx, app.govKeeper),
|
||||
slashing.ExportGenesis(ctx, app.slashingKeeper),
|
||||
)
|
||||
appState, err = codec.MarshalJSONIndent(app.cdc, genState)
|
||||
if err != nil {
|
||||
@@ -337,12 +339,15 @@ var _ sdk.StakingHooks = Hooks{}
|
||||
// nolint
|
||||
func (h Hooks) OnValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||
h.dh.OnValidatorCreated(ctx, valAddr)
|
||||
h.sh.OnValidatorCreated(ctx, valAddr)
|
||||
}
|
||||
func (h Hooks) OnValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||
h.dh.OnValidatorModified(ctx, valAddr)
|
||||
h.sh.OnValidatorModified(ctx, valAddr)
|
||||
}
|
||||
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, valAddr sdk.ValAddress) {
|
||||
h.dh.OnValidatorRemoved(ctx, valAddr)
|
||||
func (h Hooks) OnValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
|
||||
h.dh.OnValidatorRemoved(ctx, consAddr, valAddr)
|
||||
h.sh.OnValidatorRemoved(ctx, consAddr, valAddr)
|
||||
}
|
||||
func (h Hooks) OnValidatorBonded(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
|
||||
h.dh.OnValidatorBonded(ctx, consAddr, valAddr)
|
||||
@@ -358,10 +363,13 @@ func (h Hooks) OnValidatorBeginUnbonding(ctx sdk.Context, consAddr sdk.ConsAddre
|
||||
}
|
||||
func (h Hooks) OnDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||
h.dh.OnDelegationCreated(ctx, delAddr, valAddr)
|
||||
h.sh.OnDelegationCreated(ctx, delAddr, valAddr)
|
||||
}
|
||||
func (h Hooks) OnDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||
h.dh.OnDelegationSharesModified(ctx, delAddr, valAddr)
|
||||
h.sh.OnDelegationSharesModified(ctx, delAddr, valAddr)
|
||||
}
|
||||
func (h Hooks) OnDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
|
||||
h.dh.OnDelegationRemoved(ctx, delAddr, valAddr)
|
||||
h.sh.OnDelegationRemoved(ctx, delAddr, valAddr)
|
||||
}
|
||||
|
||||
+20
-10
@@ -32,6 +32,7 @@ var (
|
||||
// State to Unmarshal
|
||||
type GenesisState struct {
|
||||
Accounts []GenesisAccount `json:"accounts"`
|
||||
AuthData auth.GenesisState `json:"auth"`
|
||||
StakeData stake.GenesisState `json:"stake"`
|
||||
MintData mint.GenesisState `json:"mint"`
|
||||
DistrData distr.GenesisState `json:"distr"`
|
||||
@@ -40,11 +41,12 @@ type GenesisState struct {
|
||||
GenTxs []json.RawMessage `json:"gentxs"`
|
||||
}
|
||||
|
||||
func NewGenesisState(accounts []GenesisAccount, stakeData stake.GenesisState, mintData mint.GenesisState,
|
||||
func NewGenesisState(accounts []GenesisAccount, authData auth.GenesisState, stakeData stake.GenesisState, mintData mint.GenesisState,
|
||||
distrData distr.GenesisState, govData gov.GenesisState, slashingData slashing.GenesisState) GenesisState {
|
||||
|
||||
return GenesisState{
|
||||
Accounts: accounts,
|
||||
AuthData: authData,
|
||||
StakeData: stakeData,
|
||||
MintData: mintData,
|
||||
DistrData: distrData,
|
||||
@@ -53,31 +55,39 @@ func NewGenesisState(accounts []GenesisAccount, stakeData stake.GenesisState, mi
|
||||
}
|
||||
}
|
||||
|
||||
// GenesisAccount doesn't need pubkey or sequence
|
||||
// nolint
|
||||
type GenesisAccount struct {
|
||||
Address sdk.AccAddress `json:"address"`
|
||||
Coins sdk.Coins `json:"coins"`
|
||||
Address sdk.AccAddress `json:"address"`
|
||||
Coins sdk.Coins `json:"coins"`
|
||||
Sequence int64 `json:"sequence_number"`
|
||||
AccountNumber int64 `json:"account_number"`
|
||||
}
|
||||
|
||||
func NewGenesisAccount(acc *auth.BaseAccount) GenesisAccount {
|
||||
return GenesisAccount{
|
||||
Address: acc.Address,
|
||||
Coins: acc.Coins,
|
||||
Address: acc.Address,
|
||||
Coins: acc.Coins,
|
||||
AccountNumber: acc.AccountNumber,
|
||||
Sequence: acc.Sequence,
|
||||
}
|
||||
}
|
||||
|
||||
func NewGenesisAccountI(acc auth.Account) GenesisAccount {
|
||||
return GenesisAccount{
|
||||
Address: acc.GetAddress(),
|
||||
Coins: acc.GetCoins(),
|
||||
Address: acc.GetAddress(),
|
||||
Coins: acc.GetCoins(),
|
||||
AccountNumber: acc.GetAccountNumber(),
|
||||
Sequence: acc.GetSequence(),
|
||||
}
|
||||
}
|
||||
|
||||
// convert GenesisAccount to auth.BaseAccount
|
||||
func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) {
|
||||
return &auth.BaseAccount{
|
||||
Address: ga.Address,
|
||||
Coins: ga.Coins.Sort(),
|
||||
Address: ga.Address,
|
||||
Coins: ga.Coins.Sort(),
|
||||
AccountNumber: ga.AccountNumber,
|
||||
Sequence: ga.Sequence,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@ package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
@@ -91,8 +92,10 @@ func TestGaiaAppGenState(t *testing.T) {
|
||||
func makeMsg(name string, pk crypto.PubKey) auth.StdTx {
|
||||
desc := stake.NewDescription(name, "", "", "")
|
||||
comm := stakeTypes.CommissionMsg{}
|
||||
msg := stake.NewMsgCreateValidator(sdk.ValAddress(pk.Address()), pk, sdk.NewInt64Coin(bondDenom,
|
||||
50), desc, comm)
|
||||
msg := stake.NewMsgCreateValidator(
|
||||
sdk.ValAddress(pk.Address()), pk,
|
||||
sdk.NewInt64Coin(bondDenom, 50), desc, comm,
|
||||
)
|
||||
return auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, nil, "")
|
||||
}
|
||||
|
||||
|
||||
+103
-5
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
@@ -70,15 +71,15 @@ func appStateFn(r *rand.Rand, accs []simulation.Account) json.RawMessage {
|
||||
|
||||
// Random genesis states
|
||||
govGenesis := gov.GenesisState{
|
||||
StartingProposalID: int64(r.Intn(100)),
|
||||
DepositProcedure: gov.DepositProcedure{
|
||||
StartingProposalID: uint64(r.Intn(100)),
|
||||
DepositParams: gov.DepositParams{
|
||||
MinDeposit: sdk.Coins{sdk.NewInt64Coin("steak", int64(r.Intn(1e3)))},
|
||||
MaxDepositPeriod: time.Duration(r.Intn(2*172800)) * time.Second,
|
||||
},
|
||||
VotingProcedure: gov.VotingProcedure{
|
||||
VotingParams: gov.VotingParams{
|
||||
VotingPeriod: time.Duration(r.Intn(2*172800)) * time.Second,
|
||||
},
|
||||
TallyingProcedure: gov.TallyingProcedure{
|
||||
TallyParams: gov.TallyParams{
|
||||
Threshold: sdk.NewDecWithPrec(5, 1),
|
||||
Veto: sdk.NewDecWithPrec(334, 3),
|
||||
GovernancePenalty: sdk.NewDecWithPrec(1, 2),
|
||||
@@ -166,7 +167,7 @@ func testAndRunTxs(app *GaiaApp) []simulation.WeightedOperation {
|
||||
{50, distrsim.SimulateMsgWithdrawDelegatorReward(app.accountKeeper, app.distrKeeper)},
|
||||
{50, distrsim.SimulateMsgWithdrawValidatorRewardsAll(app.accountKeeper, app.distrKeeper)},
|
||||
{5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, app.stakeKeeper)},
|
||||
{100, govsim.SimulateMsgDeposit(app.govKeeper, app.stakeKeeper)},
|
||||
{100, govsim.SimulateMsgDeposit(app.govKeeper)},
|
||||
{100, stakesim.SimulateMsgCreateValidator(app.accountKeeper, app.stakeKeeper)},
|
||||
{5, stakesim.SimulateMsgEditValidator(app.stakeKeeper)},
|
||||
{100, stakesim.SimulateMsgDelegate(app.accountKeeper, app.stakeKeeper)},
|
||||
@@ -266,6 +267,103 @@ func TestFullGaiaSimulation(t *testing.T) {
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestGaiaImportExport(t *testing.T) {
|
||||
if !enabled {
|
||||
t.Skip("Skipping Gaia import/export simulation")
|
||||
}
|
||||
|
||||
// Setup Gaia application
|
||||
var logger log.Logger
|
||||
if verbose {
|
||||
logger = log.TestingLogger()
|
||||
} else {
|
||||
logger = log.NewNopLogger()
|
||||
}
|
||||
var db dbm.DB
|
||||
dir, _ := ioutil.TempDir("", "goleveldb-gaia-sim")
|
||||
db, _ = dbm.NewGoLevelDB("Simulation", dir)
|
||||
defer func() {
|
||||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
app := NewGaiaApp(logger, db, nil)
|
||||
require.Equal(t, "GaiaApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
err := simulation.SimulateFromSeed(
|
||||
t, app.BaseApp, appStateFn, seed,
|
||||
testAndRunTxs(app),
|
||||
[]simulation.RandSetup{},
|
||||
invariants(app),
|
||||
numBlocks,
|
||||
blockSize,
|
||||
commit,
|
||||
)
|
||||
if commit {
|
||||
// for memdb:
|
||||
// fmt.Println("Database Size", db.Stats()["database.size"])
|
||||
fmt.Println("GoLevelDB Stats")
|
||||
fmt.Println(db.Stats()["leveldb.stats"])
|
||||
fmt.Println("GoLevelDB cached block size", db.Stats()["leveldb.cachedblock"])
|
||||
}
|
||||
require.Nil(t, err)
|
||||
|
||||
fmt.Printf("Exporting genesis...\n")
|
||||
|
||||
appState, _, err := app.ExportAppStateAndValidators()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Importing genesis...\n")
|
||||
|
||||
newDir, _ := ioutil.TempDir("", "goleveldb-gaia-sim-2")
|
||||
newDB, _ := dbm.NewGoLevelDB("Simulation-2", dir)
|
||||
defer func() {
|
||||
newDB.Close()
|
||||
os.RemoveAll(newDir)
|
||||
}()
|
||||
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil)
|
||||
require.Equal(t, "GaiaApp", newApp.Name())
|
||||
request := abci.RequestInitChain{
|
||||
AppStateBytes: appState,
|
||||
}
|
||||
newApp.InitChain(request)
|
||||
newApp.Commit()
|
||||
|
||||
fmt.Printf("Comparing stores...\n")
|
||||
ctxA := app.NewContext(true, abci.Header{})
|
||||
ctxB := newApp.NewContext(true, abci.Header{})
|
||||
type StoreKeysPrefixes struct {
|
||||
A sdk.StoreKey
|
||||
B sdk.StoreKey
|
||||
Prefixes [][]byte
|
||||
}
|
||||
storeKeysPrefixes := []StoreKeysPrefixes{
|
||||
{app.keyMain, newApp.keyMain, [][]byte{}},
|
||||
{app.keyAccount, newApp.keyAccount, [][]byte{}},
|
||||
{app.keyStake, newApp.keyStake, [][]byte{stake.UnbondingQueueKey, stake.RedelegationQueueKey, stake.ValidatorQueueKey}}, // ordering may change but it doesn't matter
|
||||
{app.keySlashing, newApp.keySlashing, [][]byte{}},
|
||||
{app.keyMint, newApp.keyMint, [][]byte{}},
|
||||
{app.keyDistr, newApp.keyDistr, [][]byte{}},
|
||||
{app.keyFeeCollection, newApp.keyFeeCollection, [][]byte{}},
|
||||
{app.keyParams, newApp.keyParams, [][]byte{}},
|
||||
{app.keyGov, newApp.keyGov, [][]byte{}},
|
||||
}
|
||||
for _, storeKeysPrefix := range storeKeysPrefixes {
|
||||
storeKeyA := storeKeysPrefix.A
|
||||
storeKeyB := storeKeysPrefix.B
|
||||
prefixes := storeKeysPrefix.Prefixes
|
||||
storeA := ctxA.KVStore(storeKeyA)
|
||||
storeB := ctxB.KVStore(storeKeyB)
|
||||
kvA, kvB, count, equal := sdk.DiffKVStores(storeA, storeB, prefixes)
|
||||
fmt.Printf("Compared %d key/value pairs between %s and %s\n", count, storeKeyA, storeKeyB)
|
||||
require.True(t, equal, "unequal stores: %s / %s:\nstore A %s (%X) => %s (%X)\nstore B %s (%X) => %s (%X)",
|
||||
storeKeyA, storeKeyB, kvA.Key, kvA.Key, kvA.Value, kvA.Value, kvB.Key, kvB.Key, kvB.Value, kvB.Value)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO: Make another test for the fuzzer itself, which just has noOp txs
|
||||
// and doesn't depend on gaia
|
||||
func TestAppStateDeterminism(t *testing.T) {
|
||||
|
||||
@@ -5,13 +5,14 @@ package clitest
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
@@ -352,7 +353,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
require.Equal(t, int64(45), fooAcc.GetCoins().AmountOf("steak").Int64())
|
||||
|
||||
proposal1 := executeGetProposal(t, fmt.Sprintf("gaiacli query proposal --proposal-id=1 --output=json %v", flags))
|
||||
require.Equal(t, int64(1), proposal1.GetProposalID())
|
||||
require.Equal(t, uint64(1), proposal1.GetProposalID())
|
||||
require.Equal(t, gov.StatusDepositPeriod, proposal1.GetStatus())
|
||||
|
||||
proposalsQuery, _ = tests.ExecuteT(t, fmt.Sprintf("gaiacli query proposals %v", flags), "")
|
||||
@@ -395,7 +396,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli query account %s %v", fooAddr, flags))
|
||||
require.Equal(t, int64(35), fooAcc.GetCoins().AmountOf("steak").Int64())
|
||||
proposal1 = executeGetProposal(t, fmt.Sprintf("gaiacli query proposal --proposal-id=1 --output=json %v", flags))
|
||||
require.Equal(t, int64(1), proposal1.GetProposalID())
|
||||
require.Equal(t, uint64(1), proposal1.GetProposalID())
|
||||
require.Equal(t, gov.StatusVotingPeriod, proposal1.GetStatus())
|
||||
|
||||
voteStr := fmt.Sprintf("gaiacli tx vote %v", flags)
|
||||
@@ -417,12 +418,12 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
|
||||
vote := executeGetVote(t, fmt.Sprintf("gaiacli query vote --proposal-id=1 --voter=%s --output=json %v", fooAddr, flags))
|
||||
require.Equal(t, int64(1), vote.ProposalID)
|
||||
require.Equal(t, uint64(1), vote.ProposalID)
|
||||
require.Equal(t, gov.OptionYes, vote.Option)
|
||||
|
||||
votes := executeGetVotes(t, fmt.Sprintf("gaiacli query votes --proposal-id=1 --output=json %v", flags))
|
||||
require.Len(t, votes, 1)
|
||||
require.Equal(t, int64(1), votes[0].ProposalID)
|
||||
require.Equal(t, uint64(1), votes[0].ProposalID)
|
||||
require.Equal(t, gov.OptionYes, votes[0].Option)
|
||||
|
||||
proposalsQuery, _ = tests.ExecuteT(t, fmt.Sprintf("gaiacli query proposals --status=DepositPeriod %v", flags), "")
|
||||
@@ -442,7 +443,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
||||
executeWrite(t, spStr, app.DefaultKeyPass)
|
||||
tests.WaitForNextNBlocksTM(2, port)
|
||||
|
||||
proposalsQuery, _ = tests.ExecuteT(t, fmt.Sprintf("gaiacli query proposals --latest=1 %v", flags), "")
|
||||
proposalsQuery, _ = tests.ExecuteT(t, fmt.Sprintf("gaiacli query proposals --limit=1 %v", flags), "")
|
||||
require.Equal(t, " 2 - Apples", proposalsQuery)
|
||||
}
|
||||
|
||||
|
||||
+20
-21
@@ -2,7 +2,6 @@ package init
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
@@ -12,7 +11,6 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/tendermint/go-amino"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
@@ -35,12 +33,13 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
config := ctx.Config
|
||||
config.SetRoot(viper.GetString(cli.HomeFlag))
|
||||
|
||||
name := viper.GetString(client.FlagName)
|
||||
|
||||
nodeID, valPubKey, err := InitializeNodeValidatorFiles(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genDoc, err := loadGenesisDoc(cdc, config.GenesisFile())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -59,12 +58,14 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
||||
NodeID: nodeID,
|
||||
ValPubKey: valPubKey,
|
||||
}
|
||||
|
||||
appMessage, err := genAppStateFromConfig(cdc, config, initCfg, genDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toPrint.AppMessage = appMessage
|
||||
|
||||
// print out some key information
|
||||
return displayInfo(cdc, toPrint)
|
||||
},
|
||||
@@ -74,23 +75,29 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func genAppStateFromConfig(cdc *codec.Codec, config *cfg.Config, initCfg initConfig,
|
||||
genDoc types.GenesisDoc) (appState json.RawMessage, err error) {
|
||||
func genAppStateFromConfig(
|
||||
cdc *codec.Codec, config *cfg.Config, initCfg initConfig, genDoc types.GenesisDoc,
|
||||
) (appState json.RawMessage, err error) {
|
||||
|
||||
genFile := config.GenesisFile()
|
||||
// process genesis transactions, else create default genesis.json
|
||||
var appGenTxs []auth.StdTx
|
||||
var persistentPeers string
|
||||
var genTxs []json.RawMessage
|
||||
var jsonRawTx json.RawMessage
|
||||
var (
|
||||
appGenTxs []auth.StdTx
|
||||
persistentPeers string
|
||||
genTxs []json.RawMessage
|
||||
jsonRawTx json.RawMessage
|
||||
)
|
||||
|
||||
// process genesis transactions, else create default genesis.json
|
||||
appGenTxs, persistentPeers, err = app.CollectStdTxs(
|
||||
cdc, config.Moniker, initCfg.GenTxsDir, genDoc)
|
||||
cdc, config.Moniker, initCfg.GenTxsDir, genDoc,
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
genTxs = make([]json.RawMessage, len(appGenTxs))
|
||||
config.P2P.PersistentPeers = persistentPeers
|
||||
|
||||
for i, stdTx := range appGenTxs {
|
||||
jsonRawTx, err = cdc.MarshalJSON(stdTx)
|
||||
if err != nil {
|
||||
@@ -100,20 +107,12 @@ func genAppStateFromConfig(cdc *codec.Codec, config *cfg.Config, initCfg initCon
|
||||
}
|
||||
|
||||
cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
|
||||
|
||||
appState, err = app.GaiaAppGenStateJSON(cdc, genDoc, genTxs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = WriteGenesisFile(genFile, initCfg.ChainID, nil, appState)
|
||||
return
|
||||
}
|
||||
|
||||
func loadGenesisDoc(cdc *amino.Codec, genFile string) (genDoc types.GenesisDoc, err error) {
|
||||
genContents, err := ioutil.ReadFile(genFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = cdc.UnmarshalJSON(genContents, &genDoc)
|
||||
err = ExportGenesisFile(genFile, initCfg.ChainID, nil, appState)
|
||||
return
|
||||
}
|
||||
|
||||
+1
-56
@@ -3,7 +3,6 @@ package init
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/tendermint/tendermint/privval"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@@ -14,11 +13,8 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -74,7 +70,7 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
|
||||
viper.GetBool(flagOverwrite)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = WriteGenesisFile(genFile, chainID, nil, appState); err != nil {
|
||||
if err = ExportGenesisFile(genFile, chainID, nil, appState); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -97,54 +93,3 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec, appInit server.AppInit) *cob
|
||||
cmd.Flags().String(flagMoniker, "", "set the validator's moniker")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// InitializeNodeValidatorFiles creates private validator and p2p configuration files.
|
||||
func InitializeNodeValidatorFiles(config *cfg.Config) (nodeID string, valPubKey crypto.PubKey, err error) {
|
||||
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
nodeID = string(nodeKey.ID())
|
||||
valPubKey = ReadOrCreatePrivValidator(config.PrivValidatorFile())
|
||||
return
|
||||
}
|
||||
|
||||
// WriteGenesisFile creates and writes the genesis configuration to disk. An
|
||||
// error is returned if building or writing the configuration to file fails.
|
||||
// nolint: unparam
|
||||
func WriteGenesisFile(genesisFile, chainID string, validators []types.GenesisValidator, appState json.RawMessage) error {
|
||||
genDoc := types.GenesisDoc{
|
||||
ChainID: chainID,
|
||||
Validators: validators,
|
||||
AppState: appState,
|
||||
}
|
||||
|
||||
if err := genDoc.ValidateAndComplete(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return genDoc.SaveAs(genesisFile)
|
||||
}
|
||||
|
||||
// read of create the private key file for this config
|
||||
func ReadOrCreatePrivValidator(privValFile string) crypto.PubKey {
|
||||
// private validator
|
||||
var privValidator *privval.FilePV
|
||||
if common.FileExists(privValFile) {
|
||||
privValidator = privval.LoadFilePV(privValFile)
|
||||
} else {
|
||||
privValidator = privval.GenFilePV(privValFile)
|
||||
privValidator.Save()
|
||||
}
|
||||
return privValidator.GetPubKey()
|
||||
}
|
||||
|
||||
func initializeEmptyGenesis(cdc *codec.Codec, genFile string, chainID string,
|
||||
overwrite bool) (appState json.RawMessage, err error) {
|
||||
if !overwrite && common.FileExists(genFile) {
|
||||
err = fmt.Errorf("genesis.json file already exists: %v", genFile)
|
||||
return
|
||||
}
|
||||
|
||||
return codec.MarshalJSONIndent(cdc, app.NewDefaultGenesisState())
|
||||
}
|
||||
|
||||
+126
-51
@@ -3,6 +3,10 @@ package init
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
@@ -10,10 +14,6 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authtx "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -21,16 +21,17 @@ import (
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
tmtime "github.com/tendermint/tendermint/types/time"
|
||||
)
|
||||
|
||||
var (
|
||||
nodeDirPrefix = "node-dir-prefix"
|
||||
nValidators = "v"
|
||||
outputDir = "output-dir"
|
||||
nodeDaemonHome = "node-daemon-home"
|
||||
nodeCliHome = "node-cli-home"
|
||||
|
||||
startingIPAddress = "starting-ip-address"
|
||||
flagNodeDirPrefix = "node-dir-prefix"
|
||||
flagNumValidators = "v"
|
||||
flagOutputDir = "output-dir"
|
||||
flagNodeDaemonHome = "node-daemon-home"
|
||||
flagNodeCliHome = "node-cli-home"
|
||||
flagStartingIPAddress = "starting-ip-address"
|
||||
)
|
||||
|
||||
const nodeDirPerm = 0755
|
||||
@@ -48,50 +49,59 @@ necessary files (private validator, genesis, config, etc.).
|
||||
Note, strict routability for addresses is turned off in the config file.
|
||||
|
||||
Example:
|
||||
|
||||
gaiad testnet --v 4 --o ./output --starting-ip-address 192.168.10.2
|
||||
gaiad testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2
|
||||
`,
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
config := ctx.Config
|
||||
return testnetWithConfig(config, cdc)
|
||||
return initTestnet(config, cdc)
|
||||
},
|
||||
}
|
||||
cmd.Flags().Int(nValidators, 4,
|
||||
"Number of validators to initialize the testnet with")
|
||||
cmd.Flags().StringP(outputDir, "o", "./mytestnet",
|
||||
"Directory to store initialization data for the testnet")
|
||||
cmd.Flags().String(nodeDirPrefix, "node",
|
||||
"Prefix the directory name for each node with (node results in node0, node1, ...)")
|
||||
cmd.Flags().String(nodeDaemonHome, "gaiad",
|
||||
"Home directory of the node's daemon configuration")
|
||||
cmd.Flags().String(nodeCliHome, "gaiacli",
|
||||
"Home directory of the node's cli configuration")
|
||||
|
||||
cmd.Flags().String(startingIPAddress, "192.168.0.1",
|
||||
cmd.Flags().Int(flagNumValidators, 4,
|
||||
"Number of validators to initialize the testnet with",
|
||||
)
|
||||
cmd.Flags().StringP(flagOutputDir, "o", "./mytestnet",
|
||||
"Directory to store initialization data for the testnet",
|
||||
)
|
||||
cmd.Flags().String(flagNodeDirPrefix, "node",
|
||||
"Prefix the directory name for each node with (node results in node0, node1, ...)",
|
||||
)
|
||||
cmd.Flags().String(flagNodeDaemonHome, "gaiad",
|
||||
"Home directory of the node's daemon configuration",
|
||||
)
|
||||
cmd.Flags().String(flagNodeCliHome, "gaiacli",
|
||||
"Home directory of the node's cli configuration",
|
||||
)
|
||||
cmd.Flags().String(flagStartingIPAddress, "192.168.0.1",
|
||||
"Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
|
||||
outDir := viper.GetString(outputDir)
|
||||
numValidators := viper.GetInt(nValidators)
|
||||
func initTestnet(config *cfg.Config, cdc *codec.Codec) error {
|
||||
outDir := viper.GetString(flagOutputDir)
|
||||
numValidators := viper.GetInt(flagNumValidators)
|
||||
|
||||
// Generate genesis.json and config.toml
|
||||
chainID := "chain-" + cmn.RandStr(6)
|
||||
|
||||
monikers := make([]string, numValidators)
|
||||
nodeIDs := make([]string, numValidators)
|
||||
valPubKeys := make([]crypto.PubKey, numValidators)
|
||||
|
||||
// Generate private key, node ID, initial transaction
|
||||
var accs []app.GenesisAccount
|
||||
var genFiles []string
|
||||
var (
|
||||
accs []app.GenesisAccount
|
||||
genFiles []string
|
||||
)
|
||||
|
||||
// generate private keys, node IDs, and initial transactions
|
||||
for i := 0; i < numValidators; i++ {
|
||||
nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i)
|
||||
nodeDaemonHomeName := viper.GetString(nodeDaemonHome)
|
||||
nodeCliHomeName := viper.GetString(nodeCliHome)
|
||||
nodeDirName := fmt.Sprintf("%s%d", viper.GetString(flagNodeDirPrefix), i)
|
||||
nodeDaemonHomeName := viper.GetString(flagNodeDaemonHome)
|
||||
nodeCliHomeName := viper.GetString(flagNodeCliHome)
|
||||
nodeDir := filepath.Join(outDir, nodeDirName, nodeDaemonHomeName)
|
||||
clientDir := filepath.Join(outDir, nodeDirName, nodeCliHomeName)
|
||||
gentxsDir := filepath.Join(outDir, "gentxs")
|
||||
|
||||
config.SetRoot(nodeDir)
|
||||
|
||||
err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm)
|
||||
@@ -108,24 +118,27 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
|
||||
|
||||
monikers = append(monikers, nodeDirName)
|
||||
config.Moniker = nodeDirName
|
||||
ip, err := getIP(i)
|
||||
|
||||
ip, err := getIP(i, viper.GetString(flagStartingIPAddress))
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(outDir)
|
||||
return err
|
||||
}
|
||||
|
||||
nodeIDs[i], valPubKeys[i], err = InitializeNodeValidatorFiles(config)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(outDir)
|
||||
return err
|
||||
}
|
||||
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
|
||||
|
||||
// write genesis
|
||||
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
|
||||
genFiles = append(genFiles, config.GenesisFile())
|
||||
|
||||
buf := client.BufferStdin()
|
||||
prompt := fmt.Sprintf(
|
||||
"Password for account '%s' (default %s):", nodeDirName, app.DefaultKeyPass)
|
||||
"Password for account '%s' (default %s):", nodeDirName, app.DefaultKeyPass,
|
||||
)
|
||||
|
||||
keyPass, err := client.GetPassword(prompt, buf)
|
||||
if err != nil && keyPass != "" {
|
||||
// An error was returned that either failed to read the password from
|
||||
@@ -133,6 +146,7 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
|
||||
// length requirements.
|
||||
return err
|
||||
}
|
||||
|
||||
if keyPass == "" {
|
||||
keyPass = app.DefaultKeyPass
|
||||
}
|
||||
@@ -142,11 +156,14 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
|
||||
_ = os.RemoveAll(outDir)
|
||||
return err
|
||||
}
|
||||
|
||||
info := map[string]string{"secret": secret}
|
||||
|
||||
cliPrint, err := json.Marshal(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// save private key seed words
|
||||
err = writeFile(fmt.Sprintf("%v.json", "key_seed"), clientDir, cliPrint)
|
||||
if err != nil {
|
||||
@@ -170,6 +187,7 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
|
||||
)
|
||||
tx := auth.NewStdTx([]sdk.Msg{msg}, auth.StdFee{}, []auth.StdSignature{}, memo)
|
||||
txBldr := authtx.NewTxBuilderFromCLI().WithChainID(chainID).WithMemo(memo)
|
||||
|
||||
signedTx, err := txBldr.SignStdTx(nodeDirName, app.DefaultKeyPass, tx, false)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(outDir)
|
||||
@@ -182,7 +200,7 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Gather gentxs folder
|
||||
// gather gentxs folder
|
||||
err = writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBytes)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(outDir)
|
||||
@@ -190,37 +208,70 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Generate empty genesis.json
|
||||
if err := initGenFiles(cdc, chainID, accs, genFiles, numValidators); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := collectGenFiles(
|
||||
cdc, config, chainID, monikers, nodeIDs, valPubKeys, numValidators,
|
||||
outDir, viper.GetString(flagNodeDirPrefix), viper.GetString(flagNodeDaemonHome),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Successfully initialized %d node directories\n", numValidators)
|
||||
return nil
|
||||
}
|
||||
|
||||
func initGenFiles(
|
||||
cdc *codec.Codec, chainID string, accs []app.GenesisAccount,
|
||||
genFiles []string, numValidators int,
|
||||
) error {
|
||||
|
||||
appGenState := app.NewDefaultGenesisState()
|
||||
appGenState.Accounts = accs
|
||||
|
||||
appGenStateJSON, err := codec.MarshalJSONIndent(cdc, appGenState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genDoc := types.GenesisDoc{
|
||||
ChainID: chainID,
|
||||
AppState: appGenStateJSON,
|
||||
Validators: nil,
|
||||
}
|
||||
|
||||
// Save all genesis.json files
|
||||
// generate empty genesis files for each validator and save
|
||||
for i := 0; i < numValidators; i++ {
|
||||
if err := genDoc.SaveAs(genFiles[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func collectGenFiles(
|
||||
cdc *codec.Codec, config *cfg.Config, chainID string,
|
||||
monikers, nodeIDs []string, valPubKeys []crypto.PubKey,
|
||||
numValidators int, outDir, nodeDirPrefix, nodeDaemonHomeName string,
|
||||
) error {
|
||||
|
||||
var appState json.RawMessage
|
||||
genTime := tmtime.Now()
|
||||
|
||||
for i := 0; i < numValidators; i++ {
|
||||
nodeDirName := fmt.Sprintf("%s%d", viper.GetString(nodeDirPrefix), i)
|
||||
nodeDaemonHomeName := viper.GetString(nodeDaemonHome)
|
||||
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
|
||||
nodeDir := filepath.Join(outDir, nodeDirName, nodeDaemonHomeName)
|
||||
gentxsDir := filepath.Join(outDir, "gentxs")
|
||||
moniker := monikers[i]
|
||||
config.Moniker = nodeDirName
|
||||
|
||||
config.SetRoot(nodeDir)
|
||||
|
||||
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
|
||||
// Run `init` and generate genesis.json and config.toml
|
||||
initCfg := initConfig{
|
||||
ChainID: chainID,
|
||||
GenTxsDir: gentxsDir,
|
||||
@@ -228,46 +279,69 @@ func testnetWithConfig(config *cfg.Config, cdc *codec.Codec) error {
|
||||
NodeID: nodeID,
|
||||
ValPubKey: valPubKey,
|
||||
}
|
||||
|
||||
genDoc, err := loadGenesisDoc(cdc, config.GenesisFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := genAppStateFromConfig(cdc, config, initCfg, genDoc); err != nil {
|
||||
|
||||
nodeAppState, err := genAppStateFromConfig(cdc, config, initCfg, genDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if appState == nil {
|
||||
// set the canonical application state (they should not differ)
|
||||
appState = nodeAppState
|
||||
}
|
||||
|
||||
genFile := config.GenesisFile()
|
||||
|
||||
// overwrite each validator's genesis file to have a canonical genesis time
|
||||
err = ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Successfully initialized %v node directories\n", viper.GetInt(nValidators))
|
||||
return nil
|
||||
}
|
||||
|
||||
func getIP(i int) (ip string, err error) {
|
||||
ip = viper.GetString(startingIPAddress)
|
||||
if len(ip) == 0 {
|
||||
func getIP(i int, startingIPAddr string) (string, error) {
|
||||
var (
|
||||
ip string
|
||||
err error
|
||||
)
|
||||
|
||||
if len(startingIPAddr) == 0 {
|
||||
ip, err = server.ExternalIP()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
ip, err = calculateIP(ip, i)
|
||||
ip, err = calculateIP(startingIPAddr, i)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
func writeFile(name string, dir string, contents []byte) error {
|
||||
writePath := filepath.Join(dir)
|
||||
file := filepath.Join(writePath, name)
|
||||
|
||||
err := cmn.EnsureDir(writePath, 0700)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cmn.WriteFile(file, contents, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -280,5 +354,6 @@ func calculateIP(ip string, i int) (string, error) {
|
||||
for j := 0; j < i; j++ {
|
||||
ipv4[3]++
|
||||
}
|
||||
|
||||
return ipv4.String(), nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
package init
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/privval"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// ExportGenesisFile creates and writes the genesis configuration to disk. An
|
||||
// error is returned if building or writing the configuration to file fails.
|
||||
func ExportGenesisFile(
|
||||
genFile, chainID string, validators []types.GenesisValidator, appState json.RawMessage,
|
||||
) error {
|
||||
|
||||
genDoc := types.GenesisDoc{
|
||||
ChainID: chainID,
|
||||
Validators: validators,
|
||||
AppState: appState,
|
||||
}
|
||||
|
||||
if err := genDoc.ValidateAndComplete(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return genDoc.SaveAs(genFile)
|
||||
}
|
||||
|
||||
// ExportGenesisFileWithTime creates and writes the genesis configuration to disk.
|
||||
// An error is returned if building or writing the configuration to file fails.
|
||||
func ExportGenesisFileWithTime(
|
||||
genFile, chainID string, validators []types.GenesisValidator,
|
||||
appState json.RawMessage, genTime time.Time,
|
||||
) error {
|
||||
|
||||
genDoc := types.GenesisDoc{
|
||||
GenesisTime: genTime,
|
||||
ChainID: chainID,
|
||||
Validators: validators,
|
||||
AppState: appState,
|
||||
}
|
||||
|
||||
if err := genDoc.ValidateAndComplete(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return genDoc.SaveAs(genFile)
|
||||
}
|
||||
|
||||
// read of create the private key file for this config
|
||||
func ReadOrCreatePrivValidator(privValFile string) crypto.PubKey {
|
||||
var privValidator *privval.FilePV
|
||||
|
||||
if common.FileExists(privValFile) {
|
||||
privValidator = privval.LoadFilePV(privValFile)
|
||||
} else {
|
||||
privValidator = privval.GenFilePV(privValFile)
|
||||
privValidator.Save()
|
||||
}
|
||||
|
||||
return privValidator.GetPubKey()
|
||||
}
|
||||
|
||||
// InitializeNodeValidatorFiles creates private validator and p2p configuration files.
|
||||
func InitializeNodeValidatorFiles(
|
||||
config *cfg.Config) (nodeID string, valPubKey crypto.PubKey, err error,
|
||||
) {
|
||||
|
||||
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
|
||||
if err != nil {
|
||||
return nodeID, valPubKey, err
|
||||
}
|
||||
|
||||
nodeID = string(nodeKey.ID())
|
||||
valPubKey = ReadOrCreatePrivValidator(config.PrivValidatorFile())
|
||||
|
||||
return nodeID, valPubKey, nil
|
||||
}
|
||||
|
||||
func loadGenesisDoc(cdc *amino.Codec, genFile string) (genDoc types.GenesisDoc, err error) {
|
||||
genContents, err := ioutil.ReadFile(genFile)
|
||||
if err != nil {
|
||||
return genDoc, err
|
||||
}
|
||||
|
||||
if err := cdc.UnmarshalJSON(genContents, &genDoc); err != nil {
|
||||
return genDoc, err
|
||||
}
|
||||
|
||||
return genDoc, err
|
||||
}
|
||||
|
||||
func initializeEmptyGenesis(
|
||||
cdc *codec.Codec, genFile, chainID string, overwrite bool,
|
||||
) (appState json.RawMessage, err error) {
|
||||
|
||||
if !overwrite && common.FileExists(genFile) {
|
||||
return nil, fmt.Errorf("genesis.json file already exists: %v", genFile)
|
||||
}
|
||||
|
||||
return codec.MarshalJSONIndent(cdc, app.NewDefaultGenesisState())
|
||||
}
|
||||
Reference in New Issue
Block a user