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: register denom metadata #27

Merged
merged 2 commits into from
Mar 9, 2024
Merged
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
5 changes: 4 additions & 1 deletion proto/opinit/opchild/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,11 @@ message MsgFinalizeTokenDeposit {
// height is the height of l1 which is including the deposit message
uint64 height = 6;

// base_denom is the l1 denomination of the sent coin.
string base_denom = 7;

/// data is a extra bytes for hooks.
bytes data = 7 [(gogoproto.nullable) = true, (amino.dont_omitempty) = true];
bytes data = 8 [(gogoproto.nullable) = true, (amino.dont_omitempty) = true];
}

// MsgFinalizeTokenDepositResponse returns deposit result data
Expand Down
26 changes: 20 additions & 6 deletions x/opchild/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func GetTxCmd(ac address.Codec) *cobra.Command {
// NewDepositCmd returns a CLI command handler for the transaction sending a deposit to an user account.
func NewDepositCmd(ac address.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "deposit [sequence] [from_l1] [to_l2] [amount]",
Args: cobra.ExactArgs(4),
Use: "deposit [sequence] [from_l1] [to_l2] [amount] [base_denom]",
Args: cobra.ExactArgs(5),
Short: "send a deposit to an user account",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
Expand Down Expand Up @@ -72,12 +72,18 @@ func NewDepositCmd(ac address.Codec) *cobra.Command {
return err
}

baseDenom := args[4]

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

txf, msg, err := newBuildDepositMsg(clientCtx, ac, txf, cmd.Flags(), sequence, from, to, amount, []byte(hookMsg))
txf, msg, err := newBuildDepositMsg(
clientCtx, ac, txf, cmd.Flags(),
sequence, from, to, amount, baseDenom,
[]byte(hookMsg),
)
if err != nil {
return err
}
Expand Down Expand Up @@ -217,8 +223,16 @@ func newBuildWithdrawMsg(clientCtx client.Context, ac address.Codec, txf tx.Fact
return txf, msg, nil
}

func newBuildDepositMsg(clientCtx client.Context, ac address.Codec, txf tx.Factory, fs *flag.FlagSet,
sequence uint64, from, to sdk.AccAddress, amount sdk.Coin, hookMsg []byte,
func newBuildDepositMsg(
clientCtx client.Context,
ac address.Codec,
txf tx.Factory,
fs *flag.FlagSet,
sequence uint64,
from, to sdk.AccAddress,
amount sdk.Coin,
baseDenom string,
hookMsg []byte,
) (tx.Factory, *types.MsgFinalizeTokenDeposit, error) {
sender := clientCtx.GetFromAddress()
senderAddr, err := ac.BytesToString(sender)
Expand All @@ -236,7 +250,7 @@ func newBuildDepositMsg(clientCtx client.Context, ac address.Codec, txf tx.Facto
return txf, nil, err
}

msg := types.NewMsgFinalizeTokenDeposit(senderAddr, fromAddr, toAddr, amount, sequence, hookMsg)
msg := types.NewMsgFinalizeTokenDeposit(senderAddr, fromAddr, toAddr, amount, sequence, baseDenom, hookMsg)
if err := msg.Validate(ac); err != nil {
return txf, nil, err
}
Expand Down
22 changes: 22 additions & 0 deletions x/opchild/client/cli/tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ func (s *CLITestSuite) TestNewDepositCmd() {
"_invalid_acc_",
s.addrs[0].String(),
"100umin",
"test_token",
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
Expand All @@ -186,6 +187,7 @@ func (s *CLITestSuite) TestNewDepositCmd() {
"_invalid_acc_",
"1",
"100umin",
"test_token",
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
Expand All @@ -200,6 +202,7 @@ func (s *CLITestSuite) TestNewDepositCmd() {
s.addrs[0].String(),
s.addrs[1].String(),
"100umin",
"test_token",
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
Expand All @@ -214,6 +217,22 @@ func (s *CLITestSuite) TestNewDepositCmd() {
s.addrs[0].String(),
s.addrs[1].String(),
"0umin",
"test_token",
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(10))).String()),
},
true, 0, &sdk.TxResponse{},
},
{
"invalid transaction (invalid base_denom)",
[]string{
"1",
s.addrs[0].String(),
s.addrs[1].String(),
"100umin",
"1test_token",
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
Expand All @@ -228,6 +247,7 @@ func (s *CLITestSuite) TestNewDepositCmd() {
s.addrs[0].String(),
s.addrs[1].String(),
"100umin",
"test_token",
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
Expand All @@ -242,6 +262,7 @@ func (s *CLITestSuite) TestNewDepositCmd() {
s.addrs[0].String(),
s.addrs[1].String(),
"100umin",
"test_token",
fmt.Sprintf("--%s=%s", cli.FlagHookMsg, hookMsgString),
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
Expand All @@ -257,6 +278,7 @@ func (s *CLITestSuite) TestNewDepositCmd() {
s.addrs[0].String(),
s.addrs[1].String(),
"100umin",
"test_token",
fmt.Sprintf("--%s=%s", cli.FlagHookMsg, "__invalid_hook_msg__"),
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.addrs[0]),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
Expand Down
20 changes: 20 additions & 0 deletions x/opchild/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
cosmostypes "github.com/cosmos/cosmos-sdk/x/staking/types"

"github.com/initia-labs/OPinit/x/opchild/types"
Expand Down Expand Up @@ -113,3 +114,22 @@ func (k Keeper) Logger(ctx context.Context) log.Logger {
func (keeper Keeper) Router() *baseapp.MsgServiceRouter {
return keeper.router
}

// setDenomMetadata sets an OPinit token's denomination metadata
func (k Keeper) setDenomMetadata(ctx context.Context, baseDenom, denom string) {
metadata := banktypes.Metadata{
Base: denom,
Display: baseDenom,
Symbol: baseDenom,
Name: fmt.Sprintf("%s OPinit token", baseDenom),
Description: fmt.Sprintf("OPinit token of %s", baseDenom),
DenomUnits: []*banktypes.DenomUnit{
{
Denom: baseDenom,
Exponent: 0,
},
},
}

k.bankKeeper.SetDenomMetaData(ctx, metadata)
}
5 changes: 5 additions & 0 deletions x/opchild/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,11 @@ func (ms MsgServer) FinalizeTokenDeposit(ctx context.Context, req *types.MsgFina
return nil, err
}

// register denom metadata
if ok := ms.bankKeeper.HasDenomMetaData(ctx, coin.Denom); !ok {
ms.setDenomMetadata(ctx, req.BaseDenom, coin.Denom)
}

event := sdk.NewEvent(
types.EventTypeFinalizeTokenDeposit,
sdk.NewAttribute(types.AttributeKeyL1Sequence, strconv.FormatUint(req.Sequence, 10)),
Expand Down
8 changes: 4 additions & 4 deletions x/opchild/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,15 @@ func Test_MsgServer_Deposit_NoHook(t *testing.T) {
denom := "l2/" + hex.EncodeToString(bz[:])

// unauthorized deposit
msg := types.NewMsgFinalizeTokenDeposit(addrsStr[1], addrsStr[1], addrsStr[1], sdk.NewCoin(denom, math.NewInt(100)), 1, nil)
msg := types.NewMsgFinalizeTokenDeposit(addrsStr[1], addrsStr[1], addrsStr[1], sdk.NewCoin(denom, math.NewInt(100)), 1, "test_token", nil)
_, err := ms.FinalizeTokenDeposit(ctx, msg)
require.Error(t, err)

beforeBalance := input.BankKeeper.GetBalance(ctx, addrs[1], denom)
require.Equal(t, math.ZeroInt(), beforeBalance.Amount)

// valid deposit
msg = types.NewMsgFinalizeTokenDeposit(addrsStr[0], addrsStr[1], addrsStr[1], sdk.NewCoin(denom, math.NewInt(100)), 1, nil)
msg = types.NewMsgFinalizeTokenDeposit(addrsStr[0], addrsStr[1], addrsStr[1], sdk.NewCoin(denom, math.NewInt(100)), 1, "test_token", nil)
_, err = ms.FinalizeTokenDeposit(ctx, msg)
require.NoError(t, err)

Expand All @@ -283,7 +283,7 @@ func Test_MsgServer_Deposit_HookSuccess(t *testing.T) {
input.BridgeHook.err = nil

// valid deposit
msg := types.NewMsgFinalizeTokenDeposit(addrsStr[0], addrsStr[1], addrsStr[1], sdk.NewCoin(denom, math.NewInt(100)), 1, hookMsgBytes)
msg := types.NewMsgFinalizeTokenDeposit(addrsStr[0], addrsStr[1], addrsStr[1], sdk.NewCoin(denom, math.NewInt(100)), 1, "test_token", hookMsgBytes)
_, err = ms.FinalizeTokenDeposit(ctx, msg)
require.NoError(t, err)
require.Equal(t, hookMsgBytes, input.BridgeHook.msgBytes)
Expand All @@ -309,7 +309,7 @@ func Test_MsgServer_Deposit_HookFail(t *testing.T) {
input.BridgeHook.err = errors.New("should be failed")

// valid deposit
msg := types.NewMsgFinalizeTokenDeposit(addrsStr[0], addrsStr[1], addrsStr[1], sdk.NewCoin(denom, math.NewInt(100)), 1, []byte("invalid_message"))
msg := types.NewMsgFinalizeTokenDeposit(addrsStr[0], addrsStr[1], addrsStr[1], sdk.NewCoin(denom, math.NewInt(100)), 1, "test_token", []byte("invalid_message"))
_, err := ms.FinalizeTokenDeposit(ctx, msg)
require.NoError(t, err)
require.Empty(t, input.BridgeHook.msgBytes)
Expand Down
4 changes: 4 additions & 0 deletions x/opchild/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"cosmossdk.io/core/address"
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)

// AccountKeeper defines the expected account keeper (noalias)
Expand Down Expand Up @@ -41,6 +42,9 @@ type BankKeeper interface {

MintCoins(ctx context.Context, moduleName string, amounts sdk.Coins) error
BurnCoins(ctx context.Context, moduleName string, amounts sdk.Coins) error

HasDenomMetaData(ctx context.Context, denom string) bool
SetDenomMetaData(ctx context.Context, denomMetaData banktypes.Metadata)
}

// ValidatorSet expected properties for the set of all validators (noalias)
Expand Down
18 changes: 12 additions & 6 deletions x/opchild/types/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,17 @@ func NewMsgFinalizeTokenDeposit(
sender, from, to string,
amount sdk.Coin,
sequence uint64,
baseDenom string,
data []byte,
) *MsgFinalizeTokenDeposit {
return &MsgFinalizeTokenDeposit{
Sender: sender,
From: from,
To: to,
Amount: amount,
Sequence: sequence,
Data: data,
Sender: sender,
From: from,
To: to,
Amount: amount,
Sequence: sequence,
BaseDenom: baseDenom,
Data: data,
}
}

Expand All @@ -228,6 +230,10 @@ func (msg MsgFinalizeTokenDeposit) Validate(ac address.Codec) error {
return ErrInvalidAmount
}

if err := sdk.ValidateDenom(msg.BaseDenom); err != nil {
return err
}

if msg.Sequence == 0 {
return ErrInvalidSequence
}
Expand Down
Loading
Loading