diff --git a/docs/architecture/README.md b/docs/architecture/README.md index 89f739a02..7cbb035e8 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -1,6 +1,6 @@ # Architecture Decision Records (ADR) -This is a location to record all high-level architecture decisions in the Tendermint-RS project. +This is a location to record all high-level architecture decisions in the IBC-RS project. You can read more about the ADR concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t). @@ -27,5 +27,5 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov | ADR \# | Description | Status | | ------ | ----------- | ------ | -| [001](./adr-001-repo.md) | Repository structure for `ibc-rs` | | -| [002](./adr-002-relayer.md) | IBC Relayer | | +| [001](./adr-001-repo.md) | Repository structure for `ibc-rs` | Proposed | +| [002](./adr-002-ibc-relayer.md) | IBC Relayer in Rust | | diff --git a/docs/architecture/adr-001-repo.md b/docs/architecture/adr-001-repo.md index 269b0834a..a53124bd1 100644 --- a/docs/architecture/adr-001-repo.md +++ b/docs/architecture/adr-001-repo.md @@ -1,36 +1,167 @@ # ADR 001: Repository Structure ## Changelog -* {date}: {changelog} + +* 2020-07-22: First draft. ## Context -> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high level idea behind the solution. +This document provides a basic rundown of the structure of this repository, plus some plans for its evolution. + +This repository comprises a Rust implementation of the [IBC](https://github.com/cosmos/ics) suite of protocols. +To complement this implementation, this repository also comprises specifications, primarily written in TLA+, and +sometimes in English. + +At the moment we are invested mostly in the development of a relayer and several important modules (client, connection, +channel, and packets). +Eventually, we hope to cover the full IBC suite. + ## Decision -> This section explains all of the details of the proposed solution, including implementation details. -It should also describe affects / corollary items that may need to be changed as a part of this. -If the proposed change will be large, please also indicate a way to do the change to maximize ease of review. -(e.g. the optimal split of things to do between separate PR's) +The `ibc-rs` repository comprises three broad parts: -## Status +1. The codebase for the IBC relayer implementation in Rust is in `relayer/`, which consists of crate **`relayer-cli`** (the +frontend application of the relayer) as well as crate **`relayer`** (the core relayer functionality). +2. The codebase for IBC modules is in `modules/`, making up the crate called **`relayer-modules`**. +3. English and TLA+ specs reside under `docs/spec`, classified by the component they target, e.g., relayer or connection +handshake. -> A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement. +Following the work in [#142](https://github.com/informalsystems/ibc-rs/issues/142), the crate +**`ibc-proto`**(originally in a [separate repo](https://github.com/informalsystems/ibc-proto) and [documented here](https://docs.rs/ibc-proto/)) +shall also become absorbed into the present repo. -{Deprecated|Proposed|Accepted} +In the following, we discuss the current state and proposed evolution of each of the Rust crates. -## Consequences +#### Crate `relayer-cli` + +The basic concern of this crate is to provide user-facing functionality for the IBC relayer. This means +implementing a CLI application that dispatches a _command_ to a specific part of the relayer, and then outputs the +result of executing that command. This crate builds on +[Abscissa](https://docs.rs/abscissa_core/0.5.2/abscissa_core/) to simplify command line parsing, application process +lifecycle, and error handling. + +This crate can accept various sub-commands, e.g. `query` a chain for some specific part of their store, `start` the +relayer, or start the `light` client for a given chain. Note that most commands can be further refined with parameters +(for instance, the `query` command can be issued for a `connection` or `channel` or `client`). The bulk of data types +and logic resides in `relayer/cli/commands`, grouped by each specific command. + +#### Crate `relayer` + +This crate implements the core responsibilities of an IBC relayer. Briefly speaking, there are 3 high-level +requirements on a IBC relayer, in no particular order: + +- __R1.__ ability to interface with IBC-enabled chains, with the purpose of reading their state and submitting transactions to +these chains; +- __R2.__ ability to run a light client for IBC-enabled chains, with the purpose of verifying headers and state of these chains; +- __R3.__ implement the IBC relayer algorithms (ICS 018). + +Some functionality described above overlaps with functionality of IBC Modules. For instance, some logic +that the relayer implements for handling connection handshakes (in ICS18) overlaps with logic in the IBC module specific +for connections (ICS3). Given this overlap, the `relayer-modules` crate serves as the "ground truth" implementing the +said logic, while the `relayer` crate has a natural dependency on `relayer-modules`. + +In addition to the dependency on the IBC Modules, the relayer also depends on the `tendermint-rs` crate. This is +useful in particular for interfacing with the light client implementation from this crate, as well as core data types +such as `SignedHeader`, `Validator`, or `ValidatorSet`. + +[ADR 002](./adr-002-ibc-relayer.md) captures more specific details on the relayer architecture. + +#### Crate `relayer-modules` + +The [canonical IBC specification](https://github.com/cosmos/ics/tree/master/spec/) is modular in the sense of grouping +different components of the specification in modules; for instance, specification _ICS03_ pertains to the abstraction of +IBC connections and the IBC connection handshake protocol, while _ICS04_ pertains to IBC channels and packets. +We group the code in this crate to reflect the modular separation in the canonical IBC specification. + +A few common patterns we employ in this crate are as follows. + +###### `msgs.rs` + +Many IBC protocols involve the receiving and processing of messages. +The protocols for establishing a connection (ICS03) or a channel (ICS04), for example, comprise +the processing of four different types of messages each. +In particular, the data structures representing these messages for connection handshake are `MsgConnectionOpenInit`, +`MsgConnectionOpenTry`, `MsgConnectionOpenAck`, and `MsgConnectionOpenConfirm`. + +The creation and validation of protocol messages for each protocol resides in `msgs.rs` within the respective ICS. +Each of these messages should implement the trait `pub trait Msg`, ensuring that all messages implement a basic +interface allowing them to be routed correctly (via the IBC routing module and with the help of the `route()` method) +or support basic validation. -> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. +###### Error handling -### Positive +Each ICS enumerates specific errors that may occur within `icsX_NAME/error.rs`. +The error-handling pattern here build on [thiserror](https://lib.rs/crates/thiserror) and +[anomaly](https://lib.rs/crates/anomaly) for capturing the context of errors plus backtraces (optional). +Generally speaking, an IBC module constructs and propagates errors to the caller by two patterns: -### Negative +```Rust +return Err(Kind::MissingCounterparty.into()) +``` -### Neutral +or if a context can be supplied this is preferable: -## References +```rust +return Err(Kind::InvalidConnectionHopsLength + .context("validate channel") + .into()); +``` +where the ICS itself defines `Kind::InvalidConnectionHopsLength` and `Kind::MissingCounterparty`. -> Are there any relevant PR comments, issues that led up to this, or articles referrenced for why we made the given design choice? If so link them here! +###### Deserialization + +See the details for the crate `ibc-proto` [below](#crate-ibc-proto). + +#### Crate `ibc_proto` + +The `ibc-proto` library gives a developer access to the Cosmos SDK IBC proto-defined structs directly in Rust. +The canonical IBC structs reside presently in [cosmos-sdk](https://github.com/cosmos/cosmos-sdk/tree/master/proto/ibc), +defined in a proto3 syntax. +We compile these structs via prost directly to .rs files and import them into the other crates typically under the same +name prefixed with "Raw", for example: + +```Rust +use ibc_proto::channel::Channel as RawChannel; +``` + +For any Raw data type that is defined in `ibc-proto` we implement the `TryFromRaw` trait, which serves as a translation +& validation layer between the proto ("Raw") types and the domain types. For example, for a `Channel` we do as follows: + +```Rust +impl TryFromRaw for ChannelEnd { + type RawType = RawChannel; + type Error = anomaly::Error; + + fn try_from(value: RawChannel) -> Result { + // Translate, validate each field from RawChannel into a Channel. + } +``` + +This issue [#130](https://github.com/informalsystems/ibc-rs/issues/130) is a good starting place for more context +on `ibc-proto`. + +### References + +The following resources serve as reference implementations or specifications that we use to guide the development of +the present crates: + +For the IBC relayer: + +- A first implementation of the IBC relayer in Golang is under active development at +[iqlusioninc/relayer](https://github.com/iqlusioninc/relayer). +- The English specification of the relayer algorithm is captured in the +[ICS018](https://github.com/cosmos/ics/tree/master/spec/ics-018-relayer-algorithms) spec. + +For IBC modules: + +- A Golang implementation of IBC modules is under active development as part of the Cosmos SDK, +at [cosmos/cosmos-sdk/x/ibc](https://github.com/cosmos/cosmos-sdk/tree/master/x/ibc). +- The English specifications for IBC modules reside in [cosmos/ics](https://github.com/cosmos/ics/tree/master/spec). + +## Status + +Proposed + +## Consequences -* {reference link} \ No newline at end of file +Not applicable. \ No newline at end of file