-
Notifications
You must be signed in to change notification settings - Fork 210
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(testutil): implement custom testnet config
Signed-off-by: Artur Troian <troian.ap@gmail.com>
- Loading branch information
Showing
11 changed files
with
751 additions
and
39 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
package network | ||
|
||
import ( | ||
"encoding/json" | ||
"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/server/api" | ||
servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" | ||
srvtypes "github.com/cosmos/cosmos-sdk/server/types" | ||
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 | ||
|
||
if err := val.AppConfig.ValidateBasic(); err != nil { | ||
return err | ||
} | ||
|
||
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) | ||
} | ||
|
||
// We'll need an RPC client if the validator exposes a gRPC or REST endpoint. | ||
if val.APIAddress != "" || val.AppConfig.GRPC.Enable { | ||
val.ClientCtx = val.ClientCtx. | ||
WithClient(val.RPCClient) | ||
|
||
app.RegisterTxService(val.ClientCtx) | ||
app.RegisterTendermintService(val.ClientCtx) | ||
|
||
if a, ok := app.(srvtypes.ApplicationQueryService); ok { | ||
a.RegisterNodeService(val.ClientCtx) | ||
} | ||
} | ||
|
||
if val.APIAddress != "" { | ||
apiSrv := api.New(val.ClientCtx, logger.With("module", "api-server")) | ||
app.RegisterAPIRoutes(apiSrv, val.AppConfig.API) | ||
|
||
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(srvtypes.ServerStartTime): // assume server started successfully | ||
} | ||
|
||
val.api = apiSrv | ||
} | ||
|
||
if val.AppConfig.GRPC.Enable { | ||
grpcSrv, err := servergrpc.StartGRPCServer(val.ClientCtx, app, val.AppConfig.GRPC.Address) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
val.grpc = grpcSrv | ||
|
||
if val.AppConfig.GRPCWeb.Enable { | ||
val.grpcWeb, err = servergrpc.StartGRPCWeb(grpcSrv, *val.AppConfig) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
|
||
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, cfg.TxConfig, | ||
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) | ||
|
||
accounts, err := authtypes.PackAccounts(genAccounts) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
authGenState.Accounts = append(authGenState.Accounts, accounts...) | ||
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 = append(bankGenState.Balances, genBalances...) | ||
cfg.GenesisState[banktypes.ModuleName] = cfg.Codec.MustMarshalJSON(&bankGenState) | ||
|
||
appGenStateJSON, err := json.MarshalIndent(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) //nolint:gocritic | ||
file := filepath.Join(writePath, name) | ||
|
||
err := tmos.EnsureDir(writePath, 0o755) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = tmos.WriteFile(file, contents, 0o644) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.