Port router refactor #6941
Labels
04-channel
05-port
Issues concerns the 05-port submodule
epic
type: refactor
Architecture, code or CI improvements that may or may not tackle technical debt.
Milestone
This issue was written with @damiannolan
Summary
The port router refactor should simplify core IBC's usage of the port router and application callbacks by:
Problem
Capability
The capability module is currently used for routing to application modules and was intended to provide object capability authorization, but in practice it only provides pseudo-security.
To accomplish this, it uses an in-memory mapping from port/channel keys to the application and requests that when applications wish to send a packet, it must retrieve it's in memory object and provide to core IBC, which can authenticate that the correct object was provided to send on that port.
The problem is that this is an overly complex approach. There is already a contractual assumption that modules built on the SDK are not malicious and in addition, using an in-memory map is very problematic as that map must be reloaded anytime a node starts and stops which can lead to very difficult bugs to debug.
The routing can be greatly simplified, by using a simple map which is defined on the app.go and relies solely on the port.
See related issue: #71, #3817
ICS4Wrapper
The ICS4Wrapper is currently used to allow actions to be initiated by the bottom most IBC application in an IBC stack. This functionality includes:
SendPacket
,WriteAcknowledgement
andGetAppVersion
.The problem with the ICS4Wrapper is that it is wired in reverse of the IBC stack and creates an additional conceptual model of how IBC middlewares and apps are wired, which can be difficult for devs to reason about and wire correctly. There have been several instances of incorrectly wired ICS4Wrappers.
Because the flow of activity can happen in either direction from top of the stack or from bottom of the stack, it creates a cyclical dependency which is difficult to handle when wiring up the IBC stack.
See related issues: #3371, #4427
Middleware Wiring
Initially, the middleware abstractions were very useful as it allowed for other IBC applications to extend and build upon existing IBC apps without abandoning the accumulated state and network effect(s) of an already existing channel.
However, as the complexity of IBC has increased, we have found that the middleware abstraction has its limits and can be very problematic as we increase its complexity in the number of applications on a middleware stack.
This can be exemplified by the difficulty in creating new versions, packet data, or acknowledgement structures for middlewares (as discussed below), but also in the confusion around properly wiring an IBC application in an app.go file.
See related issues: #4444, #5814
Wrapping versions, acks and packet data
IBC applications may wish to act upon another IBC application, which is why they might be placed in a middleware stack and in addition, they may want their own information to be encoded into a channel version, packet data or acknowledgement.
The problem is that given the current middleware abstractions, applications must wrap their information around the version, packet data, or acknowledgement that the application below then in the stack returns.
This is problematic because it requires having access to the entire IBC stack in order to unwrap any version, packet data, or acknowledgement.
Early on after the middleware design was introduced, there was a request to allow other applications, such as ibc hooks, to extend the existing transfer packet data with their own information.
This was accomplished by adding the memo into the transfer packet data, with the idea that we would later extend the packet to support multiple packet datas.
Proposal
Remove capabilities
Both port and channel capabilities should be removed. This can be done by maintaining a simple map from the port name (IBC application name) or port prefix (dynamic port creation) to the actual application implementation.
Ordered list of callbacks
We should convert IBC application wrapping, which generates an implicit IBC stack, into an explicit ordered list of callbacks for a given port ID. The purpose of this is to decouple applications from one another, while maintaining backwards compatibility with existing IBC usage.
Future features of packet processing may choose to invoke a single application in this list of callbacks (which is why we must decouple application from one another).
Removing the bi-directional flow of IBC core <> IBC app messenging
Replacing ICS4Wrapper with core API's
The ICS4Wrapper should be replaced with API's which allow for IBC messaging to occur from core IBC initially, rather than being initiated by IBC applications
SendPacket
One example of this is the SendPacket api on the ICS4Wrapper. It should be moved to the IBC application interface as
OnSendPacket
. A new msg type should be added to the core IBC msg server, which allows for users or applications to send packets. It will invoke the ordered list of callbacks in the same fashion it would for receiving, acknowledging or timing out a packet.Wrapping/unwrapping version and acknowledgement
Given that applications will no longer depend on one another when being wired, but will continue to potentially have wrapped versions and acknowledgements from historical usage, we must provide interfaces for core IBC to wrap and unwrap versions or acknowledgement when necessary. This should condense down the existing complexity around wrapping/unwrapping versions and acknoweldgement into interfaces which hopefully will be removed with the adoption of future work, such as multi-packetdata packets.
Future work, multi-packetdata
Once the port router refactor has been completed, it should be possible to introduce a new port and packet data type.
The port will indicate that a packet is sent using a new multi-packetdata structure.
This structure should contain a list of {application port, encoding type, packet data type, packet data value} which can then be delivered to an individual IBC application.
This would allow users to send packets without needing to rely on the ordered list of callbacks or the wrapped channel versions or acknowledgements.
They can choose to interact with any number of IBC applications atomically within a single packet.
A initial investigation occurred in #6314
The text was updated successfully, but these errors were encountered: