diff --git a/.github/scripts/go-imports.sh b/.github/scripts/go-imports.sh deleted file mode 100755 index bc5e6db3f86..00000000000 --- a/.github/scripts/go-imports.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -formatted_files="$(docker run -v "$(pwd)":/ibc-go --rm -w "/ibc-go" --entrypoint="" cytopia/goimports goimports -l -local 'github.com/cosmos/ibc-go' /ibc-go)" - -exit_code=0 -for f in $formatted_files -do - # we don't care about formatting in pb.go files. - if [ "${f: -5}" == "pb.go" ]; then - continue - fi - exit_code=1 - echo "formatted file ${f}..." -done - -if [ "${exit_code}" == 1 ]; then - echo "not all files were correctly formated, run the following:" - echo "make goimports" -fi - -exit $exit_code diff --git a/.github/workflows/goimports.yaml b/.github/workflows/goimports.yaml deleted file mode 100644 index b951b17aa1d..00000000000 --- a/.github/workflows/goimports.yaml +++ /dev/null @@ -1,9 +0,0 @@ -name: Goimports -on: pull_request -jobs: - goimports: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: "Go Imports" - run: .github/scripts/go-imports.sh diff --git a/Dockerfile b/Dockerfile index a193f54906e..3c6d2bd6094 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ ADD testing testing ADD modules modules ADD LICENSE LICENSE +COPY contrib/devtools/Makefile contrib/devtools/Makefile COPY Makefile . RUN make build diff --git a/Makefile b/Makefile index a92b39e0c52..9311b6b80a6 100644 --- a/Makefile +++ b/Makefile @@ -96,7 +96,7 @@ endif all: build lint test # The below include contains the tools and runsim targets. -#include contrib/devtools/Makefile +include contrib/devtools/Makefile ############################################################################### ### Build ### @@ -114,47 +114,7 @@ $(BUILD_TARGETS): go.sum $(BUILDDIR)/ $(BUILDDIR)/: mkdir -p $(BUILDDIR)/ -build-simd-all: go.sum - $(DOCKER) rm latest-build || true - $(DOCKER) run --volume=$(CURDIR):/sources:ro \ - --env TARGET_PLATFORMS='linux/amd64 darwin/amd64 linux/arm64 windows/amd64' \ - --env APP=simd \ - --env VERSION=$(VERSION) \ - --env COMMIT=$(COMMIT) \ - --env LEDGER_ENABLED=$(LEDGER_ENABLED) \ - --name latest-build cosmossdk/rbuilder:latest - $(DOCKER) cp -a latest-build:/home/builder/artifacts/ $(CURDIR)/ - -build-simd-linux: go.sum $(BUILDDIR)/ - $(DOCKER) rm latest-build || true - $(DOCKER) run --volume=$(CURDIR):/sources:ro \ - --env TARGET_PLATFORMS='linux/amd64' \ - --env APP=simd \ - --env VERSION=$(VERSION) \ - --env COMMIT=$(COMMIT) \ - --env LEDGER_ENABLED=false \ - --name latest-build cosmossdk/rbuilder:latest - $(DOCKER) cp -a latest-build:/home/builder/artifacts/ $(CURDIR)/ - cp artifacts/simd-*-linux-amd64 $(BUILDDIR)/simd - -cosmovisor: - $(MAKE) -C cosmovisor cosmovisor - -.PHONY: build build-linux build-simd-all build-simd-linux cosmovisor - -mocks: $(MOCKS_DIR) - mockgen -source=client/account_retriever.go -package mocks -destination tests/mocks/account_retriever.go - mockgen -package mocks -destination tests/mocks/tendermint_tm_db_DB.go github.com/tendermint/tm-db DB - mockgen -source=types/module/module.go -package mocks -destination tests/mocks/types_module_module.go - mockgen -source=types/invariant.go -package mocks -destination tests/mocks/types_invariant.go - mockgen -source=types/router.go -package mocks -destination tests/mocks/types_router.go - mockgen -source=types/handler.go -package mocks -destination tests/mocks/types_handler.go - mockgen -package mocks -destination tests/mocks/grpc_server.go github.com/gogo/protobuf/grpc Server - mockgen -package mocks -destination tests/mocks/tendermint_tendermint_libs_log_DB.go github.com/tendermint/tendermint/libs/log Logger -.PHONY: mocks - -$(MOCKS_DIR): - mkdir -p $(MOCKS_DIR) +.PHONY: build build-linux distclean: clean clean: @@ -179,7 +139,7 @@ go.sum: go.mod ############################################################################### update-swagger-docs: statik - $(BINDIR)/statik -src=client/docs/swagger-ui -dest=client/docs -f -m + $(BINDIR)/statik -src=docs/client/swagger-ui -dest=docs/client -f -m @if [ -n "$(git status --porcelain)" ]; then \ echo "\033[91mSwagger docs are out of sync!!!\033[0m";\ exit 1;\ @@ -318,11 +278,6 @@ test-cover: @export VERSION=$(VERSION); bash -x contrib/test_cover.sh .PHONY: test-cover -test-rosetta: - docker build -t rosetta-ci:latest -f contrib/rosetta/node/Dockerfile . - docker-compose -f contrib/rosetta/docker-compose.yaml up --abort-on-container-exit --exit-code-from test_rosetta --build -.PHONY: test-rosetta - benchmark: @go test -mod=readonly -bench=. $(PACKAGES_NOSIMULATION) .PHONY: benchmark @@ -338,43 +293,11 @@ lint-fix: golangci-lint run --fix --out-format=tab --issues-exit-code=0 .PHONY: lint lint-fix -format: goimports - find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' -not -name '*.pb.gw.go' | xargs gofumpt -w - find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' -not -name '*.pb.gw.go' | xargs misspell -w +format: + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./docs/client/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' -not -name '*.pb.gw.go' | xargs gofumpt -w + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./docs/client/statik/statik.go" -not -path "./tests/mocks/*" -not -name '*.pb.go' -not -name '*.pb.gw.go' | xargs misspell -w .PHONY: format -goimports: - $(DOCKER) run -v $(CURDIR):/ibc-go --rm -w "/ibc-go" cytopia/goimports -w -local 'github.com/cosmos/ibc-go' "$(CHANGED_GO_FILES)" &> /dev/null || echo "No changed go files to format" - -goimports-all: - $(DOCKER) run -v $(CURDIR):/ibc-go --rm -w "/ibc-go" cytopia/goimports -w -local 'github.com/cosmos/ibc-go' "$(ALL_GO_FILES)" - -############################################################################### -### Devdoc ### -############################################################################### - -DEVDOC_SAVE = docker commit `docker ps -a -n 1 -q` devdoc:local - -devdoc-init: - $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/cosmos/cosmos-sdk" -w "/go/src/github.com/cosmos/cosmos-sdk" tendermint/devdoc echo - # TODO make this safer - $(call DEVDOC_SAVE) - -devdoc: - $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/cosmos/cosmos-sdk" -w "/go/src/github.com/cosmos/cosmos-sdk" devdoc:local bash - -devdoc-save: - # TODO make this safer - $(call DEVDOC_SAVE) - -devdoc-clean: - docker rmi -f $$(docker images -f "dangling=true" -q) - -devdoc-update: - docker pull tendermint/devdoc - -.PHONY: devdoc devdoc-clean devdoc-init devdoc-save devdoc-update - ############################################################################### ### Protobuf ### ############################################################################### @@ -466,36 +389,3 @@ proto-update-deps: @perl -lp -i -e 'print q(option go_package = "github.com/confio/ics23/go";) if $$. == 4' $(CONFIO_TYPES)/proofs.proto .PHONY: proto-all proto-gen proto-gen-any proto-swagger-gen proto-format proto-lint proto-check-breaking proto-update-deps - -############################################################################### -### Localnet ### -############################################################################### - -# Run a 4-node testnet locally -localnet-start: build-linux localnet-stop - $(if $(shell $(DOCKER) inspect -f '{{ .Id }}' cosmossdk/simd-env 2>/dev/null),$(info found image cosmossdk/simd-env),$(MAKE) -C contrib/images simd-env) - if ! [ -f build/node0/simd/config/genesis.json ]; then $(DOCKER) run --rm \ - --user $(shell id -u):$(shell id -g) \ - -v $(BUILDDIR):/simd:Z \ - -v /etc/group:/etc/group:ro \ - -v /etc/passwd:/etc/passwd:ro \ - -v /etc/shadow:/etc/shadow:ro \ - cosmossdk/simd-env testnet --v 4 -o . --starting-ip-address 192.168.10.2 --keyring-backend=test ; fi - docker-compose up -d - -localnet-stop: - docker-compose down - -.PHONY: localnet-start localnet-stop - -############################################################################### -### rosetta ### -############################################################################### -# builds rosetta test data dir -rosetta-data: - -docker container rm data_dir_build - docker build -t rosetta-ci:latest -f contrib/rosetta/node/Dockerfile . - docker run --name data_dir_build -t rosetta-ci:latest sh /rosetta/data.sh - docker cp data_dir_build:/tmp/data.tar.gz "$(CURDIR)/contrib/rosetta/node/data.tar.gz" - docker container rm data_dir_build -.PHONY: rosetta-data diff --git a/contrib/devtools/Makefile b/contrib/devtools/Makefile new file mode 100644 index 00000000000..dc9eb0c8e3b --- /dev/null +++ b/contrib/devtools/Makefile @@ -0,0 +1,76 @@ +### +# Find OS and Go environment +# GO contains the Go binary +# FS contains the OS file separator +### +ifeq ($(OS),Windows_NT) + GO := $(shell where go.exe 2> NUL) + FS := "\\" +else + GO := $(shell command -v go 2> /dev/null) + FS := "/" +endif + +ifeq ($(GO),) + $(error could not find go. Is it in PATH? $(GO)) +endif + +############################################################################### +### Functions ### +############################################################################### + +go_get = $(if $(findstring Windows_NT,$(OS)),\ +IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS) ( mkdir $(GITHUBDIR)$(FS)$(1) ) else (cd .) &\ +IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS)$(2)$(FS) ( cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2) ) else (cd .) &\ +,\ +mkdir -p $(GITHUBDIR)$(FS)$(1) &&\ +(test ! -d $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2)) || true &&\ +)\ +cd $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && git fetch origin && git checkout -q $(3) + +mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) +mkfile_dir := $(shell cd $(shell dirname $(mkfile_path)); pwd) + + +############################################################################### +### Tools ### +############################################################################### + +PREFIX ?= /usr/local +BIN ?= $(PREFIX)/bin +UNAME_S ?= $(shell uname -s) +UNAME_M ?= $(shell uname -m) + +GOPATH ?= $(shell $(GO) env GOPATH) +GITHUBDIR := $(GOPATH)$(FS)src$(FS)github.com + +BUF_VERSION ?= 0.11.0 + +TOOLS_DESTDIR ?= $(GOPATH)/bin +STATIK = $(TOOLS_DESTDIR)/statik +RUNSIM = $(TOOLS_DESTDIR)/runsim + +tools: tools-stamp +tools-stamp: statik runsim + # Create dummy file to satisfy dependency and avoid + # rebuilding when this Makefile target is hit twice + # in a row. + touch $@ + +# Install the runsim binary +statik: $(STATIK) +$(STATIK): + @echo "Installing statik..." + @go install github.com/rakyll/statik@v0.1.6 + +# Install the runsim binary +runsim: $(RUNSIM) +$(RUNSIM): + @echo "Installing runsim..." + @go install github.com/cosmos/tools/cmd/runsim@v1.0.0 + +tools-clean: + rm -f $(STATIK) $(GOLANGCI_LINT) $(RUNSIM) + rm -f tools-stamp + +.PHONY: tools-clean statik runsim diff --git a/contrib/test_cover.sh b/contrib/test_cover.sh new file mode 100644 index 00000000000..24f7804b516 --- /dev/null +++ b/contrib/test_cover.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -e + +PKGS=$(go list ./... | grep -v '/simapp') + +set -e +echo "mode: atomic" > coverage.txt +for pkg in ${PKGS[@]}; do + go test -v -timeout 30m -race -coverprofile=profile.out -covermode=atomic -tags='ledger test_ledger_mock' "$pkg" + if [ -f profile.out ]; then + tail -n +2 profile.out >> coverage.txt; + rm profile.out + fi +done diff --git a/testing/simapp/simd/cmd/root.go b/testing/simapp/simd/cmd/root.go index da5e8134386..fdb52105b76 100644 --- a/testing/simapp/simd/cmd/root.go +++ b/testing/simapp/simd/cmd/root.go @@ -16,6 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/server" serverconfig "github.com/cosmos/cosmos-sdk/server/config" servertypes "github.com/cosmos/cosmos-sdk/server/types" + sdkcmd "github.com/cosmos/cosmos-sdk/simapp/simd/cmd" "github.com/cosmos/cosmos-sdk/snapshots" snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" "github.com/cosmos/cosmos-sdk/store" @@ -164,7 +165,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { genutilcli.ValidateGenesisCmd(simapp.ModuleBasics), AddGenesisAccountCmd(simapp.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), - testnetCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}), + sdkcmd.NewTestnetCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}), debug.Cmd(), config.Cmd(), ) diff --git a/testing/simapp/simd/cmd/testnet.go b/testing/simapp/simd/cmd/testnet.go deleted file mode 100644 index ae505599ad1..00000000000 --- a/testing/simapp/simd/cmd/testnet.go +++ /dev/null @@ -1,397 +0,0 @@ -package cmd - -// DONTCOVER - -import ( - "bufio" - "encoding/json" - "fmt" - "net" - "os" - "path/filepath" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keyring" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/cosmos/cosmos-sdk/server" - srvconfig "github.com/cosmos/cosmos-sdk/server/config" - "github.com/cosmos/cosmos-sdk/testutil" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - 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" - stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/spf13/cobra" - tmconfig "github.com/tendermint/tendermint/config" - tmos "github.com/tendermint/tendermint/libs/os" - tmrand "github.com/tendermint/tendermint/libs/rand" - "github.com/tendermint/tendermint/types" - tmtime "github.com/tendermint/tendermint/types/time" -) - -var ( - flagNodeDirPrefix = "node-dir-prefix" - flagNumValidators = "v" - flagOutputDir = "output-dir" - flagNodeDaemonHome = "node-daemon-home" - flagStartingIPAddress = "starting-ip-address" -) - -// get cmd to initialize all files for tendermint testnet and application -func testnetCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command { - cmd := &cobra.Command{ - Use: "testnet", - Short: "Initialize files for a simapp testnet", - Long: `testnet will create "v" number of directories and populate each with -necessary files (private validator, genesis, config, etc.). - -Note, strict routability for addresses is turned off in the config file. - -Example: - simd testnet --v 4 --output-dir ./output --starting-ip-address 192.168.10.2 - `, - RunE: func(cmd *cobra.Command, _ []string) error { - clientCtx, err := client.GetClientQueryContext(cmd) - if err != nil { - return err - } - - serverCtx := server.GetServerContextFromCmd(cmd) - config := serverCtx.Config - - outputDir, _ := cmd.Flags().GetString(flagOutputDir) - keyringBackend, _ := cmd.Flags().GetString(flags.FlagKeyringBackend) - chainID, _ := cmd.Flags().GetString(flags.FlagChainID) - minGasPrices, _ := cmd.Flags().GetString(server.FlagMinGasPrices) - nodeDirPrefix, _ := cmd.Flags().GetString(flagNodeDirPrefix) - nodeDaemonHome, _ := cmd.Flags().GetString(flagNodeDaemonHome) - startingIPAddress, _ := cmd.Flags().GetString(flagStartingIPAddress) - numValidators, _ := cmd.Flags().GetInt(flagNumValidators) - algo, _ := cmd.Flags().GetString(flags.FlagKeyAlgorithm) - - return InitTestnet( - clientCtx, cmd, config, mbm, genBalIterator, outputDir, chainID, minGasPrices, - nodeDirPrefix, nodeDaemonHome, startingIPAddress, keyringBackend, algo, numValidators, - ) - }, - } - - 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, "simd", "Home directory of the node's daemon 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, ...)") - cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") - cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)") - cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") - cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for") - - return cmd -} - -const nodeDirPerm = 0o755 - -// Initialize the testnet -func InitTestnet( - clientCtx client.Context, - cmd *cobra.Command, - nodeConfig *tmconfig.Config, - mbm module.BasicManager, - genBalIterator banktypes.GenesisBalancesIterator, - outputDir, - chainID, - minGasPrices, - nodeDirPrefix, - nodeDaemonHome, - startingIPAddress, - keyringBackend, - algoStr string, - numValidators int, -) error { - if chainID == "" { - chainID = "chain-" + tmrand.NewRand().Str(6) - } - - nodeIDs := make([]string, numValidators) - valPubKeys := make([]cryptotypes.PubKey, numValidators) - - simappConfig := srvconfig.DefaultConfig() - simappConfig.MinGasPrices = minGasPrices - simappConfig.API.Enable = true - simappConfig.Telemetry.Enabled = true - simappConfig.Telemetry.PrometheusRetentionTime = 60 - simappConfig.Telemetry.EnableHostnameLabel = false - simappConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", chainID}} - - var ( - genAccounts []authtypes.GenesisAccount - genBalances []banktypes.Balance - genFiles []string - ) - - inBuf := bufio.NewReader(cmd.InOrStdin()) - // generate private keys, node IDs, and initial transactions - for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) - nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) - gentxsDir := filepath.Join(outputDir, "gentxs") - - nodeConfig.SetRoot(nodeDir) - nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657" - - if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - nodeConfig.Moniker = nodeDirName - - ip, err := getIP(i, startingIPAddress) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip) - genFiles = append(genFiles, nodeConfig.GenesisFile()) - - kb, err := keyring.New(sdk.KeyringServiceName(), keyringBackend, nodeDir, inBuf, clientCtx.Codec) - if err != nil { - return err - } - - keyringAlgos, _ := kb.SupportedAlgorithms() - algo, err := keyring.NewSigningAlgoFromString(algoStr, keyringAlgos) - if err != nil { - return err - } - - addr, secret, err := testutil.GenerateSaveCoinKey(kb, nodeDirName, "test", true, algo) - if err != nil { - _ = os.RemoveAll(outputDir) - return err - } - - info := map[string]string{"secret": secret} - - cliPrint, err := json.Marshal(info) - if err != nil { - return err - } - - // save private key seed words - if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil { - return err - } - - accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction) - accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction) - coins := sdk.Coins{ - sdk.NewCoin(fmt.Sprintf("%stoken", nodeDirName), accTokens), - sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens), - } - - genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()}) - genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0)) - - valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction) - createValMsg, err := stakingtypes.NewMsgCreateValidator( - sdk.ValAddress(addr), - valPubKeys[i], - sdk.NewCoin(sdk.DefaultBondDenom, valTokens), - stakingtypes.NewDescription(nodeDirName, "", "", "", ""), - stakingtypes.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.OneDec()), - sdk.OneInt(), - ) - if err != nil { - return err - } - - txBuilder := clientCtx.TxConfig.NewTxBuilder() - if err := txBuilder.SetMsgs(createValMsg); err != nil { - return err - } - - txBuilder.SetMemo(memo) - - txFactory := tx.Factory{} - txFactory = txFactory. - WithChainID(chainID). - WithMemo(memo). - WithKeybase(kb). - WithTxConfig(clientCtx.TxConfig) - - if err := tx.Sign(txFactory, nodeDirName, txBuilder, true); err != nil { - return err - } - - txBz, err := clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx()) - if err != nil { - return err - } - - if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil { - return err - } - - srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), simappConfig) - } - - if err := initGenFiles(clientCtx, mbm, chainID, genAccounts, genBalances, genFiles, numValidators); err != nil { - return err - } - - err := collectGenFiles( - clientCtx, nodeConfig, chainID, nodeIDs, valPubKeys, numValidators, - outputDir, nodeDirPrefix, nodeDaemonHome, genBalIterator, - ) - if err != nil { - return err - } - - cmd.PrintErrf("Successfully initialized %d node directories\n", numValidators) - return nil -} - -func initGenFiles( - clientCtx client.Context, mbm module.BasicManager, chainID string, - genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance, - genFiles []string, numValidators int, -) error { - appGenState := mbm.DefaultGenesis(clientCtx.Codec) - - // set the accounts in the genesis state - var authGenState authtypes.GenesisState - clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState) - - accounts, err := authtypes.PackAccounts(genAccounts) - if err != nil { - return err - } - - authGenState.Accounts = accounts - appGenState[authtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&authGenState) - - // set the balances in the genesis state - var bankGenState banktypes.GenesisState - clientCtx.Codec.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState) - - bankGenState.Balances = genBalances - appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState) - - appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ") - if err != nil { - return err - } - - genDoc := types.GenesisDoc{ - ChainID: chainID, - AppState: appGenStateJSON, - Validators: nil, - } - - // 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( - clientCtx client.Context, nodeConfig *tmconfig.Config, chainID string, - nodeIDs []string, valPubKeys []cryptotypes.PubKey, numValidators int, - outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator, -) error { - var appState json.RawMessage - genTime := tmtime.Now() - - for i := 0; i < numValidators; i++ { - nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i) - nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome) - gentxsDir := filepath.Join(outputDir, "gentxs") - nodeConfig.Moniker = nodeDirName - - nodeConfig.SetRoot(nodeDir) - - nodeID, valPubKey := nodeIDs[i], valPubKeys[i] - initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey) - - genDoc, err := types.GenesisDocFromFile(nodeConfig.GenesisFile()) - if err != nil { - return err - } - - nodeAppState, err := genutil.GenAppStateFromConfig(clientCtx.Codec, clientCtx.TxConfig, nodeConfig, initCfg, *genDoc, genBalIterator) - if err != nil { - return err - } - - if appState == nil { - // set the canonical application state (they should not differ) - appState = nodeAppState - } - - genFile := nodeConfig.GenesisFile() - - // overwrite each validator's genesis file to have a canonical genesis time - if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil { - return err - } - } - - return nil -} - -func getIP(i int, startingIPAddr string) (ip string, err error) { - if len(startingIPAddr) == 0 { - ip, err = server.ExternalIP() - if err != nil { - return "", err - } - return ip, nil - } - return calculateIP(startingIPAddr, i) -} - -func calculateIP(ip string, i int) (string, error) { - ipv4 := net.ParseIP(ip).To4() - if ipv4 == nil { - return "", fmt.Errorf("%v: non ipv4 address", ip) - } - - for j := 0; j < i; j++ { - ipv4[3]++ - } - - return ipv4.String(), nil -} - -func writeFile(name string, dir string, contents []byte) error { - writePath := filepath.Dir(dir) - 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 -}