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

Problem: require gas in RecvPacket is inaccurate when ReceiverChainIsSource #1458

Merged
merged 4 commits into from
May 28, 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
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 @@
"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 @@
)

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 @@
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 @@
var methodID [4]byte
copy(methodID[:], input[:4])
requiredGas, ok := relayerGasRequiredByMethod[methodID]
method, err := irelayerABI.MethodById(methodID[:])
if err != nil {
panic(err)

Check warning on line 137 in x/cronos/keeper/precompiles/relayer.go

View check run for this annotation

Codecov / codecov/patch

x/cronos/keeper/precompiles/relayer.go#L135-L137

Added lines #L135 - L137 were not covered by tests
}
if method.Name == RecvPacket {
args, err := method.Inputs.Unpack(input[4:])
if err != nil {
panic(err)

Check warning on line 142 in x/cronos/keeper/precompiles/relayer.go

View check run for this annotation

Codecov / codecov/patch

x/cronos/keeper/precompiles/relayer.go#L139-L142

Added lines #L139 - L142 were not covered by tests
}
i := args[0].([]byte)
var msg channeltypes.MsgRecvPacket
if err = bc.cdc.Unmarshal(i, &msg); err != nil {
panic(err)

Check warning on line 147 in x/cronos/keeper/precompiles/relayer.go

View check run for this annotation

Codecov / codecov/patch

x/cronos/keeper/precompiles/relayer.go#L144-L147

Added lines #L144 - L147 were not covered by tests
}
var data ibctransfertypes.FungibleTokenPacketData
if err = ibctransfertypes.ModuleCdc.UnmarshalJSON(msg.Packet.GetData(), &data); err != nil {
panic(err)

Check warning on line 151 in x/cronos/keeper/precompiles/relayer.go

View check run for this annotation

Codecov / codecov/patch

x/cronos/keeper/precompiles/relayer.go#L149-L151

Added lines #L149 - L151 were not covered by tests
}
if ibctransfertypes.ReceiverChainIsSource(msg.Packet.GetSourcePort(), msg.Packet.GetSourceChannel(), data.Denom) {
requiredGas = GasWhenReceiverChainIsSource

Check warning on line 154 in x/cronos/keeper/precompiles/relayer.go

View check run for this annotation

Codecov / codecov/patch

x/cronos/keeper/precompiles/relayer.go#L153-L154

Added lines #L153 - L154 were not covered by tests
}
}
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 @@
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 @@
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)
}
Loading