From 3d05dfd2b9e8e49f4ec76f5beec613e1b58b3b71 Mon Sep 17 00:00:00 2001 From: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Wed, 22 Feb 2023 11:43:14 +0900 Subject: [PATCH 1/7] change the `offline` flag to work as described --- client/tx/factory.go | 27 +++++++++++++++------------ client/tx/tx.go | 9 ++++++++- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/client/tx/factory.go b/client/tx/factory.go index cb2a7b0e271e..d642991a4426 100644 --- a/client/tx/factory.go +++ b/client/tx/factory.go @@ -47,7 +47,7 @@ type Factory struct { } // NewFactoryCLI creates a new Factory. -func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) Factory { +func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, error) { signModeStr := clientCtx.SignModeStr signMode := signing.SignMode_SIGN_MODE_UNSPECIFIED @@ -64,8 +64,16 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) Factory { signMode = signing.SignMode_SIGN_MODE_EIP_191 } - accNum, _ := flagSet.GetUint64(flags.FlagAccountNumber) - accSeq, _ := flagSet.GetUint64(flags.FlagSequence) + var accNum, accSeq uint64 + if clientCtx.Offline { + if flagSet.Changed(flags.FlagAccountNumber) && flagSet.Changed(flags.FlagSequence) { + accNum, _ = flagSet.GetUint64(flags.FlagAccountNumber) + accSeq, _ = flagSet.GetUint64(flags.FlagSequence) + } else { + return Factory{}, errors.New("account-number and sequence must be set in offline mode") + } + } + gasAdj, _ := flagSet.GetFloat64(flags.FlagGasAdjustment) memo, _ := flagSet.GetString(flags.FlagNote) timeoutHeight, _ := flagSet.GetUint64(flags.FlagTimeoutHeight) @@ -105,7 +113,7 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) Factory { f = f.WithPreprocessTxHook(clientCtx.PreprocessTxHook) - return f + return f, nil } func (f Factory) AccountNumber() uint64 { return f.accountNumber } @@ -435,19 +443,14 @@ func (f Factory) Prepare(clientCtx client.Context) (Factory, error) { } initNum, initSeq := fc.accountNumber, fc.sequence - if initNum == 0 || initSeq == 0 { + if initNum == 0 && initSeq == 0 { num, seq, err := fc.accountRetriever.GetAccountNumberSequence(clientCtx, from) if err != nil { return fc, err } - if initNum == 0 { - fc = fc.WithAccountNumber(num) - } - - if initSeq == 0 { - fc = fc.WithSequence(seq) - } + fc = fc.WithAccountNumber(num) + fc = fc.WithSequence(seq) } return fc, nil diff --git a/client/tx/tx.go b/client/tx/tx.go index 9311bbd2908f..0e4e9ac96609 100644 --- a/client/tx/tx.go +++ b/client/tx/tx.go @@ -24,7 +24,10 @@ import ( // GenerateOrBroadcastTxCLI will either generate and print and unsigned transaction // or sign it and broadcast it returning an error upon failure. func GenerateOrBroadcastTxCLI(clientCtx client.Context, flagSet *pflag.FlagSet, msgs ...sdk.Msg) error { - txf := NewFactoryCLI(clientCtx, flagSet) + txf, err := NewFactoryCLI(clientCtx, flagSet) + if err != nil { + return err + } return GenerateOrBroadcastTxWithFactory(clientCtx, txf, msgs...) } @@ -69,6 +72,10 @@ func BroadcastTx(clientCtx client.Context, txf Factory, msgs ...sdk.Msg) error { } if txf.SimulateAndExecute() || clientCtx.Simulate { + if clientCtx.Offline { + return errors.New("cannot estimate gas in offline mode") + } + _, adjusted, err := CalculateGas(clientCtx, txf, msgs...) if err != nil { return err From f7beafb0e63644bfda402eda842740506ee4fefa Mon Sep 17 00:00:00 2001 From: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Wed, 22 Feb 2023 11:44:28 +0900 Subject: [PATCH 2/7] add error handling for TxFactory --- x/auth/client/cli/tips.go | 5 ++++- x/auth/client/cli/tx_multisign.go | 10 ++++++++-- x/auth/client/cli/tx_sign.go | 5 ++++- x/auth/client/cli/validate_sigs.go | 5 ++++- x/genutil/client/cli/gentx.go | 5 ++++- x/staking/client/cli/tx.go | 7 +++++-- 6 files changed, 29 insertions(+), 8 deletions(-) diff --git a/x/auth/client/cli/tips.go b/x/auth/client/cli/tips.go index ab4f8937f91c..82904c6ab064 100644 --- a/x/auth/client/cli/tips.go +++ b/x/auth/client/cli/tips.go @@ -35,7 +35,10 @@ func GetAuxToFeeCommand() *cobra.Command { return fmt.Errorf("expected chain-id %s, got %s in aux signer data", clientCtx.ChainID, auxSignerData.SignDoc.ChainId) } - f := clienttx.NewFactoryCLI(clientCtx, cmd.Flags()) + f, err := clienttx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } txBuilder := clientCtx.TxConfig.NewTxBuilder() err = txBuilder.AddAuxSignerData(auxSignerData) diff --git a/x/auth/client/cli/tx_multisign.go b/x/auth/client/cli/tx_multisign.go index d5f271b3bdb6..58d9e5265989 100644 --- a/x/auth/client/cli/tx_multisign.go +++ b/x/auth/client/cli/tx_multisign.go @@ -82,7 +82,10 @@ func makeMultiSignCmd() func(cmd *cobra.Command, args []string) (err error) { return } - txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + txFactory, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } if txFactory.SignMode() == signingtypes.SignMode_SIGN_MODE_UNSPECIFIED { txFactory = txFactory.WithSignMode(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) } @@ -257,7 +260,10 @@ func makeBatchMultisignCmd() func(cmd *cobra.Command, args []string) error { } txCfg := clientCtx.TxConfig - txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + txFactory, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } if txFactory.SignMode() == signingtypes.SignMode_SIGN_MODE_UNSPECIFIED { txFactory = txFactory.WithSignMode(signingtypes.SignMode_SIGN_MODE_LEGACY_AMINO_JSON) } diff --git a/x/auth/client/cli/tx_sign.go b/x/auth/client/cli/tx_sign.go index 30132ec14fd3..9b37937dc634 100644 --- a/x/auth/client/cli/tx_sign.go +++ b/x/auth/client/cli/tx_sign.go @@ -71,7 +71,10 @@ func makeSignBatchCmd() func(cmd *cobra.Command, args []string) error { if err != nil { return err } - txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + txFactory, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } txCfg := clientCtx.TxConfig printSignatureOnly, _ := cmd.Flags().GetBool(flagSigOnly) diff --git a/x/auth/client/cli/validate_sigs.go b/x/auth/client/cli/validate_sigs.go index 784cac89d912..54bfaa0406fb 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -133,7 +133,10 @@ func readTxAndInitContexts(clientCtx client.Context, cmd *cobra.Command, filenam return clientCtx, tx.Factory{}, nil, err } - txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + txFactory, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return clientCtx, tx.Factory{}, nil, err + } return clientCtx, txFactory, stdTx, nil } diff --git a/x/genutil/client/cli/gentx.go b/x/genutil/client/cli/gentx.go index f7a6fe3ec978..14ef1590ddac 100644 --- a/x/genutil/client/cli/gentx.go +++ b/x/genutil/client/cli/gentx.go @@ -128,7 +128,10 @@ $ %s gentx my-key-name 1000000stake --home=/path/to/home/dir --keyring-backend=o return errors.Wrap(err, "failed to validate account in genesis") } - txFactory := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + txFactory, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } pub, err := key.GetAddress() if err != nil { diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 258a6c248f11..b6a3406a41ef 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -66,8 +66,11 @@ func NewCreateValidatorCmd() *cobra.Command { return err } - txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()). - WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + if err != nil { + return err + } + txf, msg, err := newBuildCreateValidatorMsg(clientCtx, txf, cmd.Flags()) if err != nil { return err From 909508b6415bdeea81c487afb87584158b2bb4c0 Mon Sep 17 00:00:00 2001 From: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Wed, 22 Feb 2023 16:05:50 +0900 Subject: [PATCH 3/7] add CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9da4394faa2..97b05b60f9f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/gov,cli) [#14718](https://github.com/cosmos/cosmos-sdk/pull/14718) Added `AddGovPropFlagsToCmd` and `ReadGovPropFlags` functions. * (x/bank) [#14894](https://github.com/cosmos/cosmos-sdk/pull/14894) Return a human readable denomination for IBC vouchers when querying bank balances. Added a `ResolveDenom` parameter to `types.QueryAllBalancesRequest` and `--resolve-denom` flag to `GetBalancesCmd()`. * (x/groups) [#14879](https://github.com/cosmos/cosmos-sdk/pull/14879) Add `Query/Groups` query to get all the groups. +* (cli) [#15123](https://github.com/cosmos/cosmos-sdk/pull/15123) Change the behavior of offline mode correctly ### Improvements From 8303f6dd1739f04a99569e2bc44b5da3e6ebcf1a Mon Sep 17 00:00:00 2001 From: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Wed, 22 Feb 2023 16:08:07 +0900 Subject: [PATCH 4/7] go fmt --- x/staking/client/cli/tx.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x/staking/client/cli/tx.go b/x/staking/client/cli/tx.go index 8ee48d3228e4..9453c10aef1a 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -91,16 +91,15 @@ where we can get the pubkey using "%s tendermint show-validator" } txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) - if err != nil { + if err != nil { return err } - + validator, err := parseAndValidateValidatorJSON(clientCtx.Codec, args[0]) if err != nil { return err } - txf, msg, err := newBuildCreateValidatorMsg(clientCtx, txf, cmd.Flags(), validator) if err != nil { return err From 319a7a56248e17746cf0a1c2d421a721a6aef4c4 Mon Sep 17 00:00:00 2001 From: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Wed, 22 Feb 2023 19:43:23 +0900 Subject: [PATCH 5/7] fix broken e2e test cases --- tests/e2e/auth/suite.go | 17 ++++++++++++++--- tests/e2e/tx/service_test.go | 3 +++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/tests/e2e/auth/suite.go b/tests/e2e/auth/suite.go index 68fa6ff59a8f..ddd3f4741564 100644 --- a/tests/e2e/auth/suite.go +++ b/tests/e2e/auth/suite.go @@ -1213,9 +1213,20 @@ func (s *E2ETestSuite) TestCLIMultisign() { sign2File := testutil.WriteToNewTempFile(s.T(), account2Signature.String()) defer sign2File.Close() - // Does not work in offline mode. - _, err = authclitestutil.TxMultiSignExec(val1.ClientCtx, multisigRecord.Name, multiGeneratedTxFile.Name(), "--offline", sign1File.Name(), sign2File.Name()) - s.Require().EqualError(err, fmt.Sprintf("couldn't verify signature for address %s", addr1)) + // Work in offline mode. + multisigAccNum, multisigSeq, err := val1.ClientCtx.AccountRetriever.GetAccountNumberSequence(val1.ClientCtx, addr) + s.Require().NoError(err) + _, err = authclitestutil.TxMultiSignExec( + val1.ClientCtx, + multisigRecord.Name, + multiGeneratedTxFile.Name(), + fmt.Sprintf("--%s", flags.FlagOffline), + fmt.Sprintf("--%s=%d", flags.FlagAccountNumber, multisigAccNum), + fmt.Sprintf("--%s=%d", flags.FlagSequence, multisigSeq), + sign1File.Name(), + sign2File.Name(), + ) + s.Require().NoError(err) val1.ClientCtx.Offline = false multiSigWith2Signatures, err := authclitestutil.TxMultiSignExec(val1.ClientCtx, multisigRecord.Name, multiGeneratedTxFile.Name(), sign1File.Name(), sign2File.Name()) diff --git a/tests/e2e/tx/service_test.go b/tests/e2e/tx/service_test.go index c7767ac089a9..533fedbd8075 100644 --- a/tests/e2e/tx/service_test.go +++ b/tests/e2e/tx/service_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/suite" errorsmod "cosmossdk.io/errors" + "cosmossdk.io/simapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -90,6 +91,8 @@ func (s *E2ETestSuite) SetupSuite() { sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(1)), ), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s", flags.FlagOffline), + fmt.Sprintf("--%s=0", flags.FlagAccountNumber), fmt.Sprintf("--%s=2", flags.FlagSequence), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), From d6db58b43a0ff41c86ee649c9f1e926e2fd882bf Mon Sep 17 00:00:00 2001 From: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Wed, 22 Feb 2023 19:47:03 +0900 Subject: [PATCH 6/7] fix CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97b05b60f9f3..fefe4e3537f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,7 +76,6 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/gov,cli) [#14718](https://github.com/cosmos/cosmos-sdk/pull/14718) Added `AddGovPropFlagsToCmd` and `ReadGovPropFlags` functions. * (x/bank) [#14894](https://github.com/cosmos/cosmos-sdk/pull/14894) Return a human readable denomination for IBC vouchers when querying bank balances. Added a `ResolveDenom` parameter to `types.QueryAllBalancesRequest` and `--resolve-denom` flag to `GetBalancesCmd()`. * (x/groups) [#14879](https://github.com/cosmos/cosmos-sdk/pull/14879) Add `Query/Groups` query to get all the groups. -* (cli) [#15123](https://github.com/cosmos/cosmos-sdk/pull/15123) Change the behavior of offline mode correctly ### Improvements @@ -308,6 +307,7 @@ extension interfaces. `module.Manager.Modules` is now of type `map[string]interf * (server) [#13778](https://github.com/cosmos/cosmos-sdk/pull/13778) Set Cosmos SDK default endpoints to localhost to avoid unknown exposure of endpoints. * (x/auth) [#13877](https://github.com/cosmos/cosmos-sdk/pull/13877) Handle missing account numbers during `InitGenesis`. * (cli) [#14509](https://github.com/cosmos/cosmos-sdk/pull/#14509) Added missing options to keyring-backend flag usage +* (cli) [#15123](https://github.com/cosmos/cosmos-sdk/pull/15123) Change the offline mode behavior that does not match the written in the description to behave as written ### Deprecated From dbd6b24ceedb3a541cf1b8ab1ffe157b58c5f5e6 Mon Sep 17 00:00:00 2001 From: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Thu, 23 Feb 2023 11:11:33 +0900 Subject: [PATCH 7/7] add CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc582ddfc121..50206e455641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -257,7 +257,8 @@ extension interfaces. `module.Manager.Modules` is now of type `map[string]interf * (x/staking) [#14590](https://github.com/cosmos/cosmos-sdk/pull/14590) `MsgUndelegateResponse` now includes undelegated amount. `x/staking` module's `keeper.Undelegate` now returns 3 values (completionTime,undelegateAmount,error) instead of 2. * (x/feegrant) [14649](https://github.com/cosmos/cosmos-sdk/pull/14649) Extract Feegrant in its own go.mod and rename the package to `cosmossdk.io/x/feegrant`. * (x/bank) [#14894](https://github.com/cosmos/cosmos-sdk/pull/14894) Return a human readable denomination for IBC vouchers when querying bank balances. Added a `ResolveDenom` parameter to `types.QueryAllBalancesRequest`. -* (crypto) [#15070](https://github.com/cosmos/cosmos-sdk/pull/15070) `GenerateFromPassword` and `Cost` from `bcrypt.go` now take a `uint32` instead of a `int` type. +* (crypto) [#15070](https://github.com/cosmos/cosmos-sdk/pull/15070) `GenerateFromPassword` and `Cost` from `bcrypt.go` now take a `uint32` instead of a `int` type. +* (client) [#15123](https://github.com/cosmos/cosmos-sdk/pull/15123) `NewFactoryCLI` now returns an error, in addition to the `Factory`. ### Client Breaking Changes