Skip to content

Commit

Permalink
Problem: require gas in RecvPacket is inaccurate when ReceiverChainIs…
Browse files Browse the repository at this point in the history
…Source (crypto-org-chain#1458)

* Problem: require gas in RecvPacket is inaccurate when ReceiverChainIsSource

* cleanup combo

* set relayer caller for hermes

* more users
  • Loading branch information
mmsqe authored and alienc0der committed Jun 8, 2024
1 parent 41f6163 commit 27923a9
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 181 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions integration_tests/configs/ibc.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand Down Expand Up @@ -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: {
Expand Down
24 changes: 12 additions & 12 deletions integration_tests/ibc_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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:
Expand Down Expand Up @@ -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"
Expand Down
6 changes: 3 additions & 3 deletions nix/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -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/<owner>/<repo>/archive/<rev>.tar.gz"
}
}
134 changes: 46 additions & 88 deletions x/cronos/keeper/precompiles/relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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() {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
Expand Down
76 changes: 0 additions & 76 deletions x/cronos/keeper/precompiles/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ type Executor struct {
caller common.Address
contract common.Address
input []byte
input2 []byte
converter statedb.EventConverter
}

Expand Down Expand Up @@ -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)
}

0 comments on commit 27923a9

Please sign in to comment.