From 61c6b77bafba797e12f06634b30e4e1aa5f82a4d Mon Sep 17 00:00:00 2001 From: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Thu, 23 Feb 2023 19:03:20 +0900 Subject: [PATCH] fix: change the behavior of offline mode correctly (#15123) ## Description Closes: #15109 Change to work only when `FlagAccountNumber` and `FlagSequence` are in offline mode. In other cases, use `AccountRetriever` to populate those values. --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) (cherry picked from commit c71d19939baa377aff576cbf0b0eeee028c5ef2b) # Conflicts: # CHANGELOG.md # tests/e2e/tx/service_test.go # x/staking/client/cli/tx.go --- CHANGELOG.md | 23 +++++++++++++++++++++++ client/tx/factory.go | 27 +++++++++++++++------------ client/tx/tx.go | 9 ++++++++- tests/e2e/auth/suite.go | 17 ++++++++++++++--- tests/e2e/tx/service_test.go | 7 +++++++ 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 | 14 ++++++++++++++ 11 files changed, 105 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 306d2278f345..21e5acf8d139 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -246,6 +246,24 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#13794](https://github.com/cosmos/cosmos-sdk/pull/13794) Most methods on `types/module.AppModule` have been moved to extension interfaces. `module.Manager.Modules` is now of type `map[string]interface{}` to support in parallel the new `cosmossdk.io/core/appmodule.AppModule` API. +<<<<<<< HEAD +======= +* (signing) [#13701](https://github.com/cosmos/cosmos-sdk/pull/) Add `context.Context` as an argument `x/auth/signing.VerifySignature`. +* (x/group) [#13876](https://github.com/cosmos/cosmos-sdk/pull/13876) Add `GetMinExecutionPeriod` method on DecisionPolicy interface. +* (x/auth)[#13780](https://github.com/cosmos/cosmos-sdk/pull/13780) Querying with `id` (type of int64) in `AccountAddressByID` grpc query now throws error, use account-id(type of uint64) instead. +* (snapshots) [14048](https://github.com/cosmos/cosmos-sdk/pull/14048) Move the Snapshot package to the store package. This is done in an effort group all storage related logic under one package. +* (baseapp) [#14050](https://github.com/cosmos/cosmos-sdk/pull/14050) refactor `ABCIListener` interface to accept go contexts +* (store/streaming)[#14603](https://github.com/cosmos/cosmos-sdk/pull/14603) `StoreDecoderRegistry` moved from store to `types/simulations` this breaks the `AppModuleSimulation` interface. +* (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. +* (client) [#15123](https://github.com/cosmos/cosmos-sdk/pull/15123) `NewFactoryCLI` now returns an error, in addition to the `Factory`. + +### Client Breaking Changes + +* (grpc-web) [#14652](https://github.com/cosmos/cosmos-sdk/pull/14652) Use same port for gRPC-Web and the API server. +>>>>>>> c71d19939 (fix: change the behavior of offline mode correctly (#15123)) ### CLI Breaking Changes @@ -270,7 +288,12 @@ extension interfaces. `module.Manager.Modules` is now of type `map[string]interf * (snapshot) [#13400](https://github.com/cosmos/cosmos-sdk/pull/13400) Fix snapshot checksum issue in golang 1.19. * (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`. +<<<<<<< HEAD * (x/gov) [#13918](https://github.com/cosmos/cosmos-sdk/pull/13918) Propagate message errors when executing a proposal. +======= +* (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 +>>>>>>> c71d19939 (fix: change the behavior of offline mode correctly (#15123)) ### Deprecated diff --git a/client/tx/factory.go b/client/tx/factory.go index 3d174c0e8946..e9482bc854ad 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 @@ -62,8 +62,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) @@ -103,7 +111,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 } @@ -433,19 +441,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 2463d1d4cfa5..059ce3a1b9a3 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 diff --git a/tests/e2e/auth/suite.go b/tests/e2e/auth/suite.go index 77d85795e9cd..e103f46052ae 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 6537ef243733..704798ae91ff 100644 --- a/tests/e2e/tx/service_test.go +++ b/tests/e2e/tx/service_test.go @@ -10,6 +10,11 @@ import ( "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" +<<<<<<< HEAD +======= + errorsmod "cosmossdk.io/errors" + +>>>>>>> c71d19939 (fix: change the behavior of offline mode correctly (#15123)) "cosmossdk.io/simapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -93,6 +98,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()), diff --git a/x/auth/client/cli/tips.go b/x/auth/client/cli/tips.go index fcf5a2cb28c8..dd6ec56a980d 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 ea91580a7f47..b1fd2525c3cf 100644 --- a/x/auth/client/cli/tx_multisign.go +++ b/x/auth/client/cli/tx_multisign.go @@ -80,7 +80,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) } @@ -254,7 +257,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 0ad65c71e35a..4e03b8200707 100644 --- a/x/auth/client/cli/validate_sigs.go +++ b/x/auth/client/cli/validate_sigs.go @@ -131,7 +131,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 73c195bf745a..4d5b31aaa13d 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 b70b0b120700..8c72b53cb557 100644 --- a/x/staking/client/cli/tx.go +++ b/x/staking/client/cli/tx.go @@ -64,9 +64,23 @@ func NewCreateValidatorCmd() *cobra.Command { return err } +<<<<<<< HEAD txf := tx.NewFactoryCLI(clientCtx, cmd.Flags()). WithTxConfig(clientCtx.TxConfig).WithAccountRetriever(clientCtx.AccountRetriever) txf, msg, err := newBuildCreateValidatorMsg(clientCtx, txf, cmd.Flags()) +======= + txf, err := tx.NewFactoryCLI(clientCtx, cmd.Flags()) + 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) +>>>>>>> c71d19939 (fix: change the behavior of offline mode correctly (#15123)) if err != nil { return err }