tokenbridge/oracle/README.md

272 lines
12 KiB
Markdown
Raw Permalink Normal View History

2019-07-19 10:18:51 +03:00
# POA TokenBridge / Oracle
Oracle responsible for listening to bridge related events and authorizing asset transfers.
## Overview
2019-07-19 10:18:51 +03:00
Please refer to the [POA TokenBridge](../README.md) overview first of all.
The Oracle is deployed on specified validator nodes (only nodes whose private keys correspond to addresses specified in the smart contracts) in the network. It connects to two chains via a Remote Procedure Call (RPC) and is responsible for:
- listening to events related to bridge contracts
- sending transactions to authorize asset transfers
## Architecture
2019-09-18 22:45:13 +03:00
### Native-to-ERC20 and Arbitrary-Message
![Native-to-ERC](Native-to-ERC.png)
### ERC20-to-ERC20 and ERC20-to-Native
![ERC-to-ERC](ERC-to-ERC.png)
### Watcher
A watcher listens for a certain event and creates proper jobs in the queue. These jobs contain the transaction data (without the nonce) and the transaction hash for the related event. The watcher runs on a given frequency, keeping track of the last processed block.
If the watcher observes that the transaction data cannot be prepared, which generally means that the corresponding method of the bridge contract cannot be invoked, it inspects the contract state to identify the potential reason for failure and records this in the logs.
There are three Watchers:
- **Signature Request Watcher**: Listens to `UserRequestForSignature` events on the Home network.
- **Collected Signatures Watcher**: Listens to `CollectedSignatures` events on the Home network.
- **Affirmation Request Watcher**: Depends on the bridge mode.
2019-09-18 22:45:13 +03:00
- `Native-to-ERC20` and `Arbitrary-Message`: Listens to `UserRequestForAffirmation` raised by the bridge contract.
- `ERC20-to-ERC20` and `ERC20-to-Native`: Listens to `Transfer` events raised by the token contract.
### Sender
A sender subscribes to the queue and keeps track of the nonce. It takes jobs from the queue, extracts transaction data, adds the proper nonce, and sends it to the network.
There are two Senders:
- **Home Sender**: Sends a transaction to the `Home` network.
- **Foreign Sender**: Sends a transaction to the `Foreign` network.
### RabbitMQ
[RabbitMQ](https://www.rabbitmq.com/) is used to transmit jobs from watchers to senders.
### Redis DB
Redis is used to store the number of blocks that were already inspected by watchers, and the NOnce (Number of Operation) which was used previously by the sender to send a transaction.
For more information on the Redis/RabbitMQ requirements, see [#90](/../../issues/90). We also provide [useful commands for development](#useful-commands-for-development).
# How to Use
## Deploy the Bridge Contracts
2019-05-21 16:07:32 +03:00
**Note:** The following steps detail the bridge deployment process for development and testing. For deployment in a production environment we recommend using the [Bridge Deployment Playbooks](../deployment/README.md).
1. [Deploy the bridge contracts](https://github.com/poanetwork/tokenbridge-contracts/blob/master/deploy/README.md)
2. Open `bridgeDeploymentResults.json` or copy the JSON output generated by the bridge contract deployment process.
#### Output examples
`Native-to-ERC20` mode example:
```json
{
"homeBridge": {
"address": "0xc60daff55ec5b5ce5c3d2105a77e287ff638c35e",
"deployedBlockNumber": 123321
},
"foreignBridge": {
"address": "0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be",
"deployedBlockNumber": 456654,
"erc677": {
"address": "0x41a29780309dc2582f080f6af89953be3435679a"
}
}
}
```
`ERC20-to-ERC20` mode example:
```json
{
"homeBridge": {
"address": "0x765a0d90e5a5773deacbd94b2dc941cbb163bdab",
"deployedBlockNumber": 789987,
"erc677": {
"address": "0x269f57f5ae5421d084686f9e353f5b7ee6af54c2"
}
},
"foreignBridge": {
"address": "0x7ae703ea88b0545eef1f0bf8f91d5276e39be2f7",
"deployedBlockNumber": 567765
}
}
```
## Install and configure the Oracle
1. [Initialize](../README.md#initializing-the-monorepository) the monorepository.
2. Go to the oracle sub-repository:
```
cd oracle
```
3. Create a `.env` file:
```
cp .env.example .env
```
Consistent variable naming (#198) * Add console.table * First steps in validate script * env rename * Added parameter names * Descriptions * Print and configuration * Added more parameters * Rename gas oracle to gas supplier * More changes * Removed env examples for now * RPC rename * Bridge address rename * More changes * jobs * Renames * Typo * jobs * Changes * jobs * Changes * Monitor changes * jovs * Typo * Changes * REACT_APP_ env prefix * Typo * Rollback changes * Oracle deployment * Defaults * Monitor * Naming * Typo * Typo * Envs * ui deployment * ALl jobs * Vars in ultimate * Lint * Lint * Lint * Another way to add REACT_APP prefixing * Unnecessary mapping * No output timeout * No output timeout * Got rid of ERC20_TOKEN_ADDRESS * Configuration readme * Configuration * Prefixes * timeout * Docs * Docs * docs * docs * docs * Roll back ERC20_TOKEN_ADDRESS for erc-to-erc * Typo * lint * Rollback * ROllback validator * Rollback yarn.lock * dai and wetc update * Rollback ERC20_TOKEN_ADDRESS * erc to native * examples * all jobs * roll back * roll back ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B" * ui env example * typo * Allow rpc for ultimate * Test * ERC20_TOKEN_ADDRESS rollback * Specify port * React port * All jobs * cosmetics * Values * Restore erc20 token * Rearrange example for easier comparision * Rearrange ultimate for easier comparision * Rearrange for easier comparision * Refactor * Conditional app styles * Loading environment variables in react app * Add missing vars for UI in wetc and dai * Bring back test parameters readme * Readme for monitor vars * Reading environment variables in e2e-commons (#207)
2019-09-13 10:11:38 +03:00
2. Fill in the required information using the JSON output data. Check [Configuration](../CONFIGURATION.md) to see their explanation.
## Run the Processes
There are two options to run the TokenBridge processes:
1. Docker containers. This requires [Docker](https://docs.docker.com/install/) and [Docker Compose](https://docs.docker.com/compose/install/). If you are on Linux, it's also recommended that you [create a docker group and add your user to it](https://docs.docker.com/install/linux/linux-postinstall/), so that you can use the CLI without sudo.
2. Yarn Package Manager.
### Docker
- While running the bridge containers for the first time use
```
env ORACLE_VALIDATOR_ADDRESS=<validator address> \
env ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=<validator address private key> \
docker-compose -f docker-compose-build.yml -f docker-compose.yml up -d --build
```
- For further launches (or in case of usage an official docker image) use
```
env ORACLE_VALIDATOR_ADDRESS=<validator address> \
env ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=<validator address private key> \
docker-compose up --d
```
All [watcher](#watcher) & [sender](#sender) services launch when `docker-compose` is called.
Redis and RabbitMQ data are placed in `~/bridge_data` directory.
In case you need to reset your bridge or setup a new one (with different configuration) you must delete this directory to prevent old data from being read.
**Note**: To view the Docker logs:
* `chdir` to the directory containing the `docker-compose.yml` file used to run the bridge instance
* [View the logs](https://docs.docker.com/v17.09/compose/reference/logs/) : `docker-compose logs`
### Yarn
- `redis-server` starts Redis. redis-cli ping will return a pong if Redis is running.
- `rabbitmq-server` starts RabbitMQ. Use rabbitmqctl status to check if RabbitMQ is running.
- `yarn watcher:signature-request`
- `yarn watcher:collected-signatures`
- `yarn watcher:affirmation-request`
- `yarn sender:home`
- `yarn sender:foreign`
### Bridge UI
See the [UI instructions](../ui/README.md) to configure and use the optional Bridge UI.
### Build the image without running the oracle
To build the image change the directory:
```
cd oracle
```
And run the docker composer:
```
docker-compose -f docker-compose-build.yml build
```
## Rollback the Last Processed Block in Redis
If the bridge does not handle an event properly (i.e. a transaction stalls due to a low gas price), the Redis DB can be rolled back. You must identify which watcher needs to re-run. For example, if the validator signatures were collected but the transaction with signatures was not sent to the Foreign network, the `collected-signatures` watcher must look at the block where the corresponding `CollectedSignatures` event was raised.
Execute this command in the bridge root directory:
for local installation:
```shell
bash ./reset-lastBlock.sh <watcher> <block num>
```
for Docker installation:
```shell
docker-compose exec bridge_affirmation bash ./reset-lastBlock.sh <watcher> <block num>
```
where the _watcher_ could be one of:
- `signature-request`
- `collected-signatures`
- `affirmation-request`
## Configuration parameters
Consistent variable naming (#198) * Add console.table * First steps in validate script * env rename * Added parameter names * Descriptions * Print and configuration * Added more parameters * Rename gas oracle to gas supplier * More changes * Removed env examples for now * RPC rename * Bridge address rename * More changes * jobs * Renames * Typo * jobs * Changes * jobs * Changes * Monitor changes * jovs * Typo * Changes * REACT_APP_ env prefix * Typo * Rollback changes * Oracle deployment * Defaults * Monitor * Naming * Typo * Typo * Envs * ui deployment * ALl jobs * Vars in ultimate * Lint * Lint * Lint * Another way to add REACT_APP prefixing * Unnecessary mapping * No output timeout * No output timeout * Got rid of ERC20_TOKEN_ADDRESS * Configuration readme * Configuration * Prefixes * timeout * Docs * Docs * docs * docs * docs * Roll back ERC20_TOKEN_ADDRESS for erc-to-erc * Typo * lint * Rollback * ROllback validator * Rollback yarn.lock * dai and wetc update * Rollback ERC20_TOKEN_ADDRESS * erc to native * examples * all jobs * roll back * roll back ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B" * ui env example * typo * Allow rpc for ultimate * Test * ERC20_TOKEN_ADDRESS rollback * Specify port * React port * All jobs * cosmetics * Values * Restore erc20 token * Rearrange example for easier comparision * Rearrange ultimate for easier comparision * Rearrange for easier comparision * Refactor * Conditional app styles * Loading environment variables in react app * Add missing vars for UI in wetc and dai * Bring back test parameters readme * Readme for monitor vars * Reading environment variables in e2e-commons (#207)
2019-09-13 10:11:38 +03:00
Please refer to [Configuration](../CONFIGURATION.md).
## Useful Commands for Development
### RabbitMQ
Command | Description
--- | ---
`rabbitmqctl list_queues` | List all queues
`rabbitmqctl purge_queue home` | Remove all messages from `home` queue
`rabbitmqctl status` | check if rabbitmq server is currently running
`rabbitmq-server` | start rabbitMQ server
### Redis
Use `redis-cli`
Command | Description
--- | ---
`KEYS *` | Returns all keys
`SET signature-request:lastProcessedBlock 1234` | Set key to hold the string value.
`GET signature-request:lastProcessedBlock` | Get the key value.
`DEL signature-request:lastProcessedBlock` | Removes the specified key.
`FLUSHALL` | Delete all the keys in all existing databases.
`redis-cli ping` | check if redis is running.
`redis-server` | start redis server.
## Testing
```bash
yarn test
```
### E2E tests
See the [E2E README](../oracle-e2e/README.md) for instructions.
*Notice*: for docker-based installations do not forget to add `docker-compose exec bridge_affirmation` before the test commands listed below.
### Native-to-ERC20 Mode Testing
When running the processes, the following commands can be used to test functionality.
- To send deposits to a home contract run `node scripts/native_to_erc20/sendHome.js <tx num>`, where `<tx num>` is how many tx will be sent out to deposit.
- To send withdrawals to a foreign contract run `node scripts/native_to_erc20/sendForeign.js <tx num>`, where `<tx num>` is how many tx will be sent out to withdraw.
### ERC20-to-ERC20 Mode Testing
- To deposit from a Foreign to a Home contract run `node scripts/erc20_to_erc20/sendForeign.js <tx num>`.
- To make withdrawal to Home from a Foreign contract run `node scripts/erc20_to_erc20/sendHome.js <tx num>`.
### ERC20-to-Native Mode Testing
- To deposit from a Foreign to a Home contract run `node scripts/erc20_to_native/sendForeign.js <tx num>`.
- To make withdrawal to Home from a Foreign contract run `node scripts/erc20_to_native/sendHome.js <tx num>`.
### Configuration parameters for testing
| Variable | Description |
|-------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
Consistent variable naming (#198) * Add console.table * First steps in validate script * env rename * Added parameter names * Descriptions * Print and configuration * Added more parameters * Rename gas oracle to gas supplier * More changes * Removed env examples for now * RPC rename * Bridge address rename * More changes * jobs * Renames * Typo * jobs * Changes * jobs * Changes * Monitor changes * jovs * Typo * Changes * REACT_APP_ env prefix * Typo * Rollback changes * Oracle deployment * Defaults * Monitor * Naming * Typo * Typo * Envs * ui deployment * ALl jobs * Vars in ultimate * Lint * Lint * Lint * Another way to add REACT_APP prefixing * Unnecessary mapping * No output timeout * No output timeout * Got rid of ERC20_TOKEN_ADDRESS * Configuration readme * Configuration * Prefixes * timeout * Docs * Docs * docs * docs * docs * Roll back ERC20_TOKEN_ADDRESS for erc-to-erc * Typo * lint * Rollback * ROllback validator * Rollback yarn.lock * dai and wetc update * Rollback ERC20_TOKEN_ADDRESS * erc to native * examples * all jobs * roll back * roll back ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B" * ui env example * typo * Allow rpc for ultimate * Test * ERC20_TOKEN_ADDRESS rollback * Specify port * React port * All jobs * cosmetics * Values * Restore erc20 token * Rearrange example for easier comparision * Rearrange ultimate for easier comparision * Rearrange for easier comparision * Refactor * Conditional app styles * Loading environment variables in react app * Add missing vars for UI in wetc and dai * Bring back test parameters readme * Readme for monitor vars * Reading environment variables in e2e-commons (#207)
2019-09-13 10:11:38 +03:00
| `COMMON_HOME_RPC_URL` | The HTTPS URL(s) used to communicate to the RPC nodes in the Home network. |
| `COMMON_FOREIGN_RPC_URL` | The HTTPS URL(s) used to communicate to the RPC nodes in the Foreign network. |
| `USER_ADDRESS` | An account - the current owner of coins/tokens. |
| `USER_ADDRESS_PRIVATE_KEY` | A private key belonging to the account. |
Consistent variable naming (#198) * Add console.table * First steps in validate script * env rename * Added parameter names * Descriptions * Print and configuration * Added more parameters * Rename gas oracle to gas supplier * More changes * Removed env examples for now * RPC rename * Bridge address rename * More changes * jobs * Renames * Typo * jobs * Changes * jobs * Changes * Monitor changes * jovs * Typo * Changes * REACT_APP_ env prefix * Typo * Rollback changes * Oracle deployment * Defaults * Monitor * Naming * Typo * Typo * Envs * ui deployment * ALl jobs * Vars in ultimate * Lint * Lint * Lint * Another way to add REACT_APP prefixing * Unnecessary mapping * No output timeout * No output timeout * Got rid of ERC20_TOKEN_ADDRESS * Configuration readme * Configuration * Prefixes * timeout * Docs * Docs * docs * docs * docs * Roll back ERC20_TOKEN_ADDRESS for erc-to-erc * Typo * lint * Rollback * ROllback validator * Rollback yarn.lock * dai and wetc update * Rollback ERC20_TOKEN_ADDRESS * erc to native * examples * all jobs * roll back * roll back ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B" * ui env example * typo * Allow rpc for ultimate * Test * ERC20_TOKEN_ADDRESS rollback * Specify port * React port * All jobs * cosmetics * Values * Restore erc20 token * Rearrange example for easier comparision * Rearrange ultimate for easier comparision * Rearrange for easier comparision * Refactor * Conditional app styles * Loading environment variables in react app * Add missing vars for UI in wetc and dai * Bring back test parameters readme * Readme for monitor vars * Reading environment variables in e2e-commons (#207)
2019-09-13 10:11:38 +03:00
| `COMMON_HOME_BRIDGE_ADDRESS` | Address of the bridge in the Home network to send transactions. |
| `HOME_MIN_AMOUNT_PER_TX` | Value (in _eth_ or tokens) to be sent in one transaction for the Home network. This should be greater than or equal to the value specified in the `tokenbridge-contracts/deploy/.env` file. The default value in that file is 500000000000000000, which is equivalent to 0.5. |
| `HOME_TEST_TX_GAS_PRICE` | The gas price (in Wei) that is used to send transactions in the Home network . |
Consistent variable naming (#198) * Add console.table * First steps in validate script * env rename * Added parameter names * Descriptions * Print and configuration * Added more parameters * Rename gas oracle to gas supplier * More changes * Removed env examples for now * RPC rename * Bridge address rename * More changes * jobs * Renames * Typo * jobs * Changes * jobs * Changes * Monitor changes * jovs * Typo * Changes * REACT_APP_ env prefix * Typo * Rollback changes * Oracle deployment * Defaults * Monitor * Naming * Typo * Typo * Envs * ui deployment * ALl jobs * Vars in ultimate * Lint * Lint * Lint * Another way to add REACT_APP prefixing * Unnecessary mapping * No output timeout * No output timeout * Got rid of ERC20_TOKEN_ADDRESS * Configuration readme * Configuration * Prefixes * timeout * Docs * Docs * docs * docs * docs * Roll back ERC20_TOKEN_ADDRESS for erc-to-erc * Typo * lint * Rollback * ROllback validator * Rollback yarn.lock * dai and wetc update * Rollback ERC20_TOKEN_ADDRESS * erc to native * examples * all jobs * roll back * roll back ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B" * ui env example * typo * Allow rpc for ultimate * Test * ERC20_TOKEN_ADDRESS rollback * Specify port * React port * All jobs * cosmetics * Values * Restore erc20 token * Rearrange example for easier comparision * Rearrange ultimate for easier comparision * Rearrange for easier comparision * Refactor * Conditional app styles * Loading environment variables in react app * Add missing vars for UI in wetc and dai * Bring back test parameters readme * Readme for monitor vars * Reading environment variables in e2e-commons (#207)
2019-09-13 10:11:38 +03:00
| `COMMON_FOREIGN_BRIDGE_ADDRESS` | Address of the bridge in the Foreign network to send transactions. |
| `FOREIGN_MIN_AMOUNT_PER_TX` | Value (in _eth_ or tokens) to be sent in one transaction for the Foreign network. This should be greater than or equal to the value specified in the `tokenbridge-contracts/deploy/.env` file. The default value in that file is 500000000000000000, which is equivalent to 0.5. |
| `FOREIGN_TEST_TX_GAS_PRICE` | The gas price (in Wei) that is used to send transactions in the Foreign network . |
## Contributing
See the [CONTRIBUTING](../CONTRIBUTING.md) document for contribution, testing and pull request protocol.
## License
[![License: LGPL v3.0](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
This project is licensed under the GNU Lesser General Public License v3.0. See the [LICENSE](../LICENSE) file for details.