From 225378357953289f33a1f6625430d4b73b649621 Mon Sep 17 00:00:00 2001 From: larry <26318510+larry0x@users.noreply.github.com> Date: Wed, 12 Jul 2023 19:36:00 +0200 Subject: [PATCH 1/2] feat: Add CLI commands: 1) simulate a transaction, 2) query block results (#16887) Co-authored-by: Facundo Medica <14063057+facundomedica@users.noreply.github.com> (cherry picked from commit ca74dcce7e15be495bd3acff52eef945d0fd485b) # Conflicts: # CHANGELOG.md --- CHANGELOG.md | 7 +++ client/cometbft.go | 1 + server/cmt_cmds.go | 75 ++++++++++++++++++++--- simapp/simd/cmd/root.go | 2 + simapp/simd/cmd/root_v2.go | 2 + x/auth/client/cli/tx_simulate.go | 101 +++++++++++++++++++++++++++++++ 6 files changed, 181 insertions(+), 7 deletions(-) create mode 100644 x/auth/client/cli/tx_simulate.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 72e26e9852f..8a419f82d33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,13 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] +<<<<<<< HEAD +======= +### Features + +* (cli) [#16887](https://github.com/cosmos/cosmos-sdk/pull/16887) Add two new CLI commands: `tx simulate` for simulating a transaction; `query block-results` for querying CometBFT RPC for block results. + +>>>>>>> ca74dcce7 (feat: Add CLI commands: 1) simulate a transaction, 2) query block results (#16887)) ### Improvements * (x/bank) [#16899](https://github.com/cosmos/cosmos-sdk/pull/16899) Align CLI queries with gRPC queries thanks to AutoCLI. diff --git a/client/cometbft.go b/client/cometbft.go index 595ea6492d2..fcf9ca64b08 100644 --- a/client/cometbft.go +++ b/client/cometbft.go @@ -16,6 +16,7 @@ type CometRPC interface { Status(context.Context) (*coretypes.ResultStatus, error) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) BlockByHash(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error) + BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) Tx(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) diff --git a/server/cmt_cmds.go b/server/cmt_cmds.go index 733067815eb..47a4e64e18f 100644 --- a/server/cmt_cmds.go +++ b/server/cmt_cmds.go @@ -1,6 +1,8 @@ package server import ( + "context" + "encoding/json" "fmt" "strconv" "strings" @@ -206,18 +208,13 @@ $ %s query block --%s=%s return fmt.Errorf("argument should be a block height") } - var height *int64 - // optional height + var height *int64 if len(args) > 0 { - h, err := strconv.Atoi(args[0]) + height, err = parseOptionalHeight(args[0]) if err != nil { return err } - if h > 0 { - tmp := int64(h) - height = &tmp - } } output, err := rpc.GetBlockByHeight(clientCtx, height) @@ -261,6 +258,70 @@ $ %s query block --%s=%s return cmd } +// QueryBlockResultCmd implements the default command for a BlockResults query. +func QueryBlockResultsCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "block-results [height]", + Short: "Query for a committed block's results by height", + Long: "Query for a specific committed block's results using the CometBFT RPC `block_results` method", + Args: cobra.RangeArgs(0, 1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + node, err := clientCtx.GetNode() + if err != nil { + return err + } + + // optional height + var height *int64 + if len(args) > 0 { + height, err = parseOptionalHeight(args[0]) + if err != nil { + return err + } + } + + blockRes, err := node.BlockResults(context.Background(), height) + if err != nil { + return err + } + + // coretypes.ResultBlockResults doesn't implement proto.Message interface + // so we can't print it using clientCtx.PrintProto + // we choose to serialize it to json and print the json instead + blockResStr, err := json.Marshal(blockRes) + if err != nil { + return err + } + + return clientCtx.PrintString(string(blockResStr) + "\n") + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func parseOptionalHeight(heightStr string) (*int64, error) { + h, err := strconv.Atoi(heightStr) + if err != nil { + return nil, err + } + + if h == 0 { + return nil, nil + } + + tmp := int64(h) + + return &tmp, nil +} + func BootstrapStateCmd(appCreator types.AppCreator) *cobra.Command { cmd := &cobra.Command{ Use: "bootstrap-state", diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 6d2cfc34e3b..dba942219e5 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -246,6 +246,7 @@ func queryCommand() *cobra.Command { authcmd.QueryTxsByEventsCmd(), server.QueryBlocksCmd(), authcmd.QueryTxCmd(), + server.QueryBlockResultsCmd(), ) return cmd @@ -270,6 +271,7 @@ func txCommand() *cobra.Command { authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), authcmd.GetAuxToFeeCommand(), + authcmd.GetSimulateCmd(), ) return cmd diff --git a/simapp/simd/cmd/root_v2.go b/simapp/simd/cmd/root_v2.go index c7fad78a06d..0689cca50fb 100644 --- a/simapp/simd/cmd/root_v2.go +++ b/simapp/simd/cmd/root_v2.go @@ -263,6 +263,7 @@ func queryCommand() *cobra.Command { authcmd.QueryTxsByEventsCmd(), server.QueryBlocksCmd(), authcmd.QueryTxCmd(), + server.QueryBlockResultsCmd(), ) return cmd @@ -287,6 +288,7 @@ func txCommand() *cobra.Command { authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), authcmd.GetAuxToFeeCommand(), + authcmd.GetSimulateCmd(), ) return cmd diff --git a/x/auth/client/cli/tx_simulate.go b/x/auth/client/cli/tx_simulate.go new file mode 100644 index 00000000000..9cb49e4778d --- /dev/null +++ b/x/auth/client/cli/tx_simulate.go @@ -0,0 +1,101 @@ +package cli + +import ( + "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + authclient "github.com/cosmos/cosmos-sdk/x/auth/client" +) + +// GetSimulateCmd returns a command that simulates whether a transaction will be +// successful. +func GetSimulateCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "simulate /path/to/unsigned-tx.json --from keyname", + Short: "Simulate the gas usage of a transaction", + Long: strings.TrimSpace(`Simulate whether a transaction will be successful: + +- if successful, the simulation result is printed, which includes the gas + consumption, message response data, and events emitted; +- if unsuccessful, the error message is printed. + +The user must provide the path to a JSON-encoded unsigned transaction, typically +generated by any transaction command with the --generate-only flag. It should +look like below. Note that the "signer_infos" and "signatures" fields are left +empty; they will be auto-populated by dummy data for simulation purpose. + +{ + "body": { + "messages": [ + { + "@type": "/cosmos.bank.v1beta1.MsgSend", + "from_address": "cosmos1...", + "to_address": "cosmos1...", + "amount": [ + { + "denom": "utoken", + "amount": "12345" + } + ] + } + ], + "memo": "", + "timeout_height": "0", + "extension_options": [], + "non_critical_extension_options": [] + }, + "auth_info": { + "signer_infos": [], + "fee": { + "amount": [], + "gas_limit": "200000", + "payer": "", + "granter": "" + }, + "tip": null + }, + "signatures": [] +} + +The --from flag is mandatory, as the signer account's correct sequence number is +necessary for simulation. +`), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + + txf, err = txf.Prepare(clientCtx) + if err != nil { + return err + } + + stdTx, err := authclient.ReadTxFromFile(clientCtx, args[0]) + if err != nil { + return err + } + + simRes, _, err := tx.CalculateGas(clientCtx, txf, stdTx.GetMsgs()...) + if err != nil { + return err + } + + return clientCtx.PrintProto(simRes) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} From f104a852c17ccc44b57f64884d8ce7b66e294fa7 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 12 Jul 2023 21:03:45 +0200 Subject: [PATCH 2/2] fix changelog --- CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a419f82d33..61efd2c2373 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,13 +38,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] -<<<<<<< HEAD -======= ### Features * (cli) [#16887](https://github.com/cosmos/cosmos-sdk/pull/16887) Add two new CLI commands: `tx simulate` for simulating a transaction; `query block-results` for querying CometBFT RPC for block results. ->>>>>>> ca74dcce7 (feat: Add CLI commands: 1) simulate a transaction, 2) query block results (#16887)) ### Improvements * (x/bank) [#16899](https://github.com/cosmos/cosmos-sdk/pull/16899) Align CLI queries with gRPC queries thanks to AutoCLI.