Skip to content

Commit

Permalink
Merge pull request #87 from ava-labs/cleanup-docs
Browse files Browse the repository at this point in the history
Cleanup docs
  • Loading branch information
cam-schultz authored Nov 7, 2023
2 parents 7103511 + 28ff12c commit f3449bc
Show file tree
Hide file tree
Showing 21 changed files with 172 additions and 200 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ jobs:
# in subdirectories. The former only checks sol files in the current directory and directories one level down.
- name: Run Lint
run: |
./scripts/local/lint.sh
./scripts/lint.sh
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ docker-compose-run-local.yml
main.log
server.log
tests.test

# Forge documentation
contracts/docs/
84 changes: 51 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# Overview
## Overview

Teleporter is an EVM compatible cross-subnet communication protocol built on top of [Avalanche Warp Messaging (AWM)](https://docs.avax.network/learn/avalanche/awm), and implemented as a Solidity smart contract. It provides a mechanism to asynchronously invoke smart contract functions on other EVM blockchains within Avalanche. Teleporter provides a handful of useful features on top of AWM, such as specifying relayer incentives for message delivery, replay protection, message delivery and execution retries, and a standard interface for sending and receiving messages within a dApp deployed across multiple subnets.

It's important to understand the distinction between Avalanche Warp Messaging and Teleporter. AWM allows subnets to communicate with each other via authenticated messages by providing signing and verification primitives in Avalanchego. These are used by the blockchain VMs to sign outgoing messages and verify incoming messages.

The Teleporter protocol, on the other hand, is implemented at the smart contract level, and is a user-friendly interface to AWM, aimed at dApp developers. All of the message signing and verification is abstracted away from developers. Instead, developers simply call `sendCrossChainMessage` on the `TeleporterMessenger` contract to send a message invoking a smart contract on another subnet, and implement the `ITeleporterReceiver` interface to receive messages on the destination subnet. Teleporter handles all of the message signing and verification, as well as the message delivery and execution.

**Note:** Teleporter and Avalanche Warp Messaging are under active development and may cease to function at any time. This repository is intended to be used for testing and development purposes only and should **not** be used in production.
The Teleporter protocol, on the other hand, is implemented at the smart contract level, and is a user-friendly interface to AWM, aimed at dApp developers. All of the message signing and verification is abstracted away from developers. Instead, developers simply call `sendCrossChainMessage` on the `TeleporterMessenger` contract to send a message invoking a smart contract on another subnet, and implement the `ITeleporterReceiver` interface to receive messages on the destination subnet. Teleporter handles all of the Warp message construction and sending, as well as the message delivery and execution.

- [Overview](#overview)
- [Setup](#setup)
- [Docker Setup](#docker-setup)
- [General Setup](#general-setup)
- [Structure](#structure)
- [Build + Run + Test](#build--run--test)
- [Run tests on Fuji Testnet](#run-tests-on-fuji-testnet)
- [E2E tests](#e2e-tests)
- [Docs](#docs)
- [Resources](#resources)
- [Setup](#setup)
- [Docker Setup](#docker-setup)
- [General Setup](#general-setup)
- [Structure](#structure)
- [Build + Run + Test](#build--run--test)
- [Run tests on Fuji Testnet](#run-tests-on-fuji-testnet)
- [E2E tests](#e2e-tests)
- [Docs](#docs)
- [Resources](#resources)

## Setup

### Docker Setup

- Install Docker:

```
Expand Down Expand Up @@ -57,32 +57,41 @@ docker run hello-world # This should work without sudo now
- Note that as you develop and continuously build Docker images, it will eat up continuously more disk space. Periodically you'll want to remedy this be removing everything Docker has built: `docker system prune --all --volumes --force`

### General Setup

The above steps are sufficient to run the included integration tests inside Docker containers. If you wish to run them outside docker, you'll need to install the following dependencies:
- [Foundry](https://book.getfoundry.sh/getting-started/installation)
- [Python3](https://www.python.org/downloads/)

## Structure

- `contracts/` is a [Foundry](https://github.com/foundry-rs/foundry) project that includes the implementation of the `TeleporterMessenger` contract and example dApps that demonstrate how to write contracts that interact with Teleporter.
- `abi-bindings/` includes Go ABI bindings for the contracts in `contracts/`.
- `tests/` includes integration tests for the contracts in `contracts/`, written using the [Ginkgo](https://onsi.github.io/ginkgo/) testing framework.
- `utils/` includes Go utility functions for interacting with the contracts in `contracts/`. Included are Golang scripts to derive the expected EVM contract address deployed from a given EOA at a specific nonce, and also construct a transaction to deploy provided byte code to the same address on any EVM chain using [Nick's method](https://yamenmerhi.medium.com/nicks-method-ethereum-keyless-execution-168a6659479c#).
- `subnet-evm/` is the public subnet-evm repository (included as a submodule) checked out on the `warp-contract` branch with our changes.
- `contract-deployment/` includes Golang scripts to derive the expected EVM contract address deployed from a given EOA at a specific nonce, and also construct a transaction to deploy provided byte code to the same address on any EVM chain using [Nick's method](https://yamenmerhi.medium.com/nicks-method-ethereum-keyless-execution-168a6659479c#).
- `contracts/` is a [foundry](https://github.com/foundry-rs/foundry) project that includes the implementation of the `TeleporterMessenger` contract and other dApps that serve as examples for how to write contracts that interact with Teleporter.
- `scripts/` includes scripts to run Teleporter and integration tests.
- Note that all the scripts should be run from the root of the repository.
- `scripts/local/` includes scripts to run Teleporter in Docker containers and tests in the `scripts/local/integration-tests` locally.
- `scripts/` includes bash scripts for interacting with Teleporter in various environments, as well as utility scripts.
- `abi_bindings.sh` generates ABI bindings for the contracts in `contracts/` and outputs them to `abi-bindings/`.
- `lint.sh` lints the contracts in `contracts/`.
- `scripts/local/` includes scripts for running Teleporter in Docker containers and for running the tests in the `scripts/local/integration-tests` locally.
- `scripts/local/integration-tests/` includes integration test scripts written in bash. The scripts use `foundry` to deploy smart contracts that use Teleporter, send transactions to interact with the contracts, and check that cross-chain messages have the expected effect on destination chains.
- `scripts/fuji/` includes scripts to interact with a live Teleporter deployment on Fuji subnets.
- `scripts/fuji/example-workflows/` includes example workflows that send transactions to interact with Teleporter contracts on Fuji subnets.
- `docker/` includes containerized setup for running a local setup of Teleporter, as well as a script to run each of the integration tests against the local network.
- *Note* These tests will be deprecated in favor of the end to end tests in `tests/`, written using the [Ginkgo](https://onsi.github.io/ginkgo/) testing framework.
- `scripts/fuji/` includes scripts to interact with a live Teleporter deployment on Fuji subnets.
- `scripts/fuji/example-workflows/` includes example workflows that send transactions to interact with Teleporter contracts on [Fuji](https://docs.avax.network/learn/avalanche/fuji) subnets.
- `docker/` includes configurations for a local, containerized setup of Teleporter.

## Build + Run + Test
## Run the Docker integration tests

- Get all submodules: `git submodule update --init --recursive`
- Install Docker as described in the setup section of the README in the root of this repository.
- If we are using a local version of the `awm-relayer` image, build it using `./scripts/build_local_image.sh` from the root of `awm-relayer` repository.
- If we are using a local version of the `awm-relayer` image, build it using `./scripts/build_local_image.sh` from the root of the `awm-relayer` repository.

### Start up the local testnet

- Run `./scripts/local/run.sh` to run the local testnet in Docker containers with the ability to interact with the nodes directly.
- `./scripts/local/run.sh` usage is as follows:
```
-l, --local-relayer-image <tag> Use a local AWM Relayer image instead of pulling from dockerhub
-p, --pause Pause the network on stop. Will attempt to restart the paused network on subsequent runs
-h, --help Print this help message
```
- Note that if `-l, --local` is not set, then the latest published `awm-relayer` image will be pulled from Dockerhub.
Expand All @@ -93,11 +102,11 @@ cast send --private-key 0x56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5c
cast balance --rpc-url http://127.0.0.1:9652/ext/bc/C/rpc 0x333d17d3b42bf7930dbc6e852ca7bcf560a69003
```

- After calling `./scripts/local/run.sh`, you can directly send messages between the deployed subnets (in comparison, calling `./scripts/local/test.sh` runs the same setup steps, then runs the tests in `./scripts/integration-tests/` automatically). As an example, `./scripts/integration-tests/basic_send_receive.sh` can be run manually like so:
- After calling `./scripts/local/run.sh`, you can directly send messages between the deployed subnets. As an example, `./scripts/integration-tests/basic_send_receive.sh` can be run manually like so:

```
# Open a shell in the container
docker exec -it relayer_run /bin/bash
docker exec -it local_network_run /bin/bash
# In the container:
set -a # export all variables so child processes can access
source vars.sh
Expand All @@ -112,6 +121,7 @@ source vars.sh
-t, --test <test_name> Run a specific test. If empty, runs all tests in the ./scripts/local/integration-tests/
-t, --test "test1 test2" Run multiple tests. Test names must be space delimited and enclosed in quotes
-l, --local-relayer-image <tag> Use a local AWM Relayer image instead of pulling from dockerhub
-p, --pause Pause the network on stop. Will attempt to restart the paused network on subsequent runs
-h, --help Print this help message
```
- Note that if `-l, --local` is not set, then the latest published `awm-relayer` image will be pulled from Dockerhub.
Expand All @@ -121,13 +131,21 @@ source vars.sh
./run_stop.sh # stop the running containers and preserve the network for subsequent runs
./run_stop.sh -c # stop the running containers and clean the network
```
- Additional Notes:
- Both the `./scripts/local/run.sh` and `./scripts/local/test.sh` scripts run local five node networks, with each of the nodes validating the primary network and three subnets (Subnet A, Subnet B, and Subnet C).
- Logs from the subnets on one of the five nodes are printed to stdout when run using either script.
- These logs can also be found at `~/.avalanche-cli/runs/network-runner-root-data_<DATE>_<TIMESTAMP>/node{1,5]/logs/<SUBNET_ID>.log`, or at `/var/lib/docker/overlay2/<CONTAINER_ID>/merged/root/.avalanche-cli/....` on your local machine. You will need to be the root user to access the logs under `/var/lib`.

### Run the integration tests in Docker containers

- Run `./scripts/local/test.sh` to run the integration tests in Docker containers. See the section above for usage.
- This script performs the same setup steps as `scripts/local/run.sh` (described above), and then runs the tests in `./scripts/integration-tests/` automatically

### Additional notes

- Both the `./scripts/local/run.sh` and `./scripts/local/test.sh` scripts run five local network nodes, with each of the nodes validating the primary network and three subnets (Subnet A, Subnet B, and Subnet C).
- Logs from the subnets on one of the five nodes are printed to stdout when run using either script.
- These logs can also be found at `~/.avalanche-cli/runs/network-runner-root-data_<DATE>_<TIMESTAMP>/node{1,5]/logs/<SUBNET_ID>.log` in the `local_network_run` container, or at `/var/lib/docker/overlay2/<CONTAINER_ID>/merged/root/.avalanche-cli/....` on your local machine. You will need to be the root user to access the logs under `/var/lib`.

### Run tests on Fuji Testnet
The following steps will allow you to run integration tests and example workflows against three Fuji subnets that have AWM enabled. These workflows send transaction on each of these subnets, so you will need to fund your account with some native tokens to pay for gas fees. The three subnets are called [Amplify](https://subnets-test.avax.network/amplify), [Bulletin](https://subnets-test.avax.network/bulletin), and [Conduit](https://subnets-test.avax.network/conduit).

The following steps will allow you to run the integration tests described above and example workflows against three Fuji subnets that have AWM enabled. These workflows send transaction on each of these subnets, so you will need to fund your account with some native tokens to pay for gas fees. The three subnets are called [Amplify](https://subnets-test.avax.network/amplify), [Bulletin](https://subnets-test.avax.network/bulletin), and [Conduit](https://subnets-test.avax.network/conduit).

The configuration for all the subnets is in `.env.testnet`. If needed, you can change the subnet IDs, the chain IDs, urls and teleporter contract address to match your setup.

Expand Down Expand Up @@ -160,16 +178,16 @@ source .env.testnet
source .env
```

### E2E tests
## E2E tests

E2E tests are ran as part of CI, but can also be ran locally with the `--local` flag. To run the E2E tests locally, you'll need to install Gingko following the intructions [here](https://onsi.github.io/ginkgo/#installing-ginkgo)
E2E tests are run as part of CI, but can also be run locally with the `--local` flag. To run the E2E tests locally, you'll need to install Gingko following the instructions [here](https://onsi.github.io/ginkgo/#installing-ginkgo)

Next, provide the path to the `subnet-evm` repository and the path to a writeable data directory (here we use the `subnet-evm` submodule and `~/tmp/e2e-test`) to use for the tests:
```bash
./scripts/local/e2e_test.sh --local --subnet-evm ./subnet-evm --data-dir ~/tmp/e2e-test
```

### ABI Bindings
## ABI Bindings

To generate Golang ABI bindings for the Solidity smart contracts, run:
```bash
Expand Down

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ This directory is set up as a [Foundry](https://github.com/foundry-rs/foundry) p
- To compile the contracts run `forge build` from this directory.
- Similarly, to run unit tests, run `forge test`.
- See additional testing and deployment options [here](https://book.getfoundry.sh/forge/).

## Generate documentation
- Documentation can be generated by running `forge doc --build` from this repository. By default, this will generate documentation to `contracts/docs/`, and an HTML book to `contracts/docs/book/`. It's also possible to serve this book locally by running `forge doc --serve <PORT>`.
12 changes: 6 additions & 6 deletions contracts/src/CrossChainApplications/ERC20Bridge/ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ contract ERC20Bridge is
uint256 public constant TRANSFER_BRIDGE_TOKENS_REQUIRED_GAS = 300_000;

/**
* @dev Initializes the Teleporter messenger used for sending and receiving messages,
* @dev Initializes the Teleporter Messenger used for sending and receiving messages,
* and initializes the current chain ID.
*/
constructor(
Expand Down Expand Up @@ -390,7 +390,7 @@ contract ERC20Bridge is
* Emits a {CreateBridgeToken} event.
*
* Note: This function is only called within `receiveTeleporterMessage`, which can only be
* called by the Teleporter messenger.
* called by the Teleporter Messenger.
*/
function _createBridgeToken(
bytes32 nativeChainID,
Expand Down Expand Up @@ -438,7 +438,7 @@ contract ERC20Bridge is
* Emits a {MintBridgeTokens} event.
*
* Note: This function is only called within `receiveTeleporterMessage`, which can only be
* called by the Teleporter messenger.
* called by the Teleporter Messenger.
*/
function _mintBridgeTokens(
bytes32 nativeChainID,
Expand Down Expand Up @@ -472,7 +472,7 @@ contract ERC20Bridge is
* and optionally routing them to a different third chain.
*
* Note: This function is only called within `receiveTeleporterMessage`, which can only be
* called by the Teleporter messenger.
* called by the Teleporter Messenger.
*/
function _transferBridgeTokens(
bytes32 sourceChainID,
Expand Down Expand Up @@ -571,7 +571,7 @@ contract ERC20Bridge is
ITeleporterMessenger teleporterMessenger = teleporterRegistry
.getLatestTeleporter();

// Allow the Teleporter messenger to spend the fee amount.
// Allow the Teleporter Messenger to spend the fee amount.
if (feeAmount > 0) {
IERC20(nativeContractAddress).safeIncreaseAllowance(
address(teleporterMessenger),
Expand Down Expand Up @@ -630,7 +630,7 @@ contract ERC20Bridge is
.getLatestTeleporter();

// If necessary, transfer the primary fee amount to this contract and approve the
// Teleporter messenger to spend it when the first message back to the native subnet
// Teleporter Messenger to spend it when the first message back to the native subnet
// is submitted. The secondary fee amount is then handled by the native subnet when
// submitting a message to the destination chain, if applicable.
uint256 adjustedPrimaryFeeAmount = 0;
Expand Down
Loading

0 comments on commit f3449bc

Please sign in to comment.