Connections
At the beginning of the lifecycle of communication between two chains, a connection must be opened. This is a process by which one chain initiates the opening of the connection, and the other responds with certain data. We call this process a 4-way handshake, as each chain must send two messages. The handshake is used to bootstrap the connection, exchanging critical information such as the current validator set, chain identifier, and consensus mechanism. This data is stored on both chains and, once the handshake is completed, used for verifying future cross-chain messages.
sequenceDiagram participant Chain A participant Relayer participant Chain B Chain A->>Relayer: ConnectionOpenInit (includes Chain A's info) Relayer->>Chain B: Relay ConnectionOpenInit Chain B->>Relayer: ConnectionOpenTry (includes Chain B's info) Relayer->>Chain A: Relay ConnectionOpenTry Chain A->>Relayer: ConnectionOpenAck (verify Chain B's info) Relayer->>Chain B: Relay ConnectionOpenAck Chain B->>Relayer: ConnectionOpenConfirm Relayer->>Chain A: Relay ConnectionOpenConfirm Note over Chain A,Chain B: Connection Established
During this handshake:
- Chain A initiates with ConnectionOpenInit, sending its chain-specific parameters
- Chain B responds with ConnectionOpenTry, verifying Chain A's data and providing its own
- Chain A acknowledges with ConnectionOpenAck, confirming Chain B's information
- Chain B finalizes with ConnectionOpenConfirm, establishing the secure connection
Once established, this connection can be used for secure cross-chain communication, with both chains able to verify messages using the exchanged parameters and consensus proofs.
This connection effectively acts as a socket to read and write bytes between the two chains. Although this is powerful, we ideally want a more structured way to communicate, akin to HTTP. For that we use channels.
Multiple Connections
Usually the relation between chains and connections is one-on-one, meaning that there only exists one connection between two chains. There is nothing preventing multiple from existing however. You will probably see some duplicates for testing reasons: deploying connections while verifiying the actual production one will work.
gq https://development.graphql.union.build/v1/graphql -q '
query Connections @cached(ttl: 60) {
v2_connections(args: { p_limit: 30 }) {
source_universal_chain_id
source_client_id
source_connection_id
destination_universal_chain_id
destination_client_id
destination_connection_id
}
}'
nix shell nixpkgs#nodePackages.graphqurl
There are uses for multiple connections outside of testing though. Connections may leverage different clients, and thus have different security guarantees. A 'fast' connection could leverage an oracle solution, while the 'slow' connection awaits full finality.