diff --git a/CHANGELOG.md b/CHANGELOG.md index 77c018fcd1..3b55981571 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * [#1394](https://github.com/crypto-org-chain/cronos/pull/1394) Add icahost wirings but disable in parameters. * [#1407](https://github.com/crypto-org-chain/cronos/pull/1407) Add end-to-end encryption module. * [#1414](https://github.com/crypto-org-chain/cronos/pull/1414) Integrate new evm tx format. +* [#1458](https://github.com/crypto-org-chain/cronos/pull/1458) Adjust require gas for recvPacket when ReceiverChainIsSource. ### Improvements diff --git a/integration_tests/configs/ibc.jsonnet b/integration_tests/configs/ibc.jsonnet index 2501cf43d7..2f672f850f 100644 --- a/integration_tests/configs/ibc.jsonnet +++ b/integration_tests/configs/ibc.jsonnet @@ -12,7 +12,7 @@ config { name: 'user' + i, coins: '30000000000000000000000basetcro', } - for i in std.range(1, 2) + for i in std.range(1, 50) ], 'app-config'+: { 'index-events': super['index-events'] + ['message.action'], @@ -87,7 +87,7 @@ config { name: 'user' + i, coins: '10000000000000cro', } - for i in std.range(1, 2) + for i in std.range(1, 50) ], genesis: { app_state: { diff --git a/integration_tests/ibc_utils.py b/integration_tests/ibc_utils.py index af6a293cbc..3f0c7f8775 100644 --- a/integration_tests/ibc_utils.py +++ b/integration_tests/ibc_utils.py @@ -173,6 +173,17 @@ def prepare_network( version = {"fee_version": "ics29-1", "app_version": "ics20-1"} path = cronos.base_dir.parent / "relayer" + w3 = cronos.w3 + acc = derive_new_account(2) + sender = acc.address + # fund new sender to deploy contract with same address + if w3.eth.get_balance(sender, "latest") == 0: + fund = 3000000000000000000 + tx = {"to": sender, "value": fund, "gasPrice": w3.eth.gas_price} + send_transaction(w3, tx) + assert w3.eth.get_balance(sender, "latest") == fund + caller = deploy_contract(w3, CONTRACTS["TestRelayer"], key=acc.key).address + assert caller == RELAYER_CALLER, caller if is_hermes: hermes = Hermes(path.with_suffix(".toml")) call_hermes_cmd( @@ -182,17 +193,6 @@ def prepare_network( version, ) else: - w3 = cronos.w3 - acc = derive_new_account(2) - sender = acc.address - # fund new sender to deploy contract with same address - if w3.eth.get_balance(sender, "latest") == 0: - fund = 3000000000000000000 - tx = {"to": sender, "value": fund, "gasPrice": w3.eth.gas_price} - send_transaction(w3, tx) - assert w3.eth.get_balance(sender, "latest") == fund - caller = deploy_contract(w3, CONTRACTS["TestRelayer"], key=acc.key).address - assert caller == RELAYER_CALLER, caller call_rly_cmd(path, connection_only, version) if incentivized: @@ -347,7 +347,7 @@ def get_balances(chain, addr): def ibc_multi_transfer(ibc): chains = [ibc.cronos.cosmos_cli(), ibc.chainmain.cosmos_cli()] # FIXME: more users after batch fix - users = [f"user{i}" for i in range(1, 2)] + users = [f"user{i}" for i in range(1, 51)] addrs0 = [chains[0].address(user) for user in users] addrs1 = [chains[1].address(user) for user in users] denom0 = "basetcro" diff --git a/nix/sources.json b/nix/sources.json index fa998d2a51..cf8c702200 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -126,10 +126,10 @@ "homepage": "https://github.com/crypto-org-chain/relayer", "owner": "crypto-org-chain", "repo": "relayer", - "rev": "1dccb3471485c7e323a913b2604d3dab399ed505", - "sha256": "075a8vxn8nxdr80gnk5g6vn5s2c4i7nky7pr3vmm9nphbz0a98mx", + "rev": "fe5722292a9961e80818e3ef5c987330b538bc05", + "sha256": "0jv4pkrqhckbabxxxbr0bcil0fakbnc7sf22k2wa5q6v6921ci0y", "type": "tarball", - "url": "https://github.com/crypto-org-chain/relayer/archive/1dccb3471485c7e323a913b2604d3dab399ed505.tar.gz", + "url": "https://github.com/crypto-org-chain/relayer/archive/fe5722292a9961e80818e3ef5c987330b538bc05.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } diff --git a/x/cronos/keeper/precompiles/relayer.go b/x/cronos/keeper/precompiles/relayer.go index 895d277333..8bbcad970c 100644 --- a/x/cronos/keeper/precompiles/relayer.go +++ b/x/cronos/keeper/precompiles/relayer.go @@ -13,6 +13,8 @@ import ( "github.com/ethereum/go-ethereum/params" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" cronosevents "github.com/crypto-org-chain/cronos/v2/x/cronos/events" "github.com/crypto-org-chain/cronos/v2/x/cronos/events/bindings/cosmos/precompile/relayer" "github.com/crypto-org-chain/cronos/v2/x/cronos/types" @@ -26,38 +28,27 @@ var ( ) const ( - CreateClient = "createClient" - UpdateClient = "updateClient" - UpgradeClient = "upgradeClient" - SubmitMisbehaviour = "submitMisbehaviour" - ConnectionOpenInit = "connectionOpenInit" - ConnectionOpenTry = "connectionOpenTry" - ConnectionOpenAck = "connectionOpenAck" - ConnectionOpenConfirm = "connectionOpenConfirm" - ChannelOpenInit = "channelOpenInit" - ChannelOpenTry = "channelOpenTry" - ChannelOpenAck = "channelOpenAck" - ChannelOpenConfirm = "channelOpenConfirm" - ChannelCloseInit = "channelCloseInit" - ChannelCloseConfirm = "channelCloseConfirm" - RecvPacket = "recvPacket" - Acknowledgement = "acknowledgement" - Timeout = "timeout" - TimeoutOnClose = "timeoutOnClose" - UpdateClientAndConnectionOpenInit = "updateClientAndConnectionOpenInit" - UpdateClientAndConnectionOpenTry = "updateClientAndConnectionOpenTry" - UpdateClientAndConnectionOpenAck = "updateClientAndConnectionOpenAck" - UpdateClientAndConnectionOpenConfirm = "updateClientAndConnectionOpenConfirm" - UpdateClientAndChannelOpenInit = "updateClientAndChannelOpenInit" - UpdateClientAndChannelOpenTry = "updateClientAndChannelOpenTry" - UpdateClientAndChannelOpenAck = "updateClientAndChannelOpenAck" - UpdateClientAndChannelCloseInit = "updateClientAndChannelCloseInit" - UpdateClientAndChannelCloseConfirm = "updateClientAndChannelCloseConfirm" - UpdateClientAndChannelOpenConfirm = "updateClientAndChannelOpenConfirm" - UpdateClientAndRecvPacket = "updateClientAndRecvPacket" - UpdateClientAndAcknowledgement = "updateClientAndAcknowledgement" - UpdateClientAndTimeout = "updateClientAndTimeout" - UpdateClientAndTimeoutOnClose = "updateClientAndTimeoutOnClose" + CreateClient = "createClient" + UpdateClient = "updateClient" + UpgradeClient = "upgradeClient" + SubmitMisbehaviour = "submitMisbehaviour" + ConnectionOpenInit = "connectionOpenInit" + ConnectionOpenTry = "connectionOpenTry" + ConnectionOpenAck = "connectionOpenAck" + ConnectionOpenConfirm = "connectionOpenConfirm" + ChannelOpenInit = "channelOpenInit" + ChannelOpenTry = "channelOpenTry" + ChannelOpenAck = "channelOpenAck" + ChannelOpenConfirm = "channelOpenConfirm" + ChannelCloseInit = "channelCloseInit" + ChannelCloseConfirm = "channelCloseConfirm" + RecvPacket = "recvPacket" + Acknowledgement = "acknowledgement" + Timeout = "timeout" + TimeoutOnClose = "timeoutOnClose" + + GasWhenReceiverChainIsSource = 51705 + GasWhenReceiverChainIsNotSource = 144025 ) func init() { @@ -93,35 +84,11 @@ func init() { case ChannelCloseConfirm: relayerGasRequiredByMethod[methodID] = 31199 case RecvPacket: - relayerGasRequiredByMethod[methodID] = 144025 + relayerGasRequiredByMethod[methodID] = GasWhenReceiverChainIsNotSource case Acknowledgement: relayerGasRequiredByMethod[methodID] = 61781 case Timeout: relayerGasRequiredByMethod[methodID] = 104283 - case UpdateClientAndConnectionOpenTry: - relayerGasRequiredByMethod[methodID] = 150362 - case UpdateClientAndConnectionOpenConfirm: - relayerGasRequiredByMethod[methodID] = 124820 - case UpdateClientAndChannelOpenTry: - relayerGasRequiredByMethod[methodID] = 182676 - case UpdateClientAndChannelOpenConfirm: - relayerGasRequiredByMethod[methodID] = 132734 - case UpdateClientAndRecvPacket: - relayerGasRequiredByMethod[methodID] = 257120 - case UpdateClientAndConnectionOpenInit: - relayerGasRequiredByMethod[methodID] = 131649 - case UpdateClientAndConnectionOpenAck: - relayerGasRequiredByMethod[methodID] = 141558 - case UpdateClientAndChannelOpenInit: - relayerGasRequiredByMethod[methodID] = 180815 - case UpdateClientAndChannelOpenAck: - relayerGasRequiredByMethod[methodID] = 133834 - case UpdateClientAndChannelCloseConfirm: - relayerGasRequiredByMethod[methodID] = 143366 - case UpdateClientAndTimeout: - relayerGasRequiredByMethod[methodID] = 230638 - case UpdateClientAndAcknowledgement: - relayerGasRequiredByMethod[methodID] = 174785 default: relayerGasRequiredByMethod[methodID] = 100000 } @@ -165,6 +132,28 @@ func (bc *RelayerContract) RequiredGas(input []byte) (gas uint64) { var methodID [4]byte copy(methodID[:], input[:4]) requiredGas, ok := relayerGasRequiredByMethod[methodID] + method, err := irelayerABI.MethodById(methodID[:]) + if err != nil { + panic(err) + } + if method.Name == RecvPacket { + args, err := method.Inputs.Unpack(input[4:]) + if err != nil { + panic(err) + } + i := args[0].([]byte) + var msg channeltypes.MsgRecvPacket + if err = bc.cdc.Unmarshal(i, &msg); err != nil { + panic(err) + } + var data ibctransfertypes.FungibleTokenPacketData + if err = ibctransfertypes.ModuleCdc.UnmarshalJSON(msg.Packet.GetData(), &data); err != nil { + panic(err) + } + if ibctransfertypes.ReceiverChainIsSource(msg.Packet.GetSourcePort(), msg.Packet.GetSourceChannel(), data.Denom) { + requiredGas = GasWhenReceiverChainIsSource + } + } intrinsicGas, _ := core.IntrinsicGas(input, nil, false, bc.isHomestead, bc.isIstanbul, bc.isShanghai) defer func() { methodName := relayerMethodNamedByMethod[methodID] @@ -211,9 +200,6 @@ func (bc *RelayerContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool input: input, converter: converter, } - if len(args) > 1 { - e.input2 = args[1].([]byte) - } switch method.Name { case CreateClient: res, err = exec(e, bc.ibcKeeper.CreateClient) @@ -249,34 +235,6 @@ func (bc *RelayerContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool res, err = exec(e, bc.ibcKeeper.Timeout) case TimeoutOnClose: res, err = exec(e, bc.ibcKeeper.TimeoutOnClose) - case UpdateClientAndConnectionOpenInit: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ConnectionOpenInit) - case UpdateClientAndConnectionOpenTry: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ConnectionOpenTry) - case UpdateClientAndConnectionOpenAck: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ConnectionOpenAck) - case UpdateClientAndConnectionOpenConfirm: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ConnectionOpenConfirm) - case UpdateClientAndChannelOpenInit: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelOpenInit) - case UpdateClientAndChannelOpenTry: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelOpenTry) - case UpdateClientAndChannelCloseInit: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelCloseInit) - case UpdateClientAndChannelCloseConfirm: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelCloseConfirm) - case UpdateClientAndChannelOpenAck: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelOpenAck) - case UpdateClientAndChannelOpenConfirm: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelOpenConfirm) - case UpdateClientAndRecvPacket: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.RecvPacket) - case UpdateClientAndAcknowledgement: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.Acknowledgement) - case UpdateClientAndTimeout: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.Timeout) - case UpdateClientAndTimeoutOnClose: - res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.TimeoutOnClose) default: return nil, fmt.Errorf("unknown method: %s", method.Name) } diff --git a/x/cronos/keeper/precompiles/utils.go b/x/cronos/keeper/precompiles/utils.go index 2501663456..bed2fbc019 100644 --- a/x/cronos/keeper/precompiles/utils.go +++ b/x/cronos/keeper/precompiles/utils.go @@ -23,7 +23,6 @@ type Executor struct { caller common.Address contract common.Address input []byte - input2 []byte converter statedb.EventConverter } @@ -64,78 +63,3 @@ func exec[Req any, PReq interface { } return output, nil } - -func execMultipleWithHooks[Req any, - PReq interface { - *Req - NativeMessage - }, - Resp proto.Message, - Req2 any, - PReq2 interface { - *Req2 - NativeMessage - }, - Resp2 proto.Message, -]( - e *Executor, - preAction func(sdk.Context, PReq, PReq2) error, - action func(context.Context, PReq) (Resp, error), - action2 func(context.Context, PReq2) (Resp2, error), -) ([]byte, error) { - msg := PReq(new(Req)) - if err := e.cdc.Unmarshal(e.input, msg); err != nil { - return nil, fmt.Errorf("fail to Unmarshal %T %w", msg, err) - } - - msg2 := PReq2(new(Req2)) - if err := e.cdc.Unmarshal(e.input2, msg2); err != nil { - return nil, fmt.Errorf("fail to Unmarshal %T %w", msg2, err) - } - - signers := msg.GetSigners() - if len(signers) != 1 { - return nil, fmt.Errorf("expected 1 signer, got %d", len(signers)) - } - if common.BytesToAddress(signers[0].Bytes()) != e.caller { - return nil, errors.New("caller is not authenticated") - } - - var res Resp - if err := e.stateDB.ExecuteNativeAction(e.contract, e.converter, func(ctx sdk.Context) (err error) { - if preAction != nil { - if err = preAction(ctx, msg, msg2); err != nil { - return err - } - } - - res, err = action(ctx, msg) - if err == nil && len(e.input2) > 0 { - _, err = action2(ctx, msg2) - } - return - }); err != nil { - return nil, err - } - return e.cdc.Marshal(res) -} - -func execMultiple[Req any, - PReq interface { - *Req - NativeMessage - }, - Resp proto.Message, - Req2 any, - PReq2 interface { - *Req2 - NativeMessage - }, - Resp2 proto.Message, -]( - e *Executor, - action func(context.Context, PReq) (Resp, error), - action2 func(context.Context, PReq2) (Resp2, error), -) ([]byte, error) { - return execMultipleWithHooks(e, nil, action, action2) -}