strangelove-ventures / packet-forward-middleware Goto Github PK
View Code? Open in Web Editor NEWMiddleware for forwarding IBC packets
License: MIT License
Middleware for forwarding IBC packets
License: MIT License
In case of giving an unsupported destination address for the destination chain, the packet forwarder is not able to revert the tx. And the transferred amount is getting lost. This should be handled. I did not find any other failure cases so far.
Note - Though if you give the wrong channel-id for the middle chain, it is successfully reverting the tx, and giving tokens back to the sender address in the first chain.
The actual destination address is osmo1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq, but if you give xyz1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq - tokens will be lost.
quasarnoded --home run/quasar/home/ --node=http://localhost:26659/ --chain-id quasar tx --from alice ibc-transfer transfer transfer channel-1 "cosmos1ppkxa0hxak05tcqq3338k76xqxy2qse96uelcu|transfer/channel-1:xyz1t8eh66t2w5k67kwurmn5gqhtq6d2ja0vp7jmmq" 10ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9
In this case - 10ibc/C4CFF46FD6DE35CA4CF4CE031E643C8FDC9BA4B99AE598E9B0ED98FE3A2319F9 will get lost.
The detailed demo can be found for the successful case - https://github.com/quasar-finance/quasar/tree/main/demos/packet-forwarder
PR incoming
When forwarding tokens from EVM-based chains, which use 10^18
denom, it causes an overflow in the middleware
The issue happens on float32(token.Amount.Int64()),
Apr 27 10:52:42 ip-172-31-17-38 rly[376272]: ts=2023-04-27T10:52:42.781136Z lvl=error msg="Error broadcasting packet message" src_chain_id=evmos_9000-4 dst_chain_id=35-C src_client_id=07-tendermint-85 dst_client_id=07-tendermint-18 msgError="unsupported value type" error="rpc error: code = Unknown desc = rpc error: code = Unknown desc = recovered: Int64() out of bound\nstack:\ngoroutine 8744021819 [running]:\nruntime/debug.Stack()\n\truntime/debug/stack.go:24 +0x65\ngithub.com/cosmos/cosmos-sdk/baseapp.newDefaultRecoveryMiddleware.func1({0x1cb0660, 0x2b75ce0})\n\tgithub.com/cosmos/[email protected]/baseapp/recovery.go:71 +0x27\ngithub.com/cosmos/cosmos-sdk/baseapp.newRecoveryMiddleware.func1({0x1cb0660?, 0x2b75ce0?})\n\tgithub.com/cosmos/[email protected]/baseapp/recovery.go:39 +0x30\ngithub.com/cosmos/cosmos-sdk/baseapp.processRecovery({0x1cb0660, 0x2b75ce0}, 0xc02d17cb40?)\n\tgithub.com/cosmos/[email protected]/baseapp/recovery.go:28 +0x37\ngithub.com/cosmos/cosmos-sdk/baseapp.processRecovery({0x1cb0660, 0x2b75ce0}, 0x2ba8d60?)\n\tgithub.com/cosmos/[email protected]/baseapp/recovery.go:33 +0x5e\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).runTx.func1()\n\tgithub.com/cosmos/[email protected]/baseapp/baseapp.go:632 +0xfd\npanic({0x1cb0660, 0x2b75ce0})\n\truntime/panic.go:838 +0x207\ngithub.com/cosmos/cosmos-sdk/types.Int.Int64({0xdf9f66?})\n\tgithub.com/cosmos/[email protected]/types/int.go:162 +0x86\ngithub.com/strangelove-ventures/packet-forward-middleware/v3/router/keeper.Keeper.ForwardTransferPacket.func1()\n\tgithub.com/strangelove-ventures/packet-forward-middleware/[email protected]/router/keeper/keeper.go:291 +0x5f\ngithub.com/strangelove-ventures/packet-forward-middleware/v3/router/keeper.Keeper.ForwardTransferPacket({{0x2b82558, 0xc0014265f0}, {0x2ba7260, 0xc000253eb0}, {{0x2ba7260, 0xc000253eb0}, 0xc00012a590, {0x2b82558, 0xc001426550}, {0x2b825a8, ...}, ...}, ...}, ...)\n\tgithub.com/strangelove-ventures/packet-forward-middleware/[email protected]/router/keeper/keeper.go:301 +0x1046\ngithub.com/strangelove-ventures/packet-forward-middleware/v3/router.AppModule.OnRecvPacket({{}, {{0x2b82558, 0xc0014265f0}, {0x2ba7260, 0xc000253eb0}, {{0x2ba7260, 0xc000253eb0}, 0xc00012a590, {0x2b82558, 0xc001426550}, ...}, ...}, ...}, ...)\n\tgithub.com/strangelove-ventures/packet-forward-middleware/[email protected]/router/module.go:306 +0xadb\ngithub.com/cosmos/ibc-go/v3/modules/core/keeper.Keeper.RecvPacket({{0x0, 0x0}, {0x2ba7260, 0xc000253eb0}, {{0x2b82558, 0xc001426560}, {0x2ba7260, 0xc000253eb0}, {{0x2ba7260, 0xc000253eb0}, ...}, ...}, ...}, ...)\n\tgithub.com/cosmos/ibc-go/[email protected]/modules/core/keeper/msg_server.go:412 +0x955\ngithub.com/cosmos/ibc-go/v3/modules/core/04-channel/types._Msg_RecvPacket_Handler.func1({0x2b9af48, 0xc141c10f90}, {0x1f63600?, 0xc0002554a0})\n\tgithub.com/cosmos/ibc-go/[email protected]/modules/core/04-channel/types/tx.pb.go:1323 +0x78\ngithub.com/cosmos/cosmos-sdk/baseapp.(*MsgServiceRouter).RegisterService.func2.1({0x2b9af48, 0xc141c10f60}, {0x4c0ca6?, 0x41198b?}, 0x1ff1e60?, 0xc0e72c2270)\n\tgithub.com/cosmos/[email protected]/baseapp/msg_service_router.go:113 +0xdb\ngithub.com/cosmos/ibc-go/v3/modules/core/04-channel/types._Msg_RecvPacket_Handler({0x1fe6220?, 0xc001007680}, {0x2b9af48, 0xc141c10f60}, 0x290b518, 0xc098dc6800)\n\tgithub.com/cosmos/ibc-go/[email protected]/modules/core/04-channel/types/tx.pb.go:1325 +0x138\ngithub.com/cosmos/cosmos-sdk/baseapp.(*MsgServiceRouter).RegisterService.func2({{0x2b9aed8, 0xc00012e000}, {0x2ba8d60, 0xc02d164c80}, {{0xb, 0x0}, {0xc1450412fc, 0x4}, 0xff9bd, {0x24f5967d, ...}, ...}, ...}, ...)\n\tgithub.com/cosmos/[email protected]/baseapp/msg_service_router.go:126 +0x3d0\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).runMsgs(_, {{0x2b9aed8, 0xc00012e000}, {0x2ba8d60, 0xc02d164c80}, {{0xb, 0x0}, {0xc1450412fc, 0x4}, 0xff9bd, ...}, ...}, ...)\n\tgithub.com/cosmos/[email protected]/baseapp/baseapp.go:760 +0x5c5\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).runTx(0xc000dcc380, 0x2, {0xc02d13e000, 0x1e2a, 0x1e2a})\n\tgithub.com/cosmos/[email protected]/baseapp/baseapp.go:717 +0xd0c\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).Simulate(0x414307?, {0xc02d13e000?, 0x1e34be0?, 0x2b7e001?})\n\tgithub.com/cosmos/[email protected]/baseapp/test_helpers.go:23 +0x2c\ngithub.com/cosmos/cosmos-sdk/x/auth/tx.txServer.Simulate({{{0x0, 0x0, 0x0}, {0x2bb0da8, 0xc004b597e0}, {0xc000d35c98, 0x4}, {0x2b9f520, 0xc000253eb0}, {0x2bab3c8, ...}, ...}, ...}, ...)\n\tgithub.com/cosmos/[email protected]/x/auth/tx/service.go:120 +0x12e\ngithub.com/cosmos/cosmos-sdk/types/tx._Service_Simulate_Handler({0x1ee5440?, 0xc004f029c0}, {0x2b9af48, 0xc0fd770240}, 0xc159602910, 0x0)\n\tgithub.com/cosmos/[email protected]/types/tx/service.pb.go:910 +0x170\ngithub.com/cosmos/cosmos-sdk/baseapp.(*GRPCQueryRouter).RegisterService.func1({{0x2b9aed8, 0xc00012e000}, {0x2ba8d60, 0xc02d136600}, {{0xb, 0x0}, {0xc1450412fc, 0x4}, 0xff9bd, {0x24f5967d, ...}, ...}, ...}, ...)\n\tgithub.com/cosmos/[email protected]/baseapp/grpcrouter.go:85 +0x22d\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).handleQueryGRPC(0xc000dcc380, 0xc004f521e0, {{0xc02d154000, 0x1e2d, 0x4000}, {0xc1ed5928d0, 0x23}, 0xff9bd, 0x0})\n\tgithub.com/cosmos/[email protected]/baseapp/abci.go:583 +0x1cf\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).Query(0xc000dcc380, {{0xc02d154000, 0x1e2d, 0x4000}, {0xc1ed5928d0, 0x23}, 0xff9bd, 0x0})\n\tgithub.com/cosmos/[email protected]/baseapp/abci.go:427 +0x77d\ngithub.com/tendermint/tendermint/abci/client.(*localClient).QuerySync(0xc00024f320, {{0xc02d154000, 0x1e2d, 0x4000}, {0xc1ed5928d0, 0x23}, 0x0, 0x0})\n\tgithub.com/tendermint/[email protected]/abci/client/local_client.go:256 +0x171\ngithub.com/tendermint/tendermint/proxy.(*appConnQuery).QuerySync(0x2?, {{0xc02d154000, 0x1e2d, 0x4000}, {0xc1ed5928d0, 0x23}, 0x0, 0x0})\n\tgithub.com/tendermint/[email protected]/proxy/app_conn.go:159 +0x6e\ngithub.com/tendermint/tendermint/rpc/core.ABCIQuery(0x8?, {0xc1ed5928d0?, 0xc00019c780?}, {0xc02d154000?, 0x4?, 0xc00de26280?}, 0x2?, 0xb9?)\n\tgithub.com/tendermint/[email protected]/rpc/core/abci.go:20 +0xa6\nreflect.Value.call({0x1d86180?, 0x290d690?, 0x80?}, {0x2004638, 0x4}, {0xc02cee8200, 0x5, 0x18?})\n\treflect/value.go:556 +0x845\nreflect.Value.Call({0x1d86180?, 0x290d690?, 0x3cad?}, {0xc02cee8200, 0x5, 0x5})\n\treflect/value.go:339 +0xbf\ngithub.com/tendermint/tendermint/rpc/jsonrpc/server.makeJSONRPCHandler.func1({0x2b99240, 0xc0ebd3d2d8}, 0xc02ceeac00)\n\tgithub.com/tendermint/[email protected]/rpc/jsonrpc/server/http_json_handler.go:96 +0x1075\ngithub.com/tendermint/tendermint/rpc/jsonrpc/server.handleInvalidJSONRPCPaths.func1({0x2b99240?, 0xc0ebd3d2d8?}, 0x0?)\n\tgithub.com/tendermint/[email protected]/rpc/jsonrpc/server/http_json_handler.go:122 +0x5d\nnet/http.HandlerFunc.ServeHTTP(0x0?, {0x2b99240?, 0xc0ebd3d2d8?}, 0x54e2c8?)\n\tnet/http/server.go:2084 +0x2f\nnet/http.(*ServeMux).ServeHTTP(0xc000012540?, {0x2b99240, 0xc0ebd3d2d8}, 0xc02ceeac00)\n\tnet/http/server.go:2462 +0x149\ngithub.com/rs/cors.(*Cors).Handler.func1({0x2b99240, 0xc0ebd3d2d8}, 0xc02ceeac00)\n\tgithub.com/rs/[email protected]/cors.go:231 +0x1c4\nnet/http.HandlerFunc.ServeHTTP(0x160?, {0x2b99240?, 0xc0ebd3d2d8?}, 0x0?)\n\tnet/http/server.go:2084 +0x2f\ngithub.com/tendermint/tendermint/rpc/jsonrpc/server.maxBytesHandler.ServeHTTP({{0x2b81280?, 0xc004b59280?}, 0x414307?}, {0x2b99240?, 0xc0ebd3d2d8}, 0xc02ceeac00)\n\tgithub.com/tendermint/[email protected]/rpc/jsonrpc/server/http_server.go:238 +0x122\ngithub.com/tendermint/tendermint/rpc/jsonrpc/server.RecoverAndLogHandler.func1({0x2b99ba0?, 0xc021775880}, 0xc02ceeac00)\n\tgithub.com/tendermint/[email protected]/rpc/jsonrpc/server/http_server.go:211 +0x37f\nnet/http.HandlerFunc.ServeHTTP(0x0?, {0x2b99ba0?, 0xc021775880?}, 0x413fa5?)\n\tnet/http/server.go:2084 +0x2f\nnet/http.serverHandler.ServeHTTP({0x2b83f98?}, {0x2b99ba0, 0xc021775880}, 0xc02ceeac00)\n\tnet/http/server.go:2916 +0x43b\nnet/http.(*conn).serve(0xc183bd6b40, {0x2b9af48, 0xc004e94210})\n\tnet/http/server.go:1966 +0x5d7\ncreated by net/http.(*Server).Serve\n\tnet/http/server.go:3071 +0x4db\n: panic [cosmos/[email protected]/baseapp/recovery.go:69] With gas wanted: '0' and gas used: '274653' : unknown request"
Packet forward middleware should be added to ibc-apps with an accompanying sim app (to be created, can reference implementations such as noble, juno, osmosis) and interchaintest case
Hi @jtieri , i think go requires that module name in go.sum should be
module github.com/strangelove-ventures/packet-forward-middleware/v2
in order to import it by gaia or other app as tag v2.1.0?
packet-forward-middleware/go.mod
Line 3 in 2c91784
if this is true, all the self import should also add v2
like "github.com/strangelove-ventures/packet-forward-middleware/v2/router/client/cli"
sorry for this, i should have added in the pr. but please let me know if it is still possible that i can import v2.1.0 so that we do not need to make the change as above mentioned?
@jtieri @jackzampolin
Steps of replication :
Hermes version : 0.10.0
Packet-forward-middleware version : v1.0.1
Gaia version : 6.0.0
Sending ibc token back from C to B and then from B to A works.
Also, the logs do not provide sufficient information for the same.
go get github.com/strangelove-ventures/packet-forward-middleware/v7@main
go: downloading github.com/strangelove-ventures/packet-forward-middleware v1.0.2-0.20220314155821-2c91784afc35
go: downloading github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230321175727-de5b28b4b6ca
go: added github.com/strangelove-ventures/packet-forward-middleware/v7 v7.0.0-20230321175727-de5b28b4b6ca
I think I can find it and make a PR
module needs to be updated to v0.46 for Rho upgrade.
current work in cosmos/gaia#1436 blocked by this.
IG hub team will try updating but might need support
As IBC Apps maintainers
We should archive this repo (or at the very least we should point users to the new repo) so we can start migrating users and that new issues/PRs are opened up over there.
We want to centralize all PMF work and meta (ie, Issue) in ibc-apps
ibc-apps
(as separate from, say, ICQ issues)For next cosmoshub v07-Theta upgrade:
we need packet-forward-middleware
to bump to depend on cosmos-sdk0.45.1 or cosmos-sdk0.46 if cosmos-sdk 0.46 will be released much earlier before end of March.
Thank you!
When a multi-hop IBC transfer takes place there's a chance that the second hop fails. If that's the case the tokens are returned to the sending chain. In a multi-hop scenario this is not always the original sending chain. That means that a user has to find which chain their assets landed on, and hope that the chain they landed on was using an address they control. This is part of the multihop design, that users designate an address on each chain that they control in order to remain in control of the funds should the multi-hop transfer fail.
Create an escrow module on each chain that is used to hold the tokens and record who the original sender was. When a transfer hop fails it is sent back to this escrow module and correlated to the original sender. In this scenario anyone can execute a "return-to-sender" message, not just the original sender who has to find their stalled transfer. Also this decreases the chance that the original sender accidentally uses an address they don't control (or keeps them from having to create an account they control in the first place).
router
is used in a few different contexts across modules/in the SDK so perhaps renaming to ibcrouter
would be less confusing
Context: This is something that arose when I was asked to review and help out the gaia team with debugging an upgrade handler. I reviewed a lot of the app
configuration code in the gaia repo and came to find that the transfer keeper is misconfigured to bypass the router
module on SendPacket
.
For an IBC application stack composed of transfer
and router
there is two distinct flows. For the sake of simplicity let's reduce this to inbound and outbound packet flows. i.e. RecvPacket
and SendPacket
.
In gaia number 1 holds true due to the wrapping of the transfer module and correctly binding it using the ibc router.
However, number 2 does not respect the expected flow above, as the transfer keeper is misconfigured for the ICS4Wrapper
argument here. When a user sends an ibc MsgTransfer
, it will call into SendPacket
on the ICS4Wrapper
, and with its current configuration it bypasses the router
module completely, and is calling directly into ibc core's channel keeper.
At the moment this is technically fine, as the router
module doesn't implement any logic on SendPacket
. However, the issue becomes apparent when trying to compose an application with more middlewares (e.g. 29-fee
). Consider an application stack of transfer -> router -> fee. The fee middleware module does implement logic on SendPacket
so bypassing it would cause some very strange issues.
Currently there is only a type assertion for router
to implement the IBCModule
interface.
The router
module should implement the IBCMiddleware
interface and allow the RouterKeeper
to be passed to NewTransferKeeper
as the ICS4Wrapper
argument.
This will allow ibc application stacks including the router
module to be configured correctly, and adhere to the conventional flows.
The ibc transfer keeper can be configured like so:
appKeepers.TransferKeeper = ibctransferkeeper.NewKeeper(
appCodec,
appKeepers.keys[ibctransfertypes.StoreKey],
appKeepers.GetSubspace(ibctransfertypes.ModuleName),
- appKeepers.IBCKeeper.ChannelKeeper,
+ appKeepers.RouterKeeper,
appKeepers.IBCKeeper.ChannelKeeper,
&appKeepers.IBCKeeper.PortKeeper,
appKeepers.AccountKeeper,
appKeepers.BankKeeper,
appKeepers.ScopedTransferKeeper,
)
Summarizing here from my discussion about this with @agouin:
Right now the memo field is defined as a string and thus needs to be escaped if it includes json:
"next" : "\{
\"forward\":\{
\"receiver\":\"chain-d-bech32-address\",
\"port\":\"transfer\",
\"channel\":\"channel-234\",
\"timeout\":\"10m\",
\"retries\":2
\}
\}"
If a message contains many nested forward messages, then the size of the message will grow exponentially on the size of the nesting (as the escape characters also need to be escaped).
This was designed as a string to accommodate any memo that IBC allows (as it's defined as a string in the spec). Since the memo is getting standarized as a json object, the PFM should support native json as the memo field.
The solution to support both custom use cases and best-practice use cases is to "add a type detection to allow both passthrough strings as now or marshaling json in the case it's an object".
Hello, what is planned fix for https://github.com/SCV-Security/responsible-disclosures/blob/main/SCV%20-%20Responsible%20Disclosure%20-%20PFM%20and%20IBC-hooks.pdf ?
I though of all fixes I can do in contract with all data available, the only fix CW developer can do is signed token inside packet, but without ZK this is dead end for IBCing high gas cost chains with different signature schemes.
Planned fix would help to write code the way anticipating that fix to happen.
Thank you
Hey team,
I wanted to ask about the status of the project - is it being actively worked on? Or was it abandoned? Is the packer router idea on Cosmos Hub going to be realized? Thanks for the response.
It would be convenient if we had a stripped down chain binary that includes the packet-forward-middleware so that we can use it for testing
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.