Updates after deployment test (#75)
* Force ln to mitigate error when postinstall is repeated * Update readme * Using yarn in place of npm run * Changed env order - home first * Removed gh-pages UI deploy * Readme cosmetics * Removed duplicate bridge overview * Update readme * Update repository address * Update readme * Changed NPM to Yarn everywhere * Update readme * Using tokenbridge monorepo in deployment instead of token-bridge * Update ui/README.md Co-Authored-By: Andrew Gross <andogro@gmail.com> * Revert and/or change as per @akolotov explanation * Removed checkWorker3 that was used in legacy bridge-rust-v1-native-to-erc * Update deployment/oracle/README.md Co-Authored-By: Alexander Kolotov <alexandr.kolotov@gmail.com> * Apply suggestions from code review Co-Authored-By: Alexander Kolotov <alexandr.kolotov@gmail.com> * Update root readme and Update sub-repo readmes to point to root monorepository initialization. * Removed obsolete GET /stuckTransfers * Remove stuckTransfers * Use shell instead of unmaintained docker_service module. Update naming in templates.
This commit is contained in:
parent
1ab4a0eca8
commit
93347b47a8
7
.gitignore
vendored
7
.gitignore
vendored
@ -17,8 +17,8 @@ build
|
|||||||
.idea
|
.idea
|
||||||
.nyc_output
|
.nyc_output
|
||||||
logs/
|
logs/
|
||||||
responses/*
|
|
||||||
!responses/.gitkeep
|
|
||||||
*.err
|
*.err
|
||||||
*.out
|
*.out
|
||||||
data
|
data
|
||||||
@ -44,3 +44,6 @@ Vagrantfile
|
|||||||
vagrant-hosts.yml
|
vagrant-hosts.yml
|
||||||
.vagrant
|
.vagrant
|
||||||
|
|
||||||
|
#monitor
|
||||||
|
monitor/responses/*
|
||||||
|
!monitor/.gitkeep
|
48
README.md
48
README.md
@ -23,10 +23,10 @@ Sub-repositories maintained within this monorepo are listed below.
|
|||||||
| [UI](ui/README.md) | DApp interface to transfer tokens and coins between chains. |
|
| [UI](ui/README.md) | DApp interface to transfer tokens and coins between chains. |
|
||||||
| [Monitor](monitor/README.md) | Tool for checking balances and unprocessed events in bridged networks. |
|
| [Monitor](monitor/README.md) | Tool for checking balances and unprocessed events in bridged networks. |
|
||||||
| [Deployment](deployment/README.md) | Ansible playbooks for deploying cross-chain bridges. |
|
| [Deployment](deployment/README.md) | Ansible playbooks for deploying cross-chain bridges. |
|
||||||
| [Oracle-E2E]() | End to end tests for the Oracle |
|
| [Oracle-E2E](oracle-e2e/README.md) | End to end tests for the Oracle |
|
||||||
| [UI-E2E]() | End to end tests for the UI |
|
| [UI-E2E](ui-e2e/README.md) | End to end tests for the UI |
|
||||||
|
|
||||||
Additionally there are [Solidity contracts](https://github.com/poanetwork/poa-bridge-contracts) used to manage bridge validators, collect signatures, and confirm asset relay and disposal.
|
Additionally there are [Smart Contracts](https://github.com/poanetwork/poa-bridge-contracts) used to manage bridge validators, collect signatures, and confirm asset relay and disposal.
|
||||||
|
|
||||||
## Network Definitions
|
## Network Definitions
|
||||||
|
|
||||||
@ -44,33 +44,55 @@ The POA TokenBridge provides three operational modes:
|
|||||||
- [x] `ERC20-to-ERC20` ERC20-compatible tokens on the Foreign network are locked and minted as ERC20-compatible tokens (ERC677 tokens) on the Home network. When transferred from Home to Foreign, they are burnt on the Home side and unlocked in the Foreign network. This can be considered a form of atomic swap when a user swaps the token "X" in network "A" to the token "Y" in network "B". **More Information: [ERC20-to-ERC20](https://medium.com/poa-network/introducing-the-erc20-to-erc20-tokenbridge-ce266cc1a2d0)**
|
- [x] `ERC20-to-ERC20` ERC20-compatible tokens on the Foreign network are locked and minted as ERC20-compatible tokens (ERC677 tokens) on the Home network. When transferred from Home to Foreign, they are burnt on the Home side and unlocked in the Foreign network. This can be considered a form of atomic swap when a user swaps the token "X" in network "A" to the token "Y" in network "B". **More Information: [ERC20-to-ERC20](https://medium.com/poa-network/introducing-the-erc20-to-erc20-tokenbridge-ce266cc1a2d0)**
|
||||||
- [x] `ERC20-to-Native`: Pre-existing **tokens** in the Foreign network are locked and **coins** are minted in the `Home` network. In this mode, the Home network consensus engine invokes [Parity's Block Reward contract](https://wiki.parity.io/Block-Reward-Contract.html) to mint coins per the bridge contract request. **More Information: [xDai Chain](https://medium.com/poa-network/poa-network-partners-with-makerdao-on-xdai-chain-the-first-ever-usd-stable-blockchain-65a078c41e6a)**
|
- [x] `ERC20-to-Native`: Pre-existing **tokens** in the Foreign network are locked and **coins** are minted in the `Home` network. In this mode, the Home network consensus engine invokes [Parity's Block Reward contract](https://wiki.parity.io/Block-Reward-Contract.html) to mint coins per the bridge contract request. **More Information: [xDai Chain](https://medium.com/poa-network/poa-network-partners-with-makerdao-on-xdai-chain-the-first-ever-usd-stable-blockchain-65a078c41e6a)**
|
||||||
|
|
||||||
## Building, running, linting & tests
|
## Initializing the monorepository
|
||||||
|
|
||||||
To initialize submodules:
|
Clone the repository with submodules:
|
||||||
|
```bash
|
||||||
|
git clone --recursive https://github.com/poanetwork/tokenbridge
|
||||||
|
|
||||||
`git submodule update --init`
|
# or initialize submodules if already cloned without --recursive option:
|
||||||
|
git submodule update --init
|
||||||
|
```
|
||||||
|
|
||||||
To install dependencies:
|
Install dependencies:
|
||||||
|
|
||||||
`yarn install`
|
```
|
||||||
|
yarn install && yarn install:deploy
|
||||||
|
```
|
||||||
|
|
||||||
To build all projects:
|
_**Note**: The installation should be performed with an unprivileged Linux account or with the following flag: `yarn install --unsafe-perm`. [More information](https://docs.npmjs.com/misc/scripts#user)_
|
||||||
|
|
||||||
`yarn run build`
|
Compile the Smart Contracts
|
||||||
|
|
||||||
|
```
|
||||||
|
yarn compile:contracts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Linting
|
||||||
|
|
||||||
Running linter for all JS projects:
|
Running linter for all JS projects:
|
||||||
|
|
||||||
`yarn lint`
|
```
|
||||||
|
yarn lint
|
||||||
|
```
|
||||||
|
|
||||||
Running linter for all Ansible playbooks:
|
Running linter for all Ansible playbooks:
|
||||||
|
|
||||||
- [ansible-lint](https://github.com/ansible/ansible-lint) is required
|
- [ansible-lint](https://github.com/ansible/ansible-lint) is required
|
||||||
|
|
||||||
`yarn ansible-lint`
|
```
|
||||||
|
yarn ansible-lint
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
Running tests for all projects:
|
Running tests for all projects:
|
||||||
|
|
||||||
`yarn test`
|
```
|
||||||
|
yarn test
|
||||||
|
```
|
||||||
|
|
||||||
|
Additionaly there are end-to-end tests for [Oracle](oracle-e2e/README.md) and [UI](ui-e2e/README.md).
|
||||||
|
|
||||||
For details on building, running and developing please refer to respective READMEs in sub-repositories.
|
For details on building, running and developing please refer to respective READMEs in sub-repositories.
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
1. Clone this repository and go to the `deployment/oracle` folder
|
1. Clone this repository and go to the `deployment/oracle` folder
|
||||||
```
|
```
|
||||||
git clone https://github.com/poanetwork/tokenbridge
|
git clone --recursive https://github.com/poanetwork/tokenbridge
|
||||||
cd tokenbridge/deployment/oracle
|
cd tokenbridge/deployment/oracle
|
||||||
```
|
```
|
||||||
2. Create the file `hosts.yml` from `hosts.yml.example`
|
2. Create the file `hosts.yml` from `hosts.yml.example`
|
||||||
@ -53,17 +53,17 @@ cp hosts.yml.example hosts.yml
|
|||||||
|
|
||||||
1. The `group_vars/<bridge_name>.yml` file contains the public bridge parameters. This file is prepared by administrators for each bridge. The validator only needs to add the required bridge name in the hosts.yml file to tell Ansible which file to use.
|
1. The `group_vars/<bridge_name>.yml` file contains the public bridge parameters. This file is prepared by administrators for each bridge. The validator only needs to add the required bridge name in the hosts.yml file to tell Ansible which file to use.
|
||||||
|
|
||||||
`group_vars/example.yml` shows an example configuration for the POA/Sokol - POA/Sokol bridge. Parameter values should match values from the .env file for the token-bridge. See [Configuration parameters](../../oracle/README.md#configuration-parameters) for details.
|
`group_vars/example.yml` shows an example configuration for the POA/Sokol - POA/Sokol bridge. Parameter values should match values from the .env file for the Oracle. See [Configuration parameters](../../oracle/README.md#configuration-parameters) for details.
|
||||||
|
|
||||||
2. You can also add the following parameters in the `group_vars` to change the default behavior of `deployment-bridge` playbooks:
|
2. You can also add the following parameters in the `group_vars` to change the default behavior of `deployment-bridge` playbooks:
|
||||||
|
|
||||||
2.1 `compose_service_user` - specifies users to be created by playbooks. This user will be used to run POA bridge.
|
2.1 `compose_service_user` - specifies users to be created by playbooks. This user will be used to run Token Bridge Oracle.
|
||||||
|
|
||||||
2.2 `bridge_repo` contains address of token-bridge repository. The default value is https://github.com/poanetwork/token-bridge.
|
2.2 `bridge_repo` contains address of Token Bridge Oracle repository. The default value is https://github.com/poanetwork/tokenbridge.
|
||||||
|
|
||||||
2.3 `bridge_repo_branch` points to the specific branch or commit to use with the `bridge_repo`. If `bridge_repo_branch` is not specified, the default (`master`) branch is used.
|
2.3 `bridge_repo_branch` points to the specific branch or commit to use with the `bridge_repo`. If `bridge_repo_branch` is not specified, the default (`master`) branch is used.
|
||||||
|
|
||||||
2.4 `bridge_path` set the path where token-bridge would be installed. By default it point to the home folder of `compose_service_user`
|
2.4 `bridge_path` set the path where Token Bridge Oracle would be installed. By default it point to the home folder of `compose_service_user`
|
||||||
|
|
||||||
2.5 `docker_compose_version` - specifies a version of docker-compose to be installed.
|
2.5 `docker_compose_version` - specifies a version of docker-compose to be installed.
|
||||||
|
|
||||||
@ -97,6 +97,8 @@ To be used with the ansible-playbook command, for example:
|
|||||||
|
|
||||||
* `--private-key=<file_name>` - if private keyfile is required to connect to the ubuntu instance.
|
* `--private-key=<file_name>` - if private keyfile is required to connect to the ubuntu instance.
|
||||||
|
|
||||||
|
* `--user=<username>` - connect as this username
|
||||||
|
|
||||||
## Bridge service commands
|
## Bridge service commands
|
||||||
|
|
||||||
The Bridge service is named `poabridge`. Use the default `SysVinit` commands to `start`, `stop`, `restart`, and `rebuild` the service and to check the `status` of the service.
|
The Bridge service is named `poabridge`. Use the default `SysVinit` commands to `start`, `stop`, `restart`, and `rebuild` the service and to check the `status` of the service.
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
- name: Launch container
|
- name: Launch container
|
||||||
docker_service:
|
shell: docker-compose up -d
|
||||||
project_src: "{{ bridge_path }}"
|
args:
|
||||||
state: present
|
chdir: "{{ bridge_path }}/oracle"
|
||||||
build: yes
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
- name: Slurp docker compose file
|
- name: Slurp docker compose file
|
||||||
slurp:
|
slurp:
|
||||||
src: "{{ bridge_path }}/docker-compose.yml"
|
src: "{{ bridge_path }}/oracle/docker-compose.yml"
|
||||||
register: docker_compose_slurp
|
register: docker_compose_slurp
|
||||||
|
|
||||||
- name: Parse docker compose file
|
- name: Parse docker compose file
|
||||||
@ -15,7 +15,7 @@
|
|||||||
- name: Write new docker-compose file
|
- name: Write new docker-compose file
|
||||||
copy:
|
copy:
|
||||||
content: "{{ docker_compose_parsed | to_yaml }}"
|
content: "{{ docker_compose_parsed | to_yaml }}"
|
||||||
dest: "{{ bridge_path }}/docker-compose.yml"
|
dest: "{{ bridge_path }}/oracle/docker-compose.yml"
|
||||||
|
|
||||||
- name: Set the local container logs configuration file
|
- name: Set the local container logs configuration file
|
||||||
template:
|
template:
|
||||||
|
@ -5,7 +5,7 @@ template(name="DockerLogFileName" type="list") {
|
|||||||
constant(value="/docker.log")
|
constant(value="/docker.log")
|
||||||
}
|
}
|
||||||
|
|
||||||
if $programname startswith 'bridge_' then \
|
if $programname startswith 'oracle_bridge_' then \
|
||||||
?DockerLogFileName
|
?DockerLogFileName
|
||||||
else
|
else
|
||||||
/var/log/docker/no_tag/docker.log
|
/var/log/docker/no_tag/docker.log
|
||||||
|
@ -11,7 +11,7 @@ template(name="RemoteForwardFormat" type="list") {
|
|||||||
property(name="msg")
|
property(name="msg")
|
||||||
}
|
}
|
||||||
|
|
||||||
if $programname startswith 'bridge_' or $programname startswith 'docker' then {
|
if $programname startswith 'oracle_bridge_' or $programname startswith 'docker' then {
|
||||||
action(
|
action(
|
||||||
type="omfwd"
|
type="omfwd"
|
||||||
protocol="{{ syslog_server_port.split(":")[0] }}"
|
protocol="{{ syslog_server_port.split(":")[0] }}"
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
become_user: "{{ compose_service_user }}"
|
become_user: "{{ compose_service_user }}"
|
||||||
shell: docker-compose run --entrypoint "node scripts/getValidatorStartBlocks.js" bridge_affirmation
|
shell: docker-compose run --entrypoint "node scripts/getValidatorStartBlocks.js" bridge_affirmation
|
||||||
args:
|
args:
|
||||||
chdir: "{{ bridge_path }}"
|
chdir: "{{ bridge_path }}/oracle"
|
||||||
register: BLOCKS
|
register: BLOCKS
|
||||||
|
|
||||||
- name: Write blocks
|
- name: Write blocks
|
||||||
blockinfile:
|
blockinfile:
|
||||||
path: "{{ bridge_path }}/.env"
|
path: "{{ bridge_path }}/oracle/.env"
|
||||||
marker: "## {mark} Calculated by scripts/getValidatorStartBlocks.js"
|
marker: "## {mark} Calculated by scripts/getValidatorStartBlocks.js"
|
||||||
block: |
|
block: |
|
||||||
HOME_START_BLOCK={{ (BLOCKS.stdout | from_json).homeStartBlock }}
|
HOME_START_BLOCK={{ (BLOCKS.stdout | from_json).homeStartBlock }}
|
||||||
@ -17,7 +17,7 @@
|
|||||||
become_user: "{{ compose_service_user }}"
|
become_user: "{{ compose_service_user }}"
|
||||||
shell: docker-compose run -e VALIDATOR_ADDRESS_PRIVATE_KEY="{{ VALIDATOR_ADDRESS_PRIVATE_KEY }}" --entrypoint "node scripts/privateKeyToAddress.js" bridge_affirmation
|
shell: docker-compose run -e VALIDATOR_ADDRESS_PRIVATE_KEY="{{ VALIDATOR_ADDRESS_PRIVATE_KEY }}" --entrypoint "node scripts/privateKeyToAddress.js" bridge_affirmation
|
||||||
args:
|
args:
|
||||||
chdir: "{{ bridge_path }}"
|
chdir: "{{ bridge_path }}/oracle"
|
||||||
register: VADDRESS
|
register: VADDRESS
|
||||||
|
|
||||||
- name: Set VALIDATOR_ADDRESS variable
|
- name: Set VALIDATOR_ADDRESS variable
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
- name: Install .env config
|
- name: Install .env config
|
||||||
template:
|
template:
|
||||||
src: .env.j2
|
src: .env.j2
|
||||||
dest: "{{ bridge_path }}/.env"
|
dest: "{{ bridge_path }}/oracle/.env"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
bridge_path: "/home/{{ compose_service_user }}/bridge"
|
bridge_path: "/home/{{ compose_service_user }}/bridge"
|
||||||
bridge_repo: https://github.com/poanetwork/token-bridge.git
|
bridge_repo: https://github.com/poanetwork/tokenbridge.git
|
||||||
bridge_repo_branch: master
|
bridge_repo_branch: master
|
@ -10,7 +10,7 @@
|
|||||||
# Description: Enable service provided by daemon.
|
# Description: Enable service provided by daemon.
|
||||||
### END INIT INFO
|
### END INIT INFO
|
||||||
|
|
||||||
WORKDIR="{{ '/home/' + compose_service_user | default('poadocker') + '/' + bridge_path if bridge_path[:1] != "/" else bridge_path }}"
|
WORKDIR="{{ '/home/' + compose_service_user | default('poadocker') + '/' + bridge_path + '/oracle' if bridge_path[:1] != "/" else bridge_path + '/oracle' }}"
|
||||||
|
|
||||||
#Getting path to private key file and variable name for parsing key file
|
#Getting path to private key file and variable name for parsing key file
|
||||||
keyfile="{{ keyfile_path }}"
|
keyfile="{{ keyfile_path }}"
|
||||||
|
@ -94,34 +94,23 @@ Example of an API
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
* `GET /stuckTransfers` - check stucked transfers that wasnot called by transferAndCall
|
# How to run
|
||||||
```json
|
|
||||||
{
|
|
||||||
|
|
||||||
"stuckTransfers": [
|
## Setup
|
||||||
{
|
|
||||||
"address": "0x6758B7d441a9739b98552B373703d8d3d14f9e62",
|
1. [Initialize](../README.md#initializing-the-monorepository) the monorepository.
|
||||||
"blockNumber": 5964312,
|
|
||||||
"transactionHash": "0x74413ba79509a292d5d0d6edd364b3617c83a57b13d603de9deb6c8e6b6c6daf",
|
2. Go to the monitor sub-repository:
|
||||||
...
|
```
|
||||||
"returnValues": {
|
cd monitor
|
||||||
"0": "0x8D4bbc1B533aB9e3a743210870b6e3c4c0f7E935",
|
|
||||||
"1": "0xd819E948b14cA6AAD2b7Ffd333cCDf732b129EeD",
|
|
||||||
"2": "10000000000000000000000",
|
|
||||||
"from": "0x8D4bbc1B533aB9e3a743210870b6e3c4c0f7E935",
|
|
||||||
"to": "0xd819E948b14cA6AAD2b7Ffd333cCDf732b129EeD",
|
|
||||||
"value": "10000000000000000000000"
|
|
||||||
},
|
|
||||||
...
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"total": 2,
|
|
||||||
"lastChecked": 1535058662
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# How to run
|
3. Create .env file:
|
||||||
Create .env file (see `.env.example` for parameters reference)
|
```
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Example:
|
||||||
```bash
|
```bash
|
||||||
HOME_RPC_URL=https://sokol.poa.network
|
HOME_RPC_URL=https://sokol.poa.network
|
||||||
FOREIGN_RPC_URL=https://kovan.infura.io/mew
|
FOREIGN_RPC_URL=https://kovan.infura.io/mew
|
||||||
@ -133,17 +122,19 @@ GAS_PRICE_FALLBACK=21
|
|||||||
LEFT_TX_THRESHOLD=100
|
LEFT_TX_THRESHOLD=100
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
## Check balances of contracts and validators
|
||||||
npm i
|
```
|
||||||
# check balances of contracts and validators
|
|
||||||
node checkWorker.js
|
node checkWorker.js
|
||||||
# check unprocessed events
|
```
|
||||||
|
|
||||||
|
## Check unprocessed events
|
||||||
|
```
|
||||||
node checkWorker2.js
|
node checkWorker2.js
|
||||||
# check stuck transfers called by transfer, not transferAndCall
|
```
|
||||||
# only applicable for bridge-rust-v1-native-to-erc
|
|
||||||
node checkWorker3.js
|
## Run web interface
|
||||||
# run web interface
|
```
|
||||||
node index.js
|
yarn start
|
||||||
```
|
```
|
||||||
|
|
||||||
To enabled debug logging, set `DEBUG=1` env variable.
|
To enabled debug logging, set `DEBUG=1` env variable.
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
const fs = require('fs')
|
|
||||||
const path = require('path')
|
|
||||||
const logger = require('./logger')('checkWorker3')
|
|
||||||
const stuckTransfers = require('./stuckTransfers')
|
|
||||||
|
|
||||||
async function checkWorker3() {
|
|
||||||
try {
|
|
||||||
logger.debug('calling stuckTransfers()')
|
|
||||||
const transfers = await stuckTransfers()
|
|
||||||
// console.log(transfers)
|
|
||||||
if (!transfers) throw new Error('transfers is empty: ' + JSON.stringify(transfers))
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.join(__dirname, '/responses/stuckTransfers.json'),
|
|
||||||
JSON.stringify(transfers, null, 4)
|
|
||||||
)
|
|
||||||
logger.debug('Done')
|
|
||||||
return transfers
|
|
||||||
} catch (e) {
|
|
||||||
logger.error('checkWorker3.js', e)
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkWorker3()
|
|
@ -1,109 +0,0 @@
|
|||||||
require('dotenv').config()
|
|
||||||
const Web3 = require('web3')
|
|
||||||
const logger = require('./logger')('stuckTransfers.js')
|
|
||||||
|
|
||||||
const { FOREIGN_RPC_URL, FOREIGN_BRIDGE_ADDRESS, ERC20_ADDRESS } = process.env
|
|
||||||
const FOREIGN_DEPLOYMENT_BLOCK = Number(process.env.FOREIGN_DEPLOYMENT_BLOCK) || 0
|
|
||||||
|
|
||||||
const foreignProvider = new Web3.providers.HttpProvider(FOREIGN_RPC_URL)
|
|
||||||
const web3Foreign = new Web3(foreignProvider)
|
|
||||||
|
|
||||||
const ABITransferWithoutData = [
|
|
||||||
{
|
|
||||||
anonymous: false,
|
|
||||||
inputs: [
|
|
||||||
{
|
|
||||||
indexed: true,
|
|
||||||
name: 'from',
|
|
||||||
type: 'address'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
indexed: true,
|
|
||||||
name: 'to',
|
|
||||||
type: 'address'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
indexed: false,
|
|
||||||
name: 'value',
|
|
||||||
type: 'uint256'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
name: 'Transfer',
|
|
||||||
type: 'event'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const ABIWithData = [
|
|
||||||
{
|
|
||||||
anonymous: false,
|
|
||||||
inputs: [
|
|
||||||
{
|
|
||||||
indexed: true,
|
|
||||||
name: 'from',
|
|
||||||
type: 'address'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
indexed: true,
|
|
||||||
name: 'to',
|
|
||||||
type: 'address'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
indexed: false,
|
|
||||||
name: 'value',
|
|
||||||
type: 'uint256'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
indexed: false,
|
|
||||||
name: 'data',
|
|
||||||
type: 'bytes'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
name: 'Transfer',
|
|
||||||
type: 'event'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
function compareTransfers(transfersNormal) {
|
|
||||||
return withData => {
|
|
||||||
return (
|
|
||||||
transfersNormal.filter(normal => {
|
|
||||||
return normal.transactionHash === withData.transactionHash
|
|
||||||
}).length === 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
try {
|
|
||||||
// TODO: ERC20_ADDRESS is no longer an env constant. It has to be extracted from the ForeignBridge Contract.
|
|
||||||
const tokenContract = new web3Foreign.eth.Contract(ABITransferWithoutData, ERC20_ADDRESS)
|
|
||||||
const tokenContractWithData = new web3Foreign.eth.Contract(ABIWithData, ERC20_ADDRESS)
|
|
||||||
logger.debug('calling tokenContract.getPastEvents Transfer')
|
|
||||||
const transfersNormal = await tokenContract.getPastEvents('Transfer', {
|
|
||||||
filter: {
|
|
||||||
to: FOREIGN_BRIDGE_ADDRESS
|
|
||||||
},
|
|
||||||
fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
|
|
||||||
toBlock: 'latest'
|
|
||||||
})
|
|
||||||
logger.debug('calling tokenContractWithData.getPastEvents Transfer')
|
|
||||||
const transfersWithData = await tokenContractWithData.getPastEvents('Transfer', {
|
|
||||||
filter: {
|
|
||||||
to: FOREIGN_BRIDGE_ADDRESS
|
|
||||||
},
|
|
||||||
fromBlock: FOREIGN_DEPLOYMENT_BLOCK,
|
|
||||||
toBlock: 'latest'
|
|
||||||
})
|
|
||||||
const stuckTransfers = transfersNormal.filter(compareTransfers(transfersWithData))
|
|
||||||
logger.debug('Done')
|
|
||||||
return {
|
|
||||||
stuckTransfers,
|
|
||||||
total: stuckTransfers.length,
|
|
||||||
lastChecked: Math.floor(Date.now() / 1000)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
logger.error(e)
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
module.exports = main
|
|
@ -1,4 +1,4 @@
|
|||||||
# oracle-e2e
|
# POA Token Bridge / Oracle-E2E
|
||||||
|
|
||||||
End to end tests for the POA Token Bridge [Oracle](../oracle/README.md).
|
End to end tests for the POA Token Bridge [Oracle](../oracle/README.md).
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ so that you can use the CLI without sudo.
|
|||||||
To run the bridge end-to-end tests, you just have to run:
|
To run the bridge end-to-end tests, you just have to run:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ./run-tests.sh
|
./run-tests.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
If this is the first time that you do this, it will take some time to build the
|
If this is the first time that you do this, it will take some time to build the
|
||||||
|
@ -4,17 +4,17 @@ docker-compose down
|
|||||||
docker-compose up -d --build --force-recreate
|
docker-compose up -d --build --force-recreate
|
||||||
|
|
||||||
docker-compose run e2e yarn workspace oracle-e2e run deploy
|
docker-compose run e2e yarn workspace oracle-e2e run deploy
|
||||||
docker-compose run -d bridge npm run watcher:signature-request
|
docker-compose run -d bridge yarn watcher:signature-request
|
||||||
docker-compose run -d bridge npm run watcher:collected-signatures
|
docker-compose run -d bridge yarn watcher:collected-signatures
|
||||||
docker-compose run -d bridge npm run watcher:affirmation-request
|
docker-compose run -d bridge yarn watcher:affirmation-request
|
||||||
docker-compose run -d bridge-erc npm run watcher:signature-request
|
docker-compose run -d bridge-erc yarn watcher:signature-request
|
||||||
docker-compose run -d bridge-erc npm run watcher:collected-signatures
|
docker-compose run -d bridge-erc yarn watcher:collected-signatures
|
||||||
docker-compose run -d bridge-erc npm run watcher:affirmation-request
|
docker-compose run -d bridge-erc yarn watcher:affirmation-request
|
||||||
docker-compose run -d bridge-erc-native npm run watcher:signature-request
|
docker-compose run -d bridge-erc-native yarn watcher:signature-request
|
||||||
docker-compose run -d bridge-erc-native npm run watcher:collected-signatures
|
docker-compose run -d bridge-erc-native yarn watcher:collected-signatures
|
||||||
docker-compose run -d bridge-erc-native npm run watcher:affirmation-request
|
docker-compose run -d bridge-erc-native yarn watcher:affirmation-request
|
||||||
docker-compose run -d bridge npm run sender:home
|
docker-compose run -d bridge yarn sender:home
|
||||||
docker-compose run -d bridge npm run sender:foreign
|
docker-compose run -d bridge yarn sender:foreign
|
||||||
docker-compose run e2e yarn workspace oracle-e2e run start
|
docker-compose run e2e yarn workspace oracle-e2e run start
|
||||||
|
|
||||||
rc=$?
|
rc=$?
|
||||||
|
@ -49,16 +49,16 @@ For more information on the Redis/RabbitMQ requirements, see [#90](/../../issues
|
|||||||
|
|
||||||
# How to Use
|
# How to Use
|
||||||
|
|
||||||
## Installation and Deployment
|
## Deploy the Bridge Contracts
|
||||||
|
|
||||||
**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).
|
**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).
|
||||||
|
|
||||||
#### Deploy the Bridge Contracts
|
|
||||||
|
|
||||||
1. [Deploy the bridge contracts](https://github.com/poanetwork/poa-bridge-contracts/blob/master/deploy/README.md)
|
1. [Deploy the bridge contracts](https://github.com/poanetwork/poa-bridge-contracts/blob/master/deploy/README.md)
|
||||||
|
|
||||||
2. Open `bridgeDeploymentResults.json` or copy the JSON output generated by the bridge contract deployment process.
|
2. Open `bridgeDeploymentResults.json` or copy the JSON output generated by the bridge contract deployment process.
|
||||||
|
|
||||||
|
#### Output examples
|
||||||
|
|
||||||
`Native-to-ERC20` mode example:
|
`Native-to-ERC20` mode example:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@ -93,9 +93,19 @@ For more information on the Redis/RabbitMQ requirements, see [#90](/../../issues
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Install and configure the Oracle
|
||||||
|
|
||||||
1. Create a `.env` file: `cp .env.example .env`
|
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
|
||||||
|
```
|
||||||
|
|
||||||
2. Fill in the required information using the JSON output data. Check the tables with the [set of parameters](#configuration-parameters) below to see their explanation.
|
2. Fill in the required information using the JSON output data. Check the tables with the [set of parameters](#configuration-parameters) below to see their explanation.
|
||||||
|
|
||||||
@ -103,7 +113,7 @@ For more information on the Redis/RabbitMQ requirements, see [#90](/../../issues
|
|||||||
|
|
||||||
There are two options to run the TokenBridge 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.
|
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. NodeJs Package Manager (NPM).
|
2. Yarn Package Manager.
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
@ -120,19 +130,19 @@ In case you need to reset your bridge or setup a new one (with different configu
|
|||||||
* [View the logs](https://docs.docker.com/v17.09/compose/reference/logs/) : `docker-compose logs`
|
* [View the logs](https://docs.docker.com/v17.09/compose/reference/logs/) : `docker-compose logs`
|
||||||
|
|
||||||
|
|
||||||
### NPM
|
### Yarn
|
||||||
|
|
||||||
- `redis-server` starts Redis. redis-cli ping will return a pong if Redis is running.
|
- `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.
|
- `rabbitmq-server` starts RabbitMQ. Use rabbitmqctl status to check if RabbitMQ is running.
|
||||||
- `npm run watcher:signature-request`
|
- `yarn watcher:signature-request`
|
||||||
- `npm run watcher:collected-signatures`
|
- `yarn watcher:collected-signatures`
|
||||||
- `npm run watcher:affirmation-request`
|
- `yarn watcher:affirmation-request`
|
||||||
- `npm run sender:home`
|
- `yarn sender:home`
|
||||||
- `npm run sender:foreign`
|
- `yarn sender:foreign`
|
||||||
|
|
||||||
### Bridge UI
|
### Bridge UI
|
||||||
|
|
||||||
See the [Bridge UI installation instructions](https://github.com/poanetwork/bridge-ui/) to configure and use the optional Bridge UI.
|
See the [UI instructions](../ui/README.md) to configure and use the optional Bridge UI.
|
||||||
|
|
||||||
## Rollback the Last Processed Block in Redis
|
## Rollback the Last Processed Block in Redis
|
||||||
|
|
||||||
@ -140,7 +150,7 @@ If the bridge does not handle an event properly (i.e. a transaction stalls due t
|
|||||||
|
|
||||||
Execute this command in the bridge root directory:
|
Execute this command in the bridge root directory:
|
||||||
|
|
||||||
for NPM installation:
|
for local installation:
|
||||||
```shell
|
```shell
|
||||||
bash ./reset-lastBlock.sh <watcher> <block num>
|
bash ./reset-lastBlock.sh <watcher> <block num>
|
||||||
```
|
```
|
||||||
@ -210,7 +220,7 @@ Command | Description
|
|||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm test
|
yarn test
|
||||||
```
|
```
|
||||||
|
|
||||||
### E2E tests
|
### E2E tests
|
||||||
|
@ -40,7 +40,7 @@ services:
|
|||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- VALIDATOR_ADDRESS_PRIVATE_KEY=${VALIDATOR_ADDRESS_PRIVATE_KEY}
|
- VALIDATOR_ADDRESS_PRIVATE_KEY=${VALIDATOR_ADDRESS_PRIVATE_KEY}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint: npm run watcher:signature-request
|
entrypoint: yarn watcher:signature-request
|
||||||
networks:
|
networks:
|
||||||
- net_db_bridge_request
|
- net_db_bridge_request
|
||||||
- net_rabbit_bridge_request
|
- net_rabbit_bridge_request
|
||||||
@ -56,7 +56,7 @@ services:
|
|||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- VALIDATOR_ADDRESS=${VALIDATOR_ADDRESS}
|
- VALIDATOR_ADDRESS=${VALIDATOR_ADDRESS}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint: npm run watcher:collected-signatures
|
entrypoint: yarn watcher:collected-signatures
|
||||||
networks:
|
networks:
|
||||||
- net_db_bridge_collected
|
- net_db_bridge_collected
|
||||||
- net_rabbit_bridge_collected
|
- net_rabbit_bridge_collected
|
||||||
@ -72,7 +72,7 @@ services:
|
|||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- VALIDATOR_ADDRESS=${VALIDATOR_ADDRESS}
|
- VALIDATOR_ADDRESS=${VALIDATOR_ADDRESS}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint: npm run watcher:affirmation-request
|
entrypoint: yarn watcher:affirmation-request
|
||||||
networks:
|
networks:
|
||||||
- net_db_bridge_affirmation
|
- net_db_bridge_affirmation
|
||||||
- net_rabbit_bridge_affirmation
|
- net_rabbit_bridge_affirmation
|
||||||
@ -88,7 +88,7 @@ services:
|
|||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- VALIDATOR_ADDRESS_PRIVATE_KEY=${VALIDATOR_ADDRESS_PRIVATE_KEY}
|
- VALIDATOR_ADDRESS_PRIVATE_KEY=${VALIDATOR_ADDRESS_PRIVATE_KEY}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint: npm run sender:home
|
entrypoint: yarn sender:home
|
||||||
networks:
|
networks:
|
||||||
- net_db_bridge_senderhome
|
- net_db_bridge_senderhome
|
||||||
- net_rabbit_bridge_senderhome
|
- net_rabbit_bridge_senderhome
|
||||||
@ -104,7 +104,7 @@ services:
|
|||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- VALIDATOR_ADDRESS_PRIVATE_KEY=${VALIDATOR_ADDRESS_PRIVATE_KEY}
|
- VALIDATOR_ADDRESS_PRIVATE_KEY=${VALIDATOR_ADDRESS_PRIVATE_KEY}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint: npm run sender:foreign
|
entrypoint: yarn sender:foreign
|
||||||
networks:
|
networks:
|
||||||
- net_db_bridge_senderforeign
|
- net_db_bridge_senderforeign
|
||||||
- net_rabbit_bridge_senderforeign
|
- net_rabbit_bridge_senderforeign
|
||||||
|
@ -69,7 +69,7 @@ URL, `http://localhost:8546` as the foreign RPC URL and
|
|||||||
`0xaaB52d66283F7A1D5978bcFcB55721ACB467384b` as the deployer and validator.
|
`0xaaB52d66283F7A1D5978bcFcB55721ACB467384b` as the deployer and validator.
|
||||||
Deploy the contracts.
|
Deploy the contracts.
|
||||||
|
|
||||||
To start the bridge, you can do `npm run dev`, or you can start all the scripts
|
To start the bridge, you can do `yarn dev`, or you can start all the scripts
|
||||||
separately.
|
separately.
|
||||||
|
|
||||||
## Generate a block with several transactions
|
## Generate a block with several transactions
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
"watcher:affirmation-request": "./scripts/start-worker.sh watcher affirmation-request-watcher",
|
"watcher:affirmation-request": "./scripts/start-worker.sh watcher affirmation-request-watcher",
|
||||||
"sender:home": "./scripts/start-worker.sh sender home-sender",
|
"sender:home": "./scripts/start-worker.sh sender home-sender",
|
||||||
"sender:foreign": "./scripts/start-worker.sh sender foreign-sender",
|
"sender:foreign": "./scripts/start-worker.sh sender foreign-sender",
|
||||||
"dev": "concurrently -n 'watcher:signature-request,watcher:collected-signatures,watcher:affirmation-request,sender:home,sender:foreign' -c 'red,green,yellow,blue,magenta' 'npm run watcher:signature-request' 'npm run watcher:collected-signatures' 'npm run watcher:affirmation-request' 'npm run sender:home' 'npm run sender:foreign'",
|
"dev": "concurrently -n 'watcher:signature-request,watcher:collected-signatures,watcher:affirmation-request,sender:home,sender:foreign' -c 'red,green,yellow,blue,magenta' 'yarn watcher:signature-request' 'yarn watcher:collected-signatures' 'yarn watcher:affirmation-request' 'yarn sender:home' 'yarn sender:foreign'",
|
||||||
"test": "NODE_ENV=test mocha",
|
"test": "NODE_ENV=test mocha",
|
||||||
"test:watch": "NODE_ENV=test mocha --watch --reporter=min",
|
"test:watch": "NODE_ENV=test mocha --watch --reporter=min",
|
||||||
"coverage": "NODE_ENV=test nyc --reporter=text --reporter=html mocha",
|
"coverage": "NODE_ENV=test nyc --reporter=text --reporter=html mocha",
|
||||||
|
@ -40,6 +40,6 @@
|
|||||||
"clean": "rm -rf ./node_modules ./**/node_modules ./**/**/node_modules ./**/build",
|
"clean": "rm -rf ./node_modules ./**/node_modules ./**/**/node_modules ./**/build",
|
||||||
"compile:contracts": "yarn workspace poa-parity-bridge-contracts run compile",
|
"compile:contracts": "yarn workspace poa-parity-bridge-contracts run compile",
|
||||||
"install:deploy": "cd contracts/deploy && npm install --silent",
|
"install:deploy": "cd contracts/deploy && npm install --silent",
|
||||||
"postinstall": "ln -s $(pwd)/node_modules/openzeppelin-solidity/ contracts/node_modules/openzeppelin-solidity"
|
"postinstall": "ln -sf $(pwd)/node_modules/openzeppelin-solidity/ contracts/node_modules/openzeppelin-solidity"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,17 @@
|
|||||||
### ui-e2e
|
# POA Token Bridge / UI-E2E
|
||||||
End to end tests for the UI
|
|
||||||
|
End to end tests for the POA Token Bridge [UI](../UI/README.md).
|
||||||
|
|
||||||
- Configure startURL, homeAccount, foreignAccount in ```config.json```
|
- Configure startURL, homeAccount, foreignAccount in ```config.json```
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
To run the bridge end-to-end tests, you just have to run:
|
||||||
|
|
||||||
|
```
|
||||||
|
./run-tests.sh
|
||||||
|
```
|
||||||
|
|
||||||
#### Tests
|
#### Tests
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -6,17 +6,17 @@ docker-compose up -d --build --force-recreate
|
|||||||
node ./scripts/blocks.js &
|
node ./scripts/blocks.js &
|
||||||
|
|
||||||
docker-compose run e2e yarn workspace ui-e2e run deploy
|
docker-compose run e2e yarn workspace ui-e2e run deploy
|
||||||
docker-compose run -d bridge npm run watcher:signature-request
|
docker-compose run -d bridge yarn watcher:signature-request
|
||||||
docker-compose run -d bridge npm run watcher:collected-signatures
|
docker-compose run -d bridge yarn watcher:collected-signatures
|
||||||
docker-compose run -d bridge npm run watcher:affirmation-request
|
docker-compose run -d bridge yarn watcher:affirmation-request
|
||||||
docker-compose run -d bridge-erc20 npm run watcher:signature-request
|
docker-compose run -d bridge-erc20 yarn watcher:signature-request
|
||||||
docker-compose run -d bridge-erc20 npm run watcher:collected-signatures
|
docker-compose run -d bridge-erc20 yarn watcher:collected-signatures
|
||||||
docker-compose run -d bridge-erc20 npm run watcher:affirmation-request
|
docker-compose run -d bridge-erc20 yarn watcher:affirmation-request
|
||||||
docker-compose run -d bridge-erc20-native npm run watcher:signature-request
|
docker-compose run -d bridge-erc20-native yarn watcher:signature-request
|
||||||
docker-compose run -d bridge-erc20-native npm run watcher:collected-signatures
|
docker-compose run -d bridge-erc20-native yarn watcher:collected-signatures
|
||||||
docker-compose run -d bridge-erc20-native npm run watcher:affirmation-request
|
docker-compose run -d bridge-erc20-native yarn watcher:affirmation-request
|
||||||
docker-compose run -d bridge npm run sender:home
|
docker-compose run -d bridge yarn sender:home
|
||||||
docker-compose run -d bridge npm run sender:foreign
|
docker-compose run -d bridge yarn sender:foreign
|
||||||
docker-compose run -d -p 3000:3000 ui yarn workspace ui run start
|
docker-compose run -d -p 3000:3000 ui yarn workspace ui run start
|
||||||
docker-compose run -d -p 3001:3000 ui-erc20 yarn workspace ui run start
|
docker-compose run -d -p 3001:3000 ui-erc20 yarn workspace ui run start
|
||||||
docker-compose run -d -p 3002:3000 ui-erc20-native yarn workspace ui run start
|
docker-compose run -d -p 3002:3000 ui-erc20-native yarn workspace ui run start
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
REACT_APP_HOME_BRIDGE_ADDRESS=0xABb4C1399DcC28FBa3Beb76CAE2b50Be3e087353
|
REACT_APP_HOME_BRIDGE_ADDRESS=0xABb4C1399DcC28FBa3Beb76CAE2b50Be3e087353
|
||||||
REACT_APP_FOREIGN_BRIDGE_ADDRESS=0xE405F6872cE38a7a4Ff63DcF946236D458c2ca3a
|
REACT_APP_FOREIGN_BRIDGE_ADDRESS=0xE405F6872cE38a7a4Ff63DcF946236D458c2ca3a
|
||||||
REACT_APP_FOREIGN_HTTP_PARITY_URL=https://kovan.infura.io/mew
|
|
||||||
REACT_APP_HOME_HTTP_PARITY_URL=https://sokol.poa.network
|
REACT_APP_HOME_HTTP_PARITY_URL=https://sokol.poa.network
|
||||||
|
REACT_APP_FOREIGN_HTTP_PARITY_URL=https://kovan.infura.io/mew
|
||||||
|
|
||||||
REACT_APP_HOME_NATIVE_NAME=POA
|
REACT_APP_HOME_NATIVE_NAME=POA
|
||||||
|
|
||||||
|
73
ui/README.md
73
ui/README.md
@ -8,13 +8,7 @@ Please refer to the [POA Token Bridge](../README.md) overview first of all.
|
|||||||
|
|
||||||
The UI provides an intuitive interface for assets transfer between networks running the Bridge smart contracts. Users can connect to a web3 wallet such as [Nifty Wallet](https://github.com/poanetwork/nifty-wallet) or [MetaMask](https://metamask.io/) and complete the transfer through a web browser.
|
The UI provides an intuitive interface for assets transfer between networks running the Bridge smart contracts. Users can connect to a web3 wallet such as [Nifty Wallet](https://github.com/poanetwork/nifty-wallet) or [MetaMask](https://metamask.io/) and complete the transfer through a web browser.
|
||||||
|
|
||||||
The current implementation allows for several bridge modes.
|
![Bridge UI](bridge-ui.png)
|
||||||
|
|
||||||
1. `Native-to-ERC20` Coins on a Home network can be converted to ERC20-compatible tokens on a Foreign network. Coins are locked on the Home side and the corresponding amount of ERC20 tokens are minted on the Foreign side. When the operation is reversed, tokens are burnt on the Foreign side and unlocked in the Home network.
|
|
||||||
2. `ERC20-to-ERC20` ERC20-compatible tokens on the Foreign network are locked and minted as ERC20-compatible tokens (ERC677 tokens) on the Home network. When transferred from Home to Foreign, they are burnt on the Home side and unlocked in the Foreign network. This can be considered a form of atomic swap when a user swaps the token "X" in network "A" to the token "Y" in network "B".
|
|
||||||
3. `ERC20-to-Native` Pre-existing tokens in the Foreign network are locked and coins are minted in the Home network. In this mode, the Home network consensus engine invokes Parity's Block Reward contract to mint coins per the bridge contract request.
|
|
||||||
|
|
||||||
![Bridge UI](bridge-ui.png)
|
|
||||||
|
|
||||||
### UI Features
|
### UI Features
|
||||||
- Shows daily limits in both networks
|
- Shows daily limits in both networks
|
||||||
@ -58,9 +52,9 @@ The following is an example setup using the POA Sokol testnet as the Home networ
|
|||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
- [poa-bridge-contracts](https://github.com/poanetwork/poa-bridge-contracts)
|
- [Smart Contracts](https://github.com/poanetwork/poa-bridge-contracts)
|
||||||
- [oracle](../oracle/README.md)
|
- [Oracle](../oracle/README.md)
|
||||||
- [node.js](https://nodejs.org/en/download/)
|
- [Node.js](https://nodejs.org/en/download/)
|
||||||
- [AlphaWallet](https://alphawallet.com/) or [Nifty Wallet](https://github.com/poanetwork/nifty-wallet) or [MetaMask](https://metamask.io/)
|
- [AlphaWallet](https://alphawallet.com/) or [Nifty Wallet](https://github.com/poanetwork/nifty-wallet) or [MetaMask](https://metamask.io/)
|
||||||
|
|
||||||
### Example Setup
|
### Example Setup
|
||||||
@ -94,14 +88,16 @@ The following is an example setup using the POA Sokol testnet as the Home networ
|
|||||||
* `FOREIGN_RPC_URL`=https://kovan.infura.io/mew
|
* `FOREIGN_RPC_URL`=https://kovan.infura.io/mew
|
||||||
* When deployment is finished, check that the `bridgeDeploymentResults.json` file exists in the `poa-bridge-contracts/deploy` directory and includes the bridge contract addresses.
|
* When deployment is finished, check that the `bridgeDeploymentResults.json` file exists in the `poa-bridge-contracts/deploy` directory and includes the bridge contract addresses.
|
||||||
|
|
||||||
5. Install and run the POA Token Bridge Oracle.
|
5. Install and run the Token Bridge Oracle.
|
||||||
* Go to the `sokol-kovan-bridge` folder and `git clone https://github.com/poanetwork/tokenbridge`
|
* Go to the `sokol-kovan-bridge` folder
|
||||||
* `cd tokenbridge/oracle`
|
* [Initialize](../README.md#initializing-the-monorepository) the monorepository
|
||||||
* Follow instructions in the [Oracle](../oracle/README.md).
|
* Go to `oracle` sub-repository
|
||||||
|
* Follow the [Oracle instructions](../oracle/README.md).
|
||||||
|
|
||||||
If successful, you will see bridge processes run when you issue a command. For example, run `npm run watcher:signature-request`
|
If successful, you will see bridge processes run when you issue a command.
|
||||||
|
For example, run `yarn watcher:signature-request`.
|
||||||
|
|
||||||
**Example NPM Output:**
|
**Example Yarn Output:**
|
||||||
```bash
|
```bash
|
||||||
[1539195000507] INFO (watcher-signature-request): Connected to redis
|
[1539195000507] INFO (watcher-signature-request): Connected to redis
|
||||||
[1539195000545] INFO (watcher-signature-request): Connected to amqp Broker
|
[1539195000545] INFO (watcher-signature-request): Connected to amqp Broker
|
||||||
@ -119,22 +115,19 @@ If successful, you will see bridge processes run when you issue a command. For e
|
|||||||
{"level":30,"time":1539366885587,"msg":"Found 0 UserRequestForSignature events","validator":"0x..........","name":"watcher-signature-request","v":1}
|
{"level":30,"time":1539366885587,"msg":"Found 0 UserRequestForSignature events","validator":"0x..........","name":"watcher-signature-request","v":1}
|
||||||
```
|
```
|
||||||
|
|
||||||
6. Keep the bridge processes running. Open a separate terminal window and go to the `sokol-kovan-bridge` folder to install and unpack this repository.
|
6. Keep the bridge processes running. Open a separate terminal window and go to the `sokol-kovan-bridge` folder to install and run the UI.
|
||||||
|
|
||||||
* `git clone https://github.com/poanetwork/tokenbridge`
|
* Go to the `sokol-kovan-bridge/tokenbridge` monorepository that was initialized in step **5.**
|
||||||
* `cd tokenbridge`
|
* Go to `ui` sub-repository
|
||||||
* Update submodules
|
|
||||||
`git submodule update --init --recursive`
|
|
||||||
* Install dependencies
|
|
||||||
`yarn install`
|
|
||||||
* Go to UI sub-repository
|
|
||||||
`cd ui`
|
|
||||||
|
|
||||||
_**Note**: The bridge UI configuration should be performed with an unprivileged Linux account or with the following flag `npm install --unsafe-perm`. [More information](https://docs.npmjs.com/misc/scripts#user)_
|
|
||||||
* Create a .env file from the example file [.env.example](.env.example)
|
* Create a .env file from the example file [.env.example](.env.example)
|
||||||
`cp .env.example .env`
|
```
|
||||||
|
cp .env.example .env
|
||||||
|
````
|
||||||
* Insert the addresses from the bridgeDeploymentResults.json file (from step 4) into the .env file. No other changes are needed, see [Env Parameter Details](#env-parameter-details) for information about each parameter.
|
* Insert the addresses from the bridgeDeploymentResults.json file (from step 4) into the .env file. No other changes are needed, see [Env Parameter Details](#env-parameter-details) for information about each parameter.
|
||||||
`cat ../poa-bridge-contracts/deploy/bridgeDeploymentResults.json`
|
```
|
||||||
|
cat ../poa-bridge-contracts/deploy/bridgeDeploymentResults.json
|
||||||
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# HomeBridge address in bridgeDeploymentResults.json
|
# HomeBridge address in bridgeDeploymentResults.json
|
||||||
REACT_APP_HOME_BRIDGE_ADDRESS=0x..
|
REACT_APP_HOME_BRIDGE_ADDRESS=0x..
|
||||||
@ -146,7 +139,11 @@ _**Note**: The bridge UI configuration should be performed with an unprivileged
|
|||||||
REACT_APP_HOME_HTTP_PARITY_URL=https://sokol.poa.network
|
REACT_APP_HOME_HTTP_PARITY_URL=https://sokol.poa.network
|
||||||
```
|
```
|
||||||
|
|
||||||
* Run `npm run start`
|
* Run the dApp
|
||||||
|
```
|
||||||
|
yarn start
|
||||||
|
```
|
||||||
|
|
||||||
* Make sure your web3 wallet (Nifty Wallet, AlphaWallet or MetaMask) is funded and connected to the POA Sokol Network (see step 2)
|
* Make sure your web3 wallet (Nifty Wallet, AlphaWallet or MetaMask) is funded and connected to the POA Sokol Network (see step 2)
|
||||||
* Specify an amount and click `Transfer` to complete a cross-chain transaction from Sokol to Kovan
|
* Specify an amount and click `Transfer` to complete a cross-chain transaction from Sokol to Kovan
|
||||||
|
|
||||||
@ -184,19 +181,27 @@ APP_STYLES | The set of styles to render the bridge UI page. Currently only `cla
|
|||||||
|
|
||||||
To run tests
|
To run tests
|
||||||
|
|
||||||
`npm run test`
|
```
|
||||||
|
yarn test
|
||||||
|
```
|
||||||
|
|
||||||
To run linting
|
To run linting
|
||||||
|
|
||||||
`npm run lint`
|
```
|
||||||
|
yarn lint
|
||||||
|
```
|
||||||
|
|
||||||
To run tests with coverage
|
To run tests with coverage
|
||||||
|
|
||||||
`npm run coverage`
|
```
|
||||||
|
yarn coverage
|
||||||
|
```
|
||||||
|
|
||||||
To build the project
|
To build the project
|
||||||
|
|
||||||
`npm run build`
|
```
|
||||||
|
yarn build
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
"name": "ui",
|
"name": "ui",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://poanetwork.github.io/",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/plugin-proposal-decorators": "^7.4.0",
|
"@babel/plugin-proposal-decorators": "^7.4.0",
|
||||||
"bignumber.js": "^6.0.0",
|
"bignumber.js": "^6.0.0",
|
||||||
@ -11,7 +10,6 @@
|
|||||||
"customize-cra": "^0.2.12",
|
"customize-cra": "^0.2.12",
|
||||||
"dotenv": "^7.0.0",
|
"dotenv": "^7.0.0",
|
||||||
"fs-extra": "^5.0.0",
|
"fs-extra": "^5.0.0",
|
||||||
"gh-pages": "^1.1.0",
|
|
||||||
"mobx": "^4.0.2",
|
"mobx": "^4.0.2",
|
||||||
"mobx-react": "^5.0.0",
|
"mobx-react": "^5.0.0",
|
||||||
"node-sass-chokidar": "^1.0.1",
|
"node-sass-chokidar": "^1.0.1",
|
||||||
@ -34,16 +32,14 @@
|
|||||||
"lint": "eslint . --ignore-path ../.eslintignore",
|
"lint": "eslint . --ignore-path ../.eslintignore",
|
||||||
"select-css-theme": "node scripts/selectTheme.js",
|
"select-css-theme": "node scripts/selectTheme.js",
|
||||||
"build-css": "node-sass-chokidar src/assets/stylesheets -o src/assets/stylesheets --output-style=compressed -m application*.css",
|
"build-css": "node-sass-chokidar src/assets/stylesheets -o src/assets/stylesheets --output-style=compressed -m application*.css",
|
||||||
"watch-css": "nodemon -e scss -x \"npm run build-css\"",
|
"watch-css": "nodemon -e scss -x \"yarn build-css\"",
|
||||||
"start": "npm run build-css && npm run select-css-theme && react-app-rewired start",
|
"start": "yarn build-css && yarn select-css-theme && react-app-rewired start",
|
||||||
"build": "npm run build-css && npm run select-css-theme && react-app-rewired build",
|
"build": "yarn build-css && yarn select-css-theme && react-app-rewired build",
|
||||||
"test": "react-app-rewired test --env=jsdom --no-watch",
|
"test": "react-app-rewired test --env=jsdom --no-watch",
|
||||||
"test:watch": "react-app-rewired test --env=jsdom",
|
"test:watch": "react-app-rewired test --env=jsdom",
|
||||||
"coverage": "react-app-rewired test --env=jsdom --coverage",
|
"coverage": "react-app-rewired test --env=jsdom --coverage",
|
||||||
"coveralls": "cat ./coverage/lcov.info | node node_modules/.bin/coveralls",
|
"coveralls": "cat ./coverage/lcov.info | node node_modules/.bin/coveralls",
|
||||||
"eject": "react-app-rewired eject",
|
"eject": "react-app-rewired eject",
|
||||||
"predeploy": "npm run build",
|
|
||||||
"deploy": "gh-pages -d build -o origin",
|
|
||||||
"postinstall": "(cp lib/web3-eth/index.js ../node_modules/web3-eth/src && cp lib/web3-eth/index.js ./node_modules/web3-eth/src)"
|
"postinstall": "(cp lib/web3-eth/index.js ../node_modules/web3-eth/src && cp lib/web3-eth/index.js ./node_modules/web3-eth/src)"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -17,7 +17,7 @@ export const SocialIcons = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: <IconGithub />,
|
icon: <IconGithub />,
|
||||||
link: 'https://github.com/poanetwork/token-bridge'
|
link: 'https://github.com/poanetwork/tokenbridge'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user