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:
Przemyslaw Rzad 2019-05-31 14:54:32 +02:00 committed by GitHub
parent 1ab4a0eca8
commit 93347b47a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 201 additions and 295 deletions

7
.gitignore vendored

@ -17,8 +17,8 @@ build
.idea
.nyc_output
logs/
responses/*
!responses/.gitkeep
*.err
*.out
data
@ -44,3 +44,6 @@ Vagrantfile
vagrant-hosts.yml
.vagrant
#monitor
monitor/responses/*
!monitor/.gitkeep

@ -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. |
| [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. |
| [Oracle-E2E]() | End to end tests for the Oracle |
| [UI-E2E]() | End to end tests for the UI |
| [Oracle-E2E](oracle-e2e/README.md) | End to end tests for the Oracle |
| [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
@ -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-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:
`yarn lint`
```
yarn lint
```
Running linter for all Ansible playbooks:
- [ansible-lint](https://github.com/ansible/ansible-lint) is required
`yarn ansible-lint`
```
yarn ansible-lint
```
## Tests
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.

@ -13,7 +13,7 @@
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
```
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.
`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.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.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.
@ -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.
* `--user=<username>` - connect as this username
## 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.

@ -1,5 +1,4 @@
- name: Launch container
docker_service:
project_src: "{{ bridge_path }}"
state: present
build: yes
shell: docker-compose up -d
args:
chdir: "{{ bridge_path }}/oracle"

@ -1,6 +1,6 @@
- name: Slurp docker compose file
slurp:
src: "{{ bridge_path }}/docker-compose.yml"
src: "{{ bridge_path }}/oracle/docker-compose.yml"
register: docker_compose_slurp
- name: Parse docker compose file
@ -15,7 +15,7 @@
- name: Write new docker-compose file
copy:
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
template:

@ -5,7 +5,7 @@ template(name="DockerLogFileName" type="list") {
constant(value="/docker.log")
}
if $programname startswith 'bridge_' then \
if $programname startswith 'oracle_bridge_' then \
?DockerLogFileName
else
/var/log/docker/no_tag/docker.log

@ -11,7 +11,7 @@ template(name="RemoteForwardFormat" type="list") {
property(name="msg")
}
if $programname startswith 'bridge_' or $programname startswith 'docker' then {
if $programname startswith 'oracle_bridge_' or $programname startswith 'docker' then {
action(
type="omfwd"
protocol="{{ syslog_server_port.split(":")[0] }}"

@ -2,12 +2,12 @@
become_user: "{{ compose_service_user }}"
shell: docker-compose run --entrypoint "node scripts/getValidatorStartBlocks.js" bridge_affirmation
args:
chdir: "{{ bridge_path }}"
chdir: "{{ bridge_path }}/oracle"
register: BLOCKS
- name: Write blocks
blockinfile:
path: "{{ bridge_path }}/.env"
path: "{{ bridge_path }}/oracle/.env"
marker: "## {mark} Calculated by scripts/getValidatorStartBlocks.js"
block: |
HOME_START_BLOCK={{ (BLOCKS.stdout | from_json).homeStartBlock }}
@ -17,7 +17,7 @@
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
args:
chdir: "{{ bridge_path }}"
chdir: "{{ bridge_path }}/oracle"
register: VADDRESS
- name: Set VALIDATOR_ADDRESS variable

@ -1,4 +1,4 @@
- name: Install .env config
template:
src: .env.j2
dest: "{{ bridge_path }}/.env"
dest: "{{ bridge_path }}/oracle/.env"

@ -1,3 +1,3 @@
bridge_path: "/home/{{ compose_service_user }}/bridge"
bridge_repo: https://github.com/poanetwork/token-bridge.git
bridge_repo_branch: master
bridge_repo: https://github.com/poanetwork/tokenbridge.git
bridge_repo_branch: master

@ -10,7 +10,7 @@
# Description: Enable service provided by daemon.
### 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
keyfile="{{ keyfile_path }}"

@ -94,34 +94,23 @@ Example of an API
}
```
* `GET /stuckTransfers` - check stucked transfers that wasnot called by transferAndCall
```json
{
"stuckTransfers": [
{
"address": "0x6758B7d441a9739b98552B373703d8d3d14f9e62",
"blockNumber": 5964312,
"transactionHash": "0x74413ba79509a292d5d0d6edd364b3617c83a57b13d603de9deb6c8e6b6c6daf",
...
"returnValues": {
"0": "0x8D4bbc1B533aB9e3a743210870b6e3c4c0f7E935",
"1": "0xd819E948b14cA6AAD2b7Ffd333cCDf732b129EeD",
"2": "10000000000000000000000",
"from": "0x8D4bbc1B533aB9e3a743210870b6e3c4c0f7E935",
"to": "0xd819E948b14cA6AAD2b7Ffd333cCDf732b129EeD",
"value": "10000000000000000000000"
},
...
}
],
"total": 2,
"lastChecked": 1535058662
}
# How to run
## Setup
1. [Initialize](../README.md#initializing-the-monorepository) the monorepository.
2. Go to the monitor sub-repository:
```
cd monitor
```
# How to run
Create .env file (see `.env.example` for parameters reference)
3. Create .env file:
```
cp .env.example .env
```
#### Example:
```bash
HOME_RPC_URL=https://sokol.poa.network
FOREIGN_RPC_URL=https://kovan.infura.io/mew
@ -133,17 +122,19 @@ GAS_PRICE_FALLBACK=21
LEFT_TX_THRESHOLD=100
```
```bash
npm i
# check balances of contracts and validators
## Check balances of contracts and validators
```
node checkWorker.js
# check unprocessed events
```
## Check unprocessed events
```
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
node index.js
```
## Run web interface
```
yarn start
```
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).
@ -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:
```
$ ./run-tests.sh
./run-tests.sh
```
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 run e2e yarn workspace oracle-e2e run deploy
docker-compose run -d bridge npm run watcher:signature-request
docker-compose run -d bridge npm run watcher:collected-signatures
docker-compose run -d bridge npm run watcher:affirmation-request
docker-compose run -d bridge-erc npm run watcher:signature-request
docker-compose run -d bridge-erc npm run watcher:collected-signatures
docker-compose run -d bridge-erc npm run watcher:affirmation-request
docker-compose run -d bridge-erc-native npm run watcher:signature-request
docker-compose run -d bridge-erc-native npm run watcher:collected-signatures
docker-compose run -d bridge-erc-native npm run watcher:affirmation-request
docker-compose run -d bridge npm run sender:home
docker-compose run -d bridge npm run sender:foreign
docker-compose run -d bridge yarn watcher:signature-request
docker-compose run -d bridge yarn watcher:collected-signatures
docker-compose run -d bridge yarn watcher:affirmation-request
docker-compose run -d bridge-erc yarn watcher:signature-request
docker-compose run -d bridge-erc yarn watcher:collected-signatures
docker-compose run -d bridge-erc yarn watcher:affirmation-request
docker-compose run -d bridge-erc-native yarn watcher:signature-request
docker-compose run -d bridge-erc-native yarn watcher:collected-signatures
docker-compose run -d bridge-erc-native yarn watcher:affirmation-request
docker-compose run -d bridge yarn sender:home
docker-compose run -d bridge yarn sender:foreign
docker-compose run e2e yarn workspace oracle-e2e run start
rc=$?

@ -49,16 +49,16 @@ For more information on the Redis/RabbitMQ requirements, see [#90](/../../issues
# 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).
#### Deploy the Bridge Contracts
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.
#### Output examples
`Native-to-ERC20` mode example:
```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.
@ -103,7 +113,7 @@ For more information on the Redis/RabbitMQ requirements, see [#90](/../../issues
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. NodeJs Package Manager (NPM).
2. Yarn Package Manager.
### 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`
### NPM
### 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.
- `npm run watcher:signature-request`
- `npm run watcher:collected-signatures`
- `npm run watcher:affirmation-request`
- `npm run sender:home`
- `npm run sender:foreign`
- `yarn watcher:signature-request`
- `yarn watcher:collected-signatures`
- `yarn watcher:affirmation-request`
- `yarn sender:home`
- `yarn sender:foreign`
### 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
@ -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:
for NPM installation:
for local installation:
```shell
bash ./reset-lastBlock.sh <watcher> <block num>
```
@ -210,7 +220,7 @@ Command | Description
## Testing
```bash
npm test
yarn test
```
### E2E tests

@ -40,7 +40,7 @@ services:
- NODE_ENV=production
- VALIDATOR_ADDRESS_PRIVATE_KEY=${VALIDATOR_ADDRESS_PRIVATE_KEY}
restart: unless-stopped
entrypoint: npm run watcher:signature-request
entrypoint: yarn watcher:signature-request
networks:
- net_db_bridge_request
- net_rabbit_bridge_request
@ -56,7 +56,7 @@ services:
- NODE_ENV=production
- VALIDATOR_ADDRESS=${VALIDATOR_ADDRESS}
restart: unless-stopped
entrypoint: npm run watcher:collected-signatures
entrypoint: yarn watcher:collected-signatures
networks:
- net_db_bridge_collected
- net_rabbit_bridge_collected
@ -72,7 +72,7 @@ services:
- NODE_ENV=production
- VALIDATOR_ADDRESS=${VALIDATOR_ADDRESS}
restart: unless-stopped
entrypoint: npm run watcher:affirmation-request
entrypoint: yarn watcher:affirmation-request
networks:
- net_db_bridge_affirmation
- net_rabbit_bridge_affirmation
@ -88,7 +88,7 @@ services:
- NODE_ENV=production
- VALIDATOR_ADDRESS_PRIVATE_KEY=${VALIDATOR_ADDRESS_PRIVATE_KEY}
restart: unless-stopped
entrypoint: npm run sender:home
entrypoint: yarn sender:home
networks:
- net_db_bridge_senderhome
- net_rabbit_bridge_senderhome
@ -104,7 +104,7 @@ services:
- NODE_ENV=production
- VALIDATOR_ADDRESS_PRIVATE_KEY=${VALIDATOR_ADDRESS_PRIVATE_KEY}
restart: unless-stopped
entrypoint: npm run sender:foreign
entrypoint: yarn sender:foreign
networks:
- net_db_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.
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.
## Generate a block with several transactions

@ -10,7 +10,7 @@
"watcher:affirmation-request": "./scripts/start-worker.sh watcher affirmation-request-watcher",
"sender:home": "./scripts/start-worker.sh sender home-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:watch": "NODE_ENV=test mocha --watch --reporter=min",
"coverage": "NODE_ENV=test nyc --reporter=text --reporter=html mocha",

@ -40,6 +40,6 @@
"clean": "rm -rf ./node_modules ./**/node_modules ./**/**/node_modules ./**/build",
"compile:contracts": "yarn workspace poa-parity-bridge-contracts run compile",
"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
End to end tests for the UI
# POA Token Bridge / UI-E2E
End to end tests for the POA Token Bridge [UI](../UI/README.md).
- 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
```

@ -6,17 +6,17 @@ docker-compose up -d --build --force-recreate
node ./scripts/blocks.js &
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 npm run watcher:collected-signatures
docker-compose run -d bridge npm run watcher:affirmation-request
docker-compose run -d bridge-erc20 npm run watcher:signature-request
docker-compose run -d bridge-erc20 npm run watcher:collected-signatures
docker-compose run -d bridge-erc20 npm run watcher:affirmation-request
docker-compose run -d bridge-erc20-native npm run watcher:signature-request
docker-compose run -d bridge-erc20-native npm run watcher:collected-signatures
docker-compose run -d bridge-erc20-native npm run watcher:affirmation-request
docker-compose run -d bridge npm run sender:home
docker-compose run -d bridge npm run sender:foreign
docker-compose run -d bridge yarn watcher:signature-request
docker-compose run -d bridge yarn watcher:collected-signatures
docker-compose run -d bridge yarn watcher:affirmation-request
docker-compose run -d bridge-erc20 yarn watcher:signature-request
docker-compose run -d bridge-erc20 yarn watcher:collected-signatures
docker-compose run -d bridge-erc20 yarn watcher:affirmation-request
docker-compose run -d bridge-erc20-native yarn watcher:signature-request
docker-compose run -d bridge-erc20-native yarn watcher:collected-signatures
docker-compose run -d bridge-erc20-native yarn watcher:affirmation-request
docker-compose run -d bridge yarn sender:home
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 3001:3000 ui-erc20 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_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_FOREIGN_HTTP_PARITY_URL=https://kovan.infura.io/mew
REACT_APP_HOME_NATIVE_NAME=POA

@ -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 current implementation allows for several bridge modes.
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)
![Bridge UI](bridge-ui.png)
### UI Features
- 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
- [poa-bridge-contracts](https://github.com/poanetwork/poa-bridge-contracts)
- [oracle](../oracle/README.md)
- [node.js](https://nodejs.org/en/download/)
- [Smart Contracts](https://github.com/poanetwork/poa-bridge-contracts)
- [Oracle](../oracle/README.md)
- [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/)
### 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
* 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.
* Go to the `sokol-kovan-bridge` folder and `git clone https://github.com/poanetwork/tokenbridge`
* `cd tokenbridge/oracle`
* Follow instructions in the [Oracle](../oracle/README.md).
5. Install and run the Token Bridge Oracle.
* Go to the `sokol-kovan-bridge` folder
* [Initialize](../README.md#initializing-the-monorepository) the monorepository
* 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
[1539195000507] INFO (watcher-signature-request): Connected to redis
[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}
```
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`
* `cd tokenbridge`
* Update submodules
`git submodule update --init --recursive`
* Install dependencies
`yarn install`
* Go to UI sub-repository
`cd ui`
* Go to the `sokol-kovan-bridge/tokenbridge` monorepository that was initialized in step **5.**
* Go to `ui` sub-repository
* Create a .env file from the example file [.env.example](.env.example)
```
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.
```
cat ../poa-bridge-contracts/deploy/bridgeDeploymentResults.json
```
_**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)
`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.
`cat ../poa-bridge-contracts/deploy/bridgeDeploymentResults.json`
```bash
# HomeBridge address in bridgeDeploymentResults.json
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
```
* 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)
* 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
`npm run test`
```
yarn test
```
To run linting
`npm run lint`
```
yarn lint
```
To run tests with coverage
`npm run coverage`
```
yarn coverage
```
To build the project
`npm run build`
```
yarn build
```
## Contributing

