Skip to content
This repository has been archived by the owner on Oct 24, 2024. It is now read-only.

[WIP] Add tx to set registration fees #91

Closed
wants to merge 5 commits into from
Closed
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
41 changes: 41 additions & 0 deletions docs/static/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80720,6 +80720,8 @@ definitions:
type: object
mycel.registry.MsgRegisterTopLevelDomainResponse:
type: object
mycel.registry.MsgSetRegistrationFeesResponse:
type: object
mycel.registry.MsgUpdateDnsRecordResponse:
type: object
mycel.registry.MsgUpdateWalletRecordResponse:
Expand Down Expand Up @@ -81337,6 +81339,45 @@ definitions:
description: params holds all the parameters of this module.
type: object
description: QueryParamsResponse is response type for the Query/Params RPC method.
mycel.registry.ReqRegistrationFeeByLength:
type: object
properties:
length:
type: string
format: uint64
isRegistrable:
type: boolean
fee:
type: object
properties:
denom:
type: string
amount:
type: string
description: |-
Coin defines a token with a denomination and an amount.

NOTE: The amount field is an Int which implements the custom method
signatures required by gogoproto.
mycel.registry.ReqRegistrationFeeByName:
type: object
properties:
name:
type: string
isRegistrable:
type: boolean
fee:
type: object
properties:
denom:
type: string
amount:
type: string
description: |-
Coin defines a token with a denomination and an amount.

NOTE: The amount field is an Int which implements the custom method
signatures required by gogoproto.
mycel.registry.SecondLevelDomain:
type: object
properties:
Expand Down
18 changes: 18 additions & 0 deletions proto/mycel/registry/req_registration_fees.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
syntax = "proto3";
package mycel.registry;

import "cosmos/base/v1beta1/coin.proto";

option go_package = "github.com/mycel-domain/mycel/x/registry/types";

message ReqRegistrationFeeByName {
string name = 1;
bool isRegistrable = 2;
cosmos.base.v1beta1.Coin fee = 5;
}

message ReqRegistrationFeeByLength {
uint32 length = 1;
bool isRegistrable = 2;
cosmos.base.v1beta1.Coin fee = 5;
}
16 changes: 16 additions & 0 deletions proto/mycel/registry/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ syntax = "proto3";

package mycel.registry;

import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "mycel/registry/req_registration_fees.proto";

option go_package = "github.com/mycel-domain/mycel/x/registry/types";

