985 lines
26 KiB
Go
985 lines
26 KiB
Go
package testutil
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cosmos/gogoproto/proto"
|
|
"github.com/stretchr/testify/suite"
|
|
tmcli "github.com/tendermint/tendermint/libs/cli"
|
|
|
|
"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"
|
|
"github.com/cosmos/cosmos-sdk/testutil/network"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/cosmos/cosmos-sdk/x/feegrant"
|
|
"github.com/cosmos/cosmos-sdk/x/feegrant/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"
|
|
)
|
|
|
|
const (
|
|
oneYear = 365 * 24 * 60 * 60
|
|
tenHours = 10 * 60 * 60
|
|
oneHour = 60 * 60
|
|
)
|
|
|
|
type IntegrationTestSuite struct {
|
|
suite.Suite
|
|
|
|
cfg network.Config
|
|
network *network.Network
|
|
addedGranter sdk.AccAddress
|
|
addedGrantee sdk.AccAddress
|
|
addedGrant feegrant.Grant
|
|
}
|
|
|
|
func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite {
|
|
return &IntegrationTestSuite{cfg: cfg}
|
|
}
|
|
|
|
func (s *IntegrationTestSuite) SetupSuite() {
|
|
s.T().Log("setting up integration test suite")
|
|
|
|
if testing.Short() {
|
|
s.T().Skip("skipping test in unit-tests mode.")
|
|
}
|
|
|
|
var err error
|
|
s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg)
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().NoError(s.network.WaitForNextBlock())
|
|
|
|
val := s.network.Validators[0]
|
|
granter := val.Address
|
|
grantee := s.network.Validators[1].Address
|
|
|
|
s.createGrant(granter, grantee)
|
|
|
|
grant, err := feegrant.NewGrant(granter, grantee, &feegrant.BasicAllowance{
|
|
SpendLimit: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(100))),
|
|
})
|
|
s.Require().NoError(err)
|
|
|
|
s.addedGrant = grant
|
|
s.addedGranter = granter
|
|
s.addedGrantee = grantee
|
|
}
|
|
|
|
// createGrant creates a new basic allowance fee grant from granter to grantee.
|
|
func (s *IntegrationTestSuite) createGrant(granter, grantee sdk.Address) {
|
|
val := s.network.Validators[0]
|
|
|
|
clientCtx := val.ClientCtx
|
|
commonFlags := []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(s.cfg.BondDenom, sdk.NewInt(100))).String()),
|
|
}
|
|
|
|
fee := sdk.NewCoin("stake", sdk.NewInt(100))
|
|
|
|
args := append(
|
|
[]string{
|
|
granter.String(),
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, fee.String()),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", cli.FlagExpiration, getFormattedExpiration(oneYear)),
|
|
},
|
|
commonFlags...,
|
|
)
|
|
|
|
cmd := cli.NewCmdFeeGrant()
|
|
_, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
|
s.Require().NoError(err)
|
|
s.Require().NoError(s.network.WaitForNextBlock())
|
|
}
|
|
|
|
func (s *IntegrationTestSuite) TearDownSuite() {
|
|
s.T().Log("tearing down integration test suite")
|
|
s.network.Cleanup()
|
|
}
|
|
|
|
func (s *IntegrationTestSuite) TestCmdGetFeeGrant() {
|
|
val := s.network.Validators[0]
|
|
granter := val.Address
|
|
grantee := s.addedGrantee
|
|
clientCtx := val.ClientCtx
|
|
|
|
testCases := []struct {
|
|
name string
|
|
args []string
|
|
expectErrMsg string
|
|
expectErr bool
|
|
respType *feegrant.Grant
|
|
resp *feegrant.Grant
|
|
}{
|
|
{
|
|
"wrong granter",
|
|
[]string{
|
|
"wrong_granter",
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
"decoding bech32 failed",
|
|
true, nil, nil,
|
|
},
|
|
{
|
|
"wrong grantee",
|
|
[]string{
|
|
granter.String(),
|
|
"wrong_grantee",
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
"decoding bech32 failed",
|
|
true, nil, nil,
|
|
},
|
|
{
|
|
"non existed grant",
|
|
[]string{
|
|
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
"fee-grant not found",
|
|
true, nil, nil,
|
|
},
|
|
{
|
|
"valid req",
|
|
[]string{
|
|
granter.String(),
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
"",
|
|
false,
|
|
&feegrant.Grant{},
|
|
&s.addedGrant,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
|
|
s.Run(tc.name, func() {
|
|
cmd := cli.GetCmdQueryFeeGrant()
|
|
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
|
|
|
if tc.expectErr {
|
|
s.Require().Error(err)
|
|
s.Require().Contains(err.Error(), tc.expectErrMsg)
|
|
} else {
|
|
s.Require().NoError(err)
|
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
|
s.Require().Equal(tc.respType.Grantee, tc.respType.Grantee)
|
|
s.Require().Equal(tc.respType.Granter, tc.respType.Granter)
|
|
grant, err := tc.respType.GetGrant()
|
|
s.Require().NoError(err)
|
|
grant1, err1 := tc.resp.GetGrant()
|
|
s.Require().NoError(err1)
|
|
s.Require().Equal(
|
|
grant.(*feegrant.BasicAllowance).SpendLimit,
|
|
grant1.(*feegrant.BasicAllowance).SpendLimit,
|
|
)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (s *IntegrationTestSuite) TestCmdGetFeeGrantsByGrantee() {
|
|
val := s.network.Validators[0]
|
|
grantee := s.addedGrantee
|
|
clientCtx := val.ClientCtx
|
|
|
|
testCases := []struct {
|
|
name string
|
|
args []string
|
|
expectErr bool
|
|
resp *feegrant.QueryAllowancesResponse
|
|
expectLength int
|
|
}{
|
|
{
|
|
"wrong grantee",
|
|
[]string{
|
|
"wrong_grantee",
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
true, nil, 0,
|
|
},
|
|
{
|
|
"non existent grantee",
|
|
[]string{
|
|
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
false, &feegrant.QueryAllowancesResponse{}, 0,
|
|
},
|
|
{
|
|
"valid req",
|
|
[]string{
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
false, &feegrant.QueryAllowancesResponse{}, 1,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
|
|
s.Run(tc.name, func() {
|
|
cmd := cli.GetCmdQueryFeeGrantsByGrantee()
|
|
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
|
|
|
if tc.expectErr {
|
|
s.Require().Error(err)
|
|
} else {
|
|
s.Require().NoError(err)
|
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.resp), out.String())
|
|
s.Require().Len(tc.resp.Allowances, tc.expectLength)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (s *IntegrationTestSuite) TestCmdGetFeeGrantsByGranter() {
|
|
val := s.network.Validators[0]
|
|
granter := s.addedGranter
|
|
clientCtx := val.ClientCtx
|
|
|
|
testCases := []struct {
|
|
name string
|
|
args []string
|
|
expectErr bool
|
|
resp *feegrant.QueryAllowancesByGranterResponse
|
|
expectLength int
|
|
}{
|
|
{
|
|
"wrong grantee",
|
|
[]string{
|
|
"wrong_grantee",
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
true, nil, 0,
|
|
},
|
|
{
|
|
"non existent grantee",
|
|
[]string{
|
|
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
false, &feegrant.QueryAllowancesByGranterResponse{}, 0,
|
|
},
|
|
{
|
|
"valid req",
|
|
[]string{
|
|
granter.String(),
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
},
|
|
false, &feegrant.QueryAllowancesByGranterResponse{}, 1,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
|
|
s.Run(tc.name, func() {
|
|
cmd := cli.GetCmdQueryFeeGrantsByGranter()
|
|
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
|
|
|
if tc.expectErr {
|
|
s.Require().Error(err)
|
|
} else {
|
|
s.Require().NoError(err)
|
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.resp), out.String())
|
|
s.Require().Len(tc.resp.Allowances, tc.expectLength)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (s *IntegrationTestSuite) TestNewCmdFeeGrant() {
|
|
val := s.network.Validators[0]
|
|
granter := val.Address
|
|
alreadyExistedGrantee := s.addedGrantee
|
|
clientCtx := val.ClientCtx
|
|
|
|
fromAddr, fromName, _, err := client.GetFromFields(clientCtx, clientCtx.Keyring, granter.String())
|
|
s.Require().Equal(fromAddr, granter)
|
|
s.Require().NoError(err)
|
|
|
|
commonFlags := []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(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
args []string
|
|
expectErr bool
|
|
expectedCode uint32
|
|
respType proto.Message
|
|
}{
|
|
{
|
|
"wrong granter address",
|
|
append(
|
|
[]string{
|
|
"wrong_granter",
|
|
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, 0, nil,
|
|
},
|
|
{
|
|
"wrong grantee address",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"wrong_grantee",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, 0, nil,
|
|
},
|
|
{
|
|
"wrong granter key name",
|
|
append(
|
|
[]string{
|
|
"invalid_granter",
|
|
"cosmos16dun6ehcc86e03wreqqww89ey569wuj4em572w",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, 0, nil,
|
|
},
|
|
{
|
|
"valid basic fee grant",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"valid basic fee grant with granter key name",
|
|
append(
|
|
[]string{
|
|
fromName,
|
|
"cosmos16dun6ehcc86e03wreqqww89ey569wuj4em572w",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, fromName),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"valid basic fee grant with amino",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1v57fx2l2rt6ehujuu99u2fw05779m5e2ux4z2h",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"valid basic fee grant without spend limit",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos17h5lzptx3ghvsuhk7wx4c4hnl7rsswxjer97em",
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"valid basic fee grant without expiration",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos16dlc38dcqt0uralyd8hksxyrny6kaeqfjvjwp5",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"valid basic fee grant without spend-limit and expiration",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1ku40qup9vwag4wtf8cls9mkszxfthaklxkp3c8",
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"try to add existed grant",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
alreadyExistedGrantee.String(),
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 18, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"invalid number of args(periodic fee grant)",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", cli.FlagPeriodLimit, "10stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", cli.FlagExpiration, getFormattedExpiration(tenHours)),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, 0, nil,
|
|
},
|
|
{
|
|
"period mentioned and period limit omitted, invalid periodic grant",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%d", cli.FlagPeriod, tenHours),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", cli.FlagExpiration, getFormattedExpiration(oneHour)),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, 0, nil,
|
|
},
|
|
{
|
|
"period cannot be greater than the actual expiration(periodic fee grant)",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%d", cli.FlagPeriod, tenHours),
|
|
fmt.Sprintf("--%s=%s", cli.FlagPeriodLimit, "10stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", cli.FlagExpiration, getFormattedExpiration(oneHour)),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, 0, nil,
|
|
},
|
|
{
|
|
"valid periodic fee grant",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1w55kgcf3ltaqdy4ww49nge3klxmrdavrr6frmp",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%d", cli.FlagPeriod, oneHour),
|
|
fmt.Sprintf("--%s=%s", cli.FlagPeriodLimit, "10stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", cli.FlagExpiration, getFormattedExpiration(tenHours)),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"valid periodic fee grant without spend-limit",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1vevyks8pthkscvgazc97qyfjt40m6g9xe85ry8",
|
|
fmt.Sprintf("--%s=%d", cli.FlagPeriod, oneHour),
|
|
fmt.Sprintf("--%s=%s", cli.FlagPeriodLimit, "10stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", cli.FlagExpiration, getFormattedExpiration(tenHours)),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"valid periodic fee grant without expiration",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos14cm33pvnrv2497tyt8sp9yavhmw83nwej3m0e8",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%d", cli.FlagPeriod, oneHour),
|
|
fmt.Sprintf("--%s=%s", cli.FlagPeriodLimit, "10stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"valid periodic fee grant without spend-limit and expiration",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos12nyk4pcf4arshznkpz882e4l4ts0lt0ap8ce54",
|
|
fmt.Sprintf("--%s=%d", cli.FlagPeriod, oneHour),
|
|
fmt.Sprintf("--%s=%s", cli.FlagPeriodLimit, "10stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"invalid expiration",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1vevyks8pthkscvgazc97qyfjt40m6g9xe85ry8",
|
|
fmt.Sprintf("--%s=%d", cli.FlagPeriod, oneHour),
|
|
fmt.Sprintf("--%s=%s", cli.FlagPeriodLimit, "10stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", cli.FlagExpiration, "invalid"),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, 0, nil,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
|
|
s.Run(tc.name, func() {
|
|
cmd := cli.NewCmdFeeGrant()
|
|
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
|
|
|
if tc.expectErr {
|
|
s.Require().Error(err)
|
|
} else {
|
|
s.Require().NoError(err)
|
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
|
|
|
txResp := tc.respType.(*sdk.TxResponse)
|
|
s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (s *IntegrationTestSuite) TestNewCmdRevokeFeegrant() {
|
|
val := s.network.Validators[0]
|
|
granter := s.addedGranter
|
|
grantee := s.addedGrantee
|
|
clientCtx := val.ClientCtx
|
|
|
|
commonFlags := []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(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
|
}
|
|
|
|
// Create new fee grant specifically to test amino.
|
|
aminoGrantee, err := sdk.AccAddressFromBech32("cosmos16ydaqh0fcnh4qt7a3jme4mmztm2qel5axcpw00")
|
|
s.Require().NoError(err)
|
|
s.createGrant(granter, aminoGrantee)
|
|
|
|
testCases := []struct {
|
|
name string
|
|
args []string
|
|
expectErr bool
|
|
expectedCode uint32
|
|
respType proto.Message
|
|
}{
|
|
{
|
|
"invalid grantee",
|
|
append(
|
|
[]string{
|
|
"wrong_granter",
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, 0, nil,
|
|
},
|
|
{
|
|
"invalid grantee",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"wrong_grantee",
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, 0, nil,
|
|
},
|
|
{
|
|
"Non existed grant",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"cosmos1aeuqja06474dfrj7uqsvukm6rael982kk89mqr",
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 38, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"Valid revoke",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
{
|
|
"Valid revoke with amino",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
aminoGrantee.String(),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, 0, &sdk.TxResponse{},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
|
|
s.Run(tc.name, func() {
|
|
cmd := cli.NewCmdRevokeFeegrant()
|
|
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
|
|
|
if tc.expectErr {
|
|
s.Require().Error(err)
|
|
} else {
|
|
s.Require().NoError(err)
|
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
|
|
|
txResp := tc.respType.(*sdk.TxResponse)
|
|
s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (s *IntegrationTestSuite) TestTxWithFeeGrant() {
|
|
val := s.network.Validators[0]
|
|
clientCtx := val.ClientCtx
|
|
granter := val.Address
|
|
|
|
// creating an account manually (This account won't be exist in state)
|
|
k, _, err := val.ClientCtx.Keyring.NewMnemonic("grantee", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
|
|
s.Require().NoError(err)
|
|
pub, err := k.GetPubKey()
|
|
s.Require().NoError(err)
|
|
grantee := sdk.AccAddress(pub.Address())
|
|
|
|
commonFlags := []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(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
|
}
|
|
|
|
fee := sdk.NewCoin("stake", sdk.NewInt(100))
|
|
|
|
args := append(
|
|
[]string{
|
|
granter.String(),
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, fee.String()),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
fmt.Sprintf("--%s=%s", cli.FlagExpiration, getFormattedExpiration(oneYear)),
|
|
},
|
|
commonFlags...,
|
|
)
|
|
|
|
cmd := cli.NewCmdFeeGrant()
|
|
|
|
_, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
|
s.Require().NoError(err)
|
|
s.Require().NoError(s.network.WaitForNextBlock())
|
|
|
|
testcases := []struct {
|
|
name string
|
|
from string
|
|
flags []string
|
|
expErrCode uint32
|
|
}{
|
|
{
|
|
name: "granted fee allowance for an account which is not in state and creating any tx with it by using --fee-granter shouldn't fail",
|
|
from: grantee.String(),
|
|
flags: []string{fmt.Sprintf("--%s=%s", flags.FlagFeeGranter, granter.String())},
|
|
},
|
|
{
|
|
name: "--fee-payer should also sign the tx (direct)",
|
|
from: grantee.String(),
|
|
flags: []string{fmt.Sprintf("--%s=%s", flags.FlagFeePayer, granter.String())},
|
|
expErrCode: 4,
|
|
},
|
|
{
|
|
name: "--fee-payer should also sign the tx (amino-json)",
|
|
from: grantee.String(),
|
|
flags: []string{
|
|
fmt.Sprintf("--%s=%s", flags.FlagFeePayer, granter.String()),
|
|
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
|
|
},
|
|
expErrCode: 4,
|
|
},
|
|
{
|
|
name: "use --fee-payer and --fee-granter together works",
|
|
from: grantee.String(),
|
|
flags: []string{
|
|
fmt.Sprintf("--%s=%s", flags.FlagFeePayer, grantee.String()),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFeeGranter, granter.String()),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
s.Run(tc.name, func() {
|
|
out, err := govtestutil.MsgSubmitLegacyProposal(val.ClientCtx, tc.from,
|
|
"Text Proposal", "No desc", govv1beta1.ProposalTypeText,
|
|
tc.flags...,
|
|
)
|
|
s.Require().NoError(err)
|
|
|
|
var resp sdk.TxResponse
|
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp), out.String())
|
|
s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, resp.TxHash, tc.expErrCode))
|
|
})
|
|
}
|
|
}
|
|
|
|
func (s *IntegrationTestSuite) TestFilteredFeeAllowance() {
|
|
val := s.network.Validators[0]
|
|
|
|
granter := val.Address
|
|
k, _, err := val.ClientCtx.Keyring.NewMnemonic("grantee1", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
|
|
s.Require().NoError(err)
|
|
pub, err := k.GetPubKey()
|
|
s.Require().NoError(err)
|
|
grantee := sdk.AccAddress(pub.Address())
|
|
|
|
clientCtx := val.ClientCtx
|
|
|
|
commonFlags := []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(s.cfg.BondDenom, sdk.NewInt(100))).String()),
|
|
}
|
|
spendLimit := sdk.NewCoin("stake", sdk.NewInt(1000))
|
|
|
|
allowMsgs := strings.Join([]string{sdk.MsgTypeURL(&govv1beta1.MsgSubmitProposal{}), sdk.MsgTypeURL(&govv1.MsgVoteWeighted{})}, ",")
|
|
|
|
testCases := []struct {
|
|
name string
|
|
args []string
|
|
expectErr bool
|
|
respType proto.Message
|
|
expectedCode uint32
|
|
}{
|
|
{
|
|
"invalid granter address",
|
|
append(
|
|
[]string{
|
|
"not an address",
|
|
"cosmos1nph3cfzk6trsmfxkeu943nvach5qw4vwstnvkl",
|
|
fmt.Sprintf("--%s=%s", cli.FlagAllowedMsgs, allowMsgs),
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, spendLimit.String()),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, &sdk.TxResponse{}, 0,
|
|
},
|
|
{
|
|
"invalid grantee address",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
"not an address",
|
|
fmt.Sprintf("--%s=%s", cli.FlagAllowedMsgs, allowMsgs),
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, spendLimit.String()),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
true, &sdk.TxResponse{}, 0,
|
|
},
|
|
{
|
|
"valid filter fee grant",
|
|
append(
|
|
[]string{
|
|
granter.String(),
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=%s", cli.FlagAllowedMsgs, allowMsgs),
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, spendLimit.String()),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, granter),
|
|
},
|
|
commonFlags...,
|
|
),
|
|
false, &sdk.TxResponse{}, 0,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc := tc
|
|
|
|
s.Run(tc.name, func() {
|
|
cmd := cli.NewCmdFeeGrant()
|
|
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
|
|
|
if tc.expectErr {
|
|
s.Require().Error(err)
|
|
} else {
|
|
s.Require().NoError(err)
|
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
|
|
|
txResp := tc.respType.(*sdk.TxResponse)
|
|
s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode))
|
|
}
|
|
})
|
|
}
|
|
|
|
args := []string{
|
|
granter.String(),
|
|
grantee.String(),
|
|
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
|
}
|
|
|
|
// get filtered fee allowance and check info
|
|
cmd := cli.GetCmdQueryFeeGrant()
|
|
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
|
s.Require().NoError(err)
|
|
|
|
resp := &feegrant.Grant{}
|
|
|
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), resp), out.String())
|
|
s.Require().Equal(resp.Grantee, resp.Grantee)
|
|
s.Require().Equal(resp.Granter, resp.Granter)
|
|
|
|
grant, err := resp.GetGrant()
|
|
s.Require().NoError(err)
|
|
|
|
filteredFeeGrant, err := grant.(*feegrant.AllowedMsgAllowance).GetAllowance()
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(
|
|
filteredFeeGrant.(*feegrant.BasicAllowance).SpendLimit.String(),
|
|
spendLimit.String(),
|
|
)
|
|
|
|
// exec filtered fee allowance
|
|
cases := []struct {
|
|
name string
|
|
malleate func() (testutil.BufferWriter, error)
|
|
respType proto.Message
|
|
expectedCode uint32
|
|
}{
|
|
{
|
|
"valid proposal tx",
|
|
func() (testutil.BufferWriter, error) {
|
|
return govtestutil.MsgSubmitLegacyProposal(val.ClientCtx, grantee.String(),
|
|
"Text Proposal", "No desc", govv1beta1.ProposalTypeText,
|
|
fmt.Sprintf("--%s=%s", flags.FlagFeeGranter, granter.String()),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(100))).String()),
|
|
)
|
|
},
|
|
&sdk.TxResponse{},
|
|
0,
|
|
},
|
|
{
|
|
"valid weighted_vote tx",
|
|
func() (testutil.BufferWriter, error) {
|
|
return govtestutil.MsgVote(val.ClientCtx, grantee.String(), "0", "yes",
|
|
fmt.Sprintf("--%s=%s", flags.FlagFeeGranter, granter.String()),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(100))).String()),
|
|
)
|
|
},
|
|
&sdk.TxResponse{},
|
|
2,
|
|
},
|
|
{
|
|
"should fail with unauthorized msgs",
|
|
func() (testutil.BufferWriter, error) {
|
|
args := append(
|
|
[]string{
|
|
grantee.String(),
|
|
"cosmos14cm33pvnrv2497tyt8sp9yavhmw83nwej3m0e8",
|
|
fmt.Sprintf("--%s=%s", cli.FlagSpendLimit, "100stake"),
|
|
fmt.Sprintf("--%s=%s", flags.FlagFeeGranter, granter),
|
|
},
|
|
commonFlags...,
|
|
)
|
|
cmd := cli.NewCmdFeeGrant()
|
|
return clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
|
},
|
|
&sdk.TxResponse{},
|
|
7,
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
tc := tc
|
|
|
|
s.Run(tc.name, func() {
|
|
out, err := tc.malleate()
|
|
s.Require().NoError(err)
|
|
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
|
|
txResp := tc.respType.(*sdk.TxResponse)
|
|
s.Require().NoError(clitestutil.CheckTxCode(s.network, clientCtx, txResp.TxHash, tc.expectedCode))
|
|
})
|
|
}
|
|
}
|
|
|
|
func getFormattedExpiration(duration int64) string {
|
|
return time.Now().Add(time.Duration(duration) * time.Second).Format(time.RFC3339)
|
|
}
|