Prepare migrating testing auxiliary functions from tests to testutil. Remove local duplicates on testutil.WriteToNewTempFile(). Always favor testutil.NewTestCaseDir() over ioutil.TempDir(). Add test cases for the testing auxiliary functions.
176 lines
4.3 KiB
Go
176 lines
4.3 KiB
Go
package network
|
|
|
|
import (
|
|
"path/filepath"
|
|
"time"
|
|
|
|
tmos "github.com/tendermint/tendermint/libs/os"
|
|
"github.com/tendermint/tendermint/node"
|
|
"github.com/tendermint/tendermint/p2p"
|
|
pvm "github.com/tendermint/tendermint/privval"
|
|
"github.com/tendermint/tendermint/proxy"
|
|
"github.com/tendermint/tendermint/rpc/client/local"
|
|
"github.com/tendermint/tendermint/types"
|
|
tmtime "github.com/tendermint/tendermint/types/time"
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
"github.com/cosmos/cosmos-sdk/server/api"
|
|
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
|
"github.com/cosmos/cosmos-sdk/x/genutil"
|
|
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
|
)
|
|
|
|
func startInProcess(cfg Config, val *Validator) error {
|
|
logger := val.Ctx.Logger
|
|
tmCfg := val.Ctx.Config
|
|
tmCfg.Instrumentation.Prometheus = false
|
|
|
|
nodeKey, err := p2p.LoadOrGenNodeKey(tmCfg.NodeKeyFile())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
app := cfg.AppConstructor(*val)
|
|
|
|
genDocProvider := node.DefaultGenesisDocProviderFunc(tmCfg)
|
|
tmNode, err := node.NewNode(
|
|
tmCfg,
|
|
pvm.LoadOrGenFilePV(tmCfg.PrivValidatorKeyFile(), tmCfg.PrivValidatorStateFile()),
|
|
nodeKey,
|
|
proxy.NewLocalClientCreator(app),
|
|
genDocProvider,
|
|
node.DefaultDBProvider,
|
|
node.DefaultMetricsProvider(tmCfg.Instrumentation),
|
|
logger.With("module", val.Moniker),
|
|
)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := tmNode.Start(); err != nil {
|
|
return err
|
|
}
|
|
|
|
val.tmNode = tmNode
|
|
|
|
if val.RPCAddress != "" {
|
|
val.RPCClient = local.New(tmNode)
|
|
}
|
|
|
|
if val.APIAddress != "" {
|
|
val.ClientCtx = val.ClientCtx.
|
|
WithClient(val.RPCClient).
|
|
WithTrustNode(true)
|
|
|
|
apiSrv := api.New(val.ClientCtx, logger.With("module", "api-server"))
|
|
app.RegisterAPIRoutes(apiSrv)
|
|
|
|
errCh := make(chan error)
|
|
|
|
go func() {
|
|
if err := apiSrv.Start(*val.AppConfig); err != nil {
|
|
errCh <- err
|
|
}
|
|
}()
|
|
|
|
select {
|
|
case err := <-errCh:
|
|
return err
|
|
case <-time.After(5 * time.Second): // assume server started successfully
|
|
}
|
|
|
|
val.api = apiSrv
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func collectGenFiles(cfg Config, vals []*Validator, outputDir string) error {
|
|
genTime := tmtime.Now()
|
|
|
|
for i := 0; i < cfg.NumValidators; i++ {
|
|
tmCfg := vals[i].Ctx.Config
|
|
|
|
nodeDir := filepath.Join(outputDir, vals[i].Moniker, "simd")
|
|
gentxsDir := filepath.Join(outputDir, "gentxs")
|
|
|
|
tmCfg.Moniker = vals[i].Moniker
|
|
tmCfg.SetRoot(nodeDir)
|
|
|
|
initCfg := genutiltypes.NewInitConfig(cfg.ChainID, gentxsDir, vals[i].NodeID, vals[i].PubKey)
|
|
|
|
genFile := tmCfg.GenesisFile()
|
|
genDoc, err := types.GenesisDocFromFile(genFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
appState, err := genutil.GenAppStateFromConfig(cfg.Codec, tmCfg, initCfg, *genDoc, banktypes.GenesisBalancesIterator{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// overwrite each validator's genesis file to have a canonical genesis time
|
|
if err := genutil.ExportGenesisFileWithTime(genFile, cfg.ChainID, nil, appState, genTime); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func initGenFiles(cfg Config, genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance, genFiles []string) error {
|
|
|
|
// set the accounts in the genesis state
|
|
var authGenState authtypes.GenesisState
|
|
cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[authtypes.ModuleName], &authGenState)
|
|
|
|
authGenState.Accounts = genAccounts
|
|
cfg.GenesisState[authtypes.ModuleName] = cfg.Codec.MustMarshalJSON(authGenState)
|
|
|
|
// set the balances in the genesis state
|
|
var bankGenState banktypes.GenesisState
|
|
cfg.Codec.MustUnmarshalJSON(cfg.GenesisState[banktypes.ModuleName], &bankGenState)
|
|
|
|
bankGenState.Balances = genBalances
|
|
cfg.GenesisState[banktypes.ModuleName] = cfg.Codec.MustMarshalJSON(bankGenState)
|
|
|
|
appGenStateJSON, err := codec.MarshalJSONIndent(cfg.Codec, cfg.GenesisState)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
genDoc := types.GenesisDoc{
|
|
ChainID: cfg.ChainID,
|
|
AppState: appGenStateJSON,
|
|
Validators: nil,
|
|
}
|
|
|
|
// generate empty genesis files for each validator and save
|
|
for i := 0; i < cfg.NumValidators; i++ {
|
|
if err := genDoc.SaveAs(genFiles[i]); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func writeFile(name string, dir string, contents []byte) error {
|
|
writePath := filepath.Join(dir)
|
|
file := filepath.Join(writePath, name)
|
|
|
|
err := tmos.EnsureDir(writePath, 0755)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = tmos.WriteFile(file, contents, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|