diff --git a/app/app.go b/app/app.go index a54cedc1..c6e383eb 100644 --- a/app/app.go +++ b/app/app.go @@ -126,6 +126,11 @@ import ( assetmodulekeeper "github.com/realiotech/realio-network/x/asset/keeper" assetmoduletypes "github.com/realiotech/realio-network/x/asset/types" + "github.com/realiotech/realio-network/x/asset/priviledges/clawback" + "github.com/realiotech/realio-network/x/asset/priviledges/freeze" + mintpriviledge "github.com/realiotech/realio-network/x/asset/priviledges/mint" + "github.com/realiotech/realio-network/x/asset/priviledges/transfer_auth" + realionetworktypes "github.com/realiotech/realio-network/types" // unnamed import of statik for swagger UI support @@ -309,6 +314,8 @@ func New( // multi-staking keys multistakingtypes.StoreKey, // this line is used by starport scaffolding # stargate/app/storeKey + freeze.StoreKey, + transfer_auth.StoreKey, ) // Add the EVM transient store key @@ -415,6 +422,23 @@ func New( app.AccountKeeper, ) + err := app.AssetKeeper.AddPrivilege(mintpriviledge.NewMintPriviledge(app.BankKeeper)) + if err != nil { + panic(err) + } + err = app.AssetKeeper.AddPrivilege(freeze.NewFreezePriviledge(keys[freeze.StoreKey])) + if err != nil { + panic(err) + } + err = app.AssetKeeper.AddPrivilege(transfer_auth.NewTransferAuthPriviledge(keys[transfer_auth.StoreKey])) + if err != nil { + panic(err) + } + err = app.AssetKeeper.AddPrivilege(clawback.NewClawbackPriviledge(app.BankKeeper)) + if err != nil { + panic(err) + } + app.BankKeeper.AppendSendRestriction(app.AssetKeeper.AssetSendRestriction) // IBC Keeper diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go new file mode 100644 index 00000000..6b0ee013 --- /dev/null +++ b/app/apptesting/test_suite.go @@ -0,0 +1,45 @@ +package apptesting + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + "github.com/realiotech/realio-network/app" + "github.com/realiotech/realio-network/x/asset/keeper" + "github.com/realiotech/realio-network/x/asset/types" +) + +type KeeperTestSuite struct { + suite.Suite + app *app.RealioNetwork + ctx sdk.Context + + assetKeeper *keeper.Keeper + govkeeper govkeeper.Keeper + msgServer types.MsgServer + bankKeeper bankkeeper.Keeper +} + +func (suite *KeeperTestSuite) SetupTest() { + app := app.Setup(false, nil, 3) + + suite.app = app + suite.ctx = app.BaseApp.NewContext(false, tmproto.Header{Height: app.LastBlockHeight() + 1}) + suite.assetKeeper = keeper.NewKeeper( + app.AppCodec(), app.InterfaceRegistry(), app.GetKey(types.StoreKey), + app.GetMemKey(types.MemStoreKey), app.GetSubspace(types.ModuleName), app.BankKeeper, app.AccountKeeper, + ) + suite.govkeeper = app.GovKeeper + suite.bankKeeper = app.BankKeeper +} + +func (suite *KeeperTestSuite) + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} diff --git a/x/asset/priviledges/clawback/msg_handler.go b/x/asset/priviledges/clawback/msg_handler.go index 5bbd9f51..16d0b6a1 100644 --- a/x/asset/priviledges/clawback/msg_handler.go +++ b/x/asset/priviledges/clawback/msg_handler.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/gogo/protobuf/proto" "github.com/pkg/errors" + assettypes "github.com/realiotech/realio-network/x/asset/types" // "github.com/cosmos/cosmos-sdk/store/types" ) @@ -19,9 +20,9 @@ func (cp ClawbackPriviledge) clawbackToken(ctx sdk.Context, msg *MsgClawbackToke return fmt.Errorf("invalid bech 32 address: %v", err) } - spendable := cp.bk.SpendableCoin(ctx, senderAddr, tokenID) + spendable := cp.bk.SpendableCoins(ctx, senderAddr) - if spendable.Amount.LT(sdk.NewIntFromUint64(msg.Amount)) { + if spendable.IsAllLT(sdk.NewCoins(sdk.NewCoin(tokenID, sdk.NewIntFromUint64(msg.Amount)))) { return fmt.Errorf("insufficient funds want %s have %s", clawbackCoin.String(), spendable.String()) } @@ -33,14 +34,16 @@ func (cp ClawbackPriviledge) clawbackToken(ctx sdk.Context, msg *MsgClawbackToke return err } -func (cp ClawbackPriviledge) MsgHandler(context context.Context, msg proto.Message, tokenID string, privAcc sdk.AccAddress) (proto.Message, error) { - ctx := sdk.UnwrapSDKContext(context) - - switch msg := msg.(type) { - case *MsgClawbackToken: - return nil, cp.clawbackToken(ctx, msg, tokenID, privAcc) - default: - errMsg := fmt.Sprintf("unrecognized message type: %T for Clawback priviledge", msg) - return nil, errors.Errorf(errMsg) +func (cp ClawbackPriviledge) MsgHandler() assettypes.MsgHandler { + return func(context context.Context, msg proto.Message, tokenID string, privAcc sdk.AccAddress) (proto.Message, error) { + ctx := sdk.UnwrapSDKContext(context) + + switch msg := msg.(type) { + case *MsgClawbackToken: + return nil, cp.clawbackToken(ctx, msg, tokenID, privAcc) + default: + errMsg := fmt.Sprintf("unrecognized message type: %T for Clawback priviledge", msg) + return nil, errors.Errorf(errMsg) + } } } diff --git a/x/asset/priviledges/clawback/priv.go b/x/asset/priviledges/clawback/priv.go index 0657b194..e65f640f 100644 --- a/x/asset/priviledges/clawback/priv.go +++ b/x/asset/priviledges/clawback/priv.go @@ -1,7 +1,10 @@ package clawback import ( + "context" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + proto "github.com/gogo/protobuf/proto" assettypes "github.com/realiotech/realio-network/x/asset/types" ) @@ -26,3 +29,9 @@ func (cp ClawbackPriviledge) RegisterInterfaces(registry cdctypes.InterfaceRegis &MsgClawbackToken{}, ) } + +func (cb ClawbackPriviledge) QueryHandler() assettypes.QueryHandler { + return func(context context.Context, privQuery proto.Message, tokenID string) (proto.Message, error) { + return nil, nil + } +} diff --git a/x/asset/priviledges/clawback/priv_test.go b/x/asset/priviledges/clawback/priv_test.go new file mode 100644 index 00000000..b2bc94ac --- /dev/null +++ b/x/asset/priviledges/clawback/priv_test.go @@ -0,0 +1,5 @@ +package clawback_test + +// import ( +// assettest "github.com/realiotech/realio-network/x/asset/keeper" +// ) diff --git a/x/asset/priviledges/clawback/types.go b/x/asset/priviledges/clawback/types.go index 93ceffa0..53fdcca7 100644 --- a/x/asset/priviledges/clawback/types.go +++ b/x/asset/priviledges/clawback/types.go @@ -6,5 +6,5 @@ import ( type BankKeeper interface { SendCoins(ctx sdk.Context, senderAddr, recipientAddr sdk.AccAddress, amt sdk.Coins) error - SpendableCoin(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin + SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins } diff --git a/x/asset/priviledges/freeze/msg_server.go b/x/asset/priviledges/freeze/msg_server.go index 9f14a5a5..6a9886ea 100644 --- a/x/asset/priviledges/freeze/msg_server.go +++ b/x/asset/priviledges/freeze/msg_server.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/gogo/protobuf/proto" "github.com/pkg/errors" + assettypes "github.com/realiotech/realio-network/x/asset/types" // "github.com/cosmos/cosmos-sdk/store/types" ) @@ -24,16 +25,18 @@ func (mp FreezePriviledge) UnfreezeToken(ctx sdk.Context, msg *MsgUnfreezeToken, return nil } -func (mp FreezePriviledge) MsgHandler(context context.Context, msg proto.Message, tokenID string, privAcc sdk.AccAddress) (proto.Message, error) { - ctx := sdk.UnwrapSDKContext(context) +func (mp FreezePriviledge) MsgHandler() assettypes.MsgHandler { + return func(context context.Context, msg proto.Message, tokenID string, privAcc sdk.AccAddress) (proto.Message, error) { + ctx := sdk.UnwrapSDKContext(context) - switch msg := msg.(type) { - case *MsgFreezeToken: - return nil, mp.FreezeToken(ctx, msg, tokenID) - case *MsgUnfreezeToken: - return nil, mp.UnfreezeToken(ctx, msg, tokenID) - default: - errMsg := fmt.Sprintf("unrecognized message type: %T for Transfer auth priviledge", msg) - return nil, errors.Errorf(errMsg) + switch msg := msg.(type) { + case *MsgFreezeToken: + return nil, mp.FreezeToken(ctx, msg, tokenID) + case *MsgUnfreezeToken: + return nil, mp.UnfreezeToken(ctx, msg, tokenID) + default: + errMsg := fmt.Sprintf("unrecognized message type: %T for Transfer auth priviledge", msg) + return nil, errors.Errorf(errMsg) + } } } diff --git a/x/asset/priviledges/freeze/priv.go b/x/asset/priviledges/freeze/priv.go index 0c457f0d..cc090328 100644 --- a/x/asset/priviledges/freeze/priv.go +++ b/x/asset/priviledges/freeze/priv.go @@ -10,7 +10,8 @@ import ( ) var ( - _ keeper.RestrictionChecker = (*FreezePriviledge)(nil) + _ keeper.RestrictionChecker = (*FreezePriviledge)(nil) + StoreKey = "freezepriv" ) const priv_name = "transfer_auth" diff --git a/x/asset/priviledges/mint/msg_server.go b/x/asset/priviledges/mint/msg_server.go index d1391f81..b50b0137 100644 --- a/x/asset/priviledges/mint/msg_server.go +++ b/x/asset/priviledges/mint/msg_server.go @@ -25,14 +25,16 @@ func (mp MintPriviledge) MintToken(ctx sdk.Context, msg *MsgMintToken, tokenID s return err } -func (mp MintPriviledge) MsgHandler(context context.Context, msg proto.Message, tokenID string, privAcc sdk.AccAddress) (proto.Message, error) { - ctx := sdk.UnwrapSDKContext(context) - - switch msg := msg.(type) { - case *MsgMintToken: - return nil, mp.MintToken(ctx, msg, tokenID) - default: - errMsg := fmt.Sprintf("unrecognized message type: %T for Mint priviledge", msg) - return nil, errors.Errorf(errMsg) +func (mp MintPriviledge) MsgHandler() assettypes.MsgHandler { + return func(context context.Context, msg proto.Message, tokenID string, privAcc sdk.AccAddress) (proto.Message, error) { + ctx := sdk.UnwrapSDKContext(context) + + switch msg := msg.(type) { + case *MsgMintToken: + return nil, mp.MintToken(ctx, msg, tokenID) + default: + errMsg := fmt.Sprintf("unrecognized message type: %T for Mint priviledge", msg) + return nil, errors.Errorf(errMsg) + } } } diff --git a/x/asset/priviledges/mint/priv.go b/x/asset/priviledges/mint/priv.go index 313fd083..1ab1a46f 100644 --- a/x/asset/priviledges/mint/priv.go +++ b/x/asset/priviledges/mint/priv.go @@ -1,7 +1,10 @@ package mint import ( + "context" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + proto "github.com/gogo/protobuf/proto" assettypes "github.com/realiotech/realio-network/x/asset/types" ) @@ -26,3 +29,9 @@ func (mp MintPriviledge) RegisterInterfaces(registry cdctypes.InterfaceRegistry) &MsgMintToken{}, ) } + +func (mp MintPriviledge) QueryHandler() assettypes.QueryHandler { + return func(context context.Context, privQuery proto.Message, tokenID string) (proto.Message, error) { + return nil, nil + } +} diff --git a/x/asset/priviledges/transfer_auth/msg_server.go b/x/asset/priviledges/transfer_auth/msg_server.go index 9f31c827..adf6bda9 100644 --- a/x/asset/priviledges/transfer_auth/msg_server.go +++ b/x/asset/priviledges/transfer_auth/msg_server.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/gogo/protobuf/proto" "github.com/pkg/errors" + assettypes "github.com/realiotech/realio-network/x/asset/types" // "github.com/cosmos/cosmos-sdk/store/types" ) @@ -21,14 +22,16 @@ func (mp TransferAuthPriviledge) UpdateAllowList(ctx sdk.Context, msg *MsgUpdate return nil } -func (mp TransferAuthPriviledge) MsgHandler(context context.Context, msg proto.Message, tokenID string, privAcc sdk.AccAddress) (proto.Message, error) { - ctx := sdk.UnwrapSDKContext(context) +func (mp TransferAuthPriviledge) MsgHandler() assettypes.MsgHandler { + return func(context context.Context, msg proto.Message, tokenID string, privAcc sdk.AccAddress) (proto.Message, error) { + ctx := sdk.UnwrapSDKContext(context) - switch msg := msg.(type) { - case *MsgUpdateAllowList: - return nil, mp.UpdateAllowList(ctx, msg, tokenID) - default: - errMsg := fmt.Sprintf("unrecognized message type: %T for Transfer auth priviledge", msg) - return nil, errors.Errorf(errMsg) + switch msg := msg.(type) { + case *MsgUpdateAllowList: + return nil, mp.UpdateAllowList(ctx, msg, tokenID) + default: + errMsg := fmt.Sprintf("unrecognized message type: %T for Transfer auth priviledge", msg) + return nil, errors.Errorf(errMsg) + } } } diff --git a/x/asset/priviledges/transfer_auth/priv.go b/x/asset/priviledges/transfer_auth/priv.go index 969ec955..a5ab806d 100644 --- a/x/asset/priviledges/transfer_auth/priv.go +++ b/x/asset/priviledges/transfer_auth/priv.go @@ -1,7 +1,7 @@ package transfer_auth import ( - "github.com/realiotech/realio-network/x/asset/keeper" + assetkeeper "github.com/realiotech/realio-network/x/asset/keeper" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" @@ -10,7 +10,8 @@ import ( ) var ( - _ keeper.RestrictionChecker = (*TransferAuthPriviledge)(nil) + _ assetkeeper.RestrictionChecker = (*TransferAuthPriviledge)(nil) + StoreKey = "transferauthpriv" ) const priv_name = "transfer_auth" diff --git a/x/asset/priviledges/transfer_auth/query_server.go b/x/asset/priviledges/transfer_auth/query_server.go index 2e41f39a..cee4c702 100644 --- a/x/asset/priviledges/transfer_auth/query_server.go +++ b/x/asset/priviledges/transfer_auth/query_server.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" proto "github.com/gogo/protobuf/proto" "github.com/pkg/errors" + assettypes "github.com/realiotech/realio-network/x/asset/types" ) func (tp TransferAuthPriviledge) QueryWhitelistedAddresses(ctx sdk.Context, req *QueryWhitelistedAddressesRequest, tokenID string) (*QueryWhitelistedAddressesResponse, error) { @@ -23,16 +24,18 @@ func (mp TransferAuthPriviledge) QueryIsAddressWhitelisted(ctx sdk.Context, req }, nil } -func (mp TransferAuthPriviledge) QueryHandler(context context.Context, req proto.Message, tokenID string) (proto.Message, error) { - ctx := sdk.UnwrapSDKContext(context) +func (mp TransferAuthPriviledge) QueryHandler() assettypes.QueryHandler { + return func(context context.Context, req proto.Message, tokenID string) (proto.Message, error) { + ctx := sdk.UnwrapSDKContext(context) - switch req := req.(type) { - case *QueryWhitelistedAddressesRequest: - return mp.QueryWhitelistedAddresses(ctx, req, tokenID) - case *QueryIsAddressWhitelistedRequest: - return mp.QueryIsAddressWhitelisted(ctx, req, tokenID) - default: - errMsg := fmt.Sprintf("unrecognized query request type: %T for Transfer auth priviledge", req) - return nil, errors.Errorf(errMsg) + switch req := req.(type) { + case *QueryWhitelistedAddressesRequest: + return mp.QueryWhitelistedAddresses(ctx, req, tokenID) + case *QueryIsAddressWhitelistedRequest: + return mp.QueryIsAddressWhitelisted(ctx, req, tokenID) + default: + errMsg := fmt.Sprintf("unrecognized query request type: %T for Transfer auth priviledge", req) + return nil, errors.Errorf(errMsg) + } } }