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: support message based proposals #1372

Merged
merged 10 commits into from
May 9, 2024
33 changes: 30 additions & 3 deletions docs/core/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,8 @@
- [Query](#lbm.fswap.v1.Query)

- [lbm/fswap/v1/tx.proto](#lbm/fswap/v1/tx.proto)
- [MsgMakeSwapProposal](#lbm.fswap.v1.MsgMakeSwapProposal)
- [MsgMakeSwapProposalResponse](#lbm.fswap.v1.MsgMakeSwapProposalResponse)
- [MsgSwap](#lbm.fswap.v1.MsgSwap)
- [MsgSwapAll](#lbm.fswap.v1.MsgSwapAll)
- [MsgSwapAllResponse](#lbm.fswap.v1.MsgSwapAllResponse)
Expand Down Expand Up @@ -14163,13 +14165,11 @@ Msg defines the foundation Msg service.
<a name="lbm.fswap.v1.MakeSwapProposal"></a>

### MakeSwapProposal
From cosmos-sdk 0.46.0 they deprecated this way, but currently finschia-sdk based on 0.45.10



| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `title` | [string](#string) | | |
| `description` | [string](#string) | | |
| `swap` | [Swap](#lbm.fswap.v1.Swap) | | |
| `to_denom_metadata` | [cosmos.bank.v1beta1.Metadata](#cosmos.bank.v1beta1.Metadata) | | |

Expand Down Expand Up @@ -14398,6 +14398,32 @@ GenesisState defines the fswap module's genesis state.



<a name="lbm.fswap.v1.MsgMakeSwapProposal"></a>

### MsgMakeSwapProposal



| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `authority` | [string](#string) | | authority is the address of the privileged account. |
| `proposal` | [MakeSwapProposal](#lbm.fswap.v1.MakeSwapProposal) | | |






<a name="lbm.fswap.v1.MsgMakeSwapProposalResponse"></a>

### MsgMakeSwapProposalResponse







<a name="lbm.fswap.v1.MsgSwap"></a>

### MsgSwap
Expand Down Expand Up @@ -14467,6 +14493,7 @@ GenesisState defines the fswap module's genesis state.
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
| `Swap` | [MsgSwap](#lbm.fswap.v1.MsgSwap) | [MsgSwapResponse](#lbm.fswap.v1.MsgSwapResponse) | | |
| `SwapAll` | [MsgSwapAll](#lbm.fswap.v1.MsgSwapAll) | [MsgSwapAllResponse](#lbm.fswap.v1.MsgSwapAllResponse) | | |
| `MakeSwapProposal` | [MsgMakeSwapProposal](#lbm.fswap.v1.MsgMakeSwapProposal) | [MsgMakeSwapProposalResponse](#lbm.fswap.v1.MsgMakeSwapProposalResponse) | | |

<!-- end services -->

Expand Down
7 changes: 2 additions & 5 deletions proto/lbm/fswap/v1/fswap.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,11 @@ message SwapStats {
int32 swap_count = 1;
}

// From cosmos-sdk 0.46.0 they deprecated this way, but currently finschia-sdk based on 0.45.10
message MakeSwapProposal {
option (gogoproto.goproto_stringer) = false;

string title = 1;
string description = 2;
Swap swap = 3 [(gogoproto.nullable) = false];
cosmos.bank.v1beta1.Metadata to_denom_metadata = 4
Swap swap = 1 [(gogoproto.nullable) = false];
cosmos.bank.v1beta1.Metadata to_denom_metadata = 2
[(gogoproto.moretags) = "yaml:\"denom_metadata\"", (gogoproto.nullable) = false];
}

Expand Down
10 changes: 10 additions & 0 deletions proto/lbm/fswap/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ option go_package = "github.com/Finschia/finschia-sdk/x/fswap/types";

import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "lbm/fswap/v1/fswap.proto";

service Msg {
rpc Swap(MsgSwap) returns (MsgSwapResponse);
rpc SwapAll(MsgSwapAll) returns (MsgSwapAllResponse);
rpc MakeSwapProposal(MsgMakeSwapProposal) returns (MsgMakeSwapProposalResponse);
0Tech marked this conversation as resolved.
Show resolved Hide resolved
}

message MsgSwap {
Expand All @@ -30,3 +32,11 @@ message MsgSwapAll {
}

message MsgSwapAllResponse {}

message MsgMakeSwapProposal {
// authority is the address of the privileged account.
string authority = 1;
MakeSwapProposal proposal = 2;
}

message MsgMakeSwapProposalResponse {}
7 changes: 2 additions & 5 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ import (
foundationkeeper "github.com/Finschia/finschia-sdk/x/foundation/keeper"
foundationmodule "github.com/Finschia/finschia-sdk/x/foundation/module"
"github.com/Finschia/finschia-sdk/x/fswap"
fswapclient "github.com/Finschia/finschia-sdk/x/fswap/client"
fswapkeeper "github.com/Finschia/finschia-sdk/x/fswap/keeper"
fswaptypes "github.com/Finschia/finschia-sdk/x/fswap/types"
"github.com/Finschia/finschia-sdk/x/genutil"
Expand Down Expand Up @@ -134,7 +133,6 @@ var (
upgradeclient.ProposalHandler,
upgradeclient.CancelProposalHandler,
foundationclient.ProposalHandler,
fswapclient.ProposalHandler,
),
params.AppModuleBasic{},
crisis.AppModuleBasic{},
Expand Down Expand Up @@ -344,16 +342,15 @@ func NewSimApp(
app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.BaseApp.MsgServiceRouter())

fswapConfig := fswaptypes.DefaultConfig()
app.FswapKeeper = fswapkeeper.NewKeeper(appCodec, keys[fswaptypes.StoreKey], fswapConfig, app.BankKeeper)
app.FswapKeeper = fswapkeeper.NewKeeper(appCodec, keys[fswaptypes.StoreKey], fswapConfig, fswaptypes.DefaultAuthority().String(), app.BankKeeper)

// register the proposal types
govRouter := govtypes.NewRouter()
govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
AddRoute(foundation.RouterKey, foundationkeeper.NewFoundationProposalsHandler(app.FoundationKeeper)).
AddRoute(fswaptypes.RouterKey, fswap.NewSwapHandler(app.FswapKeeper))
AddRoute(foundation.RouterKey, foundationkeeper.NewFoundationProposalsHandler(app.FoundationKeeper))

govKeeper := govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
Expand Down
73 changes: 34 additions & 39 deletions x/fswap/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
bank "github.com/Finschia/finschia-sdk/x/bank/types"
"github.com/Finschia/finschia-sdk/x/fswap/types"
govcli "github.com/Finschia/finschia-sdk/x/gov/client/cli"
gov "github.com/Finschia/finschia-sdk/x/gov/types"
)

const (
Expand All @@ -36,6 +34,7 @@ func GetTxCmd() *cobra.Command {
cmd.AddCommand(
CmdTxMsgSwap(),
CmdTxMsgSwapAll(),
CmdMsgMakeSwapProposal(),
)

return cmd
Expand Down Expand Up @@ -115,21 +114,21 @@ func CmdTxMsgSwapAll() *cobra.Command {
return cmd
}

// NewCmdMakeSwapProposal implements a command handler for submitting a swap init proposal transaction.
func NewCmdMakeSwapProposal() *cobra.Command {
// CmdMsgMakeSwapProposal implements a command handler for submitting a swap init proposal transaction.
0Tech marked this conversation as resolved.
Show resolved Hide resolved
func CmdMsgMakeSwapProposal() *cobra.Command {
cmd := &cobra.Command{
Use: "make-swap [messages-json]",
Args: cobra.ExactArgs(1),
Short: "todo",
Use: "make-swap-proposal [authority] [metadata-json]",
Args: cobra.ExactArgs(2),
Short: "Make swap proposal",
Long: `
Parameters:
messages-json: messages in json format that will be executed if the proposal is accepted.
metadata-json: messages in json format that will be executed if the proposal is accepted.

Example of the content of messages-json:
Example of the content of metadata-json:

{
"metadata": {
"description": "the base coin of Finschia mainnet",
"description": "example of to-denom is finschia cony",
"denom_units": [
{
"denom": "cony",
Expand All @@ -152,19 +151,11 @@ Example of the content of messages-json:
}
`,
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

from := clientCtx.GetFromAddress()

title, err := cmd.Flags().GetString(govcli.FlagTitle)
if err != nil {
if err := validateGenerateOnly(cmd); err != nil {
return err
}

description, err := cmd.Flags().GetString(govcli.FlagDescription)
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
Expand All @@ -178,10 +169,12 @@ Example of the content of messages-json:
if err != nil {
return err
}

amountCapStr, err := cmd.Flags().GetString(FlagAmountCapForToDenom)
if err != nil {
return err
}

amountCap, ok := sdk.NewIntFromString(amountCapStr)
if !ok {
return sdkerrors.ErrInvalidRequest.Wrapf("failed to parse %s %s", FlagAmountCapForToDenom, amountCap.String())
Expand All @@ -202,42 +195,44 @@ Example of the content of messages-json:
SwapRate: swapRateDec,
}

toDenomMetadata, err := parseToDenomMetadata(args[0])
if err != nil {
return err
}

content := types.NewMakeSwapProposal(title, description, swap, toDenomMetadata)

depositStr, err := cmd.Flags().GetString(govcli.FlagDeposit)
if err != nil {
return err
}
deposit, err := sdk.ParseCoinsNormalized(depositStr)
authority := args[0]
toDenomMetadata, err := parseToDenomMetadata(args[1])
if err != nil {
return err
}

msg, err := gov.NewMsgSubmitProposal(content, deposit, from)
if err != nil {
return err
msg := types.MsgMakeSwapProposal{
Authority: authority,
Proposal: &types.MakeSwapProposalTmp{
Swap: swap,
ToDenomMetadata: toDenomMetadata,
},
}

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

cmd.Flags().String(govcli.FlagTitle, "", "title of proposal")
cmd.Flags().String(govcli.FlagDescription, "", "description of proposal")
cmd.Flags().String(govcli.FlagDeposit, "", "deposit of proposal")
cmd.Flags().String(FlagFromDenom, "", "cony")
cmd.Flags().String(FlagToDenom, "", "PDT")
cmd.Flags().String(FlagAmountCapForToDenom, "0", "tbd")
cmd.Flags().String(FlagSwapRate, "0", "tbd")
0Tech marked this conversation as resolved.
Show resolved Hide resolved

flags.AddTxFlagsToCmd(cmd)
return cmd
}

func validateGenerateOnly(cmd *cobra.Command) error {
generateOnly, err := cmd.Flags().GetBool(flags.FlagGenerateOnly)
if err != nil {
return err
}
if !generateOnly {
return fmt.Errorf("you must use it with the flag --%s", flags.FlagGenerateOnly)
}
return nil
}

func parseToDenomMetadata(jsonDenomMetadata string) (bank.Metadata, error) {
type toDenomMeta struct {
Metadata bank.Metadata `json:"metadata"`
Expand Down
8 changes: 0 additions & 8 deletions x/fswap/client/proposal_handler.go

This file was deleted.

17 changes: 0 additions & 17 deletions x/fswap/codec/codec.go
Original file line number Diff line number Diff line change
@@ -1,18 +1 @@
package codec

import (
"github.com/Finschia/finschia-sdk/codec"
cryptocodec "github.com/Finschia/finschia-sdk/crypto/codec"
sdk "github.com/Finschia/finschia-sdk/types"
)

var (
Amino = codec.NewLegacyAmino()
ModuleCdc = codec.NewAminoCodec(Amino)
)

func init() {
cryptocodec.RegisterCrypto(Amino)
codec.RegisterEvidences(Amino)
sdk.RegisterLegacyAminoCodec(Amino)
}
27 changes: 0 additions & 27 deletions x/fswap/handler.go

This file was deleted.

30 changes: 24 additions & 6 deletions x/fswap/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,33 @@
"github.com/Finschia/finschia-sdk/store/prefix"
storetypes "github.com/Finschia/finschia-sdk/store/types"
sdk "github.com/Finschia/finschia-sdk/types"
sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
"github.com/Finschia/finschia-sdk/x/fswap/types"
)

type Keeper struct {
cdc codec.BinaryCodec
storeKey storetypes.StoreKey

config types.Config

cdc codec.BinaryCodec
storeKey storetypes.StoreKey
config types.Config
authority string
BankKeeper
}

func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey, config types.Config, bk BankKeeper) Keeper {
func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey, config types.Config, authority string, bk BankKeeper) Keeper {
if _, err := sdk.AccAddressFromBech32(authority); err != nil {
panic("authority is not a valid acc address")

Check warning on line 26 in x/fswap/keeper/keeper.go

View check run for this annotation

Codecov / codecov/patch

x/fswap/keeper/keeper.go#L26

Added line #L26 was not covered by tests
}

// authority is x/foundation module account for now.
if authority != types.DefaultAuthority().String() {
0Tech marked this conversation as resolved.
Show resolved Hide resolved
panic("x/foundation authority must be the module account")

Check warning on line 31 in x/fswap/keeper/keeper.go

View check run for this annotation

Codecov / codecov/patch

x/fswap/keeper/keeper.go#L31

Added line #L31 was not covered by tests
}

return Keeper{
cdc,
storeKey,
config,
authority,
bk,
}
}
Expand Down Expand Up @@ -201,3 +211,11 @@
store.Set(swapStatsKey, bz)
return nil
}

func (k Keeper) validateAuthority(authority string) error {
if authority != k.authority {
return sdkerrors.ErrUnauthorized.Wrapf("invalid authority; expected %s, got %s", k.authority, authority)

Check warning on line 217 in x/fswap/keeper/keeper.go

View check run for this annotation

Codecov / codecov/patch

x/fswap/keeper/keeper.go#L215-L217

Added lines #L215 - L217 were not covered by tests
}

return nil

Check warning on line 220 in x/fswap/keeper/keeper.go

View check run for this annotation

Codecov / codecov/patch

x/fswap/keeper/keeper.go#L220

Added line #L220 was not covered by tests
}
Loading
Loading