diff --git a/CHANGELOG.md b/CHANGELOG.md index 592a170a6b..1666b59a6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - [cronos#110](https://github.com/crypto-org-chain/cronos/pull/110) embed swagger doc ui - [cronos#113](https://github.com/crypto-org-chain/cronos/pull/113) export token mapping state to genesis +- [cronos#128](https://github.com/crypto-org-chain/cronos/pull/128) add native message to update token mapping *September 22, 2021* ## v0.5.4 diff --git a/app/test_helpers.go b/app/test_helpers.go index 6b67a62410..b47b0fd11b 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -30,6 +30,7 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + cronostypes "github.com/crypto-org-chain/cronos/x/cronos/types" ) const ( @@ -67,8 +68,14 @@ func setup(withGenesis bool, invCheckPeriod uint) (*App, GenesisState) { } // Setup initializes a new App. A Nop logger is set in App. -func Setup(isCheckTx bool) *App { +func Setup(isCheckTx bool, cronosAdmin string) *App { app, genesisState := setup(!isCheckTx, 5) + + // set cronos_admin for test + cronosGen := cronostypes.DefaultGenesis() + cronosGen.Params.CronosAdmin = cronosAdmin + genesisState["cronos"] = app.cdc.MustMarshalJSON(cronosGen) + if !isCheckTx { // init chain must be called to stop deliverState from being nil stateBytes, err := json.MarshalIndent(genesisState, "", " ") diff --git a/docs/api/proto-docs.md b/docs/api/proto-docs.md index 6c92d8e72c..bc60a1f28a 100644 --- a/docs/api/proto-docs.md +++ b/docs/api/proto-docs.md @@ -25,6 +25,8 @@ - [MsgConvertVouchersResponse](#cronos.MsgConvertVouchersResponse) - [MsgTransferTokens](#cronos.MsgTransferTokens) - [MsgTransferTokensResponse](#cronos.MsgTransferTokensResponse) + - [MsgUpdateTokenMapping](#cronos.MsgUpdateTokenMapping) + - [MsgUpdateTokenMappingResponse](#cronos.MsgUpdateTokenMappingResponse) - [Msg](#cronos.Msg) @@ -49,6 +51,7 @@ Params defines the parameters for the cronos module. | ----- | ---- | ----- | ----------- | | `ibc_cro_denom` | [string](#string) | | | | `ibc_timeout` | [uint64](#uint64) | | | +| `cronos_admin` | [string](#string) | | the admin address who can update token mapping | @@ -274,7 +277,32 @@ MsgTransferTokens represents a message to transfer cronos evm coins through ibc. ### MsgTransferTokensResponse MsgTransferTokensResponse defines the TransferTokens response type. -this line is used by starport scaffolding # proto/tx/message + + + + + + + +### MsgUpdateTokenMapping +MsgUpdateTokenMapping defines the request type + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `sender` | [string](#string) | | | +| `denom` | [string](#string) | | | +| `contract` | [string](#string) | | | + + + + + + + + +### MsgUpdateTokenMappingResponse +MsgUpdateTokenMappingResponse defines the response type @@ -296,6 +324,7 @@ Msg defines the Cronos Msg service | ----------- | ------------ | ------------- | ------------| ------- | -------- | | `ConvertVouchers` | [MsgConvertVouchers](#cronos.MsgConvertVouchers) | [MsgConvertVouchersResponse](#cronos.MsgConvertVouchersResponse) | ConvertVouchers defines a method for converting ibc voucher to cronos evm coins. | | | `TransferTokens` | [MsgTransferTokens](#cronos.MsgTransferTokens) | [MsgTransferTokensResponse](#cronos.MsgTransferTokensResponse) | TransferTokens defines a method to transfer cronos evm coins to another chain through IBC | | +| `UpdateTokenMapping` | [MsgUpdateTokenMapping](#cronos.MsgUpdateTokenMapping) | [MsgUpdateTokenMappingResponse](#cronos.MsgUpdateTokenMappingResponse) | UpdateTokenMapping defines a method to update token mapping | | diff --git a/integration_tests/cosmoscli.py b/integration_tests/cosmoscli.py index d92c84d7d7..aa4687d6ce 100644 --- a/integration_tests/cosmoscli.py +++ b/integration_tests/cosmoscli.py @@ -983,3 +983,17 @@ def gov_propose_token_mapping_change(self, denom, contract, **kwargs): **kwargs, ) ) + + def update_token_mapping(self, denom, contract, **kwargs): + return json.loads( + self.raw( + "tx", + "cronos", + "update-token-mapping", + denom, + contract, + "-y", + home=self.data_dir, + **kwargs, + ) + ) diff --git a/integration_tests/test_gravity.py b/integration_tests/test_gravity.py index 4b897f7474..1c31a84aa0 100644 --- a/integration_tests/test_gravity.py +++ b/integration_tests/test_gravity.py @@ -271,3 +271,60 @@ def check(): return balance == 10 wait_for_fn("check balance on cronos", check) + + +def test_direct_token_mapping(gravity): + """ + Test adding a token mapping directly + - deploy test erc20 contract on geth + - deploy corresponding contract on cronos + - add the token mapping on cronos using gov module + - do a gravity transfer, check the balances + """ + geth = gravity.geth + cli = gravity.cronos.cosmos_cli() + cronos_w3 = gravity.cronos.w3 + + # deploy test erc20 contract + erc20 = deploy_contract( + geth, + Path(__file__).parent + / "contracts/artifacts/contracts/TestERC20A.sol/TestERC20A.json", + ) + print("erc20 contract", erc20.address) + crc20 = deploy_contract( + cronos_w3, + Path(__file__).parent + / "contracts/artifacts/contracts/TestERC20Utility.sol/TestERC20Utility.json", + ) + print("crc20 contract", crc20.address) + denom = f"gravity{erc20.address}" + + print("check the contract mapping not exists yet") + with pytest.raises(AssertionError): + cli.query_contract_by_denom(denom) + + rsp = cli.update_token_mapping(denom, crc20.address, from_="community") + assert rsp["code"] != 0, "should not have the permission" + + rsp = cli.update_token_mapping(denom, crc20.address, from_="validator") + assert rsp["code"] == 0, rsp["raw_log"] + wait_for_new_blocks(cli, 1) + + print("check the contract mapping exists now") + rsp = cli.query_contract_by_denom(denom) + print("contract", rsp) + assert rsp["contract"] == crc20.address + + print("try to send token from ethereum to cronos") + txreceipt = send_to_cosmos( + gravity.contract, erc20, ADDRS["community"], 10, KEYS["validator"] + ) + assert txreceipt.status == 1 + + def check(): + balance = crc20.caller.balanceOf(ADDRS["community"]) + print("crc20 balance", balance) + return balance == 10 + + wait_for_fn("check balance on cronos", check) diff --git a/proto/cronos/cronos.proto b/proto/cronos/cronos.proto index df1f30854a..2c06933acc 100644 --- a/proto/cronos/cronos.proto +++ b/proto/cronos/cronos.proto @@ -11,6 +11,8 @@ message Params { string ibc_cro_denom = 1 [ (gogoproto.moretags) = "yaml:\"ibc_cro_denom,omitempty\"" ]; uint64 ibc_timeout = 2; + // the admin address who can update token mapping + string cronos_admin = 3; } // TokenMappingChangeProposal defines a proposal to change one token mapping. diff --git a/proto/cronos/tx.proto b/proto/cronos/tx.proto index 6cacb3e335..00a0b0be8f 100644 --- a/proto/cronos/tx.proto +++ b/proto/cronos/tx.proto @@ -17,6 +17,9 @@ service Msg { // TransferTokens defines a method to transfer cronos evm coins to another chain through IBC rpc TransferTokens(MsgTransferTokens) returns (MsgTransferTokensResponse); + + // UpdateTokenMapping defines a method to update token mapping + rpc UpdateTokenMapping(MsgUpdateTokenMapping) returns (MsgUpdateTokenMappingResponse); } // MsgConvertVouchers represents a message to convert ibc voucher coins to cronos evm coins. @@ -39,4 +42,16 @@ message MsgConvertVouchersResponse {} // MsgTransferTokensResponse defines the TransferTokens response type. message MsgTransferTokensResponse {} + +// MsgUpdateTokenMapping defines the request type +message MsgUpdateTokenMapping { + string sender = 1; + string denom = 2; + string contract = 3; +} + +// MsgUpdateTokenMappingResponse defines the response type +message MsgUpdateTokenMappingResponse { +} + // this line is used by starport scaffolding # proto/tx/message diff --git a/scripts/cronos-devnet.yaml b/scripts/cronos-devnet.yaml index 411101478b..5d585fb6c8 100644 --- a/scripts/cronos-devnet.yaml +++ b/scripts/cronos-devnet.yaml @@ -21,6 +21,9 @@ cronos_777-1: evm: params: evm_denom: basetcro + cronos: + params: + cronos_admin: crc12luku6uxehhak02py4rcz65zu0swh7wjsrw0pp gov: voting_params: voting_period: "10s" diff --git a/x/cronos/client/cli/tx.go b/x/cronos/client/cli/tx.go index 1391fa357e..f5a09a0496 100644 --- a/x/cronos/client/cli/tx.go +++ b/x/cronos/client/cli/tx.go @@ -33,6 +33,7 @@ func GetTxCmd() *cobra.Command { cmd.AddCommand(CmdConvertTokens()) cmd.AddCommand(CmdSendToCryptoOrg()) + cmd.AddCommand(CmdUpdateTokenMapping()) return cmd } @@ -174,3 +175,28 @@ $ %s tx gov submit-proposal token-mapping-change gravity0x0000...0000 0x0000...0 return cmd } + +// CmdUpdateTokenMapping returns a CLI command handler for update token mapping +func CmdUpdateTokenMapping() *cobra.Command { + cmd := &cobra.Command{ + Use: "update-token-mapping [denom] [contract]", + Short: "Update token mapping", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgUpdateTokenMapping(clientCtx.GetFromAddress().String(), args[0], args[1]) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/cronos/handler.go b/x/cronos/handler.go index b1d750f066..5c95068369 100644 --- a/x/cronos/handler.go +++ b/x/cronos/handler.go @@ -27,6 +27,9 @@ func NewHandler(k keeper.Keeper) sdk.Handler { case *types.MsgTransferTokens: res, err := msgServer.TransferTokens(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgUpdateTokenMapping: + res, err := msgServer.UpdateTokenMapping(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) default: errMsg := fmt.Sprintf("unrecognized %s message type: %T", types.ModuleName, msg) return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) diff --git a/x/cronos/handler_test.go b/x/cronos/handler_test.go index c49f061c54..1251d6b874 100644 --- a/x/cronos/handler_test.go +++ b/x/cronos/handler_test.go @@ -2,6 +2,10 @@ package cronos_test import ( "errors" + "strings" + "testing" + "time" + "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -11,9 +15,6 @@ import ( "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tharsis/ethermint/crypto/ethsecp256k1" - "strings" - "testing" - "time" ) type CronosTestSuite struct { @@ -31,13 +32,13 @@ func TestCronosTestSuite(t *testing.T) { func (suite *CronosTestSuite) SetupTest() { checkTx := false - suite.app = app.Setup(false) - suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: app.TestAppChainID, Time: time.Now().UTC()}) - suite.handler = cronos.NewHandler(suite.app.CronosKeeper) - privKey, err := ethsecp256k1.GenerateKey() suite.Require().NoError(err) suite.address = sdk.AccAddress(privKey.PubKey().Address()) + suite.app = app.Setup(false, suite.address.String()) + suite.ctx = suite.app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1, ChainID: app.TestAppChainID, Time: time.Now().UTC()}) + suite.handler = cronos.NewHandler(suite.app.CronosKeeper) + } func (suite *CronosTestSuite) TestInvalidMsg() { @@ -133,3 +134,19 @@ func (suite *CronosTestSuite) TestMsgTransferTokens() { }) } } + +func (suite *CronosTestSuite) TestUpdateTokenMapping() { + suite.SetupTest() + + denom := "gravity0x6E7eef2b30585B2A4D45Ba9312015d5354FDB067" + contract := "0x57f96e6B86CdeFdB3d412547816a82E3E0EbF9D2" + + msg := types.NewMsgUpdateTokenMapping(suite.address.String(), denom, contract) + handler := cronos.NewHandler(suite.app.CronosKeeper) + _, err := handler(suite.ctx, msg) + suite.Require().NoError(err) + + contractAddr, found := suite.app.CronosKeeper.GetContractByDenom(suite.ctx, denom) + suite.Require().True(found) + suite.Require().Equal(contract, contractAddr.Hex()) +} diff --git a/x/cronos/keeper/keeper_test.go b/x/cronos/keeper/keeper_test.go index 651f2ff342..8dafc7fb6e 100644 --- a/x/cronos/keeper/keeper_test.go +++ b/x/cronos/keeper/keeper_test.go @@ -1,11 +1,12 @@ package keeper_test import ( - evmtypes "github.com/tharsis/ethermint/x/evm/types" "math/big" "testing" "time" + evmtypes "github.com/tharsis/ethermint/x/evm/types" + sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" @@ -36,6 +37,8 @@ type KeeperTestSuite struct { // EVM helpers evmParam evmtypes.Params + + address common.Address } func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) { @@ -44,14 +47,14 @@ func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) { // account key priv, err := ethsecp256k1.GenerateKey() require.NoError(t, err) - address := common.BytesToAddress(priv.PubKey().Address().Bytes()) + suite.address = common.BytesToAddress(priv.PubKey().Address().Bytes()) // consensus key priv, err = ethsecp256k1.GenerateKey() require.NoError(t, err) consAddress := sdk.ConsAddress(priv.PubKey().Address()) - suite.app = app.Setup(checkTx) + suite.app = app.Setup(checkTx, sdk.AccAddress(suite.address.Bytes()).String()) suite.ctx = suite.app.NewContext(checkTx, tmproto.Header{ Height: 1, ChainID: app.TestAppChainID, @@ -79,13 +82,13 @@ func (suite *KeeperTestSuite) DoSetupTest(t require.TestingT) { // initialize the validator acc := ðermint.EthAccount{ - BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(address.Bytes()), nil, 0, 0), + BaseAccount: authtypes.NewBaseAccount(sdk.AccAddress(suite.address.Bytes()), nil, 0, 0), CodeHash: common.BytesToHash(ethcrypto.Keccak256(nil)).String(), } suite.app.AccountKeeper.SetAccount(suite.ctx, acc) - valAddr := sdk.ValAddress(address.Bytes()) + valAddr := sdk.ValAddress(suite.address.Bytes()) validator, err := stakingtypes.NewValidator(valAddr, priv.PubKey(), stakingtypes.Description{}) err = suite.app.StakingKeeper.SetValidatorByConsAddr(suite.ctx, validator) require.NoError(t, err) diff --git a/x/cronos/keeper/msg_server.go b/x/cronos/keeper/msg_server.go index 25274371f8..82106da975 100644 --- a/x/cronos/keeper/msg_server.go +++ b/x/cronos/keeper/msg_server.go @@ -4,7 +4,9 @@ import ( "context" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/crypto-org-chain/cronos/x/cronos/types" + "github.com/ethereum/go-ethereum/common" ) type msgServer struct { @@ -55,3 +57,16 @@ func (k msgServer) TransferTokens(goCtx context.Context, msg *types.MsgTransferT ) return &types.MsgTransferTokensResponse{}, nil } + +// UpdateTokenMapping implements the grpc method +func (k msgServer) UpdateTokenMapping(goCtx context.Context, msg *types.MsgUpdateTokenMapping) (*types.MsgUpdateTokenMappingResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + admin := k.Keeper.GetParams(ctx).CronosAdmin + // if admin is empty, no sender could be equal to it + if admin != msg.Sender { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "msg sender is authorized") + } + // msg is already validated + k.Keeper.SetExternalContractForDenom(ctx, msg.Denom, common.HexToAddress(msg.Contract)) + return &types.MsgUpdateTokenMappingResponse{}, nil +} diff --git a/x/cronos/types/cronos.pb.go b/x/cronos/types/cronos.pb.go index 22b8983a4c..07b4c5630e 100644 --- a/x/cronos/types/cronos.pb.go +++ b/x/cronos/types/cronos.pb.go @@ -27,6 +27,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Params struct { IbcCroDenom string `protobuf:"bytes,1,opt,name=ibc_cro_denom,json=ibcCroDenom,proto3" json:"ibc_cro_denom,omitempty" yaml:"ibc_cro_denom,omitempty"` IbcTimeout uint64 `protobuf:"varint,2,opt,name=ibc_timeout,json=ibcTimeout,proto3" json:"ibc_timeout,omitempty"` + // the admin address who can update token mapping + CronosAdmin string `protobuf:"bytes,3,opt,name=cronos_admin,json=cronosAdmin,proto3" json:"cronos_admin,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -75,6 +77,13 @@ func (m *Params) GetIbcTimeout() uint64 { return 0 } +func (m *Params) GetCronosAdmin() string { + if m != nil { + return m.CronosAdmin + } + return "" +} + // TokenMappingChangeProposal defines a proposal to change one token mapping. type TokenMappingChangeProposal struct { Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` @@ -177,29 +186,30 @@ func init() { func init() { proto.RegisterFile("cronos/cronos.proto", fileDescriptor_8bc54992a93db2d2) } var fileDescriptor_8bc54992a93db2d2 = []byte{ - // 338 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xbf, 0x6e, 0xea, 0x30, - 0x14, 0xc6, 0x63, 0x2e, 0x17, 0x81, 0xb9, 0x77, 0x49, 0x19, 0x10, 0x83, 0x83, 0x32, 0x31, 0x14, - 0xa2, 0xaa, 0x1b, 0x53, 0x05, 0x55, 0x97, 0xaa, 0x12, 0x8a, 0x98, 0xba, 0x20, 0xc7, 0x58, 0xc1, - 0x2a, 0xf6, 0xb1, 0x1c, 0xa3, 0x36, 0x6f, 0xd0, 0x91, 0xb1, 0x23, 0x8f, 0xd3, 0x91, 0xb1, 0x53, - 0x55, 0xc1, 0x1b, 0xf4, 0x09, 0xaa, 0xc4, 0xfd, 0x03, 0x43, 0xa7, 0x73, 0x7e, 0xdf, 0xa7, 0xf3, - 0xe9, 0x93, 0x0e, 0x3e, 0x61, 0x06, 0x14, 0x64, 0x91, 0x1b, 0x03, 0x6d, 0xc0, 0x82, 0x5f, 0x73, - 0xd4, 0x69, 0xa5, 0x90, 0x42, 0x29, 0x45, 0xc5, 0xe6, 0xdc, 0xf0, 0x1e, 0xd7, 0x26, 0xd4, 0x50, - 0x99, 0xf9, 0x57, 0xf8, 0xbf, 0x48, 0xd8, 0x8c, 0x19, 0x98, 0xcd, 0xb9, 0x02, 0xd9, 0x46, 0x5d, - 0xd4, 0x6b, 0x8c, 0xc2, 0xf7, 0xd7, 0x80, 0xe4, 0x54, 0x2e, 0x87, 0xe1, 0x91, 0x7d, 0x0a, 0x52, - 0x58, 0x2e, 0xb5, 0xcd, 0xc3, 0xb8, 0x29, 0x12, 0x36, 0x36, 0x70, 0x59, 0xe8, 0x7e, 0x80, 0x0b, - 0x9c, 0x59, 0x21, 0x39, 0xac, 0x6c, 0xbb, 0xd2, 0x45, 0xbd, 0x6a, 0x8c, 0x45, 0xc2, 0xa6, 0x4e, - 0x19, 0x56, 0x9f, 0x36, 0x81, 0x17, 0xae, 0x11, 0xee, 0x4c, 0xe1, 0x8e, 0xab, 0x1b, 0xaa, 0xb5, - 0x50, 0xe9, 0x78, 0x41, 0x55, 0xca, 0x27, 0x06, 0x34, 0x64, 0x74, 0xe9, 0xb7, 0xf0, 0x5f, 0x2b, - 0xec, 0x92, 0xbb, 0x16, 0xb1, 0x03, 0xbf, 0x8b, 0x9b, 0x73, 0x9e, 0x31, 0x23, 0xb4, 0x15, 0xa0, - 0xca, 0xec, 0x46, 0x7c, 0x28, 0x15, 0x77, 0xae, 0xfd, 0x1f, 0x77, 0x57, 0x82, 0xdf, 0xc1, 0x75, - 0x06, 0xca, 0x1a, 0xca, 0x6c, 0xbb, 0x5a, 0x1a, 0xdf, 0x3c, 0xac, 0x3f, 0x6e, 0x02, 0xaf, 0xac, - 0x74, 0x81, 0xff, 0x1d, 0x36, 0xfa, 0xc9, 0x42, 0xbf, 0x65, 0x55, 0x8e, 0xb3, 0x46, 0xd7, 0xcf, - 0x3b, 0x82, 0xb6, 0x3b, 0x82, 0xde, 0x76, 0x04, 0xad, 0xf7, 0xc4, 0xdb, 0xee, 0x89, 0xf7, 0xb2, - 0x27, 0xde, 0xed, 0x59, 0x2a, 0xec, 0x62, 0x95, 0x0c, 0x18, 0xc8, 0x88, 0x99, 0x5c, 0x5b, 0xe8, - 0x83, 0x49, 0xfb, 0x6c, 0x41, 0x85, 0xfa, 0xfc, 0x57, 0xf4, 0xf0, 0xb5, 0xd8, 0x5c, 0xf3, 0x2c, - 0xa9, 0x95, 0x1f, 0x3a, 0xff, 0x08, 0x00, 0x00, 0xff, 0xff, 0x18, 0x65, 0x3a, 0xeb, 0xd6, 0x01, - 0x00, 0x00, + // 359 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xbd, 0x6e, 0xe2, 0x40, + 0x14, 0x85, 0x3d, 0x2c, 0x8b, 0x60, 0x60, 0x1b, 0x2f, 0x85, 0x45, 0x61, 0xb3, 0xae, 0x28, 0x16, + 0xac, 0xd5, 0x76, 0x54, 0xbb, 0x10, 0xa5, 0x89, 0x22, 0x21, 0x8b, 0x2a, 0x8d, 0x35, 0x1e, 0x46, + 0x66, 0x14, 0x66, 0xee, 0x68, 0x3c, 0x48, 0xf1, 0x1b, 0xa4, 0xa4, 0x8c, 0x52, 0xf1, 0x38, 0x29, + 0x29, 0x53, 0x45, 0x11, 0xbc, 0x41, 0x9e, 0x20, 0xb2, 0x27, 0x3f, 0x50, 0xa4, 0xf2, 0x3d, 0xdf, + 0x95, 0xcf, 0x39, 0xa3, 0x8b, 0x7f, 0x52, 0x0d, 0x12, 0xf2, 0xc8, 0x7e, 0x46, 0x4a, 0x83, 0x01, + 0xb7, 0x61, 0x55, 0xaf, 0x9b, 0x41, 0x06, 0x15, 0x8a, 0xca, 0xc9, 0x6e, 0xc3, 0x7b, 0x84, 0x1b, + 0x33, 0xa2, 0x89, 0xc8, 0xdd, 0x73, 0xfc, 0x83, 0xa7, 0x34, 0xa1, 0x1a, 0x92, 0x05, 0x93, 0x20, + 0x3c, 0xd4, 0x47, 0x83, 0xd6, 0x24, 0x7c, 0x79, 0x0a, 0xfc, 0x82, 0x88, 0xd5, 0x38, 0x3c, 0x59, + 0xff, 0x06, 0xc1, 0x0d, 0x13, 0xca, 0x14, 0x61, 0xdc, 0xe6, 0x29, 0x9d, 0x6a, 0x38, 0x2b, 0xb9, + 0x1b, 0xe0, 0x52, 0x26, 0x86, 0x0b, 0x06, 0x6b, 0xe3, 0xd5, 0xfa, 0x68, 0x50, 0x8f, 0x31, 0x4f, + 0xe9, 0xdc, 0x12, 0xf7, 0x17, 0xee, 0xd8, 0x4e, 0x09, 0x59, 0x08, 0x2e, 0xbd, 0x6f, 0x65, 0x4e, + 0xdc, 0xb6, 0xec, 0x7f, 0x89, 0xc6, 0xf5, 0xbb, 0x6d, 0xe0, 0x84, 0x1b, 0x84, 0x7b, 0x73, 0xb8, + 0x66, 0xf2, 0x92, 0x28, 0xc5, 0x65, 0x36, 0x5d, 0x12, 0x99, 0xb1, 0x99, 0x06, 0x05, 0x39, 0x59, + 0xb9, 0x5d, 0xfc, 0xdd, 0x70, 0xb3, 0x62, 0xb6, 0x68, 0x6c, 0x85, 0xdb, 0xc7, 0xed, 0x05, 0xcb, + 0xa9, 0xe6, 0xca, 0x70, 0x90, 0x55, 0x7c, 0x2b, 0x3e, 0x46, 0xe5, 0x7f, 0xf6, 0x81, 0x36, 0xd8, + 0x0a, 0xb7, 0x87, 0x9b, 0x14, 0xa4, 0xd1, 0x84, 0x1a, 0xaf, 0x5e, 0x2d, 0x3e, 0xf4, 0xb8, 0x79, + 0xbb, 0x0d, 0x9c, 0xaa, 0xd2, 0x3f, 0xdc, 0x39, 0x6e, 0xf4, 0xe9, 0x85, 0xbe, 0xf2, 0xaa, 0x9d, + 0x7a, 0x4d, 0x2e, 0x1e, 0xf6, 0x3e, 0xda, 0xed, 0x7d, 0xf4, 0xbc, 0xf7, 0xd1, 0xe6, 0xe0, 0x3b, + 0xbb, 0x83, 0xef, 0x3c, 0x1e, 0x7c, 0xe7, 0xea, 0x4f, 0xc6, 0xcd, 0x72, 0x9d, 0x8e, 0x28, 0x88, + 0x88, 0xea, 0x42, 0x19, 0x18, 0x82, 0xce, 0x86, 0x74, 0x49, 0xb8, 0x7c, 0xbb, 0x69, 0x74, 0xf3, + 0x3e, 0x98, 0x42, 0xb1, 0x3c, 0x6d, 0x54, 0x57, 0xfc, 0xfb, 0x1a, 0x00, 0x00, 0xff, 0xff, 0x75, + 0xe9, 0x8d, 0x5e, 0xfa, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -222,6 +232,13 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.CronosAdmin) > 0 { + i -= len(m.CronosAdmin) + copy(dAtA[i:], m.CronosAdmin) + i = encodeVarintCronos(dAtA, i, uint64(len(m.CronosAdmin))) + i-- + dAtA[i] = 0x1a + } if m.IbcTimeout != 0 { i = encodeVarintCronos(dAtA, i, uint64(m.IbcTimeout)) i-- @@ -349,6 +366,10 @@ func (m *Params) Size() (n int) { if m.IbcTimeout != 0 { n += 1 + sovCronos(uint64(m.IbcTimeout)) } + l = len(m.CronosAdmin) + if l > 0 { + n += 1 + l + sovCronos(uint64(l)) + } return n } @@ -480,6 +501,38 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CronosAdmin", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCronos + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCronos + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCronos + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CronosAdmin = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCronos(dAtA[iNdEx:]) diff --git a/x/cronos/types/messages.go b/x/cronos/types/messages.go index 621a14b2b0..c884fb4278 100644 --- a/x/cronos/types/messages.go +++ b/x/cronos/types/messages.go @@ -3,11 +3,13 @@ package types import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/ethereum/go-ethereum/common" ) const ( - TypeMsgConvertVouchers = "ConvertVouchers" - TypeMsgTransferTokens = "TransferTokens" + TypeMsgConvertVouchers = "ConvertVouchers" + TypeMsgTransferTokens = "TransferTokens" + TypeMsgUpdateTokenMapping = "UpdateTokenMapping" ) var _ sdk.Msg = &MsgConvertVouchers{} @@ -113,3 +115,57 @@ func (msg *MsgTransferTokens) ValidateBasic() error { } return nil } + +var _ sdk.Msg = &MsgUpdateTokenMapping{} + +// NewMsgUpdateTokenMapping ... +func NewMsgUpdateTokenMapping(admin string, denom string, contract string) *MsgUpdateTokenMapping { + return &MsgUpdateTokenMapping{ + Sender: admin, + Denom: denom, + Contract: contract, + } +} + +// GetSigners ... +func (msg *MsgUpdateTokenMapping) GetSigners() []sdk.AccAddress { + sender, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + panic(err) + } + return []sdk.AccAddress{sender} +} + +// ValidateBasic ... +func (msg *MsgUpdateTokenMapping) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid sender address (%s)", err) + } + + if !IsValidDenomToWrap(msg.Denom) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid denom to wrap (%s)", msg.Denom) + } + + if !common.IsHexAddress(msg.Contract) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid contract address (%s)", msg.Contract) + } + + return nil +} + +// Route ... +func (msg MsgUpdateTokenMapping) Route() string { + return RouterKey +} + +// Type ... +func (msg MsgUpdateTokenMapping) Type() string { + return TypeMsgUpdateTokenMapping +} + +// GetSignBytes ... +func (msg *MsgUpdateTokenMapping) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} diff --git a/x/cronos/types/messages_test.go b/x/cronos/types/messages_test.go new file mode 100644 index 0000000000..649b29d8f5 --- /dev/null +++ b/x/cronos/types/messages_test.go @@ -0,0 +1,56 @@ +package types_test + +import ( + "fmt" + "testing" + + "github.com/crypto-org-chain/cronos/app" + "github.com/crypto-org-chain/cronos/x/cronos/types" + "github.com/stretchr/testify/require" +) + +func TestValidateMsgUpdateTokenMapping(t *testing.T) { + app.SetConfig() + + testCases := []struct { + name string + msg *types.MsgUpdateTokenMapping + expValid bool + }{ + { + "valid gravity denom", + types.NewMsgUpdateTokenMapping("crc12luku6uxehhak02py4rcz65zu0swh7wjsrw0pp", "gravity0x6E7eef2b30585B2A4D45Ba9312015d5354FDB067", "0x57f96e6B86CdeFdB3d412547816a82E3E0EbF9D2"), + true, + }, + { + "valid ibc denom", + types.NewMsgUpdateTokenMapping("crc12luku6uxehhak02py4rcz65zu0swh7wjsrw0pp", "ibc/0000000000000000000000000000000000000000000000000000000000000000", "0x57f96e6B86CdeFdB3d412547816a82E3E0EbF9D2"), + true, + }, + { + "invalid sender", + types.NewMsgUpdateTokenMapping("crc12luku6uxehhak02py4r", "gravity0x6E7eef2b30585B2A4D45Ba9312015d5354FDB067", "0x57f96e6B86CdeFdB3d412547816a82E3E0EbF9D2"), + false, + }, + { + "invalid denom", + types.NewMsgUpdateTokenMapping("crc12luku6uxehhak02py4rcz65zu0swh7wjsrw0pp", "aaa", "0x57f96e6B86CdeFdB3d412547816a82E3E0EbF9D2"), + false, + }, + { + "invalid contract address", + types.NewMsgUpdateTokenMapping("crc12luku6uxehhak02py4rcz65zu0swh7wjsrw0pp", "gravity0x6E7eef2b30585B2A4D45Ba9312015d5354FDB067", "0x57f96e6B86CdeFdB3d4125"), + false, + }, + } + for _, tc := range testCases { + t.Run(fmt.Sprintf("Case %s", tc.name), func(t1 *testing.T) { + err := tc.msg.ValidateBasic() + if tc.expValid { + require.NoError(t1, err) + } else { + require.Error(t1, err) + } + }) + } +} diff --git a/x/cronos/types/params.go b/x/cronos/types/params.go index 9d0d4ba14b..312941c84c 100644 --- a/x/cronos/types/params.go +++ b/x/cronos/types/params.go @@ -5,6 +5,7 @@ import ( yaml "gopkg.in/yaml.v2" + sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) @@ -13,6 +14,8 @@ var ( KeyIbcCroDenom = []byte("IbcCroDenom") // KeyIbcTimeout is store's key for the IBC Timeout KeyIbcTimeout = []byte("KeyIbcTimeout") + // KeyCronosAdmin is store's key for the admin address + KeyCronosAdmin = []byte("KeyCronosAdmin") ) const IbcCroDenomDefaultValue = "ibc/6B5A664BF0AF4F71B2F0BAA33141E2F1321242FBD5D19762F541EC971ACB0865" @@ -24,10 +27,11 @@ func ParamKeyTable() paramtypes.KeyTable { } // NewParams creates a new parameter configuration for the cronos module -func NewParams(ibcCroDenom string, ibcTimeout uint64) Params { +func NewParams(ibcCroDenom string, ibcTimeout uint64, cronosAdmin string) Params { return Params{ IbcCroDenom: ibcCroDenom, IbcTimeout: ibcTimeout, + CronosAdmin: cronosAdmin, } } @@ -36,6 +40,7 @@ func DefaultParams() Params { return Params{ IbcCroDenom: IbcCroDenomDefaultValue, IbcTimeout: IbcTimeoutDefaultValue, + CronosAdmin: "", } } @@ -44,7 +49,15 @@ func (p Params) Validate() error { if err := validateIsUint64(p.IbcTimeout); err != nil { return err } - return validateIsIbcDenom(p.IbcCroDenom) + if err := validateIsIbcDenom(p.IbcCroDenom); err != nil { + return err + } + if len(p.CronosAdmin) > 0 { + if _, err := sdk.AccAddressFromBech32(p.CronosAdmin); err != nil { + return err + } + } + return nil } // String implements the fmt.Stringer interface @@ -58,6 +71,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(KeyIbcCroDenom, &p.IbcCroDenom, validateIsIbcDenom), paramtypes.NewParamSetPair(KeyIbcTimeout, &p.IbcTimeout, validateIsUint64), + paramtypes.NewParamSetPair(KeyCronosAdmin, &p.CronosAdmin, validateIsAddress), } } @@ -79,3 +93,17 @@ func validateIsUint64(i interface{}) error { } return nil } + +func validateIsAddress(i interface{}) error { + s, ok := i.(string) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if len(s) > 0 { + if _, err := sdk.AccAddressFromBech32(s); err != nil { + return err + } + } + return nil + +} diff --git a/x/cronos/types/tx.pb.go b/x/cronos/types/tx.pb.go index f4713995f6..f078f21d25 100644 --- a/x/cronos/types/tx.pb.go +++ b/x/cronos/types/tx.pb.go @@ -218,41 +218,146 @@ func (m *MsgTransferTokensResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgTransferTokensResponse proto.InternalMessageInfo +// MsgUpdateTokenMapping defines the request type +type MsgUpdateTokenMapping struct { + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + Denom string `protobuf:"bytes,2,opt,name=denom,proto3" json:"denom,omitempty"` + Contract string `protobuf:"bytes,3,opt,name=contract,proto3" json:"contract,omitempty"` +} + +func (m *MsgUpdateTokenMapping) Reset() { *m = MsgUpdateTokenMapping{} } +func (m *MsgUpdateTokenMapping) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateTokenMapping) ProtoMessage() {} +func (*MsgUpdateTokenMapping) Descriptor() ([]byte, []int) { + return fileDescriptor_28e09e4eabb18884, []int{4} +} +func (m *MsgUpdateTokenMapping) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateTokenMapping) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateTokenMapping.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateTokenMapping) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateTokenMapping.Merge(m, src) +} +func (m *MsgUpdateTokenMapping) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateTokenMapping) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateTokenMapping.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateTokenMapping proto.InternalMessageInfo + +func (m *MsgUpdateTokenMapping) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *MsgUpdateTokenMapping) GetDenom() string { + if m != nil { + return m.Denom + } + return "" +} + +func (m *MsgUpdateTokenMapping) GetContract() string { + if m != nil { + return m.Contract + } + return "" +} + +// MsgUpdateTokenMappingResponse defines the response type +type MsgUpdateTokenMappingResponse struct { +} + +func (m *MsgUpdateTokenMappingResponse) Reset() { *m = MsgUpdateTokenMappingResponse{} } +func (m *MsgUpdateTokenMappingResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateTokenMappingResponse) ProtoMessage() {} +func (*MsgUpdateTokenMappingResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_28e09e4eabb18884, []int{5} +} +func (m *MsgUpdateTokenMappingResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateTokenMappingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateTokenMappingResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateTokenMappingResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateTokenMappingResponse.Merge(m, src) +} +func (m *MsgUpdateTokenMappingResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateTokenMappingResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateTokenMappingResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateTokenMappingResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgConvertVouchers)(nil), "cronos.MsgConvertVouchers") proto.RegisterType((*MsgTransferTokens)(nil), "cronos.MsgTransferTokens") proto.RegisterType((*MsgConvertVouchersResponse)(nil), "cronos.MsgConvertVouchersResponse") proto.RegisterType((*MsgTransferTokensResponse)(nil), "cronos.MsgTransferTokensResponse") + proto.RegisterType((*MsgUpdateTokenMapping)(nil), "cronos.MsgUpdateTokenMapping") + proto.RegisterType((*MsgUpdateTokenMappingResponse)(nil), "cronos.MsgUpdateTokenMappingResponse") } func init() { proto.RegisterFile("cronos/tx.proto", fileDescriptor_28e09e4eabb18884) } var fileDescriptor_28e09e4eabb18884 = []byte{ - // 370 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x92, 0xbf, 0x8e, 0xda, 0x40, - 0x10, 0xc6, 0xbd, 0x26, 0x21, 0xca, 0x46, 0x02, 0x65, 0x95, 0xc2, 0x38, 0x91, 0x21, 0xae, 0x68, - 0xd8, 0x0d, 0xe4, 0x0d, 0xa0, 0x8c, 0x88, 0x14, 0x84, 0x52, 0xa4, 0xb3, 0xcd, 0x62, 0x2c, 0xc4, - 0x8e, 0xb5, 0xb3, 0x20, 0x78, 0x8b, 0xa4, 0xcd, 0x13, 0x9c, 0xee, 0x49, 0x28, 0x29, 0xaf, 0xba, - 0x3b, 0xc1, 0x8b, 0x9c, 0xf0, 0x1f, 0x1d, 0x07, 0xa2, 0xbc, 0xca, 0xe3, 0xf9, 0x69, 0xbe, 0xf9, - 0xf4, 0xed, 0xd0, 0x7a, 0xa4, 0x41, 0x01, 0x0a, 0xb3, 0xe6, 0xa9, 0x06, 0x03, 0xac, 0x9a, 0x37, - 0xdc, 0x4f, 0x31, 0xc4, 0x90, 0xb5, 0xc4, 0xb1, 0xca, 0xa9, 0xeb, 0x45, 0x80, 0x0b, 0x40, 0x11, - 0x06, 0x28, 0xc5, 0xaa, 0x1b, 0x4a, 0x13, 0x74, 0x45, 0x04, 0x89, 0xca, 0xb9, 0xff, 0x8f, 0x50, - 0x36, 0xc4, 0x78, 0x00, 0x6a, 0x25, 0xb5, 0xf9, 0x0d, 0xcb, 0x68, 0x26, 0x35, 0x32, 0x87, 0xbe, - 0x0b, 0x26, 0x13, 0x2d, 0x11, 0x1d, 0xd2, 0x22, 0xed, 0xf7, 0xa3, 0xf2, 0x97, 0x05, 0xf4, 0xed, - 0x71, 0x1c, 0x1d, 0xbb, 0x55, 0x69, 0x7f, 0xe8, 0x35, 0x78, 0xbe, 0x80, 0x1f, 0x17, 0xf0, 0x62, - 0x01, 0x1f, 0x40, 0xa2, 0xfa, 0xdf, 0xb6, 0xf7, 0x4d, 0xeb, 0xf6, 0xa1, 0xd9, 0x8e, 0x13, 0x33, - 0x5b, 0x86, 0x3c, 0x82, 0x85, 0x28, 0xdc, 0xe4, 0x9f, 0x0e, 0x4e, 0xe6, 0xc2, 0x6c, 0x52, 0x89, - 0xd9, 0x00, 0x8e, 0x72, 0x65, 0xff, 0x3f, 0xa1, 0x1f, 0x87, 0x18, 0x8f, 0x75, 0xa0, 0x70, 0x2a, - 0xf5, 0x18, 0xe6, 0x52, 0x21, 0x63, 0xf4, 0xcd, 0x54, 0xc3, 0xa2, 0xf0, 0x93, 0xd5, 0xac, 0x46, - 0x6d, 0x03, 0x8e, 0x9d, 0x75, 0x6c, 0x03, 0xcf, 0xe6, 0x2a, 0xaf, 0x66, 0xee, 0x0b, 0x75, 0x2f, - 0xf3, 0x1a, 0x49, 0x4c, 0x41, 0xa1, 0xf4, 0x3f, 0xd3, 0xc6, 0x85, 0xf3, 0x12, 0xf6, 0x6e, 0x08, - 0xad, 0x0c, 0x31, 0x66, 0xbf, 0x68, 0xfd, 0x3c, 0x6f, 0x97, 0xe7, 0xaf, 0xc8, 0x2f, 0xb5, 0x5d, - 0xff, 0x3a, 0x2b, 0xa5, 0xd9, 0x4f, 0x5a, 0x3b, 0x8b, 0xab, 0x71, 0x32, 0xf5, 0x12, 0xb9, 0x5f, - 0xaf, 0xa2, 0x52, 0xaf, 0xff, 0x63, 0xbb, 0xf7, 0xc8, 0x6e, 0xef, 0x91, 0xc7, 0xbd, 0x47, 0xfe, - 0x1e, 0x3c, 0x6b, 0x77, 0xf0, 0xac, 0xbb, 0x83, 0x67, 0xfd, 0xe9, 0x9e, 0x06, 0xa6, 0x37, 0xa9, - 0x81, 0x0e, 0xe8, 0xb8, 0x13, 0xcd, 0x82, 0x44, 0x89, 0xe2, 0x36, 0xd7, 0x65, 0x91, 0xe5, 0x17, - 0x56, 0xb3, 0x53, 0xfb, 0xfe, 0x14, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xf6, 0x69, 0x5d, 0xbb, 0x02, - 0x00, 0x00, + // 449 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xc1, 0x6e, 0xd3, 0x40, + 0x10, 0x86, 0x63, 0x87, 0x06, 0x18, 0xa4, 0x56, 0xac, 0x0a, 0x72, 0x0c, 0x75, 0x8a, 0x25, 0xa4, + 0x5c, 0x62, 0x93, 0xf2, 0x06, 0xed, 0x11, 0x19, 0x89, 0xa8, 0x70, 0xe8, 0x6d, 0x63, 0x6f, 0x37, + 0x56, 0x95, 0x1d, 0x6b, 0x67, 0x5b, 0xb5, 0x77, 0x1e, 0x00, 0xae, 0x3c, 0x02, 0x4f, 0xd2, 0x63, + 0x8f, 0x9c, 0x00, 0x25, 0x2f, 0x82, 0xb2, 0x6b, 0x87, 0xd0, 0x34, 0xdc, 0x7a, 0xda, 0x99, 0xf9, + 0x34, 0x33, 0xff, 0xec, 0xce, 0xc2, 0x4e, 0xae, 0x51, 0x21, 0xa5, 0xe6, 0x32, 0xa9, 0x34, 0x1a, + 0x64, 0x1d, 0x17, 0x08, 0x77, 0x25, 0x4a, 0xb4, 0xa1, 0x74, 0x61, 0x39, 0x1a, 0x46, 0x39, 0xd2, + 0x14, 0x29, 0x1d, 0x73, 0x12, 0xe9, 0xc5, 0x70, 0x2c, 0x0c, 0x1f, 0xa6, 0x39, 0x96, 0xca, 0xf1, + 0xf8, 0xab, 0x07, 0x2c, 0x23, 0x79, 0x84, 0xea, 0x42, 0x68, 0xf3, 0x09, 0xcf, 0xf3, 0x89, 0xd0, + 0xc4, 0x02, 0x78, 0xc8, 0x8b, 0x42, 0x0b, 0xa2, 0xc0, 0xdb, 0xf7, 0xfa, 0x8f, 0x47, 0x8d, 0xcb, + 0x38, 0x6c, 0x2d, 0xd2, 0x29, 0xf0, 0xf7, 0xdb, 0xfd, 0x27, 0x07, 0xdd, 0xc4, 0x35, 0x48, 0x16, + 0x0d, 0x92, 0xba, 0x41, 0x72, 0x84, 0xa5, 0x3a, 0x7c, 0x73, 0xfd, 0xb3, 0xd7, 0xfa, 0xfe, 0xab, + 0xd7, 0x97, 0xa5, 0x99, 0x9c, 0x8f, 0x93, 0x1c, 0xa7, 0x69, 0xad, 0xc6, 0x1d, 0x03, 0x2a, 0xce, + 0x52, 0x73, 0x55, 0x09, 0xb2, 0x09, 0x34, 0x72, 0x95, 0xe3, 0x6f, 0x1e, 0x3c, 0xcd, 0x48, 0x1e, + 0x6b, 0xae, 0xe8, 0x54, 0xe8, 0x63, 0x3c, 0x13, 0x8a, 0x18, 0x83, 0x07, 0xa7, 0x1a, 0xa7, 0xb5, + 0x1e, 0x6b, 0xb3, 0x6d, 0xf0, 0x0d, 0x06, 0xbe, 0x8d, 0xf8, 0x06, 0xff, 0x8a, 0x6b, 0xdf, 0x9b, + 0xb8, 0x97, 0x10, 0xae, 0xdf, 0xd7, 0x48, 0x50, 0x85, 0x8a, 0x44, 0xfc, 0x02, 0xba, 0x6b, 0xca, + 0x97, 0x90, 0xc3, 0xb3, 0x8c, 0xe4, 0xc7, 0xaa, 0xe0, 0x46, 0x58, 0x94, 0xf1, 0xaa, 0x2a, 0x95, + 0x64, 0xcf, 0xa1, 0x43, 0x42, 0x15, 0x42, 0xd7, 0xc3, 0xd5, 0x1e, 0xdb, 0x85, 0xad, 0x42, 0x28, + 0x9c, 0xd6, 0x13, 0x3a, 0x87, 0x85, 0xf0, 0x28, 0x47, 0x65, 0x34, 0xcf, 0x4d, 0xd0, 0xb6, 0x60, + 0xe9, 0xc7, 0x3d, 0xd8, 0xbb, 0xb3, 0x45, 0xa3, 0xe1, 0xe0, 0xb3, 0x0f, 0xed, 0x8c, 0x24, 0xfb, + 0x00, 0x3b, 0xb7, 0xdf, 0x3c, 0x4c, 0xdc, 0x26, 0x25, 0xeb, 0xf3, 0x85, 0xf1, 0x66, 0xd6, 0x94, + 0x66, 0xef, 0x61, 0xfb, 0xd6, 0x93, 0x75, 0x57, 0xb2, 0xfe, 0x45, 0xe1, 0xab, 0x8d, 0x68, 0x59, + 0xef, 0x04, 0xd8, 0x1d, 0x77, 0xb5, 0xb7, 0x92, 0xb8, 0x8e, 0xc3, 0xd7, 0xff, 0xc5, 0x4d, 0xed, + 0xc3, 0x77, 0xd7, 0xb3, 0xc8, 0xbb, 0x99, 0x45, 0xde, 0xef, 0x59, 0xe4, 0x7d, 0x99, 0x47, 0xad, + 0x9b, 0x79, 0xd4, 0xfa, 0x31, 0x8f, 0x5a, 0x27, 0xc3, 0xd5, 0x85, 0xd0, 0x57, 0x95, 0xc1, 0x01, + 0x6a, 0x39, 0xc8, 0x27, 0xbc, 0x54, 0x69, 0xfd, 0xf7, 0x2e, 0x1b, 0xc3, 0xee, 0xc7, 0xb8, 0x63, + 0xbf, 0xd2, 0xdb, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x45, 0x34, 0x86, 0x15, 0x9b, 0x03, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -271,6 +376,8 @@ type MsgClient interface { ConvertVouchers(ctx context.Context, in *MsgConvertVouchers, opts ...grpc.CallOption) (*MsgConvertVouchersResponse, error) // TransferTokens defines a method to transfer cronos evm coins to another chain through IBC TransferTokens(ctx context.Context, in *MsgTransferTokens, opts ...grpc.CallOption) (*MsgTransferTokensResponse, error) + // UpdateTokenMapping defines a method to update token mapping + UpdateTokenMapping(ctx context.Context, in *MsgUpdateTokenMapping, opts ...grpc.CallOption) (*MsgUpdateTokenMappingResponse, error) } type msgClient struct { @@ -299,12 +406,23 @@ func (c *msgClient) TransferTokens(ctx context.Context, in *MsgTransferTokens, o return out, nil } +func (c *msgClient) UpdateTokenMapping(ctx context.Context, in *MsgUpdateTokenMapping, opts ...grpc.CallOption) (*MsgUpdateTokenMappingResponse, error) { + out := new(MsgUpdateTokenMappingResponse) + err := c.cc.Invoke(ctx, "/cronos.Msg/UpdateTokenMapping", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { // ConvertVouchers defines a method for converting ibc voucher to cronos evm coins. ConvertVouchers(context.Context, *MsgConvertVouchers) (*MsgConvertVouchersResponse, error) // TransferTokens defines a method to transfer cronos evm coins to another chain through IBC TransferTokens(context.Context, *MsgTransferTokens) (*MsgTransferTokensResponse, error) + // UpdateTokenMapping defines a method to update token mapping + UpdateTokenMapping(context.Context, *MsgUpdateTokenMapping) (*MsgUpdateTokenMappingResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -317,6 +435,9 @@ func (*UnimplementedMsgServer) ConvertVouchers(ctx context.Context, req *MsgConv func (*UnimplementedMsgServer) TransferTokens(ctx context.Context, req *MsgTransferTokens) (*MsgTransferTokensResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method TransferTokens not implemented") } +func (*UnimplementedMsgServer) UpdateTokenMapping(ctx context.Context, req *MsgUpdateTokenMapping) (*MsgUpdateTokenMappingResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateTokenMapping not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -358,6 +479,24 @@ func _Msg_TransferTokens_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _Msg_UpdateTokenMapping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateTokenMapping) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateTokenMapping(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cronos.Msg/UpdateTokenMapping", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateTokenMapping(ctx, req.(*MsgUpdateTokenMapping)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "cronos.Msg", HandlerType: (*MsgServer)(nil), @@ -370,6 +509,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "TransferTokens", Handler: _Msg_TransferTokens_Handler, }, + { + MethodName: "UpdateTokenMapping", + Handler: _Msg_UpdateTokenMapping_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cronos/tx.proto", @@ -516,6 +659,73 @@ func (m *MsgTransferTokensResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } +func (m *MsgUpdateTokenMapping) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateTokenMapping) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateTokenMapping) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Contract) > 0 { + i -= len(m.Contract) + copy(dAtA[i:], m.Contract) + i = encodeVarintTx(dAtA, i, uint64(len(m.Contract))) + i-- + dAtA[i] = 0x1a + } + if len(m.Denom) > 0 { + i -= len(m.Denom) + copy(dAtA[i:], m.Denom) + i = encodeVarintTx(dAtA, i, uint64(len(m.Denom))) + i-- + dAtA[i] = 0x12 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateTokenMappingResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateTokenMappingResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateTokenMappingResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func encodeVarintTx(dAtA []byte, offset int, v uint64) int { offset -= sovTx(v) base := offset @@ -587,6 +797,36 @@ func (m *MsgTransferTokensResponse) Size() (n int) { return n } +func (m *MsgUpdateTokenMapping) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Denom) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Contract) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgUpdateTokenMappingResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func sovTx(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -957,6 +1197,202 @@ func (m *MsgTransferTokensResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgUpdateTokenMapping) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateTokenMapping: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateTokenMapping: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Contract = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateTokenMappingResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateTokenMappingResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateTokenMappingResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipTx(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0