Skip to content

Commit 6fe4612

Browse files
authored
Problem: require gas in RecvPacket is inaccurate when ReceiverChainIsSource (#1458)
* Problem: require gas in RecvPacket is inaccurate when ReceiverChainIsSource * cleanup combo * set relayer caller for hermes * more users
1 parent b2a47a2 commit 6fe4612

File tree

6 files changed

+64
-181
lines changed

6 files changed

+64
-181
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* [#1394](https://github.com/crypto-org-chain/cronos/pull/1394) Add icahost wirings but disable in parameters.
99
* [#1407](https://github.com/crypto-org-chain/cronos/pull/1407) Add end-to-end encryption module.
1010
* [#1414](https://github.com/crypto-org-chain/cronos/pull/1414) Integrate new evm tx format.
11+
* [#1458](https://github.com/crypto-org-chain/cronos/pull/1458) Adjust require gas for recvPacket when ReceiverChainIsSource.
1112

1213
### Improvements
1314

integration_tests/configs/ibc.jsonnet

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ config {
1212
name: 'user' + i,
1313
coins: '30000000000000000000000basetcro',
1414
}
15-
for i in std.range(1, 2)
15+
for i in std.range(1, 50)
1616
],
1717
'app-config'+: {
1818
'index-events': super['index-events'] + ['message.action'],
@@ -87,7 +87,7 @@ config {
8787
name: 'user' + i,
8888
coins: '10000000000000cro',
8989
}
90-
for i in std.range(1, 2)
90+
for i in std.range(1, 50)
9191
],
9292
genesis: {
9393
app_state: {

integration_tests/ibc_utils.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,17 @@ def prepare_network(
173173

174174
version = {"fee_version": "ics29-1", "app_version": "ics20-1"}
175175
path = cronos.base_dir.parent / "relayer"
176+
w3 = cronos.w3
177+
acc = derive_new_account(2)
178+
sender = acc.address
179+
# fund new sender to deploy contract with same address
180+
if w3.eth.get_balance(sender, "latest") == 0:
181+
fund = 3000000000000000000
182+
tx = {"to": sender, "value": fund, "gasPrice": w3.eth.gas_price}
183+
send_transaction(w3, tx)
184+
assert w3.eth.get_balance(sender, "latest") == fund
185+
caller = deploy_contract(w3, CONTRACTS["TestRelayer"], key=acc.key).address
186+
assert caller == RELAYER_CALLER, caller
176187
if is_hermes:
177188
hermes = Hermes(path.with_suffix(".toml"))
178189
call_hermes_cmd(
@@ -182,17 +193,6 @@ def prepare_network(
182193
version,
183194
)
184195
else:
185-
w3 = cronos.w3
186-
acc = derive_new_account(2)
187-
sender = acc.address
188-
# fund new sender to deploy contract with same address
189-
if w3.eth.get_balance(sender, "latest") == 0:
190-
fund = 3000000000000000000
191-
tx = {"to": sender, "value": fund, "gasPrice": w3.eth.gas_price}
192-
send_transaction(w3, tx)
193-
assert w3.eth.get_balance(sender, "latest") == fund
194-
caller = deploy_contract(w3, CONTRACTS["TestRelayer"], key=acc.key).address
195-
assert caller == RELAYER_CALLER, caller
196196
call_rly_cmd(path, connection_only, version)
197197

198198
if incentivized:
@@ -347,7 +347,7 @@ def get_balances(chain, addr):
347347
def ibc_multi_transfer(ibc):
348348
chains = [ibc.cronos.cosmos_cli(), ibc.chainmain.cosmos_cli()]
349349
# FIXME: more users after batch fix
350-
users = [f"user{i}" for i in range(1, 2)]
350+
users = [f"user{i}" for i in range(1, 51)]
351351
addrs0 = [chains[0].address(user) for user in users]
352352
addrs1 = [chains[1].address(user) for user in users]
353353
denom0 = "basetcro"

nix/sources.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@
126126
"homepage": "https://github.com/crypto-org-chain/relayer",
127127
"owner": "crypto-org-chain",
128128
"repo": "relayer",
129-
"rev": "1dccb3471485c7e323a913b2604d3dab399ed505",
130-
"sha256": "075a8vxn8nxdr80gnk5g6vn5s2c4i7nky7pr3vmm9nphbz0a98mx",
129+
"rev": "fe5722292a9961e80818e3ef5c987330b538bc05",
130+
"sha256": "0jv4pkrqhckbabxxxbr0bcil0fakbnc7sf22k2wa5q6v6921ci0y",
131131
"type": "tarball",
132-
"url": "https://github.com/crypto-org-chain/relayer/archive/1dccb3471485c7e323a913b2604d3dab399ed505.tar.gz",
132+
"url": "https://github.com/crypto-org-chain/relayer/archive/fe5722292a9961e80818e3ef5c987330b538bc05.tar.gz",
133133
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
134134
}
135135
}

x/cronos/keeper/precompiles/relayer.go

+46-88
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313
"github.com/ethereum/go-ethereum/params"
1414

1515
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
16+
ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
17+
channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
1618
cronosevents "github.com/crypto-org-chain/cronos/v2/x/cronos/events"
1719
"github.com/crypto-org-chain/cronos/v2/x/cronos/events/bindings/cosmos/precompile/relayer"
1820
"github.com/crypto-org-chain/cronos/v2/x/cronos/types"
@@ -26,38 +28,27 @@ var (
2628
)
2729

2830
const (
29-
CreateClient = "createClient"
30-
UpdateClient = "updateClient"
31-
UpgradeClient = "upgradeClient"
32-
SubmitMisbehaviour = "submitMisbehaviour"
33-
ConnectionOpenInit = "connectionOpenInit"
34-
ConnectionOpenTry = "connectionOpenTry"
35-
ConnectionOpenAck = "connectionOpenAck"
36-
ConnectionOpenConfirm = "connectionOpenConfirm"
37-
ChannelOpenInit = "channelOpenInit"
38-
ChannelOpenTry = "channelOpenTry"
39-
ChannelOpenAck = "channelOpenAck"
40-
ChannelOpenConfirm = "channelOpenConfirm"
41-
ChannelCloseInit = "channelCloseInit"
42-
ChannelCloseConfirm = "channelCloseConfirm"
43-
RecvPacket = "recvPacket"
44-
Acknowledgement = "acknowledgement"
45-
Timeout = "timeout"
46-
TimeoutOnClose = "timeoutOnClose"
47-
UpdateClientAndConnectionOpenInit = "updateClientAndConnectionOpenInit"
48-
UpdateClientAndConnectionOpenTry = "updateClientAndConnectionOpenTry"
49-
UpdateClientAndConnectionOpenAck = "updateClientAndConnectionOpenAck"
50-
UpdateClientAndConnectionOpenConfirm = "updateClientAndConnectionOpenConfirm"
51-
UpdateClientAndChannelOpenInit = "updateClientAndChannelOpenInit"
52-
UpdateClientAndChannelOpenTry = "updateClientAndChannelOpenTry"
53-
UpdateClientAndChannelOpenAck = "updateClientAndChannelOpenAck"
54-
UpdateClientAndChannelCloseInit = "updateClientAndChannelCloseInit"
55-
UpdateClientAndChannelCloseConfirm = "updateClientAndChannelCloseConfirm"
56-
UpdateClientAndChannelOpenConfirm = "updateClientAndChannelOpenConfirm"
57-
UpdateClientAndRecvPacket = "updateClientAndRecvPacket"
58-
UpdateClientAndAcknowledgement = "updateClientAndAcknowledgement"
59-
UpdateClientAndTimeout = "updateClientAndTimeout"
60-
UpdateClientAndTimeoutOnClose = "updateClientAndTimeoutOnClose"
31+
CreateClient = "createClient"
32+
UpdateClient = "updateClient"
33+
UpgradeClient = "upgradeClient"
34+
SubmitMisbehaviour = "submitMisbehaviour"
35+
ConnectionOpenInit = "connectionOpenInit"
36+
ConnectionOpenTry = "connectionOpenTry"
37+
ConnectionOpenAck = "connectionOpenAck"
38+
ConnectionOpenConfirm = "connectionOpenConfirm"
39+
ChannelOpenInit = "channelOpenInit"
40+
ChannelOpenTry = "channelOpenTry"
41+
ChannelOpenAck = "channelOpenAck"
42+
ChannelOpenConfirm = "channelOpenConfirm"
43+
ChannelCloseInit = "channelCloseInit"
44+
ChannelCloseConfirm = "channelCloseConfirm"
45+
RecvPacket = "recvPacket"
46+
Acknowledgement = "acknowledgement"
47+
Timeout = "timeout"
48+
TimeoutOnClose = "timeoutOnClose"
49+
50+
GasWhenReceiverChainIsSource = 51705
51+
GasWhenReceiverChainIsNotSource = 144025
6152
)
6253

6354
func init() {
@@ -93,35 +84,11 @@ func init() {
9384
case ChannelCloseConfirm:
9485
relayerGasRequiredByMethod[methodID] = 31199
9586
case RecvPacket:
96-
relayerGasRequiredByMethod[methodID] = 144025
87+
relayerGasRequiredByMethod[methodID] = GasWhenReceiverChainIsNotSource
9788
case Acknowledgement:
9889
relayerGasRequiredByMethod[methodID] = 61781
9990
case Timeout:
10091
relayerGasRequiredByMethod[methodID] = 104283
101-
case UpdateClientAndConnectionOpenTry:
102-
relayerGasRequiredByMethod[methodID] = 150362
103-
case UpdateClientAndConnectionOpenConfirm:
104-
relayerGasRequiredByMethod[methodID] = 124820
105-
case UpdateClientAndChannelOpenTry:
106-
relayerGasRequiredByMethod[methodID] = 182676
107-
case UpdateClientAndChannelOpenConfirm:
108-
relayerGasRequiredByMethod[methodID] = 132734
109-
case UpdateClientAndRecvPacket:
110-
relayerGasRequiredByMethod[methodID] = 257120
111-
case UpdateClientAndConnectionOpenInit:
112-
relayerGasRequiredByMethod[methodID] = 131649
113-
case UpdateClientAndConnectionOpenAck:
114-
relayerGasRequiredByMethod[methodID] = 141558
115-
case UpdateClientAndChannelOpenInit:
116-
relayerGasRequiredByMethod[methodID] = 180815
117-
case UpdateClientAndChannelOpenAck:
118-
relayerGasRequiredByMethod[methodID] = 133834
119-
case UpdateClientAndChannelCloseConfirm:
120-
relayerGasRequiredByMethod[methodID] = 143366
121-
case UpdateClientAndTimeout:
122-
relayerGasRequiredByMethod[methodID] = 230638
123-
case UpdateClientAndAcknowledgement:
124-
relayerGasRequiredByMethod[methodID] = 174785
12592
default:
12693
relayerGasRequiredByMethod[methodID] = 100000
12794
}
@@ -165,6 +132,28 @@ func (bc *RelayerContract) RequiredGas(input []byte) (gas uint64) {
165132
var methodID [4]byte
166133
copy(methodID[:], input[:4])
167134
requiredGas, ok := relayerGasRequiredByMethod[methodID]
135+
method, err := irelayerABI.MethodById(methodID[:])
136+
if err != nil {
137+
panic(err)
138+
}
139+
if method.Name == RecvPacket {
140+
args, err := method.Inputs.Unpack(input[4:])
141+
if err != nil {
142+
panic(err)
143+
}
144+
i := args[0].([]byte)
145+
var msg channeltypes.MsgRecvPacket
146+
if err = bc.cdc.Unmarshal(i, &msg); err != nil {
147+
panic(err)
148+
}
149+
var data ibctransfertypes.FungibleTokenPacketData
150+
if err = ibctransfertypes.ModuleCdc.UnmarshalJSON(msg.Packet.GetData(), &data); err != nil {
151+
panic(err)
152+
}
153+
if ibctransfertypes.ReceiverChainIsSource(msg.Packet.GetSourcePort(), msg.Packet.GetSourceChannel(), data.Denom) {
154+
requiredGas = GasWhenReceiverChainIsSource
155+
}
156+
}
168157
intrinsicGas, _ := core.IntrinsicGas(input, nil, false, bc.isHomestead, bc.isIstanbul, bc.isShanghai)
169158
defer func() {
170159
methodName := relayerMethodNamedByMethod[methodID]
@@ -211,9 +200,6 @@ func (bc *RelayerContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool
211200
input: input,
212201
converter: converter,
213202
}
214-
if len(args) > 1 {
215-
e.input2 = args[1].([]byte)
216-
}
217203
switch method.Name {
218204
case CreateClient:
219205
res, err = exec(e, bc.ibcKeeper.CreateClient)
@@ -249,34 +235,6 @@ func (bc *RelayerContract) Run(evm *vm.EVM, contract *vm.Contract, readonly bool
249235
res, err = exec(e, bc.ibcKeeper.Timeout)
250236
case TimeoutOnClose:
251237
res, err = exec(e, bc.ibcKeeper.TimeoutOnClose)
252-
case UpdateClientAndConnectionOpenInit:
253-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ConnectionOpenInit)
254-
case UpdateClientAndConnectionOpenTry:
255-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ConnectionOpenTry)
256-
case UpdateClientAndConnectionOpenAck:
257-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ConnectionOpenAck)
258-
case UpdateClientAndConnectionOpenConfirm:
259-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ConnectionOpenConfirm)
260-
case UpdateClientAndChannelOpenInit:
261-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelOpenInit)
262-
case UpdateClientAndChannelOpenTry:
263-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelOpenTry)
264-
case UpdateClientAndChannelCloseInit:
265-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelCloseInit)
266-
case UpdateClientAndChannelCloseConfirm:
267-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelCloseConfirm)
268-
case UpdateClientAndChannelOpenAck:
269-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelOpenAck)
270-
case UpdateClientAndChannelOpenConfirm:
271-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.ChannelOpenConfirm)
272-
case UpdateClientAndRecvPacket:
273-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.RecvPacket)
274-
case UpdateClientAndAcknowledgement:
275-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.Acknowledgement)
276-
case UpdateClientAndTimeout:
277-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.Timeout)
278-
case UpdateClientAndTimeoutOnClose:
279-
res, err = execMultiple(e, bc.ibcKeeper.UpdateClient, bc.ibcKeeper.TimeoutOnClose)
280238
default:
281239
return nil, fmt.Errorf("unknown method: %s", method.Name)
282240
}

