Skip to content

Commit

Permalink
Add update params to marker module (#1991)
Browse files Browse the repository at this point in the history
* add proto def for update prarams

* add msg server impl

* add marker params update event, finish msg server endpoint, refactor params and tests

* add changelong

* add cli

* fix comments in protos

* fix lint

* remove old test cases

* update test

* fix command adding and refactor name

* fix error message

* remove testing of deprecated value
  • Loading branch information
nullpointer0x00 authored May 24, 2024
1 parent 9561f93 commit 6e3cab1
Show file tree
Hide file tree
Showing 23 changed files with 1,303 additions and 271 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* Add `UpdateParams` and `Params` query rpc endpoints to modules.
* `ibcratelimit` add `UpdateParams` endpoint and deprecate `GovUpdateParams` [#1984](https://github.com/provenance-io/provenance/pull/1984).
* `attribute` add `UpdateParams` endpoint and cli [#1987](https://github.com/provenance-io/provenance/pull/1987).
* `marker` add `UpdateParams` endpoint and cli [#1991](https://github.com/provenance-io/provenance/pull/1991).
* Update the exchange `commitment-settlement-fee-calc` cli query to utilize the keyring [#2001](https://github.com/provenance-io/provenance/pull/2001).

### Client Breaking
Expand Down
2 changes: 1 addition & 1 deletion client/docs/statik/statik.go

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions client/docs/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106932,6 +106932,11 @@ definitions:
title: >-
MsgUpdateForcedTransferResponse defines the Msg/UpdateForcedTransfer
response type
provenance.marker.v1.MsgUpdateParamsResponse:
type: object
description: >-
MsgUpdateParamsResponse is a response message for the UpdateParams
endpoint.
provenance.marker.v1.MsgUpdateRequiredAttributesResponse:
type: object
title: >-
Expand Down
2 changes: 1 addition & 1 deletion proto/provenance/ibcratelimit/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ service Msg {
option deprecated = true;
}

// UpdateParams is a governance proposal endpoint for updating the exchange module's params.
// UpdateParams is a governance proposal endpoint for updating the ibcratelimit module's params.
rpc UpdateParams(MsgUpdateParamsRequest) returns (MsgUpdateParamsResponse);
}

Expand Down
7 changes: 7 additions & 0 deletions proto/provenance/marker/v1/marker.proto
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,10 @@ message EventSetNetAssetValue {
string volume = 3;
string source = 4;
}

// EventMarkerParamsUpdated event emitted when marker params are updated.
message EventMarkerParamsUpdated {
string enable_governance = 1;
string unrestricted_denom_regex = 2;
string max_supply = 3;
}
20 changes: 17 additions & 3 deletions proto/provenance/marker/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ service Msg {
rpc WithdrawEscrowProposal(MsgWithdrawEscrowProposalRequest) returns (MsgWithdrawEscrowProposalResponse);
// SetDenomMetadataProposal is a governance proposal to set marker metadata
rpc SetDenomMetadataProposal(MsgSetDenomMetadataProposalRequest) returns (MsgSetDenomMetadataProposalResponse);

// TODO: UpdateParams
// UpdateParams is a governance proposal endpoint for updating the marker module's params.
rpc UpdateParams(MsgUpdateParamsRequest) returns (MsgUpdateParamsResponse);
}

// MsgGrantAllowanceRequest validates permission to create a fee grant based on marker admin access. If
Expand Down Expand Up @@ -462,4 +462,18 @@ message MsgSetDenomMetadataProposalRequest {
}

// MsgSetDenomMetadataProposalResponse defines the Msg/SetDenomMetadataProposal response type
message MsgSetDenomMetadataProposalResponse {}
message MsgSetDenomMetadataProposalResponse {}

// MsgUpdateParamsRequest is a request message for the UpdateParams endpoint.
message MsgUpdateParamsRequest {
option (cosmos.msg.v1.signer) = "authority";

// authority should be the governance module account address.
string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];

// params are the new param values to set.
Params params = 2 [(gogoproto.nullable) = false];
}

// MsgUpdateParamsResponse is a response message for the UpdateParams endpoint.
message MsgUpdateParamsResponse {}
4 changes: 2 additions & 2 deletions x/ibcratelimit/tx.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions x/marker/client/cli/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2552,3 +2552,62 @@ func (s *IntegrationTestSuite) TestUpdateParamsProposal() {
})
}
}