// Msg defines the Msg service.
Expand All @@ -10,6 +14,7 @@ service Msg {
rpc UpdateDnsRecord (MsgUpdateDnsRecord ) returns (MsgUpdateDnsRecordResponse );
rpc RegisterDomain (MsgRegisterDomain ) returns (MsgRegisterDomainResponse );
rpc RegisterTopLevelDomain (MsgRegisterTopLevelDomain) returns (MsgRegisterTopLevelDomainResponse);
rpc SetRegistrationFees (MsgSetRegistrationFees ) returns (MsgSetRegistrationFeesResponse );
}
message MsgUpdateWalletRecord {
string creator = 1;
Expand Down Expand Up @@ -47,3 +52,14 @@ message MsgRegisterTopLevelDomain {
}

message MsgRegisterTopLevelDomainResponse {}

message MsgSetRegistrationFees {
string creator = 1;
string domain = 2;
repeated ReqRegistrationFeeByName feesByName = 3 [(gogoproto.nullable) = false];
repeated ReqRegistrationFeeByLength feesByLength = 4 [(gogoproto.nullable) = false];
cosmos.base.v1beta1.Coin defaultFee = 5 [(gogoproto.nullable) = false];
}

message MsgSetRegistrationFeesResponse {}

1 change: 1 addition & 0 deletions x/registry/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func GetTxCmd() *cobra.Command {
cmd.AddCommand(CmdUpdateDnsRecord())
cmd.AddCommand(CmdRegisterDomain())
cmd.AddCommand(CmdRegisterTopLevelDomain())
cmd.AddCommand(CmdSetRegistrationFees())
// this line is used by starport scaffolding # 1

return cmd
Expand Down
56 changes: 56 additions & 0 deletions x/registry/client/cli/tx_set_registration_fees.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package cli

import (
"strconv"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/mycel-domain/mycel/x/registry/types"
"github.com/spf13/cobra"
)

var _ = strconv.Itoa(0)

func CmdSetRegistrationFees() *cobra.Command {
cmd := &cobra.Command{
Use: "set-registration-fees [domain] [fees-by-name] [fees-by-length] [default-fees]",
Short: "Broadcast message set-registration-fees",
Args: cobra.ExactArgs(4),
RunE: func(cmd *cobra.Command, args []string) (err error) {
argDomain := args[0]
// TODO: should parse as maps
//argFeesByName := args[1]
//argFeesByLength := args[2]
argDefaultFee, err := sdk.ParseCoinNormalized(args[3])
if err != nil {
return err
}

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

msg := types.NewMsgSetRegistrationFees(
clientCtx.GetFromAddress().String(),
argDomain,
//argFeesByName,
//argFeesByLength,
//argDefaultFees,
[]types.ReqRegistrationFeeByName{},
[]types.ReqRegistrationFeeByLength{},
argDefaultFee,
)
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

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

import (
"context"
"errors"
"fmt"

errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/mycel-domain/mycel/x/registry/types"
)

func (k msgServer) SetRegistrationFees(goCtx context.Context, msg *types.MsgSetRegistrationFees) (*types.MsgSetRegistrationFeesResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// Get TLD
domain, isFound := k.Keeper.GetTopLevelDomain(ctx, msg.Domain)
if !isFound {
return nil, errorsmod.Wrapf(errors.New(fmt.Sprintf("%s", msg.Domain)), types.ErrDomainNotFound.Error())
}

// Check if domain is editable
if domain.AccessControl[msg.Creator] != types.DomainRole_OWNER {
return nil, errorsmod.Wrapf(errors.New(fmt.Sprintf("%s", msg.Creator)), types.ErrDomainNotEditable.Error())
}

// Check if request is empty

// Set fees
domain.SetRegistrationFees(msg.FeesByName, msg.FeesByLength, msg.DefaultFee)

// Validate fees
err := domain.ValidateRegistrationFees()
if err != nil {
return nil, err
}

// Store fees
k.Keeper.SetTopLevelDomain(ctx, domain)

// Emit event
ctx.EventManager().EmitEvent(
sdk.NewEvent(types.EventTypeSetRegistrationFees,
sdk.NewAttribute(types.AttributeSetRegistrationFeesDomain, msg.Domain),
),
)

return &types.MsgSetRegistrationFeesResponse{}, nil
}
103 changes: 103 additions & 0 deletions x/registry/keeper/msg_server_set_registration_fees_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package keeper_test

import (
"fmt"

"github.com/mycel-domain/mycel/testutil"
"github.com/mycel-domain/mycel/x/registry/types"

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

func (suite *KeeperTestSuite) TestSetRegistrationFees() {
fee1, err := sdk.ParseCoinNormalized("100mycel")
fee2, err := sdk.ParseCoinNormalized("200mycel")
fee3, err := sdk.ParseCoinNormalized("300mycel")
suite.Require().Nil(err)

testCases := []struct {
creator string
domain string
feesByName []types.ReqRegistrationFeeByName
feesByLength []types.ReqRegistrationFeeByLength
defaultFee sdk.Coin
expErr error
fn func()
}{
{
creator: testutil.Alice,
domain: "foo",
feesByName: []types.ReqRegistrationFeeByName{
{Name: "aaa", IsRegistrable: true, Fee: &fee1},
{Name: "bbb", IsRegistrable: true, Fee: &fee2},
{Name: "ccc", IsRegistrable: true, Fee: &fee3},
},
feesByLength: []types.ReqRegistrationFeeByLength{
{Length: 1, IsRegistrable: true, Fee: &fee1},
{Length: 2, IsRegistrable: true, Fee: &fee2},
{Length: 3, IsRegistrable: true, Fee: &fee3},
},
defaultFee: fee1,
expErr: nil,
fn: func() {},
},
}
for i, tc := range testCases {
suite.Run(fmt.Sprintf("Case %d", i), func() {
suite.SetupTest()

// Register domain
domain := &types.MsgRegisterTopLevelDomain{
Creator: testutil.Alice,
Name: "foo",
RegistrationPeriodInYear: 1,
}
_, err := suite.msgServer.RegisterTopLevelDomain(suite.ctx, domain)
suite.Require().Nil(err)
// Run test case function
tc.fn()

// set registration fees
msgSetRegistrationFees := &types.MsgSetRegistrationFees{
Creator: tc.creator,
Domain: tc.domain,
FeesByName: tc.feesByName,
FeesByLength: tc.feesByLength,
DefaultFee: tc.defaultFee,
}
_, err = suite.msgServer.SetRegistrationFees(suite.ctx, msgSetRegistrationFees)

if tc.expErr == nil {
// Evalute events
suite.Require().Nil(err)
res, _ := suite.app.RegistryKeeper.GetTopLevelDomain(suite.ctx, domain.Name)
resFees := res.SubdomainConfig.SubdomainRegistrationFees

// Evaluate stored values
for _, fee := range tc.feesByName {
suite.Require().Equal(resFees.FeeByName[fee.Name].Fee, fee.Fee)
}
for _, fee := range tc.feesByLength {
suite.Require().Equal(resFees.FeeByLength[fee.Length].Fee, fee.Fee)
}
suite.Require().Equal(resFees.DefaultFee, tc.defaultFee)

// Event check
events := sdk.StringifyEvents(suite.ctx.EventManager().ABCIEvents())
eventIndex := len(events) - 1
suite.Require().EqualValues(sdk.StringEvent{
Type: types.EventTypeSetRegistrationFees,
Attributes: []sdk.Attribute{
{Key: types.AttributeSetRegistrationFeesDomain, Value: tc.domain},
},
},
events[eventIndex])

} else {
suite.Require().EqualError(err, tc.expErr.Error())
}

})
}

}
15 changes: 15 additions & 0 deletions x/registry/module_simulation.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ const (
// TODO: Determine the simulation weight value
defaultWeightMsgRegisterTopLevelDomain int = 100

opWeightMsgSetRegistrationFees = "op_weight_msg_set_registration_fees"
// TODO: Determine the simulation weight value
defaultWeightMsgSetRegistrationFees int = 100

// this line is used by starport scaffolding # simapp/module/const
)

Expand Down Expand Up @@ -96,6 +100,17 @@ func (am AppModule) WeightedOperations(simState module.SimulationState) []simtyp
registrysimulation.SimulateMsgRegisterTopLevelDomain(am.accountKeeper, am.bankKeeper, am.keeper),
))

var weightMsgSetRegistrationFees int
simState.AppParams.GetOrGenerate(simState.Cdc, opWeightMsgSetRegistrationFees, &weightMsgSetRegistrationFees, nil,
func(_ *rand.Rand) {
weightMsgSetRegistrationFees = defaultWeightMsgSetRegistrationFees
},
)
operations = append(operations, simulation.NewWeightedOperation(
weightMsgSetRegistrationFees,
registrysimulation.SimulateMsgSetRegistrationFees(am.accountKeeper, am.bankKeeper, am.keeper),
))

// this line is used by starport scaffolding # simapp/module/operation

return operations
Expand Down
29 changes: 29 additions & 0 deletions x/registry/simulation/set_registration_fees.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package simulation

import (
"math/rand"

"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/mycel-domain/mycel/x/registry/keeper"
"github.com/mycel-domain/mycel/x/registry/types"
)

func SimulateMsgSetRegistrationFees(
ak types.AccountKeeper,
bk types.BankKeeper,
k keeper.Keeper,
) simtypes.Operation {
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
simAccount, _ := simtypes.RandomAcc(r, accs)
msg := &types.MsgSetRegistrationFees{
Creator: simAccount.Address.String(),
}

// TODO: Handling the SetRegistrationFees simulation

return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "SetRegistrationFees simulation not implemented"), nil, nil
}
}
Loading