Skip to content

Commit

Permalink
High-Level Documentation (paritytech#565)
Browse files Browse the repository at this point in the history
* High level docs - start.

* Clean up README

* Start adding details to high level docs

* More docs on the header sync pallet

* Testing scenarios document.

* Add some scenarios.

* Add multi-sig scenario.

* Start writing about message dispatch pallet

* Move content from old README into PoA specific doc

* Apply suggestions from code review

Co-authored-by: Andreas Doerr <[email protected]>

* GRANDPA for consistency.

* Describe scenario steps.

* WiP

* Add notes about block production and forks

* Update.

* Add sequence diagram for Millau to Rialto transfer

* Clean up header sync pallet overview

* Remove leftover example code

* Clean up testing scenarios and amend sequence diagram.

* Linking docs.

* Add some more docs.

* Do a bit of cleanup on the high-level docs

* Clean up the testing scenario

* Fix typos in flow charts

* Fix small typo

* Fix indentation of Rust block

* Another attempt at rendering block correctly

* TIL about lazy list numbering in Markdown

* Add list numbers across sections

* Start counting from correct number

* Update README to use correct path to local scripts

* Wrap ASCII art in code block

Co-authored-by: Tomasz Drwięga <[email protected]>
Co-authored-by: Tomasz Drwięga <[email protected]>
Co-authored-by: Andreas Doerr <[email protected]>
  • Loading branch information
4 people authored and serban300 committed Apr 8, 2024
1 parent 42a7aac commit e23542f
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 185 deletions.
238 changes: 78 additions & 160 deletions bridges/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,18 @@

This is a collection of components for building bridges.

These components include runtime modules to help you construct your bridge's runtime, as well as
bridge relays for cross-chain communication.
These components include Substrate pallets for syncing headers, passing arbitrary messages, as well
as libraries for building relayers to provide cross-chain communication capabilities.

A bridge node is also available. The node can be used to run a test network which has support for bridging Ethereum
PoA chains to Substrate. We're working on expanding this functionality in the future.
Three bridge nodes are also available. The nodes can be used to run test networks which bridge other
Substrate chains or Ethereum Proof-of-Authority chains.

🚧 The bridges are currently under construction - a hardhat is recommended beyond this point 🚧

## Contents
- [Installation](#installation)
- [High-Level Architecture](#high-level-architecture)
- [Project Layout](#project-layout)
- [Rialto Runtime](#rialto-runtime)
- [Ethereum Node](#ethereum-node)
- [Bridge Relay](#bridge-relay)
- [Running the Bridge](#running-the-bridge)

## Installation
Expand All @@ -40,199 +38,119 @@ If you need more information about setting up your development environment Subst
[Getting Started](https://substrate.dev/docs/en/knowledgebase/getting-started/) page is a good
resource.

## Project Layout
Here's an overview of how the project is laid out. The main bits are the `node`, which is the actual
"blockchain", the `modules` which are used to build the blockchain's logic (a.k.a the runtime) and
the `relays` which are used to pass messages between chains.

```
├── bin
│ └── node // Bridge ready chain implementation
├── modules // Runtime Modules
│ ├── ethereum // Manage Ethereum PoA chain info
│ ├── ethereum-contract // Ethereum built-in for validating Substrate block info
│ ├── currency-exchange // Cross-chain fund transfers
│ └── substrate // Manage Substrate chain info
├── primitives // Shared runtime and node code
│ └── ethereum-poa // Helpers for Ethereum PoA
├── relays // Cross-chain communication
│ ├── ethereum // Sync and communicate between Ethereum PoA + Substrate chains
│ └── substrate // 🚧 WIP 🚧
```

## Rialto Runtime
The node runtime consists of several runtime modules, however not all of them are used at the same
time. When running an Ethereum PoA to Substrate bridge the modules required are the Ethereum module
and the currency exchange module. When running a Substrate to Substrate bridge the Substrate and
currency exchange modules are required.

Below is a brief description of each of the runtime modules.

### Ethereum Bridge Runtime Module
The main job of this runtime module is to keep track of useful information an Ethereum PoA chain
which has been submitted by a bridge relayer. This includes:
## High-Level Architecture

- Ethereum headers and their status (e.g are they the best header, are they finalized, etc.)
- Current validator set, and upcoming validator sets

This runtime module has more responsibilties than simply storing headers and validator sets. It is
able to perform checks on the incoming headers to verify their general integrity, as well as whether
or not they've been finalized by the authorities on the PoA chain.

This module is laid out as so:
This repo has support for bridging foreign chains together using a combination of Substrate pallets
and external processes called relayers. A bridge chain is one that is able to follow the consensus
of a foreign chain independently. For example, consider the case below where we want to bridge two
Substrate based chains.

```
├── ethereum
│ └── src
│ ├── error.rs // Runtime error handling
│ ├── finality.rs // Manage finality operations
│ ├── import.rs // Import new Ethereum headers
│ ├── lib.rs // Store headers and validator set info
│ ├── validators.rs // Track current and future PoA validator sets
│ └── verification.rs // Verify validity of incoming Ethereum headers
+---------------+ +---------------+
| | | |
| Rialto | | Millau |
| | | |
+-------+-------+ +-------+-------+
^ ^
| +---------------+ |
| | | |
+-----> | Bridge Relay | <-------+
| |
+---------------+
```

### Currency Exchange Runtime Module
The currency exchange module is used to faciliate cross-chain funds transfers. It works by accepting
a transaction which proves that funds were locked on one chain, and releases a corresponding amount
of funds on the recieving chain.

For example: Alice would like to send funds from chain A to chain B. What she would do is send a
transaction to chain A indicating that she would like to send funds to an address on chain B. This
transaction would contain the amount of funds she would like to send, as well as the address of the
recipient on chain B. These funds would now be locked on chain A. Once the block containing this
"locked-funds" transaction is finalized it can be relayed to chain B. Chain B will verify that this
transaction was included in a finalized block on chain A, and if successful deposit funds into the
recipient account on chain B.

Chain B would need a way to convert from a foreign currency to its local currency. How this is done
is left to the runtime developer for chain B.

This module is one example of how an on-chain light client can be used to prove a particular action
was taken on a foreign chain. In particular it enables transfers of the foreign chain's native
currency, but more sophisticated modules such as ERC20 token transfers or arbitrary message transfers
are being worked on as well.
The Millau chain must be able to accept Rialto headers and verify their integrity. It does this by
using a runtime module designed to track GRANDPA finality. Since two blockchains can't interact
directly they need an external service, called a relayer, to communicate. The relayer will subscribe
to new Rialto headers via RPC and submit them to the Millau chain for verification.

### Substrate Bridge Runtime Module
👷 Under Construction 👷‍♀️
Take a look at [Bridge High Level Documentation](./docs/high-level-overview.md) for more in-depth
description of the bridge interaction.

## Ethereum Node
On the Ethereum side of things, we require two things. First, a Solidity smart contract to track the
Substrate headers which have been submitted to the bridge (by the relay), and a built-in contract to
be able to verify that headers have been finalized by the Grandpa finality gadget. Together this
allows the Ethereum PoA chain to verify the integrity and finality of incoming Substrate headers.

The Solidity smart contract is not part of this repo, but can be found
[here](https://github.com/svyatonik/substrate-bridge-sol/blob/master/substrate-bridge.sol) if you're
curious. We have the contract ABI in the `ethereum/relays/res` directory.

## Bridge Relay
The bridge relay is responsible for syncing the chains which are being bridged, and passing messages
between them. The current implementation of the relay supportings syncing and interacting with
Ethereum PoA and Substrate chains.

The folder structure of the bridge relay is as follows:
## Project Layout
Here's an overview of how the project is laid out. The main bits are the `node`, which is the actual
"blockchain", the `modules` which are used to build the blockchain's logic (a.k.a the runtime) and
the `relays` which are used to pass messages between chains.

```
├── relays
│ ├── ethereum
│ │ ├── res
│ │ │ └── ...
│ │ └── src
│ │ ├── ethereum_client.rs // Interface for Ethereum RPC
│ │ ├── ethereum_deploy_contract.rs // Utility for deploying bridge contract to Ethereum
│ │ ├── ethereum_exchange.rs // Relay proof of PoA -> Substrate exchange transactions
│ │ ├── ethereum_sync_loop.rs // Sync headers from Ethereum, submit to Substrate
│ │ ├── ethereum_types.rs // Useful Ethereum types
│ │ ├── exchange.rs // Relay proof of exchange transactions
│ │ ├── headers.rs // Track synced and incoming block headers
│ │ ├── main.rs // Entry point to binary
│ │ ├── substrate_client.rs // Interface for Substrate RPC
│ │ ├── substrate_sync_loop.rs // Sync headers from Substrate, submit to Ethereum
│ │ ├── substrate_types.rs // Useful Ethereum types
│ │ ├── sync.rs // Sync configuration and helpers
│ │ ├── sync_loop.rs // Header synchronization between source and target chains
│ │ ├── sync_types.rs // Useful sync types
│ │ └── utils.rs // General utilities
```
├── bin // Node and Runtime for the various Substrate chains
│ └── ...
├── deployments // Useful tools for deploying test networks
│ └── ...
├── diagrams // Pretty pictures of the project architecture
│ └── ...
├── modules // Substrate Runtime Modules (a.k.a Pallets)
│ ├── ethereum // Ethereum PoA Header Sync Module
│ ├── substrate // Substrate Based Chain Header Sync Module
│ ├── message-lane // Cross Chain Message Passing
│ └── ...
├── primitives // Code shared between modules, runtimes, and relays
│ └── ...
├── relays // Application for sending headers and messages between chains
│ └── ...
└── scripts // Useful development and maintenence scripts
```

## Running the Bridge

To run the Bridge you need to be able to connect the bridge relay node to the RPC interface of nodes
on each side of the bridge (home & foreign chain). An easy way to build all the required nodes is
through Docker.
on each side of the bridge (source and target chain).

### Local Development Build
There are 3 ways to run the bridge, described below:
- building & running from source,
- building or using Docker images for each individual component,
- running a Docker Compose setup (recommended).

#### Building
### Building

First you'll need to build the bridge node and relay. This can be done as follows:
First you'll need to build the bridge nodes and relay. This can be done as follows:

```bash
# In `parity-bridges-common` folder
cargo build -p rialto-bridge-node
cargo build -p ethereum-poa-relay
```

Next you'll need to clone the following [fork of OpenEthereum](https://github.com/paritytech/openethereum).
If you're doing development which only involves the Ethereum to Substrate side of the bridge you may
use the `master` branch. Otherwise you'll need to checkout the `substrate-builtins-stubs` branch.

```bash
# Should be at the same level as `parity-bridges-common` folder
git clone https://github.com/paritytech/openethereum.git openethereum
git fetch
git checkout substrate-builtins-stubs
cargo build -p millau-bridge-node
cargo build -p substrate-relay
```

If you've checked out the `substrate-builtins-stubs` branch make sure you've cloned the OpenEthereum
repo at the same level as `parity-bridges-common` since it references the repo.

Next you'll need to build the Ethereum node:

```bash
# In `openethereum` folder
cargo build
```

#### Running
### Running

To run a simple dev network you'll can use the scripts located in
[the `scripts` folder](./scripts). Since the relay connects to both the Substrate and Ethereum
chains it must be run last.
[the `scripts` folder](./scripts). Since the relay connects to both Substrate chains it must be run
last.

```bash
# In `parity-bridges-common` folder
./scripts/run-openethereum-node.sh
./scripts/run-rialto-bridge-node.sh
./scripts/run-eth2sub-relay.sh
./deployments/local-scripts/run-rialto-bridge-node.sh
./deployments/local-scripts/run-millau-bridge-node.sh
./deployments/local-scripts/run-millau-to-rialto-relay.sh
./deployments/local-scripts/run-rialto-to-millau-relay.sh
```
At this point you should see the relayer submitting blocks from the Ethereum chain
to the Substrate chain.

At this point you should see the relayer submitting blocks from the Millau Substrate chain to the
Rialto Substrate chain and vice-versa.

### Local Docker Build
If you want to make a Docker container using your local source files you can run the following
command at the top level of the repository:

```bash
docker build . -t bridge-relay-dev
docker build . -t local/rialto-bridge-node --build-arg PROJECT=rialto-bridge-node
docker build . -t local/millau-bridge-node --build-arg PROJECT=millau-bridge-node
docker build . -t local/substrate-relay --build-arg PROJECT=substrate-relay
```

You can also build and run the Substrate based node as follows:
You can then run the network as follows:

```bash
docker build . -t bridge-node-dev --build-arg PROJECT=rialto-bridge-node
```

To run the Substrate node you can do the following:

```bash
docker run -it bridge-node-dev --dev --tmp
docker run -it local/rialto-bridge-node --dev --tmp
docker run -it local/millau-bridge-node --dev --tmp
docker run -it local/substrate-relay
```

Notice that the `docker run` command will accept all the normal Substrate flags. For local
development you should at minimum run with the `--dev` flag or else no blocks will be produced.

### Full Network Docker Setup
See [Deployments README](./deployments/README.md) to learn more about how to run
a more sophisticated test network using `docker-compose` setup.
### Full Network Docker Compose Setup

For a more sophisticated deployment which includes bidirectional header sync, message passing,
monitoring dashboards, etc. see the [Deployments README](./deployments/README.md).
Loading

0 comments on commit e23542f

Please sign in to comment.