x/cronos/keeper/precompiles/utils.go

-76
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ type Executor struct {
2323
caller common.Address
2424
contract common.Address
2525
input []byte
26-
input2 []byte
2726
converter statedb.EventConverter
2827
}
2928

@@ -64,78 +63,3 @@ func exec[Req any, PReq interface {
6463
}
6564
return output, nil
6665
}
67-
68-
func execMultipleWithHooks[Req any,
69-
PReq interface {
70-
*Req
71-
NativeMessage
72-
},
73-
Resp proto.Message,
74-
Req2 any,
75-
PReq2 interface {
76-
*Req2
77-
NativeMessage
78-
},
79-
Resp2 proto.Message,
80-
](
81-
e *Executor,
82-
preAction func(sdk.Context, PReq, PReq2) error,
83-
action func(context.Context, PReq) (Resp, error),
84-
action2 func(context.Context, PReq2) (Resp2, error),
85-
) ([]byte, error) {
86-
msg := PReq(new(Req))
87-
if err := e.cdc.Unmarshal(e.input, msg); err != nil {
88-
return nil, fmt.Errorf("fail to Unmarshal %T %w", msg, err)
89-
}
90-
91-
msg2 := PReq2(new(Req2))
92-
if err := e.cdc.Unmarshal(e.input2, msg2); err != nil {
93-
return nil, fmt.Errorf("fail to Unmarshal %T %w", msg2, err)
94-
}
95-
96-
signers := msg.GetSigners()
97-
if len(signers) != 1 {
98-
return nil, fmt.Errorf("expected 1 signer, got %d", len(signers))
99-
}
100-
if common.BytesToAddress(signers[0].Bytes()) != e.caller {
101-
return nil, errors.New("caller is not authenticated")
102-
}
103-
104-
var res Resp
105-
if err := e.stateDB.ExecuteNativeAction(e.contract, e.converter, func(ctx sdk.Context) (err error) {
106-
if preAction != nil {
107-
if err = preAction(ctx, msg, msg2); err != nil {
108-
return err
109-
}
110-
}
111-
112-
res, err = action(ctx, msg)
113-
if err == nil && len(e.input2) > 0 {
114-
_, err = action2(ctx, msg2)
115-
}
116-
return
117-
}); err != nil {
118-
return nil, err
119-
}
120-
return e.cdc.Marshal(res)
121-
}
122-
123-
func execMultiple[Req any,
124-
PReq interface {
125-
*Req
126-
NativeMessage
127-
},
128-
Resp proto.Message,
129-
Req2 any,
130-
PReq2 interface {
131-
*Req2
132-
NativeMessage
133-
},
134-
Resp2 proto.Message,
135-
](
136-
e *Executor,
137-
action func(context.Context, PReq) (Resp, error),
138-
action2 func(context.Context, PReq2) (Resp2, error),
139-
) ([]byte, error) {
140-
return execMultipleWithHooks(e, nil, action, action2)
141-
}

0 commit comments

Comments
 (0)