Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: whitelist manager proposal #177

Open
wants to merge 2 commits into
base: new-asset-module
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,8 @@ func New(
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)).
AddRoute(multistakingtypes.RouterKey, multistaking.NewMultiStakingProposalHandler(&app.MultiStakingKeeper))
AddRoute(multistakingtypes.RouterKey, multistaking.NewMultiStakingProposalHandler(&app.MultiStakingKeeper)).
AddRoute(assetmoduletypes.RouterKey, assetmodule.NewAssetProposalHandler(&app.AssetKeeper))

govConfig := govtypes.DefaultConfig()
/*
Expand Down
31 changes: 31 additions & 0 deletions proto/realionetwork/asset/v1/proposal.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
syntax = "proto3";

package realionetwork.asset.v1;

import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";

option go_package = "github.com/realiotech/realio-network/x/asset/types";

message AddTokenManager {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

string title = 1;
string description = 2;
string manager_address = 3;
}

message RemoveTokenManager {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (gogoproto.goproto_stringer) = false;
option (cosmos_proto.implements_interface) = "cosmos.gov.v1beta1.Content";

string title = 1;
string description = 2;
string manager_address = 3;
}

73 changes: 73 additions & 0 deletions x/asset/client/cli/proposal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package cli

import (
"github.com/realiotech/realio-network/x/asset/types"
"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)

func NewCmdAddTokenManagerProposal() *cobra.Command {
cmd := &cobra.Command{
Use: "add-token-manager [title] [description] [manager] [deposit]",
Args: cobra.ExactArgs(4),
Short: "Submit an add token manager proposal",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

from := clientCtx.GetFromAddress()
content := types.NewAddTokenManager(args[0], args[1], args[2])

deposit, err := sdk.ParseCoinsNormalized(args[3])
if err != nil {
return err
}

msg, err := govv1beta1.NewMsgSubmitProposal(content, deposit, from)
if err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

return cmd
}

func NewCmdRemoveTokenManagerProposal() *cobra.Command {
cmd := &cobra.Command{
Use: "remove-token-manager [title] [description] [manager] [deposit]",
Args: cobra.ExactArgs(4),
Short: "Submit an remove token manager proposal",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

from := clientCtx.GetFromAddress()
content := types.NewRemoveTokenManager(args[0], args[1], args[2])

deposit, err := sdk.ParseCoinsNormalized(args[3])
if err != nil {
return err
}

msg, err := govv1beta1.NewMsgSubmitProposal(content, deposit, from)
if err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

return cmd
}
59 changes: 59 additions & 0 deletions x/asset/keeper/proposal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package keeper

import (
"fmt"

"github.com/realiotech/realio-network/x/asset/types"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// AddTokenManager handles the proposals to add a new manager
func (k Keeper) AddTokenManager(
ctx sdk.Context,
p *types.AddTokenManager,
) error {
managerAddress, err := sdk.AccAddressFromBech32(p.ManagerAddress)
if err != nil {
return err
}

ok := k.IsTokenManager(ctx, managerAddress)
if ok {
return fmt.Errorf("manager %s already exist", p.ManagerAddress)
}

k.SetTokenManager(ctx, managerAddress)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAddTokenManager,
sdk.NewAttribute(types.AttributeKeyAddress, p.ManagerAddress),
),
)
return nil
}

// RemoveTokenManager handles the proposals to add a new manager
func (k Keeper) RemoveTokenManager(
ctx sdk.Context,
p *types.RemoveTokenManager,
) error {
managerAddress, err := sdk.AccAddressFromBech32(p.ManagerAddress)
if err != nil {
return err
}

ok := k.IsTokenManager(ctx, managerAddress)
if !ok {
return fmt.Errorf("manager %s is not exist", p.ManagerAddress)
}

k.DeleteTokenManager(ctx, managerAddress)
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeAddTokenManager,
sdk.NewAttribute(types.AttributeKeyAddress, p.ManagerAddress),
),
)
return nil
}
27 changes: 26 additions & 1 deletion x/asset/keeper/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (k Keeper) SetTokenPrivilegeAccount(
bz := k.cdc.MustMarshal(&privList)
store.Set(key, bz)
}
}
}

func (k Keeper) DeleteTokenPrivilegeAccount(
ctx sdk.Context,
Expand Down Expand Up @@ -145,3 +145,28 @@ func (k Keeper) GetTokenAccountPrivileges(

return privList.Privileges
}

func (k Keeper) SetTokenManager(
ctx sdk.Context,
address sdk.AccAddress,
) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ManagerStoreKey)
store.Set(types.GetManagerKey(address), types.ManagerExists)
}

func (k Keeper) IsTokenManager(
ctx sdk.Context,
address sdk.AccAddress,
) bool {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ManagerStoreKey)
bz := store.Get(types.GetManagerKey(address))
return bz != nil
}

func (k Keeper) DeleteTokenManager(
ctx sdk.Context,
address sdk.AccAddress,
) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ManagerStoreKey)
store.Delete(types.GetManagerKey(address))
}
33 changes: 33 additions & 0 deletions x/asset/proposal_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package asset

import (
"github.com/realiotech/realio-network/x/asset/client/cli"
"github.com/realiotech/realio-network/x/asset/keeper"
"github.com/realiotech/realio-network/x/asset/types"

sdkerrors "cosmossdk.io/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
errortypes "github.com/cosmos/cosmos-sdk/types/errors"
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)

var (
AddTokenManagerHandler = govclient.NewProposalHandler(cli.NewCmdAddTokenManagerProposal)
RemoveTokenManagerHandler = govclient.NewProposalHandler(cli.NewCmdRemoveTokenManagerProposal)
)

// NewAssetProposalHandler creates a governance handler to manage asset proposals.
func NewAssetProposalHandler(k *keeper.Keeper) govv1beta1.Handler {
return func(ctx sdk.Context, content govv1beta1.Content) error {
switch c := content.(type) {
case *types.AddTokenManager:
return k.AddTokenManager(ctx, c)
case *types.RemoveTokenManager:
return k.RemoveTokenManager(ctx, c)
default:
return sdkerrors.Wrapf(errortypes.ErrUnknownRequest, "unrecognized %s proposal content type: %T", types.ModuleName, c)
}
}
}
3 changes: 3 additions & 0 deletions x/asset/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
EventTypeTokenCreated = "create_token"
EventTypeTokenUpdated = "update_token"

EventTypeAddTokenManager = "add_manager"
EventTypeRemoveTokenManager = "remove_manager"

AttributeKeyTokenId = "token_id"

Check warning on line 11 in x/asset/types/events.go

View workflow job for this annotation

GitHub Actions / lint

var-naming: const AttributeKeyTokenId should be AttributeKeyTokenID (revive)
AttributeKeySymbol = "symbol"
AttributeKeyIndex = "index"
AttributeKeyAddress = "address"
Expand Down
10 changes: 10 additions & 0 deletions x/asset/types/keys.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package types

import sdk "github.com/cosmos/cosmos-sdk/types"

const (
// ModuleName defines the module name
ModuleName = "asset"
Expand Down Expand Up @@ -35,4 +37,12 @@
PrivilegedAccountsKey = []byte{0x02}
// PrivilegeStoreKey
PrivilegeStoreKey = []byte{0x03}
// PrivilegeStoreKey
ManagerStoreKey = []byte{0x04}
// ManagerExists is the byte to determine manager is exists
ManagerExists = []byte{0x01}
)

func GetManagerKey(manager sdk.AccAddress) []byte {
return append(ManagerStoreKey, manager.Bytes()...)
}

Check failure on line 48 in x/asset/types/keys.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
106 changes: 106 additions & 0 deletions x/asset/types/proposal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package types

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)

// Proposal types
const (
ProposalTypeAddTokenManager string = "AddTokenManager"
ProposalTypeRemoveTokenManager string = "RemoveTokenManager"
)

var (
_ govv1beta1.Content = &AddTokenManager{}
_ govv1beta1.Content = &RemoveTokenManager{}
)

func init() {
govv1beta1.RegisterProposalType(ProposalTypeAddTokenManager)
govv1beta1.RegisterProposalType(ProposalTypeRemoveTokenManager)
}

// NewAddAddTokenManager returns new instance of AddTokenManager proposal
func NewAddTokenManager(title, description, manager string) govv1beta1.Content {
return &AddTokenManager{
Title: title,
Description: description,
ManagerAddress: manager,
}
}

// GetTitle returns the title of a AddTokenManager
func (atmp *AddTokenManager) GetTitle() string { return atmp.Title }

// GetDescription returns the description of a AddTokenManager
func (atmp *AddTokenManager) GetDescription() string { return atmp.Description }

// ProposalRoute returns router key for a AddTokenManager
func (*AddTokenManager) ProposalRoute() string { return RouterKey }

// ProposalType returns proposal type for a AddTokenManager
func (*AddTokenManager) ProposalType() string {
return ProposalTypeAddTokenManager
}

// ValidateBasic runs basic stateless validity checks
func (atmp *AddTokenManager) ValidateBasic() error {
err := govv1beta1.ValidateAbstract(atmp)
if err != nil {
return err
}
if _, err = sdk.AccAddressFromBech32(atmp.ManagerAddress); err != nil {
return err
}

return nil
}

// String implements the Stringer interface.
func (atmp AddTokenManager) String() string {
return fmt.Sprintf("AddTokenManager: Title: %s Description: %s Manager: %s", atmp.Title, atmp.Description, atmp.ManagerAddress)
}

// NewRemoveTokenManager returns new instance of RemoveTokenManager
func NewRemoveTokenManager(title, description, manager string) govv1beta1.Content {
return &RemoveTokenManager{
Title: title,
Description: description,
ManagerAddress: manager,
}
}

// GetTitle returns the title of a RemoveTokenManager
func (rtmp *RemoveTokenManager) GetTitle() string { return rtmp.Title }

// GetDescription returns the description of a RemoveTokenManager
func (rtmp *RemoveTokenManager) GetDescription() string { return rtmp.Description }

// ProposalRoute returns router key for a RemoveTokenManager
func (*RemoveTokenManager) ProposalRoute() string { return RouterKey }

// ProposalType returns proposal type for a RemoveTokenManager
func (*RemoveTokenManager) ProposalType() string {
return ProposalTypeRemoveTokenManager
}

// String implements the Stringer interface.
func (rtmp RemoveTokenManager) String() string {
return fmt.Sprintf("UpdateBondWeightProposal: Title: %s Description: %s Manager: %s", rtmp.Title, rtmp.Description, rtmp.ManagerAddress)
}

// ValidateBasic runs basic stateless validity checks
func (rtmp *RemoveTokenManager) ValidateBasic() error {
err := govv1beta1.ValidateAbstract(rtmp)
if err != nil {
return err
}
if _, err = sdk.AccAddressFromBech32(rtmp.ManagerAddress); err != nil {
return err
}

return nil
}
Loading
Loading