From bc583ab1d0b9d02c6b3935f16f48f9fb58e3e2f0 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 22 Oct 2018 15:37:20 -0700 Subject: [PATCH 01/19] Various sign command improvements - Exit with error if the user is attempting to sign with a key whose address is not among those who are expected to sign the transaction. - Add --print-signature-only to output only the generated signature. --- client/utils/utils.go | 3 ++- x/auth/client/cli/sign.go | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/client/utils/utils.go b/client/utils/utils.go index f5cf04168..9d20f0ab8 100644 --- a/client/utils/utils.go +++ b/client/utils/utils.go @@ -123,7 +123,8 @@ func SignStdTx(txBldr authtxb.TxBuilder, cliCtx context.CLIContext, name string, // Check whether the address is a signer if !isTxSigner(sdk.AccAddress(addr), stdTx.GetSigners()) { - fmt.Fprintf(os.Stderr, "WARNING: The generated transaction's intended signer does not match the given signer: '%v'\n", name) + return signedStdTx, fmt.Errorf( + "The generated transaction's intended signer does not match the given signer: %q", name) } if !offline && txBldr.AccountNumber == 0 { diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 67c64dc2a..fdc7269ce 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -20,6 +20,7 @@ const ( flagAppend = "append" flagPrintSigs = "print-sigs" flagOffline = "offline" + flagSigOnly = "print-signature-only" ) // GetSignCommand returns the sign command @@ -38,6 +39,7 @@ recommended to set such parameters manually.`, } cmd.Flags().String(client.FlagName, "", "Name of private key with which to sign") cmd.Flags().Bool(flagAppend, true, "Append the signature to the existing ones. If disabled, old signatures would be overwritten") + cmd.Flags().Bool(flagSigOnly, false, "Print only the generated signature, then exit.") cmd.Flags().Bool(flagPrintSigs, false, "Print the addresses that must sign the transaction and those who have already signed it, then exit") cmd.Flags().Bool(flagOffline, false, "Offline mode. Do not query local cache.") return cmd @@ -59,14 +61,24 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(decoder) txBldr := authtxb.NewTxBuilderFromCLI() - newTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, viper.GetBool(flagAppend), viper.GetBool(flagOffline)) + // if --print-signature-only is on, then override --append + generateSignatureOnly := viper.GetBool(flagSigOnly) + append := viper.GetBool(flagAppend) && !generateSignatureOnly + newTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, append, viper.GetBool(flagOffline)) if err != nil { return err } + var json []byte - if cliCtx.Indent { + + switch { + case generateSignatureOnly && cliCtx.Indent: + json, err = cdc.MarshalJSONIndent(newTx.Signatures[0], "", " ") + case generateSignatureOnly && !cliCtx.Indent: + json, err = cdc.MarshalJSON(newTx.Signatures[0]) + case !generateSignatureOnly && cliCtx.Indent: json, err = cdc.MarshalJSONIndent(newTx, "", " ") - } else { + case !generateSignatureOnly && !cliCtx.Indent: json, err = cdc.MarshalJSON(newTx) } if err != nil { From 933592d05222f79dbb523621d2ba86bdd3f95549 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 22 Oct 2018 15:52:19 -0700 Subject: [PATCH 02/19] Check sanity of signatures and report errors when run with --print-sigs --- x/auth/client/cli/sign.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index fdc7269ce..4b04139f2 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -91,13 +91,19 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. func printSignatures(stdTx auth.StdTx) { fmt.Println("Signers:") - for i, signer := range stdTx.GetSigners() { + signers := stdTx.GetSigners() + for i, signer := range signers { fmt.Printf(" %v: %v\n", i, signer.String()) } fmt.Println("") fmt.Println("Signatures:") for i, sig := range stdTx.GetSignatures() { - fmt.Printf(" %v: %v\n", i, sdk.AccAddress(sig.Address()).String()) + sigAddr := sdk.AccAddress(sig.Address()) + sigSanity := "OK" + if i >= len(signers) || !sigAddr.Equals(signers[i]) { + sigSanity = "ERROR" + } + fmt.Printf(" %v: %v\t[%s]\n", i, sigAddr.String(), sigSanity) } return } From 4bf17e82b4539f2f2ea70687bb8d3cfb7b1af27c Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 22 Oct 2018 16:11:13 -0700 Subject: [PATCH 03/19] Improve errors reporting --- x/auth/client/cli/sign.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 4b04139f2..98c3e750c 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -2,9 +2,8 @@ package cli import ( "fmt" - "io/ioutil" - "github.com/spf13/viper" + "io/ioutil" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" @@ -13,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth" authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder" "github.com/spf13/cobra" - amino "github.com/tendermint/go-amino" + "github.com/tendermint/go-amino" ) const ( @@ -53,7 +52,9 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. } if viper.GetBool(flagPrintSigs) { - printSignatures(stdTx) + if !printSignatures(stdTx) { + return fmt.Errorf("signatures validation failed") + } return nil } @@ -89,23 +90,31 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. } } -func printSignatures(stdTx auth.StdTx) { +func printSignatures(stdTx auth.StdTx) bool { fmt.Println("Signers:") signers := stdTx.GetSigners() for i, signer := range signers { fmt.Printf(" %v: %v\n", i, signer.String()) } + + sigs := stdTx.GetSignatures() fmt.Println("") fmt.Println("Signatures:") + success := true + if len(sigs) != len(signers) { + success = false + } for i, sig := range stdTx.GetSignatures() { sigAddr := sdk.AccAddress(sig.Address()) sigSanity := "OK" if i >= len(signers) || !sigAddr.Equals(signers[i]) { - sigSanity = "ERROR" + sigSanity = fmt.Sprintf("ERROR: signature %d does not match its respective signer", i) + if success { success = false } } fmt.Printf(" %v: %v\t[%s]\n", i, sigAddr.String(), sigSanity) } - return + fmt.Println("") + return success } func readAndUnmarshalStdTx(cdc *amino.Codec, filename string) (stdTx auth.StdTx, err error) { From 62974e627eb7385e94a115888f45b0e3b88c6fc4 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 22 Oct 2018 16:52:54 -0700 Subject: [PATCH 04/19] Improve online docs --- x/auth/client/cli/sign.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 98c3e750c..7d17dde44 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -30,6 +30,9 @@ func GetSignCommand(codec *amino.Codec, decoder auth.AccountDecoder) *cobra.Comm Long: `Sign transactions created with the --generate-only flag. Read a transaction from , sign it, and print its JSON encoding. +If the flag --print-signature-only flag is on, it outputs a JSON representation +of the generated signature only. + The --offline flag makes sure that the client will not reach out to the local cache. Thus account number or sequence number lookups will not be performed and it is recommended to set such parameters manually.`, From a4c4e280f8d0d53522ece2b3f14e67fb2e715acf Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 31 Oct 2018 13:42:38 +0000 Subject: [PATCH 05/19] Refresh PENDING.md --- PENDING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PENDING.md b/PENDING.md index 4453ddf8e..dd34ed56d 100644 --- a/PENDING.md +++ b/PENDING.md @@ -18,7 +18,8 @@ FEATURES * Gaia REST API (`gaiacli advanced rest-server`) * Gaia CLI (`gaiacli`) - * [cli] [\#2569](https://github.com/cosmos/cosmos-sdk/pull/2569) Add commands to query validator unbondings and redelegations + * [cli] [\#2524](https://github.com/cosmos/cosmos-sdk/issues/2524) Add support offline mode to `gaiacli tx sign`. Lookups are not performed if the flag `--offline` is on. + * [cli] [\#2558](https://github.com/cosmos/cosmos-sdk/issues/2558) Improve --print-sigs mode. It now performs a complete set of sanity checks and reports to the user. Also added --raw-signature to print the signature only, not the whole transaction. * Gaia From 69a7c06ef7830cbab492e6903ef4722d7ad47738 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 22 Oct 2018 16:59:19 -0700 Subject: [PATCH 06/19] Find better name for --print-signature-only --- x/auth/client/cli/sign.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 7d17dde44..ba8372e98 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -16,10 +16,10 @@ import ( ) const ( - flagAppend = "append" - flagPrintSigs = "print-sigs" - flagOffline = "offline" - flagSigOnly = "print-signature-only" + flagAppend = "append" + flagPrintSigs = "print-sigs" + flagOffline = "offline" + flagRawSignature = "raw-signature" ) // GetSignCommand returns the sign command @@ -30,7 +30,7 @@ func GetSignCommand(codec *amino.Codec, decoder auth.AccountDecoder) *cobra.Comm Long: `Sign transactions created with the --generate-only flag. Read a transaction from , sign it, and print its JSON encoding. -If the flag --print-signature-only flag is on, it outputs a JSON representation +If the flag --raw-signature flag is on, it outputs a JSON representation of the generated signature only. The --offline flag makes sure that the client will not reach out to the local cache. @@ -41,7 +41,7 @@ recommended to set such parameters manually.`, } cmd.Flags().String(client.FlagName, "", "Name of private key with which to sign") cmd.Flags().Bool(flagAppend, true, "Append the signature to the existing ones. If disabled, old signatures would be overwritten") - cmd.Flags().Bool(flagSigOnly, false, "Print only the generated signature, then exit.") + cmd.Flags().Bool(flagRawSignature, false, "Print only the generated signature, then exit.") cmd.Flags().Bool(flagPrintSigs, false, "Print the addresses that must sign the transaction and those who have already signed it, then exit") cmd.Flags().Bool(flagOffline, false, "Offline mode. Do not query local cache.") return cmd @@ -66,7 +66,7 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. txBldr := authtxb.NewTxBuilderFromCLI() // if --print-signature-only is on, then override --append - generateSignatureOnly := viper.GetBool(flagSigOnly) + generateSignatureOnly := viper.GetBool(flagRawSignature) append := viper.GetBool(flagAppend) && !generateSignatureOnly newTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, append, viper.GetBool(flagOffline)) if err != nil { @@ -112,7 +112,9 @@ func printSignatures(stdTx auth.StdTx) bool { sigSanity := "OK" if i >= len(signers) || !sigAddr.Equals(signers[i]) { sigSanity = fmt.Sprintf("ERROR: signature %d does not match its respective signer", i) - if success { success = false } + if success { + success = false + } } fmt.Printf(" %v: %v\t[%s]\n", i, sigAddr.String(), sigSanity) } From e65c02dd42d9d5e73a8d276aef25b7d108f748c4 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 22 Oct 2018 17:37:28 -0700 Subject: [PATCH 07/19] Fix integration tests --- cmd/gaia/cli_test/cli_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index ad1549641..d965a894d 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -493,7 +493,7 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { // Test sign --print-sigs success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf( "gaiacli tx sign %v --print-sigs %v", flags, unsignedTxFile.Name())) - require.True(t, success) + require.False(t, success) require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n", fooAddr.String()), stdout) // Test sign From 31c062689de71e0ad4499e7b1cf85e43f51962e0 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 22 Oct 2018 17:51:46 -0700 Subject: [PATCH 08/19] Validate --name --- x/auth/client/cli/sign.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index ba8372e98..7009bd968 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + "github.com/pkg/errors" "github.com/spf13/viper" "io/ioutil" @@ -62,6 +63,9 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. } name := viper.GetString(client.FlagName) + if name == "" { + return errors.New("required flag \"name\" has not been set") + } cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(decoder) txBldr := authtxb.NewTxBuilderFromCLI() From a5142951286d0eb0aee7a3afda11cc9201697785 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 22 Oct 2018 17:53:02 -0700 Subject: [PATCH 09/19] Fix integration tests --- cmd/gaia/cli_test/cli_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index d965a894d..ba3839779 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -494,7 +494,7 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf( "gaiacli tx sign %v --print-sigs %v", flags, unsignedTxFile.Name())) require.False(t, success) - require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n", fooAddr.String()), stdout) + require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n\n", fooAddr.String()), stdout) // Test sign success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf( @@ -513,7 +513,8 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf( "gaiacli tx sign %v --print-sigs %v", flags, signedTxFile.Name())) require.True(t, success) - require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n 0: %v\n", fooAddr.String(), fooAddr.String()), stdout) + require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n 0: %v\t[OK]\n\n", fooAddr.String(), + fooAddr.String()), stdout) // Test broadcast fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli query account %s %v", fooAddr, flags)) From 53f1233f0a16377e3ce0f2151c5ca8945090cf67 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 23 Oct 2018 11:53:47 -0700 Subject: [PATCH 10/19] s/--print-sigs/--validate-signatures/ --- cmd/gaia/cli_test/cli_test.go | 12 +++++++----- x/auth/client/cli/sign.go | 14 ++++++++------ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index ba3839779..b4791bf12 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -445,7 +445,8 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID) // start gaiad server - proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr)) + proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf( + "gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr)) defer proc.Stop(false) tests.WaitForTMStart(port) @@ -490,9 +491,9 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { unsignedTxFile := writeToNewTempFile(t, stdout) defer os.Remove(unsignedTxFile.Name()) - // Test sign --print-sigs + // Test sign --validate-signatures success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf( - "gaiacli tx sign %v --print-sigs %v", flags, unsignedTxFile.Name())) + "gaiacli tx sign %v --validate-signatures %v", flags, unsignedTxFile.Name())) require.False(t, success) require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n\n", fooAddr.String()), stdout) @@ -511,7 +512,7 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { // Test sign --print-signatures success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf( - "gaiacli tx sign %v --print-sigs %v", flags, signedTxFile.Name())) + "gaiacli tx sign %v --validate-signatures %v", flags, signedTxFile.Name())) require.True(t, success) require.Equal(t, fmt.Sprintf("Signers:\n 0: %v\n\nSignatures:\n 0: %v\t[OK]\n\n", fooAddr.String(), fooAddr.String()), stdout) @@ -520,7 +521,8 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) { fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli query account %s %v", fooAddr, flags)) require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak").Int64()) - success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf("gaiacli tx broadcast %v --json %v", flags, signedTxFile.Name())) + success, stdout, _ = executeWriteRetStdStreams(t, fmt.Sprintf( + "gaiacli tx broadcast %v --json %v", flags, signedTxFile.Name())) require.True(t, success) var result struct { Response abci.ResponseDeliverTx diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 7009bd968..bc4ad59ab 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -18,9 +18,9 @@ import ( const ( flagAppend = "append" - flagPrintSigs = "print-sigs" + flagPrintSigs = "validate-signatures" flagOffline = "offline" - flagRawSignature = "raw-signature" + flagRawSignature = "sig-only" ) // GetSignCommand returns the sign command @@ -31,7 +31,7 @@ func GetSignCommand(codec *amino.Codec, decoder auth.AccountDecoder) *cobra.Comm Long: `Sign transactions created with the --generate-only flag. Read a transaction from , sign it, and print its JSON encoding. -If the flag --raw-signature flag is on, it outputs a JSON representation +If the flag --sig-only flag is on, it outputs a JSON representation of the generated signature only. The --offline flag makes sure that the client will not reach out to the local cache. @@ -41,9 +41,11 @@ recommended to set such parameters manually.`, Args: cobra.ExactArgs(1), } cmd.Flags().String(client.FlagName, "", "Name of private key with which to sign") - cmd.Flags().Bool(flagAppend, true, "Append the signature to the existing ones. If disabled, old signatures would be overwritten") + cmd.Flags().Bool(flagAppend, true, + "Append the signature to the existing ones. If disabled, old signatures would be overwritten") cmd.Flags().Bool(flagRawSignature, false, "Print only the generated signature, then exit.") - cmd.Flags().Bool(flagPrintSigs, false, "Print the addresses that must sign the transaction and those who have already signed it, then exit") + cmd.Flags().Bool(flagPrintSigs, false, "Print the addresses that must sign the transaction, "+ + "those who have already signed it, and make sure that signatures are in the correct order.") cmd.Flags().Bool(flagOffline, false, "Offline mode. Do not query local cache.") return cmd } @@ -69,7 +71,7 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(decoder) txBldr := authtxb.NewTxBuilderFromCLI() - // if --print-signature-only is on, then override --append + // if --sig-only is on, then override --append generateSignatureOnly := viper.GetBool(flagRawSignature) append := viper.GetBool(flagAppend) && !generateSignatureOnly newTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, append, viper.GetBool(flagOffline)) From f752525d5496b4011da6213ccd874003a4f36db3 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Tue, 23 Oct 2018 12:41:24 -0700 Subject: [PATCH 11/19] s/--sig-only/--signature-only/ --- x/auth/client/cli/sign.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index bc4ad59ab..60deefb3d 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -20,7 +20,7 @@ const ( flagAppend = "append" flagPrintSigs = "validate-signatures" flagOffline = "offline" - flagRawSignature = "sig-only" + flagRawSignature = "signature-only" ) // GetSignCommand returns the sign command @@ -31,7 +31,7 @@ func GetSignCommand(codec *amino.Codec, decoder auth.AccountDecoder) *cobra.Comm Long: `Sign transactions created with the --generate-only flag. Read a transaction from , sign it, and print its JSON encoding. -If the flag --sig-only flag is on, it outputs a JSON representation +If the flag --signature-only flag is on, it outputs a JSON representation of the generated signature only. The --offline flag makes sure that the client will not reach out to the local cache. @@ -71,7 +71,7 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(decoder) txBldr := authtxb.NewTxBuilderFromCLI() - // if --sig-only is on, then override --append + // if --signature-only is on, then override --append generateSignatureOnly := viper.GetBool(flagRawSignature) append := viper.GetBool(flagAppend) && !generateSignatureOnly newTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, append, viper.GetBool(flagOffline)) From bb734c43c6ffa3819269e77125d3ca718ecc056e Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Thu, 25 Oct 2018 04:44:42 +0100 Subject: [PATCH 12/19] Docs updated --- docs/sdk/clients.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/sdk/clients.md b/docs/sdk/clients.md index 73d9a3b9a..4f0669183 100644 --- a/docs/sdk/clients.md +++ b/docs/sdk/clients.md @@ -181,6 +181,12 @@ gaiacli tx sign \ unsignedSendTx.json > signedSendTx.json ``` +You can validate the transaction's signagures by typing the following: + +```bash +gaiacli tx sign --validate-signatures signedSendTx.json +``` + You can broadcast the signed transaction to a node by providing the JSON file to the following command: ``` From 17f799abb08d352e618c8914a13a6a3b6a39a584 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 31 Oct 2018 13:43:17 +0000 Subject: [PATCH 13/19] Update PENDING.md --- PENDING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PENDING.md b/PENDING.md index dd34ed56d..e9f502210 100644 --- a/PENDING.md +++ b/PENDING.md @@ -19,7 +19,8 @@ FEATURES * Gaia CLI (`gaiacli`) * [cli] [\#2524](https://github.com/cosmos/cosmos-sdk/issues/2524) Add support offline mode to `gaiacli tx sign`. Lookups are not performed if the flag `--offline` is on. - * [cli] [\#2558](https://github.com/cosmos/cosmos-sdk/issues/2558) Improve --print-sigs mode. It now performs a complete set of sanity checks and reports to the user. Also added --raw-signature to print the signature only, not the whole transaction. + * [cli] [\#2558](https://github.com/cosmos/cosmos-sdk/issues/2558) Rename --print-sigs to --validate-signatures. It now performs a complete set of sanity checks and reports to the user. Also added --print-signature-only to print the signature only, not the whole transaction. + * [cli] [\#2554](https://github.com/cosmos/cosmos-sdk/issues/2554) Make `gaiacli keys show` multisig ready. * Gaia From 9e397907be91bcc9a759890366941379d7ce557f Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 29 Oct 2018 15:11:32 +0000 Subject: [PATCH 14/19] Rename append, it's go builtin --- x/auth/client/cli/sign.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 60deefb3d..812c2be24 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -73,8 +73,8 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. // if --signature-only is on, then override --append generateSignatureOnly := viper.GetBool(flagRawSignature) - append := viper.GetBool(flagAppend) && !generateSignatureOnly - newTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, append, viper.GetBool(flagOffline)) + appendSig := viper.GetBool(flagAppend) && !generateSignatureOnly + newTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, appendSig, viper.GetBool(flagOffline)) if err != nil { return err } From 44d2347109d49d3e9d99598bdab4bf753b493bd7 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 29 Oct 2018 15:13:36 +0000 Subject: [PATCH 15/19] Set success = false when it fails --- x/auth/client/cli/sign.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 812c2be24..fd8d39796 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -118,9 +118,7 @@ func printSignatures(stdTx auth.StdTx) bool { sigSanity := "OK" if i >= len(signers) || !sigAddr.Equals(signers[i]) { sigSanity = fmt.Sprintf("ERROR: signature %d does not match its respective signer", i) - if success { - success = false - } + success = false } fmt.Printf(" %v: %v\t[%s]\n", i, sigAddr.String(), sigSanity) } From 84aef0d106c566d378d0d40bf0766b752ed935a0 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 29 Oct 2018 15:15:59 +0000 Subject: [PATCH 16/19] Apply suggestions from bez --- x/auth/client/cli/sign.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index fd8d39796..4ea734355 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -18,9 +18,9 @@ import ( const ( flagAppend = "append" - flagPrintSigs = "validate-signatures" + flagValidateSigs = "validate-signatures" flagOffline = "offline" - flagRawSignature = "signature-only" + flagSigOnly = "signature-only" ) // GetSignCommand returns the sign command @@ -43,8 +43,8 @@ recommended to set such parameters manually.`, cmd.Flags().String(client.FlagName, "", "Name of private key with which to sign") cmd.Flags().Bool(flagAppend, true, "Append the signature to the existing ones. If disabled, old signatures would be overwritten") - cmd.Flags().Bool(flagRawSignature, false, "Print only the generated signature, then exit.") - cmd.Flags().Bool(flagPrintSigs, false, "Print the addresses that must sign the transaction, "+ + cmd.Flags().Bool(flagSigOnly, false, "Print only the generated signature, then exit.") + cmd.Flags().Bool(flagValidateSigs, false, "Print the addresses that must sign the transaction, "+ "those who have already signed it, and make sure that signatures are in the correct order.") cmd.Flags().Bool(flagOffline, false, "Offline mode. Do not query local cache.") return cmd @@ -57,7 +57,7 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. return } - if viper.GetBool(flagPrintSigs) { + if viper.GetBool(flagValidateSigs) { if !printSignatures(stdTx) { return fmt.Errorf("signatures validation failed") } @@ -72,7 +72,7 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. txBldr := authtxb.NewTxBuilderFromCLI() // if --signature-only is on, then override --append - generateSignatureOnly := viper.GetBool(flagRawSignature) + generateSignatureOnly := viper.GetBool(flagSigOnly) appendSig := viper.GetBool(flagAppend) && !generateSignatureOnly newTx, err := utils.SignStdTx(txBldr, cliCtx, name, stdTx, appendSig, viper.GetBool(flagOffline)) if err != nil { From 6c8791f5055950bcae4b2554019b44f48d987680 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Mon, 29 Oct 2018 15:34:11 +0000 Subject: [PATCH 17/19] Nest switches --- x/auth/client/cli/sign.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index 4ea734355..cb128e38c 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -81,15 +81,21 @@ func makeSignCmd(cdc *amino.Codec, decoder auth.AccountDecoder) func(cmd *cobra. var json []byte - switch { - case generateSignatureOnly && cliCtx.Indent: - json, err = cdc.MarshalJSONIndent(newTx.Signatures[0], "", " ") - case generateSignatureOnly && !cliCtx.Indent: - json, err = cdc.MarshalJSON(newTx.Signatures[0]) - case !generateSignatureOnly && cliCtx.Indent: - json, err = cdc.MarshalJSONIndent(newTx, "", " ") - case !generateSignatureOnly && !cliCtx.Indent: - json, err = cdc.MarshalJSON(newTx) + switch generateSignatureOnly { + case true: + switch cliCtx.Indent { + case true: + json, err = cdc.MarshalJSONIndent(newTx.Signatures[0], "", " ") + default: + json, err = cdc.MarshalJSON(newTx.Signatures[0]) + } + default: + switch cliCtx.Indent { + case true: + json, err = cdc.MarshalJSONIndent(newTx, "", " ") + default: + json, err = cdc.MarshalJSON(newTx) + } } if err != nil { return err From 06989bee618965d33ed1e443c3fadabb545e2e41 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 31 Oct 2018 13:44:00 +0000 Subject: [PATCH 18/19] Fix rebase --- PENDING.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/PENDING.md b/PENDING.md index e9f502210..a376a154c 100644 --- a/PENDING.md +++ b/PENDING.md @@ -18,9 +18,10 @@ FEATURES * Gaia REST API (`gaiacli advanced rest-server`) * Gaia CLI (`gaiacli`) - * [cli] [\#2524](https://github.com/cosmos/cosmos-sdk/issues/2524) Add support offline mode to `gaiacli tx sign`. Lookups are not performed if the flag `--offline` is on. - * [cli] [\#2558](https://github.com/cosmos/cosmos-sdk/issues/2558) Rename --print-sigs to --validate-signatures. It now performs a complete set of sanity checks and reports to the user. Also added --print-signature-only to print the signature only, not the whole transaction. - * [cli] [\#2554](https://github.com/cosmos/cosmos-sdk/issues/2554) Make `gaiacli keys show` multisig ready. + * [cli] [\#2569](https://github.com/cosmos/cosmos-sdk/pull/2569) Add commands to query validator unbondings and redelegations + * [cli] [\#2569](https://github.com/cosmos/cosmos-sdk/pull/2569) Add commands to query validator unbondings and redelegations + * [cli] [\#2524](https://github.com/cosmos/cosmos-sdk/issues/2524) Add support offline mode to `gaiacli tx sign`. Lookups are not performed if the flag `--offline` is on. + * [cli] [\#2558](https://github.com/cosmos/cosmos-sdk/issues/2558) Rename --print-sigs to --validate-signatures. It now performs a complete set of sanity checks and reports to the user. Also added --print-signature-only to print the signature only, not the whole transaction. * Gaia From dbbf0647f0dd8057eb1ae593cfcf66d6b4f7e4a5 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Wed, 31 Oct 2018 13:50:01 +0000 Subject: [PATCH 19/19] Document what --validate-signatures does --- x/auth/client/cli/sign.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x/auth/client/cli/sign.go b/x/auth/client/cli/sign.go index cb128e38c..f4a4548d4 100644 --- a/x/auth/client/cli/sign.go +++ b/x/auth/client/cli/sign.go @@ -34,6 +34,10 @@ Read a transaction from , sign it, and print its JSON encoding. If the flag --signature-only flag is on, it outputs a JSON representation of the generated signature only. +If the flag --validate-signatures is on, then the command would check whether all required +signers have signed the transactions and whether the signatures were collected in the right +order. + The --offline flag makes sure that the client will not reach out to the local cache. Thus account number or sequence number lookups will not be performed and it is recommended to set such parameters manually.`,