func (s *IntegrationTestSuite) TestUpdateMarkerParamsCmd() {
testCases := []struct {
name string
cmd *cobra.Command
args []string
expectErr string
expectedCode uint32
}{
{
name: "update marker params, should succeed",
cmd: markercli.GetUpdateMarkerParamsCmd(),
args: []string{
"true",
"[a-zA-Z][a-zA-Z0-9\\-\\.]{2,83}",
"1000000",
},
expectedCode: 0,
},
{
name: "update marker params, should fail incorrect governance flag",
cmd: markercli.GetUpdateMarkerParamsCmd(),
args: []string{
"invalid",
"[a-zA-Z][a-zA-Z0-9\\-\\.]{2,83}",
"1000000",
},
expectErr: `invalid enable governance flag: strconv.ParseBool: parsing "invalid": invalid syntax`,
},
{
name: "update marker params, should fail incorrect maxSupply",
cmd: markercli.GetUpdateMarkerParamsCmd(),
args: []string{
"true",
"[a-zA-Z][a-zA-Z0-9\\-\\.]{2,83}",
"invalid",
},
expectErr: `invalid max supply: "invalid"`,
},
}

for _, tc := range testCases {
s.Run(tc.name, func() {
tc.args = append(tc.args,
"--title", fmt.Sprintf("title: %v", tc.name),
"--summary", fmt.Sprintf("summary: %v", tc.name),
"--deposit=1000000stake",
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.testnet.Validators[0].Address.String()),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()),
)
testcli.NewTxExecutor(tc.cmd, tc.args).
WithExpErrMsg(tc.expectErr).
WithExpCode(tc.expectedCode).
Execute(s.T(), s.testnet)
})
}
}
48 changes: 48 additions & 0 deletions x/marker/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/spf13/pflag"

cerrs "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
"cosmossdk.io/x/feegrant"

"github.com/cosmos/cosmos-sdk/client"
Expand Down Expand Up @@ -95,6 +96,7 @@ func NewTxCmd() *cobra.Command {
GetCmdRemoveAdministratorProposal(),
GetCmdChangeStatusProposal(),
GetCmdWithdrawEscrowProposal(),
GetUpdateMarkerParamsCmd(),
)
return txCmd
}
Expand Down Expand Up @@ -1551,3 +1553,49 @@ func generateOrBroadcastOptGovProp(clientCtx client.Context, flagSet *pflag.Flag
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, flagSet, msg)
}

// GetUpdateMarkerParamsCmd creates a command to update the marker module's params via governance proposal.
func GetUpdateMarkerParamsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "update-marker-params <enable-governance> <unrestricted-denom-regex> <max-supply>",
Short: "Update the marker module's params via governance proposal",
Long: "Submit an update marker params via governance proposal along with an initial deposit.",
Args: cobra.ExactArgs(3),
Example: fmt.Sprintf(`%[1]s tx marker update-marker-params true "[a-zA-Z][a-zA-Z0-9\\-\\.]{2,83}" 1000000000000 --deposit 50000nhash`, version.AppName),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

flagSet := cmd.Flags()
authority := provcli.GetAuthority(flagSet)

enableGovernance, err := strconv.ParseBool(args[0])
if err != nil {
return fmt.Errorf("invalid enable governance flag: %w", err)
}

unrestrictedDenomRegex := args[1]

maxSupply, ok := sdkmath.NewIntFromString(args[2])
if !ok {
return fmt.Errorf("invalid max supply: %q", args[2])
}

msg := types.NewMsgUpdateParamsRequest(
enableGovernance,
unrestrictedDenomRegex,
maxSupply,
authority,
)
return provcli.GenerateOrBroadcastTxCLIAsGovProp(clientCtx, flagSet, msg)
},
}

govcli.AddGovPropFlagsToCmd(cmd)
provcli.AddAuthorityFlagToCmd(cmd)
flags.AddTxFlagsToCmd(cmd)

