Sharing a document that I’ve shared internally at Informal, as it’s relevant to this discussion!
Executive summary
This document explores the reasons why we see little to no adoption of IBC outside of Cosmos, and suggest some avenues for fixing the problem. After building a shared background, I deep dive into some technical reasons why IBC is not “universal”; that is, I identify parts of its design which make it unfit for some bridging use cases. We end with providing avenues for how to improve IBC, and identify future research questions.
The purpose of this document is to inform business decisions from mid- to high-level technical arguments. Minor technical inaccuracies are included to help readability.
Background
In this section, I provide background for the concepts that will be discussed. I will be referring back to them in the ensuing discussion. This can be safely skipped and referred back to if needed.
Review of bridges
Fundamentally, a bridge provides transport of messages from one chain to another. Transport refers to the mechanism by which a message sent from chain A is delivered to chain B. Every transport protocol defines how chain A sends a message, how a relayer picks up on that, and what on-chain verification chain B must perform when receiving a message.
In practice, there are 3 main categories of bridges: multisig-based, light client-based, and validating bridges. We will briefly go over the main ideas of each. This is not a comprehensive review; we only go over those to serve the ensuing discussion.
Multisig bridges
Multisig bridges implement transport by giving full authority to a set of keys to dictate what messages were sent by a counterparty chain. That is, from chain A’s perspective, to validate the claim that a message was sent to A, A needs to verify that a sufficient number of known keys signed the message to be convinced that the message was indeed sent.
Note that an interesting special case of multisig bridges is when there is only one trusted key. This is how centralized platforms such as Coinbase work. On Ethereum, they have a smart contract where that escrows tokens. When a token is escrowed, their centralized database is updated (e.g. if you escrowed 1 ETH, you will now see 1 ETH in your Coinbase account). Conversely, to send 1 ETH out of Coinbase, they first deduct 1 ETH from your account, and then send 1 ETH from the escrow contract back to your Ethereum address. Note that the contract only accepts such transactions if it is originated by a predetermined account, which they control. Note that this is a bridge just like any other given our original definition of bridges; we just described here how the Coinbase bridge implements transport.
Multisig bridges are in wide use today, for better or for worse.
Light client bridges
Light client bridges implement transport by having each chain run a light client of its counterparty. There is no one definition of what a “light client” is, but broadly speaking, it is an algorithm that verifies that the validators of the counterparty chain approved the state transition (i.e. the validators signed off on a new block), as opposed to verifying the state transition itself. To send a message, chain A must then commit the message to state; chain B will require a Merkle proof that the packet was indeed included in the state. Note that chain B can do that because it has a light client which tracks the state root of the other chain.
This is the effectively the sole use of IBC today.
Validating bridges
For the purpose of this discussion, I include all bridges which validate the state transition function under the name “validating bridge”. In essence, a validating bridge is similar to a light client bridge, except that the “light client” actually verifies the state transition as well. That is, it doesn’t blindly trust that the counterparty chain’s validators are honest; it verifies that the new blocks are indeed valid.
The two primary ways that this is is done today are either optimistically or using zero-knowledge proofs. In the optimistic scenario, new block headers are accepted, but given a “challenge period” (typically on the order of days) for anyone to publish a proof that the state transition function was violated. In the zero-knowledge proof scenario, to update the counterparty client, chain A must also submit a so-called “zero-knowledge proof”: a proof that turns out to be simultaneously cheap to verify, and at the same time prove that the state-transition function was not violated.
Why IBC is not a universal protocol
We begin our main discussion by exploring some technical reasons why IBC as currently designed is not always the best bridging solution.
The connection and channel primitives don’t apply to all bridges
In order to send a message (packet) in IBC, one must set up a connection and channel on top of the connection. IBC has handshakes to establish connections or channels, which serve 2 purposes:
- (connection only) Ensuring that the counterparty chain runs a proper light client
- For example, A ensures that the root of trust on B actually refers to A (i.e. proper Merkle root of the state at some height H).
- Negotiating parameters
- e.g. if channels using a given connection are ordered or unordered.
The connection and channel primitives make sense only in a subset of transport protocols. For example, they are not needed for multisig bridges. As previously explored, multisig bridges implement transport by giving full authority to a set of keys to dictate what messages were sent by a counterparty chain. Connections and channels are not needed in this scheme; they add complexity for no benefit.
Note that IBC supports multisigs the solomachine client is used. However, multisig bridges over IBC are made more complex by the connection and channel primitives. This also has a runtime cost; receiving messages is then more expensive due to all the extra checks imposed by the connection and channel primitives.
Many core types require on-chain parsing
A self-describing format is one where bytes in the data structure contain information about the structure of the rest of the data. The most common example is JSON.
IBC has many core types that need to be parsed on-chain.
For example, chain IDs are encoded as a string of the form "<client type>-<revision number>"
. Many IBC datagrams’ on-chain validation require parsing the revision number out of the chain ID.
Another example is the use of JSON as a packet data format. Notably, the token transfer app’s packet format roughly look like:
{
"token": "a/b/denom",
"amount": 42,
"sender": "address",
"receiver": "address",
"memo": "some text"
}
Hence, processing token transfers requires parsing a JSON-encoded string.
While this seems to work fine on app chains, this is prohibitively expensive in resource-constrained environments. Two such notable environments are:
- EVM-based chains
- zk-based validating bridges
- As previously discussed, validating a message on the receiving chain requires validating a SNARK (or “succinct proof”) attesting to the fact that the counterparty’s state transition function (or “chain logic”) was properly executed. Parsing JSON, or self-describing data types in general, drastically increases the size of SNARKs.
- This is relevant in the context where an IBC-enabled rollup has a zk-bridge to its “settlement chain”. Everytime the rollup updates the zk-bridge, it must construct a SNARK attesting to the fact that it ran its state transition function properly. Some of the rollup’s transactions will contain IBC message processing, which often involves parsing JSON. This ends up drastically increasing the size of the SNARK sent to the rollup’s settlement chain.
In contrast, bridges commonly used on Ethereum understand this. They avoid self-describing formats, and use fixed-width types.
For example, this is the definition of a Wormhole packet:
// Wormhole's "packet" format
VAA struct {
Version uint8
GuardianSetIndex uint32
LenSignatures uint8
Signatures []*Signature
Timestamp time.Time
Nonce uint32
EmitterChain uint8
EmitterAddress [32]byte
Sequence uint64
ConsistencyLevel uint8
Payload []byte
}
// Signature
Signature struct {
Index uint8
Signature [65]byte
}
The critical property of this packet format is that it is very efficient to parse.
Avenues for improving IBC
The key to getting IBC out of Cosmos is to make sending and receiving messages efficient in resource-constrained environments. Recommendations follow directly from problems identified in the previous section.
Avoid self-describing formats and use fixed-width types
Specifically, chain IDs should be, for example, a u64
.
Also, IBC apps should carefully design their packet formats to use fixed-width types as much as possible. The previously mentioned Wormhole packet format is a good example.
To accomodate apps that must use strings, IBC should provide a standard efficient String
representation, such as
struct String {
len: u32,
data: char[],
}
This format is efficient to parse: read the first 4 bytes interpreted as an unsigned integer. This tells indicates how many bytes the string contains. A parser which doesn’t care about the string value can simply jump the data field and keep parsing the rest of the data. Note that although this String
structure is technically self-describing, the overhead of parsing it is very minimal (i.e. one unsigned integer read).
Strings should never contain structured data. That is, no parsing of the data
field should be needed. Note that the token
field of the ICS-20 packet data structure violates this principle and should be redesigned.
Future research
There are still many questions left to answer:
- Is IBC a good protocol to implement a validating bridge? Specifically, are the connection & channel primitives (and their current handshakes) useful abstractions for validating bridges?
- If not, can we redesign them in a way that they are?
- Can IBC enable certain clients to not require connections & channels? As we previously saw, those are unnecessary for multisig bridges; can we get rid of them on a per-client basis?
- Say we come up with a design which we believe solves all the problems previously described; how do we upgrade the ecosystem to this “IBC v2” protocol?