Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: --generate-only and --offline flags can use keyname. #9838

Merged
merged 10 commits into from
Aug 9, 2021
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#9533](https://github.com/cosmos/cosmos-sdk/pull/9533) Added a new gRPC method, `DenomOwners`, in `x/bank` to query for all account holders of a specific denomination.
* (bank) [\#9618](https://github.com/cosmos/cosmos-sdk/pull/9618) Update bank.Metadata: add URI and URIHash attributes.
* [\#9750](https://github.com/cosmos/cosmos-sdk/pull/9750) Emit events for tx signature and sequence, so clients can now query txs by signature (`tx.signature='<base64_sig>'`) or by address and sequence combo (`tx.acc_seq='<addr>/<seq>'`).
* [\#9837](https://github.com/cosmos/cosmos-sdk/issues/9837) `--generate-only` flag will accept the keyname now.

### API Breaking Changes

Expand Down
10 changes: 0 additions & 10 deletions client/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"gopkg.in/yaml.v2"

"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
rpcclient "github.com/tendermint/tendermint/rpc/client"

"github.com/cosmos/cosmos-sdk/codec"
Expand Down Expand Up @@ -324,15 +323,6 @@ func GetFromFields(kr keyring.Keyring, from string, genOnly bool) (sdk.AccAddres
return nil, "", 0, nil
}

if genOnly {
addr, err := sdk.AccAddressFromBech32(from)
if err != nil {
return nil, "", 0, errors.Wrap(err, "must provide a valid Bech32 address in generate-only mode")
}

return addr, "", 0, nil
}

var info keyring.Info
if addr, err := sdk.AccAddressFromBech32(from); err == nil {
info, err = kr.KeyByAddress(addr)
Expand Down
111 changes: 111 additions & 0 deletions x/auth/client/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authcli "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bank "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
Expand Down Expand Up @@ -108,6 +109,116 @@ func (s *IntegrationTestSuite) TestCLIValidateSignatures() {
s.Require().EqualError(err, "signatures validation failed")
}

func (s *IntegrationTestSuite) TestCLISignGenOnly() {
val := s.network.Validators[0]
val2 := s.network.Validators[1]

info, err := val.ClientCtx.Keyring.KeyByAddress(val.Address)
s.Require().NoError(err)
keyName := info.GetName()

account, err := val.ClientCtx.AccountRetriever.GetAccount(val.ClientCtx, info.GetAddress())
s.Require().NoError(err)

sendTokens := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)))
args := []string{
keyName, // from keyname
val2.Address.String(),
sendTokens.String(),
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), // shouldn't break if we use keyname with --generate-only flag
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
}
generatedStd, err := clitestutil.ExecTestCLICmd(val.ClientCtx, bank.NewSendTxCmd(), args)
s.Require().NoError(err)
opFile := testutil.WriteToNewTempFile(s.T(), generatedStd.String())

commonArgs := []string{
fmt.Sprintf("--%s=%s", flags.FlagKeyringBackend, keyring.BackendTest),
fmt.Sprintf("--%s=%s", flags.FlagHome, strings.Replace(val.ClientCtx.HomeDir, "simd", "simcli", 1)),
fmt.Sprintf("--%s=%s", flags.FlagChainID, val.ClientCtx.ChainID),
}

cases := []struct {
name string
args []string
expErr bool
errMsg string
}{
{
"offline mode with account-number, sequence and keyname (valid)",
[]string{
opFile.Name(),
fmt.Sprintf("--%s=true", flags.FlagOffline),
fmt.Sprintf("--%s=%s", flags.FlagFrom, keyName),
fmt.Sprintf("--%s=%d", flags.FlagAccountNumber, account.GetAccountNumber()),
fmt.Sprintf("--%s=%d", flags.FlagSequence, account.GetSequence()),
},
false,
"",
},
{
"offline mode with account-number, sequence and address key (valid)",
[]string{
opFile.Name(),
fmt.Sprintf("--%s=true", flags.FlagOffline),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=%d", flags.FlagAccountNumber, account.GetAccountNumber()),
fmt.Sprintf("--%s=%d", flags.FlagSequence, account.GetSequence()),
},
false,
"",
},
{
"offline mode without account-number and keyname (invalid)",
[]string{
opFile.Name(),
fmt.Sprintf("--%s=true", flags.FlagOffline),
fmt.Sprintf("--%s=%s", flags.FlagFrom, keyName),
fmt.Sprintf("--%s=%d", flags.FlagSequence, account.GetSequence()),
},
true,
`required flag(s) "account-number" not set`,
},
{
"offline mode without sequence and keyname (invalid)",
[]string{
opFile.Name(),
fmt.Sprintf("--%s=true", flags.FlagOffline),
fmt.Sprintf("--%s=%s", flags.FlagFrom, keyName),
fmt.Sprintf("--%s=%d", flags.FlagAccountNumber, account.GetAccountNumber()),
},
true,
`required flag(s) "sequence" not set`,
},
{
"offline mode without account-number, sequence and keyname (invalid)",
[]string{
opFile.Name(),
fmt.Sprintf("--%s=%s", flags.FlagFrom, keyName),
fmt.Sprintf("--%s=true", flags.FlagOffline),
},
true,
`required flag(s) "account-number", "sequence" not set`,
atheeshp marked this conversation as resolved.
Show resolved Hide resolved
},
}

for _, tc := range cases {
cmd := authcli.GetSignCommand()
tmcli.PrepareBaseCmd(cmd, "", "")
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, append(tc.args, commonArgs...))
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.errMsg)
} else {
s.Require().NoError(err)
signedTx := testutil.WriteToNewTempFile(s.T(), out.String())
_, err := TxBroadcastExec(val.ClientCtx, signedTx.Name())
s.Require().NoError(err)
}
}
}

func (s *IntegrationTestSuite) TestCLISignBatch() {
val := s.network.Validators[0]
var sendTokens = sdk.NewCoins(
Expand Down