return cmd
}
14 changes: 14 additions & 0 deletions x/marker/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper
import (
"errors"
"fmt"
"strings"

"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
Expand Down Expand Up @@ -203,6 +204,19 @@ func (k Keeper) GetAuthority() string {
return k.authority
}

// IsAuthority returns true if the provided address bech32 string is the authority address.
func (k Keeper) IsAuthority(addr string) bool {
return strings.EqualFold(k.authority, addr)
}

// ValidateAuthority returns an error if the provided address is not the authority.
func (k Keeper) ValidateAuthority(addr string) error {
if !k.IsAuthority(addr) {
return govtypes.ErrInvalidSigner.Wrapf("expected %q got %q", k.GetAuthority(), addr)
}
return nil
}

// IsSendDeny returns true if sender address is denied for marker
func (k Keeper) IsSendDeny(ctx sdk.Context, markerAddr, senderAddr sdk.AccAddress) bool {
store := ctx.KVStore(k.storeKey)
Expand Down
2 changes: 1 addition & 1 deletion x/marker/keeper/marker.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ func (k Keeper) IncreaseSupply(ctx sdk.Context, marker types.MarkerAccountI, coi

inCirculation := sdk.NewCoin(marker.GetDenom(), k.bankKeeper.GetSupply(ctx, marker.GetDenom()).Amount)
total := inCirculation.Add(coin)
maxAllowed := sdk.NewCoin(marker.GetDenom(), k.GetParams(ctx).MaxSupply)
maxAllowed := sdk.NewCoin(marker.GetDenom(), k.GetMaxSupply(ctx))
if total.Amount.GT(maxAllowed.Amount) {
return fmt.Errorf(
"requested supply %s exceeds maximum allowed value %s", total.Amount.String(), maxAllowed.Amount.String())
Expand Down
16 changes: 16 additions & 0 deletions x/marker/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -820,3 +820,19 @@ func (k msgServer) SetDenomMetadataProposal(goCtx context.Context, msg *types.Ms

return &types.MsgSetDenomMetadataProposalResponse{}, nil
}

// UpdateParams is a governance proposal endpoint for updating the marker module's params.
func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParamsRequest) (*types.MsgUpdateParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

if err := k.ValidateAuthority(msg.Authority); err != nil {
return nil, err
}

k.SetParams(ctx, msg.Params)
if err := ctx.EventManager().EmitTypedEvent(types.NewEventMarkerParamsUpdated(msg.Params.EnableGovernance, msg.Params.GetUnrestrictedDenomRegex(), msg.Params.MaxSupply)); err != nil {
return nil, err
}

return &types.MsgUpdateParamsResponse{}, nil
}
48 changes: 48 additions & 0 deletions x/marker/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1845,3 +1845,51 @@ func (s *MsgServerTestSuite) TestSetDenomMetadataProposal() {
})
}
}

func (s *MsgServerTestSuite) TestMsgUpdateParamsRequest() {
authority := s.app.MarkerKeeper.GetAuthority()

testCases := []struct {
name string
msg *types.MsgUpdateParamsRequest
expErr string
}{
{
name: "successfully update params",
msg: &types.MsgUpdateParamsRequest{
Authority: authority,
Params: types.NewParams(
true,
"[a-zA-Z][a-zA-Z0-9\\-\\.]{2,83}",
sdkmath.NewInt(1000000000000),
),
},
},
{
name: "fail to update params, invalid authority",
msg: &types.MsgUpdateParamsRequest{
Authority: "invalidAuthority",
Params: types.NewParams(
true,
"[a-zA-Z][a-zA-Z0-9\\-\\.]{2,83}",
sdkmath.NewInt(1000000000000),
),
},
expErr: `expected "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn" got "invalidAuthority": expected gov account as only signer for proposal message`,
},
}

for _, tc := range testCases {
s.Run(tc.name, func() {
ctx := sdk.WrapSDKContext(s.ctx)
res, err := s.msgServer.UpdateParams(ctx, tc.msg)
if len(tc.expErr) > 0 {
s.Require().EqualError(err, tc.expErr, "UpdateParams error")
s.Require().Nil(res, "UpdateParams response")
} else {
s.Require().NoError(err, "UpdateParams error")
s.Require().NotNil(res, "UpdateParams response")
}
})
}
}
5 changes: 0 additions & 5 deletions x/marker/keeper/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
store.Set(types.MarkerParamStoreKey, bz)
}

