Merge the develop branch to the master branch, preparation to v2.5.0

This commit is contained in:
Alexander Kolotov 2020-09-13 11:11:29 +03:00 committed by GitHub
commit 48dd53622c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 551 additions and 705 deletions

@ -1,382 +0,0 @@
version: 2.1
orbs:
tokenbridge-orb:
commands:
install-chrome:
steps:
- run:
name: Update dpkg
command: |
sudo apt-get clean
sudo apt-get update
sudo apt-get install dpkg
- run:
name: Install Chrome
command: |
wget -O chrome.deb https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_77.0.3865.120-1_amd64.deb
sudo dpkg -i chrome.deb
install-node:
steps:
- run:
name: Install Node
command: |
export NVM_DIR="/opt/circleci/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install 10.16.3 && nvm alias default 10.16.3
echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV
echo ' [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV
install-yarn:
steps:
- run:
name: Install Yarn
command: |
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get -y install yarn
wait-for-oracle:
parameters:
redis-key:
type: string
steps:
- run:
name: Install redis tools
command: sudo apt-get install -y redis-tools
- run:
name: Wait for the Oracle to start
command: |
set +e
i=0
while [[ $(redis-cli GET << parameters.redis-key >> ) ]]; do
((i++))
if [ "$i" -gt 30 ]
then
exit -1
fi
echo "Sleeping..."
sleep 3
done
init-repo:
steps:
- checkout
- run: git submodule update --init
executors:
docker-node:
docker:
- image: circleci/node:10.15
machine-with-dlc:
machine:
image: ubuntu-1604:202007-01
docker_layer_caching: true
classic-machine-without-dlc:
machine:
image: circleci/classic:latest
machine-without-dlc:
machine:
image: ubuntu-1604:202007-01
jobs:
initialize:
executor: tokenbridge-orb/docker-node
steps:
- tokenbridge-orb/init-repo
- restore_cache:
name: Restore Yarn Package Cache
keys:
- yarn-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
- run: git submodule status > submodule.status
- restore_cache:
name: Restore contracts submodule with compiled contracts
keys:
- contracts-{{ checksum "submodule.status" }}
- run: yarn install --frozen-lockfile
- save_cache:
name: Save Yarn Package Cache
key: yarn-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
- run: touch install_deploy.log; test -d contracts/build/contracts || yarn install:deploy &> install_deploy.log
- store_artifacts:
path: install_deploy.log
- run: test -d contracts/build/contracts || yarn compile:contracts
- save_cache:
name: Save contracts submodule with compiled contracts
key: contracts-{{ checksum "submodule.status" }}
paths:
- contracts
- save_cache:
name: Save initialized project for subsequent jobs
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
paths:
- ~/project
initialize-root:
executor: tokenbridge-orb/docker-node
steps:
- checkout
- run: sudo su - -c 'export CI=true && cd /home/circleci/project && yarn initialize && yarn test'
build:
executor: tokenbridge-orb/docker-node
steps:
- restore_cache:
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn run build
lint:
executor: tokenbridge-orb/docker-node
steps:
- restore_cache:
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn run lint
test:
executor: tokenbridge-orb/docker-node
steps:
- restore_cache:
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn run test
build-e2e-images:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/init-repo
- run:
command: |
docker login -u ${DOCKER_LOGIN} -p ${DOCKER_PASSWORD}
cd e2e-commons
docker-compose build oracle monitor ui alm e2e molecule_runner
docker-compose push oracle monitor ui alm e2e molecule_runner
oracle-e2e:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/init-repo
- run: ./oracle-e2e/run-tests.sh
ui-e2e:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/install-node
- tokenbridge-orb/install-yarn
- tokenbridge-orb/install-chrome
- restore_cache:
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn run ui-e2e
monitor-e2e:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/init-repo
- run: ./monitor-e2e/run-tests.sh
alm-e2e:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/install-node
- tokenbridge-orb/install-yarn
- restore_cache:
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn run alm-e2e
cover:
executor: tokenbridge-orb/docker-node
steps:
- restore_cache:
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
- run: yarn workspace ui run coverage
- run: yarn workspace ui run coveralls
deployment-oracle:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/init-repo
- run:
name: Run the scenario
command: deployment-e2e/molecule.sh oracle
no_output_timeout: 40m
deployment-ui:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/init-repo
- run:
name: Run the scenario
command: deployment-e2e/molecule.sh ui
no_output_timeout: 40m
deployment-monitor:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/init-repo
- run:
name: Run the scenario
command: deployment-e2e/molecule.sh monitor
no_output_timeout: 40m
deployment-repo:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/init-repo
- run:
name: Run the scenario
command: deployment-e2e/molecule.sh repo
no_output_timeout: 40m
deployment-multiple:
executor: tokenbridge-orb/machine-without-dlc
steps:
- tokenbridge-orb/init-repo
- run:
name: Run the scenario
command: deployment-e2e/molecule.sh multiple
no_output_timeout: 40m
ultimate:
executor: tokenbridge-orb/classic-machine-without-dlc
parameters:
scenario-name:
description: "Molecule scenario name used to create the infrastructure"
type: string
redis-key:
description: "Redis key checked for non-emptiness to assert if Oracle is running"
type: string
ui-e2e-grep:
description: "Mocha grep string used to run ui-e2e tests specific to given type of bridge"
default: ''
type: string
oracle-e2e-script:
description: "Yarn script string used to run oracle-e2e tests specific to given type of bridge"
default: ''
type: string
steps:
- tokenbridge-orb/install-node
- tokenbridge-orb/install-chrome
- tokenbridge-orb/install-yarn
- restore_cache:
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
- run:
name: Prepare the infrastructure
command: e2e-commons/up.sh deploy << parameters.scenario-name >> blocks
no_output_timeout: 50m
- tokenbridge-orb/wait-for-oracle:
redis-key: << parameters.redis-key >>
- when:
condition: << parameters.ui-e2e-grep >>
steps:
- run:
name: Run the ui-e2e tests
command: |
nvm use default;
cd ui-e2e; yarn mocha -g "<< parameters.ui-e2e-grep >>" -b ./test.js
- when:
condition: << parameters.oracle-e2e-script >>
steps:
- run:
name: Run the oracle-e2e tests
command: cd e2e-commons && docker-compose run e2e yarn workspace oracle-e2e run << parameters.oracle-e2e-script >>
workflows:
tokenbridge:
jobs:
- initialize
- initialize-root:
filters:
branches:
only: master
- build:
requires:
- initialize
- lint:
requires:
- initialize
- test:
requires:
- initialize
- cover:
requires:
- initialize
filters:
branches:
only: master
- build-e2e-images
- oracle-e2e:
requires:
- build-e2e-images
- ui-e2e:
requires:
- build-e2e-images
- initialize
- monitor-e2e:
requires:
- build-e2e-images
- alm-e2e:
requires:
- build-e2e-images
- initialize
- deployment-oracle:
requires:
- build-e2e-images
- deployment-ui:
requires:
- build-e2e-images
- deployment-monitor:
requires:
- build-e2e-images
- deployment-repo:
requires:
- build-e2e-images
- deployment-multiple:
requires:
- build-e2e-images
- ultimate:
requires:
- build-e2e-images
- initialize
filters:
branches:
only:
- master
- develop
name: "ultimate: native to erc"
scenario-name: native-to-erc
redis-key: native-erc-collected-signatures:lastProcessedBlock
ui-e2e-grep: "NATIVE TO ERC"
- ultimate:
requires:
- build-e2e-images
- initialize
filters:
branches:
only:
- master
- develop
name: "ultimate: erc to native"
scenario-name: erc-to-native
redis-key: erc-native-collected-signatures:lastProcessedBlock
ui-e2e-grep: "ERC TO NATIVE"
- ultimate:
requires:
- build-e2e-images
- initialize
filters:
branches:
only:
- master
- develop
name: "ultimate: erc to erc"
scenario-name: erc-to-erc
redis-key: erc-erc-collected-signatures:lastProcessedBlock
ui-e2e-grep: "ERC TO ERC"
- ultimate:
requires:
- build-e2e-images
- initialize
filters:
branches:
only:
- master
- develop
name: "ultimate: amb"
scenario-name: amb
redis-key: amb-collected-signatures:lastProcessedBlock
oracle-e2e-script: "amb"
- ultimate:
requires:
- build-e2e-images
- initialize
filters:
branches:
only:
- master
- develop
name: "ultimate: amb stake erc to erc"
scenario-name: ultimate-amb-stake-erc-to-erc
redis-key: amb-collected-signatures:lastProcessedBlock
ui-e2e-grep: "AMB-STAKE-ERC-TO-ERC"

@ -11,6 +11,9 @@
contracts/test contracts/test
contracts/build contracts/build
oracle/test oracle/test
monitor/test
monitor/responses
commons/test
oracle/**/*.png oracle/**/*.png
oracle/**/*.jpg oracle/**/*.jpg
audit audit

231
.github/workflows/main.yml vendored Normal file

