Compare commits
26 Commits
2.4.0
...
allow-rela
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60b45faa6c | ||
|
|
48752e8575 | ||
|
|
86a47f4a0b | ||
|
|
7af04fa0e8 | ||
|
|
bc871a6844 | ||
|
|
4198b092a6 | ||
|
|
30208b4f8e | ||
|
|
d5946f7df1 | ||
|
|
4efda98f2b | ||
|
|
9e309db876 | ||
|
|
aff8b777c5 | ||
|
|
74293959f3 | ||
|
|
46daeb6815 | ||
|
|
44ca0d71ce | ||
|
|
fbeb878cdb | ||
|
|
d17ea2ad2b | ||
|
|
4cc87ef61a | ||
|
|
125b66b86d | ||
|
|
7a0ed3f699 | ||
|
|
4e04f2ae1f | ||
|
|
dc377aeb9b | ||
|
|
48dd53622c | ||
|
|
6fe63ae9f4 | ||
|
|
4954c859c3 | ||
|
|
27f059db94 | ||
|
|
686c415a5c |
@@ -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
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 }}
|
||||||
@@ -22,7 +22,7 @@ COMMON_FOREIGN_GAS_PRICE_FACTOR | A value that will multiply the gas price of th
|
|||||||
|
|
||||||
name | description | value
|
name | description | value
|
||||||
--- | --- | ---
|
--- | --- | ---
|
||||||
ORACLE_BRIDGE_MODE | The bridge mode. The bridge starts listening to a different set of events based on this parameter. | NATIVE_TO_ERC / ERC_TO_ERC / ERC_TO_NATIVE
|
ORACLE_BRIDGE_MODE | The bridge mode. The bridge starts listening to a different set of events based on this parameter. | NATIVE_TO_ERC / ERC_TO_ERC / ERC_TO_NATIVE / ARBITRARY_MESSAGE
|
||||||
ORACLE_ALLOW_HTTP_FOR_RPC | **Only use in test environments - must be omitted in production environments.**. If this parameter is specified and set to `yes`, RPC URLs can be specified in form of HTTP links. A warning that the connection is insecure will be written to the logs. | `yes` / `no`
|
ORACLE_ALLOW_HTTP_FOR_RPC | **Only use in test environments - must be omitted in production environments.**. If this parameter is specified and set to `yes`, RPC URLs can be specified in form of HTTP links. A warning that the connection is insecure will be written to the logs. | `yes` / `no`
|
||||||
ORACLE_HOME_RPC_POLLING_INTERVAL | The interval in milliseconds used to request the RPC node in the Home network for new blocks. The interval should match the average production time for a new block. | integer
|
ORACLE_HOME_RPC_POLLING_INTERVAL | The interval in milliseconds used to request the RPC node in the Home network for new blocks. The interval should match the average production time for a new block. | integer
|
||||||
ORACLE_FOREIGN_RPC_POLLING_INTERVAL | The interval in milliseconds used to request the RPC node in the Foreign network for new blocks. The interval should match the average production time for a new block. | integer
|
ORACLE_FOREIGN_RPC_POLLING_INTERVAL | The interval in milliseconds used to request the RPC node in the Foreign network for new blocks. The interval should match the average production time for a new block. | integer
|
||||||
@@ -37,6 +37,10 @@ ORACLE_MAX_PROCESSING_TIME | The workers processes will be killed if this amount
|
|||||||
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY | The private key of the bridge validator used to sign confirmations before sending transactions to the bridge contracts. The validator account is calculated automatically from the private key. Every bridge instance (set of watchers and senders) must have its own unique private key. The specified private key is used to sign transactions on both sides of the bridge. | hexidecimal without "0x"
|
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY | The private key of the bridge validator used to sign confirmations before sending transactions to the bridge contracts. The validator account is calculated automatically from the private key. Every bridge instance (set of watchers and senders) must have its own unique private key. The specified private key is used to sign transactions on both sides of the bridge. | hexidecimal without "0x"
|
||||||
ORACLE_VALIDATOR_ADDRESS | The public address of the bridge validator | hexidecimal with "0x"
|
ORACLE_VALIDATOR_ADDRESS | The public address of the bridge validator | hexidecimal with "0x"
|
||||||
ORACLE_TX_REDUNDANCY | If set to `true`, instructs oracle to send `eth_sendRawTransaction` requests through all available RPC urls defined in `COMMON_HOME_RPC_URL` and `COMMON_FOREIGN_RPC_URL` variables instead of using first available one
|
ORACLE_TX_REDUNDANCY | If set to `true`, instructs oracle to send `eth_sendRawTransaction` requests through all available RPC urls defined in `COMMON_HOME_RPC_URL` and `COMMON_FOREIGN_RPC_URL` variables instead of using first available one
|
||||||
|
ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST | Filename with a list of addresses, separated by newlines. If set, determines the privileged set of accounts whose requests will be automatically processed by the CollectedSignatures watcher. | string
|
||||||
|
ORACLE_HOME_TO_FOREIGN_BLOCK_LIST | Filename with a list of addresses, separated by newlines. If set, determines the blocked set of accounts whose requests will not be automatically processed by the CollectedSignatures watcher. Has a lower priority than the `ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST` | string
|
||||||
|
ORACLE_HOME_TO_FOREIGN_CHECK_SENDER | If set to `true`, instructs the oracle to do an extra check for transaction origin in the block/allowance list. `false` by default. | `true` / `false`
|
||||||
|
ORACLE_ALWAYS_RELAY_SIGNATURES | If set to `true`, the oracle will always relay signatures even if it was not the last who finilized the signatures collecting process. The default is `false`. | `true` / `false`
|
||||||
|
|
||||||
|
|
||||||
## UI configuration
|
## UI configuration
|
||||||
@@ -73,4 +77,4 @@ MONITOR_VALIDATOR_FOREIGN_TX_LIMIT | Average gas usage of a transaction sent by
|
|||||||
MONITOR_TX_NUMBER_THRESHOLD | If estimated number of transaction is equal to or below this value, the monitor will report that the validator has less funds than it is required. | integer
|
MONITOR_TX_NUMBER_THRESHOLD | If estimated number of transaction is equal to or below this value, the monitor will report that the validator has less funds than it is required. | integer
|
||||||
MONITOR_PORT | The port for the Monitor. | integer
|
MONITOR_PORT | The port for the Monitor. | integer
|
||||||
MONITOR_BRIDGE_NAME | The name to be used in the url path for the bridge | string
|
MONITOR_BRIDGE_NAME | The name to be used in the url path for the bridge | string
|
||||||
MONITOR_CACHE_EVENTS | If set to true, monitor will cache obtained events for other workers runs
|
MONITOR_CACHE_EVENTS | If set to true, monitor will cache obtained events for other workers runs | `true` / `false`
|
||||||
|
|||||||
@@ -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 @@
|
|||||||
[](https://circleci.com/gh/poanetwork/tokenbridge)
|

|
||||||
[](https://gitter.im/poanetwork/poa-bridge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/poanetwork/poa-bridge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[](https://www.gnu.org/licenses/lgpl-3.0)
|
[](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/)
|
||||||
|
|||||||
@@ -19,6 +19,6 @@
|
|||||||
"eslint-plugin-jest": "^23.18.0"
|
"eslint-plugin-jest": "^23.18.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 8.9"
|
"node": ">= 10.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
0
alm-e2e/run-tests.sh
Normal file → Executable file
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
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export const CONFIRMATIONS_STATUS_DESCRIPTION_HOME: { [key: string]: string } =
|
|||||||
EXECUTION_PENDING:
|
EXECUTION_PENDING:
|
||||||
'The specified transaction was included in a block\nand the validators collected signatures. The\nvalidator’s transaction with collected signatures was\nsent but is not yet added to a block.',
|
'The specified transaction was included in a block\nand the validators collected signatures. The\nvalidator’s transaction with collected signatures was\nsent but is not yet added to a block.',
|
||||||
EXECUTION_WAITING:
|
EXECUTION_WAITING:
|
||||||
'The specified transaction was included in a block\nand the validators collected signatures. Either\n1. One of the validators is waiting for chain finalization.\n2. A validator skipped its duty to relay signatures.\nCheck status again after a few blocks. If the issue still persists contact to the validators by messaging on %linkhttps://forum.poa.network/c/support',
|
'The specified transaction was included in a block\nand the validators collected signatures. Either\n1. One of the validators is waiting for chain finalization.\n2. A validator skipped its duty to relay signatures.\n3. The execution transaction is still pending (e.g. due to the gas price spike).\nCheck status again after a few blocks. If the issue still persists contact to the validators by messaging on %linkhttps://forum.poa.network/c/support',
|
||||||
FAILED:
|
FAILED:
|
||||||
'The specified transaction was included in a block,\nbut transactions with signatures sent by a majority of\nvalidators failed. The cross-chain relay request will\nnot be processed. Contact to the validators by\nmessaging on %linkhttps://forum.poa.network/c/support',
|
'The specified transaction was included in a block,\nbut transactions with signatures sent by a majority of\nvalidators failed. The cross-chain relay request will\nnot be processed. Contact to the validators by\nmessaging on %linkhttps://forum.poa.network/c/support',
|
||||||
PENDING:
|
PENDING:
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -169,13 +169,13 @@ const getPastEvents = async (
|
|||||||
const middlePlusOne = middle.add(toBN(1))
|
const middlePlusOne = middle.add(toBN(1))
|
||||||
|
|
||||||
const firstHalfEvents = await getPastEvents(contract, {
|
const firstHalfEvents = await getPastEvents(contract, {
|
||||||
...options,
|
options,
|
||||||
event,
|
event,
|
||||||
fromBlock,
|
fromBlock,
|
||||||
toBlock: middle
|
toBlock: middle
|
||||||
})
|
})
|
||||||
const secondHalfEvents = await getPastEvents(contract, {
|
const secondHalfEvents = await getPastEvents(contract, {
|
||||||
...options,
|
options,
|
||||||
event,
|
event,
|
||||||
fromBlock: middlePlusOne,
|
fromBlock: middlePlusOne,
|
||||||
toBlock
|
toBlock
|
||||||
|
|||||||
@@ -65,6 +65,20 @@ const homeV1Abi = [
|
|||||||
payable: false,
|
payable: false,
|
||||||
stateMutability: 'view',
|
stateMutability: 'view',
|
||||||
type: 'function'
|
type: 'function'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
constant: true,
|
||||||
|
inputs: [],
|
||||||
|
name: 'requiredBlockConfirmations',
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
type: 'uint256'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
payable: false,
|
||||||
|
stateMutability: 'view',
|
||||||
|
type: 'function'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -154,6 +168,20 @@ const foreignViAbi = [
|
|||||||
payable: false,
|
payable: false,
|
||||||
stateMutability: 'view',
|
stateMutability: 'view',
|
||||||
type: 'function'
|
type: 'function'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
constant: true,
|
||||||
|
inputs: [],
|
||||||
|
name: 'requiredBlockConfirmations',
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
type: 'uint256'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
payable: false,
|
||||||
|
stateMutability: 'view',
|
||||||
|
type: 'function'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
if [ -z "$CI" ]; then
|
||||||
|
docker-compose build molecule_runner
|
||||||
|
else
|
||||||
docker-compose pull molecule_runner
|
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
|
||||||
|
|
||||||
|
|||||||
0
e2e-commons/access-lists/allowance_list.txt
Normal file
0
e2e-commons/access-lists/allowance_list.txt
Normal file
1
e2e-commons/access-lists/block_list.txt
Normal file
1
e2e-commons/access-lists/block_list.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0xc9e38bfdB9c635F0796ad83CC8705dc379F41c04
|
||||||
17
e2e-commons/build.sh
Executable file
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
|
||||||
@@ -23,3 +23,4 @@ ORACLE_FOREIGN_RPC_POLLING_INTERVAL=500
|
|||||||
ORACLE_ALLOW_HTTP_FOR_RPC=yes
|
ORACLE_ALLOW_HTTP_FOR_RPC=yes
|
||||||
ORACLE_HOME_START_BLOCK=1
|
ORACLE_HOME_START_BLOCK=1
|
||||||
ORACLE_FOREIGN_START_BLOCK=1
|
ORACLE_FOREIGN_START_BLOCK=1
|
||||||
|
ORACLE_HOME_TO_FOREIGN_BLOCK_LIST=/mono/oracle/access-lists/block_list.txt
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
"address": "0x3CC5baAB679eC0732C175760079Bf48F564ad26B",
|
"address": "0x3CC5baAB679eC0732C175760079Bf48F564ad26B",
|
||||||
"privateKey": "0xedb53ee050631b7914d5f1a66c2f0d2df3ec85a9ed2a9616b16a7b1b7a10b8d1"
|
"privateKey": "0xedb53ee050631b7914d5f1a66c2f0d2df3ec85a9ed2a9616b16a7b1b7a10b8d1"
|
||||||
},
|
},
|
||||||
|
"blockedUser": {
|
||||||
|
"address": "0xc9e38bfdB9c635F0796ad83CC8705dc379F41c04",
|
||||||
|
"privateKey": "0x65df4ea787916f6ed9660f0b0fe36858a65735ad0dcd34527497f4ce32e53883"
|
||||||
|
},
|
||||||
"validator": {
|
"validator": {
|
||||||
"address": "0xaaB52d66283F7A1D5978bcFcB55721ACB467384b",
|
"address": "0xaaB52d66283F7A1D5978bcFcB55721ACB467384b",
|
||||||
"privateKey": "0x8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9"
|
"privateKey": "0x8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9"
|
||||||
|
|||||||
@@ -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,21 +45,18 @@ 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
|
||||||
command: "true"
|
command: "true"
|
||||||
|
volumes:
|
||||||
|
- '../e2e-commons/access-lists/block_list.txt:/mono/oracle/access-lists/block_list.txt'
|
||||||
|
- '../e2e-commons/access-lists/allowance_list.txt:/mono/oracle/access-lists/allowance_list.txt'
|
||||||
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 +64,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 +78,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 +89,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 +100,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 +117,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 +128,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 +136,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 +144,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 +152,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 +160,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": "",
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"axios": "0.19.0"
|
"axios": "0.19.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 8.9"
|
"node": ">= 10.18"
|
||||||
},
|
},
|
||||||
"devDependencies": {}
|
"devDependencies": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 .
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"web3": "1.0.0-beta.34"
|
"web3": "1.0.0-beta.34"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.9"
|
"node": ">= 10.18"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"chai": "^4.2.0"
|
"chai": "^4.2.0"
|
||||||
|
|||||||
@@ -74,6 +74,11 @@ async function main(mode) {
|
|||||||
|
|
||||||
logger.debug('getting last block numbers')
|
logger.debug('getting last block numbers')
|
||||||
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
||||||
|
const homeConfirmations = toBN(await homeBridge.methods.requiredBlockConfirmations().call())
|
||||||
|
const foreignConfirmations = toBN(await foreignBridge.methods.requiredBlockConfirmations().call())
|
||||||
|
const homeDelayedBlockNumber = homeBlockNumber.sub(homeConfirmations)
|
||||||
|
const foreignDelayedBlockNumber = foreignBlockNumber.sub(foreignConfirmations)
|
||||||
|
|
||||||
let homeToForeignRequests = []
|
let homeToForeignRequests = []
|
||||||
let foreignToHomeRequests = []
|
let foreignToHomeRequests = []
|
||||||
let homeMigrationBlock = MONITOR_HOME_START_BLOCK
|
let homeMigrationBlock = MONITOR_HOME_START_BLOCK
|
||||||
@@ -90,7 +95,7 @@ async function main(mode) {
|
|||||||
homeToForeignRequests = (await getPastEvents(oldHomeBridge, {
|
homeToForeignRequests = (await getPastEvents(oldHomeBridge, {
|
||||||
event: 'UserRequestForSignature',
|
event: 'UserRequestForSignature',
|
||||||
fromBlock: MONITOR_HOME_START_BLOCK,
|
fromBlock: MONITOR_HOME_START_BLOCK,
|
||||||
toBlock: homeBlockNumber
|
toBlock: homeDelayedBlockNumber
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
logger.debug(`found ${homeToForeignRequests.length} events`)
|
logger.debug(`found ${homeToForeignRequests.length} events`)
|
||||||
if (homeToForeignRequests.length > 0) {
|
if (homeToForeignRequests.length > 0) {
|
||||||
@@ -101,7 +106,7 @@ async function main(mode) {
|
|||||||
foreignToHomeRequests = (await getPastEvents(oldForeignBridge, {
|
foreignToHomeRequests = (await getPastEvents(oldForeignBridge, {
|
||||||
event: 'UserRequestForAffirmation',
|
event: 'UserRequestForAffirmation',
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignBlockNumber
|
toBlock: foreignDelayedBlockNumber
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
logger.debug(`found ${foreignToHomeRequests.length} events`)
|
logger.debug(`found ${foreignToHomeRequests.length} events`)
|
||||||
if (foreignToHomeRequests.length > 0) {
|
if (foreignToHomeRequests.length > 0) {
|
||||||
@@ -113,7 +118,7 @@ async function main(mode) {
|
|||||||
const homeToForeignRequestsNew = (await getPastEvents(homeBridge, {
|
const homeToForeignRequestsNew = (await getPastEvents(homeBridge, {
|
||||||
event: v1Bridge ? 'Deposit' : 'UserRequestForSignature',
|
event: v1Bridge ? 'Deposit' : 'UserRequestForSignature',
|
||||||
fromBlock: homeMigrationBlock,
|
fromBlock: homeMigrationBlock,
|
||||||
toBlock: homeBlockNumber
|
toBlock: homeDelayedBlockNumber
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
homeToForeignRequests = [...homeToForeignRequests, ...homeToForeignRequestsNew]
|
homeToForeignRequests = [...homeToForeignRequests, ...homeToForeignRequestsNew]
|
||||||
|
|
||||||
@@ -135,7 +140,7 @@ async function main(mode) {
|
|||||||
const foreignToHomeRequestsNew = (await getPastEvents(foreignBridge, {
|
const foreignToHomeRequestsNew = (await getPastEvents(foreignBridge, {
|
||||||
event: v1Bridge ? 'Withdraw' : 'UserRequestForAffirmation',
|
event: v1Bridge ? 'Withdraw' : 'UserRequestForAffirmation',
|
||||||
fromBlock: foreignMigrationBlock,
|
fromBlock: foreignMigrationBlock,
|
||||||
toBlock: foreignBlockNumber
|
toBlock: foreignDelayedBlockNumber
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
foreignToHomeRequests = [...foreignToHomeRequests, ...foreignToHomeRequestsNew]
|
foreignToHomeRequests = [...foreignToHomeRequests, ...foreignToHomeRequestsNew]
|
||||||
|
|
||||||
@@ -144,7 +149,7 @@ async function main(mode) {
|
|||||||
let transferEvents = (await getPastEvents(erc20Contract, {
|
let transferEvents = (await getPastEvents(erc20Contract, {
|
||||||
event: 'Transfer',
|
event: 'Transfer',
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignBlockNumber,
|
toBlock: foreignDelayedBlockNumber,
|
||||||
options: {
|
options: {
|
||||||
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
||||||
}
|
}
|
||||||
@@ -194,7 +199,7 @@ async function main(mode) {
|
|||||||
const halfDuplexTransferEvents = (await getPastEvents(halfDuplexTokenContract, {
|
const halfDuplexTransferEvents = (await getPastEvents(halfDuplexTokenContract, {
|
||||||
event: 'Transfer',
|
event: 'Transfer',
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignBlockNumber,
|
toBlock: foreignDelayedBlockNumber,
|
||||||
options: {
|
options: {
|
||||||
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
const Web3 = require('web3')
|
|
||||||
const { BRIDGE_MODES, getBridgeMode, HOME_ERC_TO_ERC_ABI } = require('../../commons')
|
|
||||||
|
|
||||||
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_HOME_RPC_URL } = process.env
|
|
||||||
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
|
||||||
const web3Home = new Web3(homeProvider)
|
|
||||||
|
|
||||||
async function isV1Bridge() {
|
|
||||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
|
||||||
const bridgeMode = await getBridgeMode(homeBridge)
|
|
||||||
return bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC_V1
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
isV1Bridge
|
|
||||||
}
|
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
"websocket": "^1.0.28"
|
"websocket": "^1.0.28"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 8.9"
|
"node": ">= 10.18"
|
||||||
},
|
},
|
||||||
"devDependencies": {}
|
"devDependencies": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ const promiseRetry = require('promise-retry')
|
|||||||
const {
|
const {
|
||||||
user,
|
user,
|
||||||
secondUser,
|
secondUser,
|
||||||
|
blockedUser,
|
||||||
validator,
|
validator,
|
||||||
ercToNativeBridge,
|
ercToNativeBridge,
|
||||||
homeRPC,
|
homeRPC,
|
||||||
foreignRPC
|
foreignRPC
|
||||||
} = require('../../e2e-commons/constants.json')
|
} = require('../../e2e-commons/constants.json')
|
||||||
const { ERC677_BRIDGE_TOKEN_ABI, FOREIGN_ERC_TO_NATIVE_ABI, HOME_ERC_TO_NATIVE_ABI } = require('../../commons')
|
const { ERC677_BRIDGE_TOKEN_ABI, FOREIGN_ERC_TO_NATIVE_ABI, HOME_ERC_TO_NATIVE_ABI } = require('../../commons')
|
||||||
const { uniformRetry } = require('../../e2e-commons/utils')
|
const { uniformRetry, sleep } = require('../../e2e-commons/utils')
|
||||||
const { setRequiredSignatures } = require('./utils')
|
const { setRequiredSignatures } = require('./utils')
|
||||||
|
|
||||||
const homeWeb3 = new Web3(new Web3.providers.HttpProvider(homeRPC.URL))
|
const homeWeb3 = new Web3(new Web3.providers.HttpProvider(homeRPC.URL))
|
||||||
@@ -22,6 +23,7 @@ const COMMON_FOREIGN_BRIDGE_ADDRESS = ercToNativeBridge.foreign
|
|||||||
const { toBN } = foreignWeb3.utils
|
const { toBN } = foreignWeb3.utils
|
||||||
|
|
||||||
homeWeb3.eth.accounts.wallet.add(user.privateKey)
|
homeWeb3.eth.accounts.wallet.add(user.privateKey)
|
||||||
|
homeWeb3.eth.accounts.wallet.add(blockedUser.privateKey)
|
||||||
homeWeb3.eth.accounts.wallet.add(validator.privateKey)
|
homeWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||||
foreignWeb3.eth.accounts.wallet.add(user.privateKey)
|
foreignWeb3.eth.accounts.wallet.add(user.privateKey)
|
||||||
foreignWeb3.eth.accounts.wallet.add(validator.privateKey)
|
foreignWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||||
@@ -142,6 +144,47 @@ describe('erc to native', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
it('should not process transaction from blocked users', async () => {
|
||||||
|
const originalBalance1 = await erc20Token.methods.balanceOf(user.address).call()
|
||||||
|
const originalBalance2 = await erc20Token.methods.balanceOf(blockedUser.address).call()
|
||||||
|
|
||||||
|
// check that account has tokens in home chain
|
||||||
|
const balance1 = await homeWeb3.eth.getBalance(user.address)
|
||||||
|
const balance2 = await homeWeb3.eth.getBalance(blockedUser.address)
|
||||||
|
assert(!toBN(balance1).isZero(), 'Account should have tokens')
|
||||||
|
assert(!toBN(balance2).isZero(), 'Account should have tokens')
|
||||||
|
|
||||||
|
// send transaction to home bridge
|
||||||
|
await homeWeb3.eth.sendTransaction({
|
||||||
|
from: user.address,
|
||||||
|
to: COMMON_HOME_BRIDGE_ADDRESS,
|
||||||
|
gasPrice: '1',
|
||||||
|
gas: '1000000',
|
||||||
|
value: homeWeb3.utils.toWei('0.01')
|
||||||
|
})
|
||||||
|
|
||||||
|
// send transaction to home bridge
|
||||||
|
await homeWeb3.eth.sendTransaction({
|
||||||
|
from: blockedUser.address,
|
||||||
|
to: COMMON_HOME_BRIDGE_ADDRESS,
|
||||||
|
gasPrice: '1',
|
||||||
|
gas: '1000000',
|
||||||
|
value: homeWeb3.utils.toWei('0.01')
|
||||||
|
})
|
||||||
|
|
||||||
|
// check that balance increases
|
||||||
|
await uniformRetry(async retry => {
|
||||||
|
const balance = await erc20Token.methods.balanceOf(user.address).call()
|
||||||
|
if (toBN(balance).lte(toBN(originalBalance1))) {
|
||||||
|
retry()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await sleep(3000)
|
||||||
|
|
||||||
|
const balance = await erc20Token.methods.balanceOf(blockedUser.address).call()
|
||||||
|
assert(toBN(balance).eq(toBN(originalBalance2)), 'Bridge should not process collected signatures from blocked user')
|
||||||
|
})
|
||||||
it('should not invest dai when chai token is disabled', async () => {
|
it('should not invest dai when chai token is disabled', async () => {
|
||||||
const bridgeDaiTokenBalance = await erc20Token.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
const bridgeDaiTokenBalance = await erc20Token.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ ORACLE_FOREIGN_START_BLOCK=
|
|||||||
ORACLE_LOG_LEVEL=debug
|
ORACLE_LOG_LEVEL=debug
|
||||||
ORACLE_MAX_PROCESSING_TIME=20000
|
ORACLE_MAX_PROCESSING_TIME=20000
|
||||||
|
|
||||||
|
ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST=access-lists/allowance_list.txt
|
||||||
|
ORACLE_HOME_TO_FOREIGN_BLOCK_LIST=access-lists/block_list.txt
|
||||||
|
ORACLE_HOME_TO_FOREIGN_CHECK_SENDER=false
|
||||||
|
|
||||||
#Uncomment these lines only if you are going to send transaction by testing scripts
|
#Uncomment these lines only if you are going to send transaction by testing scripts
|
||||||
#USER_ADDRESS=0x59c4474184579b9c31b5e51445b6eef91cebf370
|
#USER_ADDRESS=0x59c4474184579b9c31b5e51445b6eef91cebf370
|
||||||
#USER_ADDRESS_PRIVATE_KEY=
|
#USER_ADDRESS_PRIVATE_KEY=
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ services:
|
|||||||
extends:
|
extends:
|
||||||
file: docker-compose.yml
|
file: docker-compose.yml
|
||||||
service: bridge_collected
|
service: bridge_collected
|
||||||
|
volumes:
|
||||||
|
- '~/bridge_data/access-lists/block_list.txt:/mono/oracle/access-lists/block_list.txt'
|
||||||
|
- '~/bridge_data/access-lists/allowance_list.txt:/mono/oracle/access-lists/allowance_list.txt'
|
||||||
networks:
|
networks:
|
||||||
- net_db_bridge_request
|
- net_db_bridge_request
|
||||||
- net_rabbit_bridge_request
|
- net_rabbit_bridge_request
|
||||||
|
|||||||
@@ -48,6 +48,6 @@
|
|||||||
"sinon": "^6.1.0"
|
"sinon": "^6.1.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 8.9"
|
"node": ">= 10.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
@@ -177,7 +177,7 @@ async function sendJobTx(jobs) {
|
|||||||
e.message
|
e.message
|
||||||
)
|
)
|
||||||
|
|
||||||
if (e.message.includes('Insufficient funds')) {
|
if (e.message.toLowerCase().includes('insufficient funds')) {
|
||||||
const currentBalance = await web3Instance.eth.getBalance(ORACLE_VALIDATOR_ADDRESS)
|
const currentBalance = await web3Instance.eth.getBalance(ORACLE_VALIDATOR_ADDRESS)
|
||||||
const minimumBalance = gasLimit.multipliedBy(gasPrice)
|
const minimumBalance = gasLimit.multipliedBy(gasPrice)
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ const { MAX_CONCURRENT_EVENTS, EXTRA_GAS_ABSOLUTE } = require('../../utils/const
|
|||||||
|
|
||||||
const limit = promiseLimit(MAX_CONCURRENT_EVENTS)
|
const limit = promiseLimit(MAX_CONCURRENT_EVENTS)
|
||||||
|
|
||||||
|
const { ORACLE_ALWAYS_RELAY_SIGNATURES } = process.env
|
||||||
|
|
||||||
let validatorContract = null
|
let validatorContract = null
|
||||||
|
|
||||||
function processCollectedSignaturesBuilder(config) {
|
function processCollectedSignaturesBuilder(config) {
|
||||||
@@ -39,7 +41,9 @@ function processCollectedSignaturesBuilder(config) {
|
|||||||
eventTransactionHash: colSignature.transactionHash
|
eventTransactionHash: colSignature.transactionHash
|
||||||
})
|
})
|
||||||
|
|
||||||
if (authorityResponsibleForRelay !== web3Home.utils.toChecksumAddress(config.validatorAddress)) {
|
if (ORACLE_ALWAYS_RELAY_SIGNATURES && ORACLE_ALWAYS_RELAY_SIGNATURES === 'true') {
|
||||||
|
logger.debug('Validator handles all CollectedSignature requests')
|
||||||
|
} else if (authorityResponsibleForRelay !== web3Home.utils.toChecksumAddress(config.validatorAddress)) {
|
||||||
logger.info(`Validator not responsible for relaying CollectedSignatures ${colSignature.transactionHash}`)
|
logger.info(`Validator not responsible for relaying CollectedSignatures ${colSignature.transactionHash}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,19 @@ const { HttpListProviderError } = require('http-list-provider')
|
|||||||
const { BRIDGE_VALIDATORS_ABI } = require('../../../../commons')
|
const { BRIDGE_VALIDATORS_ABI } = require('../../../../commons')
|
||||||
const rootLogger = require('../../services/logger')
|
const rootLogger = require('../../services/logger')
|
||||||
const { web3Home, web3Foreign } = require('../../services/web3')
|
const { web3Home, web3Foreign } = require('../../services/web3')
|
||||||
const { signatureToVRS, packSignatures } = require('../../utils/message')
|
const { signatureToVRS, packSignatures, parseMessage } = require('../../utils/message')
|
||||||
|
const { readAccessListFile } = require('../../utils/utils')
|
||||||
const estimateGas = require('./estimateGas')
|
const estimateGas = require('./estimateGas')
|
||||||
const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors')
|
const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors')
|
||||||
const { MAX_CONCURRENT_EVENTS } = require('../../utils/constants')
|
const { MAX_CONCURRENT_EVENTS } = require('../../utils/constants')
|
||||||
|
|
||||||
|
const {
|
||||||
|
ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST,
|
||||||
|
ORACLE_HOME_TO_FOREIGN_BLOCK_LIST,
|
||||||
|
ORACLE_HOME_TO_FOREIGN_CHECK_SENDER,
|
||||||
|
ORACLE_ALWAYS_RELAY_SIGNATURES
|
||||||
|
} = process.env
|
||||||
|
|
||||||
const limit = promiseLimit(MAX_CONCURRENT_EVENTS)
|
const limit = promiseLimit(MAX_CONCURRENT_EVENTS)
|
||||||
|
|
||||||
let validatorContract = null
|
let validatorContract = null
|
||||||
@@ -38,7 +46,9 @@ function processCollectedSignaturesBuilder(config) {
|
|||||||
eventTransactionHash: colSignature.transactionHash
|
eventTransactionHash: colSignature.transactionHash
|
||||||
})
|
})
|
||||||
|
|
||||||
if (authorityResponsibleForRelay !== web3Home.utils.toChecksumAddress(config.validatorAddress)) {
|
if (ORACLE_ALWAYS_RELAY_SIGNATURES && ORACLE_ALWAYS_RELAY_SIGNATURES === 'true') {
|
||||||
|
logger.debug('Validator handles all CollectedSignature requests')
|
||||||
|
} else if (authorityResponsibleForRelay !== web3Home.utils.toChecksumAddress(config.validatorAddress)) {
|
||||||
logger.info(`Validator not responsible for relaying CollectedSignatures ${colSignature.transactionHash}`)
|
logger.info(`Validator not responsible for relaying CollectedSignatures ${colSignature.transactionHash}`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -46,6 +56,53 @@ function processCollectedSignaturesBuilder(config) {
|
|||||||
logger.info(`Processing CollectedSignatures ${colSignature.transactionHash}`)
|
logger.info(`Processing CollectedSignatures ${colSignature.transactionHash}`)
|
||||||
const message = await homeBridge.methods.message(messageHash).call()
|
const message = await homeBridge.methods.message(messageHash).call()
|
||||||
|
|
||||||
|
if (ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST || ORACLE_HOME_TO_FOREIGN_BLOCK_LIST) {
|
||||||
|
const parsedMessage = parseMessage(message)
|
||||||
|
const recipient = parsedMessage.recipient.toLowerCase()
|
||||||
|
const originalTxHash = parsedMessage.txHash
|
||||||
|
|
||||||
|
if (ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST) {
|
||||||
|
const allowanceList = await readAccessListFile(ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST, logger)
|
||||||
|
if (allowanceList.indexOf(recipient) === -1) {
|
||||||
|
if (ORACLE_HOME_TO_FOREIGN_CHECK_SENDER === 'true') {
|
||||||
|
logger.debug({ txHash: originalTxHash }, 'Requested sender of an original withdrawal transaction')
|
||||||
|
const originalTx = await web3Home.eth.getTransaction(originalTxHash)
|
||||||
|
logger.debug(`Tx data of an original withdrawal transaction ${originalTx.input}`)
|
||||||
|
const isRelayTokens = originalTx.input.slice(2, 10) === '5d1e9307'
|
||||||
|
logger.info(`Is the relayTokens method invoked: ${isRelayTokens}`)
|
||||||
|
const sender = originalTx.from.toLowerCase()
|
||||||
|
if (allowanceList.indexOf(sender) === -1 && !isRelayTokens) {
|
||||||
|
logger.info(
|
||||||
|
{ sender, recipient },
|
||||||
|
'Validator skips a transaction. Neither sender nor recipient addresses are in the allowance list.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.info(
|
||||||
|
{ recipient },
|
||||||
|
'Validator skips a transaction. Recipient address is not in the allowance list.'
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (ORACLE_HOME_TO_FOREIGN_BLOCK_LIST) {
|
||||||
|
const blockList = await readAccessListFile(ORACLE_HOME_TO_FOREIGN_BLOCK_LIST, logger)
|
||||||
|
if (blockList.indexOf(recipient) > -1) {
|
||||||
|
logger.info({ recipient }, 'Validator skips a transaction. Recipient address is in the block list.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (ORACLE_HOME_TO_FOREIGN_CHECK_SENDER === 'true') {
|
||||||
|
logger.debug({ txHash: originalTxHash }, 'Requested sender of an original withdrawal transaction')
|
||||||
|
const sender = (await web3Home.eth.getTransaction(originalTxHash)).from.toLowerCase()
|
||||||
|
if (blockList.indexOf(sender) > -1) {
|
||||||
|
logger.info({ sender }, 'Validator skips a transaction. Sender address is in the block list.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.debug({ NumberOfCollectedSignatures }, 'Number of signatures to get')
|
logger.debug({ NumberOfCollectedSignatures }, 'Number of signatures to get')
|
||||||
|
|
||||||
const requiredSignatures = []
|
const requiredSignatures = []
|
||||||
|
|||||||
@@ -45,6 +45,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, () => {
|
||||||
@@ -79,16 +80,20 @@ async function readNonce(forceUpdate) {
|
|||||||
logger.debug({ nonce }, 'Nonce found in the DB')
|
logger.debug({ nonce }, 'Nonce found in the DB')
|
||||||
return Number(nonce)
|
return Number(nonce)
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Nonce wasn't found in the DB")
|
logger.warn("Nonce wasn't found in the DB")
|
||||||
return getNonce(web3Instance, ORACLE_VALIDATOR_ADDRESS)
|
return getNonce(web3Instance, ORACLE_VALIDATOR_ADDRESS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateNonce(nonce) {
|
function updateNonce(nonce) {
|
||||||
return redis.set(nonceKey, nonce)
|
if (typeof nonce !== 'number') {
|
||||||
|
logger.warn('Given nonce value is not a valid number. Nothing will be updated in the DB.')
|
||||||
|
} else {
|
||||||
|
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)
|
||||||
@@ -96,15 +101,24 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const txArray = JSON.parse(msg.content)
|
const txArray = JSON.parse(msg.content)
|
||||||
logger.info(`Msg received with ${txArray.length} Tx to send`)
|
logger.debug(`Msg received with ${txArray.length} Tx to send`)
|
||||||
const gasPrice = GasPrice.getPrice()
|
const gasPrice = GasPrice.getPrice().toString(10)
|
||||||
|
|
||||||
let nonce = await readNonce()
|
let nonce
|
||||||
let insufficientFunds = false
|
let insufficientFunds = false
|
||||||
let minimumBalance = null
|
let minimumBalance = null
|
||||||
const failedTx = []
|
const failedTx = []
|
||||||
|
const resendJobs = []
|
||||||
|
|
||||||
logger.debug(`Sending ${txArray.length} transactions`)
|
const isResend = txArray.length > 0 && !!txArray[0].txHash
|
||||||
|
|
||||||
|
if (isResend) {
|
||||||
|
logger.info(`Checking status of ${txArray.length} transactions`)
|
||||||
|
nonce = null
|
||||||
|
} else {
|
||||||
|
logger.info(`Sending ${txArray.length} transactions`)
|
||||||
|
nonce = await readNonce()
|
||||||
|
}
|
||||||
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,12 +128,26 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (isResend) {
|
||||||
|
const tx = await web3Instance.eth.getTransaction(job.txHash)
|
||||||
|
|
||||||
|
if (tx && tx.blockNumber !== null) {
|
||||||
|
logger.debug(`Transaction ${job.txHash} was successfully mined`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nonce === null) {
|
||||||
|
nonce = await readNonce(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`Transaction ${job.txHash} was not mined, updating gasPrice: ${job.gasPrice} -> ${gasPrice}`)
|
||||||
|
}
|
||||||
logger.info(`Sending transaction with nonce ${nonce}`)
|
logger.info(`Sending transaction with nonce ${nonce}`)
|
||||||
const txHash = await sendTx({
|
const txHash = await sendTx({
|
||||||
chain: config.id,
|
chain: config.id,
|
||||||
data: job.data,
|
data: job.data,
|
||||||
nonce,
|
nonce,
|
||||||
gasPrice: gasPrice.toString(10),
|
gasPrice,
|
||||||
amount: '0',
|
amount: '0',
|
||||||
gasLimit,
|
gasLimit,
|
||||||
privateKey: ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY,
|
privateKey: ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY,
|
||||||
@@ -127,6 +155,12 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
|
|||||||
chainId,
|
chainId,
|
||||||
web3: web3Instance
|
web3: web3Instance
|
||||||
})
|
})
|
||||||
|
const resendJob = {
|
||||||
|
...job,
|
||||||
|
txHash,
|
||||||
|
gasPrice
|
||||||
|
}
|
||||||
|
resendJobs.push(resendJob)
|
||||||
|
|
||||||
nonce++
|
nonce++
|
||||||
logger.info(
|
logger.info(
|
||||||
@@ -139,11 +173,15 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
|
|||||||
`Tx Failed for event Tx ${job.transactionReference}.`,
|
`Tx Failed for event Tx ${job.transactionReference}.`,
|
||||||
e.message
|
e.message
|
||||||
)
|
)
|
||||||
if (!e.message.includes('Transaction with the same hash was already imported')) {
|
if (!e.message.toLowerCase().includes('transaction with the same hash was already imported')) {
|
||||||
|
if (isResend) {
|
||||||
|
resendJobs.push(job)
|
||||||
|
} else {
|
||||||
failedTx.push(job)
|
failedTx.push(job)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (e.message.includes('Insufficient funds')) {
|
if (e.message.toLowerCase().includes('insufficient funds')) {
|
||||||
insufficientFunds = true
|
insufficientFunds = true
|
||||||
const currentBalance = await web3Instance.eth.getBalance(ORACLE_VALIDATOR_ADDRESS)
|
const currentBalance = await web3Instance.eth.getBalance(ORACLE_VALIDATOR_ADDRESS)
|
||||||
minimumBalance = gasLimit.multipliedBy(gasPrice)
|
minimumBalance = gasLimit.multipliedBy(gasPrice)
|
||||||
@@ -156,13 +194,19 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry }) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (typeof nonce === 'number') {
|
||||||
logger.debug('Updating nonce')
|
logger.debug('Updating nonce')
|
||||||
await updateNonce(nonce)
|
await updateNonce(nonce)
|
||||||
|
}
|
||||||
|
|
||||||
if (failedTx.length) {
|
if (failedTx.length) {
|
||||||
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 (resendJobs.length) {
|
||||||
|
logger.info(`Sending ${resendJobs.length} Tx Delayed Resend Requests to Queue`)
|
||||||
|
await scheduleTransactionResend(resendJobs)
|
||||||
|
}
|
||||||
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,
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
GAS_PRICE_BOUNDARIES: {
|
GAS_PRICE_BOUNDARIES: {
|
||||||
MIN: 1,
|
MIN: 1,
|
||||||
MAX: 250
|
MAX: 1000
|
||||||
}
|
},
|
||||||
|
TRANSACTION_RESEND_TIMEOUT: 20 * 60 * 1000,
|
||||||
|
SENDER_QUEUE_MAX_PRIORITY: 10,
|
||||||
|
SENDER_QUEUE_SEND_PRIORITY: 5,
|
||||||
|
SENDER_QUEUE_CHECK_STATUS_PRIORITY: 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
const fs = require('fs')
|
||||||
const BigNumber = require('bignumber.js')
|
const BigNumber = require('bignumber.js')
|
||||||
const promiseRetry = require('promise-retry')
|
const promiseRetry = require('promise-retry')
|
||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
@@ -33,7 +34,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 {
|
||||||
@@ -93,10 +94,11 @@ function privateKeyToAddress(privateKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function nonceError(e) {
|
function nonceError(e) {
|
||||||
|
const message = e.message.toLowerCase()
|
||||||
return (
|
return (
|
||||||
e.message.includes('Transaction nonce is too low') ||
|
message.includes('transaction nonce is too low') ||
|
||||||
e.message.includes('nonce too low') ||
|
message.includes('nonce too low') ||
|
||||||
e.message.includes('transaction with same nonce in the queue')
|
message.includes('transaction with same nonce in the queue')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +107,27 @@ function nonceError(e) {
|
|||||||
const invert = p => new Promise((res, rej) => p.then(rej, res))
|
const invert = p => new Promise((res, rej) => p.then(rej, res))
|
||||||
const promiseAny = ps => invert(Promise.all(ps.map(invert)))
|
const promiseAny = ps => invert(Promise.all(ps.map(invert)))
|
||||||
|
|
||||||
|
const readAccessLists = {}
|
||||||
|
async function readAccessListFile(fileName, logger) {
|
||||||
|
if (!readAccessLists[fileName]) {
|
||||||
|
logger.debug({ fileName }, 'Access list file read requested')
|
||||||
|
try {
|
||||||
|
const data = await fs.promises.readFile(fileName)
|
||||||
|
readAccessLists[fileName] = data
|
||||||
|
.toString()
|
||||||
|
.split('\n')
|
||||||
|
.map(addr => addr.trim().toLowerCase())
|
||||||
|
.filter(addr => addr.length === 42)
|
||||||
|
logger.info({ fileName }, `Access list was read successfully, ${data.length} addresses found`)
|
||||||
|
logger.debug({ addresses: readAccessLists[fileName] }, `Read addresses from the file`)
|
||||||
|
} catch (e) {
|
||||||
|
readAccessLists[fileName] = []
|
||||||
|
logger.error({ fileName, error: e }, `Failed to read access list from the file`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return readAccessLists[fileName]
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
syncForEach,
|
syncForEach,
|
||||||
checkHTTPS,
|
checkHTTPS,
|
||||||
@@ -115,5 +138,6 @@ module.exports = {
|
|||||||
privateKeyToAddress,
|
privateKeyToAddress,
|
||||||
nonceError,
|
nonceError,
|
||||||
getRetrySequence,
|
getRetrySequence,
|
||||||
promiseAny
|
promiseAny,
|
||||||
|
readAccessListFile
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
"Dcef88209a20D52165230104B245803C3269454d": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
"Dcef88209a20D52165230104B245803C3269454d": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
||||||
"bb140FbA6242a1c3887A7823F7750a73101383e3": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
"bb140FbA6242a1c3887A7823F7750a73101383e3": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
||||||
"7FC1442AB55Da569940Eb750AaD2BAA63DA4010E": { "balance": "500000000000000000000" },
|
"7FC1442AB55Da569940Eb750AaD2BAA63DA4010E": { "balance": "500000000000000000000" },
|
||||||
"B4579fd5AfEaB60B03Db3F408AAdD315035943f7": { "balance": "500000000000000000000" }
|
"B4579fd5AfEaB60B03Db3F408AAdD315035943f7": { "balance": "500000000000000000000" },
|
||||||
|
"c9e38bfdB9c635F0796ad83CC8705dc379F41c04": { "balance": "500000000000000000000" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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"
|
||||||
},
|
},
|
||||||
@@ -12,6 +11,6 @@
|
|||||||
"lint": "eslint . --ignore-path ../.eslintignore"
|
"lint": "eslint . --ignore-path ../.eslintignore"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 8.9"
|
"node": ">= 10.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) || :"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ class ForeignStore {
|
|||||||
@action
|
@action
|
||||||
async getCurrentLimit() {
|
async getCurrentLimit() {
|
||||||
try {
|
try {
|
||||||
const result = await getCurrentLimit(this.foreignBridge, this.tokenDecimals)
|
const result = await getCurrentLimit(this.foreignBridge, this.homeStore.homeBridge, this.tokenDecimals)
|
||||||
this.maxCurrentDeposit = result.maxCurrentDeposit
|
this.maxCurrentDeposit = result.maxCurrentDeposit
|
||||||
this.dailyLimit = result.dailyLimit
|
this.dailyLimit = result.dailyLimit
|
||||||
this.totalSpentPerDay = result.totalSpentPerDay
|
this.totalSpentPerDay = result.totalSpentPerDay
|
||||||
|
|||||||
@@ -429,7 +429,11 @@ class HomeStore {
|
|||||||
@action
|
@action
|
||||||
async getCurrentLimit() {
|
async getCurrentLimit() {
|
||||||
try {
|
try {
|
||||||
const result = await getCurrentLimit(this.homeBridge, this.tokenDecimals)
|
const result = await getCurrentLimit(
|
||||||
|
this.homeBridge,
|
||||||
|
this.rootStore.foreignStore.foreignBridge,
|
||||||
|
this.tokenDecimals
|
||||||
|
)
|
||||||
this.maxCurrentDeposit = result.maxCurrentDeposit
|
this.maxCurrentDeposit = result.maxCurrentDeposit
|
||||||
this.dailyLimit = result.dailyLimit
|
this.dailyLimit = result.dailyLimit
|
||||||
this.totalSpentPerDay = result.totalSpentPerDay
|
this.totalSpentPerDay = result.totalSpentPerDay
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ export const getMinPerTxLimit = async (contract, decimals) => {
|
|||||||
return fromDecimals(minPerTx, decimals)
|
return fromDecimals(minPerTx, decimals)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getCurrentLimit = async (contract, decimals) => {
|
export const getCurrentLimit = async (contract, otherContract, decimals) => {
|
||||||
const currentDay = await contract.methods.getCurrentDay().call()
|
const currentDay = await contract.methods.getCurrentDay().call()
|
||||||
const dailyLimit = await contract.methods.dailyLimit().call()
|
const dailyLimit = await contract.methods.dailyLimit().call()
|
||||||
const totalSpentPerDay = await contract.methods.totalSpentPerDay(currentDay).call()
|
const totalSpentPerDay = await otherContract.methods.totalExecutedPerDay(currentDay).call()
|
||||||
const maxCurrentDeposit = new BN(dailyLimit).minus(new BN(totalSpentPerDay)).toString(10)
|
const maxCurrentDeposit = new BN(dailyLimit).minus(new BN(totalSpentPerDay)).toString(10)
|
||||||
return {
|
return {
|
||||||
maxCurrentDeposit: fromDecimals(maxCurrentDeposit, decimals),
|
maxCurrentDeposit: fromDecimals(maxCurrentDeposit, decimals),
|
||||||
|
|||||||
125
yarn.lock
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"
|
||||||
|
|||||||
Reference in New Issue
Block a user