259 lines
6.0 KiB
Go
259 lines
6.0 KiB
Go
package keeper_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/simapp"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/cosmos/cosmos-sdk/x/feegrant/types"
|
|
)
|
|
|
|
type KeeperTestSuite struct {
|
|
suite.Suite
|
|
|
|
app *simapp.SimApp
|
|
ctx sdk.Context
|
|
addrs []sdk.AccAddress
|
|
}
|
|
|
|
func TestKeeperTestSuite(t *testing.T) {
|
|
suite.Run(t, new(KeeperTestSuite))
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) SetupTest() {
|
|
app := simapp.Setup(false)
|
|
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
|
|
|
suite.app = app
|
|
suite.ctx = ctx
|
|
suite.addrs = simapp.AddTestAddrsIncremental(app, ctx, 4, sdk.NewInt(30000000))
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestKeeperCrud() {
|
|
ctx := suite.ctx
|
|
k := suite.app.FeeGrantKeeper
|
|
|
|
// some helpers
|
|
atom := sdk.NewCoins(sdk.NewInt64Coin("atom", 555))
|
|
eth := sdk.NewCoins(sdk.NewInt64Coin("eth", 123))
|
|
basic := &types.BasicFeeAllowance{
|
|
SpendLimit: atom,
|
|
Expiration: types.ExpiresAtHeight(334455),
|
|
}
|
|
|
|
basic2 := &types.BasicFeeAllowance{
|
|
SpendLimit: eth,
|
|
Expiration: types.ExpiresAtHeight(172436),
|
|
}
|
|
|
|
// let's set up some initial state here
|
|
err := k.GrantFeeAllowance(ctx, suite.addrs[0], suite.addrs[1], basic)
|
|
suite.Require().NoError(err)
|
|
|
|
err = k.GrantFeeAllowance(ctx, suite.addrs[0], suite.addrs[2], basic2)
|
|
suite.Require().NoError(err)
|
|
|
|
err = k.GrantFeeAllowance(ctx, suite.addrs[1], suite.addrs[2], basic)
|
|
suite.Require().NoError(err)
|
|
|
|
err = k.GrantFeeAllowance(ctx, suite.addrs[1], suite.addrs[3], basic)
|
|
suite.Require().NoError(err)
|
|
|
|
err = k.GrantFeeAllowance(ctx, suite.addrs[3], suite.addrs[0], basic2)
|
|
suite.Require().NoError(err)
|
|
|
|
// remove some, overwrite other
|
|
k.RevokeFeeAllowance(ctx, suite.addrs[0], suite.addrs[1])
|
|
k.RevokeFeeAllowance(ctx, suite.addrs[0], suite.addrs[2])
|
|
|
|
err = k.GrantFeeAllowance(ctx, suite.addrs[0], suite.addrs[2], basic)
|
|
suite.Require().NoError(err)
|
|
|
|
err = k.GrantFeeAllowance(ctx, suite.addrs[1], suite.addrs[2], basic2)
|
|
suite.Require().NoError(err)
|
|
|
|
// end state:
|
|
// addr -> addr3 (basic)
|
|
// addr2 -> addr3 (basic2), addr4(basic)
|
|
// addr4 -> addr (basic2)
|
|
|
|
// then lots of queries
|
|
cases := map[string]struct {
|
|
grantee sdk.AccAddress
|
|
granter sdk.AccAddress
|
|
allowance types.FeeAllowanceI
|
|
}{
|
|
"addr revoked": {
|
|
granter: suite.addrs[0],
|
|
grantee: suite.addrs[1],
|
|
},
|
|
"addr revoked and added": {
|
|
granter: suite.addrs[0],
|
|
grantee: suite.addrs[2],
|
|
allowance: basic,
|
|
},
|
|
"addr never there": {
|
|
granter: suite.addrs[0],
|
|
grantee: suite.addrs[3],
|
|
},
|
|
"addr modified": {
|
|
granter: suite.addrs[1],
|
|
grantee: suite.addrs[2],
|
|
allowance: basic2,
|
|
},
|
|
}
|
|
|
|
for name, tc := range cases {
|
|
tc := tc
|
|
suite.Run(name, func() {
|
|
allow, _ := k.GetFeeAllowance(ctx, tc.granter, tc.grantee)
|
|
|
|
if tc.allowance == nil {
|
|
suite.Nil(allow)
|
|
return
|
|
}
|
|
suite.NotNil(allow)
|
|
suite.Equal(tc.allowance, allow)
|
|
})
|
|
}
|
|
|
|
grant1, err := types.NewFeeAllowanceGrant(suite.addrs[3], suite.addrs[0], basic2)
|
|
suite.NoError(err)
|
|
|
|
grant2, err := types.NewFeeAllowanceGrant(suite.addrs[1], suite.addrs[2], basic2)
|
|
suite.NoError(err)
|
|
|
|
grant3, err := types.NewFeeAllowanceGrant(suite.addrs[0], suite.addrs[2], basic)
|
|
suite.NoError(err)
|
|
|
|
allCases := map[string]struct {
|
|
grantee sdk.AccAddress
|
|
grants []types.FeeAllowanceGrant
|
|
}{
|
|
"addr2 has none": {
|
|
grantee: suite.addrs[1],
|
|
},
|
|
"addr has one": {
|
|
grantee: suite.addrs[0],
|
|
grants: []types.FeeAllowanceGrant{
|
|
grant1,
|
|
},
|
|
},
|
|
"addr3 has two": {
|
|
grantee: suite.addrs[2],
|
|
grants: []types.FeeAllowanceGrant{
|
|
grant3,
|
|
grant2,
|
|
},
|
|
},
|
|
}
|
|
|
|
for name, tc := range allCases {
|
|
tc := tc
|
|
suite.Run(name, func() {
|
|
var grants []types.FeeAllowanceGrant
|
|
err := k.IterateAllGranteeFeeAllowances(ctx, tc.grantee, func(grant types.FeeAllowanceGrant) bool {
|
|
grants = append(grants, grant)
|
|
return false
|
|
})
|
|
suite.NoError(err)
|
|
suite.Equal(tc.grants, grants)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestUseGrantedFee() {
|
|
ctx := suite.ctx
|
|
k := suite.app.FeeGrantKeeper
|
|
|
|
// some helpers
|
|
atom := sdk.NewCoins(sdk.NewInt64Coin("atom", 555))
|
|
eth := sdk.NewCoins(sdk.NewInt64Coin("eth", 123))
|
|
future := &types.BasicFeeAllowance{
|
|
SpendLimit: atom,
|
|
Expiration: types.ExpiresAtHeight(5678),
|
|
}
|
|
|
|
expired := &types.BasicFeeAllowance{
|
|
SpendLimit: eth,
|
|
Expiration: types.ExpiresAtHeight(55),
|
|
}
|
|
|
|
// for testing limits of the contract
|
|
hugeAtom := sdk.NewCoins(sdk.NewInt64Coin("atom", 9999))
|
|
_ = hugeAtom
|
|
smallAtom := sdk.NewCoins(sdk.NewInt64Coin("atom", 1))
|
|
_ = smallAtom
|
|
futureAfterSmall := &types.BasicFeeAllowance{
|
|
SpendLimit: sdk.NewCoins(sdk.NewInt64Coin("atom", 554)),
|
|
Expiration: types.ExpiresAtHeight(5678),
|
|
}
|
|
|
|
// then lots of queries
|
|
cases := map[string]struct {
|
|
grantee sdk.AccAddress
|
|
granter sdk.AccAddress
|
|
fee sdk.Coins
|
|
allowed bool
|
|
final types.FeeAllowanceI
|
|
}{
|
|
"use entire pot": {
|
|
granter: suite.addrs[0],
|
|
grantee: suite.addrs[1],
|
|
fee: atom,
|
|
allowed: true,
|
|
final: nil,
|
|
},
|
|
"expired and removed": {
|
|
granter: suite.addrs[0],
|
|
grantee: suite.addrs[2],
|
|
fee: eth,
|
|
allowed: false,
|
|
final: nil,
|
|
},
|
|
"too high": {
|
|
granter: suite.addrs[0],
|
|
grantee: suite.addrs[1],
|
|
fee: hugeAtom,
|
|
allowed: false,
|
|
final: future,
|
|
},
|
|
"use a little": {
|
|
granter: suite.addrs[0],
|
|
grantee: suite.addrs[1],
|
|
fee: smallAtom,
|
|
allowed: true,
|
|
final: futureAfterSmall,
|
|
},
|
|
}
|
|
|
|
for name, tc := range cases {
|
|
tc := tc
|
|
suite.Run(name, func() {
|
|
// let's set up some initial state here
|
|
// addr -> addr2 (future)
|
|
// addr -> addr3 (expired)
|
|
|
|
err := k.GrantFeeAllowance(ctx, suite.addrs[0], suite.addrs[1], future)
|
|
suite.Require().NoError(err)
|
|
|
|
err = k.GrantFeeAllowance(ctx, suite.addrs[0], suite.addrs[3], expired)
|
|
suite.Require().NoError(err)
|
|
|
|
err = k.UseGrantedFees(ctx, tc.granter, tc.grantee, tc.fee, []sdk.Msg{})
|
|
if tc.allowed {
|
|
suite.NoError(err)
|
|
} else {
|
|
suite.Error(err)
|
|
}
|
|
|
|
loaded, _ := k.GetFeeAllowance(ctx, tc.granter, tc.grantee)
|
|
|
|
suite.Equal(tc.final, loaded)
|
|
})
|
|
}
|
|
}
|