@ -0,0 +1,231 @@
name: tokenbridge
on: [push]
env:
DOCKER_REGISTRY: docker.pkg.github.com
DOCKER_REPO: poanetwork/tokenbridge
DOCKER_IMAGE_BASE: docker.pkg.github.com/poanetwork/tokenbridge
jobs:
initialize:
runs-on: ubuntu-latest
outputs:
cache_key: ${{ steps.get_cache_key.outputs.cache_key }}
steps:
- uses: actions/setup-node@v1
with:
node-version: 10
- uses: actions/checkout@v2
with:
submodules: true
- run: git submodule status > submodule.status
- id: get_cache_key
run: echo "::set-output name=cache_key::cache-repo-${{ hashFiles('yarn.lock', 'package.json', 'submodule.status') }}"
- uses: actions/cache@v2
id: cache-repo
with:
path: |
**/node_modules
contracts/build
key: ${{ steps.get_cache_key.outputs.cache_key }}
- if: ${{ !steps.cache-repo.outputs.cache-hit }}
run: |
yarn install --frozen-lockfile
yarn run install:deploy
yarn run compile:contracts
validate:
runs-on: ubuntu-latest
needs:
- initialize
strategy:
fail-fast: false
matrix:
task: [build, lint, test]
steps:
- uses: actions/setup-node@v1
with:
node-version: 10
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/cache@v2
id: cache-repo
with:
path: |
**/node_modules
contracts/build
key: ${{ needs.initialize.outputs.cache_key }}
- run: ${{ steps.cache-repo.outputs.cache-hit }} && yarn run ${{ matrix.task }}
ui-coverage:
runs-on: ubuntu-latest
needs:
- initialize
if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags')
steps:
- uses: actions/setup-node@v1
with:
node-version: 10
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/cache@v2
id: cache-repo
with:
path: |
**/node_modules
contracts/build
key: ${{ needs.initialize.outputs.cache_key }}
- run: ${{ steps.cache-repo.outputs.cache-hit }} && yarn workspace ui run coverage
- uses: coverallsapp/github-action@master
with:
github-token: ${{ github.token }}
path-to-lcov: ./ui/coverage/lcov.info
build-e2e-images:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- run: |
git submodule status > submodule.status
echo "::set-env name=E2E_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e') }}"
echo "::set-env name=ORACLE_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}"
echo "::set-env name=MONITOR_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}"
echo "::set-env name=UI_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'ui') }}"
echo "::set-env name=ALM_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}"
- run: |
function check_if_image_exists() {
curl -fsSlL -H 'Authorization: bearer ${{ github.token }}' "https://${DOCKER_REGISTRY}/v2/${DOCKER_REPO}/tokenbridge-e2e-$1/manifests/$2" > /dev/null
}
updated=()
if ! check_if_image_exists e2e ${E2E_TAG}; then updated+=("e2e"); fi
if ! check_if_image_exists oracle ${ORACLE_TAG}; then updated+=("oracle"); fi
if ! check_if_image_exists monitor ${MONITOR_TAG}; then updated+=("monitor"); fi
if ! check_if_image_exists ui ${UI_TAG}; then updated+=("ui"); fi
if ! check_if_image_exists alm ${ALM_TAG}; then updated+=("alm"); fi
if [ ${#updated[@]} -gt 0 ]; then
echo "Updated services: ${updated[@]}"
cd e2e-commons
docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
docker-compose build ${updated[@]}
docker-compose push ${updated[@]}
else
echo "Nothing relevant was changed in the source"
fi
build-molecule-runner:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- run: echo "::set-env name=MOLECULE_RUNNER_TAG::${{ hashFiles('./deployment-e2e/Dockerfile') }}"
- run: |
function check_if_image_exists() {
curl -fsSlL -H 'Authorization: bearer ${{ github.token }}' "https://${DOCKER_REGISTRY}/v2/${DOCKER_REPO}/tokenbridge-e2e-$1/manifests/$2" > /dev/null
}
if check_if_image_exists molecule_runner ${MOLECULE_RUNNER_TAG}; then
echo "Image already exists"
else
cd e2e-commons
docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
docker-compose build molecule_runner
docker-compose push molecule_runner
fi
e2e:
runs-on: ubuntu-latest
needs:
- initialize
- build-e2e-images
strategy:
fail-fast: false
matrix:
task: [oracle-e2e, monitor-e2e, alm-e2e, 'ui-e2e:ci']
include:
- task: alm-e2e
use-cache: true
- task: 'ui-e2e:ci'
use-cache: true
steps:
- uses: actions/checkout@v2
with:
submodules: true
- run: |
git submodule status > submodule.status
echo "::set-env name=E2E_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e') }}"
echo "::set-env name=ORACLE_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}"
echo "::set-env name=MONITOR_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}"
echo "::set-env name=UI_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'ui') }}"
echo "::set-env name=ALM_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}"
- if: ${{ matrix.use-cache }}
uses: actions/cache@v2
id: cache-repo
with:
path: |
**/node_modules
contracts/build
key: ${{ needs.initialize.outputs.cache_key }}
- run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
- run: ${{ !matrix.use-cache || steps.cache-repo.outputs.cache-hit }} && yarn run ${{ matrix.task }}
deployment:
runs-on: ubuntu-latest
needs:
- build-molecule-runner
strategy:
fail-fast: false
matrix:
task: [oracle, ui, monitor, multiple, repo]
steps:
- uses: actions/checkout@v2
with:
submodules: true
- run: echo "::set-env name=MOLECULE_RUNNER_TAG::${{ hashFiles('./deployment-e2e/Dockerfile') }}"
- run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
- run: deployment-e2e/molecule.sh ${{ matrix.task }}
ultimate:
runs-on: ubuntu-latest
needs:
- initialize
- build-e2e-images
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/develop' || startsWith(github.ref, 'refs/tags')
strategy:
fail-fast: false
matrix:
task: [amb, erc-to-erc, erc-to-native, native-to-erc, amb-stake-erc-to-erc]
include:
- task: erc-to-erc
ui-e2e-grep: 'ERC TO ERC'
- task: erc-to-native
ui-e2e-grep: 'ERC TO NATIVE'
- task: native-to-erc
ui-e2e-grep: 'NATIVE TO ERC'
- task: amb-stake-erc-to-erc
ui-e2e-grep: 'AMB-STAKE-ERC-TO-ERC'
steps:
- uses: actions/checkout@v2
with:
submodules: true
- run: |
git submodule status > submodule.status
echo "::set-env name=E2E_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e') }}"
echo "::set-env name=ORACLE_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}"
echo "::set-env name=MONITOR_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}"
echo "::set-env name=UI_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'ui') }}"
echo "::set-env name=ALM_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}"
echo "::set-env name=MOLECULE_RUNNER_TAG::${{ hashFiles('./deployment-e2e/Dockerfile') }}"
- uses: actions/cache@v2
id: cache-repo
with:
path: |
**/node_modules
contracts/build
key: ${{ needs.initialize.outputs.cache_key }}
- run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
- run: ${{ steps.cache-repo.outputs.cache-hit }} && e2e-commons/up.sh deploy blocks
- run: docker-compose -f ./e2e-commons/docker-compose.yml pull oracle
- run: deployment-e2e/molecule.sh ultimate-${{ matrix.task }}
- run: sudo chown -R $USER:docker /var/run/docker.sock
- if: ${{ matrix.ui-e2e-grep }}
run: cd ui-e2e && xvfb-run yarn mocha -g "${{ matrix.ui-e2e-grep }}" -b ./test.js
- if: ${{ !matrix.ui-e2e-grep }}
run: docker-compose -f ./e2e-commons/docker-compose.yml run e2e yarn workspace oracle-e2e run ${{ matrix.task }}

@ -1,4 +1,4 @@
FROM node:8 as contracts FROM node:10 as contracts
WORKDIR /mono WORKDIR /mono
@ -11,11 +11,12 @@ COPY ./contracts/truffle-config.js ./
COPY ./contracts/contracts ./contracts COPY ./contracts/contracts ./contracts
RUN npm run compile RUN npm run compile
FROM node:8 FROM node:10
WORKDIR /mono WORKDIR /mono
COPY package.json . COPY package.json .
COPY --from=contracts /mono/contracts/build ./contracts/build COPY --from=contracts /mono/contracts/build ./contracts/build
COPY commons/package.json ./commons/
COPY oracle-e2e/package.json ./oracle-e2e/ COPY oracle-e2e/package.json ./oracle-e2e/
COPY monitor-e2e/package.json ./monitor-e2e/ COPY monitor-e2e/package.json ./monitor-e2e/

@ -1,4 +1,4 @@
[![CircleCI](https://circleci.com/gh/poanetwork/tokenbridge.svg?style=svg)](https://circleci.com/gh/poanetwork/tokenbridge) ![tokenbridge](https://github.com/poanetwork/tokenbridge/workflows/tokenbridge/badge.svg?branch=master)
[![Gitter](https://badges.gitter.im/poanetwork/poa-bridge.svg)](https://gitter.im/poanetwork/poa-bridge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Gitter](https://badges.gitter.im/poanetwork/poa-bridge.svg)](https://gitter.im/poanetwork/poa-bridge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![License: LGPL v3.0](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) [![License: LGPL v3.0](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
@ -110,4 +110,4 @@ This project is licensed under the GNU Lesser General Public License v3.0. See t
## References ## References
* [TokenBridge Documentation](http://www.tokenbridge.net/) * [TokenBridge Documentation](https://docs.tokenbridge.net/)

0
alm-e2e/run-tests.sh Normal file → Executable file

@ -1,4 +1,4 @@
FROM node:8 as contracts FROM node:10 as contracts
WORKDIR /mono WORKDIR /mono

@ -351,7 +351,7 @@ describe('getConfirmationsForTx', () => {
{ validator: validator1, status: VALIDATOR_CONFIRMATION_STATUS.SUCCESS }, { validator: validator1, status: VALIDATOR_CONFIRMATION_STATUS.SUCCESS },
{ validator: validator2, status: VALIDATOR_CONFIRMATION_STATUS.SUCCESS }, { validator: validator2, status: VALIDATOR_CONFIRMATION_STATUS.SUCCESS },
{ validator: validator3, status: VALIDATOR_CONFIRMATION_STATUS.FAILED, txHash: '0x123', timestamp: 123 }, { validator: validator3, status: VALIDATOR_CONFIRMATION_STATUS.FAILED, txHash: '0x123', timestamp: 123 },
{ validator: validator4, status: VALIDATOR_CONFIRMATION_STATUS.UNDEFINED } { validator: validator4, status: VALIDATOR_CONFIRMATION_STATUS.NOT_REQUIRED }
]) ])
) )
expect(setResult.mock.calls[1][0]).toEqual( expect(setResult.mock.calls[1][0]).toEqual(

@ -13,7 +13,7 @@ git push
Alternatively, if there are no changes except the playbooks, you can use the `master` branch: Alternatively, if there are no changes except the playbooks, you can use the `master` branch:
``` ```
CIRCLE_BRANCH=master ./molecule.sh <scenario_name> ./molecule.sh <scenario_name>
``` ```
In this case `master` branch will be used as a codebase for Monitor, UI, Oracle and Contracts deployed by your local playbook. In this case `master` branch will be used as a codebase for Monitor, UI, Oracle and Contracts deployed by your local playbook.
@ -21,7 +21,7 @@ In this case `master` branch will be used as a codebase for Monitor, UI, Oracle
## Run the tests ## Run the tests
``` ```
CIRCLE_BRANCH=master ./molecule.sh <scenario_name> ./molecule.sh <scenario_name>
``` ```
Available scenarios: Available scenarios:

@ -2,7 +2,11 @@
cd ./e2e-commons cd ./e2e-commons
set -e # exit when any command fails set -e # exit when any command fails
docker-compose pull molecule_runner if [ -z "$CI" ]; then
docker-compose build molecule_runner
else
docker-compose pull molecule_runner
fi
docker network create --driver bridge ultimate || true docker network create --driver bridge ultimate || true
while [ "$1" != "" ]; do while [ "$1" != "" ]; do
docker-compose run molecule_runner /bin/bash -c "molecule test --scenario-name $1" docker-compose run molecule_runner /bin/bash -c "molecule test --scenario-name $1"

@ -6,12 +6,10 @@
- name: stop the service - name: stop the service
shell: service poabridge stop shell: service poabridge stop
- name: Build current oracle image - name: ReTag current oracle image
shell: docker build -t oracle:ultimate-testing --file oracle/Dockerfile . shell: docker tag $(docker images --format '{{ '{{' }}.Repository{{ '}}' }}:{{ '{{' }}.Tag{{ '}}' }}' | grep -m 1 tokenbridge-e2e-oracle) oracle:ultimate-testing
delegate_to: 127.0.0.1 delegate_to: 127.0.0.1
become: false become: false
args:
chdir: "{{ lookup('env', 'PWD') }}/.."
- name: Replace oracle image - name: Replace oracle image
replace: replace:

@ -12,6 +12,7 @@
copy: copy:
src: ../../../../{{ item }} src: ../../../../{{ item }}
dest: "{{ bridge_path }}/" dest: "{{ bridge_path }}/"
mode: '0640'
with_items: with_items:
- monorepo.tar.gz - monorepo.tar.gz
- contracts.tar.gz - contracts.tar.gz

@ -24,6 +24,8 @@
template: template:
src: .env.j2 src: .env.j2
dest: "{{ bridge_path }}/monitor/.env" dest: "{{ bridge_path }}/monitor/.env"
owner: "{{ compose_service_user }}"
mode: '0640'
when: skip_task != true when: skip_task != true
- name: Copy docker-compose file - name: Copy docker-compose file
@ -45,3 +47,5 @@
template: template:
src: config.env.j2 src: config.env.j2
dest: "{{ bridge_path }}/monitor/configs/{{ MONITOR_BRIDGE_NAME }}.env" dest: "{{ bridge_path }}/monitor/configs/{{ MONITOR_BRIDGE_NAME }}.env"
owner: "{{ compose_service_user }}"
mode: '0640'

@ -9,6 +9,8 @@
template: template:
src: .env.j2 src: .env.j2
dest: "{{ bridge_path }}/oracle/.env" dest: "{{ bridge_path }}/oracle/.env"
owner: "{{ compose_service_user }}"
mode: '0640'
- name: Copy docker-compose files - name: Copy docker-compose files
copy: copy:

@ -3,3 +3,5 @@
template: template:
src: .env.j2 src: .env.j2
dest: "{{ bridge_path }}/ui/.env" dest: "{{ bridge_path }}/ui/.env"
owner: "{{ compose_service_user }}"
mode: '0640'

@ -1,6 +1,6 @@
ARG DOCKER_LOGIN ARG DOCKER_IMAGE_BASE
ARG CIRCLE_BRANCH ARG UI_TAG
FROM ${DOCKER_LOGIN}/tokenbridge-e2e-ui:${CIRCLE_BRANCH} FROM ${DOCKER_IMAGE_BASE}/tokenbridge-e2e-ui:${UI_TAG}
ARG DOT_ENV_PATH ARG DOT_ENV_PATH

17
e2e-commons/build.sh Executable file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
cd $(dirname $0)
set -e # exit when any command fails
docker-compose build e2e
while [ "$1" != "" ]; do
if [ "$1" == "oracle" ]; then
docker-compose build oracle
elif [ "$1" == "monitor" ]; then
docker-compose build monitor
elif [ "$1" == "ui" ]; then
docker-compose build ui
elif [ "$1" == "alm" ]; then
docker-compose build alm
fi
shift
done

@ -1,5 +1,4 @@
--- version: '3.8'
version: '3'
networks: networks:
ultimate: ultimate:
external: true external: true
@ -27,7 +26,7 @@ services:
networks: networks:
- ultimate - ultimate
oracle: oracle:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-oracle:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-oracle:${ORACLE_TAG:-local}
build: build:
context: .. context: ..
dockerfile: oracle/Dockerfile dockerfile: oracle/Dockerfile
@ -38,10 +37,7 @@ services:
networks: networks:
- ultimate - ultimate
oracle-erc20: oracle-erc20:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-oracle:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-oracle:${ORACLE_TAG:-local}
build:
context: ..
dockerfile: oracle/Dockerfile
env_file: ../e2e-commons/components-envs/oracle-erc20.env env_file: ../e2e-commons/components-envs/oracle-erc20.env
environment: environment:
- NODE_ENV=production - NODE_ENV=production
@ -49,10 +45,7 @@ services:
networks: networks:
- ultimate - ultimate
oracle-erc20-native: oracle-erc20-native:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-oracle:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-oracle:${ORACLE_TAG:-local}
build:
context: ..
dockerfile: oracle/Dockerfile
env_file: ../e2e-commons/components-envs/oracle-erc20-native.env env_file: ../e2e-commons/components-envs/oracle-erc20-native.env
environment: environment:
- NODE_ENV=production - NODE_ENV=production
@ -60,10 +53,7 @@ services:
networks: networks:
- ultimate - ultimate
oracle-amb: oracle-amb:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-oracle:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-oracle:${ORACLE_TAG:-local}
build:
context: ..
dockerfile: oracle/Dockerfile
env_file: ../e2e-commons/components-envs/oracle-amb.env env_file: ../e2e-commons/components-envs/oracle-amb.env
environment: environment:
- NODE_ENV=production - NODE_ENV=production
@ -71,7 +61,7 @@ services:
networks: networks:
- ultimate - ultimate
ui: ui:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-ui:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-ui:${UI_TAG:-local}
build: build:
context: .. context: ..
dockerfile: ui/Dockerfile dockerfile: ui/Dockerfile
@ -85,8 +75,8 @@ services:
context: .. context: ..
dockerfile: e2e-commons/Dockerfile.ui dockerfile: e2e-commons/Dockerfile.ui
args: args:
DOCKER_LOGIN: ${DOCKER_LOGIN} DOCKER_IMAGE_BASE: ${DOCKER_IMAGE_BASE:-tokenbridge}
CIRCLE_BRANCH: ${CIRCLE_BRANCH} UI_TAG: ${UI_TAG:-local}
DOT_ENV_PATH: e2e-commons/components-envs/ui-erc20.env DOT_ENV_PATH: e2e-commons/components-envs/ui-erc20.env
command: "true" command: "true"
networks: networks:
@ -96,8 +86,8 @@ services:
context: .. context: ..
dockerfile: e2e-commons/Dockerfile.ui dockerfile: e2e-commons/Dockerfile.ui
args: args:
DOCKER_LOGIN: ${DOCKER_LOGIN} DOCKER_IMAGE_BASE: ${DOCKER_IMAGE_BASE:-tokenbridge}
CIRCLE_BRANCH: ${CIRCLE_BRANCH} UI_TAG: ${UI_TAG:-local}
DOT_ENV_PATH: e2e-commons/components-envs/ui-erc20-native.env DOT_ENV_PATH: e2e-commons/components-envs/ui-erc20-native.env
command: "true" command: "true"
networks: networks:
@ -107,14 +97,14 @@ services:
context: .. context: ..
dockerfile: e2e-commons/Dockerfile.ui dockerfile: e2e-commons/Dockerfile.ui
args: args:
DOCKER_LOGIN: ${DOCKER_LOGIN} DOCKER_IMAGE_BASE: ${DOCKER_IMAGE_BASE:-tokenbridge}
CIRCLE_BRANCH: ${CIRCLE_BRANCH} UI_TAG: ${UI_TAG:-local}
DOT_ENV_PATH: e2e-commons/components-envs/ui-amb-stake-erc20-erc20.env DOT_ENV_PATH: e2e-commons/components-envs/ui-amb-stake-erc20-erc20.env
command: "true" command: "true"
networks: networks:
- ultimate - ultimate
alm: alm:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-alm:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-alm:${ALM_TAG:-local}
build: build:
context: .. context: ..
dockerfile: alm/Dockerfile dockerfile: alm/Dockerfile
@ -124,7 +114,7 @@ services:
networks: networks:
- ultimate - ultimate
monitor: monitor:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-monitor:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-monitor:${MONITOR_TAG:-local}
build: build:
context: .. context: ..
dockerfile: monitor/Dockerfile dockerfile: monitor/Dockerfile
@ -135,10 +125,7 @@ services:
networks: networks:
- ultimate - ultimate
monitor-erc20: monitor-erc20:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-monitor:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-monitor:${MONITOR_TAG:-local}
build:
context: ..
dockerfile: monitor/Dockerfile
env_file: ../e2e-commons/components-envs/monitor-erc20.env env_file: ../e2e-commons/components-envs/monitor-erc20.env
entrypoint: yarn check-and-start entrypoint: yarn check-and-start
ports: ports:
@ -146,10 +133,7 @@ services:
networks: networks:
- ultimate - ultimate
monitor-erc20-native: monitor-erc20-native:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-monitor:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-monitor:${MONITOR_TAG:-local}
build:
context: ..
dockerfile: monitor/Dockerfile
env_file: ../e2e-commons/components-envs/monitor-erc20-native.env env_file: ../e2e-commons/components-envs/monitor-erc20-native.env
entrypoint: yarn check-and-start entrypoint: yarn check-and-start
ports: ports:
@ -157,10 +141,7 @@ services:
networks: networks:
- ultimate - ultimate
monitor-amb: monitor-amb:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-monitor:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-monitor:${MONITOR_TAG:-local}
build:
context: ..
dockerfile: monitor/Dockerfile
env_file: ../e2e-commons/components-envs/monitor-amb.env env_file: ../e2e-commons/components-envs/monitor-amb.env
entrypoint: yarn check-and-start entrypoint: yarn check-and-start
ports: ports:
@ -168,7 +149,7 @@ services:
networks: networks:
- ultimate - ultimate
e2e: e2e:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-e2e:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-e2e:${E2E_TAG:-local}
build: build:
context: .. context: ..
dockerfile: Dockerfile.e2e dockerfile: Dockerfile.e2e
@ -176,15 +157,12 @@ services:
networks: networks:
- ultimate - ultimate
blocks: blocks:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-e2e:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-e2e:${E2E_TAG:-local}
build:
context: ..
dockerfile: Dockerfile.e2e
entrypoint: node e2e-commons/scripts/blocks.js entrypoint: node e2e-commons/scripts/blocks.js
networks: networks:
- ultimate - ultimate
molecule_runner: molecule_runner:
image: ${DOCKER_LOGIN}/tokenbridge-e2e-molecule_runner:${CIRCLE_BRANCH} image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-molecule_runner:${MOLECULE_RUNNER_TAG:-local}
build: build:
context: .. context: ..
dockerfile: deployment-e2e/Dockerfile dockerfile: deployment-e2e/Dockerfile

@ -4,7 +4,13 @@ set -e # exit when any command fails
./down.sh ./down.sh
docker-compose build parity1 parity2 docker-compose build parity1 parity2
test -n "$NODOCKERPULL" || ./pull.sh $@
if [ -z "$CI" ]; then
./build.sh $@
else
./pull.sh $@
fi
docker network create --driver bridge ultimate || true docker network create --driver bridge ultimate || true
docker-compose up -d parity1 parity2 e2e docker-compose up -d parity1 parity2 e2e
@ -107,26 +113,6 @@ while [ "$1" != "" ]; do
docker-compose up -d monitor monitor-erc20 monitor-erc20-native monitor-amb docker-compose up -d monitor monitor-erc20 monitor-erc20-native monitor-amb
fi fi
if [ "$1" == "native-to-erc" ]; then
../deployment-e2e/molecule.sh ultimate-native-to-erc
fi
if [ "$1" == "erc-to-native" ]; then
../deployment-e2e/molecule.sh ultimate-erc-to-native
fi
if [ "$1" == "erc-to-erc" ]; then
../deployment-e2e/molecule.sh ultimate-erc-to-erc
fi
if [ "$1" == "amb" ]; then
../deployment-e2e/molecule.sh ultimate-amb
fi
if [ "$1" == "ultimate-amb-stake-erc-to-erc" ]; then
../deployment-e2e/molecule.sh ultimate-amb-stake-erc-to-erc
fi
if [ "$1" == "alm-e2e" ]; then if [ "$1" == "alm-e2e" ]; then
docker-compose up -d redis rabbit docker-compose up -d redis rabbit

@ -4,7 +4,7 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "mocha --timeout 30000", "start": "mocha --timeout 120000",
"lint": "eslint . --ignore-path ../.eslintignore" "lint": "eslint . --ignore-path ../.eslintignore"
}, },
"author": "", "author": "",

@ -1,7 +1,7 @@
while true; do while true; do
sleep 3 sleep 5
COMPOSE_INTERACTIVE_NO_CLI=1 nohup docker-compose -f ../e2e-commons/docker-compose.yml exec monitor yarn check-all docker-compose -f ../e2e-commons/docker-compose.yml exec -d monitor yarn check-all
COMPOSE_INTERACTIVE_NO_CLI=1 nohup docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20 yarn check-all docker-compose -f ../e2e-commons/docker-compose.yml exec -d monitor-erc20 yarn check-all
COMPOSE_INTERACTIVE_NO_CLI=1 nohup docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20-native yarn check-all docker-compose -f ../e2e-commons/docker-compose.yml exec -d monitor-erc20-native yarn check-all
COMPOSE_INTERACTIVE_NO_CLI=1 nohup docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-amb yarn check-all docker-compose -f ../e2e-commons/docker-compose.yml exec -d monitor-amb yarn check-all
done done

@ -37,6 +37,9 @@ describe('ERC TO NATIVE with changing state of contracts', () => {
await waitUntil(async () => { await waitUntil(async () => {
;({ data } = await axios.get(`${baseUrl}`)) ;({ data } = await axios.get(`${baseUrl}`))
if (!data.foreign) {
return false
}
const { erc20Balance, investedErc20Balance } = data.foreign const { erc20Balance, investedErc20Balance } = data.foreign
return data.balanceDiff === 0.01 && erc20Balance === '0.01' && investedErc20Balance === undefined return data.balanceDiff === 0.01 && erc20Balance === '0.01' && investedErc20Balance === undefined
}) })
@ -58,6 +61,9 @@ describe('ERC TO NATIVE with changing state of contracts', () => {
await waitUntil(async () => { await waitUntil(async () => {
;({ data } = await axios.get(`${baseUrl}`)) ;({ data } = await axios.get(`${baseUrl}`))
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
if (!data.foreign) {
return false
}
return ( return (
data.balanceDiff === 0.02 && data.balanceDiff === 0.02 &&
erc20Balance === '0.02' && erc20Balance === '0.02' &&
@ -72,6 +78,9 @@ describe('ERC TO NATIVE with changing state of contracts', () => {
await waitUntil(async () => { await waitUntil(async () => {
;({ data } = await axios.get(`${baseUrl}`)) ;({ data } = await axios.get(`${baseUrl}`))
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
if (!data.foreign) {
return false
}
return ( return (
data.balanceDiff === 0.02 && data.balanceDiff === 0.02 &&
erc20Balance === '0.01' && erc20Balance === '0.01' &&
@ -86,6 +95,9 @@ describe('ERC TO NATIVE with changing state of contracts', () => {
await waitUntil(async () => { await waitUntil(async () => {
;({ data } = await axios.get(`${baseUrl}`)) ;({ data } = await axios.get(`${baseUrl}`))
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
if (!data.foreign) {
return false
}
return ( return (
data.balanceDiff === 0.02 && data.balanceDiff === 0.02 &&
erc20Balance === '0.005' && erc20Balance === '0.005' &&

@ -8,7 +8,7 @@ const {
} = require('../commons') } = require('../commons')
const { validator } = require('../e2e-commons/constants') const { validator } = require('../e2e-commons/constants')
const waitUntil = async (predicate, step = 100, timeout = 20000) => { const waitUntil = async (predicate, step = 100, timeout = 60000) => {
const stopTime = Date.now() + timeout const stopTime = Date.now() + timeout
while (Date.now() <= stopTime) { while (Date.now() <= stopTime) {
const result = await predicate() const result = await predicate()

@ -1,13 +1,15 @@
#!/bin/bash
FILES=(getBalances.json validators.json eventsStats.json alerts.json) FILES=(getBalances.json validators.json eventsStats.json alerts.json)
check_files_exist() { check_files_exist() {
rc=0 rc=0
for f in "${FILES[@]}"; do for f in "${FILES[@]}"; do
command="test -f responses/bridge/$f" command="test -f responses/bridge/$f"
(docker-compose -f ../e2e-commons/docker-compose.yml exec monitor /bin/bash -c "$command") || rc=1 (docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor /bin/bash -c "$command") || rc=1
(docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20 /bin/bash -c "$command") || rc=1 (docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20 /bin/bash -c "$command") || rc=1
(docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-erc20-native /bin/bash -c "$command") || rc=1 (docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20-native /bin/bash -c "$command") || rc=1
(docker-compose -f ../e2e-commons/docker-compose.yml exec monitor-amb /bin/bash -c "$command") || rc=1 (docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-amb /bin/bash -c "$command") || rc=1
done done
return $rc return $rc
} }

@ -1,4 +1,4 @@
FROM node:8 as contracts FROM node:10 as contracts
WORKDIR /mono WORKDIR /mono
@ -11,7 +11,7 @@ COPY ./contracts/truffle-config.js ./
COPY ./contracts/contracts ./contracts COPY ./contracts/contracts ./contracts
RUN npm run compile RUN npm run compile
FROM node:8 FROM node:10
WORKDIR /mono WORKDIR /mono
COPY package.json . COPY package.json .

@ -1,4 +1,4 @@
FROM node:8 as contracts FROM node:10 as contracts
WORKDIR /mono WORKDIR /mono
@ -11,14 +11,11 @@ COPY ./contracts/truffle-config.js ./
COPY ./contracts/contracts ./contracts COPY ./contracts/contracts ./contracts
RUN npm run compile RUN npm run compile
FROM node:8 FROM node:10
RUN apt-get update RUN apt-get update && \
RUN apt-get install -y build-essential apt-get install -y build-essential libc6-dev libc6-dev-i386 wget && \
RUN apt-get install -y libc6-dev apt-get clean
RUN apt-get install -y libc6-dev-i386
RUN apt-get install -y wget
RUN apt-get clean
WORKDIR /mono WORKDIR /mono
COPY package.json . COPY package.json .

@ -24,7 +24,7 @@ module.exports = {
...baseConfig.bridgeConfig, ...baseConfig.bridgeConfig,
...baseConfig.foreignConfig, ...baseConfig.foreignConfig,
event: 'UserRequestForAffirmation', event: 'UserRequestForAffirmation',
queue: 'home', queue: 'home-prioritized',
name: `watcher-${id}`, name: `watcher-${id}`,
id id
} }

@ -73,6 +73,7 @@ const bridgeConfig = {
} }
const homeConfig = { const homeConfig = {
chain: 'home',
eventContractAddress: process.env.COMMON_HOME_BRIDGE_ADDRESS, eventContractAddress: process.env.COMMON_HOME_BRIDGE_ADDRESS,
eventAbi: homeAbi, eventAbi: homeAbi,
bridgeContractAddress: process.env.COMMON_HOME_BRIDGE_ADDRESS, bridgeContractAddress: process.env.COMMON_HOME_BRIDGE_ADDRESS,
@ -83,6 +84,7 @@ const homeConfig = {
} }
const foreignConfig = { const foreignConfig = {
chain: 'foreign',
eventContractAddress: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS, eventContractAddress: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS,
eventAbi: foreignAbi, eventAbi: foreignAbi,
bridgeContractAddress: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS, bridgeContractAddress: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS,

@ -6,7 +6,7 @@ module.exports = {
...baseConfig.bridgeConfig, ...baseConfig.bridgeConfig,
...baseConfig.homeConfig, ...baseConfig.homeConfig,
event: 'CollectedSignatures', event: 'CollectedSignatures',
queue: 'foreign', queue: 'foreign-prioritized',
name: `watcher-${id}`, name: `watcher-${id}`,
id id
} }

@ -14,7 +14,7 @@ module.exports = {
...baseConfig.bridgeConfig, ...baseConfig.bridgeConfig,
...baseConfig.foreignConfig, ...baseConfig.foreignConfig,
workerQueue: 'convert-to-chai', workerQueue: 'convert-to-chai',
senderQueue: 'foreign', senderQueue: 'foreign-prioritized',
name: `worker-${id}`, name: `worker-${id}`,
id id
} }

@ -4,7 +4,8 @@ const { web3Foreign } = require('../src/services/web3')
module.exports = { module.exports = {
...baseConfig.bridgeConfig, ...baseConfig.bridgeConfig,
queue: 'foreign', queue: 'foreign-prioritized',
oldQueue: 'foreign',
id: 'foreign', id: 'foreign',
name: 'sender-foreign', name: 'sender-foreign',
web3: web3Foreign web3: web3Foreign

@ -4,7 +4,8 @@ const { web3Home } = require('../src/services/web3')
module.exports = { module.exports = {
...baseConfig.bridgeConfig, ...baseConfig.bridgeConfig,
queue: 'home', queue: 'home-prioritized',
oldQueue: 'home',
id: 'home', id: 'home',
name: 'sender-home', name: 'sender-home',
web3: web3Home web3: web3Home

@ -6,7 +6,7 @@ module.exports = {
...baseConfig.bridgeConfig, ...baseConfig.bridgeConfig,
...baseConfig.homeConfig, ...baseConfig.homeConfig,
event: 'UserRequestForSignature', event: 'UserRequestForSignature',
queue: 'home', queue: 'home-prioritized',
name: `watcher-${id}`, name: `watcher-${id}`,
id id
} }

@ -41,7 +41,7 @@ module.exports = {
eventContractAddress: initialChecks.bridgeableTokenAddress, eventContractAddress: initialChecks.bridgeableTokenAddress,
eventAbi: ERC20_ABI, eventAbi: ERC20_ABI,
eventFilter: { to: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS }, eventFilter: { to: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS },
queue: 'home', queue: 'home-prioritized',
...workerQueueConfig, ...workerQueueConfig,
name: `watcher-${id}`, name: `watcher-${id}`,
id id

@ -138,8 +138,8 @@ async function main({ sendJob, txHash }) {
} }
async function sendJobTx(jobs) { async function sendJobTx(jobs) {
const gasPrice = await GasPrice.start(config.queue, true) const gasPrice = await GasPrice.start(config.chain, true)
const chainId = await getChainId(config.queue) const chainId = await getChainId(config.chain)
let nonce = await getNonce(web3Instance, ORACLE_VALIDATOR_ADDRESS) let nonce = await getNonce(web3Instance, ORACLE_VALIDATOR_ADDRESS)
await syncForEach(jobs, async job => { await syncForEach(jobs, async job => {
@ -153,7 +153,7 @@ async function sendJobTx(jobs) {
try { try {
logger.info(`Sending transaction with nonce ${nonce}`) logger.info(`Sending transaction with nonce ${nonce}`)
const txHash = await sendTx({ const txHash = await sendTx({
chain: config.queue, chain: config.chain,
data: job.data, data: job.data,
nonce, nonce,
gasPrice: gasPrice.toString(10), gasPrice: gasPrice.toString(10),

@ -1,5 +1,6 @@
require('../env') require('../env')
const path = require('path') const path = require('path')
const { toBN } = require('web3-utils')
const { connectSenderToQueue } = require('./services/amqpClient') const { connectSenderToQueue } = require('./services/amqpClient')
const { redis } = require('./services/redisClient') const { redis } = require('./services/redisClient')
const GasPrice = require('./services/gasPrice') const GasPrice = require('./services/gasPrice')
@ -45,6 +46,7 @@ async function initialize() {
chainId = await getChainId(config.id) chainId = await getChainId(config.id)
connectSenderToQueue({ connectSenderToQueue({
queueName: config.queue, queueName: config.queue,
oldQueueName: config.oldQueue,
cb: options => { cb: options => {
if (config.maxProcessingTime) { if (config.maxProcessingTime) {
return watchdog(() => main(options), config.maxProcessingTime, () => { return watchdog(() => main(options), config.maxProcessingTime, () => {
@ -88,7 +90,7 @@ function updateNonce(nonce) {
return redis.set(nonceKey, nonce) return redis.set(nonceKey, nonce)
} }
async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) { async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleTransactionResend }) {
try { try {
if (redis.status !== 'ready') { if (redis.status !== 'ready') {
nackMsg(msg) nackMsg(msg)
@ -103,8 +105,15 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
let insufficientFunds = false let insufficientFunds = false
let minimumBalance = null let minimumBalance = null
const failedTx = [] const failedTx = []
const sentTx = []
const isResend = txArray.length > 0 && !!txArray[0].txHash
if (isResend) {
logger.debug(`Checking status of ${txArray.length} transactions`)
} else {
logger.debug(`Sending ${txArray.length} transactions`) logger.debug(`Sending ${txArray.length} transactions`)
}
await syncForEach(txArray, async job => { await syncForEach(txArray, async job => {
let gasLimit let gasLimit
if (typeof job.extraGas === 'number') { if (typeof job.extraGas === 'number') {
@ -114,11 +123,37 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
} }
try { try {
logger.info(`Sending transaction with nonce ${nonce}`) let txNonce
if (isResend) {
const tx = await web3Instance.eth.getTransaction(job.txHash)
if (tx === null) {
logger.info(`Transaction ${job.txHash} was not found, dropping it`)
return
}
if (tx.blockNumber !== null) {
logger.info(`Transaction ${job.txHash} was successfully mined`)
return
}
logger.info(
`Previously sent transaction is stuck, updating gasPrice: ${tx.gasPrice} -> ${gasPrice.toString(10)}`
)
if (toBN(tx.gasPrice).gte(toBN(gasPrice))) {
logger.info("Gas price returned from the oracle didn't increase, will reinspect this transaction later")
sentTx.push(job)
return
}
txNonce = tx.nonce
} else {
txNonce = nonce++
}
logger.info(`Sending transaction with nonce ${txNonce}`)
const txHash = await sendTx({ const txHash = await sendTx({
chain: config.id, chain: config.id,
data: job.data, data: job.data,
nonce, nonce: txNonce,
gasPrice: gasPrice.toString(10), gasPrice: gasPrice.toString(10),
amount: '0', amount: '0',
gasLimit, gasLimit,
@ -127,8 +162,11 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
chainId, chainId,
web3: web3Instance web3: web3Instance
}) })
sentTx.push({
...job,
txHash
})
nonce++
logger.info( logger.info(
{ eventTransactionHash: job.transactionReference, generatedTransactionHash: txHash }, { eventTransactionHash: job.transactionReference, generatedTransactionHash: txHash },
`Tx generated ${txHash} for event Tx ${job.transactionReference}` `Tx generated ${txHash} for event Tx ${job.transactionReference}`
@ -163,6 +201,10 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
logger.info(`Sending ${failedTx.length} Failed Tx to Queue`) logger.info(`Sending ${failedTx.length} Failed Tx to Queue`)
await scheduleForRetry(failedTx, msg.properties.headers['x-retries']) await scheduleForRetry(failedTx, msg.properties.headers['x-retries'])
} }
if (sentTx.length) {
logger.info(`Sending ${sentTx.length} Tx Delayed Resend Requests to Queue`)
await scheduleTransactionResend(sentTx)
}
ackMsg(msg) ackMsg(msg)
logger.debug(`Finished processing msg`) logger.debug(`Finished processing msg`)

@ -11,8 +11,8 @@ function RpcUrlsManager(homeUrls, foreignUrls) {
throw new Error(`Invalid foreignUrls: '${foreignUrls}'`) throw new Error(`Invalid foreignUrls: '${foreignUrls}'`)
} }
this.homeUrls = homeUrls.split(',') this.homeUrls = homeUrls.split(' ')
this.foreignUrls = foreignUrls.split(',') this.foreignUrls = foreignUrls.split(' ')
} }
RpcUrlsManager.prototype.tryEach = async function(chain, f, redundant = false) { RpcUrlsManager.prototype.tryEach = async function(chain, f, redundant = false) {

@ -4,6 +4,12 @@ const dns = require('dns')
const connection = require('amqp-connection-manager').connect(process.env.ORACLE_QUEUE_URL) const connection = require('amqp-connection-manager').connect(process.env.ORACLE_QUEUE_URL)
const logger = require('./logger') const logger = require('./logger')
const { getRetrySequence } = require('../utils/utils') const { getRetrySequence } = require('../utils/utils')
const {
TRANSACTION_RESEND_TIMEOUT,
SENDER_QUEUE_MAX_PRIORITY,
SENDER_QUEUE_SEND_PRIORITY,
SENDER_QUEUE_CHECK_STATUS_PRIORITY
} = require('../utils/constants')
connection.on('connect', () => { connection.on('connect', () => {
logger.info('Connected to amqp Broker') logger.info('Connected to amqp Broker')
@ -22,16 +28,18 @@ async function isAttached() {
} }
function connectWatcherToQueue({ queueName, workerQueue, cb }) { function connectWatcherToQueue({ queueName, workerQueue, cb }) {
const queueList = workerQueue ? [queueName, workerQueue] : [queueName]
const channelWrapper = connection.createChannel({ const channelWrapper = connection.createChannel({
json: true, json: true,
setup(channel) { async setup(channel) {
return Promise.all(queueList.map(queue => channel.assertQueue(queue, { durable: true }))) await channel.assertQueue(queueName, { durable: true, maxPriority: SENDER_QUEUE_MAX_PRIORITY })
if (workerQueue) {
await channel.assertQueue(workerQueue, { durable: true })
}
} }
}) })
const sendToQueue = data => channelWrapper.sendToQueue(queueName, data, { persistent: true }) const sendToQueue = data =>
channelWrapper.sendToQueue(queueName, data, { persistent: true, priority: SENDER_QUEUE_SEND_PRIORITY })
let sendToWorker let sendToWorker
if (workerQueue) { if (workerQueue) {
sendToWorker = data => channelWrapper.sendToQueue(workerQueue, data, { persistent: true }) sendToWorker = data => channelWrapper.sendToQueue(workerQueue, data, { persistent: true })
@ -40,20 +48,34 @@ function connectWatcherToQueue({ queueName, workerQueue, cb }) {
cb({ sendToQueue, sendToWorker, channel: channelWrapper }) cb({ sendToQueue, sendToWorker, channel: channelWrapper })
} }
function connectSenderToQueue({ queueName, cb }) { function connectSenderToQueue({ queueName, oldQueueName, cb }) {
const deadLetterExchange = `${queueName}-retry` const deadLetterExchange = `${queueName}-retry`
async function resendMessagesToNewQueue(channel) {
logger.info(`Trying to check messages in the old non-priority queue ${queueName}`)
while (true) {
const msg = await channel.get(oldQueueName)
if (msg === false) {
logger.info(`No messages in the old queue ${oldQueueName} left`)
break
}
logger.debug(`Message in the old queue ${oldQueueName} was found, redirecting it to the new queue ${queueName}`)
await channel.sendToQueue(queueName, msg.content, { persistent: true, priority: SENDER_QUEUE_SEND_PRIORITY })
await channel.ack(msg)
}
}
const channelWrapper = connection.createChannel({ const channelWrapper = connection.createChannel({
json: true json: true
}) })
channelWrapper.addSetup(channel => { channelWrapper.addSetup(async channel => {
return Promise.all([ await channel.assertExchange(deadLetterExchange, 'fanout', { durable: true })
channel.assertExchange(deadLetterExchange, 'fanout', { durable: true }), await channel.assertQueue(queueName, { durable: true, maxPriority: SENDER_QUEUE_MAX_PRIORITY })
channel.assertQueue(queueName, { durable: true }), await channel.assertQueue(oldQueueName, { durable: true }).then(() => resendMessagesToNewQueue(channel))
channel.bindQueue(queueName, deadLetterExchange), await channel.bindQueue(queueName, deadLetterExchange)
channel.prefetch(1), await channel.prefetch(1)
channel.consume(queueName, msg => await channel.consume(queueName, msg =>
cb({ cb({
msg, msg,
channel: channelWrapper, channel: channelWrapper,
@ -68,10 +90,18 @@ function connectSenderToQueue({ queueName, cb }) {
queueName, queueName,
deadLetterExchange deadLetterExchange
}) })
},
scheduleTransactionResend: async data => {
await generateTransactionResend({
data,
channelWrapper,
channel,
queueName,
deadLetterExchange
})
} }
}) })
) )
])
}) })
} }
@ -82,20 +112,20 @@ function connectWorkerToQueue({ queueName, senderQueue, cb }) {
json: true json: true
}) })
channelWrapper.addSetup(channel => { channelWrapper.addSetup(async channel => {
return Promise.all([ await channel.assertExchange(deadLetterExchange, 'fanout', { durable: true })
channel.assertExchange(deadLetterExchange, 'fanout', { durable: true }), await channel.assertQueue(queueName, { durable: true })
channel.assertQueue(queueName, { durable: true }), await channel.assertQueue(senderQueue, { durable: true, maxPriority: SENDER_QUEUE_MAX_PRIORITY })
channel.assertQueue(senderQueue, { durable: true }), await channel.bindQueue(queueName, deadLetterExchange)
channel.bindQueue(queueName, deadLetterExchange), await channel.prefetch(1)
channel.prefetch(1), await channel.consume(queueName, msg =>
channel.consume(queueName, msg =>
cb({ cb({
msg, msg,
channel: channelWrapper, channel: channelWrapper,
ackMsg: job => channelWrapper.ack(job), ackMsg: job => channelWrapper.ack(job),
nackMsg: job => channelWrapper.nack(job, false, true), nackMsg: job => channelWrapper.nack(job, false, true),
sendToSenderQueue: data => channelWrapper.sendToQueue(senderQueue, data, { persistent: true }), sendToSenderQueue: data =>
channelWrapper.sendToQueue(senderQueue, data, { persistent: true, priority: SENDER_QUEUE_SEND_PRIORITY }),
scheduleForRetry: async (data, msgRetries = 0) => { scheduleForRetry: async (data, msgRetries = 0) => {
await generateRetry({ await generateRetry({
data, data,
@ -108,26 +138,47 @@ function connectWorkerToQueue({ queueName, senderQueue, cb }) {
} }
}) })
) )
])
}) })
} }
async function generateRetry({ data, msgRetries, channelWrapper, channel, queueName, deadLetterExchange }) { async function generateRetry({ data, msgRetries, channelWrapper, channel, queueName, deadLetterExchange }) {
const retries = msgRetries + 1 const retries = msgRetries + 1
const delay = getRetrySequence(retries) * 1000 const delay = getRetrySequence(retries) * 1000
// New retry queue is created, and one message is send to it.
// Nobody consumes messages from this queue, so eventually the message will be dropped.
// `messageTtl` defines a timeout after which the message will be dropped out of the queue.
// When message is dropped, it will be resend into the specified `deadLetterExchange` with the updated `x-retries` header.
const retryQueue = `${queueName}-retry-${delay}` const retryQueue = `${queueName}-retry-${delay}`
await channel.assertQueue(retryQueue, { await channel.assertQueue(retryQueue, {
durable: true, durable: true,
deadLetterExchange, deadLetterExchange,
messageTtl: delay, messageTtl: delay,
expires: delay * 10 expires: delay * 10,
maxPriority: SENDER_QUEUE_MAX_PRIORITY
}) })
await channelWrapper.sendToQueue(retryQueue, data, { await channelWrapper.sendToQueue(retryQueue, data, {
persistent: true, persistent: true,
priority: SENDER_QUEUE_SEND_PRIORITY,
headers: { 'x-retries': retries } headers: { 'x-retries': retries }
}) })
} }
async function generateTransactionResend({ data, channelWrapper, channel, queueName, deadLetterExchange }) {
const retryQueue = `${queueName}-check-tx-status`
await channel.assertQueue(retryQueue, {
durable: true,
deadLetterExchange,
messageTtl: TRANSACTION_RESEND_TIMEOUT,
expires: TRANSACTION_RESEND_TIMEOUT * 10,
maxPriority: SENDER_QUEUE_MAX_PRIORITY
})
await channelWrapper.sendToQueue(retryQueue, data, {
priority: SENDER_QUEUE_CHECK_STATUS_PRIORITY,
persistent: true
})
}
module.exports = { module.exports = {
isAttached, isAttached,
connectWatcherToQueue, connectWatcherToQueue,

@ -22,5 +22,9 @@ module.exports = {
GAS_PRICE_BOUNDARIES: { GAS_PRICE_BOUNDARIES: {
MIN: 1, MIN: 1,
MAX: 250 MAX: 250
} },
TRANSACTION_RESEND_TIMEOUT: 20 * 60 * 1000,
SENDER_QUEUE_MAX_PRIORITY: 10,
SENDER_QUEUE_SEND_PRIORITY: 5,
SENDER_QUEUE_CHECK_STATUS_PRIORITY: 1
} }

@ -33,7 +33,7 @@ async function waitForFunds(web3, address, minimumBalance, cb, logger) {
async retry => { async retry => {
logger.debug('Getting balance of validator account') logger.debug('Getting balance of validator account')
const newBalance = web3.utils.toBN(await web3.eth.getBalance(address)) const newBalance = web3.utils.toBN(await web3.eth.getBalance(address))
if (newBalance.gte(minimumBalance)) { if (newBalance.gte(web3.utils.toBN(minimumBalance.toString(10)))) {
logger.debug({ balance: newBalance, minimumBalance }, 'Validator has minimum necessary balance') logger.debug({ balance: newBalance, minimumBalance }, 'Validator has minimum necessary balance')
cb(newBalance) cb(newBalance)
} else { } else {

@ -73,7 +73,7 @@ describe('gasPrice', () => {
await gasPrice.start('home') await gasPrice.start('home')
// when // when
await gasPrice.fetchGasPrice('standard', 1, null, null) await gasPrice.fetchGasPrice('standard', 1, null, () => null)
// then // then
expect(gasPrice.getPrice()).to.equal('101000000000') expect(gasPrice.getPrice()).to.equal('101000000000')
@ -113,7 +113,7 @@ describe('gasPrice', () => {
} }
// when // when
await gasPrice.fetchGasPrice('standard', 1, bridgeContractMock, null) await gasPrice.fetchGasPrice('standard', 1, bridgeContractMock, () => {})
// then // then
expect(gasPrice.getPrice().toString()).to.equal('102000000000') expect(gasPrice.getPrice().toString()).to.equal('102000000000')
@ -156,7 +156,7 @@ describe('gasPrice', () => {
await gasPrice.start('home') await gasPrice.start('home')
// when // when
await gasPrice.fetchGasPrice('standard', 1, null, null) await gasPrice.fetchGasPrice('standard', 1, null, () => {})
// then // then
expect(fakeLogger.error.calledTwice).to.equal(true) // two errors expect(fakeLogger.error.calledTwice).to.equal(true) // two errors

@ -43,6 +43,7 @@
"test": "yarn wsrun --exclude oracle-e2e --exclude ui-e2e --exclude monitor-e2e --exclude alm-e2e test", "test": "yarn wsrun --exclude oracle-e2e --exclude ui-e2e --exclude monitor-e2e --exclude alm-e2e test",
"oracle-e2e": "./oracle-e2e/run-tests.sh", "oracle-e2e": "./oracle-e2e/run-tests.sh",
"ui-e2e": "./ui-e2e/run-tests.sh", "ui-e2e": "./ui-e2e/run-tests.sh",
"ui-e2e:ci": "xvfb-run yarn ui-e2e",
"monitor-e2e": "./monitor-e2e/run-tests.sh", "monitor-e2e": "./monitor-e2e/run-tests.sh",
"alm-e2e": "./alm-e2e/run-tests.sh", "alm-e2e": "./alm-e2e/run-tests.sh",
"clean": "rm -rf ./node_modules ./**/node_modules ./**/**/node_modules ./**/build ./**/**/dist", "clean": "rm -rf ./node_modules ./**/node_modules ./**/**/node_modules ./**/build ./**/**/dist",

Binary file not shown.

@ -3,7 +3,7 @@ const { By } = require('selenium-webdriver/lib/by')
const { Page } = require('./Page.js') const { Page } = require('./Page.js')
const { homeRPC, foreignRPC } = require('../e2e-commons/constants.json') const { homeRPC, foreignRPC } = require('../e2e-commons/constants.json')
const IDMetaMask = 'dapggmdndodedfoaljbglbkaicfpmkkm' const IDMetaMask = 'hccmbhdehlhjhkenmcjnbcahkmljpife'
const URL = 'chrome-extension://' + IDMetaMask + '//popup.html' const URL = 'chrome-extension://' + IDMetaMask + '//popup.html'
const buttonSubmit = By.className('confirm btn-green') const buttonSubmit = By.className('confirm btn-green')
const buttonAccept = By.xpath('//*[@id="app-content"]/div/div[4]/div/button') const buttonAccept = By.xpath('//*[@id="app-content"]/div/div[4]/div/button')

@ -46,8 +46,11 @@ class Utils {
static async startBrowserWithMetamask() { static async startBrowserWithMetamask() {
const source = './MetaMask.crx' const source = './MetaMask.crx'
const options = new chrome.Options() const options = new chrome.Options()
await options.addExtensions(source) await options.addArguments('--no-sandbox')
await options.addArguments('--disable-gpu')
await options.addArguments('--disable-dev-shm-usage')
await options.addArguments('disable-popup-blocking') await options.addArguments('disable-popup-blocking')
await options.addExtensions(source)
const driver = await new webdriver.Builder().withCapabilities(options.toCapabilities()).build() const driver = await new webdriver.Builder().withCapabilities(options.toCapabilities()).build()
await driver.sleep(5000) await driver.sleep(5000)
return driver return driver

@ -4,7 +4,6 @@
"license": "MIT", "license": "MIT",
"private": true, "private": true,
"devDependencies": { "devDependencies": {
"chromedriver": "^77.0.0",
"mocha": "^5.2.0", "mocha": "^5.2.0",
"selenium-webdriver": "3.6.0" "selenium-webdriver": "3.6.0"
}, },

@ -1,4 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
cd $(dirname $0) cd $(dirname $0)
../e2e-commons/up.sh deploy oracle ui blocks ../e2e-commons/up.sh deploy oracle ui blocks

@ -83,7 +83,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = homeBalanceBefore - maxAmountPerTransactionLimit const shouldBe = homeBalanceBefore - maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance) console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 10
homeBalanceBefore = newHomeBalance homeBalanceBefore = newHomeBalance
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
}) })
@ -95,7 +95,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
console.log('newForeignBalance = ' + newForeignBalance) console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction')
}) })
@ -115,7 +115,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = foreignBalanceBefore - maxAmountPerTransactionLimit const shouldBe = foreignBalanceBefore - maxAmountPerTransactionLimit
console.log('newForeignBalance = ' + newForeignBalance) console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED.Foreign POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Foreign POA balance is not correct after transaction')
}) })
@ -124,7 +124,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = homeBalanceBefore + maxAmountPerTransactionLimit const shouldBe = homeBalanceBefore + maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance) console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
}) })
}) })
@ -173,7 +173,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = foreignBalanceBefore - maxAmountPerTransactionLimit const shouldBe = foreignBalanceBefore - maxAmountPerTransactionLimit
console.log('newForeignBalance = ' + newForeignBalance) console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED.Foreign POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Foreign POA balance is not correct after transaction')
}) })
@ -182,7 +182,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = homeBalanceBefore + maxAmountPerTransactionLimit const shouldBe = homeBalanceBefore + maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance) console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
}) })
test.it('User is able to send tokens from Home account to Foreign account ', async () => { test.it('User is able to send tokens from Home account to Foreign account ', async () => {
@ -202,7 +202,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = homeBalanceBefore - maxAmountPerTransactionLimit const shouldBe = homeBalanceBefore - maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance) console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 10
homeBalanceBefore = newHomeBalance homeBalanceBefore = newHomeBalance
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
}) })
@ -214,7 +214,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
console.log('newForeignBalance = ' + newForeignBalance) console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction')
}) })
}) })
@ -263,7 +263,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = foreignBalanceBefore - maxAmountPerTransactionLimit const shouldBe = foreignBalanceBefore - maxAmountPerTransactionLimit
console.log('newForeignBalance = ' + newForeignBalance) console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED.Foreign POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Foreign POA balance is not correct after transaction')
}) })
@ -272,7 +272,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = homeBalanceBefore + maxAmountPerTransactionLimit const shouldBe = homeBalanceBefore + maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance) console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
}) })
test.it('User is able to send tokens from Home account to Foreign account', async () => { test.it('User is able to send tokens from Home account to Foreign account', async () => {
@ -292,7 +292,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = homeBalanceBefore - maxAmountPerTransactionLimit const shouldBe = homeBalanceBefore - maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance) console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 10
homeBalanceBefore = newHomeBalance homeBalanceBefore = newHomeBalance
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
}) })
@ -304,7 +304,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
console.log('newForeignBalance = ' + newForeignBalance) console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction')
}) })
}) })
@ -353,7 +353,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = foreignBalanceBefore - maxAmountPerTransactionLimit const shouldBe = foreignBalanceBefore - maxAmountPerTransactionLimit
console.log('newForeignBalance = ' + newForeignBalance) console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED.Foreign POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Foreign POA balance is not correct after transaction')
}) })
@ -362,7 +362,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = homeBalanceBefore + maxAmountPerTransactionLimit const shouldBe = homeBalanceBefore + maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance) console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
}) })
test.it('User is able to send tokens from Home account to Foreign account', async () => { test.it('User is able to send tokens from Home account to Foreign account', async () => {
@ -382,7 +382,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
const shouldBe = homeBalanceBefore - maxAmountPerTransactionLimit const shouldBe = homeBalanceBefore - maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance) console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 10
homeBalanceBefore = newHomeBalance homeBalanceBefore = newHomeBalance
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
}) })
@ -394,7 +394,7 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
console.log('newForeignBalance = ' + newForeignBalance) console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe) console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100 const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 10
return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction')
}) })
}) })

@ -1,4 +1,4 @@
FROM node:8 as contracts FROM node:10 as contracts
WORKDIR /mono WORKDIR /mono
@ -11,7 +11,7 @@ COPY ./contracts/truffle-config.js ./
COPY ./contracts/contracts ./contracts COPY ./contracts/contracts ./contracts
RUN npm run compile RUN npm run compile
FROM node:8 FROM node:10
WORKDIR /mono WORKDIR /mono
COPY package.json . COPY package.json .

@ -5,7 +5,6 @@
"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",
"coveralls": "^3.0.0",
"customize-cra": "^0.2.12", "customize-cra": "^0.2.12",
"date-fns": "^2.13.0", "date-fns": "^2.13.0",
"dotenv": "^7.0.0", "dotenv": "^7.0.0",
@ -37,7 +36,6 @@
"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",
"eject": "react-app-rewired eject", "eject": "react-app-rewired eject",
"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) || :"
}, },

125
yarn.lock

@ -5847,17 +5847,6 @@ chrome-trace-event@^1.0.0:
dependencies: dependencies:
tslib "^1.9.0" tslib "^1.9.0"
chromedriver@^77.0.0:
version "77.0.0"
resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-77.0.0.tgz#bd916cc87a0ccb7a6e4fb4b43cb2368bc54db6a0"
integrity sha512-mZa1IVx4HD8rDaItWbnS470mmypgiWsDiu98r0NkiT4uLm3qrANl4vOU6no6vtWtLQiW5kt1POcIbjeNpsLbXA==
dependencies:
del "^4.1.1"
extract-zip "^1.6.7"
mkdirp "^0.5.1"
request "^2.88.0"
tcp-port-used "^1.0.1"
ci-info@^1.5.0: ci-info@^1.5.0:
version "1.6.0" version "1.6.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
@ -6242,7 +6231,7 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
concat-stream@1.6.2, concat-stream@^1.5.0, concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@^1.6.2: concat-stream@^1.5.0, concat-stream@^1.5.1, concat-stream@^1.6.0, concat-stream@^1.6.2:
version "1.6.2" version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
@ -6557,18 +6546,6 @@ cosmiconfig@^5.0.0, cosmiconfig@^5.0.7, cosmiconfig@^5.1.0, cosmiconfig@^5.2.0:
js-yaml "^3.13.1" js-yaml "^3.13.1"
parse-json "^4.0.0" parse-json "^4.0.0"
coveralls@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.3.tgz#83b1c64aea1c6afa69beaf50b55ac1bc4d13e2b8"
integrity sha512-viNfeGlda2zJr8Gj1zqXpDMRjw9uM54p7wzZdvLRyOgnAfCe974Dq4veZkjJdxQXbmdppu6flEajFYseHYaUhg==
dependencies:
growl "~> 1.10.0"
js-yaml "^3.11.0"
lcov-parse "^0.0.10"
log-driver "^1.2.7"
minimist "^1.2.0"
request "^2.86.0"
coveralls@^3.0.6: coveralls@^3.0.6:
version "3.0.11" version "3.0.11"
resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.11.tgz#e141da0922b632fcc66620f334460c3f0026a4ce" resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.11.tgz#e141da0922b632fcc66620f334460c3f0026a4ce"
@ -7061,13 +7038,6 @@ debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
debug@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87"
integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==
dependencies:
ms "^2.1.1"
debuglog@^1.0.1: debuglog@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
@ -7199,7 +7169,7 @@ deep-extend@^0.6.0:
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
deep-is@^0.1.3, deep-is@~0.1.3: deep-is@~0.1.3:
version "0.1.3" version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
@ -7309,19 +7279,6 @@ del@^3.0.0:
pify "^3.0.0" pify "^3.0.0"
rimraf "^2.2.8" rimraf "^2.2.8"
del@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4"
integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==
dependencies:
"@types/glob" "^7.1.1"
globby "^6.1.0"
is-path-cwd "^2.0.0"
is-path-in-cwd "^2.0.0"
p-map "^2.0.0"
pify "^4.0.1"
rimraf "^2.6.3"
delayed-stream@~1.0.0: delayed-stream@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@ -9108,16 +9065,6 @@ extract-comments@^1.1.0:
esprima-extract-comments "^1.1.0" esprima-extract-comments "^1.1.0"
parse-code-context "^1.0.0" parse-code-context "^1.0.0"
extract-zip@^1.6.7:
version "1.6.7"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9"
integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=
dependencies:
concat-stream "1.6.2"
debug "2.6.9"
mkdirp "0.5.1"
yauzl "2.4.1"
extract-zip@^2.0.0: extract-zip@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
@ -9234,13 +9181,6 @@ fb-watchman@^2.0.0:
dependencies: dependencies:
bser "^2.0.0" bser "^2.0.0"
fd-slicer@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65"
integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=
dependencies:
pend "~1.2.0"
fd-slicer@~1.1.0: fd-slicer@~1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
@ -10331,7 +10271,7 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.6:
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
growl@1.10.5, "growl@~> 1.10.0": growl@1.10.5:
version "1.10.5" version "1.10.5"
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
@ -11571,11 +11511,6 @@ is-path-cwd@^1.0.0:
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=
is-path-cwd@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb"
integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==
is-path-in-cwd@^1.0.0: is-path-in-cwd@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52"
@ -11583,13 +11518,6 @@ is-path-in-cwd@^1.0.0:
dependencies: dependencies:
is-path-inside "^1.0.0" is-path-inside "^1.0.0"
is-path-in-cwd@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb"
integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==
dependencies:
is-path-inside "^2.1.0"
is-path-inside@^1.0.0: is-path-inside@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036"
@ -11597,13 +11525,6 @@ is-path-inside@^1.0.0:
dependencies: dependencies:
path-is-inside "^1.0.1" path-is-inside "^1.0.1"
is-path-inside@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2"
integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==
dependencies:
path-is-inside "^1.0.2"
is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: is-plain-obj@^1.0.0, is-plain-obj@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
@ -11734,11 +11655,6 @@ is-unc-path@^1.0.0:
dependencies: dependencies:
unc-path-regex "^0.1.2" unc-path-regex "^0.1.2"
is-url@^1.2.2:
version "1.2.4"
resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
is-utf8@^0.2.0, is-utf8@^0.2.1: is-utf8@^0.2.0, is-utf8@^0.2.1:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
@ -11764,15 +11680,6 @@ is-wsl@^1.1.0:
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=
is2@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is2/-/is2-2.0.1.tgz#8ac355644840921ce435d94f05d3a94634d3481a"
integrity sha512-+WaJvnaA7aJySz2q/8sLjMb2Mw14KTplHmSwcSpZ/fWJPkUmqw3YTzSWbPJ7OAwRvdYTWF2Wg+yYJ1AdP5Z8CA==
dependencies:
deep-is "^0.1.3"
ip-regex "^2.1.0"
is-url "^1.2.2"
isarray@0.0.1: isarray@0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
@ -12438,7 +12345,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@3.x, js-yaml@^3.11.0, js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.9.0: js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.9.0:
version "3.13.1" version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
@ -12826,11 +12733,6 @@ lcid@^2.0.0:
dependencies: dependencies:
invert-kv "^2.0.0" invert-kv "^2.0.0"
lcov-parse@^0.0.10:
version "0.0.10"
resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3"
integrity sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=
lcov-parse@^1.0.0: lcov-parse@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0"
@ -15080,7 +14982,7 @@ p-map@^1.1.1:
resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b"
integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==
p-map@^2.0.0, p-map@^2.1.0: p-map@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
@ -17540,7 +17442,7 @@ request@^2.67.0, request@^2.85.0, request@^2.87.0, request@^2.88.0:
tunnel-agent "^0.6.0" tunnel-agent "^0.6.0"
uuid "^3.3.2" uuid "^3.3.2"
request@^2.79.0, request@^2.86.0: request@^2.79.0:
version "2.88.0" version "2.88.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
@ -19382,14 +19284,6 @@ tar@^4.0.2, tar@^4.4.10, tar@^4.4.12, tar@^4.4.8:
safe-buffer "^5.1.2" safe-buffer "^5.1.2"
yallist "^3.0.3" yallist "^3.0.3"
tcp-port-used@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/tcp-port-used/-/tcp-port-used-1.0.1.tgz#46061078e2d38c73979a2c2c12b5a674e6689d70"
integrity sha512-rwi5xJeU6utXoEIiMvVBMc9eJ2/ofzB+7nLOdnZuFTmNCLqRiQh2sMG9MqCxHU/69VC/Fwp5dV9306Qd54ll1Q==
dependencies:
debug "4.1.0"
is2 "2.0.1"
temp-dir@^1.0.0: temp-dir@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d"
@ -22433,13 +22327,6 @@ yargs@^7.0.0, yargs@^7.1.0:
y18n "^3.2.1" y18n "^3.2.1"
yargs-parser "^5.0.0" yargs-parser "^5.0.0"
yauzl@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005"
integrity sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=
dependencies:
fd-slicer "~1.0.1"
yauzl@^2.10.0, yauzl@^2.4.2: yauzl@^2.10.0, yauzl@^2.4.2:
version "2.10.0" version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"