From 953cbb48e9c0b4a066dc8ef917170f476604a1eb Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Mon, 28 Oct 2024 15:49:47 +0530 Subject: [PATCH 1/9] WIP: remove testutil/network --- client/grpc/cmtservice/status_test.go | 34 ------------------ simapp/testutil_network_test.go | 43 ----------------------- tests/systemtests/cometbft_client_test.go | 11 ++++++ testutil/cli/tx.go | 28 --------------- 4 files changed, 11 insertions(+), 105 deletions(-) delete mode 100644 client/grpc/cmtservice/status_test.go delete mode 100644 simapp/testutil_network_test.go diff --git a/client/grpc/cmtservice/status_test.go b/client/grpc/cmtservice/status_test.go deleted file mode 100644 index d7bfa6bdc192..000000000000 --- a/client/grpc/cmtservice/status_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package cmtservice_test - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" - - "cosmossdk.io/depinject" - - "github.com/cosmos/cosmos-sdk/server" - clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" -) - -func TestStatusCommand(t *testing.T) { - t.Skip() // Rewrite as system test - - cfg, err := network.DefaultConfigWithAppConfig(depinject.Configs() /* TODO, test skipped anyway */) - require.NoError(t, err) - - network, err := network.New(t, t.TempDir(), cfg) - require.NoError(t, err) - require.NoError(t, network.WaitForNextBlock()) - - val0 := network.GetValidators()[0] - cmd := server.StatusCommand() - - out, err := clitestutil.ExecTestCLICmd(val0.GetClientCtx(), cmd, []string{}) - require.NoError(t, err) - - // Make sure the output has the validator moniker. - require.Contains(t, out.String(), fmt.Sprintf("\"moniker\":\"%s\"", val0.GetMoniker())) -} diff --git a/simapp/testutil_network_test.go b/simapp/testutil_network_test.go deleted file mode 100644 index 6d551b1dfd47..000000000000 --- a/simapp/testutil_network_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package simapp_test - -import ( - "testing" - "time" - - "github.com/stretchr/testify/suite" - - "cosmossdk.io/simapp" - - "github.com/cosmos/cosmos-sdk/testutil/network" -) - -type IntegrationTestSuite struct { - suite.Suite - - network network.NetworkI -} - -func (s *IntegrationTestSuite) SetupSuite() { - s.T().Log("setting up integration test suite") - - var err error - s.network, err = network.New(s.T(), s.T().TempDir(), network.DefaultConfig(simapp.NewTestNetworkFixture)) - s.Require().NoError(err) - - h, err := s.network.WaitForHeight(1) - s.Require().NoError(err, "stalled at height %d", h) -} - -func (s *IntegrationTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -func (s *IntegrationTestSuite) TestNetwork_Liveness() { - h, err := s.network.WaitForHeightWithTimeout(10, time.Minute) - s.Require().NoError(err, "expected to reach 10 blocks; got %d", h) -} - -func TestIntegrationTestSuite(t *testing.T) { - suite.Run(t, new(IntegrationTestSuite)) -} diff --git a/tests/systemtests/cometbft_client_test.go b/tests/systemtests/cometbft_client_test.go index cee97baa0c61..81ae571543c7 100644 --- a/tests/systemtests/cometbft_client_test.go +++ b/tests/systemtests/cometbft_client_test.go @@ -20,6 +20,17 @@ import ( qtypes "github.com/cosmos/cosmos-sdk/types/query" ) +func TestQueryStatus(t *testing.T) { + sut.ResetChain(t) + cli := NewCLIWrapper(t, sut, verbose) + sut.StartChain(t) + + resp := cli.CustomQuery("status") + + // make sure the output has the validator moniker. + assert.Contains(t, resp, "\"moniker\":\"node0\"") +} + func TestQueryNodeInfo(t *testing.T) { baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart) sut.ResetChain(t) diff --git a/testutil/cli/tx.go b/testutil/cli/tx.go index 73f0f8867670..686817d5fd08 100644 --- a/testutil/cli/tx.go +++ b/testutil/cli/tx.go @@ -10,34 +10,6 @@ import ( authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli" ) -// CheckTxCode verifies that the transaction result returns a specific code -// Takes a network, wait for two blocks and fetch the transaction from its hash -func CheckTxCode(network network.NetworkI, clientCtx client.Context, txHash string, expectedCode uint32) error { - // wait for 2 blocks - for i := 0; i < 2; i++ { - if err := network.WaitForNextBlock(); err != nil { - return fmt.Errorf("failed to wait for next block: %w", err) - } - } - - cmd := authcli.QueryTxCmd() - out, err := ExecTestCLICmd(clientCtx, cmd, []string{txHash, fmt.Sprintf("--%s=json", flags.FlagOutput)}) - if err != nil { - return err - } - - var response sdk.TxResponse - if err := clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response); err != nil { - return err - } - - if response.Code != expectedCode { - return fmt.Errorf("expected code %d, got %d", expectedCode, response.Code) - } - - return nil -} - // GetTxResponse returns queries the transaction response of a transaction from its hash // Takes a network, wait for two blocks and fetch the transaction from its hash func GetTxResponse(network network.NetworkI, clientCtx client.Context, txHash string) (sdk.TxResponse, error) { From 2e4f4d40bf014678118ecb706a6a74bee2e901a2 Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Tue, 29 Oct 2024 16:40:11 +0530 Subject: [PATCH 2/9] remove network from start testnet command --- simapp/simd/cmd/testnet.go | 285 ++++++++++++++++++++++++++++--------- 1 file changed, 217 insertions(+), 68 deletions(-) diff --git a/simapp/simd/cmd/testnet.go b/simapp/simd/cmd/testnet.go index b7199b4cbafa..15aa18c132b8 100644 --- a/simapp/simd/cmd/testnet.go +++ b/simapp/simd/cmd/testnet.go @@ -4,9 +4,15 @@ import ( "bufio" "encoding/json" "fmt" + "io" "net" + "net/url" "os" + "os/exec" + "os/signal" "path/filepath" + "strconv" + "strings" "time" cmtconfig "github.com/cometbft/cometbft/config" @@ -16,7 +22,6 @@ import ( "cosmossdk.io/math" "cosmossdk.io/math/unsafe" - "cosmossdk.io/simapp" banktypes "cosmossdk.io/x/bank/types" stakingtypes "cosmossdk.io/x/staking/types" @@ -29,7 +34,6 @@ import ( "github.com/cosmos/cosmos-sdk/server" srvconfig "github.com/cosmos/cosmos-sdk/server/config" "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" @@ -53,6 +57,15 @@ var ( flagStakingDenom = "staking-denom" flagCommitTimeout = "commit-timeout" flagSingleHost = "single-host" + + // default values + defaultRPCPort = 26657 + defaultAPIPort = 1317 + defaultGRPCPort = 9090 + defaultListenIPAddress = "127.0.0.1" + defaultStartingIPAddress = "192.168.0.1" + defaultNodeDirPrefix = "node" + defaultNodeDaemonHome = "simd" ) type initArgs struct { @@ -68,20 +81,15 @@ type initArgs struct { listenIPAddress string singleMachine bool bondTokenDenom string -} -type startArgs struct { - algo string - apiAddress string - chainID string - enableLogging bool - grpcAddress string - minGasPrices string - numValidators int - outputDir string - printMnemonic bool - rpcAddress string - timeoutCommit time.Duration + // start command arguments + apiListenAddress string + grpcListenAddress string + rpcPort int + apiPort int + grpcPort int + enableLogging bool + printMnemonic bool } func addTestnetFlagsToCmd(cmd *cobra.Command) { @@ -112,7 +120,7 @@ func NewTestnetCmd(mm *module.Manager) *cobra.Command { RunE: client.ValidateCmd, } - testnetCmd.AddCommand(testnetStartCmd()) + testnetCmd.AddCommand(testnetStartCmd(mm)) testnetCmd.AddCommand(testnetInitFilesCmd(mm)) return testnetCmd @@ -142,7 +150,13 @@ Example: config := client.GetConfigFromCmd(cmd) - args := initArgs{} + args := initArgs{ + rpcPort: defaultRPCPort, + apiPort: defaultAPIPort, + grpcPort: defaultGRPCPort, + apiListenAddress: defaultListenIPAddress, + grpcListenAddress: defaultListenIPAddress, + } args.outputDir, _ = cmd.Flags().GetString(flagOutputDir) args.keyringBackend, _ = cmd.Flags().GetString(flags.FlagKeyringBackend) args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID) @@ -160,15 +174,19 @@ Example: return err } + if args.chainID == "" { + args.chainID = "chain-" + unsafe.Str(6) + } + return initTestnetFiles(clientCtx, cmd, config, mm, args) }, } addTestnetFlagsToCmd(cmd) - cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix for the name of per-validator subdirectories (to be number-suffixed like 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(flagListenIPAddress, "127.0.0.1", "TCP or UNIX socket IP address for the RPC server to listen on") + cmd.Flags().String(flagNodeDirPrefix, defaultNodeDirPrefix, "Prefix for the name of per-validator subdirectories (to be number-suffixed like node0, node1, ...)") + cmd.Flags().String(flagNodeDaemonHome, defaultNodeDaemonHome, "Home directory of the node's daemon configuration") + cmd.Flags().String(flagStartingIPAddress, defaultStartingIPAddress, "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(flagListenIPAddress, defaultListenIPAddress, "TCP or UNIX socket IP address for the RPC server to listen on") cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)") cmd.Flags().Duration(flagCommitTimeout, 5*time.Second, "Time to wait after a block commit before starting on the new height") cmd.Flags().Bool(flagSingleHost, false, "Cluster runs on a single host machine with different ports") @@ -178,7 +196,7 @@ Example: } // testnetStartCmd returns a cmd to start multi validator in-process testnet -func testnetStartCmd() *cobra.Command { +func testnetStartCmd(mm *module.Manager) *cobra.Command { cmd := &cobra.Command{ Use: "start", Short: "Launch an in-process multi-validator testnet", @@ -190,19 +208,45 @@ Example: %s testnet --validator-count4 --output-dir ./.testnets `, version.AppName), RunE: func(cmd *cobra.Command, _ []string) (err error) { - args := startArgs{} + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + config := client.GetConfigFromCmd(cmd) + + args := initArgs{ + singleMachine: true, + bondTokenDenom: sdk.DefaultBondDenom, + nodeDaemonHome: defaultNodeDaemonHome, + nodeDirPrefix: defaultNodeDirPrefix, + keyringBackend: keyring.BackendTest, + } args.outputDir, _ = cmd.Flags().GetString(flagOutputDir) args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID) args.minGasPrices, _ = cmd.Flags().GetString(server.FlagMinGasPrices) args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators) args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType) args.enableLogging, _ = cmd.Flags().GetBool(flagEnableLogging) - args.rpcAddress, _ = cmd.Flags().GetString(flagRPCAddress) - args.apiAddress, _ = cmd.Flags().GetString(flagAPIAddress) - args.grpcAddress, _ = cmd.Flags().GetString(flagGRPCAddress) + rpcAddress, _ := cmd.Flags().GetString(flagRPCAddress) + args.listenIPAddress, args.rpcPort, err = parseURL(rpcAddress) + apiAddress, _ := cmd.Flags().GetString(flagAPIAddress) + args.apiListenAddress, args.apiPort, err = parseURL(apiAddress) + + grpcAddress, _ := cmd.Flags().GetString(flagGRPCAddress) + // add scheme to avoid issues with parsing + if !strings.Contains(grpcAddress, "://") { + grpcAddress = "tcp://" + grpcAddress + } + args.grpcListenAddress, args.grpcPort, err = parseURL(grpcAddress) + args.printMnemonic, _ = cmd.Flags().GetBool(flagPrintMnemonic) - return startTestnet(cmd, args) + if args.chainID == "" { + args.chainID = "chain-" + unsafe.Str(6) + } + + return startTestnet(clientCtx, cmd, config, mm, args) }, } @@ -215,6 +259,24 @@ Example: return cmd } +func parseURL(str string) (host string, port int, err error) { + u, err := url.Parse(str) + if err != nil { + return + } + + host = u.Hostname() + + portInt64, err := strconv.ParseInt(u.Port(), 10, 64) + if err != nil { + return + } + + port = int(portInt64) + + return +} + const nodeDirPerm = 0o755 // initTestnetFiles initializes testnet files for a testnet to be run in a separate process @@ -225,15 +287,13 @@ func initTestnetFiles( mm *module.Manager, args initArgs, ) error { - if args.chainID == "" { - args.chainID = "chain-" + unsafe.Str(6) - } nodeIDs := make([]string, args.numValidators) valPubKeys := make([]cryptotypes.PubKey, args.numValidators) appConfig := srvconfig.DefaultConfig() appConfig.MinGasPrices = args.minGasPrices appConfig.API.Enable = true + appConfig.GRPC.Enable = true appConfig.Telemetry.Enabled = true appConfig.Telemetry.PrometheusRetentionTime = 60 appConfig.Telemetry.EnableHostnameLabel = false @@ -244,10 +304,10 @@ func initTestnetFiles( genBalances []banktypes.Balance genFiles []string ) - const ( - rpcPort = 26657 - apiPort = 1317 - grpcPort = 9090 + var ( + rpcPort = args.rpcPort + apiPort = args.apiPort + grpcPort = args.grpcPort ) p2pPortStart := 26656 @@ -261,12 +321,11 @@ func initTestnetFiles( nodeConfig.P2P.AddrBookStrict = false nodeConfig.P2P.PexReactor = false nodeConfig.P2P.AllowDuplicateIP = true - appConfig.API.Address = fmt.Sprintf("tcp://127.0.0.1:%d", apiPort+portOffset) - appConfig.GRPC.Address = fmt.Sprintf("127.0.0.1:%d", grpcPort+portOffset) + appConfig.API.Address = fmt.Sprintf("tcp://%s:%d", args.apiListenAddress, apiPort+portOffset) + appConfig.GRPC.Address = fmt.Sprintf("%s:%d", args.grpcListenAddress, grpcPort+portOffset) } - nodeDirName := fmt.Sprintf("%s%d", args.nodeDirPrefix, i) - nodeDir := filepath.Join(args.outputDir, nodeDirName, args.nodeDaemonHome) + nodeDirName, nodeDir := getNodeDir(args, i) gentxsDir := filepath.Join(args.outputDir, "gentxs") nodeConfig.SetRoot(nodeDir) @@ -317,6 +376,12 @@ func initTestnetFiles( return err } + // if PrintMnemonic is set to true, we print the first validator node's secret to the network's logger + // for debugging and manual testing + if args.printMnemonic && i == 0 { + printMnemonic(secret) + } + info := map[string]string{"secret": secret} cliPrint, err := json.Marshal(info) @@ -552,46 +617,130 @@ func writeFile(name, dir string, contents []byte) error { return os.WriteFile(file, contents, 0o600) } -// startTestnet starts an in-process testnet -func startTestnet(cmd *cobra.Command, args startArgs) error { - networkConfig := network.DefaultConfig(simapp.NewTestNetworkFixture) +// printMnemonic prints a provided mnemonic seed phrase on a network logger +// for debugging and manual testing +func printMnemonic(secret string) { + lines := []string{ + "THIS MNEMONIC IS FOR TESTING PURPOSES ONLY", + "DO NOT USE IN PRODUCTION", + "", + strings.Join(strings.Fields(secret)[0:8], " "), + strings.Join(strings.Fields(secret)[8:16], " "), + strings.Join(strings.Fields(secret)[16:24], " "), + } - // Default networkConfig.ChainID is random, and we should only override it if chainID provided - // is non-empty - if args.chainID != "" { - networkConfig.ChainID = args.chainID + lineLengths := make([]int, len(lines)) + for i, line := range lines { + lineLengths[i] = len(line) } - networkConfig.SigningAlgo = args.algo - networkConfig.MinGasPrices = args.minGasPrices - networkConfig.NumValidators = args.numValidators - networkConfig.EnableLogging = args.enableLogging - networkConfig.RPCAddress = args.rpcAddress - networkConfig.APIAddress = args.apiAddress - networkConfig.GRPCAddress = args.grpcAddress - networkConfig.PrintMnemonic = args.printMnemonic - networkConfig.TimeoutCommit = args.timeoutCommit - networkLogger := network.NewCLILogger(cmd) - - baseDir := fmt.Sprintf("%s/%s", args.outputDir, networkConfig.ChainID) - if _, err := os.Stat(baseDir); !os.IsNotExist(err) { - return fmt.Errorf( - "testnests directory already exists for chain-id '%s': %s, please remove or select a new --chain-id", - networkConfig.ChainID, baseDir) + + maxLineLength := 0 + for _, lineLen := range lineLengths { + if lineLen > maxLineLength { + maxLineLength = lineLen + } + } + + fmt.Printf("\n") + fmt.Printf(strings.Repeat("+", maxLineLength+8)) + for _, line := range lines { + fmt.Printf("++ %s ++\n", centerText(line, maxLineLength)) } + fmt.Printf(strings.Repeat("+", maxLineLength+8)) + fmt.Printf("\n") +} + +// centerText centers text across a fixed width, filling either side with whitespace buffers +func centerText(text string, width int) string { + textLen := len(text) + leftBuffer := strings.Repeat(" ", (width-textLen)/2) + rightBuffer := strings.Repeat(" ", (width-textLen)/2+(width-textLen)%2) + + return fmt.Sprintf("%s%s%s", leftBuffer, text, rightBuffer) +} - testnet, err := network.New(networkLogger, baseDir, networkConfig) +func getNodeDir(args initArgs, nodeID int) (nodeDirName, nodeDir string) { + nodeDirName = fmt.Sprintf("%s%d", args.nodeDirPrefix, nodeID) + nodeDir = filepath.Join(args.outputDir, nodeDirName, args.nodeDaemonHome) + return +} + +// startTestnet starts an in-process testnet +func startTestnet( + clientCtx client.Context, + cmd *cobra.Command, + nodeConfig *cmtconfig.Config, + mm *module.Manager, + args initArgs, +) error { + args.outputDir = fmt.Sprintf("%s/%s", args.outputDir, args.chainID) + err := initTestnetFiles(clientCtx, cmd, nodeConfig, mm, args) if err != nil { return err } - if _, err := testnet.WaitForHeight(1); err != nil { - return err + // slice to keep track of validator processes + var processes []*exec.Cmd + + // channel to signal shutdown + shutdownCh := make(chan struct{}) + + fmt.Println("Starting test network...") + // Start each validator in a separate process + for i := 0; i < args.numValidators; i++ { + _, nodeDir := getNodeDir(args, i) + + // run start command + cmdArgs := []string{"start", fmt.Sprintf("--%s=%s", flags.FlagHome, nodeDir)} + runCmd := exec.Command(os.Args[0], cmdArgs...) // spawn new process + + // Set stdout and stderr based on enableLogging flag + if args.enableLogging { + runCmd.Stdout = os.Stdout + runCmd.Stderr = os.Stderr + } else { + runCmd.Stdout = io.Discard // discard output when logging is disabled + runCmd.Stderr = io.Discard + } + + if err := runCmd.Start(); err != nil { + return fmt.Errorf("failed to start validator %d: %w", i, err) + } + fmt.Printf("Started Validator %d\n", i+1) + processes = append(processes, runCmd) // add to processes slice } - cmd.Println("press the Enter Key to terminate") - if _, err := fmt.Scanln(); err != nil { // wait for Enter Key - return err + + // goroutine to listen for Enter key press + go func() { + fmt.Println("Press the Enter Key to terminate all validator processes") + if _, err := fmt.Scanln(); err == nil { + close(shutdownCh) // Signal shutdown + } + }() + + // goroutine to listen for Ctrl+C (SIGINT) + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, os.Interrupt) + go func() { + <-sigCh // Wait for Ctrl+C + fmt.Println("\nCtrl+C detected, terminating validator processes...") + close(shutdownCh) // Signal shutdown + }() + + // block until shutdown signal is received + <-shutdownCh + + // terminate all validator processes + fmt.Println("Shutting down validator processes...") + for i, p := range processes { + if err := p.Process.Kill(); err != nil { + fmt.Printf("Failed to terminate validator %d process: %v\n", i+1, err) + } else { + fmt.Printf("Validator %d terminated\n", i+1) + } } - testnet.Cleanup() + _ = os.RemoveAll(args.outputDir) // Clean up the output directory + fmt.Println("Finished cleaning up test network") return nil } From c26ccbc6418604a6a56eb929a7d2d83cdd06cb73 Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Wed, 30 Oct 2024 11:05:55 +0530 Subject: [PATCH 3/9] updates --- simapp/simd/cmd/testnet.go | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/simapp/simd/cmd/testnet.go b/simapp/simd/cmd/testnet.go index 15aa18c132b8..7e637c5f1086 100644 --- a/simapp/simd/cmd/testnet.go +++ b/simapp/simd/cmd/testnet.go @@ -228,10 +228,18 @@ Example: args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators) args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType) args.enableLogging, _ = cmd.Flags().GetBool(flagEnableLogging) + rpcAddress, _ := cmd.Flags().GetString(flagRPCAddress) args.listenIPAddress, args.rpcPort, err = parseURL(rpcAddress) + if err != nil { + return fmt.Errorf("invalid rpc address: %w", err) + } + apiAddress, _ := cmd.Flags().GetString(flagAPIAddress) args.apiListenAddress, args.apiPort, err = parseURL(apiAddress) + if err != nil { + return fmt.Errorf("invalid api address: %w", err) + } grpcAddress, _ := cmd.Flags().GetString(flagGRPCAddress) // add scheme to avoid issues with parsing @@ -239,6 +247,9 @@ Example: grpcAddress = "tcp://" + grpcAddress } args.grpcListenAddress, args.grpcPort, err = parseURL(grpcAddress) + if err != nil { + return fmt.Errorf("invalid grpc address: %w", err) + } args.printMnemonic, _ = cmd.Flags().GetBool(flagPrintMnemonic) @@ -267,13 +278,7 @@ func parseURL(str string) (host string, port int, err error) { host = u.Hostname() - portInt64, err := strconv.ParseInt(u.Port(), 10, 64) - if err != nil { - return - } - - port = int(portInt64) - + port, err = strconv.Atoi(u.Port()) return } @@ -641,13 +646,13 @@ func printMnemonic(secret string) { } } - fmt.Printf("\n") - fmt.Printf(strings.Repeat("+", maxLineLength+8)) + fmt.Printf("\n\n") + fmt.Println(strings.Repeat("+", maxLineLength+8)) for _, line := range lines { fmt.Printf("++ %s ++\n", centerText(line, maxLineLength)) } - fmt.Printf(strings.Repeat("+", maxLineLength+8)) - fmt.Printf("\n") + fmt.Println(strings.Repeat("+", maxLineLength+8)) + fmt.Printf("\n\n") } // centerText centers text across a fixed width, filling either side with whitespace buffers @@ -673,6 +678,8 @@ func startTestnet( mm *module.Manager, args initArgs, ) error { + fmt.Printf(`Preparing test network with chain-id "%s"`, args.chainID) + args.outputDir = fmt.Sprintf("%s/%s", args.outputDir, args.chainID) err := initTestnetFiles(clientCtx, cmd, nodeConfig, mm, args) if err != nil { From ea71562000dbf84fa0b0f8350149dde8e68e73e7 Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Fri, 1 Nov 2024 12:42:13 +0530 Subject: [PATCH 4/9] remove network from few more files --- tests/integration/distribution/cli_tx_test.go | 19 ---------------- tests/integration/genutil/init_test.go | 22 +++++++++++++++++-- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/tests/integration/distribution/cli_tx_test.go b/tests/integration/distribution/cli_tx_test.go index 0eb26d978c2f..654feeea48ac 100644 --- a/tests/integration/distribution/cli_tx_test.go +++ b/tests/integration/distribution/cli_tx_test.go @@ -11,7 +11,6 @@ import ( sdkmath "cosmossdk.io/math" "cosmossdk.io/x/distribution/client/cli" - minttypes "cosmossdk.io/x/mint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -20,7 +19,6 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/testutil" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" - "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil" ) @@ -61,23 +59,6 @@ func (s *CLITestSuite) SetupSuite() { return s.baseCtx.WithClient(c) } s.clientCtx = ctxGen() - - cfg, err := network.DefaultConfigWithAppConfig(AppConfig) - s.Require().NoError(err) - - genesisState := cfg.GenesisState - var mintData minttypes.GenesisState - s.Require().NoError(cfg.Codec.UnmarshalJSON(genesisState[minttypes.ModuleName], &mintData)) - - inflation := sdkmath.LegacyMustNewDecFromStr("1.0") - mintData.Minter.Inflation = inflation - mintData.Params.InflationMin = inflation - mintData.Params.InflationMax = inflation - - mintDataBz, err := cfg.Codec.MarshalJSON(&mintData) - s.Require().NoError(err) - genesisState[minttypes.ModuleName] = mintDataBz - cfg.GenesisState = genesisState } func (s *CLITestSuite) TestTxWithdrawAllRewardsCmd() { diff --git a/tests/integration/genutil/init_test.go b/tests/integration/genutil/init_test.go index b49dbc6a7458..a1027a56fe1a 100644 --- a/tests/integration/genutil/init_test.go +++ b/tests/integration/genutil/init_test.go @@ -5,6 +5,7 @@ import ( "context" "fmt" "io" + "net" "os" "testing" "time" @@ -27,7 +28,6 @@ import ( servercmtlog "github.com/cosmos/cosmos-sdk/server/log" "github.com/cosmos/cosmos-sdk/server/mock" "github.com/cosmos/cosmos-sdk/testutil" - "github.com/cosmos/cosmos-sdk/testutil/network" genutilhelpers "github.com/cosmos/cosmos-sdk/testutil/x/genutil" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -220,7 +220,7 @@ func TestStartStandAlone(t *testing.T) { app, err := mock.NewApp(home, logger) require.NoError(t, err) - svrAddr, _, closeFn, err := network.FreeTCPAddr() + svrAddr, _, closeFn, err := freeTCPAddr() require.NoError(t, err) require.NoError(t, closeFn()) @@ -392,3 +392,21 @@ func writeAndTrackDefaultConfig(v *viper.Viper, home string) error { } return genutilhelpers.WriteAndTrackCometConfig(v, home, cfg) } + +// Get a free address for a test CometBFT server +// protocol is either tcp, http, etc +func freeTCPAddr() (addr, port string, closeFn func() error, err error) { + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + return "", "", nil, err + } + + closeFn = func() error { + return l.Close() + } + + portI := l.Addr().(*net.TCPAddr).Port + port = fmt.Sprintf("%d", portI) + addr = fmt.Sprintf("tcp://127.0.0.1:%s", port) + return +} From a9950dcafda54586793b3cdfb9450a7a78f3d0ca Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Mon, 4 Nov 2024 17:43:35 +0530 Subject: [PATCH 5/9] WIP: replace network --- .../server/grpc/out_of_gas_test.go | 149 ++++++++++++++---- 1 file changed, 116 insertions(+), 33 deletions(-) diff --git a/tests/integration/server/grpc/out_of_gas_test.go b/tests/integration/server/grpc/out_of_gas_test.go index eabd41fc754d..ae5144959012 100644 --- a/tests/integration/server/grpc/out_of_gas_test.go +++ b/tests/integration/server/grpc/out_of_gas_test.go @@ -5,70 +5,155 @@ import ( "fmt" "testing" + minttypes "cosmossdk.io/x/mint/types" "github.com/stretchr/testify/suite" + "go.uber.org/mock/gomock" "google.golang.org/grpc" "google.golang.org/grpc/metadata" + "cosmossdk.io/core/appmodule" + "cosmossdk.io/log" _ "cosmossdk.io/x/accounts" + "cosmossdk.io/x/bank" _ "cosmossdk.io/x/bank" + "cosmossdk.io/x/bank/keeper" + bankkeeper "cosmossdk.io/x/bank/keeper" banktypes "cosmossdk.io/x/bank/types" _ "cosmossdk.io/x/consensus" _ "cosmossdk.io/x/staking" + storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/testutil/configurator" - "github.com/cosmos/cosmos-sdk/testutil/network" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" + codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil" + "github.com/cosmos/cosmos-sdk/runtime" + srvconfig "github.com/cosmos/cosmos-sdk/server/config" + servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" + "github.com/cosmos/cosmos-sdk/testutil/integration" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + "github.com/cosmos/cosmos-sdk/x/auth" _ "github.com/cosmos/cosmos-sdk/x/auth" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" + authtestutil "github.com/cosmos/cosmos-sdk/x/auth/testutil" _ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) type IntegrationTestOutOfGasSuite struct { suite.Suite - - cfg network.Config - network network.NetworkI + ctx context.Context conn *grpc.ClientConn + address sdk.AccAddress } func (s *IntegrationTestOutOfGasSuite) SetupSuite() { - var err error s.T().Log("setting up integration test suite") - s.cfg, err = network.DefaultConfigWithAppConfig(configurator.NewAppConfig( - configurator.AccountsModule(), - configurator.AuthModule(), - configurator.BankModule(), - configurator.GenutilModule(), - configurator.StakingModule(), - configurator.ConsensusModule(), - configurator.TxModule(), - configurator.ValidateModule(), - ), baseapp.SetQueryGasLimit(10)) - s.NoError(err) - s.cfg.NumValidators = 1 - - s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg) - s.Require().NoError(err) + keys := storetypes.NewKVStoreKeys(authtypes.StoreKey, banktypes.StoreKey) + encodingCfg := moduletestutil.MakeTestEncodingConfig(codectestutil.CodecOptions{}, auth.AppModule{}, bank.AppModule{}) + cdc := encodingCfg.Codec + + logger := log.NewTestLogger(s.T()) + cms := integration.CreateMultiStore(keys, logger) + + newCtx := sdk.NewContext(cms, true, logger) + + authority := authtypes.NewModuleAddress("gov") + + maccPerms := map[string][]string{ + minttypes.ModuleName: {authtypes.Minter}, + } + + // gomock initializations + ctrl := gomock.NewController(s.T()) + acctsModKeeper := authtestutil.NewMockAccountsModKeeper(ctrl) + accNum := uint64(0) + acctsModKeeper.EXPECT().NextAccountNumber(gomock.Any()).AnyTimes().DoAndReturn(func(ctx context.Context) (uint64, error) { + currentNum := accNum + accNum++ + return currentNum, nil + }) + + accountKeeper := authkeeper.NewAccountKeeper( + runtime.NewEnvironment(runtime.NewKVStoreService(keys[authtypes.StoreKey]), log.NewNopLogger()), + cdc, + authtypes.ProtoBaseAccount, + acctsModKeeper, + maccPerms, + addresscodec.NewBech32Codec(sdk.Bech32MainPrefix), + sdk.Bech32MainPrefix, + authority.String(), + ) - _, err = s.network.WaitForHeight(2) - s.Require().NoError(err) + blockedAddresses := map[string]bool{ + accountKeeper.GetAuthority(): false, + } + bankKeeper := bankkeeper.NewBaseKeeper( + runtime.NewEnvironment(runtime.NewKVStoreService(keys[banktypes.StoreKey]), log.NewNopLogger()), + cdc, + accountKeeper, + blockedAddresses, + authority.String(), + ) + + s.Require().NoError(bankKeeper.SetParams(newCtx, banktypes.DefaultParams())) + + authModule := auth.NewAppModule(cdc, accountKeeper, acctsModKeeper, authsims.RandomGenesisAccounts, nil) + bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper) + + integrationApp := integration.NewIntegrationApp(newCtx, logger, keys, cdc, + encodingCfg.InterfaceRegistry.SigningContext().AddressCodec(), + encodingCfg.InterfaceRegistry.SigningContext().ValidatorAddressCodec(), + map[string]appmodule.AppModule{ + authtypes.ModuleName: authModule, + banktypes.ModuleName: bankModule, + }, + baseapp.NewMsgServiceRouter(), + baseapp.NewGRPCQueryRouter(), + baseapp.SetQueryGasLimit(1), + ) - val0 := s.network.GetValidators()[0] + pubkeys := simtestutil.CreateTestPubKeys(1) + s.address = sdk.AccAddress(pubkeys[0].Address()) + sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context()) + + // mint some tokens + amount := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) + s.Require().NoError(bankKeeper.MintCoins(sdkCtx, minttypes.ModuleName, amount)) + + s.Require().NoError(bankKeeper.SendCoinsFromModuleToAccount(sdkCtx, minttypes.ModuleName, s.address, amount)) + + grpcSrv := grpc.NewServer(grpc.ForceServerCodec(codec.NewProtoCodec(encodingCfg.InterfaceRegistry).GRPCCodec())) + integrationApp.RegisterGRPCServer(grpcSrv) + grpcCfg := srvconfig.DefaultConfig().GRPC + go func() { + s.Require().NoError(servergrpc.StartGRPCServer(context.Background(), integrationApp.Logger(), grpcCfg, grpcSrv)) + }() + + // Register MsgServer and QueryServer + banktypes.RegisterQueryServer(grpcSrv, keeper.NewQuerier(&bankKeeper)) + testdata.RegisterQueryServer(grpcSrv, testdata.QueryImpl{}) + + var err error s.conn, err = grpc.NewClient( - val0.GetAppConfig().GRPC.Address, + grpcCfg.Address, grpc.WithInsecure(), //nolint:staticcheck // ignore SA1019, we don't need to use a secure connection for tests - grpc.WithDefaultCallOptions(grpc.ForceCodec(codec.NewProtoCodec(s.cfg.InterfaceRegistry).GRPCCodec())), + grpc.WithDefaultCallOptions(grpc.ForceCodec(codec.NewProtoCodec(encodingCfg.InterfaceRegistry).GRPCCodec())), ) s.Require().NoError(err) + s.ctx = context.WithValue(context.Background(), sdk.SdkContextKey, integrationApp.Context()) + fmt.Println("Ctx.........", s.ctx) } func (s *IntegrationTestOutOfGasSuite) TearDownSuite() { s.T().Log("tearing down integration test suite") s.conn.Close() - s.network.Cleanup() } func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_TestService() { @@ -80,17 +165,15 @@ func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_TestService() { } func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_BankBalance_OutOfGas() { - val0 := s.network.GetValidators()[0] - // gRPC query to bank service should work - denom := fmt.Sprintf("%stoken", val0.GetMoniker()) bankClient := banktypes.NewQueryClient(s.conn) var header metadata.MD - _, err := bankClient.Balance( - context.Background(), - &banktypes.QueryBalanceRequest{Address: val0.GetAddress().String(), Denom: denom}, + res, err := bankClient.Balance( + s.ctx, + &banktypes.QueryBalanceRequest{Address: s.address.String(), Denom: "stake"}, grpc.Header(&header), // Also fetch grpc header ) + fmt.Println("Res....", res) s.Require().ErrorContains(err, sdkerrors.ErrOutOfGas.Error()) } From 51b6a6558d76291d953c152b225a00a99d52c6f0 Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Wed, 6 Nov 2024 15:37:21 +0530 Subject: [PATCH 6/9] WIP: setup grpc server and fix issues --- .../auth/keeper/account_retriever_test.go | 52 +++++++++++------ tests/integration/auth/keeper/fixture_test.go | 6 +- .../server/grpc/out_of_gas_test.go | 57 +++++++------------ 3 files changed, 61 insertions(+), 54 deletions(-) diff --git a/tests/integration/auth/keeper/account_retriever_test.go b/tests/integration/auth/keeper/account_retriever_test.go index 68481cdebc5c..f3c7d763e902 100644 --- a/tests/integration/auth/keeper/account_retriever_test.go +++ b/tests/integration/auth/keeper/account_retriever_test.go @@ -1,45 +1,65 @@ package keeper_test import ( + "context" "testing" "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" - authTest "github.com/cosmos/cosmos-sdk/tests/integration/auth/keeper" - "github.com/cosmos/cosmos-sdk/testutil/network" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + srvconfig "github.com/cosmos/cosmos-sdk/server/config" + servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/types" ) func TestAccountRetriever(t *testing.T) { - cfg, err := network.DefaultConfigWithAppConfig(authTest.AppConfig) - require.NoError(t, err) - cfg.NumValidators = 1 + f := initFixture(t, nil) - network, err := network.New(t, t.TempDir(), cfg) - require.NoError(t, err) - defer network.Cleanup() + grpcSrv := grpc.NewServer(grpc.ForceServerCodec(codec.NewProtoCodec(f.encodingCfg.InterfaceRegistry).GRPCCodec())) + + types.RegisterQueryServer(f.app.GRPCQueryRouter(), keeper.NewQueryServer(f.authKeeper)) + f.app.RegisterGRPCServer(grpcSrv) - _, err = network.WaitForHeight(3) + grpcCfg := srvconfig.DefaultConfig().GRPC + + go func() { + require.NoError(t, servergrpc.StartGRPCServer(context.Background(), f.app.Logger(), grpcCfg, grpcSrv)) + }() + + conn, err := grpc.NewClient( + grpcCfg.Address, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithDefaultCallOptions(grpc.ForceCodec(codec.NewProtoCodec(f.encodingCfg.InterfaceRegistry).GRPCCodec())), + ) require.NoError(t, err) - val := network.GetValidators()[0] - clientCtx := val.GetClientCtx() + pubkeys := simtestutil.CreateTestPubKeys(1) + addr := sdk.AccAddress(pubkeys[0].Address()) + ar := types.AccountRetriever{} - clientCtx = clientCtx.WithHeight(2) + clientCtx := client.Context{}. + WithAccountRetriever(types.AccountRetriever{}). + WithGRPCClient(conn) - acc, err := ar.GetAccount(clientCtx, val.GetAddress()) + acc, err := ar.GetAccount(clientCtx, addr) require.NoError(t, err) require.NotNil(t, acc) - acc, height, err := ar.GetAccountWithHeight(clientCtx, val.GetAddress()) + acc, height, err := ar.GetAccountWithHeight(clientCtx, addr) require.NoError(t, err) require.NotNil(t, acc) require.Equal(t, height, int64(2)) - require.NoError(t, ar.EnsureExists(clientCtx, val.GetAddress())) + require.NoError(t, ar.EnsureExists(clientCtx, addr)) - accNum, accSeq, err := ar.GetAccountNumberSequence(clientCtx, val.GetAddress()) + accNum, accSeq, err := ar.GetAccountNumberSequence(clientCtx, addr) require.NoError(t, err) require.Equal(t, accNum, uint64(0)) require.Equal(t, accSeq, uint64(1)) diff --git a/tests/integration/auth/keeper/fixture_test.go b/tests/integration/auth/keeper/fixture_test.go index f8a2d10ba871..9c31f7837e89 100644 --- a/tests/integration/auth/keeper/fixture_test.go +++ b/tests/integration/auth/keeper/fixture_test.go @@ -35,8 +35,9 @@ import ( type fixture struct { app *integration.App - cdc codec.Codec - ctx sdk.Context + cdc codec.Codec + ctx sdk.Context + encodingCfg moduletestutil.TestEncodingConfig authKeeper authkeeper.AccountKeeper accountsKeeper accounts.Keeper @@ -140,5 +141,6 @@ func initFixture(t *testing.T, extraAccs map[string]accountstd.Interface) *fixtu accountsKeeper: accountsKeeper, authKeeper: authKeeper, bankKeeper: bankKeeper, + encodingCfg: encodingCfg, } } diff --git a/tests/integration/server/grpc/out_of_gas_test.go b/tests/integration/server/grpc/out_of_gas_test.go index ae5144959012..2763df217c0e 100644 --- a/tests/integration/server/grpc/out_of_gas_test.go +++ b/tests/integration/server/grpc/out_of_gas_test.go @@ -2,25 +2,19 @@ package grpc_test import ( "context" - "fmt" "testing" - minttypes "cosmossdk.io/x/mint/types" "github.com/stretchr/testify/suite" "go.uber.org/mock/gomock" "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" "cosmossdk.io/core/appmodule" "cosmossdk.io/log" - _ "cosmossdk.io/x/accounts" "cosmossdk.io/x/bank" - _ "cosmossdk.io/x/bank" - "cosmossdk.io/x/bank/keeper" bankkeeper "cosmossdk.io/x/bank/keeper" banktypes "cosmossdk.io/x/bank/types" - _ "cosmossdk.io/x/consensus" - _ "cosmossdk.io/x/staking" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -35,19 +29,19 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" "github.com/cosmos/cosmos-sdk/x/auth" - _ "github.com/cosmos/cosmos-sdk/x/auth" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authtestutil "github.com/cosmos/cosmos-sdk/x/auth/testutil" - _ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) type IntegrationTestOutOfGasSuite struct { suite.Suite - ctx context.Context + + grpcCtx context.Context conn *grpc.ClientConn address sdk.AccAddress } @@ -66,10 +60,6 @@ func (s *IntegrationTestOutOfGasSuite) SetupSuite() { authority := authtypes.NewModuleAddress("gov") - maccPerms := map[string][]string{ - minttypes.ModuleName: {authtypes.Minter}, - } - // gomock initializations ctrl := gomock.NewController(s.T()) acctsModKeeper := authtestutil.NewMockAccountsModKeeper(ctrl) @@ -85,7 +75,7 @@ func (s *IntegrationTestOutOfGasSuite) SetupSuite() { cdc, authtypes.ProtoBaseAccount, acctsModKeeper, - maccPerms, + map[string][]string{}, addresscodec.NewBech32Codec(sdk.Bech32MainPrefix), sdk.Bech32MainPrefix, authority.String(), @@ -116,39 +106,34 @@ func (s *IntegrationTestOutOfGasSuite) SetupSuite() { }, baseapp.NewMsgServiceRouter(), baseapp.NewGRPCQueryRouter(), - baseapp.SetQueryGasLimit(1), + baseapp.SetQueryGasLimit(10), ) pubkeys := simtestutil.CreateTestPubKeys(1) s.address = sdk.AccAddress(pubkeys[0].Address()) - sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context()) - - // mint some tokens - amount := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) - s.Require().NoError(bankKeeper.MintCoins(sdkCtx, minttypes.ModuleName, amount)) - - s.Require().NoError(bankKeeper.SendCoinsFromModuleToAccount(sdkCtx, minttypes.ModuleName, s.address, amount)) grpcSrv := grpc.NewServer(grpc.ForceServerCodec(codec.NewProtoCodec(encodingCfg.InterfaceRegistry).GRPCCodec())) + + // Register MsgServer and QueryServer + banktypes.RegisterQueryServer(integrationApp.GRPCQueryRouter(), bankkeeper.NewQuerier(&bankKeeper)) + testdata.RegisterQueryServer(integrationApp.GRPCQueryRouter(), testdata.QueryImpl{}) integrationApp.RegisterGRPCServer(grpcSrv) + grpcCfg := srvconfig.DefaultConfig().GRPC + go func() { s.Require().NoError(servergrpc.StartGRPCServer(context.Background(), integrationApp.Logger(), grpcCfg, grpcSrv)) }() - // Register MsgServer and QueryServer - banktypes.RegisterQueryServer(grpcSrv, keeper.NewQuerier(&bankKeeper)) - testdata.RegisterQueryServer(grpcSrv, testdata.QueryImpl{}) - var err error s.conn, err = grpc.NewClient( grpcCfg.Address, - grpc.WithInsecure(), //nolint:staticcheck // ignore SA1019, we don't need to use a secure connection for tests + grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions(grpc.ForceCodec(codec.NewProtoCodec(encodingCfg.InterfaceRegistry).GRPCCodec())), ) s.Require().NoError(err) - s.ctx = context.WithValue(context.Background(), sdk.SdkContextKey, integrationApp.Context()) - fmt.Println("Ctx.........", s.ctx) + + s.grpcCtx = metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, "1") } func (s *IntegrationTestOutOfGasSuite) TearDownSuite() { @@ -159,7 +144,9 @@ func (s *IntegrationTestOutOfGasSuite) TearDownSuite() { func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_TestService() { // gRPC query to test service should work testClient := testdata.NewQueryClient(s.conn) - testRes, err := testClient.Echo(context.Background(), &testdata.EchoRequest{Message: "hello"}) + testRes, err := testClient.Echo( + s.grpcCtx, + &testdata.EchoRequest{Message: "hello"}) s.Require().NoError(err) s.Require().Equal("hello", testRes.Message) } @@ -167,13 +154,11 @@ func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_TestService() { func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_BankBalance_OutOfGas() { // gRPC query to bank service should work bankClient := banktypes.NewQueryClient(s.conn) - var header metadata.MD - res, err := bankClient.Balance( - s.ctx, + + _, err := bankClient.Balance( + s.grpcCtx, &banktypes.QueryBalanceRequest{Address: s.address.String(), Denom: "stake"}, - grpc.Header(&header), // Also fetch grpc header ) - fmt.Println("Res....", res) s.Require().ErrorContains(err, sdkerrors.ErrOutOfGas.Error()) } From 5d0dc555b4334e8f41b419dbf288ca02a203493c Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Wed, 6 Nov 2024 19:59:11 +0530 Subject: [PATCH 7/9] fix issues --- .../auth/keeper/account_retriever_test.go | 23 +++++++++++++++++-- tests/integration/auth/keeper/fixture_test.go | 13 +++++++++++ .../server/grpc/out_of_gas_test.go | 19 +++++++++++---- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/tests/integration/auth/keeper/account_retriever_test.go b/tests/integration/auth/keeper/account_retriever_test.go index f3c7d763e902..c5dde42e37bf 100644 --- a/tests/integration/auth/keeper/account_retriever_test.go +++ b/tests/integration/auth/keeper/account_retriever_test.go @@ -4,6 +4,8 @@ import ( "context" "testing" + "cosmossdk.io/math" + minttypes "cosmossdk.io/x/mint/types" "github.com/stretchr/testify/require" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -16,6 +18,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/keeper" "github.com/cosmos/cosmos-sdk/x/auth/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) func TestAccountRetriever(t *testing.T) { @@ -39,14 +42,30 @@ func TestAccountRetriever(t *testing.T) { ) require.NoError(t, err) + defer conn.Close() + pubkeys := simtestutil.CreateTestPubKeys(1) addr := sdk.AccAddress(pubkeys[0].Address()) + newAcc := authtypes.BaseAccount{ + Address: addr.String(), + PubKey: nil, + AccountNumber: 2, + Sequence: 7, + } + + updatedAcc := f.authKeeper.NewAccount(f.ctx, &newAcc) + f.authKeeper.SetAccount(f.ctx, updatedAcc) + + amount := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(10000))) + require.NoError(t, f.bankKeeper.MintCoins(f.ctx, minttypes.ModuleName, amount)) + require.NoError(t, f.bankKeeper.SendCoinsFromModuleToAccount(f.ctx, minttypes.ModuleName, addr, amount)) + ar := types.AccountRetriever{} clientCtx := client.Context{}. - WithAccountRetriever(types.AccountRetriever{}). - WithGRPCClient(conn) + WithGRPCClient(conn). + WithAddressPrefix(sdk.Bech32MainPrefix) acc, err := ar.GetAccount(clientCtx, addr) require.NoError(t, err) diff --git a/tests/integration/auth/keeper/fixture_test.go b/tests/integration/auth/keeper/fixture_test.go index 9c31f7837e89..4cab23231915 100644 --- a/tests/integration/auth/keeper/fixture_test.go +++ b/tests/integration/auth/keeper/fixture_test.go @@ -18,6 +18,7 @@ import ( minttypes "cosmossdk.io/x/mint/types" "cosmossdk.io/x/tx/signing" + cmtabcitypes "github.com/cometbft/cometbft/api/cometbft/abci/v1" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" @@ -30,6 +31,7 @@ import ( authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/stretchr/testify/require" ) type fixture struct { @@ -134,6 +136,17 @@ func initFixture(t *testing.T, extraAccs map[string]accountstd.Interface) *fixtu banktypes.RegisterMsgServer(router, bankkeeper.NewMsgServerImpl(bankKeeper)) + // commit and finalize block + defer func() { + _, err := integrationApp.Commit() + if err != nil { + panic(err) + } + }() + height := integrationApp.LastBlockHeight() + 1 + _, err = integrationApp.FinalizeBlock(&cmtabcitypes.FinalizeBlockRequest{Height: height, DecidedLastCommit: cmtabcitypes.CommitInfo{Votes: []cmtabcitypes.VoteInfo{{}}}}) + require.NoError(t, err) + return &fixture{ app: integrationApp, cdc: cdc, diff --git a/tests/integration/server/grpc/out_of_gas_test.go b/tests/integration/server/grpc/out_of_gas_test.go index 2763df217c0e..5fc4b6e38500 100644 --- a/tests/integration/server/grpc/out_of_gas_test.go +++ b/tests/integration/server/grpc/out_of_gas_test.go @@ -8,7 +8,6 @@ import ( "go.uber.org/mock/gomock" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/metadata" "cosmossdk.io/core/appmodule" "cosmossdk.io/log" @@ -17,6 +16,7 @@ import ( banktypes "cosmossdk.io/x/bank/types" storetypes "cosmossdk.io/store/types" + cmtabcitypes "github.com/cometbft/cometbft/api/cometbft/abci/v1" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" @@ -29,7 +29,6 @@ import ( "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" "github.com/cosmos/cosmos-sdk/x/auth" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" @@ -133,7 +132,17 @@ func (s *IntegrationTestOutOfGasSuite) SetupSuite() { ) s.Require().NoError(err) - s.grpcCtx = metadata.AppendToOutgoingContext(context.Background(), grpctypes.GRPCBlockHeightHeader, "1") + // commit and finalize block + defer func() { + _, err := integrationApp.Commit() + if err != nil { + panic(err) + } + }() + + height := integrationApp.LastBlockHeight() + 1 + _, err = integrationApp.FinalizeBlock(&cmtabcitypes.FinalizeBlockRequest{Height: height, DecidedLastCommit: cmtabcitypes.CommitInfo{Votes: []cmtabcitypes.VoteInfo{{}}}}) + s.Require().NoError(err) } func (s *IntegrationTestOutOfGasSuite) TearDownSuite() { @@ -145,7 +154,7 @@ func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_TestService() { // gRPC query to test service should work testClient := testdata.NewQueryClient(s.conn) testRes, err := testClient.Echo( - s.grpcCtx, + context.Background(), &testdata.EchoRequest{Message: "hello"}) s.Require().NoError(err) s.Require().Equal("hello", testRes.Message) @@ -156,7 +165,7 @@ func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_BankBalance_OutOfGas() { bankClient := banktypes.NewQueryClient(s.conn) _, err := bankClient.Balance( - s.grpcCtx, + context.Background(), &banktypes.QueryBalanceRequest{Address: s.address.String(), Denom: "stake"}, ) From a01cf4851aaeb6534c1e9a3db9137e76acdaa728 Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Thu, 7 Nov 2024 15:17:48 +0530 Subject: [PATCH 8/9] update tests for some testing purpose --- .../server/grpc/out_of_gas_test.go | 54 ++++++++++++------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/tests/integration/server/grpc/out_of_gas_test.go b/tests/integration/server/grpc/out_of_gas_test.go index 5fc4b6e38500..48ae788277ea 100644 --- a/tests/integration/server/grpc/out_of_gas_test.go +++ b/tests/integration/server/grpc/out_of_gas_test.go @@ -2,6 +2,7 @@ package grpc_test import ( "context" + "fmt" "testing" "github.com/stretchr/testify/suite" @@ -16,7 +17,7 @@ import ( banktypes "cosmossdk.io/x/bank/types" storetypes "cosmossdk.io/store/types" - cmtabcitypes "github.com/cometbft/cometbft/api/cometbft/abci/v1" + minttypes "cosmossdk.io/x/mint/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" @@ -74,7 +75,7 @@ func (s *IntegrationTestOutOfGasSuite) SetupSuite() { cdc, authtypes.ProtoBaseAccount, acctsModKeeper, - map[string][]string{}, + map[string][]string{minttypes.ModuleName: {authtypes.Minter}}, addresscodec.NewBech32Codec(sdk.Bech32MainPrefix), sdk.Bech32MainPrefix, authority.String(), @@ -105,44 +106,55 @@ func (s *IntegrationTestOutOfGasSuite) SetupSuite() { }, baseapp.NewMsgServiceRouter(), baseapp.NewGRPCQueryRouter(), - baseapp.SetQueryGasLimit(10), + // baseapp.SetQueryGasLimit(10), ) - pubkeys := simtestutil.CreateTestPubKeys(1) + pubkeys := simtestutil.CreateTestPubKeys(2) s.address = sdk.AccAddress(pubkeys[0].Address()) + addr2 := sdk.AccAddress(pubkeys[1].Address()) - grpcSrv := grpc.NewServer(grpc.ForceServerCodec(codec.NewProtoCodec(encodingCfg.InterfaceRegistry).GRPCCodec())) + sdkCtx := sdk.UnwrapSDKContext(integrationApp.Context()) + + // mint some tokens + amount := sdk.NewCoins(sdk.NewInt64Coin("stake", 100)) + s.Require().NoError(bankKeeper.MintCoins(sdkCtx, minttypes.ModuleName, amount)) + s.Require().NoError(bankKeeper.SendCoinsFromModuleToAccount(sdkCtx, minttypes.ModuleName, addr2, amount)) // Register MsgServer and QueryServer + banktypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), bankkeeper.NewMsgServerImpl(bankKeeper)) banktypes.RegisterQueryServer(integrationApp.GRPCQueryRouter(), bankkeeper.NewQuerier(&bankKeeper)) testdata.RegisterQueryServer(integrationApp.GRPCQueryRouter(), testdata.QueryImpl{}) - integrationApp.RegisterGRPCServer(grpcSrv) + + banktypes.RegisterInterfaces(encodingCfg.InterfaceRegistry) grpcCfg := srvconfig.DefaultConfig().GRPC + msgSend := banktypes.MsgSend{ + FromAddress: addr2.String(), + ToAddress: s.address.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 50)), + } + + _, err := integrationApp.RunMsg( + &msgSend, + integration.WithAutomaticFinalizeBlock(), + integration.WithAutomaticCommit(), + ) + s.Require().NoError(err) + + grpcSrv := grpc.NewServer(grpc.ForceServerCodec(codec.NewProtoCodec(encodingCfg.InterfaceRegistry).GRPCCodec())) + integrationApp.RegisterGRPCServer(grpcSrv) + go func() { s.Require().NoError(servergrpc.StartGRPCServer(context.Background(), integrationApp.Logger(), grpcCfg, grpcSrv)) }() - var err error s.conn, err = grpc.NewClient( grpcCfg.Address, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultCallOptions(grpc.ForceCodec(codec.NewProtoCodec(encodingCfg.InterfaceRegistry).GRPCCodec())), ) s.Require().NoError(err) - - // commit and finalize block - defer func() { - _, err := integrationApp.Commit() - if err != nil { - panic(err) - } - }() - - height := integrationApp.LastBlockHeight() + 1 - _, err = integrationApp.FinalizeBlock(&cmtabcitypes.FinalizeBlockRequest{Height: height, DecidedLastCommit: cmtabcitypes.CommitInfo{Votes: []cmtabcitypes.VoteInfo{{}}}}) - s.Require().NoError(err) } func (s *IntegrationTestOutOfGasSuite) TearDownSuite() { @@ -164,11 +176,13 @@ func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_BankBalance_OutOfGas() { // gRPC query to bank service should work bankClient := banktypes.NewQueryClient(s.conn) - _, err := bankClient.Balance( + res, err := bankClient.Balance( context.Background(), &banktypes.QueryBalanceRequest{Address: s.address.String(), Denom: "stake"}, ) + fmt.Println("Res....", res) + s.Require().ErrorContains(err, sdkerrors.ErrOutOfGas.Error()) } From f623b96214d59945fa177f86fabc9953d79a537f Mon Sep 17 00:00:00 2001 From: akhilkumarpilli Date: Wed, 13 Nov 2024 19:12:54 +0530 Subject: [PATCH 9/9] cleanup and add testcase for testing --- .../server/grpc/out_of_gas_test.go | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/tests/integration/server/grpc/out_of_gas_test.go b/tests/integration/server/grpc/out_of_gas_test.go index 48ae788277ea..47d89019bc35 100644 --- a/tests/integration/server/grpc/out_of_gas_test.go +++ b/tests/integration/server/grpc/out_of_gas_test.go @@ -2,7 +2,6 @@ package grpc_test import ( "context" - "fmt" "testing" "github.com/stretchr/testify/suite" @@ -12,6 +11,7 @@ import ( "cosmossdk.io/core/appmodule" "cosmossdk.io/log" + "cosmossdk.io/math" "cosmossdk.io/x/bank" bankkeeper "cosmossdk.io/x/bank/keeper" banktypes "cosmossdk.io/x/bank/types" @@ -41,7 +41,6 @@ import ( type IntegrationTestOutOfGasSuite struct { suite.Suite - grpcCtx context.Context conn *grpc.ClientConn address sdk.AccAddress } @@ -124,29 +123,39 @@ func (s *IntegrationTestOutOfGasSuite) SetupSuite() { banktypes.RegisterMsgServer(integrationApp.MsgServiceRouter(), bankkeeper.NewMsgServerImpl(bankKeeper)) banktypes.RegisterQueryServer(integrationApp.GRPCQueryRouter(), bankkeeper.NewQuerier(&bankKeeper)) testdata.RegisterQueryServer(integrationApp.GRPCQueryRouter(), testdata.QueryImpl{}) - banktypes.RegisterInterfaces(encodingCfg.InterfaceRegistry) - grpcCfg := srvconfig.DefaultConfig().GRPC - - msgSend := banktypes.MsgSend{ - FromAddress: addr2.String(), - ToAddress: s.address.String(), - Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 50)), - } - _, err := integrationApp.RunMsg( - &msgSend, + &banktypes.MsgSend{ + FromAddress: addr2.String(), + ToAddress: s.address.String(), + Amount: sdk.NewCoins(sdk.NewInt64Coin("stake", 50)), + }, integration.WithAutomaticFinalizeBlock(), integration.WithAutomaticCommit(), ) s.Require().NoError(err) + s.Require().Equal(integrationApp.LastBlockHeight(), int64(2)) - grpcSrv := grpc.NewServer(grpc.ForceServerCodec(codec.NewProtoCodec(encodingCfg.InterfaceRegistry).GRPCCodec())) + resp, err := bankKeeper.Balance(integrationApp.Context(), &banktypes.QueryBalanceRequest{Address: s.address.String(), Denom: "stake"}) + s.Require().NoError(err) + s.Require().Equal(int64(50), resp.Balance.Amount.Int64()) + + grpcSrv := grpc.NewServer( + grpc.ForceServerCodec(codec.NewProtoCodec(encodingCfg.InterfaceRegistry).GRPCCodec()), + ) integrationApp.RegisterGRPCServer(grpcSrv) + grpcCfg := srvconfig.DefaultConfig().GRPC go func() { - s.Require().NoError(servergrpc.StartGRPCServer(context.Background(), integrationApp.Logger(), grpcCfg, grpcSrv)) + err := servergrpc.StartGRPCServer( + integrationApp.Context(), + integrationApp.Logger(), + grpcCfg, + grpcSrv, + ) + s.Require().NoError(err) + defer grpcSrv.GracefulStop() }() s.conn, err = grpc.NewClient( @@ -181,8 +190,7 @@ func (s *IntegrationTestOutOfGasSuite) TestGRPCServer_BankBalance_OutOfGas() { &banktypes.QueryBalanceRequest{Address: s.address.String(), Denom: "stake"}, ) - fmt.Println("Res....", res) - + s.Require().Equal(math.NewInt(50).Int64(), res.Balance.Amount.Int64()) s.Require().ErrorContains(err, sdkerrors.ErrOutOfGas.Error()) }