// Deprecated: GetMaxTotalSupply is kept for backwards compatibility.
func (k Keeper) GetMaxTotalSupply(ctx sdk.Context) (max uint64) {
return k.GetParams(ctx).MaxTotalSupply
}

// GetMaxSupply returns the current parameter value for the max allowed supply.
func (k Keeper) GetMaxSupply(ctx sdk.Context) (max sdkmath.Int) {
return k.GetParams(ctx).MaxSupply
Expand Down
5 changes: 1 addition & 4 deletions x/marker/keeper/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,16 @@ func TestParamTestSuite(t *testing.T) {

func (s *ParamTestSuite) TestGetSetParams() {
defaultParams := s.app.MarkerKeeper.GetParams(s.ctx)
s.Require().Equal(types.DefaultMaxTotalSupply, defaultParams.MaxTotalSupply, "Default MaxTotalSupply should match")
s.Require().Equal(uint64(0), defaultParams.MaxTotalSupply, "MaxTotalSupply is deprecated and should not be set")
s.Require().Equal(types.DefaultEnableGovernance, defaultParams.EnableGovernance, "Default EnableGovernance should match")
s.Require().Equal(types.DefaultUnrestrictedDenomRegex, defaultParams.UnrestrictedDenomRegex, "Default UnrestrictedDenomRegex should match")
s.Require().Equal(types.StringToBigInt(types.DefaultMaxSupply), defaultParams.MaxSupply, "Default MaxSupply should match")

newMaxTotalSupply := uint64(2000000)
newEnableGovernance := false
newUnrestrictedDenomRegex := "xyz.*"
newMaxSupply := "3000000"

newParams := types.Params{
MaxTotalSupply: newMaxTotalSupply,
EnableGovernance: newEnableGovernance,
UnrestrictedDenomRegex: newUnrestrictedDenomRegex,
MaxSupply: types.StringToBigInt(newMaxSupply),
Expand All @@ -53,7 +51,6 @@ func (s *ParamTestSuite) TestGetSetParams() {
s.app.MarkerKeeper.SetParams(s.ctx, newParams)

updatedParams := s.app.MarkerKeeper.GetParams(s.ctx)
s.Require().Equal(newMaxTotalSupply, updatedParams.MaxTotalSupply, "Updated MaxTotalSupply should match")
s.Require().Equal(newEnableGovernance, updatedParams.EnableGovernance, "Updated EnableGovernance should match")
s.Require().Equal(newUnrestrictedDenomRegex, updatedParams.UnrestrictedDenomRegex, "Updated UnrestrictedDenomRegex should match")
s.Require().Equal(types.StringToBigInt(newMaxSupply), updatedParams.MaxSupply, "Updated MaxSupply should match")
Expand Down
14 changes: 14 additions & 0 deletions x/marker/spec/07_events.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The marker module emits the following events:
- [Transfer](#transfer)
- [Set Denom Metadata](#set-denom-metadata)
- [Set Net Asset Value](#set-net-asset-value)
- [Marker Params Updated](#marker-params-updated)



Expand Down Expand Up @@ -216,3 +217,16 @@ Type: `provenance.marker.v1.EventSetNetAssetValue`
| Price | \{token amount the marker is valued at for volume\} |
| Volume | \{total volume/shares associated with price\} |
| Source | \{source address of caller\} |

---
## Marker Params Updated

Fires when an `EventMarkerParamsUpdated` event occurs, indicating that the marker module's parameters have been updated via a governance proposal.

Type: `provenance.marker.v1.EventMarkerParamsUpdated`

| Attribute Key | Attribute Value |
|-------------------------|-----------------------------------------------------|
| EnableGovernance | \{value for if governance control is enabled\} |
| UnrestrictedDenomRegex | \{regex for unrestricted denom validation\} |
| MaxSupply | \{value for the max allowed supply\} |
Loading

0 comments on commit 6e3cab1

Please sign in to comment.