diff --git a/app/app_configure.go b/app/app_configure.go index 6921d9e120..c2f615de80 100644 --- a/app/app_configure.go +++ b/app/app_configure.go @@ -105,6 +105,7 @@ func (app *AkashApp) setAkashKeepers() { app.Keepers.Cosmos.Bank, app.Keepers.Akash.Take, app.Keepers.Cosmos.Distr, + app.Keepers.Cosmos.Authz, ) app.Keepers.Akash.Deployment = deployment.NewKeeper( diff --git a/app/types/app.go b/app/types/app.go index c74147118a..bb362c9597 100644 --- a/app/types/app.go +++ b/app/types/app.go @@ -26,7 +26,7 @@ import ( akeeper "github.com/akash-network/node/x/audit/keeper" ckeeper "github.com/akash-network/node/x/cert/keeper" dkeeper "github.com/akash-network/node/x/deployment/keeper" - escrowkeeper "github.com/akash-network/node/x/escrow/keeper" + ekeeper "github.com/akash-network/node/x/escrow/keeper" agovkeeper "github.com/akash-network/node/x/gov/keeper" ikeeper "github.com/akash-network/node/x/inflation/keeper" mkeeper "github.com/akash-network/node/x/market/keeper" @@ -60,7 +60,7 @@ type AppKeepers struct { } Akash struct { - Escrow escrowkeeper.Keeper + Escrow ekeeper.Keeper Deployment dkeeper.IKeeper Take tkeeper.IKeeper Market mkeeper.IKeeper diff --git a/go.mod b/go.mod index 1eef721d6b..987c6d5af3 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,11 @@ module github.com/akash-network/node go 1.21 require ( - github.com/akash-network/akash-api v0.0.61 + github.com/akash-network/akash-api v0.0.64 github.com/blang/semver/v4 v4.0.0 github.com/boz/go-lifecycle v0.1.1 github.com/cosmos/cosmos-sdk v0.45.16 + github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/ibc-go/v4 v4.4.2 github.com/gogo/protobuf v1.3.3 github.com/google/go-github/v56 v56.0.0 @@ -95,7 +96,6 @@ require ( github.com/cosmos/btcutil v1.0.4 // indirect github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.1 // indirect - github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect github.com/cosmos/iavl v0.19.5 // indirect github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect diff --git a/go.sum b/go.sum index 7e18c99ad8..f2fc5819d9 100644 --- a/go.sum +++ b/go.sum @@ -98,8 +98,8 @@ github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBA github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/akash-network/akash-api v0.0.61 h1:Hj/IBr9cFMsFs4VjymLZCoX/5dNfZSFd4iFwUSqhBtQ= -github.com/akash-network/akash-api v0.0.61/go.mod h1:pNr61L4+0sheol7ZK0HjgK3rxpIAbYBGq1w1oH4B0+M= +github.com/akash-network/akash-api v0.0.64 h1:8WZsjCtR86Of87RNCrlRA2Lnb7+1qG5NYyI9A5xvYmM= +github.com/akash-network/akash-api v0.0.64/go.mod h1:pNr61L4+0sheol7ZK0HjgK3rxpIAbYBGq1w1oH4B0+M= github.com/akash-network/cometbft v0.34.27-akash h1:V1dApDOr8Ee7BJzYyQ7Z9VBtrAul4+baMeA6C49dje0= github.com/akash-network/cometbft v0.34.27-akash/go.mod h1:BcCbhKv7ieM0KEddnYXvQZR+pZykTKReJJYf7YC7qhw= github.com/akash-network/ledger-go v0.14.3 h1:LCEFkTfgGA2xFMN2CtiKvXKE7dh0QSM77PJHCpSkaAo= diff --git a/make/init.mk b/make/init.mk index f0cb10530e..c5eb7fc6a8 100644 --- a/make/init.mk +++ b/make/init.mk @@ -53,7 +53,7 @@ endif GOLANGCI_LINT_VERSION ?= v1.51.2 STATIK_VERSION ?= v0.1.7 GIT_CHGLOG_VERSION ?= v0.15.1 -MOCKERY_VERSION ?= 2.24.0 +MOCKERY_VERSION ?= 2.42.0 COSMOVISOR_VERSION ?= v1.5.0 # ==== Build tools version tracking ==== diff --git a/tests/upgrade/upgrade-v0.34.0.json b/tests/upgrade/upgrade-v0.34.0.json new file mode 100644 index 0000000000..0a47ef39d8 --- /dev/null +++ b/tests/upgrade/upgrade-v0.34.0.json @@ -0,0 +1,4 @@ +{ + "migrations": { + } +} diff --git a/tests/upgrade/v0.34.0/postupgrade.go b/tests/upgrade/v0.34.0/postupgrade.go new file mode 100644 index 0000000000..d8886cb622 --- /dev/null +++ b/tests/upgrade/v0.34.0/postupgrade.go @@ -0,0 +1,321 @@ +//go:build e2e.upgrade + +// Package v0_34_0 +// nolint revive +package v0_34_0 + +import ( + "context" + "testing" + "time" + + "github.com/spf13/pflag" + "github.com/stretchr/testify/require" + + sdkclient "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" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/authz" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/cosmos/go-bip39" + + cltypes "github.com/akash-network/akash-api/go/node/client/types" + dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + + "github.com/akash-network/node/app" + "github.com/akash-network/node/client" + "github.com/akash-network/node/cmd/common" + "github.com/akash-network/node/sdl" + uttypes "github.com/akash-network/node/tests/upgrade/types" +) + +const ( + mnemonicEntropySize = 256 +) + +const ( + testSDL = ` +--- +version: "2.0" +services: + web: + image: nginx + expose: + - port: 80 + accept: + - ahostname.com + to: + - global: true + - port: 12345 + to: + - global: true + proto: udp +profiles: + compute: + web: + resources: + cpu: + units: "100m" + memory: + size: "128Mi" + storage: + size: "1Gi" + placement: + westcoast: + attributes: + region: us-west + signedBy: + anyOf: + - 1 + - 2 + allOf: + - 3 + - 4 + pricing: + web: + denom: uakt + amount: 50 +deployment: + web: + westcoast: + profile: web + count: 2 +` +) + +func init() { + uttypes.RegisterPostUpgradeWorker("v0.34.0", &postUpgrade{}) +} + +type postUpgrade struct{} + +var _ uttypes.TestWorker = (*postUpgrade)(nil) + +func (pu *postUpgrade) Run(ctx context.Context, t *testing.T, params uttypes.TestParams) { + encodingConfig := app.MakeEncodingConfig() + + rpcClient, err := sdkclient.NewClientFromNode(params.Node) + require.NoError(t, err) + + cctx := sdkclient.Context{}. + WithCodec(encodingConfig.Marshaler). + WithInterfaceRegistry(encodingConfig.InterfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithLegacyAmino(encodingConfig.Amino). + WithAccountRetriever(authtypes.AccountRetriever{}). + WithBroadcastMode(flags.BroadcastBlock). + WithHomeDir(params.Home). + WithChainID(params.ChainID). + WithNodeURI(params.Node). + WithClient(rpcClient). + WithSkipConfirmation(true). + WithFrom(params.From). + WithKeyringDir(params.Home) + + kr, err := sdkclient.NewKeyringFromBackend(cctx, params.KeyringBackend) + require.NoError(t, err) + + cctx = cctx.WithKeyring(kr) + + info, err := kr.Key(params.From) + require.NoError(t, err) + + entropySeed, err := bip39.NewEntropy(mnemonicEntropySize) + require.NoError(t, err) + + mnemonic, err := bip39.NewMnemonic(entropySeed) + require.NoError(t, err) + + keyringAlgos, _ := kr.SupportedAlgorithms() + + algo, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), keyringAlgos) + + coinType := sdk.GetConfig().GetCoinType() + hdPath := hd.CreateHDPath(coinType, 0, 0).String() + + deplAcc, err := kr.NewAccount("depl", mnemonic, "", hdPath, algo) + require.NoError(t, err) + + hdPath = hd.CreateHDPath(coinType, 0, 1).String() + authz1, err := kr.NewAccount("authz1", mnemonic, "", hdPath, algo) + require.NoError(t, err) + + hdPath = hd.CreateHDPath(coinType, 0, 2).String() + authz2, err := kr.NewAccount("authz2", mnemonic, "", hdPath, algo) + require.NoError(t, err) + + mcctx := cctx.WithFromName(info.GetName()). + WithFromAddress(info.GetAddress()) + + dcctx := cctx.WithFromName(deplAcc.GetName()). + WithFromAddress(deplAcc.GetAddress()) + + a1cctx := cctx.WithFromName(authz1.GetName()). + WithFromAddress(authz1.GetAddress()) + + a2cctx := cctx.WithFromName(authz2.GetName()). + WithFromAddress(authz2.GetAddress()) + + opts := []cltypes.ClientOption{ + cltypes.WithGasPrices("0.025uakt"), + cltypes.WithGas(flags.GasSetting{Simulate: true}), + cltypes.WithGasAdjustment(2), + } + + mcl, err := client.DiscoverClient(ctx, mcctx, opts...) + require.NoError(t, err) + require.NotNil(t, mcl) + + dcl, err := client.DiscoverClient(ctx, dcctx, opts...) + require.NoError(t, err) + require.NotNil(t, mcl) + + a1cl, err := client.DiscoverClient(ctx, a1cctx, opts...) + require.NoError(t, err) + require.NotNil(t, mcl) + + a2cl, err := client.DiscoverClient(ctx, a2cctx, opts...) + require.NoError(t, err) + require.NotNil(t, mcl) + + msgs := []sdk.Msg{ + &banktypes.MsgSend{ + FromAddress: info.GetAddress().String(), + ToAddress: deplAcc.GetAddress().String(), + Amount: sdk.NewCoins(sdk.NewCoin("uakt", sdk.NewInt(100000000))), + }, + &banktypes.MsgSend{ + FromAddress: info.GetAddress().String(), + ToAddress: authz1.GetAddress().String(), + Amount: sdk.NewCoins(sdk.NewCoin("uakt", sdk.NewInt(100000000))), + }, + &banktypes.MsgSend{ + FromAddress: info.GetAddress().String(), + ToAddress: authz2.GetAddress().String(), + Amount: sdk.NewCoins(sdk.NewCoin("uakt", sdk.NewInt(100000000))), + }, + } + + // fund all new accounts with some tokens + resp, err := mcl.Tx().Broadcast(ctx, msgs) + require.NoError(t, err) + require.NotNil(t, resp) + require.IsType(t, &sdk.TxResponse{}, resp) + txResp := resp.(*sdk.TxResponse) + require.Equal(t, uint32(0), txResp.Code) + + // give deployment key deployment deposit authorization from two accounts + spendLimit := sdk.NewCoin("uakt", sdk.NewInt(10000000)) + authorization := dtypes.NewDepositDeploymentAuthorization(spendLimit) + + msg, err := authz.NewMsgGrant(a1cctx.FromAddress, deplAcc.GetAddress(), authorization, time.Now().AddDate(1, 0, 0)) + require.NoError(t, err) + require.NotNil(t, msg) + + resp, err = a1cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) + require.NoError(t, err) + require.NotNil(t, resp) + require.IsType(t, &sdk.TxResponse{}, resp) + txResp = resp.(*sdk.TxResponse) + require.Equal(t, uint32(0), txResp.Code) + + msg, err = authz.NewMsgGrant(a2cctx.FromAddress, deplAcc.GetAddress(), authorization, time.Now().AddDate(1, 0, 0)) + require.NoError(t, err) + require.NotNil(t, msg) + + resp, err = a2cl.Tx().Broadcast(ctx, []sdk.Msg{msg}) + require.NoError(t, err) + require.NotNil(t, resp) + require.IsType(t, &sdk.TxResponse{}, resp) + txResp = resp.(*sdk.TxResponse) + require.Equal(t, uint32(0), txResp.Code) + + tsdl, err := sdl.Read([]byte(testSDL)) + require.NoError(t, err) + require.NotNil(t, tsdl) + + syncInfo, err := dcl.Node().SyncInfo(ctx) + require.NoError(t, err) + require.NotNil(t, syncInfo) + require.False(t, syncInfo.CatchingUp) + + dID := dtypes.DeploymentID{ + Owner: deplAcc.GetAddress().String(), + DSeq: uint64(syncInfo.LatestBlockHeight), + } + + dVersion, err := tsdl.Version() + require.NoError(t, err) + + dGroups, err := tsdl.DeploymentGroups() + require.NoError(t, err) + + deposit, err := common.DetectDeposit(ctx, &pflag.FlagSet{}, dcl.Query(), "deployment", "MinDeposits") + require.NoError(t, err) + + // create deployment with deposit from owner + // should not have any errors + deploymentMsg := &dtypes.MsgCreateDeployment{ + ID: dID, + Version: dVersion, + Groups: make([]dtypes.GroupSpec, 0, len(dGroups)), + Deposit: deposit, + Depositor: deplAcc.GetAddress().String(), + } + + for _, group := range dGroups { + deploymentMsg.Groups = append(deploymentMsg.Groups, *group) + } + + resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{deploymentMsg}) + require.NoError(t, err) + require.NotNil(t, resp) + require.IsType(t, &sdk.TxResponse{}, resp) + txResp = resp.(*sdk.TxResponse) + require.Equal(t, uint32(0), txResp.Code) + + // should be able to fund escrow with owner as depositor + depositMsg := &dtypes.MsgDepositDeployment{ + ID: dID, + Amount: deposit, + Depositor: deplAcc.GetAddress().String(), + } + + resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{depositMsg}) + require.NoError(t, err) + require.NotNil(t, resp) + require.IsType(t, &sdk.TxResponse{}, resp) + txResp = resp.(*sdk.TxResponse) + require.Equal(t, uint32(0), txResp.Code) + + // should be able to fund escrow with depositor from authz1 + depositMsg = &dtypes.MsgDepositDeployment{ + ID: dID, + Amount: deposit, + Depositor: authz1.GetAddress().String(), + } + + resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{depositMsg}) + require.NoError(t, err) + require.NotNil(t, resp) + require.IsType(t, &sdk.TxResponse{}, resp) + txResp = resp.(*sdk.TxResponse) + require.Equal(t, uint32(0), txResp.Code) + + // should not be able to fund escrow with depositor from authz2 + depositMsg = &dtypes.MsgDepositDeployment{ + ID: dID, + Amount: deposit, + Depositor: authz2.GetAddress().String(), + } + + resp, err = dcl.Tx().Broadcast(ctx, []sdk.Msg{depositMsg}) + require.NoError(t, err) + require.NotNil(t, resp) + require.IsType(t, &sdk.TxResponse{}, resp) + txResp = resp.(*sdk.TxResponse) + require.NotEqual(t, uint32(0), txResp.Code) +} diff --git a/tests/upgrade/workers_test.go b/tests/upgrade/workers_test.go index 3549b0c091..ba590ac5b4 100644 --- a/tests/upgrade/workers_test.go +++ b/tests/upgrade/workers_test.go @@ -5,4 +5,5 @@ package upgrade import ( _ "github.com/akash-network/node/tests/upgrade/v0.26.0" _ "github.com/akash-network/node/tests/upgrade/v0.32.0" + _ "github.com/akash-network/node/tests/upgrade/v0.34.0" ) diff --git a/testutil/cosmos/keepers.go b/testutil/cosmos/keepers.go new file mode 100644 index 0000000000..943959bff4 --- /dev/null +++ b/testutil/cosmos/keepers.go @@ -0,0 +1,34 @@ +package keeper + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" +) + +//go:generate mockery --name BankKeeper --output ./mocks +type BankKeeper interface { + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error +} + +//go:generate mockery --name TakeKeeper --output ./mocks +type TakeKeeper interface { + SubtractFees(ctx sdk.Context, amt sdk.Coin) (sdk.Coin, sdk.Coin, error) +} + +//go:generate mockery --name DistrKeeper --output ./mocks +type DistrKeeper interface { + GetFeePool(ctx sdk.Context) distrtypes.FeePool + SetFeePool(ctx sdk.Context, pool distrtypes.FeePool) +} + +//go:generate mockery --name AuthzKeeper --output ./mocks +type AuthzKeeper interface { + DeleteGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) error + GetCleanAuthorization(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) (cap authz.Authorization, expiration time.Time) + SaveGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization authz.Authorization, expiration time.Time) error +} diff --git a/testutil/cosmos/mocks/authz_keeper.go b/testutil/cosmos/mocks/authz_keeper.go new file mode 100644 index 0000000000..2109d51ead --- /dev/null +++ b/testutil/cosmos/mocks/authz_keeper.go @@ -0,0 +1,200 @@ +// Code generated by mockery v2.42.0. DO NOT EDIT. + +package mocks + +import ( + authz "github.com/cosmos/cosmos-sdk/x/authz" + + mock "github.com/stretchr/testify/mock" + + time "time" + + types "github.com/cosmos/cosmos-sdk/types" +) + +// AuthzKeeper is an autogenerated mock type for the AuthzKeeper type +type AuthzKeeper struct { + mock.Mock +} + +type AuthzKeeper_Expecter struct { + mock *mock.Mock +} + +func (_m *AuthzKeeper) EXPECT() *AuthzKeeper_Expecter { + return &AuthzKeeper_Expecter{mock: &_m.Mock} +} + +// DeleteGrant provides a mock function with given fields: ctx, grantee, granter, msgType +func (_m *AuthzKeeper) DeleteGrant(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) error { + ret := _m.Called(ctx, grantee, granter, msgType) + + if len(ret) == 0 { + panic("no return value specified for DeleteGrant") + } + + var r0 error + if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) error); ok { + r0 = rf(ctx, grantee, granter, msgType) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// AuthzKeeper_DeleteGrant_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteGrant' +type AuthzKeeper_DeleteGrant_Call struct { + *mock.Call +} + +// DeleteGrant is a helper method to define mock.On call +// - ctx types.Context +// - grantee types.AccAddress +// - granter types.AccAddress +// - msgType string +func (_e *AuthzKeeper_Expecter) DeleteGrant(ctx interface{}, grantee interface{}, granter interface{}, msgType interface{}) *AuthzKeeper_DeleteGrant_Call { + return &AuthzKeeper_DeleteGrant_Call{Call: _e.mock.On("DeleteGrant", ctx, grantee, granter, msgType)} +} + +func (_c *AuthzKeeper_DeleteGrant_Call) Run(run func(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string)) *AuthzKeeper_DeleteGrant_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(types.AccAddress), args[3].(string)) + }) + return _c +} + +func (_c *AuthzKeeper_DeleteGrant_Call) Return(_a0 error) *AuthzKeeper_DeleteGrant_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *AuthzKeeper_DeleteGrant_Call) RunAndReturn(run func(types.Context, types.AccAddress, types.AccAddress, string) error) *AuthzKeeper_DeleteGrant_Call { + _c.Call.Return(run) + return _c +} + +// GetCleanAuthorization provides a mock function with given fields: ctx, grantee, granter, msgType +func (_m *AuthzKeeper) GetCleanAuthorization(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) (authz.Authorization, time.Time) { + ret := _m.Called(ctx, grantee, granter, msgType) + + if len(ret) == 0 { + panic("no return value specified for GetCleanAuthorization") + } + + var r0 authz.Authorization + var r1 time.Time + if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) (authz.Authorization, time.Time)); ok { + return rf(ctx, grantee, granter, msgType) + } + if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) authz.Authorization); ok { + r0 = rf(ctx, grantee, granter, msgType) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(authz.Authorization) + } + } + + if rf, ok := ret.Get(1).(func(types.Context, types.AccAddress, types.AccAddress, string) time.Time); ok { + r1 = rf(ctx, grantee, granter, msgType) + } else { + r1 = ret.Get(1).(time.Time) + } + + return r0, r1 +} + +// AuthzKeeper_GetCleanAuthorization_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCleanAuthorization' +type AuthzKeeper_GetCleanAuthorization_Call struct { + *mock.Call +} + +// GetCleanAuthorization is a helper method to define mock.On call +// - ctx types.Context +// - grantee types.AccAddress +// - granter types.AccAddress +// - msgType string +func (_e *AuthzKeeper_Expecter) GetCleanAuthorization(ctx interface{}, grantee interface{}, granter interface{}, msgType interface{}) *AuthzKeeper_GetCleanAuthorization_Call { + return &AuthzKeeper_GetCleanAuthorization_Call{Call: _e.mock.On("GetCleanAuthorization", ctx, grantee, granter, msgType)} +} + +func (_c *AuthzKeeper_GetCleanAuthorization_Call) Run(run func(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string)) *AuthzKeeper_GetCleanAuthorization_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(types.AccAddress), args[3].(string)) + }) + return _c +} + +func (_c *AuthzKeeper_GetCleanAuthorization_Call) Return(cap authz.Authorization, expiration time.Time) *AuthzKeeper_GetCleanAuthorization_Call { + _c.Call.Return(cap, expiration) + return _c +} + +func (_c *AuthzKeeper_GetCleanAuthorization_Call) RunAndReturn(run func(types.Context, types.AccAddress, types.AccAddress, string) (authz.Authorization, time.Time)) *AuthzKeeper_GetCleanAuthorization_Call { + _c.Call.Return(run) + return _c +} + +// SaveGrant provides a mock function with given fields: ctx, grantee, granter, authorization, expiration +func (_m *AuthzKeeper) SaveGrant(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration time.Time) error { + ret := _m.Called(ctx, grantee, granter, authorization, expiration) + + if len(ret) == 0 { + panic("no return value specified for SaveGrant") + } + + var r0 error + if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, authz.Authorization, time.Time) error); ok { + r0 = rf(ctx, grantee, granter, authorization, expiration) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// AuthzKeeper_SaveGrant_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveGrant' +type AuthzKeeper_SaveGrant_Call struct { + *mock.Call +} + +// SaveGrant is a helper method to define mock.On call +// - ctx types.Context +// - grantee types.AccAddress +// - granter types.AccAddress +// - authorization authz.Authorization +// - expiration time.Time +func (_e *AuthzKeeper_Expecter) SaveGrant(ctx interface{}, grantee interface{}, granter interface{}, authorization interface{}, expiration interface{}) *AuthzKeeper_SaveGrant_Call { + return &AuthzKeeper_SaveGrant_Call{Call: _e.mock.On("SaveGrant", ctx, grantee, granter, authorization, expiration)} +} + +func (_c *AuthzKeeper_SaveGrant_Call) Run(run func(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration time.Time)) *AuthzKeeper_SaveGrant_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(types.Context), args[1].(types.AccAddress), args[2].(types.AccAddress), args[3].(authz.Authorization), args[4].(time.Time)) + }) + return _c +} + +func (_c *AuthzKeeper_SaveGrant_Call) Return(_a0 error) *AuthzKeeper_SaveGrant_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *AuthzKeeper_SaveGrant_Call) RunAndReturn(run func(types.Context, types.AccAddress, types.AccAddress, authz.Authorization, time.Time) error) *AuthzKeeper_SaveGrant_Call { + _c.Call.Return(run) + return _c +} + +// NewAuthzKeeper creates a new instance of AuthzKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAuthzKeeper(t interface { + mock.TestingT + Cleanup(func()) +}) *AuthzKeeper { + mock := &AuthzKeeper{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/x/escrow/keeper/mocks/bank_keeper.go b/testutil/cosmos/mocks/bank_keeper.go similarity index 93% rename from x/escrow/keeper/mocks/bank_keeper.go rename to testutil/cosmos/mocks/bank_keeper.go index 2aabcdbbed..d68cc96ac2 100644 --- a/x/escrow/keeper/mocks/bank_keeper.go +++ b/testutil/cosmos/mocks/bank_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.24.0. DO NOT EDIT. +// Code generated by mockery v2.42.0. DO NOT EDIT. package mocks @@ -24,6 +24,10 @@ func (_m *BankKeeper) EXPECT() *BankKeeper_Expecter { func (_m *BankKeeper) SendCoinsFromAccountToModule(ctx types.Context, senderAddr types.AccAddress, recipientModule string, amt types.Coins) error { ret := _m.Called(ctx, senderAddr, recipientModule, amt) + if len(ret) == 0 { + panic("no return value specified for SendCoinsFromAccountToModule") + } + var r0 error if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, string, types.Coins) error); ok { r0 = rf(ctx, senderAddr, recipientModule, amt) @@ -69,6 +73,10 @@ func (_c *BankKeeper_SendCoinsFromAccountToModule_Call) RunAndReturn(run func(ty func (_m *BankKeeper) SendCoinsFromModuleToAccount(ctx types.Context, senderModule string, recipientAddr types.AccAddress, amt types.Coins) error { ret := _m.Called(ctx, senderModule, recipientAddr, amt) + if len(ret) == 0 { + panic("no return value specified for SendCoinsFromModuleToAccount") + } + var r0 error if rf, ok := ret.Get(0).(func(types.Context, string, types.AccAddress, types.Coins) error); ok { r0 = rf(ctx, senderModule, recipientAddr, amt) @@ -114,6 +122,10 @@ func (_c *BankKeeper_SendCoinsFromModuleToAccount_Call) RunAndReturn(run func(ty func (_m *BankKeeper) SendCoinsFromModuleToModule(ctx types.Context, senderModule string, recipientModule string, amt types.Coins) error { ret := _m.Called(ctx, senderModule, recipientModule, amt) + if len(ret) == 0 { + panic("no return value specified for SendCoinsFromModuleToModule") + } + var r0 error if rf, ok := ret.Get(0).(func(types.Context, string, string, types.Coins) error); ok { r0 = rf(ctx, senderModule, recipientModule, amt) @@ -155,13 +167,12 @@ func (_c *BankKeeper_SendCoinsFromModuleToModule_Call) RunAndReturn(run func(typ return _c } -type mockConstructorTestingTNewBankKeeper interface { +// NewBankKeeper creates a new instance of BankKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewBankKeeper(t interface { mock.TestingT Cleanup(func()) -} - -// NewBankKeeper creates a new instance of BankKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewBankKeeper(t mockConstructorTestingTNewBankKeeper) *BankKeeper { +}) *BankKeeper { mock := &BankKeeper{} mock.Mock.Test(t) diff --git a/x/escrow/keeper/mocks/distr_keeper.go b/testutil/cosmos/mocks/distr_keeper.go similarity index 93% rename from x/escrow/keeper/mocks/distr_keeper.go rename to testutil/cosmos/mocks/distr_keeper.go index de24d87f79..d013b76750 100644 --- a/x/escrow/keeper/mocks/distr_keeper.go +++ b/testutil/cosmos/mocks/distr_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.24.0. DO NOT EDIT. +// Code generated by mockery v2.42.0. DO NOT EDIT. package mocks @@ -27,6 +27,10 @@ func (_m *DistrKeeper) EXPECT() *DistrKeeper_Expecter { func (_m *DistrKeeper) GetFeePool(ctx types.Context) distributiontypes.FeePool { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for GetFeePool") + } + var r0 distributiontypes.FeePool if rf, ok := ret.Get(0).(func(types.Context) distributiontypes.FeePool); ok { r0 = rf(ctx) @@ -99,13 +103,12 @@ func (_c *DistrKeeper_SetFeePool_Call) RunAndReturn(run func(types.Context, dist return _c } -type mockConstructorTestingTNewDistrKeeper interface { +// NewDistrKeeper creates a new instance of DistrKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewDistrKeeper(t interface { mock.TestingT Cleanup(func()) -} - -// NewDistrKeeper creates a new instance of DistrKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewDistrKeeper(t mockConstructorTestingTNewDistrKeeper) *DistrKeeper { +}) *DistrKeeper { mock := &DistrKeeper{} mock.Mock.Test(t) diff --git a/x/escrow/keeper/mocks/take_keeper.go b/testutil/cosmos/mocks/take_keeper.go similarity index 91% rename from x/escrow/keeper/mocks/take_keeper.go rename to testutil/cosmos/mocks/take_keeper.go index 85eae899c4..1ecf9727be 100644 --- a/x/escrow/keeper/mocks/take_keeper.go +++ b/testutil/cosmos/mocks/take_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.24.0. DO NOT EDIT. +// Code generated by mockery v2.42.0. DO NOT EDIT. package mocks @@ -24,6 +24,10 @@ func (_m *TakeKeeper) EXPECT() *TakeKeeper_Expecter { func (_m *TakeKeeper) SubtractFees(ctx types.Context, amt types.Coin) (types.Coin, types.Coin, error) { ret := _m.Called(ctx, amt) + if len(ret) == 0 { + panic("no return value specified for SubtractFees") + } + var r0 types.Coin var r1 types.Coin var r2 error @@ -80,13 +84,12 @@ func (_c *TakeKeeper_SubtractFees_Call) RunAndReturn(run func(types.Context, typ return _c } -type mockConstructorTestingTNewTakeKeeper interface { +// NewTakeKeeper creates a new instance of TakeKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewTakeKeeper(t interface { mock.TestingT Cleanup(func()) -} - -// NewTakeKeeper creates a new instance of TakeKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewTakeKeeper(t mockConstructorTestingTNewTakeKeeper) *TakeKeeper { +}) *TakeKeeper { mock := &TakeKeeper{} mock.Mock.Test(t) diff --git a/testutil/cosmos_mock/query_client.go b/testutil/cosmos_mock/query_client.go deleted file mode 100644 index 2acbd5f7cd..0000000000 --- a/testutil/cosmos_mock/query_client.go +++ /dev/null @@ -1,601 +0,0 @@ -// Code generated by mockery v2.24.0. DO NOT EDIT. - -package cosmos_mocks - -import ( - context "context" - - grpc "google.golang.org/grpc" - - mock "github.com/stretchr/testify/mock" - - types "github.com/cosmos/cosmos-sdk/x/bank/types" -) - -// QueryClient is an autogenerated mock type for the QueryClient type -type QueryClient struct { - mock.Mock -} - -type QueryClient_Expecter struct { - mock *mock.Mock -} - -func (_m *QueryClient) EXPECT() *QueryClient_Expecter { - return &QueryClient_Expecter{mock: &_m.Mock} -} - -// AllBalances provides a mock function with given fields: ctx, in, opts -func (_m *QueryClient) AllBalances(ctx context.Context, in *types.QueryAllBalancesRequest, opts ...grpc.CallOption) (*types.QueryAllBalancesResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryAllBalancesResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllBalancesRequest, ...grpc.CallOption) (*types.QueryAllBalancesResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryAllBalancesRequest, ...grpc.CallOption) *types.QueryAllBalancesResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryAllBalancesResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryAllBalancesRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// QueryClient_AllBalances_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AllBalances' -type QueryClient_AllBalances_Call struct { - *mock.Call -} - -// AllBalances is a helper method to define mock.On call -// - ctx context.Context -// - in *types.QueryAllBalancesRequest -// - opts ...grpc.CallOption -func (_e *QueryClient_Expecter) AllBalances(ctx interface{}, in interface{}, opts ...interface{}) *QueryClient_AllBalances_Call { - return &QueryClient_AllBalances_Call{Call: _e.mock.On("AllBalances", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *QueryClient_AllBalances_Call) Run(run func(ctx context.Context, in *types.QueryAllBalancesRequest, opts ...grpc.CallOption)) *QueryClient_AllBalances_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*types.QueryAllBalancesRequest), variadicArgs...) - }) - return _c -} - -func (_c *QueryClient_AllBalances_Call) Return(_a0 *types.QueryAllBalancesResponse, _a1 error) *QueryClient_AllBalances_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *QueryClient_AllBalances_Call) RunAndReturn(run func(context.Context, *types.QueryAllBalancesRequest, ...grpc.CallOption) (*types.QueryAllBalancesResponse, error)) *QueryClient_AllBalances_Call { - _c.Call.Return(run) - return _c -} - -// Balance provides a mock function with given fields: ctx, in, opts -func (_m *QueryClient) Balance(ctx context.Context, in *types.QueryBalanceRequest, opts ...grpc.CallOption) (*types.QueryBalanceResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryBalanceResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryBalanceRequest, ...grpc.CallOption) (*types.QueryBalanceResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryBalanceRequest, ...grpc.CallOption) *types.QueryBalanceResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryBalanceResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryBalanceRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// QueryClient_Balance_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Balance' -type QueryClient_Balance_Call struct { - *mock.Call -} - -// Balance is a helper method to define mock.On call -// - ctx context.Context -// - in *types.QueryBalanceRequest -// - opts ...grpc.CallOption -func (_e *QueryClient_Expecter) Balance(ctx interface{}, in interface{}, opts ...interface{}) *QueryClient_Balance_Call { - return &QueryClient_Balance_Call{Call: _e.mock.On("Balance", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *QueryClient_Balance_Call) Run(run func(ctx context.Context, in *types.QueryBalanceRequest, opts ...grpc.CallOption)) *QueryClient_Balance_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*types.QueryBalanceRequest), variadicArgs...) - }) - return _c -} - -func (_c *QueryClient_Balance_Call) Return(_a0 *types.QueryBalanceResponse, _a1 error) *QueryClient_Balance_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *QueryClient_Balance_Call) RunAndReturn(run func(context.Context, *types.QueryBalanceRequest, ...grpc.CallOption) (*types.QueryBalanceResponse, error)) *QueryClient_Balance_Call { - _c.Call.Return(run) - return _c -} - -// DenomMetadata provides a mock function with given fields: ctx, in, opts -func (_m *QueryClient) DenomMetadata(ctx context.Context, in *types.QueryDenomMetadataRequest, opts ...grpc.CallOption) (*types.QueryDenomMetadataResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDenomMetadataResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDenomMetadataRequest, ...grpc.CallOption) (*types.QueryDenomMetadataResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDenomMetadataRequest, ...grpc.CallOption) *types.QueryDenomMetadataResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDenomMetadataResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDenomMetadataRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// QueryClient_DenomMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DenomMetadata' -type QueryClient_DenomMetadata_Call struct { - *mock.Call -} - -// DenomMetadata is a helper method to define mock.On call -// - ctx context.Context -// - in *types.QueryDenomMetadataRequest -// - opts ...grpc.CallOption -func (_e *QueryClient_Expecter) DenomMetadata(ctx interface{}, in interface{}, opts ...interface{}) *QueryClient_DenomMetadata_Call { - return &QueryClient_DenomMetadata_Call{Call: _e.mock.On("DenomMetadata", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *QueryClient_DenomMetadata_Call) Run(run func(ctx context.Context, in *types.QueryDenomMetadataRequest, opts ...grpc.CallOption)) *QueryClient_DenomMetadata_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*types.QueryDenomMetadataRequest), variadicArgs...) - }) - return _c -} - -func (_c *QueryClient_DenomMetadata_Call) Return(_a0 *types.QueryDenomMetadataResponse, _a1 error) *QueryClient_DenomMetadata_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *QueryClient_DenomMetadata_Call) RunAndReturn(run func(context.Context, *types.QueryDenomMetadataRequest, ...grpc.CallOption) (*types.QueryDenomMetadataResponse, error)) *QueryClient_DenomMetadata_Call { - _c.Call.Return(run) - return _c -} - -// DenomsMetadata provides a mock function with given fields: ctx, in, opts -func (_m *QueryClient) DenomsMetadata(ctx context.Context, in *types.QueryDenomsMetadataRequest, opts ...grpc.CallOption) (*types.QueryDenomsMetadataResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryDenomsMetadataResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDenomsMetadataRequest, ...grpc.CallOption) (*types.QueryDenomsMetadataResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryDenomsMetadataRequest, ...grpc.CallOption) *types.QueryDenomsMetadataResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryDenomsMetadataResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryDenomsMetadataRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// QueryClient_DenomsMetadata_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DenomsMetadata' -type QueryClient_DenomsMetadata_Call struct { - *mock.Call -} - -// DenomsMetadata is a helper method to define mock.On call -// - ctx context.Context -// - in *types.QueryDenomsMetadataRequest -// - opts ...grpc.CallOption -func (_e *QueryClient_Expecter) DenomsMetadata(ctx interface{}, in interface{}, opts ...interface{}) *QueryClient_DenomsMetadata_Call { - return &QueryClient_DenomsMetadata_Call{Call: _e.mock.On("DenomsMetadata", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *QueryClient_DenomsMetadata_Call) Run(run func(ctx context.Context, in *types.QueryDenomsMetadataRequest, opts ...grpc.CallOption)) *QueryClient_DenomsMetadata_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*types.QueryDenomsMetadataRequest), variadicArgs...) - }) - return _c -} - -func (_c *QueryClient_DenomsMetadata_Call) Return(_a0 *types.QueryDenomsMetadataResponse, _a1 error) *QueryClient_DenomsMetadata_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *QueryClient_DenomsMetadata_Call) RunAndReturn(run func(context.Context, *types.QueryDenomsMetadataRequest, ...grpc.CallOption) (*types.QueryDenomsMetadataResponse, error)) *QueryClient_DenomsMetadata_Call { - _c.Call.Return(run) - return _c -} - -// Params provides a mock function with given fields: ctx, in, opts -func (_m *QueryClient) Params(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption) (*types.QueryParamsResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryParamsResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) (*types.QueryParamsResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) *types.QueryParamsResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryParamsResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// QueryClient_Params_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Params' -type QueryClient_Params_Call struct { - *mock.Call -} - -// Params is a helper method to define mock.On call -// - ctx context.Context -// - in *types.QueryParamsRequest -// - opts ...grpc.CallOption -func (_e *QueryClient_Expecter) Params(ctx interface{}, in interface{}, opts ...interface{}) *QueryClient_Params_Call { - return &QueryClient_Params_Call{Call: _e.mock.On("Params", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *QueryClient_Params_Call) Run(run func(ctx context.Context, in *types.QueryParamsRequest, opts ...grpc.CallOption)) *QueryClient_Params_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*types.QueryParamsRequest), variadicArgs...) - }) - return _c -} - -func (_c *QueryClient_Params_Call) Return(_a0 *types.QueryParamsResponse, _a1 error) *QueryClient_Params_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *QueryClient_Params_Call) RunAndReturn(run func(context.Context, *types.QueryParamsRequest, ...grpc.CallOption) (*types.QueryParamsResponse, error)) *QueryClient_Params_Call { - _c.Call.Return(run) - return _c -} - -// SpendableBalances provides a mock function with given fields: ctx, in, opts -func (_m *QueryClient) SpendableBalances(ctx context.Context, in *types.QuerySpendableBalancesRequest, opts ...grpc.CallOption) (*types.QuerySpendableBalancesResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QuerySpendableBalancesResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.QuerySpendableBalancesRequest, ...grpc.CallOption) (*types.QuerySpendableBalancesResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.QuerySpendableBalancesRequest, ...grpc.CallOption) *types.QuerySpendableBalancesResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QuerySpendableBalancesResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.QuerySpendableBalancesRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// QueryClient_SpendableBalances_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SpendableBalances' -type QueryClient_SpendableBalances_Call struct { - *mock.Call -} - -// SpendableBalances is a helper method to define mock.On call -// - ctx context.Context -// - in *types.QuerySpendableBalancesRequest -// - opts ...grpc.CallOption -func (_e *QueryClient_Expecter) SpendableBalances(ctx interface{}, in interface{}, opts ...interface{}) *QueryClient_SpendableBalances_Call { - return &QueryClient_SpendableBalances_Call{Call: _e.mock.On("SpendableBalances", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *QueryClient_SpendableBalances_Call) Run(run func(ctx context.Context, in *types.QuerySpendableBalancesRequest, opts ...grpc.CallOption)) *QueryClient_SpendableBalances_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*types.QuerySpendableBalancesRequest), variadicArgs...) - }) - return _c -} - -func (_c *QueryClient_SpendableBalances_Call) Return(_a0 *types.QuerySpendableBalancesResponse, _a1 error) *QueryClient_SpendableBalances_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *QueryClient_SpendableBalances_Call) RunAndReturn(run func(context.Context, *types.QuerySpendableBalancesRequest, ...grpc.CallOption) (*types.QuerySpendableBalancesResponse, error)) *QueryClient_SpendableBalances_Call { - _c.Call.Return(run) - return _c -} - -// SupplyOf provides a mock function with given fields: ctx, in, opts -func (_m *QueryClient) SupplyOf(ctx context.Context, in *types.QuerySupplyOfRequest, opts ...grpc.CallOption) (*types.QuerySupplyOfResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QuerySupplyOfResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.QuerySupplyOfRequest, ...grpc.CallOption) (*types.QuerySupplyOfResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.QuerySupplyOfRequest, ...grpc.CallOption) *types.QuerySupplyOfResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QuerySupplyOfResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.QuerySupplyOfRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// QueryClient_SupplyOf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SupplyOf' -type QueryClient_SupplyOf_Call struct { - *mock.Call -} - -// SupplyOf is a helper method to define mock.On call -// - ctx context.Context -// - in *types.QuerySupplyOfRequest -// - opts ...grpc.CallOption -func (_e *QueryClient_Expecter) SupplyOf(ctx interface{}, in interface{}, opts ...interface{}) *QueryClient_SupplyOf_Call { - return &QueryClient_SupplyOf_Call{Call: _e.mock.On("SupplyOf", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *QueryClient_SupplyOf_Call) Run(run func(ctx context.Context, in *types.QuerySupplyOfRequest, opts ...grpc.CallOption)) *QueryClient_SupplyOf_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*types.QuerySupplyOfRequest), variadicArgs...) - }) - return _c -} - -func (_c *QueryClient_SupplyOf_Call) Return(_a0 *types.QuerySupplyOfResponse, _a1 error) *QueryClient_SupplyOf_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *QueryClient_SupplyOf_Call) RunAndReturn(run func(context.Context, *types.QuerySupplyOfRequest, ...grpc.CallOption) (*types.QuerySupplyOfResponse, error)) *QueryClient_SupplyOf_Call { - _c.Call.Return(run) - return _c -} - -// TotalSupply provides a mock function with given fields: ctx, in, opts -func (_m *QueryClient) TotalSupply(ctx context.Context, in *types.QueryTotalSupplyRequest, opts ...grpc.CallOption) (*types.QueryTotalSupplyResponse, error) { - _va := make([]interface{}, len(opts)) - for _i := range opts { - _va[_i] = opts[_i] - } - var _ca []interface{} - _ca = append(_ca, ctx, in) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - var r0 *types.QueryTotalSupplyResponse - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryTotalSupplyRequest, ...grpc.CallOption) (*types.QueryTotalSupplyResponse, error)); ok { - return rf(ctx, in, opts...) - } - if rf, ok := ret.Get(0).(func(context.Context, *types.QueryTotalSupplyRequest, ...grpc.CallOption) *types.QueryTotalSupplyResponse); ok { - r0 = rf(ctx, in, opts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.QueryTotalSupplyResponse) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, *types.QueryTotalSupplyRequest, ...grpc.CallOption) error); ok { - r1 = rf(ctx, in, opts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// QueryClient_TotalSupply_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TotalSupply' -type QueryClient_TotalSupply_Call struct { - *mock.Call -} - -// TotalSupply is a helper method to define mock.On call -// - ctx context.Context -// - in *types.QueryTotalSupplyRequest -// - opts ...grpc.CallOption -func (_e *QueryClient_Expecter) TotalSupply(ctx interface{}, in interface{}, opts ...interface{}) *QueryClient_TotalSupply_Call { - return &QueryClient_TotalSupply_Call{Call: _e.mock.On("TotalSupply", - append([]interface{}{ctx, in}, opts...)...)} -} - -func (_c *QueryClient_TotalSupply_Call) Run(run func(ctx context.Context, in *types.QueryTotalSupplyRequest, opts ...grpc.CallOption)) *QueryClient_TotalSupply_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]grpc.CallOption, len(args)-2) - for i, a := range args[2:] { - if a != nil { - variadicArgs[i] = a.(grpc.CallOption) - } - } - run(args[0].(context.Context), args[1].(*types.QueryTotalSupplyRequest), variadicArgs...) - }) - return _c -} - -func (_c *QueryClient_TotalSupply_Call) Return(_a0 *types.QueryTotalSupplyResponse, _a1 error) *QueryClient_TotalSupply_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *QueryClient_TotalSupply_Call) RunAndReturn(run func(context.Context, *types.QueryTotalSupplyRequest, ...grpc.CallOption) (*types.QueryTotalSupplyResponse, error)) *QueryClient_TotalSupply_Call { - _c.Call.Return(run) - return _c -} - -type mockConstructorTestingTNewQueryClient interface { - mock.TestingT - Cleanup(func()) -} - -// NewQueryClient creates a new instance of QueryClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewQueryClient(t mockConstructorTestingTNewQueryClient) *QueryClient { - mock := &QueryClient{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/testutil/state/suite.go b/testutil/state/suite.go index 36d0f488a6..e80f70b605 100644 --- a/testutil/state/suite.go +++ b/testutil/state/suite.go @@ -17,10 +17,10 @@ import ( ptypes "github.com/akash-network/akash-api/go/node/provider/v1beta3" "github.com/akash-network/node/app" + emocks "github.com/akash-network/node/testutil/cosmos/mocks" akeeper "github.com/akash-network/node/x/audit/keeper" dkeeper "github.com/akash-network/node/x/deployment/keeper" ekeeper "github.com/akash-network/node/x/escrow/keeper" - emocks "github.com/akash-network/node/x/escrow/keeper/mocks" mhooks "github.com/akash-network/node/x/market/hooks" mkeeper "github.com/akash-network/node/x/market/keeper" pkeeper "github.com/akash-network/node/x/provider/keeper" @@ -46,6 +46,7 @@ type Keepers struct { Provider pkeeper.IKeeper Bank *emocks.BankKeeper Distr *emocks.DistrKeeper + Authz *emocks.AuthzKeeper } // SetupTestSuite provides toolkit for accessing stores and keepers @@ -80,6 +81,12 @@ func SetupTestSuiteWithKeepers(t testing.TB, keepers Keepers) *TestSuite { keepers.Distr = dkeeper } + if keepers.Authz == nil { + keeper := &emocks.AuthzKeeper{} + + keepers.Authz = keeper + } + app := app.Setup(false) if keepers.Audit == nil { @@ -91,7 +98,7 @@ func SetupTestSuiteWithKeepers(t testing.TB, keepers Keepers) *TestSuite { } if keepers.Escrow == nil { - keepers.Escrow = ekeeper.NewKeeper(etypes.ModuleCdc, app.GetKey(etypes.StoreKey), keepers.Bank, keepers.Take, keepers.Distr) + keepers.Escrow = ekeeper.NewKeeper(etypes.ModuleCdc, app.GetKey(etypes.StoreKey), keepers.Bank, keepers.Take, keepers.Distr, keepers.Authz) } if keepers.Market == nil { keepers.Market = mkeeper.NewKeeper(mtypes.ModuleCdc, app.GetKey(mtypes.StoreKey), app.GetSubspace(mtypes.ModuleName), keepers.Escrow) @@ -164,3 +171,8 @@ func (ts *TestSuite) ProviderKeeper() pkeeper.IKeeper { func (ts *TestSuite) BankKeeper() *emocks.BankKeeper { return ts.keepers.Bank } + +// AuthzKeeper key store +func (ts *TestSuite) AuthzKeeper() *emocks.AuthzKeeper { + return ts.keepers.Authz +} diff --git a/upgrades/software/v0.34.0/init.go b/upgrades/software/v0.34.0/init.go new file mode 100644 index 0000000000..85fac9c593 --- /dev/null +++ b/upgrades/software/v0.34.0/init.go @@ -0,0 +1,11 @@ +// Package v0_34_0 +// nolint revive +package v0_34_0 + +import ( + utypes "github.com/akash-network/node/upgrades/types" +) + +func init() { + utypes.RegisterUpgrade(UpgradeName, initUpgrade) +} diff --git a/upgrades/software/v0.34.0/upgrade.go b/upgrades/software/v0.34.0/upgrade.go new file mode 100644 index 0000000000..1a20e1ad17 --- /dev/null +++ b/upgrades/software/v0.34.0/upgrade.go @@ -0,0 +1,47 @@ +// Package v0_34_0 +// nolint revive +package v0_34_0 + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + + apptypes "github.com/akash-network/node/app/types" + utypes "github.com/akash-network/node/upgrades/types" +) + +const ( + UpgradeName = "v0.34.0" +) + +type upgrade struct { + *apptypes.App + log log.Logger +} + +var _ utypes.IUpgrade = (*upgrade)(nil) + +func initUpgrade(log log.Logger, app *apptypes.App) (utypes.IUpgrade, error) { + up := &upgrade{ + App: app, + log: log.With("module", fmt.Sprintf("upgrade/%s", UpgradeName)), + } + + return up, nil +} + +func (up *upgrade) StoreLoader() *storetypes.StoreUpgrades { + return &storetypes.StoreUpgrades{} +} + +func (up *upgrade) UpgradeHandler() upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + return up.MM.RunMigrations(ctx, up.Configurator, fromVM) + } +} diff --git a/upgrades/upgrades.go b/upgrades/upgrades.go index 9a92c90f0c..c999c9713b 100644 --- a/upgrades/upgrades.go +++ b/upgrades/upgrades.go @@ -1,6 +1,8 @@ package upgrades import ( + // nolint: revive + _ "github.com/akash-network/node/upgrades/software/v0.34.0" // nolint: revive _ "github.com/akash-network/node/upgrades/software/v0.32.0" // nolint: revive diff --git a/x/deployment/handler/handler.go b/x/deployment/handler/handler.go index 7f2ae03952..4643f252d4 100644 --- a/x/deployment/handler/handler.go +++ b/x/deployment/handler/handler.go @@ -5,6 +5,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + "github.com/akash-network/node/x/deployment/keeper" ) diff --git a/x/deployment/handler/handler_test.go b/x/deployment/handler/handler_test.go index 265ee03b1a..62730b26c7 100644 --- a/x/deployment/handler/handler_test.go +++ b/x/deployment/handler/handler_test.go @@ -20,33 +20,30 @@ import ( types "github.com/akash-network/akash-api/go/node/deployment/v1beta3" "github.com/akash-network/node/testutil" + cmocks "github.com/akash-network/node/testutil/cosmos/mocks" "github.com/akash-network/node/testutil/state" - "github.com/akash-network/node/x/deployment/handler/mocks" "github.com/akash-network/node/x/deployment/keeper" mkeeper "github.com/akash-network/node/x/market/keeper" ) type testSuite struct { *state.TestSuite - t *testing.T - ctx sdk.Context - mkeeper mkeeper.IKeeper - dkeeper keeper.IKeeper - authzKeeper handler.AuthzKeeper - depositor string - handler sdk.Handler - + t *testing.T + ctx sdk.Context + mkeeper mkeeper.IKeeper + dkeeper keeper.IKeeper + authzKeeper handler.AuthzKeeper + depositor string + handler sdk.Handler defaultDeposit sdk.Coin } func setupTestSuite(t *testing.T) *testSuite { - ssuite := state.SetupTestSuite(t) - defaultDeposit, err := types.DefaultParams().MinDepositFor("uakt") require.NoError(t, err) depositor := testutil.AccAddress(t) - authzKeeper := &mocks.AuthzKeeper{} + authzKeeper := &cmocks.AuthzKeeper{} authzKeeper. On("GetCleanAuthorization", mock.Anything, mock.Anything, depositor, sdk.MsgTypeURL(&types.MsgDepositDeployment{})). Return(&types.DepositDeploymentAuthorization{ @@ -58,6 +55,16 @@ func setupTestSuite(t *testing.T) *testSuite { SpendLimit: defaultDeposit, }, time.Time{}). Once(). + On("GetCleanAuthorization", mock.Anything, mock.Anything, depositor, sdk.MsgTypeURL(&types.MsgDepositDeployment{})). + Return(&types.DepositDeploymentAuthorization{ + SpendLimit: defaultDeposit, + }, time.Time{}). + Once(). + On("GetCleanAuthorization", mock.Anything, mock.Anything, depositor, sdk.MsgTypeURL(&types.MsgDepositDeployment{})). + Return(&types.DepositDeploymentAuthorization{ + SpendLimit: defaultDeposit, + }, time.Time{}). + Once(). On("GetCleanAuthorization", mock.Anything, mock.Anything, mock.MatchedBy(func(addr sdk.AccAddress) bool { return !depositor.Equals(addr) @@ -70,13 +77,18 @@ func setupTestSuite(t *testing.T) *testSuite { On("SaveGrant", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(nil) + keepers := state.Keepers{ + Authz: authzKeeper, + } + ssuite := state.SetupTestSuiteWithKeepers(t, keepers) + suite := &testSuite{ TestSuite: ssuite, t: t, ctx: ssuite.Context(), mkeeper: ssuite.MarketKeeper(), dkeeper: ssuite.DeploymentKeeper(), - authzKeeper: authzKeeper, + authzKeeper: ssuite.AuthzKeeper(), depositor: depositor.String(), defaultDeposit: defaultDeposit, } diff --git a/x/deployment/handler/keepers.go b/x/deployment/handler/keepers.go index 4d0e31d086..fa0e76470c 100644 --- a/x/deployment/handler/keepers.go +++ b/x/deployment/handler/keepers.go @@ -22,6 +22,7 @@ type EscrowKeeper interface { AccountCreate(ctx sdk.Context, id etypes.AccountID, owner, depositor sdk.AccAddress, deposit sdk.Coin) error AccountDeposit(ctx sdk.Context, id etypes.AccountID, depositor sdk.AccAddress, amount sdk.Coin) error AccountClose(ctx sdk.Context, id etypes.AccountID) error + GetAccount(ctx sdk.Context, id etypes.AccountID) (etypes.Account, error) } //go:generate mockery --name AuthzKeeper --output ./mocks diff --git a/x/deployment/handler/mocks/authz_keeper.go b/x/deployment/handler/mocks/authz_keeper.go index 057e85bda6..2109d51ead 100644 --- a/x/deployment/handler/mocks/authz_keeper.go +++ b/x/deployment/handler/mocks/authz_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.24.0. DO NOT EDIT. +// Code generated by mockery v2.42.0. DO NOT EDIT. package mocks @@ -29,6 +29,10 @@ func (_m *AuthzKeeper) EXPECT() *AuthzKeeper_Expecter { func (_m *AuthzKeeper) DeleteGrant(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) error { ret := _m.Called(ctx, grantee, granter, msgType) + if len(ret) == 0 { + panic("no return value specified for DeleteGrant") + } + var r0 error if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) error); ok { r0 = rf(ctx, grantee, granter, msgType) @@ -74,6 +78,10 @@ func (_c *AuthzKeeper_DeleteGrant_Call) RunAndReturn(run func(types.Context, typ func (_m *AuthzKeeper) GetCleanAuthorization(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, msgType string) (authz.Authorization, time.Time) { ret := _m.Called(ctx, grantee, granter, msgType) + if len(ret) == 0 { + panic("no return value specified for GetCleanAuthorization") + } + var r0 authz.Authorization var r1 time.Time if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, string) (authz.Authorization, time.Time)); ok { @@ -131,6 +139,10 @@ func (_c *AuthzKeeper_GetCleanAuthorization_Call) RunAndReturn(run func(types.Co func (_m *AuthzKeeper) SaveGrant(ctx types.Context, grantee types.AccAddress, granter types.AccAddress, authorization authz.Authorization, expiration time.Time) error { ret := _m.Called(ctx, grantee, granter, authorization, expiration) + if len(ret) == 0 { + panic("no return value specified for SaveGrant") + } + var r0 error if rf, ok := ret.Get(0).(func(types.Context, types.AccAddress, types.AccAddress, authz.Authorization, time.Time) error); ok { r0 = rf(ctx, grantee, granter, authorization, expiration) @@ -173,13 +185,12 @@ func (_c *AuthzKeeper_SaveGrant_Call) RunAndReturn(run func(types.Context, types return _c } -type mockConstructorTestingTNewAuthzKeeper interface { +// NewAuthzKeeper creates a new instance of AuthzKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAuthzKeeper(t interface { mock.TestingT Cleanup(func()) -} - -// NewAuthzKeeper creates a new instance of AuthzKeeper. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewAuthzKeeper(t mockConstructorTestingTNewAuthzKeeper) *AuthzKeeper { +}) *AuthzKeeper { mock := &AuthzKeeper{} mock.Mock.Test(t) diff --git a/x/deployment/handler/server.go b/x/deployment/handler/server.go index cc60f7c76e..3399abb094 100644 --- a/x/deployment/handler/server.go +++ b/x/deployment/handler/server.go @@ -112,10 +112,12 @@ func (ms msgServer) authorizeDeposit(ctx sdk.Context, owner, depositor sdk.AccAd if authorization == nil { return sdkerrors.ErrUnauthorized.Wrap("authorization not found") } + resp, err := authorization.Accept(ctx, msg) if err != nil { return err } + if resp.Delete { err = ms.authzKeeper.DeleteGrant(ctx, owner, depositor, sdk.MsgTypeURL(msg)) } else if resp.Updated != nil { @@ -124,6 +126,7 @@ func (ms msgServer) authorizeDeposit(ctx sdk.Context, owner, depositor sdk.AccAd if err != nil { return err } + if !resp.Accept { return sdkerrors.ErrUnauthorized } @@ -153,12 +156,24 @@ func (ms msgServer) DepositDeployment(goCtx context.Context, msg *types.MsgDepos return &types.MsgDepositDeploymentResponse{}, err } + eID := types.EscrowAccountForDeployment(msg.ID) + + eAccount, err := ms.escrow.GetAccount(ctx, eID) + if err != nil { + return &types.MsgDepositDeploymentResponse{}, err + } + + // error if depositor is not an owner and there is already exists authorization from another account + if (msg.Depositor != msg.ID.Owner) && eAccount.HasDepositor() && (eAccount.Depositor != msg.Depositor) { + return &types.MsgDepositDeploymentResponse{}, types.ErrInvalidDeploymentDepositor + } + if err = ms.authorizeDeposit(ctx, owner, depositor, msg.Amount); err != nil { return nil, err } if err := ms.escrow.AccountDeposit(ctx, - types.EscrowAccountForDeployment(msg.ID), + eID, depositor, msg.Amount); err != nil { return &types.MsgDepositDeploymentResponse{}, err diff --git a/x/deployment/keeper/keeper.go b/x/deployment/keeper/keeper.go index ec1506cdb4..6368f14809 100644 --- a/x/deployment/keeper/keeper.go +++ b/x/deployment/keeper/keeper.go @@ -42,7 +42,6 @@ type Keeper struct { // NewKeeper creates and returns an instance for deployment keeper func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, pspace paramtypes.Subspace, ekeeper EscrowKeeper) IKeeper { - if !pspace.HasKeyTable() { pspace = pspace.WithKeyTable(types.ParamKeyTable()) } diff --git a/x/escrow/keeper/external.go b/x/escrow/keeper/external.go index e7f0907c6a..d4fef815b1 100644 --- a/x/escrow/keeper/external.go +++ b/x/escrow/keeper/external.go @@ -1,24 +1,30 @@ package keeper import ( + "time" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" ) -//go:generate mockery --name BankKeeper --output ./mocks type BankKeeper interface { SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error } -//go:generate mockery --name TakeKeeper --output ./mocks type TakeKeeper interface { SubtractFees(ctx sdk.Context, amt sdk.Coin) (sdk.Coin, sdk.Coin, error) } -//go:generate mockery --name DistrKeeper --output ./mocks type DistrKeeper interface { GetFeePool(ctx sdk.Context) distrtypes.FeePool SetFeePool(ctx sdk.Context, pool distrtypes.FeePool) } + +type AuthzKeeper interface { + DeleteGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) error + GetCleanAuthorization(ctx sdk.Context, grantee, granter sdk.AccAddress, msgType string) (cap authz.Authorization, expiration time.Time) + SaveGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization authz.Authorization, expiration time.Time) error +} diff --git a/x/escrow/keeper/keeper.go b/x/escrow/keeper/keeper.go index 903346e164..cae57f4606 100644 --- a/x/escrow/keeper/keeper.go +++ b/x/escrow/keeper/keeper.go @@ -3,10 +3,10 @@ package keeper import ( "fmt" + dtypes "github.com/akash-network/akash-api/go/node/deployment/v1beta3" + types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - - types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" ) @@ -27,30 +27,30 @@ type Keeper interface { GetPayment(ctx sdk.Context, id types.AccountID, pid string) (types.FractionalPayment, error) AddOnAccountClosedHook(AccountHook) Keeper AddOnPaymentClosedHook(PaymentHook) Keeper - - // for genesis WithAccounts(sdk.Context, func(types.Account) bool) WithPayments(sdk.Context, func(types.FractionalPayment) bool) SaveAccount(sdk.Context, types.Account) SavePayment(sdk.Context, types.FractionalPayment) } -func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, bkeeper BankKeeper, tkeeper TakeKeeper, dkeeper DistrKeeper) Keeper { +func NewKeeper(cdc codec.BinaryCodec, skey sdk.StoreKey, bkeeper BankKeeper, tkeeper TakeKeeper, dkeeper DistrKeeper, akeeper AuthzKeeper) Keeper { return &keeper{ - cdc: cdc, - skey: skey, - bkeeper: bkeeper, - tkeeper: tkeeper, - dkeeper: dkeeper, + cdc: cdc, + skey: skey, + bkeeper: bkeeper, + tkeeper: tkeeper, + dkeeper: dkeeper, + authzKeeper: akeeper, } } type keeper struct { - cdc codec.BinaryCodec - skey sdk.StoreKey - bkeeper BankKeeper - tkeeper TakeKeeper - dkeeper DistrKeeper + cdc codec.BinaryCodec + skey sdk.StoreKey + bkeeper BankKeeper + tkeeper TakeKeeper + dkeeper DistrKeeper + authzKeeper AuthzKeeper hooks struct { onAccountClosed []AccountHook @@ -105,14 +105,30 @@ func (k *keeper) fetchDepositToAccount(ctx sdk.Context, acc *types.Account, owne if err := k.bkeeper.SendCoinsFromAccountToModule(ctx, depositor, types.ModuleName, sdk.NewCoins(deposit)); err != nil { return err } + if owner.Equals(depositor) { acc.Balance = acc.Balance.Add(sdk.NewDecCoinFromCoin(deposit)) } else { acc.Funds = acc.Funds.Add(sdk.NewDecCoinFromCoin(deposit)) } + return nil } +func (k *keeper) GetAccountDepositor(ctx sdk.Context, id types.AccountID) (sdk.AccAddress, error) { + obj, err := k.GetAccount(ctx, id) + if err != nil { + return sdk.AccAddress{}, err + } + + depositor, err := sdk.AccAddressFromBech32(obj.Depositor) + if err != nil { + return sdk.AccAddress{}, err + } + + return depositor, nil +} + func (k *keeper) AccountDeposit(ctx sdk.Context, id types.AccountID, depositor sdk.AccAddress, amount sdk.Coin) error { store := ctx.KVStore(k.skey) key := accountKey(id) @@ -131,6 +147,14 @@ func (k *keeper) AccountDeposit(ctx sdk.Context, id types.AccountID, depositor s return err } + if (depositor.String() != obj.Owner) && obj.HasDepositor() { + if obj.Depositor != depositor.String() { + return types.ErrInvalidAccountDepositor + } + + obj.Depositor = depositor.String() + } + if err = k.fetchDepositToAccount(ctx, &obj, owner, depositor, amount); err != nil { return err } @@ -252,7 +276,6 @@ func (k *keeper) PaymentWithdraw(ctx sdk.Context, id types.AccountID, pid string } func (k *keeper) PaymentClose(ctx sdk.Context, id types.AccountID, pid string) error { - payment, err := k.GetPayment(ctx, id, pid) if err != nil { return err @@ -300,7 +323,6 @@ func (k *keeper) AddOnPaymentClosedHook(hook PaymentHook) Keeper { } func (k *keeper) GetAccount(ctx sdk.Context, id types.AccountID) (types.Account, error) { - store := ctx.KVStore(k.skey) key := accountKey(id) @@ -345,7 +367,11 @@ func (k *keeper) SavePayment(ctx sdk.Context, obj types.FractionalPayment) { func (k *keeper) WithAccounts(ctx sdk.Context, fn func(types.Account) bool) { store := ctx.KVStore(k.skey) iter := sdk.KVStorePrefixIterator(store, types.AccountKeyPrefix()) - defer iter.Close() + + defer func() { + _ = iter.Close() + }() + for ; iter.Valid(); iter.Next() { var val types.Account k.cdc.MustUnmarshal(iter.Value(), &val) @@ -358,7 +384,11 @@ func (k *keeper) WithAccounts(ctx sdk.Context, fn func(types.Account) bool) { func (k *keeper) WithPayments(ctx sdk.Context, fn func(types.FractionalPayment) bool) { store := ctx.KVStore(k.skey) iter := sdk.KVStorePrefixIterator(store, types.PaymentKeyPrefix()) - defer iter.Close() + + defer func() { + _ = iter.Close() + }() + for ; iter.Valid(); iter.Next() { var val types.FractionalPayment k.cdc.MustUnmarshal(iter.Value(), &val) @@ -400,12 +430,31 @@ func (k *keeper) doAccountSettle(ctx sdk.Context, id types.AccountID) (types.Acc blockRate = blockRate.Add(payment.Rate) } - account, payments, overdrawn, amountRemaining := accountSettleFullblocks( - account, payments, heightDelta, blockRate) + account, payments, overdrawn, amountRemaining := accountSettleFullBlocks(account, payments, heightDelta, blockRate) + + if account.Funds.Amount.IsPositive() { + owner := sdk.MustAccAddressFromBech32(account.Owner) + depositor := sdk.MustAccAddressFromBech32(account.Depositor) + + msg := &dtypes.MsgDepositDeployment{Amount: sdk.NewCoin(account.Balance.Denom, sdk.NewInt(0))} + + authz, _ := k.authzKeeper.GetCleanAuthorization(ctx, owner, depositor, sdk.MsgTypeURL(msg)) + + // if authorization has been revoked or expired it cannot be used anymore + // send coins back to the owner + if authz == nil { + withdrawal := sdk.NewCoin(account.Balance.Denom, account.Funds.Amount.TruncateInt()) + if err := k.bkeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, depositor, sdk.NewCoins(withdrawal)); err != nil { + ctx.Logger().Error("account withdraw", "err", err, "id", account.ID) + return account, payments, overdrawn, err + } + + account.Funds.Amount = sdk.ZeroDec() + } + } // all payments made in full if !overdrawn { - // save objects k.saveAccount(ctx, &account) for idx := range payments { @@ -421,8 +470,7 @@ func (k *keeper) doAccountSettle(ctx sdk.Context, id types.AccountID) (types.Acc // // distribute weighted by payment block rate - account, payments, amountRemaining = accountSettleDistributeWeighted( - account, payments, blockRate, amountRemaining) + account, payments, amountRemaining = accountSettleDistributeWeighted(account, payments, blockRate, amountRemaining) if amountRemaining.Amount.GT(sdk.NewDec(1)) { return account, payments, false, fmt.Errorf("%w: Invalid settlement: %v remains", types.ErrInvalidSettlement, amountRemaining) @@ -471,7 +519,10 @@ func (k *keeper) accountPayments(ctx sdk.Context, id types.AccountID) []types.Fr var payments []types.FractionalPayment - defer iter.Close() + defer func() { + _ = iter.Close() + }() + for ; iter.Valid(); iter.Next() { var val types.FractionalPayment k.cdc.MustUnmarshal(iter.Value(), &val) @@ -491,6 +542,7 @@ func (k *keeper) accountOpenPayments(ctx sdk.Context, id types.AccountID) []type } payments = append(payments, payment) } + return payments } @@ -499,12 +551,12 @@ func (k *keeper) accountWithdraw(ctx sdk.Context, obj *types.Account) error { return nil } - if !obj.Balance.Amount.LT(sdk.NewDec(1)) { - owner, err := sdk.AccAddressFromBech32(obj.Owner) - if err != nil { - return err - } + owner, err := sdk.AccAddressFromBech32(obj.Owner) + if err != nil { + return err + } + if !obj.Balance.Amount.LT(sdk.NewDec(1)) { withdrawal := sdk.NewCoin(obj.Balance.Denom, obj.Balance.Amount.TruncateInt()) if err = k.bkeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, owner, sdk.NewCoins(withdrawal)); err != nil { ctx.Logger().Error("account withdraw", "err", err, "id", obj.ID) @@ -513,7 +565,7 @@ func (k *keeper) accountWithdraw(ctx sdk.Context, obj *types.Account) error { obj.Balance = obj.Balance.Sub(sdk.NewDecCoinFromCoin(withdrawal)) } - if !obj.Funds.Amount.LT(sdk.NewDec(1)) { + if obj.Funds.IsPositive() { depositor, err := sdk.AccAddressFromBech32(obj.Depositor) if err != nil { return err @@ -524,10 +576,26 @@ func (k *keeper) accountWithdraw(ctx sdk.Context, obj *types.Account) error { ctx.Logger().Error("account withdraw", "err", err, "id", obj.ID) return err } + obj.Funds = obj.Funds.Sub(sdk.NewDecCoinFromCoin(withdrawal)) + + msg := &dtypes.MsgDepositDeployment{Amount: sdk.NewCoin(obj.Balance.Denom, sdk.NewInt(0))} + + // Funds field is solely to track deposits via authz. + // check if there is active deployment authorization from given depositor + // if exists, increase allowed authz deposit by remainder in the Funds, it will allow owner to reuse active authz + // without asking for renew. + authorization, expiration := k.authzKeeper.GetCleanAuthorization(ctx, owner, depositor, sdk.MsgTypeURL(msg)) + dauthz, valid := authorization.(*dtypes.DepositDeploymentAuthorization) + if valid && authorization != nil { + dauthz.SpendLimit = dauthz.SpendLimit.Add(withdrawal) + err = k.authzKeeper.SaveGrant(ctx, owner, depositor, dauthz, expiration) + return err + } } k.saveAccount(ctx, obj) + return nil } @@ -566,6 +634,7 @@ func (k *keeper) paymentWithdraw(ctx sdk.Context, obj *types.FractionalPayment) obj.Balance = obj.Balance.Sub(sdk.NewDecCoinFromCoin(total)) k.savePayment(ctx, obj) + return nil } @@ -587,7 +656,7 @@ func (k *keeper) sendFeeToCommunityPool(ctx sdk.Context, fee sdk.Coin) error { return nil } -func accountSettleFullblocks( +func accountSettleFullBlocks( account types.Account, payments []types.FractionalPayment, heightDelta sdk.Int, @@ -648,7 +717,6 @@ func accountSettleDistributeWeighted( []types.FractionalPayment, sdk.DecCoin, ) { - actualTransferred := sdk.ZeroDec() // distribute remaining balance weighted by rate diff --git a/x/escrow/keeper/keeper_settle_test.go b/x/escrow/keeper/keeper_settle_test.go index bc28d57ee7..971ae88a9f 100644 --- a/x/escrow/keeper/keeper_settle_test.go +++ b/x/escrow/keeper/keeper_settle_test.go @@ -11,7 +11,7 @@ import ( const denom = "uakt" -func TestSettleFullblocks(t *testing.T) { +func TestSettleFullBlocks(t *testing.T) { for _, tt := range []struct { name string cfg distTestConfig @@ -165,7 +165,7 @@ func TestSettleFullblocks(t *testing.T) { } { account, payments, blocks, blockRate := setupDistTest(tt.cfg) - account, payments, overdrawn, remaining := accountSettleFullblocks( + account, payments, overdrawn, remaining := accountSettleFullBlocks( account, payments, blocks, blockRate) assertCoinsEqual(t, sdk.NewInt64DecCoin(denom, tt.cfg.balanceEnd), account.Balance, tt.name) diff --git a/x/escrow/keeper/keeper_test.go b/x/escrow/keeper/keeper_test.go index 29b8d4fac0..4e91454823 100644 --- a/x/escrow/keeper/keeper_test.go +++ b/x/escrow/keeper/keeper_test.go @@ -10,9 +10,9 @@ import ( types "github.com/akash-network/akash-api/go/node/escrow/v1beta3" "github.com/akash-network/node/testutil" + "github.com/akash-network/node/testutil/cosmos/mocks" "github.com/akash-network/node/testutil/state" "github.com/akash-network/node/x/escrow/keeper" - "github.com/akash-network/node/x/escrow/keeper/mocks" ) func Test_AccountCreate(t *testing.T) {