From 1feb84e2726c268e183ba6e4aa2f5a2ca2631b68 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 13 Feb 2018 20:20:22 +0100 Subject: [PATCH] Cleaned up queue section --- docs/spec/ibc/images/ReceiptError.png | Bin 0 -> 26687 bytes docs/spec/ibc/images/Receipts.png | Bin 0 -> 26870 bytes docs/spec/ibc/queues.md | 317 +++++--------------------- docs/spec/ibc/specification.md | 3 +- 4 files changed, 55 insertions(+), 265 deletions(-) create mode 100644 docs/spec/ibc/images/ReceiptError.png create mode 100644 docs/spec/ibc/images/Receipts.png diff --git a/docs/spec/ibc/images/ReceiptError.png b/docs/spec/ibc/images/ReceiptError.png new file mode 100644 index 0000000000000000000000000000000000000000..6ffa3f9558eaf0bc27f54ab449484320e24ea527 GIT binary patch literal 26687 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 NUMi?RuaGkf`7eI6vKIgV literal 0 HcmV?d00001 diff --git a/docs/spec/ibc/images/Receipts.png b/docs/spec/ibc/images/Receipts.png new file mode 100644 index 0000000000000000000000000000000000000000..19306867c5d1e03338a8809f2407e9af5ac8904b GIT binary patch literal 26870 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 Cisyj< literal 0 HcmV?d00001 diff --git a/docs/spec/ibc/queues.md b/docs/spec/ibc/queues.md index f118361e65..8a2b9beb36 100644 --- a/docs/spec/ibc/queues.md +++ b/docs/spec/ibc/queues.md @@ -12,70 +12,22 @@ To build useful algorithms upon a provable asynchronous messaging primitive, we Causal ordering means that if _x_ is causally before _y_ on chain A, it must also be on chain B. Many events may happen concurrently (unrelated tx on two different blockchains) with no causality relation, but every transaction on the same chain has a clear causality relation (same as the order in the blockchain). -Message passing implies a causal ordering over multiple chains and these can be important for reasoning on the system. Given _x _ +Message passing implies a causal ordering over multiple chains and these can be important for reasoning on the system. Given _x_ → _y_ means _x_ is causally before _y_, and chains A and B, and _a_ ⇒ _b_ means _a_ implies _b_: - +_A:send(msgi )_ → _B:receive(msgi )_ -_ y_ means _x_ is causally before _y_, and chains A and B, and _a_ +_B:receive(msgi )_ → _A:receipt(msgi )_ -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

+_A:send(msgi )_ → _A:send(msgi+1 )_ -_b_ means _a_ implies _b_: +_x_ → _A:send(msgi )_ ⇒ +_x_ → _B:receive(msgi )_ -_A:send(msgi )_ - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -_ B:receive(msgi )_ - -_B:receive(msgi )_ - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -_ A:receipt(msgi )_ - -_A:send(msgi )_ - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -_A:send(msgi+1 )_ - -_x_ - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -_A:send(msgi )_ - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- - _x_ - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -_B:receive(msgi )_ - -_y_ - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -_B:receive(msgi )_ - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- - _y_ - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -_A:receipt(msgi )_ - - - -

>>>>> gd2md-html alert: inline image link here (to images/Cosmos-IBC0.png). Store image on your image server and adjust path/filename if necessary.
(Back to top)(Next alert)
>>>>>

- - -![alt_text](images/Cosmos-IBC0.png "image_tooltip") +_y_ → _B:receive(msgi )_ ⇒ +_y_ → _A:receipt(msgi )_ +![Vector Clock image](https://upload.wikimedia.org/wikipedia/commons/5/55/Vector_Clock.svg) ([https://en.wikipedia.org/wiki/Vector_clock](https://en.wikipedia.org/wiki/Vector_clock)) In this section, we define an efficient implementation of a secure, reliable messaging queue. @@ -88,37 +40,21 @@ We can visualize a queue as a slice pointing into an infinite sized array. It ma **init**: _qhead = qtail = 0_ -**peek ** +**peek** ⇒ **m**: _if qhead = qtail { return None } else { return q[qhead] }_ -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -**m**: _if qhead = qtail { return None } else { return q[qhead] }_ - -**pop ** - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -**m**: _if qhead = qtail { return None } else { qhead++; return q[qhead-1] }_ +**pop** ⇒ **m**: _if qhead = qtail { return None } else { qhead++; return q[qhead-1] }_ **push(m)**: _q[qtail] = m; qtail++_ **advance(i)**: _qhead = i; qtail = max(qtail , i)_ -**head ** +**head** ⇒ **i**: _qhead_ -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -**i**: _qhead_ - -**tail** - -

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(Back to top)(Next alert)
>>>>>

- -**i**: _qtail_ +**tail** ⇒ **i**: _qtail_ Based upon this needed functionality, we define a set of keys to be stored in the merkle tree, which allows us to efficiently implement and prove any of the above queries. -**Key:_ (queue name, [head|tail|index])_** +**Key:** _(queue name, [head|tail|index])_ The index is stored as a fixed-length unsigned integer in big endian format, so that the lexicographical order of the byte representation of the key is consistent with their sequence number. This allows us to quickly iterate over the queue, as well as prove the content of a packet (or lack of packet) at a given sequence. _head_ and _tail_ are two special constants that store an integer index, and are chosen such that their serialization cannot collide with any possible index. @@ -132,10 +68,10 @@ As mentioned above, in order for the receiver to unambiguously interpret the mer The queue name must be unambiguously associated with a given connection to another chain, so an observer can prove if a message was intended for chain A or chain B. In order to do so, upon registration of a connection with a remote chain, we create two queues with different names (prefixes). -* _ibc::send_ - all outgoing packets destined to chain A -* _ibc::receipt_ - the results of executing the packets received from chain A +* _ibc::send_ - all outgoing packets destined to chain A +* _ibc::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. +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 @@ -151,86 +87,23 @@ _Vreceipt = (result, [success|error code])_ 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. +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})_ +_(IBCsend(D, type, data)_ ⇒ _Success)_ + ⇒ _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 _ +_A:IBCreceive(S, Mk,v,h)_ ⇒ _match_ + * _qS.receipt =_ ∅ ⇒ _Error("unregistered sender"),_ + * _k = (\_, reciept, \_)_ ⇒ _Error("must be a send"),_ + * _k = (d, \_, \_) and d_ ≠ _A_ ⇒ _Error("sent to a different chain"),_ + * _k = (\_, send, i) and head(qS.receipt)_ ≠ _i_ ⇒ _Error("out of order"),_ + * _Hh_ ∉ _TS_ ⇒ _Error("must submit header for height h"),_ + * _valid(Hh ,Mk,v,h ) = false_ ⇒ _Error("invalid merkle proof"),_ + * _v = (type, data)_ ⇒ _(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). @@ -240,98 +113,22 @@ When we wish to create a transaction that atomically commits or rolls back acros 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_ +_S:IBCreceipt(A, Mk,v,h)_ ⇒ _match_ + * _qA.send =_ ∅ ⇒ _Error("unregistered sender"), _ + * _k = (\_, send, \_)_ ⇒ _Error("must be a recipient"),_ + * _k = (d, \_, \_) and d_ ≠ _S_ ⇒ _Error("sent to a different chain"),_ + * _Hh_ ∉ _TA_ ⇒ _Error("must submit header for height h"),_ + * _not valid(Hh , Mk,v,h )_ ⇒ _Error("invalid merkle proof"),_ + * _k = (\_, receipt, head|tail)_ ⇒ _Error("only accepts message proofs"),_ + * _k = (\_, receipt, i) and head(qS.send)_ ≠ _i_ ⇒ _Error("out of order"),_ + * _v = (\_, error)_ ⇒ _(type, data) := pop(qS.send ); rollbacktype(data); Success_ + * _v = (res, success)_ ⇒ _(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. +![Successful Transaction](images/Receipts.png) - -

>>>>> 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)
>>>>>

- - -![alt_text](images/Cosmos-IBC1.png "image_tooltip") - - - - -

>>>>> 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)
>>>>>

- - -![alt_text](images/Cosmos-IBC2.png "image_tooltip") +![Rejected Transaction](images/ReceiptError.png) ### 3.6 Relay Process @@ -342,27 +139,19 @@ The relay process must have access to accounts on both chains with sufficient ba 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)_ +``` +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. diff --git a/docs/spec/ibc/specification.md b/docs/spec/ibc/specification.md index 21cbe0b6b2..9674abbb32 100644 --- a/docs/spec/ibc/specification.md +++ b/docs/spec/ibc/specification.md @@ -10,7 +10,8 @@ This paper specifies the IBC (inter blockchain communication) protocol, which wa Each chain maintains a local partial order, while inter-chain messages track any cross-chain causality relations. Once two chains have registered a trust relationship, cryptographically provable packets can be securely sent between the chains, using Tendermint's instant finality for quick and efficient transmission. -We currently use this protocol for secure value transfer in the Cosmos Hub, but the protocol can support arbitrary application logic. Details of how Cosmos Hub uses IBC to securely route and transfer value are provided in a separate paper, along with a framework for expressing global invariants. Designing secure communication logic for other types of applications is still an area of research. +We currently use this protocol for secure value transfer in the Cosmos Hub, but the protocol can support arbitrary application logic. Details of how Cosmos Hub uses IBC to securely route and transfer value ar +e provided in a separate paper, along with a framework for expressing global invariants. Designing secure communication logic for other types of applications is still an area of research. The protocol makes no assumptions of block times or network delays in the transmission of the packets between chains and requires cryptographic proofs for every message, and thus is highly robust in a heterogeneous environment with Byzantine actors. This paper explains the requirements and structure of the Cosmos IBC protocol. It aims to provide enough detail to fully understand and analyze the security of the protocol.

>>>>> gd2md-html alert: equation: use MathJax/LaTeX if your publishing platform supports it.
(
Back to top)(Next alert)
>>>>>