refactor(authz): CLI tests using Tendermint Mock (#13517)
## Description Closes: #13487 --- ### 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/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)
This commit is contained in:
parent
de49cb4b1c
commit
d01aa5b4a8
|
@ -1,7 +1,7 @@
|
||||||
//go:build e2e
|
//go:build e2e
|
||||||
// +build e2e
|
// +build e2e
|
||||||
|
|
||||||
package testutil
|
package authz
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -9,12 +9,12 @@ import (
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"cosmossdk.io/simapp"
|
"cosmossdk.io/simapp"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||||
clienttestutil "github.com/cosmos/cosmos-sdk/x/authz/client/testutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIntegrationTestSuite(t *testing.T) {
|
func TestIntegrationTestSuite(t *testing.T) {
|
||||||
cfg := network.DefaultConfig(simapp.NewTestNetworkFixture)
|
cfg := network.DefaultConfig(simapp.NewTestNetworkFixture)
|
||||||
cfg.NumValidators = 1
|
cfg.NumValidators = 1
|
||||||
suite.Run(t, clienttestutil.NewIntegrationTestSuite(cfg))
|
suite.Run(t, NewIntegrationTestSuite(cfg))
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package testutil
|
package authz
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package testutil
|
package authz
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package testutil
|
package authz
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/cosmos/cosmos-sdk/testutil"
|
"github.com/cosmos/cosmos-sdk/testutil"
|
|
@ -1,4 +1,4 @@
|
||||||
package testutil
|
package authz
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -0,0 +1,238 @@
|
||||||
|
package cli_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
|
"github.com/cosmos/cosmos-sdk/testutil"
|
||||||
|
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *CLITestSuite) TestQueryAuthorizations() {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
|
||||||
|
grantee := s.grantee[0]
|
||||||
|
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||||
|
|
||||||
|
_, err := s.createGrant(
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
expectErr bool
|
||||||
|
expErrMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"Error: Invalid grantee",
|
||||||
|
[]string{
|
||||||
|
val[0].Address.String(),
|
||||||
|
"invalid grantee",
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"decoding bech32 failed: invalid character in string: ' '",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Error: Invalid granter",
|
||||||
|
[]string{
|
||||||
|
"invalid granter",
|
||||||
|
grantee.String(),
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"decoding bech32 failed: invalid character in string: ' '",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid txn (json)",
|
||||||
|
[]string{
|
||||||
|
val[0].Address.String(),
|
||||||
|
grantee.String(),
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
``,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
|
||||||
|
s.Run(tc.name, func() {
|
||||||
|
cmd := cli.GetCmdQueryGrants()
|
||||||
|
resp, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
|
||||||
|
if tc.expectErr {
|
||||||
|
s.Require().Error(err)
|
||||||
|
s.Require().Contains(string(resp.Bytes()), tc.expErrMsg)
|
||||||
|
} else {
|
||||||
|
s.Require().NoError(err)
|
||||||
|
var grants authz.QueryGrantsResponse
|
||||||
|
err = s.clientCtx.Codec.UnmarshalJSON(resp.Bytes(), &grants)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) TestQueryAuthorization() {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
|
||||||
|
grantee := s.grantee[0]
|
||||||
|
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||||
|
|
||||||
|
_, err := s.createGrant(
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
expectErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"Error: Invalid grantee",
|
||||||
|
[]string{
|
||||||
|
val[0].Address.String(),
|
||||||
|
"invalid grantee",
|
||||||
|
typeMsgSend,
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Error: Invalid granter",
|
||||||
|
[]string{
|
||||||
|
"invalid granter",
|
||||||
|
grantee.String(),
|
||||||
|
typeMsgSend,
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid txn (json)",
|
||||||
|
[]string{
|
||||||
|
val[0].Address.String(),
|
||||||
|
grantee.String(),
|
||||||
|
typeMsgSend,
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid txn with allowed list (json)",
|
||||||
|
[]string{
|
||||||
|
val[0].Address.String(),
|
||||||
|
s.grantee[3].String(),
|
||||||
|
typeMsgSend,
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
|
||||||
|
s.Run(tc.name, func() {
|
||||||
|
cmd := cli.GetCmdQueryGrants()
|
||||||
|
_, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
|
||||||
|
if tc.expectErr {
|
||||||
|
s.Require().Error(err)
|
||||||
|
} else {
|
||||||
|
s.Require().NoError(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) TestQueryGranterGrants() {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
|
||||||
|
grantee := s.grantee[0]
|
||||||
|
require := s.Require()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
expectErr bool
|
||||||
|
expectedErr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"invalid address",
|
||||||
|
[]string{
|
||||||
|
"invalid-address",
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"decoding bech32 failed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"no authorization found",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid case",
|
||||||
|
[]string{
|
||||||
|
val[0].Address.String(),
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid case with pagination",
|
||||||
|
[]string{
|
||||||
|
val[0].Address.String(),
|
||||||
|
"--limit=2",
|
||||||
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
s.Run(tc.name, func() {
|
||||||
|
cmd := cli.GetQueryGranterGrants()
|
||||||
|
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
|
||||||
|
if tc.expectErr {
|
||||||
|
require.Error(err)
|
||||||
|
require.Contains(out.String(), tc.expectedErr)
|
||||||
|
} else {
|
||||||
|
require.NoError(err)
|
||||||
|
var grants authz.QueryGranterGrantsResponse
|
||||||
|
require.NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &grants))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,919 @@
|
||||||
|
package cli_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/cosmos/gogoproto/proto"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
abci "github.com/tendermint/tendermint/abci/types"
|
||||||
|
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||||
|
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||||
|
rpcclientmock "github.com/tendermint/tendermint/rpc/client/mock"
|
||||||
|
coretypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||||
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
|
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||||
|
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||||
|
"github.com/cosmos/cosmos-sdk/testutil"
|
||||||
|
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||||
|
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||||
|
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||||
|
govcli "github.com/cosmos/cosmos-sdk/x/gov/client/cli"
|
||||||
|
govtestutil "github.com/cosmos/cosmos-sdk/x/gov/client/testutil"
|
||||||
|
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
|
||||||
|
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
typeMsgSend = banktypes.SendAuthorization{}.MsgTypeURL()
|
||||||
|
typeMsgVote = sdk.MsgTypeURL(&govv1.MsgVote{})
|
||||||
|
typeMsgSubmitProposal = sdk.MsgTypeURL(&govv1.MsgSubmitProposal{})
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ client.TendermintRPC = (*mockTendermintRPC)(nil)
|
||||||
|
|
||||||
|
type mockTendermintRPC struct {
|
||||||
|
rpcclientmock.Client
|
||||||
|
|
||||||
|
responseQuery abci.ResponseQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
func newMockTendermintRPC(respQuery abci.ResponseQuery) mockTendermintRPC {
|
||||||
|
return mockTendermintRPC{responseQuery: respQuery}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mockTendermintRPC) BroadcastTxSync(context.Context, tmtypes.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||||
|
return &coretypes.ResultBroadcastTx{Code: 0}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m mockTendermintRPC) ABCIQueryWithOptions(
|
||||||
|
_ context.Context,
|
||||||
|
_ string, _ tmbytes.HexBytes,
|
||||||
|
_ rpcclient.ABCIQueryOptions,
|
||||||
|
) (*coretypes.ResultABCIQuery, error) {
|
||||||
|
return &coretypes.ResultABCIQuery{Response: m.responseQuery}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type CLITestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
|
||||||
|
kr keyring.Keyring
|
||||||
|
encCfg testutilmod.TestEncodingConfig
|
||||||
|
baseCtx client.Context
|
||||||
|
clientCtx client.Context
|
||||||
|
grantee []sdk.AccAddress
|
||||||
|
addrs []sdk.AccAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCLITestSuite(t *testing.T) {
|
||||||
|
suite.Run(t, new(CLITestSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) SetupSuite() {
|
||||||
|
s.encCfg = testutilmod.MakeTestEncodingConfig(gov.AppModuleBasic{}, bank.AppModuleBasic{})
|
||||||
|
s.kr = keyring.NewInMemory(s.encCfg.Codec)
|
||||||
|
s.baseCtx = client.Context{}.
|
||||||
|
WithKeyring(s.kr).
|
||||||
|
WithTxConfig(s.encCfg.TxConfig).
|
||||||
|
WithCodec(s.encCfg.Codec).
|
||||||
|
WithClient(mockTendermintRPC{Client: rpcclientmock.Client{}}).
|
||||||
|
WithAccountRetriever(client.MockAccountRetriever{}).
|
||||||
|
WithOutput(io.Discard).
|
||||||
|
WithChainID("test-chain")
|
||||||
|
|
||||||
|
var outBuf bytes.Buffer
|
||||||
|
ctxGen := func() client.Context {
|
||||||
|
bz, _ := s.encCfg.Codec.Marshal(&sdk.TxResponse{})
|
||||||
|
c := newMockTendermintRPC(abci.ResponseQuery{
|
||||||
|
Value: bz,
|
||||||
|
})
|
||||||
|
return s.baseCtx.WithClient(c)
|
||||||
|
}
|
||||||
|
s.clientCtx = ctxGen().WithOutput(&outBuf)
|
||||||
|
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
s.grantee = make([]sdk.AccAddress, 6)
|
||||||
|
|
||||||
|
s.addrs = make([]sdk.AccAddress, 1)
|
||||||
|
s.addrs[0] = s.createAccount("validator address")
|
||||||
|
|
||||||
|
// Send some funds to the new account.
|
||||||
|
// Create new account in the keyring.
|
||||||
|
s.grantee[0] = s.createAccount("grantee1")
|
||||||
|
s.msgSendExec(s.grantee[0])
|
||||||
|
|
||||||
|
// create a proposal with deposit
|
||||||
|
_, err := govtestutil.MsgSubmitLegacyProposal(s.clientCtx, val[0].Address.String(),
|
||||||
|
"Text Proposal 1", "Where is the title!?", govv1beta1.ProposalTypeText,
|
||||||
|
fmt.Sprintf("--%s=%s", govcli.FlagDeposit, sdk.NewCoin("stake", govv1.DefaultMinDepositTokens).String()))
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// Create new account in the keyring.
|
||||||
|
s.grantee[1] = s.createAccount("grantee2")
|
||||||
|
// Send some funds to the new account.
|
||||||
|
s.msgSendExec(s.grantee[1])
|
||||||
|
|
||||||
|
// grant send authorization to grantee2
|
||||||
|
out, err := s.createGrant([]string{
|
||||||
|
s.grantee[1].String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()),
|
||||||
|
})
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
var response sdk.TxResponse
|
||||||
|
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String())
|
||||||
|
|
||||||
|
// Create new account in the keyring.
|
||||||
|
s.grantee[2] = s.createAccount("grantee3")
|
||||||
|
|
||||||
|
// grant send authorization to grantee3
|
||||||
|
_, err = s.createGrant([]string{
|
||||||
|
s.grantee[2].String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()),
|
||||||
|
})
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// Create new accounts in the keyring.
|
||||||
|
s.grantee[3] = s.createAccount("grantee4")
|
||||||
|
s.msgSendExec(s.grantee[3])
|
||||||
|
|
||||||
|
s.grantee[4] = s.createAccount("grantee5")
|
||||||
|
s.grantee[5] = s.createAccount("grantee6")
|
||||||
|
|
||||||
|
// grant send authorization with allow list to grantee4
|
||||||
|
out, err = s.createGrant(
|
||||||
|
[]string{
|
||||||
|
s.grantee[3].String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, time.Now().Add(time.Minute*time.Duration(120)).Unix()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagAllowList, s.grantee[4]),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) createAccount(uid string) sdk.AccAddress {
|
||||||
|
// Create new account in the keyring.
|
||||||
|
k, _, err := s.clientCtx.Keyring.NewMnemonic(uid, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
addr, err := k.GetAddress()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) msgSendExec(grantee sdk.AccAddress) {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
// Send some funds to the new account.
|
||||||
|
out, err := clitestutil.MsgSendExec(
|
||||||
|
s.clientCtx,
|
||||||
|
val[0].Address,
|
||||||
|
grantee,
|
||||||
|
sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(200))), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Contains(out.String(), `"code":0`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) createGrant(args []string) (testutil.BufferWriter, error) {
|
||||||
|
cmd := cli.NewCmdGrantAuthorization()
|
||||||
|
return clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) TestCLITxGrantAuthorization() {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
|
||||||
|
grantee := s.grantee[0]
|
||||||
|
|
||||||
|
twoHours := time.Now().Add(time.Minute * 120).Unix()
|
||||||
|
pastHour := time.Now().Add(-time.Minute * 60).Unix()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
expectErr bool
|
||||||
|
expErrMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"Invalid granter Address",
|
||||||
|
[]string{
|
||||||
|
"grantee_addr",
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, "granter"),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"key not found",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Invalid grantee Address",
|
||||||
|
[]string{
|
||||||
|
"grantee_addr",
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"invalid separator index",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Invalid expiration time",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagBroadcastMode),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, pastHour),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail with error invalid msg-type",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"generic",
|
||||||
|
fmt.Sprintf("--%s=invalid-msg-type", cli.FlagMsgType),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid bond denom for tx delegate authorization allowed validators",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"delegate",
|
||||||
|
fmt.Sprintf("--%s=100xyz", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, sdk.ValAddress(s.addrs[0]).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"invalid denom",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid bond denom for tx delegate authorization deny validators",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"delegate",
|
||||||
|
fmt.Sprintf("--%s=100xyz", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagDenyValidators, sdk.ValAddress(s.addrs[0]).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"invalid denom",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid bond denom for tx undelegate authorization",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"unbond",
|
||||||
|
fmt.Sprintf("--%s=100xyz", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, sdk.ValAddress(s.addrs[0]).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"invalid denom",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid bond denon for tx redelegate authorization",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"redelegate",
|
||||||
|
fmt.Sprintf("--%s=100xyz", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, sdk.ValAddress(s.addrs[0]).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"invalid denom",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid decimal coin expression with more than single coin",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"delegate",
|
||||||
|
fmt.Sprintf("--%s=100stake,20xyz", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagAllowedValidators, sdk.ValAddress(s.addrs[0]).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"invalid decimal coin expression",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid tx send authorization",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid tx send authorization with allow list",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagAllowList, s.grantee[1]),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Invalid tx send authorization with duplicate allow list",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagAllowList, fmt.Sprintf("%s,%s", s.grantee[1], s.grantee[1])),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"duplicate entry",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid tx generic authorization",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"generic",
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail when granter = grantee",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"generic",
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
"grantee and granter should be different",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid tx with amino",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"generic",
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
s.Run(tc.name, func() {
|
||||||
|
out, err := s.createGrant(
|
||||||
|
tc.args,
|
||||||
|
)
|
||||||
|
if tc.expectErr {
|
||||||
|
s.Require().Error(err, out)
|
||||||
|
s.Require().Contains(err.Error(), tc.expErrMsg)
|
||||||
|
} else {
|
||||||
|
var txResp sdk.TxResponse
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &txResp), out.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) TestCmdRevokeAuthorizations() {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
|
||||||
|
grantee := s.grantee[0]
|
||||||
|
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||||
|
|
||||||
|
// send-authorization
|
||||||
|
_, err := s.createGrant(
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// generic-authorization
|
||||||
|
_, err = s.createGrant(
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"generic",
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// generic-authorization used for amino testing
|
||||||
|
_, err = s.createGrant(
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"generic",
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgSubmitProposal),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
respType proto.Message
|
||||||
|
expectErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"invalid grantee address",
|
||||||
|
[]string{
|
||||||
|
"invalid grantee",
|
||||||
|
typeMsgSend,
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid granter address",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
typeMsgSend,
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, "granter"),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid tx send authorization",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
typeMsgSend,
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
&sdk.TxResponse{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid tx generic authorization",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
typeMsgVote,
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
&sdk.TxResponse{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Valid tx with amino",
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
typeMsgSubmitProposal,
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
||||||
|
},
|
||||||
|
&sdk.TxResponse{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
s.Run(tc.name, func() {
|
||||||
|
cmd := cli.NewCmdRevokeAuthorization()
|
||||||
|
|
||||||
|
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
|
||||||
|
if tc.expectErr {
|
||||||
|
s.Require().Error(err)
|
||||||
|
} else {
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) TestExecAuthorizationWithExpiration() {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
|
||||||
|
grantee := s.grantee[0]
|
||||||
|
tenSeconds := time.Now().Add(time.Second * time.Duration(10)).Unix()
|
||||||
|
|
||||||
|
_, err := s.createGrant(
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"generic",
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, tenSeconds),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
// msg vote
|
||||||
|
voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val[0].Address.String())
|
||||||
|
execMsg := testutil.WriteToNewTempFile(s.T(), voteTx)
|
||||||
|
defer execMsg.Close()
|
||||||
|
|
||||||
|
// waiting for authorization to expire
|
||||||
|
time.Sleep(12 * time.Second)
|
||||||
|
|
||||||
|
cmd := cli.NewCmdExecAuthorization()
|
||||||
|
|
||||||
|
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, []string{
|
||||||
|
execMsg.Name(),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
})
|
||||||
|
s.Require().NoError(err)
|
||||||
|
var response sdk.TxResponse
|
||||||
|
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) TestNewExecGenericAuthorized() {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
grantee := s.grantee[0]
|
||||||
|
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||||
|
|
||||||
|
_, err := s.createGrant(
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"generic",
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// msg vote
|
||||||
|
voteTx := fmt.Sprintf(`{"body":{"messages":[{"@type":"/cosmos.gov.v1.MsgVote","proposal_id":"1","voter":"%s","option":"VOTE_OPTION_YES"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}`, val[0].Address.String())
|
||||||
|
execMsg := testutil.WriteToNewTempFile(s.T(), voteTx)
|
||||||
|
defer execMsg.Close()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
respType proto.Message
|
||||||
|
expectErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"fail invalid grantee",
|
||||||
|
[]string{
|
||||||
|
execMsg.Name(),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, "grantee"),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fail invalid json path",
|
||||||
|
[]string{
|
||||||
|
"/invalid/file.txt",
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid txn",
|
||||||
|
[]string{
|
||||||
|
execMsg.Name(),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
},
|
||||||
|
&sdk.TxResponse{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid tx with amino",
|
||||||
|
[]string{
|
||||||
|
execMsg.Name(),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
||||||
|
},
|
||||||
|
&sdk.TxResponse{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
s.Run(tc.name, func() {
|
||||||
|
cmd := cli.NewCmdExecAuthorization()
|
||||||
|
|
||||||
|
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
|
||||||
|
if tc.expectErr {
|
||||||
|
s.Require().Error(err)
|
||||||
|
} else {
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) TestNewExecGrantAuthorized() {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
grantee := s.grantee[0]
|
||||||
|
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||||
|
|
||||||
|
_, err := s.createGrant(
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=12testtoken", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
tokens := sdk.NewCoins(
|
||||||
|
sdk.NewCoin("testtoken", sdk.NewInt(12)),
|
||||||
|
)
|
||||||
|
normalGeneratedTx, err := clitestutil.MsgSendExec(
|
||||||
|
s.clientCtx,
|
||||||
|
val[0].Address,
|
||||||
|
grantee,
|
||||||
|
tokens,
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
execMsg := testutil.WriteToNewTempFile(s.T(), normalGeneratedTx.String())
|
||||||
|
defer execMsg.Close()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
args []string
|
||||||
|
expectErr bool
|
||||||
|
expectErrMsg string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"valid txn",
|
||||||
|
[]string{
|
||||||
|
execMsg.Name(),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"error over spent",
|
||||||
|
[]string{
|
||||||
|
execMsg.Name(),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
s.Run(tc.name, func() {
|
||||||
|
cmd := cli.NewCmdExecAuthorization()
|
||||||
|
clientCtx := s.clientCtx
|
||||||
|
|
||||||
|
var response sdk.TxResponse
|
||||||
|
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||||
|
switch {
|
||||||
|
case tc.expectErrMsg != "":
|
||||||
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String())
|
||||||
|
s.Require().Contains(response.RawLog, tc.expectErrMsg)
|
||||||
|
|
||||||
|
case tc.expectErr:
|
||||||
|
s.Require().Error(err)
|
||||||
|
|
||||||
|
default:
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *CLITestSuite) TestExecSendAuthzWithAllowList() {
|
||||||
|
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
grantee := s.grantee[3]
|
||||||
|
|
||||||
|
allowedAddr := s.grantee[4]
|
||||||
|
notAllowedAddr := s.grantee[5]
|
||||||
|
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
|
||||||
|
|
||||||
|
_, err := s.createGrant(
|
||||||
|
[]string{
|
||||||
|
grantee.String(),
|
||||||
|
"send",
|
||||||
|
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=%s", cli.FlagAllowList, allowedAddr),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
tokens := sdk.NewCoins(
|
||||||
|
sdk.NewCoin("stake", sdk.NewInt(12)),
|
||||||
|
)
|
||||||
|
|
||||||
|
validGeneratedTx, err := clitestutil.MsgSendExec(
|
||||||
|
s.clientCtx,
|
||||||
|
val[0].Address,
|
||||||
|
allowedAddr,
|
||||||
|
tokens,
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
execMsg := testutil.WriteToNewTempFile(s.T(), validGeneratedTx.String())
|
||||||
|
defer execMsg.Close()
|
||||||
|
|
||||||
|
invalidGeneratedTx, err := clitestutil.MsgSendExec(
|
||||||
|
s.clientCtx,
|
||||||
|
val[0].Address,
|
||||||
|
notAllowedAddr,
|
||||||
|
tokens,
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
|
||||||
|
)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
execMsg1 := testutil.WriteToNewTempFile(s.T(), invalidGeneratedTx.String())
|
||||||
|
defer execMsg1.Close()
|
||||||
|
|
||||||
|
// test sending to allowed address
|
||||||
|
args := []string{
|
||||||
|
execMsg.Name(),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
}
|
||||||
|
var response sdk.TxResponse
|
||||||
|
cmd := cli.NewCmdExecAuthorization()
|
||||||
|
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String())
|
||||||
|
|
||||||
|
// test sending to not allowed address
|
||||||
|
args = []string{
|
||||||
|
execMsg1.Name(),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, grantee.String()),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(10))).String()),
|
||||||
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
|
}
|
||||||
|
out, err = clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response), out.String())
|
||||||
|
}
|
Loading…
Reference in New Issue