:receipt_ - the results of executing the packets received from chain A
+
+These two queues have different purposes and store messages of different types. By parsing the key of a merkle proof, a recipient can uniquely identify which queue, if any, this message belongs to. We now define _k =_ (_remote id, [send|receipt], index)_. This tuple is used to route and verify every message, before the contents of the packet are processed by the appropriate application logic.
+
+### 3.3 Message Contents
+
+Up to this point, we have focused on the semantics of the message key, and how we can produce a unique identifier for every possible message in every possible connection. The actual data written at the location has been left as an opaque blob, put by providing some structure to the messages, we can enable more functionality.
+
+We define every message in a _send queue _to consist of a well-known type and opaque data. The IBC protocol relies on the type for routing, and lets the appropriate module process the data as it sees fit. The _receipt queue_ stores if it was an error, an optional error code, and an optional return value. We use the same index as the received message, so that the results of _A:qB.send[i]_ are stored at _B:qA.receipt[i]_. (read: the message at index _i_ in the _send_ queue for chain B as stored on chain A)
+
+_Vsend = (type, data)_
+
+_Vreceipt = (result, [success|error code])_
+
+### 3.4 Sending a Message
+
+A proper implementation of IBC requires all relevant state to be encapsulated, so that other modules can only interact with it via a fixed API (to be defined in the next sections) rather than directly mutating internal state. This allows the IBC module to provide security guarantees.
+
+Sending an IBC packet involves an application module calling the send method of the IBC module with a packet and a destination chain id. The IBC module must ensure that the destination chain was already properly registered, and that the calling module has permission to write this packet. If so, the IBC module simply pushes the packet to the tail of the _send_ _queue_, which enables all the proofs described above.
+
+The permissioning of which module can write which packet can be defined per type, so this module can maintain any application-level invariants related to this area. Thus, the "coin" module can maintain the constant supply of tokens, while another module can maintain its own invariants, without IBC messages providing a means to escape their encapsulations. The IBC module must associate every supported message type with a particular handler (_ftype_) and return an error for unsupported types.
+
+_(IBCsend(D, type, data) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_ Success)_
+
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_ push(qD.send ,Vsend{type, data})_
+
+We also consider how a given blockchain _A _is expected to receive the packet from a source chain _S_ with a merkle proof, given the current set of trusted headers for that chain, _TS_:
+
+_A:IBCreceive(S, Mk,v,h) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_ match_
+
+_qS.receipt =_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("unregistered sender"), _
+
+_ k = (_, reciept, _) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("must be a send"),_
+
+_ k = (d, _, _) and d _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_A_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("sent to a different chain"),_
+
+_ k = (_, send, i) and head(qS.receipt) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_i_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("out of order"),_
+
+_ Hh _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_TS _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("must submit header for height h"),_
+
+_ valid(Hh ,Mk,v,h ) = false _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("invalid merkle proof"),_
+
+_ v = (type, data) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_(result, err) :=ftype(data); push(qS.receipt , (result, err)); Success _
+
+Note that this requires not only an valid proof, but also that the proper header as well as all prior messages were previously submitted. This returns success upon accepting a proper message, even if the message execution returned an error (which must then be relayed to the sender).
+
+### 3.5 Receipts
+
+When we wish to create a transaction that atomically commits or rolls back across two chains, we must look at the receipts from sending the original message. For example, if I want to send tokens from Alice on chain A to Bob on chain B, chain A must decrement Alice's account _if and only if_ Bob's account was incremented on chain B. We can achieve that by storing a protected intermediate state on chain A, which is then committed or rolled back based on the result of executing the transaction on chain B.
+
+To do this requires that we not only provable send a message from chain A to chain B, but provably return the result of that message (the receipt) from chain B to chain A. As one noticed above in the implementation of _IBCreceive_, if the valid IBC message was sent from A to B, then the result of executing it, even if it was an error, is stored in _B:qA.receipt_. Since the receipts are stored in a queue with the same key construction as the sending queue, we can generate the same set of proofs for them, and perform a similar sequence of steps to handle a receipt coming back to _S_ for a message previously sent to _A_:
+
+_S:IBCreceipt(A, Mk,v,h) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_ match_
+
+_qA.send =_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("unregistered sender"), _
+
+_ k = (_, send, _) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("must be a recipient"),_
+
+_ k = (d, _, _) and d _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_S_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("sent to a different chain"),_
+
+_Hh _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_TA _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("must submit header for height h"),_
+
+_ not valid(Hh ,Mk,v,h ) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("invalid merkle proof"),_
+
+_ k = (_, receipt, head|tail)_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("only accepts message proofs"),_
+
+_ k = (_, receipt, i) and head(qS.send) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_i_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("out of order"),_
+
+_ v = (_, error) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_(type, data) := pop(qS.send ); rollbacktype(data); Success_
+
+_ v = (res, success) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_(type, data) := pop(qS.send ); committype(data, res); Success_
+
+This enforces that the receipts are processed in order, to allow some the application to make use of some basic assumptions about ordering. It also removes the message from the send queue, as there is now proof it was processed on the receiving chain and there is no more need to store this information.
+
+
+
+>>>>> gd2md-html alert: inline image link here (to images/Cosmos-IBC1.png). Store image on your image server and adjust path/filename if necessary.
(Back to top)(Next alert)
>>>>>
+
+
+
+
+
+
+
+>>>>> gd2md-html alert: inline image link here (to images/Cosmos-IBC2.png). Store image on your image server and adjust path/filename if necessary.
(Back to top)(Next alert)
>>>>>
+
+
+
+
+
+### 3.6 Relay Process
+
+The blockchain itself only records the _intention_ to send the given message to the recipient chain, it doesn't make any network connections as that would add unbounded delays and non-determinism into the state machine. We define the concept of a _relay_ process that connects two chain by querying one for all proofs needed to prove outgoing messages and submit these proofs to the recipient chain.
+
+The relay process must have access to accounts on both chains with sufficient balance to pay for transaction fees but needs no other permissions. Many _relay_ processes may run in parallel without violating any safety consideration. However, they will consume unnecessary fees if they submit the same proof multiple times, so some minimal coordination is ideal.
+
+As an example, here is a naive algorithm for relaying send messages from A to B, without error handling. We must also concurrently run the relay of receipts from B back to A, in order to complete the cycle. Note that all reads of variables belonging to a chain imply queries and all function calls imply submitting a transaction to the blockchain.
+
+_while true_
+
+_ pending := tail(A:qB.send)_
+
+_ received := tail(B:qA.receive)_
+
+_ if pending > received_
+
+_ Uh := A:latestHeader_
+
+_ B:updateHeader(Uh)_
+
+_ for i :=received...pending_
+
+_ k := (B, send, i)_
+
+_ packet := A:Mk,v,h_
+
+_ B:IBCreceive(A, packet)_
+
+_ sleep(desiredLatency)_
+
+Note that updating a header is a costly transaction compared to posting a merkle proof for a known header. Thus, a process could wait until many messages are pending, then submit one header along with multiple merkle proofs, rather than a separate header for each message. This decreases total computation cost (and fees) at the price of additional latency and is a trade-off each relay can dynamically adjust.
+
+In the presence of multiple concurrent relays, any given relay can perform local optimizations to minimize the number of headers it submits, but remember the frequency of header submissions defines the latency of the packet transfer.
+
+Indeed, it is ideal if each user that initiates the creation of an IBC packet also relays it to the recipient chain. The only constraint is that the relay must be able to pay the appropriate fees on the destination chain. However, in order to avoid bottlenecks, a group may sponsor an account to pay fees for a public relayer that moves all unrelayed packets (perhaps with a high latency).
+
+## 4 Optimizations
+
+The above sections describe a secure messaging protocol that can handle all normal situations between two blockchains. It guarantees that all messages are processed exactly once and in order, and provides a mechanism for non-blocking atomic transactions spanning two blockchains. However, to increase efficiency over millions of messages with many possible failure modes on both sides of the connection, we can extend the protocol. These extensions allow us to clean up the receipt queue to avoid state bloat, as well as more gracefully recover from cases where large numbers of messages are not being relayed, or other failure modes in the remote chain.
+
+### 4.1 Timeouts
+
+Sometimes it is desirable to have some timeout, an upper limit to how long you will wait for a transaction to be processed before considering it an error. At the same time, this is an obvious attack vector for a double spend, just delaying the relay of the receipt or waiting to send the message in the first place and then relaying it right after the cutoff to take advantage of different local clocks on the two chains.
+
+One solution to this is to include a timeout in the IBC message itself. When sending it, one can specify a block height or timestamp on the **receiving** chain after which it is no longer valid. If the message is posted before the cutoff, it will be processed normally. If it is posted after that cutoff, it will be a guaranteed error. Note that to make this secure, the timeout must be relative to a condition on the **receiving** chain, and the sending chain must have proof of the state of the receiving chain after the cutoff.
+
+For a sending chain _A_ and a receiving chain _B_, with _k=(_, _, i)_ for _A:qB.send_ or _B:qA.receipt_ we currently have the following guarantees:
+
+_A:Mk,v,h = _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_if message i was not sent before height h_
+
+_A:Mk,v,h = _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_if message i was sent and receipt received before height h _
+
+
+ _(and the receipts for all messages j < i were also handled)_
+
+_A:Mk,v,h _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_otherwise (message result is not yet processed)_
+
+_B:Mk,v,h = _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_if message i was not received before height h_
+
+_B:Mk,v,h _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_if message i was received before height h_
+
+_ (and all messages j < i were received)_
+
+Based on these guarantees, we can make a few modifications of the above protocol to allow us to prove timeouts, by adding some fields to the messages in the send queue, and defining an expired function that returns true iff _h > maxHeight_ or _timestamp(Hh ) > maxTime._
+
+_Vsend = (maxHeight, maxTime, type, data)_
+
+_expired(Hh ,Vsend ) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_[true/false]_
+
+We then update message handling in _IBCreceive_, so it doesn't even call the handler function if the timeout was reached, but rather directly writes and error in the receipt queue:
+
+_IBCreceive:_
+
+_ …._
+
+_ expired(latestHeader, v) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_push(qS.receipt , (None, TimeoutError));_
+
+_ v = (_, _, type, data) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_(result, err) :=ftype(data); push(qS.receipt , (result, err)); _
+
+and add a new _IBCtimeout_ function to accept tail proofs to demonstrate that the message was not processed at some given header on the recipient chain. This allows the sender chain to assert timeouts locally.
+
+_S:IBCtimeout(A, Mk,v,h) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_ match_
+
+_qA.send =_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("unregistered sender"), _
+
+_ k = (_, send, _) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("must be a receipt"),_
+
+_ k = (d, _, _) and d _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_S_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("sent to a different chain"),_
+
+_ Hh _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_TA _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("must submit header for height h"),_
+
+_ not valid(Hh ,Mk,v,h ) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("invalid merkle proof"),_
+
+_ k = (S, receipt, tail)_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_match_
+
+
+ _tail _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_head(qS.send )_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("receipt exists, no timeout proof")_
+
+
+ _not expired(peek(qS.send )) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("message timeout not yet reached")_
+
+
+ _default _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_(_, _, type, data) := pop(qS.send ); rollbacktype(data); Success_
+
+
+ _default _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("must be a tail proof")_
+
+which processes timeouts in order, and adds one more condition to the queues:
+
+_A:Mk,v,h = _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_if message i was sent and timeout proven before height h_
+
+
+ _(and the receipts for all messages j < i were also handled)_
+
+Now chain A can rollback all transactions that were blocked by this flood of unrelayed messages, without waiting for chain B to process them and return a receipt. Adding reasonable time outs to all packets allows us to gracefully handle any errors with the IBC relay processes, or a flood of unrelayed "spam" IBC packets. If a blockchain requires a timeout on all messages, and imposes some reasonable upper limit (or just assigns it automatically), we can guarantee that if message _i_ is not processed by the upper limit of the timeout period, then all previous messages must also have either been processed or reached the timeout period.
+
+Note that in order to avoid any possible "double-spend" attacks, the timeout algorithm requires that the destination chain is running and reachable. One can prove nothing in a complete network partition, and must wait to connect; the timeout must be proven on the recipient chain, not simply the absence of a response on the sending chain.
+
+### 4.2 Clean up
+
+While we clean up the _send queue_ upon getting a receipt, if left to run indefinitely, the _receipt queues_ could grow without limit and create a major storage requirement for the chains. However, we must not delete receipts until they have been proven to be processed by the sending chain, or we lose important information and sacrifice reliability.
+
+The observant reader may also notice, that when we perform the timeout on the sending chain, we do not update the _receipt queue_ on the receiving chain, and now it is blocked waiting for a message _i_, which **no longer exists** on the sending chain. We can update the guarantees of the receipt queue as follows to allow us to handle both:
+
+_B:Mk,v,h = _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_if message i was not received before height h_
+
+_B:Mk,v,h = _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_if message i was provably resolved on the sending chain before height h_
+
+_B:Mk,v,h _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_otherwise (if message i was processed before height h,_
+
+_ and no ack of receipt from the sending chain)_
+
+Consider a connection where many messages have been sent, and their receipts processed on the sending chain, either explicitly or through a timeout. We wish to quickly advance over all the processed messages, either for a normal cleanup, or to prepare the queue for normal use again after timeouts.
+
+Through the definition of the send queue above, we see that all messages _i < head_ have been fully processed, and all messages _head <= i < tail_ are awaiting processing. By proving a much advanced _head_ of the _send queue_, we can demonstrate that the sending chain already handled all messages. Thus, we can safely advance our local _receipt queue_ to the new head of the remote _send queue_.
+
+_S:IBCcleanup(A, Mk,v,h) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_ match_
+
+_qA.receipt =_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("unknown sender"), _
+
+_ k = (_, send, _) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("must be for the send queue"),_
+
+_ k = (d, _, _) and d _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_S_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("sent to a different chain"),_
+
+_ k_
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_ (_, _, head) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("Need a proof of the head of the queue"),_
+
+_ Hh _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_TA _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("must submit header for height h"),_
+
+_ not valid(Hh ,Mk,v,h ) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("invalid merkle proof"),_
+
+_ head := v _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_match_
+
+_ head <= head(qA.receipt) _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_Error("cleanup must go forward"),_
+
+_ default _
+
+>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>
+
+_advance(qA.receipt , head); Success_
+
+This allows us to invoke the _IBCcleanup _function to resolve all outstanding messages up to and including _head_ with one merkle proof. Note that if this handles both recovering from a blocked queue after timeouts, as well as a routine cleanup method to recover space. In the cleanup scenario, we assume that there may also be a number of messages that have been processed by the receiving chain, but not yet posted to the sending chain, _tail(B:qA.reciept ) > head(A:qB.send )_. As such, the _advance_ function must not modify any messages between the head and the tail.
+
+
+
+>>>>> gd2md-html alert: inline image link here (to images/Cosmos-IBC3.png). Store image on your image server and adjust path/filename if necessary.
(Back to top)(Next alert)
>>>>>
+
+
+
+
+
+### 4.3 Handling Byzantine Failures
+
+While every message is guaranteed reliable in the face of malicious nodes or relays, all guarantees break down when the entire blockchain on the other end of the connection exhibits byzantine faults. These can be in two forms: failures of the consensus mechanism (reversing "final" blocks), or failure at the application level (not performing the action defined by the message).
+
+The IBC protocol can only detect byzantine faults at the consensus level, and is designed to halt with an error upon detecting any such fault. That is, if it ever sees two different headers for the same height (or any evidence that headers belong to different forks), then it must freeze the connection immediately. The resolution of the fault must be handled by the blockchain governance, as this is a serious incident and cannot be predefined.
+
+If there is a big divide in the remote chain and they split eg. 60-40 as to the direction of the chain, then the light-client protocol will refuses to follow either fork. If both sides declare a hard fork and continue with new validator sets that are not compatible with the consensus engine (they don't have ⅔ support from the previous block), then users will have to manually tell their local client which chain to follow (or fork and follow both with different IDs).
+
+The IBC protocol doesn't have the option to follow both chains as the queue and associated state must map to exactly one remote chain. In a fork, the chain can continue the connection with one fork, and optionally make a fresh connection with the other fork (which will also have to adjust internally to wipe its view of the connection clean).
+
+The other major byzantine action is at the application level. Let us assume messages represent transfer of value. If chain A sends a message with X tokens to chain B, then it promises to remove X tokens from the local supply. And if chain B handles this message with a success code, it promises to credit X tokens to the account mentioned in the message. What if A isn't actually removing tokens from the supply, or if B is not actually crediting accounts?
+
+Such application level issues cannot be proven in a generic sense, but must be handled individually by each application. The activity should be provable in some manner (as it is all in an auditable blockchain), but there are too many failure modes to attempt to enumerate, so we rely on the vigilance of the participants in the extremely rare case of a rogue blockchain. Of course, this misbehavior is provable and can negatively impact the value of the offending chain, providing economic incentives for any normal chain not to run malicious applications over IBC.
+
+## 5 Conclusion
+
+We have demonstrated a secure, performant, and flexible protocol for connecting two blockchains with complete finality using a secure, reliable messaging queue. The algorithm and semantics of all data types have been defined above, which provides a solid basis for reasoning about correctness and efficiency of the algorithm.
+
+The observant reader may note that while we have defined a message queue protocol, we have not yet defined how to use that to transfer value within the Cosmos ecosystem. We will shortly release a separate paper on Cosmos IBC that defines the application logic used for direct value transfer as well as routing over the Cosmos hub. That paper builds upon the IBC protocol defined here and provides a first example of how to reason about application logic and global invariants in the context of IBC.
+
+There is a reference implementation of the Cosmos IBC protocol as part of the Cosmos SDK, written in go and freely usable under the Apache license. For those wish to write an implementation of IBC in another language, or who want to analyze the specification further, the following appendixes define the exact message formats and binary encoding.
+
+
+
+## Appendix A: Encoding Libraries
+
+The specification has focused on semantics and functionality of the IBC protocol. However in order to facilitate the communication between multiple implementations of the protocol, we seek to define a standard syntax, or binary encoding, of the data structures defined above. Many structures are universal and for these, we provide one standard syntax. Other structures, such as _Hh , Uh , _and _Xh_ are tied to the consensus engine and we can define the standard encoding for tendermint, but support for additional consensus engines must be added separately. Finally, there are some aspects of the messaging, such as the envelope to post this data (fees, nonce, signatures, etc.), which is different for every chain, and must be known to the relay, but are not important to the IBC algorithm itself and left undefined.
+
+In defining a standard binary encoding for all the "universal" components, we wish to make use of a standardized library, with efficient serialization and support in multiple languages. We considered two main formats: ethereum's rlp[^6] and google's protobuf[^7]. We decided for protobuf, as it is more widely supported, is more expressive for different data types, and supports code generation for very efficient (de)serialization codecs. It does have a learning curve and more setup to generate the code from the type specifications, but the ibc data types should not change often and this code generation setup only needs to happen once per language (and can be exposed in a common repo), so this is not a strong counter-argument. Efficiency, expressiveness, and wider support rule in its favor. It is also widely used in gRPC and in many microservice architectures.
+
+The tendermint-specific data structures are encoded with go-wire[^8], the native binary encoding used inside of tendermint. Most blockchains define their own formats, and until some universal format for headers and signatures among blockchains emerge, it seems very premature to enforce any encoding here. These are defined as arbitrary byte slices in the protocol, to be parsed in an consensus engine-dependent manner.
+
+For the following appendixes, the data structure specifications will be in proto3[^9] format.
+
+## Appendix B: IBC Queue Format
+
+The foundational data structure of the IBC protocol are the message queues stored inside each chain. We start with a well-defined binary representation of the keys and values used in these queues. The encodings mirror the semantics defined above:
+
+_key = _(_remote id, [send|receipt], [head|tail|index])_
+
+_Vsend = (maxHeight, maxTime, type, data)_
+
+_Vreceipt = (result, [success|error code])_
+
+
+```
+ message QueueName {
+ // chain_id is which chain this queue is
+ // associated with
+ string chain_id = 1;
+ enum Purpose {
+ SEND = 0;
+ RECEIPT = 1;
+ }
+ Purpose purpose = 2;
+ }
+ // StateKey is a key for the head/tail of a given queue
+ message StateKey {
+ QueueName queue = 1;
+ // both encode into one byte with varint encoding
+ // never clash with 8 byte message indexes
+ enum State {
+ HEAD = 0;
+ TAIL = 0x7f;
+ }
+ State state = 2;
+ }
+ // StateValue is the type stored under a StateKey
+ message StateValue {
+ fixed64 index = 1;
+ }
+ // MessageKey is the key for message *index* in a given queue
+ message MessageKey {
+ QueueName queue = 1;
+ fixed64 index = 2;
+ }
+ // SendValue is stored under a MessageKey in the SEND queue
+ message SendValue {
+ uint64 maxHeight = 1;
+ google.protobuf.Timestamp maxTime = 2;
+ // use kind instead of type to avoid keyword conflict
+ bytes kind = 3;
+ bytes data = 4;
+ }
+ // ReceiptValue is stored under a MessageKey in the RECEIPT queue
+ message ReceiptValue {
+ // 0 is success, others are application-defined errors
+ int32 errorCode = 1;
+ // contains result on success, optional info on error
+ bytes data = 2;
+ }
+```
+
+Keys and values are binary encoded and stored as bytes in the merkle tree in order to generate the root hash stored in the block header, which validates all proofs. They are treated as arrays of bytes by the merkle proofs for deterministically generating the sequence of hashes, and passed as such in all interchain messages. Once the validity of a key value pair has been determined from the merkle proof and header, the bytes can be deserialized and the contents interpreted by the protocol.
+
+## Appendix C: Merkle Proof Formats
+
+A merkle tree (or a trie) generates one hash that can prove every element of the tree. Generating this hash starts with hashing the leaf nodes. Then hashing multiple leaf nodes together to get the hash of an inner node (two or more, based on degree k of the k-ary tree). And continue hashing together the inner nodes at each level of the tree, until it reaches a root hash. Once you have a known root hash, you can prove key/value belongs to this tree by tracing the path to the value and revealing the (k-1) hashes for all the paths we did not take on each level. If this is new to you, you can read a basic introduction[^10].
+
+There are a number of different implementations of this basic idea, using different hash functions, as well as prefixes to prevent second preimage attacks (differentiating leaf nodes from inner nodes). Rather than force all chains that wish to participate in IBC to use the same data store, we provide a data structure that can represent merkle proofs from a variety of data stores, and provide for chaining proofs to allow for sub-trees. While searching for a solution, we did find the chainpoint proof format[^11], which inspired this design significantly, but didn't (yet) offer the flexibility we needed.
+
+We generalize the left/right idiom to concatenating a (possibly empty) fixed prefix, the (just calculated) last hash, and a (possibly empty) fixed suffix. We must only define two fields on each level and can represent any type, even a 16-ary Patricia tree, with this structure. One must only translate from the store's native proof to this format, and it can be verified by any chain, providing compatibility for arbitrary data stores.
+
+The proof format also allows for chaining of trees, combining multiple merkle stores into a "multi-store". Many applications (such as the EVM) define a data store with a large proof size for internal use. Rather than force them to change the store (impossible), or live with huge proofs (inefficient), we provide the possibility to express merkle proofs connecting multiple subtrees. Thus, one could have one subtree for data, and a second for IBC. Each tree produces their own merkle root, and these are then hashed together to produce the root hash that is stored in the block header.
+
+A valid merkle proof for IBC must either consist of a proof of one tree, and prepend "ibc" to all key names as defined above, or use a subtree named "ibc" in the first section, and store the key names as above in the second tree.
+
+For those who wish to minimize the size of their merkle proofs, we recommend using Tendermint's IAVL+ tree implementation[^12], which is designed for optimal proof size, and freely available for use. It uses an AVL tree (a type of binary tree) with ripemd160 as the hashing algorithm at each stage. This produces optimally compact proofs, ideal for posting in blockchain transactions. For a data store of _n_ values, there will be _log2(n)_ levels, each requiring one 20-byte hash for proving the branch not taken (plus possible metadata for the level). We can express a proof in a tree of 1 million elements in something around 400 bytes. If we further store all IBC messages in a separate subtree, we should expect the count of nodes in this tree to be a few thousand, and require less than 400 bytes, even for blockchains with a quite large state.
+
+```
+ // HashOp is the hashing algorithm we use at each level
+ enum HashOp {
+ RIPEMD160 = 0;
+ SHA224 = 1;
+ SHA256 = 2;
+ SHA384 = 3;
+ SHA512 = 4;
+ SHA3_224 = 5;
+ SHA3_256 = 6;
+ SHA3_384 = 7;
+ SHA3_512 = 8;
+ SHA256_X2 = 9;
+ };
+ // Op represents one hash in a chain of hashes.
+ // An operation takes the output of the last level and returns
+ // a hash for the next level:
+ // Op(last) => Operation(prefix + last + sufix)
+ //
+ // A simple left/right hash would simply set prefix=left or
+ // suffix=right and leave the other blank. However, one could
+ // also represent the a Patricia trie proof by setting
+ // prefix to the rlp encoding of all nodes before the branch
+ // we select, and suffix to all those after the one we select.
+ message Op {
+ bytes prefix = 1;
+ bytes suffix = 2;
+ HashOp op = 3;
+ }
+ // Data is the end value stored, used to generate the initial hash
+ message Data {
+ bytes prefix = 1;
+ bytes key = 2;
+ bytes value = 3;
+ HashOp op = 4;
+ // If it is KeyValue, this is the data we want
+ // If it is SubTree, key is name of the tree, value is root hash
+ // Expect another branch to follow
+ enum DataType {
+ KeyValue = 0;
+ SubTree = 1;
+ }
+ DataType dataType = 5;
+ }
+ // Branch will hash data and then pass it through operations from
+ // last to first in order to calculate the root node.
+ //
+ // Visualize Branch as representing the data closest to root as the
+ // first item, and the leaf as the last item.
+ message Branch {
+ repeated Op operations = 1;
+ Data data = 2;
+ }
+ // MerkleProof shows a veriable path from the data to
+ // a root hash (potentially spanning multiple sub-trees).
+ message MerkleProof {
+ // identify the header this is rooted in
+ string chainId = 1;
+ uint64 height = 2;
+ // this hash must match the header as well as the
+ // calculation from below
+ bytes rootHash = 3;
+ // branches start from the value, and then may
+ // include multiple subtree branches to embed it
+ //
+ // The first branch must have dataType KeyValue
+ // Following branches must have dataType SubTree
+ repeated Branch branches = 1;
+ }
+ ```
+
+## Appendix D: Universal IBC Packets
+
+The structures above can be used to define standard encodings for the basic IBC transactions that must be exposed by a blockchain: _IBCreceive_, _IBCreceipt_,_ IBCtimeout_, and _IBCcleanup_. As mentioned above, these are not complete transactions to be posted as is to a blockchain, but rather the "data" content of a transaction, which must also contain fees, nonce, and signatures. The other IBC transaction types _IBCregisterChain_, _IBCupdateHeader_, and _IBCchangeValidators_ are specific to the consensus engine and use unique encodings. We define the tendermint-specific format in the next section.
+
+```
+ // IBCPacket sends a proven key/value pair from an IBCQueue.
+ // Depending on the type of message, we require a certain type
+ // of key (MessageKey at a given height, or StateKey).
+ //
+ // Includes src_chain and src_height to look up the proper
+ // header to verify the merkle proof.
+ message IBCPacket {
+ // chain id it is coming from
+ string src_chain = 1;
+ // height for the header the proof belongs to
+ uint64 src_height = 2;
+ // the message type, which determines what key/value mean
+ enum MsgType {
+ RECEIVE = 0;
+ RECEIPT = 1;
+ TIMEOUT = 2;
+ CLEANUP = 3;
+ }
+ MsgType msgType = 3;
+ bytes key = 4;
+ bytes value = 5;
+ // the proof of the message
+ MerkleProof proof = 6;
+ }
+```
+
+## Appendix E: Tendermint Header Proofs
+
+TODO: clean this all up
+
+This is a mess now, we need to figure out what formats we use, define go-wire, etc. or just point to the source???? Will do more later, need help here from the tendermint core team.
+
+In order to prove a merkle root, we must fully define the headers, signatures, and validator information returned from the Tendermint consensus engine, as well as the rules by which to verify a header. We also define here the messages used for creating and removing connections to other blockchains as well as how to handle forks.
+
+**Building Blocks: Header, PubKey, Signature, Commit, ValidatorSet**
+
+**-> needs input/support from Tendermint Core team (and go-crypto)**
+
+**Registering Chain**
+
+**Updating Header**
+
+**Validator Changes**
+
+ROOT of trust
+
+As mentioned in the definitions, all proofs are based on an original assumption. The root of trust here is either the genesis block (if it is newer than the unbonding period) or any signed header of the other chain.
+
+When governance on a pair of chain, the respective chains must agree to a root of trust on the counterparty chain. This can be the genesis block on a chain that launches with an IBC channel or a later block header.
+
+From this signed header, one can check the validator set against the validator hash stored in the header, and then verify the signatures match. This provides internal consistency and accountability, but if 5 nodes provide you different headers (eg. of forks), you must make a subjective decision which one to trust. This should be performed by on-chain governance to avoid an exploitable position of trust.
+
+VERIFYING HEADERS
+
+Once we have a trusted header with a known validator set, we can quickly validate any new header with the same validator set. To validate a new header, simply verifying that the validator hash has not changed, and that over 2/3 of the voting power in that set has properly signed a commit for that header. We can skip all intervening headers, as we have complete finality (no forks) and accountability (to punish a double-sign).
+
+This is safe as long as we have a valid signed header by the trusted validator set that is within the unbonding period for staking. In that case, if we were given a false (forked) header, we could use this as proof to slash the stake of all the double-signing validators. This demonstrates the importance of attribution and is the same security guarantee of any non-validating full node. Even in the presence of some ultra-powerful malicious actors, this makes the cost of creating a fake proof for a header equal to at least one third of all staked tokens, which should be significantly higher than any gain of a false message.
+
+UPDATING VALIDATORS SET
+
+If the validator hash is different than the trusted one, we must simultaneously both verify that if the change is valid while, as well as use using the new set to validate the header. Since the entire validator set is not provided by default when we give a header and commit votes, this must be provided as extra data to the certifier.
+
+A validator change in Tendermint can be securely verified with the following checks:
+
+
+
+* First, that the new header, validators, and signatures are internally consistent
+ * We have a new set of validators that matches the hash on the new header
+ * At least 2/3 of the voting power of the new set validates the new header
+* Second, that the new header is also valid in the eyes of our trust set
+ * Verify at least 2/3 of the voting power of our trusted set, which are also in the new set, properly signed a commit to the new header
+
+In that case, we can update to this header, and update the trusted validator set, with the same guarantees as above (the ability to slash at least one third of all staked tokens on any false proof).
+
+
+
+## Notes
+
+[^1]:
+ [https://github.com/cosmos/cosmos/blob/master/WHITEPAPER.md#inter-blockchain-communication-ibc](https://github.com/cosmos/cosmos/blob/master/WHITEPAPER.md#inter-blockchain-communication-ibc)
+
+[^2]:
+ [http://www.amqp.org/sites/amqp.org/files/amqp.pdf](http://www.amqp.org/sites/amqp.org/files/amqp.pdf)
+
+[^3]:
+ [https://blog.cosmos.network/consensus-compare-casper-vs-tendermint-6df154ad56ae#215d](https://blog.cosmos.network/consensus-compare-casper-vs-tendermint-6df154ad56ae#215d)
+
+[^4]:
+ [https://blog.cosmos.network/light-clients-in-tendermint-consensus-1237cfbda104](https://blog.cosmos.network/light-clients-in-tendermint-consensus-1237cfbda104)
+
+[^5]:
+ [http://scattered-thoughts.net/blog/2012/08/16/causal-ordering/](http://scattered-thoughts.net/blog/2012/08/16/causal-ordering/)
+
+[^6]:
+ [https://github.com/ethereum/wiki/wiki/RLP](https://github.com/ethereum/wiki/wiki/RLP)
+
+[^7]:
+ [https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/)
+
+[^8]:
+ [https://github.com/tendermint/go-wire](https://github.com/tendermint/go-wire)
+
+[^9]:
+ [https://developers.google.com/protocol-buffers/docs/proto3](https://developers.google.com/protocol-buffers/docs/proto3)
+
+[^10]:
+ [https://en.wikipedia.org/wiki/Merkle_tree](https://en.wikipedia.org/wiki/Merkle_tree)
+
+[^11]:
+ [https://chainpoint.org/](https://chainpoint.org/)
+
+[^12]:
+ [https://github.com/tendermint/iavl](https://github.com/tendermint/iavl)