@ -2,7 +2,6 @@
"name": "ui",
"version": "0.1.0",
"private": true,
"homepage": "https://poanetwork.github.io/",
"dependencies": {
"@babel/plugin-proposal-decorators": "^7.4.0",
"bignumber.js": "^6.0.0",
@ -11,7 +10,6 @@
"customize-cra": "^0.2.12",
"dotenv": "^7.0.0",
"fs-extra": "^5.0.0",
"gh-pages": "^1.1.0",
"mobx": "^4.0.2",
"mobx-react": "^5.0.0",
"node-sass-chokidar": "^1.0.1",
@ -34,16 +32,14 @@
"lint": "eslint . --ignore-path ../.eslintignore",
"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",
"watch-css": "nodemon -e scss -x \"npm run build-css\"",
"start": "npm run build-css && npm run select-css-theme && react-app-rewired start",
"build": "npm run build-css && npm run select-css-theme && react-app-rewired build",
"watch-css": "nodemon -e scss -x \"yarn build-css\"",
"start": "yarn build-css && yarn select-css-theme && react-app-rewired start",
"build": "yarn build-css && yarn select-css-theme && react-app-rewired build",
"test": "react-app-rewired test --env=jsdom --no-watch",
"test:watch": "react-app-rewired test --env=jsdom",
"coverage": "react-app-rewired test --env=jsdom --coverage",
"coveralls": "cat ./coverage/lcov.info | node node_modules/.bin/coveralls",
"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)"
},
"devDependencies": {

@ -17,7 +17,7 @@ export const SocialIcons = () => {
},
{
icon: <IconGithub />,
link: 'https://github.com/poanetwork/token-bridge'
link: 'https://github.com/poanetwork/tokenbridge'
}
]