Compare commits
1 Commits
2.6.0-rc2
...
fix-bw-plu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c02ecad8fd |
@@ -8,16 +8,11 @@
|
|||||||
**/docs
|
**/docs
|
||||||
**/*.md
|
**/*.md
|
||||||
|
|
||||||
monitor/**/*.env*
|
|
||||||
oracle/**/*.env*
|
|
||||||
!**/.env.example
|
|
||||||
|
|
||||||
contracts/test
|
contracts/test
|
||||||
contracts/build
|
contracts/build
|
||||||
oracle/test
|
oracle/test
|
||||||
monitor/test
|
monitor/test
|
||||||
monitor/responses
|
monitor/responses
|
||||||
monitor/cache/*
|
|
||||||
commons/test
|
commons/test
|
||||||
oracle/**/*.png
|
oracle/**/*.png
|
||||||
oracle/**/*.jpg
|
oracle/**/*.jpg
|
||||||
|
|||||||
102
.github/workflows/main.yml
vendored
102
.github/workflows/main.yml
vendored
@@ -19,11 +19,9 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Set cache key
|
- run: git submodule status > submodule.status
|
||||||
id: get_cache_key
|
- id: get_cache_key
|
||||||
run: |
|
run: echo "::set-output name=cache_key::cache-repo-${{ hashFiles('yarn.lock', 'package.json', 'submodule.status') }}"
|
||||||
git submodule status > submodule.status
|
|
||||||
echo "::set-output name=cache_key::cache-repo-${{ hashFiles('yarn.lock', 'package.json', 'submodule.status') }}"
|
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v2
|
||||||
id: cache-repo
|
id: cache-repo
|
||||||
with:
|
with:
|
||||||
@@ -31,8 +29,7 @@ jobs:
|
|||||||
**/node_modules
|
**/node_modules
|
||||||
contracts/build
|
contracts/build
|
||||||
key: ${{ steps.get_cache_key.outputs.cache_key }}
|
key: ${{ steps.get_cache_key.outputs.cache_key }}
|
||||||
- name: Install dependencies and compile contracts
|
- if: ${{ !steps.cache-repo.outputs.cache-hit }}
|
||||||
if: ${{ !steps.cache-repo.outputs.cache-hit }}
|
|
||||||
run: |
|
run: |
|
||||||
yarn install --frozen-lockfile
|
yarn install --frozen-lockfile
|
||||||
yarn run install:deploy
|
yarn run install:deploy
|
||||||
@@ -59,8 +56,7 @@ jobs:
|
|||||||
**/node_modules
|
**/node_modules
|
||||||
contracts/build
|
contracts/build
|
||||||
key: ${{ needs.initialize.outputs.cache_key }}
|
key: ${{ needs.initialize.outputs.cache_key }}
|
||||||
- name: yarn run ${{ matrix.task }}
|
- run: ${{ steps.cache-repo.outputs.cache-hit }} && yarn run ${{ matrix.task }}
|
||||||
run: ${{ steps.cache-repo.outputs.cache-hit }} && yarn run ${{ matrix.task }}
|
|
||||||
ui-coverage:
|
ui-coverage:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs:
|
needs:
|
||||||
@@ -80,8 +76,7 @@ jobs:
|
|||||||
**/node_modules
|
**/node_modules
|
||||||
contracts/build
|
contracts/build
|
||||||
key: ${{ needs.initialize.outputs.cache_key }}
|
key: ${{ needs.initialize.outputs.cache_key }}
|
||||||
- name: yarn workspace ui run coverage
|
- run: ${{ steps.cache-repo.outputs.cache-hit }} && yarn workspace ui run coverage
|
||||||
run: ${{ steps.cache-repo.outputs.cache-hit }} && yarn workspace ui run coverage
|
|
||||||
- uses: coverallsapp/github-action@master
|
- uses: coverallsapp/github-action@master
|
||||||
with:
|
with:
|
||||||
github-token: ${{ github.token }}
|
github-token: ${{ github.token }}
|
||||||
@@ -92,16 +87,14 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Evaluate e2e docker images tags
|
- run: |
|
||||||
run: |
|
|
||||||
git submodule status > submodule.status
|
git submodule status > submodule.status
|
||||||
echo "E2E_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e') }}" >> $GITHUB_ENV
|
echo "::set-env name=E2E_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e') }}"
|
||||||
echo "ORACLE_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}" >> $GITHUB_ENV
|
echo "::set-env name=ORACLE_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}"
|
||||||
echo "MONITOR_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}" >> $GITHUB_ENV
|
echo "::set-env name=MONITOR_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}"
|
||||||
echo "UI_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'ui') }}" >> $GITHUB_ENV
|
echo "::set-env name=UI_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'ui') }}"
|
||||||
echo "ALM_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}" >> $GITHUB_ENV
|
echo "::set-env name=ALM_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}"
|
||||||
- name: Rebuild and push updated images
|
- run: |
|
||||||
run: |
|
|
||||||
function check_if_image_exists() {
|
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
|
curl -fsSlL -H 'Authorization: bearer ${{ github.token }}' "https://${DOCKER_REGISTRY}/v2/${DOCKER_REPO}/tokenbridge-e2e-$1/manifests/$2" > /dev/null
|
||||||
}
|
}
|
||||||
@@ -126,10 +119,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Evaluate e2e molecule runner tag
|
- run: echo "::set-env name=MOLECULE_RUNNER_TAG::${{ hashFiles('./deployment-e2e/Dockerfile') }}"
|
||||||
run: echo "MOLECULE_RUNNER_TAG=${{ hashFiles('./deployment-e2e/Dockerfile') }}" >> $GITHUB_ENV
|
- run: |
|
||||||
- name: Rebuild and push molecule runner e2e image
|
|
||||||
run: |
|
|
||||||
function check_if_image_exists() {
|
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
|
curl -fsSlL -H 'Authorization: bearer ${{ github.token }}' "https://${DOCKER_REGISTRY}/v2/${DOCKER_REPO}/tokenbridge-e2e-$1/manifests/$2" > /dev/null
|
||||||
}
|
}
|
||||||
@@ -159,15 +150,14 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Evaluate e2e docker images tags
|
- run: |
|
||||||
run: |
|
|
||||||
git submodule status > submodule.status
|
git submodule status > submodule.status
|
||||||
echo "E2E_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e') }}" >> $GITHUB_ENV
|
echo "::set-env name=E2E_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e') }}"
|
||||||
echo "ORACLE_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}" >> $GITHUB_ENV
|
echo "::set-env name=ORACLE_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}"
|
||||||
echo "MONITOR_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}" >> $GITHUB_ENV
|
echo "::set-env name=MONITOR_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}"
|
||||||
echo "UI_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'ui') }}" >> $GITHUB_ENV
|
echo "::set-env name=UI_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'ui') }}"
|
||||||
echo "ALM_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}" >> $GITHUB_ENV
|
echo "::set-env name=ALM_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}"
|
||||||
- if: ${{ matrix.use-cache }}
|
- if: ${{ matrix.use-cache }}
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
id: cache-repo
|
id: cache-repo
|
||||||
with:
|
with:
|
||||||
@@ -175,10 +165,8 @@ jobs:
|
|||||||
**/node_modules
|
**/node_modules
|
||||||
contracts/build
|
contracts/build
|
||||||
key: ${{ needs.initialize.outputs.cache_key }}
|
key: ${{ needs.initialize.outputs.cache_key }}
|
||||||
- name: Login to docker registry
|
- run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
|
||||||
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 }}
|
||||||
- name: yarn run ${{ matrix.task }}
|
|
||||||
run: ${{ !matrix.use-cache || steps.cache-repo.outputs.cache-hit }} && yarn run ${{ matrix.task }}
|
|
||||||
deployment:
|
deployment:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs:
|
needs:
|
||||||
@@ -191,10 +179,8 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Evaluate e2e molecule runner tag
|
- run: echo "::set-env name=MOLECULE_RUNNER_TAG::${{ hashFiles('./deployment-e2e/Dockerfile') }}"
|
||||||
run: echo "MOLECULE_RUNNER_TAG=${{ hashFiles('./deployment-e2e/Dockerfile') }}" >> $GITHUB_ENV
|
- run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
|
||||||
- name: Login to docker registry
|
|
||||||
run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
|
|
||||||
- run: deployment-e2e/molecule.sh ${{ matrix.task }}
|
- run: deployment-e2e/molecule.sh ${{ matrix.task }}
|
||||||
ultimate:
|
ultimate:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -219,15 +205,14 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Evaluate e2e docker images tags
|
- run: |
|
||||||
run: |
|
|
||||||
git submodule status > submodule.status
|
git submodule status > submodule.status
|
||||||
echo "E2E_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e') }}" >> $GITHUB_ENV
|
echo "::set-env name=E2E_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e') }}"
|
||||||
echo "ORACLE_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}" >> $GITHUB_ENV
|
echo "::set-env name=ORACLE_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}"
|
||||||
echo "MONITOR_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}" >> $GITHUB_ENV
|
echo "::set-env name=MONITOR_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}"
|
||||||
echo "UI_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'ui') }}" >> $GITHUB_ENV
|
echo "::set-env name=UI_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'ui') }}"
|
||||||
echo "ALM_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}" >> $GITHUB_ENV
|
echo "::set-env name=ALM_TAG::${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}"
|
||||||
echo "MOLECULE_RUNNER_TAG=${{ hashFiles('./deployment-e2e/Dockerfile') }}" >> $GITHUB_ENV
|
echo "::set-env name=MOLECULE_RUNNER_TAG::${{ hashFiles('./deployment-e2e/Dockerfile') }}"
|
||||||
- uses: actions/cache@v2
|
- uses: actions/cache@v2
|
||||||
id: cache-repo
|
id: cache-repo
|
||||||
with:
|
with:
|
||||||
@@ -235,19 +220,12 @@ jobs:
|
|||||||
**/node_modules
|
**/node_modules
|
||||||
contracts/build
|
contracts/build
|
||||||
key: ${{ needs.initialize.outputs.cache_key }}
|
key: ${{ needs.initialize.outputs.cache_key }}
|
||||||
- name: Login to docker registry
|
- run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
|
||||||
run: docker login ${DOCKER_REGISTRY} -u ${{ github.actor }} -p ${{ github.token }}
|
- run: ${{ steps.cache-repo.outputs.cache-hit }} && e2e-commons/up.sh deploy blocks
|
||||||
- name: Deploy contracts
|
- run: docker-compose -f ./e2e-commons/docker-compose.yml pull oracle
|
||||||
run: ${{ steps.cache-repo.outputs.cache-hit }} && e2e-commons/up.sh deploy blocks
|
- run: deployment-e2e/molecule.sh ultimate-${{ matrix.task }}
|
||||||
- name: Pull e2e oracle image
|
- run: sudo chown -R $USER:docker /var/run/docker.sock
|
||||||
run: docker-compose -f ./e2e-commons/docker-compose.yml pull oracle
|
- if: ${{ matrix.ui-e2e-grep }}
|
||||||
- name: Deploy oracle and ui
|
|
||||||
run: deployment-e2e/molecule.sh ultimate-${{ matrix.task }}
|
|
||||||
- name: Reset docker socket permissions
|
|
||||||
run: sudo chown -R $USER:docker /var/run/docker.sock
|
|
||||||
- name: Run ui e2e tests
|
|
||||||
if: ${{ matrix.ui-e2e-grep }}
|
|
||||||
run: cd ui-e2e && xvfb-run yarn mocha -g "${{ matrix.ui-e2e-grep }}" -b ./test.js
|
run: cd ui-e2e && xvfb-run yarn mocha -g "${{ matrix.ui-e2e-grep }}" -b ./test.js
|
||||||
- name: Run oracle e2e tests
|
- if: ${{ !matrix.ui-e2e-grep }}
|
||||||
if: ${{ !matrix.ui-e2e-grep }}
|
|
||||||
run: docker-compose -f ./e2e-commons/docker-compose.yml run e2e yarn workspace oracle-e2e run ${{ matrix.task }}
|
run: docker-compose -f ./e2e-commons/docker-compose.yml run e2e yarn workspace oracle-e2e run ${{ matrix.task }}
|
||||||
|
|||||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -10,8 +10,11 @@ dist
|
|||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.env*
|
.env
|
||||||
!.env.example
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
.idea
|
.idea
|
||||||
.nyc_output
|
.nyc_output
|
||||||
logs/
|
logs/
|
||||||
@@ -46,6 +49,5 @@ __pycache__
|
|||||||
|
|
||||||
#monitor
|
#monitor
|
||||||
monitor/responses/*
|
monitor/responses/*
|
||||||
monitor/cache/*
|
monitor/configs/*.env
|
||||||
!monitor/cache/.gitkeep
|
|
||||||
!monitor/.gitkeep
|
!monitor/.gitkeep
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST | Filename with a list of addresses, separ
|
|||||||
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_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_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`
|
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`
|
||||||
ORACLE_RPC_REQUEST_TIMEOUT | Timeout in milliseconds for a single RPC request. Default value is `ORACLE_*_RPC_POLLING_INTERVAL * 2`. | integer
|
|
||||||
|
|
||||||
|
|
||||||
## UI configuration
|
## UI configuration
|
||||||
@@ -78,7 +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 | `true` / `false`
|
MONITOR_CACHE_EVENTS | If set to true, monitor will cache obtained events for other workers runs
|
||||||
MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST | File with a list of addresses, separated by newlines. If set, determines the privileged set of accounts whose requests should be automatically processed by the CollectedSignatures watcher. | string
|
|
||||||
MONITOR_HOME_TO_FOREIGN_BLOCK_LIST | File with a list of addresses, separated by newlines. If set, determines the set of accounts whose requests should be marked as unclaimed. Has a lower priority than the `MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST`. | string
|
|
||||||
MONITOR_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`
|
|
||||||
|
|||||||
Binary file not shown.
@@ -51,6 +51,9 @@ export const isBridgeContract = async (contract: Contract, allowedModes?: string
|
|||||||
}
|
}
|
||||||
return allowedModes.includes(mode)
|
return allowedModes.includes(mode)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
if (e.message.includes("Returned values aren't valid")) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2600,11 +2600,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||||
|
|
||||||
"@types/mocha@^7.0.2":
|
|
||||||
version "7.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-7.0.2.tgz#b17f16cf933597e10d6d78eae3251e692ce8b0ce"
|
|
||||||
integrity sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==
|
|
||||||
|
|
||||||
"@types/node@*", "@types/node@>= 8":
|
"@types/node@*", "@types/node@>= 8":
|
||||||
version "13.11.0"
|
version "13.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.0.tgz#390ea202539c61c8fa6ba4428b57e05bc36dc47b"
|
||||||
@@ -3220,11 +3215,6 @@ are-we-there-yet@~1.1.2:
|
|||||||
delegates "^1.0.0"
|
delegates "^1.0.0"
|
||||||
readable-stream "^2.0.6"
|
readable-stream "^2.0.6"
|
||||||
|
|
||||||
arg@^4.1.0:
|
|
||||||
version "4.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
|
||||||
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
|
||||||
|
|
||||||
argparse@^1.0.7:
|
argparse@^1.0.7:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||||
@@ -3350,11 +3340,6 @@ assert@^1.1.1:
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
util "0.10.3"
|
util "0.10.3"
|
||||||
|
|
||||||
assertion-error@^1.1.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
|
|
||||||
integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
|
|
||||||
|
|
||||||
assign-symbols@^1.0.0:
|
assign-symbols@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
|
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
|
||||||
@@ -3450,13 +3435,6 @@ axios@^0.18.0:
|
|||||||
follow-redirects "1.5.10"
|
follow-redirects "1.5.10"
|
||||||
is-buffer "^2.0.2"
|
is-buffer "^2.0.2"
|
||||||
|
|
||||||
axios@^0.19.0:
|
|
||||||
version "0.19.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
|
|
||||||
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
|
|
||||||
dependencies:
|
|
||||||
follow-redirects "1.5.10"
|
|
||||||
|
|
||||||
axobject-query@^2.0.2:
|
axobject-query@^2.0.2:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799"
|
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.1.2.tgz#2bdffc0371e643e5f03ba99065d5179b9ca79799"
|
||||||
@@ -3821,11 +3799,6 @@ browser-resolve@^1.11.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
resolve "1.1.7"
|
resolve "1.1.7"
|
||||||
|
|
||||||
browser-stdout@1.3.1:
|
|
||||||
version "1.3.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
|
|
||||||
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
|
|
||||||
|
|
||||||
browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6:
|
browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.0.6:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
|
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48"
|
||||||
@@ -4215,18 +4188,6 @@ caseless@~0.12.0:
|
|||||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||||
|
|
||||||
chai@^4.2.0:
|
|
||||||
version "4.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5"
|
|
||||||
integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==
|
|
||||||
dependencies:
|
|
||||||
assertion-error "^1.1.0"
|
|
||||||
check-error "^1.0.2"
|
|
||||||
deep-eql "^3.0.1"
|
|
||||||
get-func-name "^2.0.0"
|
|
||||||
pathval "^1.1.0"
|
|
||||||
type-detect "^4.0.5"
|
|
||||||
|
|
||||||
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2:
|
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||||
@@ -4252,11 +4213,6 @@ chardet@^0.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
||||||
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
||||||
|
|
||||||
check-error@^1.0.2:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
|
||||||
integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=
|
|
||||||
|
|
||||||
check-types@^8.0.3:
|
check-types@^8.0.3:
|
||||||
version "8.0.3"
|
version "8.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552"
|
resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552"
|
||||||
@@ -4490,11 +4446,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
|
|||||||
dependencies:
|
dependencies:
|
||||||
delayed-stream "~1.0.0"
|
delayed-stream "~1.0.0"
|
||||||
|
|
||||||
commander@2.15.1:
|
|
||||||
version "2.15.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
|
|
||||||
integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
|
|
||||||
|
|
||||||
commander@2.17.x:
|
commander@2.17.x:
|
||||||
version "2.17.1"
|
version "2.17.1"
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
|
||||||
@@ -5290,13 +5241,6 @@ dedent@^0.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
|
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
|
||||||
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
|
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
|
||||||
|
|
||||||
deep-eql@^3.0.1:
|
|
||||||
version "3.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
|
|
||||||
integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==
|
|
||||||
dependencies:
|
|
||||||
type-detect "^4.0.0"
|
|
||||||
|
|
||||||
deep-equal@^1.0.1:
|
deep-equal@^1.0.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
|
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
|
||||||
@@ -5469,16 +5413,6 @@ diff-sequences@^24.9.0:
|
|||||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
|
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5"
|
||||||
integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==
|
integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==
|
||||||
|
|
||||||
diff@3.5.0:
|
|
||||||
version "3.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
|
||||||
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
|
|
||||||
|
|
||||||
diff@^4.0.1:
|
|
||||||
version "4.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
|
||||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
|
||||||
|
|
||||||
diffie-hellman@^5.0.0:
|
diffie-hellman@^5.0.0:
|
||||||
version "5.0.3"
|
version "5.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
|
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
|
||||||
@@ -7159,11 +7093,6 @@ get-caller-file@^2.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||||
|
|
||||||
get-func-name@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
|
|
||||||
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
|
|
||||||
|
|
||||||
get-own-enumerable-property-symbols@^3.0.0:
|
get-own-enumerable-property-symbols@^3.0.0:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
|
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
|
||||||
@@ -7298,18 +7227,6 @@ glob-to-regexp@^0.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
|
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
|
||||||
integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
|
integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
|
||||||
|
|
||||||
glob@7.1.2:
|
|
||||||
version "7.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
|
||||||
integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==
|
|
||||||
dependencies:
|
|
||||||
fs.realpath "^1.0.0"
|
|
||||||
inflight "^1.0.4"
|
|
||||||
inherits "2"
|
|
||||||
minimatch "^3.0.4"
|
|
||||||
once "^1.3.0"
|
|
||||||
path-is-absolute "^1.0.0"
|
|
||||||
|
|
||||||
glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
|
glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
|
||||||
version "7.1.6"
|
version "7.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||||
@@ -7443,11 +7360,6 @@ graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.
|
|||||||
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:
|
|
||||||
version "1.10.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
|
|
||||||
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
|
|
||||||
|
|
||||||
growly@^1.3.0:
|
growly@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
|
||||||
@@ -7606,11 +7518,6 @@ hdkey@^1.1.1:
|
|||||||
safe-buffer "^5.1.1"
|
safe-buffer "^5.1.1"
|
||||||
secp256k1 "^3.0.1"
|
secp256k1 "^3.0.1"
|
||||||
|
|
||||||
he@1.1.1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
|
||||||
integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
|
|
||||||
|
|
||||||
he@1.2.x:
|
he@1.2.x:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||||
@@ -9685,11 +9592,6 @@ make-dir@^2.0.0, make-dir@^2.1.0:
|
|||||||
pify "^4.0.1"
|
pify "^4.0.1"
|
||||||
semver "^5.6.0"
|
semver "^5.6.0"
|
||||||
|
|
||||||
make-error@^1.1.1:
|
|
||||||
version "1.3.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
|
||||||
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
|
||||||
|
|
||||||
make-fetch-happen@^5.0.0:
|
make-fetch-happen@^5.0.0:
|
||||||
version "5.0.2"
|
version "5.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd"
|
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.2.tgz#aa8387104f2687edca01c8687ee45013d02d19bd"
|
||||||
@@ -10041,11 +9943,6 @@ minimist-options@^3.0.1:
|
|||||||
arrify "^1.0.1"
|
arrify "^1.0.1"
|
||||||
is-plain-obj "^1.1.0"
|
is-plain-obj "^1.1.0"
|
||||||
|
|
||||||
minimist@0.0.8:
|
|
||||||
version "0.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
|
||||||
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
|
|
||||||
|
|
||||||
minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
|
||||||
version "1.2.5"
|
version "1.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||||
@@ -10110,13 +10007,6 @@ mkdirp@*:
|
|||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||||
|
|
||||||
mkdirp@0.5.1:
|
|
||||||
version "0.5.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
|
||||||
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
|
|
||||||
dependencies:
|
|
||||||
minimist "0.0.8"
|
|
||||||
|
|
||||||
mkdirp@^0.5.0, mkdirp@^0.5.1:
|
mkdirp@^0.5.0, mkdirp@^0.5.1:
|
||||||
version "0.5.5"
|
version "0.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||||
@@ -10131,23 +10021,6 @@ mkdirp@~0.5.0, mkdirp@~0.5.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
minimist "^1.2.5"
|
minimist "^1.2.5"
|
||||||
|
|
||||||
mocha@^5.2.0:
|
|
||||||
version "5.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6"
|
|
||||||
integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==
|
|
||||||
dependencies:
|
|
||||||
browser-stdout "1.3.1"
|
|
||||||
commander "2.15.1"
|
|
||||||
debug "3.1.0"
|
|
||||||
diff "3.5.0"
|
|
||||||
escape-string-regexp "1.0.5"
|
|
||||||
glob "7.1.2"
|
|
||||||
growl "1.10.5"
|
|
||||||
he "1.1.1"
|
|
||||||
minimatch "3.0.4"
|
|
||||||
mkdirp "0.5.1"
|
|
||||||
supports-color "5.4.0"
|
|
||||||
|
|
||||||
mock-fs@^4.1.0:
|
mock-fs@^4.1.0:
|
||||||
version "4.11.0"
|
version "4.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.11.0.tgz#0828107e4b843a6ba855ecebfe3c6e073b69db92"
|
resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.11.0.tgz#0828107e4b843a6ba855ecebfe3c6e073b69db92"
|
||||||
@@ -11094,11 +10967,6 @@ path-type@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||||
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
|
||||||
|
|
||||||
pathval@^1.1.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0"
|
|
||||||
integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA=
|
|
||||||
|
|
||||||
pbkdf2@^3.0.3:
|
pbkdf2@^3.0.3:
|
||||||
version "3.0.17"
|
version "3.0.17"
|
||||||
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
|
resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6"
|
||||||
@@ -13403,14 +13271,6 @@ source-map-support@0.5.6:
|
|||||||
buffer-from "^1.0.0"
|
buffer-from "^1.0.0"
|
||||||
source-map "^0.6.0"
|
source-map "^0.6.0"
|
||||||
|
|
||||||
source-map-support@^0.5.17:
|
|
||||||
version "0.5.19"
|
|
||||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
|
|
||||||
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
|
|
||||||
dependencies:
|
|
||||||
buffer-from "^1.0.0"
|
|
||||||
source-map "^0.6.0"
|
|
||||||
|
|
||||||
source-map-support@^0.5.6, source-map-support@~0.5.10, source-map-support@~0.5.12:
|
source-map-support@^0.5.6, source-map-support@~0.5.10, source-map-support@~0.5.12:
|
||||||
version "0.5.16"
|
version "0.5.16"
|
||||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
|
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
|
||||||
@@ -13852,13 +13712,6 @@ stylis@^3.5.0:
|
|||||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
|
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
|
||||||
integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
|
integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
|
||||||
|
|
||||||
supports-color@5.4.0:
|
|
||||||
version "5.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
|
|
||||||
integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==
|
|
||||||
dependencies:
|
|
||||||
has-flag "^3.0.0"
|
|
||||||
|
|
||||||
supports-color@^2.0.0:
|
supports-color@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||||
@@ -14223,17 +14076,6 @@ tryer@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
|
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
|
||||||
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
|
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
|
||||||
|
|
||||||
ts-node@^8.8.2:
|
|
||||||
version "8.10.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d"
|
|
||||||
integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==
|
|
||||||
dependencies:
|
|
||||||
arg "^4.1.0"
|
|
||||||
diff "^4.0.1"
|
|
||||||
make-error "^1.1.1"
|
|
||||||
source-map-support "^0.5.17"
|
|
||||||
yn "3.1.1"
|
|
||||||
|
|
||||||
ts-pnp@1.1.2:
|
ts-pnp@1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.2.tgz#be8e4bfce5d00f0f58e0666a82260c34a57af552"
|
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.2.tgz#be8e4bfce5d00f0f58e0666a82260c34a57af552"
|
||||||
@@ -14280,11 +14122,6 @@ type-check@~0.3.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
prelude-ls "~1.1.2"
|
prelude-ls "~1.1.2"
|
||||||
|
|
||||||
type-detect@^4.0.0, type-detect@^4.0.5:
|
|
||||||
version "4.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
|
|
||||||
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
|
|
||||||
|
|
||||||
type-fest@^0.3.0:
|
type-fest@^0.3.0:
|
||||||
version "0.3.1"
|
version "0.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1"
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1"
|
||||||
@@ -14330,11 +14167,6 @@ typescript@3.5.3:
|
|||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977"
|
||||||
integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==
|
integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==
|
||||||
|
|
||||||
typescript@^3.5.2:
|
|
||||||
version "3.9.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa"
|
|
||||||
integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==
|
|
||||||
|
|
||||||
uglify-js@3.4.x:
|
uglify-js@3.4.x:
|
||||||
version "3.4.10"
|
version "3.4.10"
|
||||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
|
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f"
|
||||||
@@ -15649,8 +15481,3 @@ yauzl@^2.4.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
buffer-crc32 "~0.2.3"
|
buffer-crc32 "~0.2.3"
|
||||||
fd-slicer "~1.1.0"
|
fd-slicer "~1.1.0"
|
||||||
|
|
||||||
yn@3.1.1:
|
|
||||||
version "3.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
|
||||||
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
|
||||||
|
|||||||
@@ -5,8 +5,7 @@
|
|||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-unused-expressions": "off",
|
"no-unused-expressions": "off",
|
||||||
"import/no-extraneous-dependencies": "off",
|
"import/no-extraneous-dependencies": "off"
|
||||||
"no-bitwise": "off"
|
|
||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"mocha": true
|
"mocha": true
|
||||||
|
|||||||
@@ -6,30 +6,17 @@ function addTxHashToData({ encodedData, transactionHash }) {
|
|||||||
return encodedData.slice(0, 2) + strip0x(transactionHash) + encodedData.slice(2)
|
return encodedData.slice(0, 2) + strip0x(transactionHash) + encodedData.slice(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes the datatype byte from the AMB message.
|
|
||||||
* First (the most significant bit) denotes if the message should be forwarded to the manual lane.
|
|
||||||
* @param dataType: number datatype of the received AMB message.
|
|
||||||
* @return {{manualLane: boolean}}
|
|
||||||
*/
|
|
||||||
const decodeAMBDataType = dataType => ({
|
|
||||||
manualLane: (dataType & 128) === 128
|
|
||||||
})
|
|
||||||
|
|
||||||
function parseAMBMessage(message) {
|
function parseAMBMessage(message) {
|
||||||
message = strip0x(message)
|
message = strip0x(message)
|
||||||
|
|
||||||
const messageId = `0x${message.slice(0, 64)}`
|
const messageId = `0x${message.slice(0, 64)}`
|
||||||
const sender = `0x${message.slice(64, 104)}`
|
const sender = `0x${message.slice(64, 104)}`
|
||||||
const executor = `0x${message.slice(104, 144)}`
|
const executor = `0x${message.slice(104, 144)}`
|
||||||
const dataType = parseInt(message.slice(156, 158), 16)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sender,
|
sender,
|
||||||
executor,
|
executor,
|
||||||
messageId,
|
messageId
|
||||||
dataType,
|
|
||||||
decodedDataType: decodeAMBDataType(dataType)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -164,18 +164,18 @@ const getPastEvents = async (
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message.includes('query returned more than') && toBlock !== 'latest') {
|
if (e.message.includes('query returned more than') && toBlock !== 'latest') {
|
||||||
const middle = toBN(fromBlock)
|
const middle = toBN(fromBlock)
|
||||||
.add(toBN(toBlock))
|
.add(toBlock)
|
||||||
.divRound(toBN(2))
|
.divRound(toBN(2))
|
||||||
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,20 +65,6 @@ 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'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -168,20 +154,6 @@ 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'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Submodule contracts updated: 835742dfd8...dd46135248
@@ -1,2 +1 @@
|
|||||||
0xc9e38bfdB9c635F0796ad83CC8705dc379F41c04
|
0xc9e38bfdB9c635F0796ad83CC8705dc379F41c04
|
||||||
0x612E8bd50A7b1F009F43f2b8679E9B8eD91eb5CE
|
|
||||||
@@ -23,4 +23,3 @@ 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
|
|
||||||
|
|||||||
@@ -63,7 +63,6 @@
|
|||||||
"foreign": "0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0",
|
"foreign": "0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0",
|
||||||
"homeBox": "0x6C4EaAb8756d53Bf599FFe2347FAFF1123D6C8A1",
|
"homeBox": "0x6C4EaAb8756d53Bf599FFe2347FAFF1123D6C8A1",
|
||||||
"foreignBox": "0x6C4EaAb8756d53Bf599FFe2347FAFF1123D6C8A1",
|
"foreignBox": "0x6C4EaAb8756d53Bf599FFe2347FAFF1123D6C8A1",
|
||||||
"blockedHomeBox": "0x612E8bd50A7b1F009F43f2b8679E9B8eD91eb5CE",
|
|
||||||
"monitor": "http://monitor-amb:3013/bridge"
|
"monitor": "http://monitor-amb:3013/bridge"
|
||||||
},
|
},
|
||||||
"ambStakeErcToErc": {
|
"ambStakeErcToErc": {
|
||||||
|
|||||||
@@ -61,9 +61,6 @@ services:
|
|||||||
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
|
||||||
ui:
|
ui:
|
||||||
|
|||||||
@@ -53,8 +53,3 @@ node deploy.js
|
|||||||
cd - > /dev/null
|
cd - > /dev/null
|
||||||
node setupStakeTokens.js
|
node setupStakeTokens.js
|
||||||
cd - > /dev/null
|
cd - > /dev/null
|
||||||
|
|
||||||
echo -e "\n\n############ Deploying one more test contract for amb ############\n"
|
|
||||||
cd "$DEPLOY_PATH"
|
|
||||||
node src/utils/deployTestBox.js
|
|
||||||
cd - > /dev/null
|
|
||||||
|
|||||||
@@ -17,29 +17,21 @@ docker-compose up -d parity1 parity2 e2e
|
|||||||
startValidator () {
|
startValidator () {
|
||||||
docker-compose $1 run -d --name $4 redis
|
docker-compose $1 run -d --name $4 redis
|
||||||
docker-compose $1 run -d --name $5 rabbit
|
docker-compose $1 run -d --name $5 rabbit
|
||||||
if [[ -z "$MODE" || "$MODE" == native-to-erc ]]; then
|
docker-compose $1 run $2 $3 -d oracle yarn watcher:signature-request
|
||||||
docker-compose $1 run $2 $3 -d oracle yarn watcher:signature-request
|
docker-compose $1 run $2 $3 -d oracle yarn watcher:collected-signatures
|
||||||
docker-compose $1 run $2 $3 -d oracle yarn watcher:collected-signatures
|
docker-compose $1 run $2 $3 -d oracle yarn watcher:affirmation-request
|
||||||
docker-compose $1 run $2 $3 -d oracle yarn watcher:affirmation-request
|
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:signature-request
|
||||||
fi
|
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:collected-signatures
|
||||||
if [[ -z "$MODE" || "$MODE" == erc-to-erc ]]; then
|
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:affirmation-request
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:signature-request
|
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:transfer
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:collected-signatures
|
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn watcher:signature-request
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:affirmation-request
|
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn watcher:collected-signatures
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:transfer
|
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn watcher:affirmation-request
|
||||||
fi
|
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn watcher:transfer
|
||||||
if [[ -z "$MODE" || "$MODE" == erc-to-native ]]; then
|
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn worker:convert-to-chai
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn watcher:signature-request
|
docker-compose $1 run $2 $3 -d oracle-amb yarn watcher:signature-request
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn watcher:collected-signatures
|
docker-compose $1 run $2 $3 -d oracle-amb yarn watcher:collected-signatures
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn watcher:affirmation-request
|
docker-compose $1 run $2 $3 -d oracle-amb yarn watcher:affirmation-request
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn watcher:transfer
|
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn worker:convert-to-chai
|
|
||||||
fi
|
|
||||||
if [[ -z "$MODE" || "$MODE" == amb ]]; then
|
|
||||||
docker-compose $1 run $2 $3 -d oracle-amb yarn watcher:signature-request
|
|
||||||
docker-compose $1 run $2 $3 -d oracle-amb yarn watcher:collected-signatures
|
|
||||||
docker-compose $1 run $2 $3 -d oracle-amb yarn watcher:affirmation-request
|
|
||||||
fi
|
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn sender:home
|
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn sender:home
|
||||||
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn sender:foreign
|
docker-compose $1 run $2 $3 -d oracle-erc20-native yarn sender:foreign
|
||||||
}
|
}
|
||||||
@@ -56,7 +48,25 @@ startAMBValidator () {
|
|||||||
|
|
||||||
while [ "$1" != "" ]; do
|
while [ "$1" != "" ]; do
|
||||||
if [ "$1" == "oracle" ]; then
|
if [ "$1" == "oracle" ]; then
|
||||||
startValidator "" "" "" "redis" "rabbit"
|
docker-compose up -d redis rabbit
|
||||||
|
|
||||||
|
docker-compose run -d oracle yarn watcher:signature-request
|
||||||
|
docker-compose run -d oracle yarn watcher:collected-signatures
|
||||||
|
docker-compose run -d oracle yarn watcher:affirmation-request
|
||||||
|
docker-compose run -d oracle-erc20 yarn watcher:signature-request
|
||||||
|
docker-compose run -d oracle-erc20 yarn watcher:collected-signatures
|
||||||
|
docker-compose run -d oracle-erc20 yarn watcher:affirmation-request
|
||||||
|
docker-compose run -d oracle-erc20 yarn watcher:transfer
|
||||||
|
docker-compose run -d oracle-erc20-native yarn watcher:signature-request
|
||||||
|
docker-compose run -d oracle-erc20-native yarn watcher:collected-signatures
|
||||||
|
docker-compose run -d oracle-erc20-native yarn watcher:affirmation-request
|
||||||
|
docker-compose run -d oracle-erc20-native yarn watcher:transfer
|
||||||
|
docker-compose run -d oracle-erc20-native yarn worker:convert-to-chai
|
||||||
|
docker-compose run -d oracle-amb yarn watcher:signature-request
|
||||||
|
docker-compose run -d oracle-amb yarn watcher:collected-signatures
|
||||||
|
docker-compose run -d oracle-amb yarn watcher:affirmation-request
|
||||||
|
docker-compose run -d oracle yarn sender:home
|
||||||
|
docker-compose run -d oracle yarn sender:foreign
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$1" == "oracle-validator-2" ]; then
|
if [ "$1" == "oracle-validator-2" ]; then
|
||||||
@@ -100,23 +110,7 @@ while [ "$1" != "" ]; do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$1" == "monitor" ]; then
|
if [ "$1" == "monitor" ]; then
|
||||||
case "$MODE" in
|
docker-compose up -d monitor monitor-erc20 monitor-erc20-native monitor-amb
|
||||||
amb)
|
|
||||||
docker-compose up -d monitor-amb
|
|
||||||
;;
|
|
||||||
native-to-erc)
|
|
||||||
docker-compose up -d monitor
|
|
||||||
;;
|
|
||||||
erc-to-erc)
|
|
||||||
docker-compose up -d monitor-erc20
|
|
||||||
;;
|
|
||||||
erc-to-native)
|
|
||||||
docker-compose up -d monitor-erc20-native
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
docker-compose up -d monitor monitor-erc20 monitor-erc20-native monitor-amb
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$1" == "alm-e2e" ]; then
|
if [ "$1" == "alm-e2e" ]; then
|
||||||
|
|||||||
@@ -1,15 +1,7 @@
|
|||||||
while true; do
|
while true; do
|
||||||
docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor yarn check-all
|
sleep 5
|
||||||
pid1=$!
|
docker-compose -f ../e2e-commons/docker-compose.yml exec -d monitor yarn check-all
|
||||||
docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20 yarn check-all
|
docker-compose -f ../e2e-commons/docker-compose.yml exec -d monitor-erc20 yarn check-all
|
||||||
pid2=$!
|
docker-compose -f ../e2e-commons/docker-compose.yml exec -d monitor-erc20-native yarn check-all
|
||||||
docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20-native yarn check-all
|
docker-compose -f ../e2e-commons/docker-compose.yml exec -d monitor-amb yarn check-all
|
||||||
pid3=$!
|
|
||||||
docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-amb yarn check-all
|
|
||||||
pid4=$!
|
|
||||||
|
|
||||||
wait $pid1
|
|
||||||
wait $pid2
|
|
||||||
wait $pid3
|
|
||||||
wait $pid4
|
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -1,28 +1,12 @@
|
|||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
|
|
||||||
mode="$1"
|
../e2e-commons/up.sh deploy blocks monitor
|
||||||
case "$mode" in
|
|
||||||
amb)
|
|
||||||
script=./test/amb.js
|
|
||||||
;;
|
|
||||||
native-to-erc)
|
|
||||||
script=./test/nativeToErc.js
|
|
||||||
;;
|
|
||||||
erc-to-erc)
|
|
||||||
script=./test/ercToErc.js
|
|
||||||
;;
|
|
||||||
erc-to-native)
|
|
||||||
script=./test/ercToNative.js
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
MODE="$mode" ../e2e-commons/up.sh deploy blocks monitor
|
./wait-for-monitor.sh
|
||||||
|
|
||||||
MODE="$mode" ./wait-for-monitor.sh
|
|
||||||
nohup ./periodically-check-all.sh < /dev/null > /dev/null 2>&1 &
|
nohup ./periodically-check-all.sh < /dev/null > /dev/null 2>&1 &
|
||||||
checkPID=$!
|
checkPID=$!
|
||||||
|
|
||||||
docker-compose -f ../e2e-commons/docker-compose.yml run e2e yarn workspace monitor-e2e run start $script
|
docker-compose -f ../e2e-commons/docker-compose.yml run e2e yarn workspace monitor-e2e run start
|
||||||
rc=$?
|
rc=$?
|
||||||
|
|
||||||
../e2e-commons/down.sh
|
../e2e-commons/down.sh
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ describe('AMB', () => {
|
|||||||
|
|
||||||
describe('general', async () => {
|
describe('general', async () => {
|
||||||
it('should contain fromHomeToForeignDiff', () => assert(data.fromHomeToForeignDiff === 0))
|
it('should contain fromHomeToForeignDiff', () => assert(data.fromHomeToForeignDiff === 0))
|
||||||
it('should contain fromHomeToForeignPBUDiff', () => assert(data.fromHomeToForeignPBUDiff === 0))
|
|
||||||
it('should contain fromForeignToHomeDiff', () => assert(data.fromForeignToHomeDiff === 0))
|
it('should contain fromForeignToHomeDiff', () => assert(data.fromForeignToHomeDiff === 0))
|
||||||
it('should contain lastChecked', () => assert(data.lastChecked >= 0))
|
it('should contain lastChecked', () => assert(data.lastChecked >= 0))
|
||||||
it('should contain timeDiff', () => assert(data.timeDiff >= 0))
|
it('should contain timeDiff', () => assert(data.timeDiff >= 0))
|
||||||
@@ -115,16 +114,7 @@ describe('AMB', () => {
|
|||||||
|
|
||||||
await waitUntil(async () => {
|
await waitUntil(async () => {
|
||||||
;({ data } = await axios.get(`${baseUrl}`))
|
;({ data } = await axios.get(`${baseUrl}`))
|
||||||
return data.fromHomeToForeignDiff === 1 && data.fromHomeToForeignPBUDiff === 0
|
return data.fromHomeToForeignDiff !== 0
|
||||||
})
|
|
||||||
})
|
|
||||||
it('should change fromHomeToForeignPBUDiff', async () => {
|
|
||||||
// send message
|
|
||||||
await sendAMBMessage(homeRPC.URL, user, amb.homeBox, amb.home, amb.foreignBox, true)
|
|
||||||
|
|
||||||
await waitUntil(async () => {
|
|
||||||
;({ data } = await axios.get(`${baseUrl}`))
|
|
||||||
return data.fromHomeToForeignDiff === 1 && data.fromHomeToForeignPBUDiff === 1
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
it('should change validatorsMatch', async () => {
|
it('should change validatorsMatch', async () => {
|
||||||
|
|||||||
@@ -54,16 +54,16 @@ describe('ERC TO NATIVE with changing state of contracts', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should consider chai token balance', async function() {
|
it('should consider chai token balance', async function() {
|
||||||
this.timeout(120000)
|
this.timeout(60000)
|
||||||
await initializeChaiToken(foreignRPC.URL, ercToNativeBridge.foreign)
|
await initializeChaiToken(foreignRPC.URL, ercToNativeBridge.foreign)
|
||||||
await sendTokens(foreignRPC.URL, user, ercToNativeBridge.foreignToken, ercToNativeBridge.foreign)
|
await sendTokens(foreignRPC.URL, user, ercToNativeBridge.foreignToken, ercToNativeBridge.foreign)
|
||||||
|
|
||||||
await waitUntil(async () => {
|
await waitUntil(async () => {
|
||||||
;({ data } = await axios.get(`${baseUrl}`))
|
;({ data } = await axios.get(`${baseUrl}`))
|
||||||
|
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
|
||||||
if (!data.foreign) {
|
if (!data.foreign) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
|
|
||||||
return (
|
return (
|
||||||
data.balanceDiff === 0.02 &&
|
data.balanceDiff === 0.02 &&
|
||||||
erc20Balance === '0.02' &&
|
erc20Balance === '0.02' &&
|
||||||
@@ -77,10 +77,10 @@ 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
|
||||||
if (!data.foreign) {
|
if (!data.foreign) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
|
|
||||||
return (
|
return (
|
||||||
data.balanceDiff === 0.02 &&
|
data.balanceDiff === 0.02 &&
|
||||||
erc20Balance === '0.01' &&
|
erc20Balance === '0.01' &&
|
||||||
@@ -94,10 +94,10 @@ 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
|
||||||
if (!data.foreign) {
|
if (!data.foreign) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
|
|
||||||
return (
|
return (
|
||||||
data.balanceDiff === 0.02 &&
|
data.balanceDiff === 0.02 &&
|
||||||
erc20Balance === '0.005' &&
|
erc20Balance === '0.005' &&
|
||||||
|
|||||||
@@ -44,16 +44,12 @@ const sendTokens = async (rpcUrl, account, tokenAddress, recipientAddress) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendAMBMessage = async (rpcUrl, account, boxAddress, bridgeAddress, boxOtherSideAddress, manualLane = false) => {
|
const sendAMBMessage = async (rpcUrl, account, boxAddress, bridgeAddress, boxOtherSideAddress) => {
|
||||||
const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl))
|
const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl))
|
||||||
web3.eth.accounts.wallet.add(account.privateKey)
|
web3.eth.accounts.wallet.add(account.privateKey)
|
||||||
const homeBox = new web3.eth.Contract(BOX_ABI, boxAddress)
|
const homeBox = new web3.eth.Contract(BOX_ABI, boxAddress)
|
||||||
|
|
||||||
await homeBox.methods[manualLane ? 'setValueOnOtherNetworkUsingManualLane' : 'setValueOnOtherNetwork'](
|
await homeBox.methods.setValueOnOtherNetwork(3, bridgeAddress, boxOtherSideAddress).send({
|
||||||
3,
|
|
||||||
bridgeAddress,
|
|
||||||
boxOtherSideAddress
|
|
||||||
).send({
|
|
||||||
from: account.address,
|
from: account.address,
|
||||||
gas: '400000'
|
gas: '400000'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,18 +6,10 @@ 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"
|
||||||
if [[ -z "$MODE" || "$MODE" == native-to-erc ]]; then
|
(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 -T monitor /bin/bash -c "$command") || rc=1
|
(docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20 /bin/bash -c "$command") || rc=1
|
||||||
fi
|
(docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20-native /bin/bash -c "$command") || rc=1
|
||||||
if [[ -z "$MODE" || "$MODE" == erc-to-erc ]]; then
|
(docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-amb /bin/bash -c "$command") || rc=1
|
||||||
(docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20 /bin/bash -c "$command") || rc=1
|
|
||||||
fi
|
|
||||||
if [[ -z "$MODE" || "$MODE" == erc-to-native ]]; then
|
|
||||||
(docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20-native /bin/bash -c "$command") || rc=1
|
|
||||||
fi
|
|
||||||
if [[ -z "$MODE" || "$MODE" == amb ]]; then
|
|
||||||
(docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-amb /bin/bash -c "$command") || rc=1
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
return $rc
|
return $rc
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,3 @@ COMMON_FOREIGN_GAS_PRICE_FACTOR=1
|
|||||||
MONITOR_TX_NUMBER_THRESHOLD=100
|
MONITOR_TX_NUMBER_THRESHOLD=100
|
||||||
MONITOR_PORT=3003
|
MONITOR_PORT=3003
|
||||||
MONITOR_CACHE_EVENTS=true
|
MONITOR_CACHE_EVENTS=true
|
||||||
|
|
||||||
MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST=
|
|
||||||
MONITOR_HOME_TO_FOREIGN_BLOCK_LIST=
|
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
const Web3 = require('web3')
|
||||||
const logger = require('./logger')('alerts')
|
const logger = require('./logger')('alerts')
|
||||||
const eventsInfo = require('./utils/events')
|
const eventsInfo = require('./utils/events')
|
||||||
|
const { getBlockNumber } = require('./utils/contract')
|
||||||
const { processedMsgNotDelivered, eventWithoutReference } = require('./utils/message')
|
const { processedMsgNotDelivered, eventWithoutReference } = require('./utils/message')
|
||||||
const { BRIDGE_MODES } = require('../commons')
|
const { BRIDGE_MODES } = require('../commons')
|
||||||
const { web3Home, web3Foreign, getHomeBlockNumber, getForeignBlockNumber } = require('./utils/web3')
|
|
||||||
|
const { COMMON_HOME_RPC_URL, COMMON_FOREIGN_RPC_URL } = process.env
|
||||||
|
|
||||||
|
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
||||||
|
const web3Home = new Web3(homeProvider)
|
||||||
|
|
||||||
|
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
||||||
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const {
|
const {
|
||||||
@@ -24,8 +33,7 @@ async function main() {
|
|||||||
xAffirmations = foreignToHomeConfirmations.filter(eventWithoutReference(foreignToHomeRequests))
|
xAffirmations = foreignToHomeConfirmations.filter(eventWithoutReference(foreignToHomeRequests))
|
||||||
}
|
}
|
||||||
logger.debug('building misbehavior blocks')
|
logger.debug('building misbehavior blocks')
|
||||||
const homeBlockNumber = await getHomeBlockNumber()
|
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
||||||
const foreignBlockNumber = await getForeignBlockNumber()
|
|
||||||
|
|
||||||
const baseRange = [false, false, false, false, false]
|
const baseRange = [false, false, false, false, false]
|
||||||
const xSignaturesMisbehavior = buildRangesObject(
|
const xSignaturesMisbehavior = buildRangesObject(
|
||||||
@@ -65,21 +73,21 @@ async function main() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the location for the blockNumber in a specific range starting from currentBlockNumber
|
* Finds the location for the blockNumber in a specific range starting from currentBlockNumber
|
||||||
* @param {Number} currentBlockNumber
|
* @param {BN} currentBlockNumber
|
||||||
* @returns {function({blockNumber?: *}): boolean[]}
|
* @returns {function({blockNumber?: *}): boolean[]}
|
||||||
*/
|
*/
|
||||||
const findMisbehaviorRange = currentBlockNumber => ({ blockNumber }) => {
|
const findMisbehaviorRange = currentBlockNumber => ({ blockNumber }) => {
|
||||||
const minus60 = currentBlockNumber - 60
|
const minus60 = currentBlockNumber.sub(Web3.utils.toBN(60))
|
||||||
const minus180 = currentBlockNumber - 180
|
const minus180 = currentBlockNumber.sub(Web3.utils.toBN(180))
|
||||||
const minus720 = currentBlockNumber - 720
|
const minus720 = currentBlockNumber.sub(Web3.utils.toBN(720))
|
||||||
const minus17280 = currentBlockNumber - 17280
|
const minus17280 = currentBlockNumber.sub(Web3.utils.toBN(17280))
|
||||||
|
|
||||||
return [
|
return [
|
||||||
minus60 <= blockNumber,
|
minus60.lte(blockNumber),
|
||||||
minus180 <= blockNumber && minus60 > blockNumber,
|
minus180.lte(blockNumber) && minus60.gt(blockNumber),
|
||||||
minus720 <= blockNumber && minus180 > blockNumber,
|
minus720.lte(blockNumber) && minus180.gt(blockNumber),
|
||||||
minus17280 <= blockNumber && minus720 > blockNumber,
|
minus17280.lte(blockNumber) && minus720.gt(blockNumber),
|
||||||
minus17280 > blockNumber
|
minus17280.gt(blockNumber)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
0
monitor/cache/.gitkeep
vendored
0
monitor/cache/.gitkeep
vendored
@@ -1,21 +1,21 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const BN = require('bignumber.js')
|
const Web3 = require('web3')
|
||||||
const logger = require('./logger')('checkWorker')
|
const logger = require('./logger')('checkWorker')
|
||||||
const { getBridgeMode } = require('../commons')
|
const { getBridgeMode } = require('../commons')
|
||||||
const getBalances = require('./getBalances')
|
const getBalances = require('./getBalances')
|
||||||
const getShortEventStats = require('./getShortEventStats')
|
const getShortEventStats = require('./getShortEventStats')
|
||||||
const validators = require('./validators')
|
const validators = require('./validators')
|
||||||
const getEventsInfo = require('./utils/events')
|
|
||||||
const { writeFile, createDir } = require('./utils/file')
|
const { writeFile, createDir } = require('./utils/file')
|
||||||
const { saveCache } = require('./utils/web3Cache')
|
|
||||||
const { web3Home } = require('./utils/web3')
|
|
||||||
|
|
||||||
const { COMMON_HOME_BRIDGE_ADDRESS, MONITOR_BRIDGE_NAME } = process.env
|
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_HOME_RPC_URL, MONITOR_BRIDGE_NAME } = process.env
|
||||||
|
|
||||||
const MONITOR_VALIDATOR_HOME_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_HOME_TX_LIMIT) || 0
|
const MONITOR_VALIDATOR_HOME_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_HOME_TX_LIMIT) || 0
|
||||||
const MONITOR_VALIDATOR_FOREIGN_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_FOREIGN_TX_LIMIT) || 0
|
const MONITOR_VALIDATOR_FOREIGN_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_FOREIGN_TX_LIMIT) || 0
|
||||||
const MONITOR_TX_NUMBER_THRESHOLD = Number(process.env.MONITOR_TX_NUMBER_THRESHOLD) || 100
|
const MONITOR_TX_NUMBER_THRESHOLD = Number(process.env.MONITOR_TX_NUMBER_THRESHOLD) || 100
|
||||||
|
|
||||||
|
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
||||||
|
const web3Home = new Web3(homeProvider)
|
||||||
|
|
||||||
const { HOME_ERC_TO_ERC_ABI } = require('../commons')
|
const { HOME_ERC_TO_ERC_ABI } = require('../commons')
|
||||||
|
|
||||||
async function checkWorker() {
|
async function checkWorker() {
|
||||||
@@ -24,22 +24,16 @@ async function checkWorker() {
|
|||||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
const bridgeMode = await getBridgeMode(homeBridge)
|
const bridgeMode = await getBridgeMode(homeBridge)
|
||||||
logger.debug('Bridge mode:', bridgeMode)
|
logger.debug('Bridge mode:', bridgeMode)
|
||||||
logger.debug('calling getEventsInfo()')
|
|
||||||
const eventsInfo = await getEventsInfo(bridgeMode)
|
|
||||||
logger.debug('calling getBalances()')
|
logger.debug('calling getBalances()')
|
||||||
const balances = await getBalances(bridgeMode, eventsInfo)
|
const balances = await getBalances(bridgeMode)
|
||||||
logger.debug('calling getShortEventStats()')
|
logger.debug('calling getShortEventStats()')
|
||||||
const events = await getShortEventStats(bridgeMode, eventsInfo)
|
const events = await getShortEventStats(bridgeMode)
|
||||||
const home = Object.assign({}, balances.home, events.home)
|
const home = Object.assign({}, balances.home, events.home)
|
||||||
const foreign = Object.assign({}, balances.foreign, events.foreign)
|
const foreign = Object.assign({}, balances.foreign, events.foreign)
|
||||||
const status = Object.assign({}, balances, events, { home }, { foreign })
|
const status = Object.assign({}, balances, events, { home }, { foreign })
|
||||||
if (status.balanceDiff && status.unclaimedBalance) {
|
|
||||||
status.balanceDiff = new BN(status.balanceDiff).minus(status.unclaimedBalance).toFixed()
|
|
||||||
}
|
|
||||||
if (!status) throw new Error('status is empty: ' + JSON.stringify(status))
|
if (!status) throw new Error('status is empty: ' + JSON.stringify(status))
|
||||||
status.health = true
|
status.health = true
|
||||||
writeFile(`/responses/${MONITOR_BRIDGE_NAME}/getBalances.json`, status)
|
writeFile(`/responses/${MONITOR_BRIDGE_NAME}/getBalances.json`, status)
|
||||||
saveCache()
|
|
||||||
|
|
||||||
logger.debug('calling validators()')
|
logger.debug('calling validators()')
|
||||||
const vBalances = await validators(bridgeMode)
|
const vBalances = await validators(bridgeMode)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ const logger = require('./logger')('checkWorker2')
|
|||||||
const eventsStats = require('./eventsStats')
|
const eventsStats = require('./eventsStats')
|
||||||
const alerts = require('./alerts')
|
const alerts = require('./alerts')
|
||||||
const { writeFile, createDir } = require('./utils/file')
|
const { writeFile, createDir } = require('./utils/file')
|
||||||
const { saveCache } = require('./utils/web3Cache')
|
|
||||||
|
|
||||||
const { MONITOR_BRIDGE_NAME } = process.env
|
const { MONITOR_BRIDGE_NAME } = process.env
|
||||||
|
|
||||||
@@ -27,7 +26,6 @@ async function checkWorker2() {
|
|||||||
_alerts.ok = !_alerts.executeAffirmations.mostRecentTxHash && !_alerts.executeSignatures.mostRecentTxHash
|
_alerts.ok = !_alerts.executeAffirmations.mostRecentTxHash && !_alerts.executeSignatures.mostRecentTxHash
|
||||||
_alerts.health = true
|
_alerts.health = true
|
||||||
writeFile(`/responses/${MONITOR_BRIDGE_NAME}/alerts.json`, _alerts)
|
writeFile(`/responses/${MONITOR_BRIDGE_NAME}/alerts.json`, _alerts)
|
||||||
saveCache()
|
|
||||||
logger.debug('Done x2')
|
logger.debug('Done x2')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
const Web3 = require('web3')
|
||||||
const logger = require('./logger')('checkWorker3')
|
const logger = require('./logger')('checkWorker3')
|
||||||
const stuckTransfers = require('./stuckTransfers')
|
const stuckTransfers = require('./stuckTransfers')
|
||||||
const { writeFile, createDir } = require('./utils/file')
|
const { writeFile, createDir } = require('./utils/file')
|
||||||
const { web3Home } = require('./utils/web3')
|
|
||||||
|
|
||||||
const { MONITOR_BRIDGE_NAME, COMMON_HOME_BRIDGE_ADDRESS } = process.env
|
const { MONITOR_BRIDGE_NAME, COMMON_HOME_BRIDGE_ADDRESS, COMMON_HOME_RPC_URL } = process.env
|
||||||
const { getBridgeMode, HOME_NATIVE_TO_ERC_ABI, BRIDGE_MODES } = require('../commons')
|
const { getBridgeMode, HOME_NATIVE_TO_ERC_ABI, BRIDGE_MODES } = require('../commons')
|
||||||
|
|
||||||
|
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
||||||
|
const web3Home = new Web3(homeProvider)
|
||||||
|
|
||||||
async function checkWorker3() {
|
async function checkWorker3() {
|
||||||
try {
|
try {
|
||||||
const homeBridge = new web3Home.eth.Contract(HOME_NATIVE_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBridge = new web3Home.eth.Contract(HOME_NATIVE_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ services:
|
|||||||
monitor:
|
monitor:
|
||||||
image: poanetwork/tokenbridge-monitor:latest
|
image: poanetwork/tokenbridge-monitor:latest
|
||||||
ports:
|
ports:
|
||||||
- "${MONITOR_PORT}:${MONITOR_PORT}"
|
- "${MONITOR_PORT}:${MONITOR_PORT}"
|
||||||
env_file: ./.env
|
env_file: ./.env
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
volumes:
|
volumes:
|
||||||
- ./responses:/mono/monitor/responses
|
- ./responses:/mono/monitor/responses
|
||||||
- ./cache:/mono/monitor/cache
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
entrypoint: "yarn start"
|
entrypoint: "yarn start"
|
||||||
|
|||||||
@@ -1,20 +1,8 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const eventsInfo = require('./utils/events')
|
const eventsInfo = require('./utils/events')
|
||||||
const {
|
const { processedMsgNotDelivered, deliveredMsgNotProcessed, eventWithoutReference } = require('./utils/message')
|
||||||
processedMsgNotDelivered,
|
|
||||||
deliveredMsgNotProcessed,
|
|
||||||
eventWithoutReference,
|
|
||||||
unclaimedHomeToForeignRequests
|
|
||||||
} = require('./utils/message')
|
|
||||||
const { getHomeTxSender } = require('./utils/web3Cache')
|
|
||||||
const { BRIDGE_MODES } = require('../commons')
|
const { BRIDGE_MODES } = require('../commons')
|
||||||
|
|
||||||
const {
|
|
||||||
MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST,
|
|
||||||
MONITOR_HOME_TO_FOREIGN_BLOCK_LIST,
|
|
||||||
MONITOR_HOME_TO_FOREIGN_CHECK_SENDER
|
|
||||||
} = process.env
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const {
|
const {
|
||||||
homeToForeignRequests,
|
homeToForeignRequests,
|
||||||
@@ -45,30 +33,17 @@ async function main() {
|
|||||||
lastChecked: Math.floor(Date.now() / 1000)
|
lastChecked: Math.floor(Date.now() / 1000)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let onlyInHomeDeposits = homeToForeignRequests.filter(eventWithoutReference(homeToForeignConfirmations))
|
const onlyInHomeDeposits = homeToForeignRequests.filter(eventWithoutReference(homeToForeignConfirmations))
|
||||||
const onlyInForeignDeposits = homeToForeignConfirmations.filter(eventWithoutReference(homeToForeignRequests))
|
const onlyInForeignDeposits = homeToForeignConfirmations.filter(eventWithoutReference(homeToForeignRequests))
|
||||||
|
|
||||||
const onlyInHomeWithdrawals = foreignToHomeConfirmations.filter(eventWithoutReference(foreignToHomeRequests))
|
const onlyInHomeWithdrawals = foreignToHomeConfirmations.filter(eventWithoutReference(foreignToHomeRequests))
|
||||||
const onlyInForeignWithdrawals = foreignToHomeRequests.filter(eventWithoutReference(foreignToHomeConfirmations))
|
const onlyInForeignWithdrawals = foreignToHomeRequests.filter(eventWithoutReference(foreignToHomeConfirmations))
|
||||||
|
|
||||||
const unclaimedStats = {}
|
|
||||||
if (MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST || MONITOR_HOME_TO_FOREIGN_BLOCK_LIST) {
|
|
||||||
const unclaimedFilter = unclaimedHomeToForeignRequests()
|
|
||||||
if (MONITOR_HOME_TO_FOREIGN_CHECK_SENDER === 'true') {
|
|
||||||
for (let i = 0; i < onlyInHomeDeposits.length; i++) {
|
|
||||||
onlyInHomeDeposits[i].sender = await getHomeTxSender(onlyInHomeDeposits[i].transactionHash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unclaimedStats.unclaimedHomeDeposits = onlyInHomeDeposits.filter(unclaimedFilter)
|
|
||||||
onlyInHomeDeposits = onlyInHomeDeposits.filter(e => !unclaimedFilter(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onlyInHomeDeposits,
|
onlyInHomeDeposits,
|
||||||
onlyInForeignDeposits,
|
onlyInForeignDeposits,
|
||||||
onlyInHomeWithdrawals,
|
onlyInHomeWithdrawals,
|
||||||
onlyInForeignWithdrawals,
|
onlyInForeignWithdrawals,
|
||||||
...unclaimedStats,
|
|
||||||
lastChecked: Math.floor(Date.now() / 1000)
|
lastChecked: Math.floor(Date.now() / 1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,23 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const BN = require('bignumber.js')
|
const BN = require('bignumber.js')
|
||||||
const Web3Utils = require('web3').utils
|
const Web3 = require('web3')
|
||||||
const logger = require('./logger')('getBalances')
|
const logger = require('./logger')('getBalances')
|
||||||
const { BRIDGE_MODES } = require('../commons')
|
const { BRIDGE_MODES } = require('../commons')
|
||||||
const { web3Home, web3Foreign, getHomeBlockNumber } = require('./utils/web3')
|
|
||||||
|
|
||||||
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
const Web3Utils = Web3.utils
|
||||||
|
|
||||||
|
const {
|
||||||
|
COMMON_HOME_RPC_URL,
|
||||||
|
COMMON_FOREIGN_RPC_URL,
|
||||||
|
COMMON_HOME_BRIDGE_ADDRESS,
|
||||||
|
COMMON_FOREIGN_BRIDGE_ADDRESS
|
||||||
|
} = process.env
|
||||||
|
|
||||||
|
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
||||||
|
const web3Home = new Web3(homeProvider)
|
||||||
|
|
||||||
|
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
||||||
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ERC20_ABI,
|
ERC20_ABI,
|
||||||
@@ -18,50 +30,21 @@ const {
|
|||||||
FOREIGN_NATIVE_TO_ERC_ABI
|
FOREIGN_NATIVE_TO_ERC_ABI
|
||||||
} = require('../commons')
|
} = require('../commons')
|
||||||
|
|
||||||
async function main(bridgeMode, eventsInfo) {
|
async function main(bridgeMode) {
|
||||||
const {
|
|
||||||
homeToForeignConfirmations,
|
|
||||||
foreignToHomeConfirmations,
|
|
||||||
homeDelayedBlockNumber,
|
|
||||||
foreignDelayedBlockNumber
|
|
||||||
} = eventsInfo
|
|
||||||
|
|
||||||
// Events in the ./utils/events.js are fetched for different block ranges,
|
|
||||||
// In order to be consistent with the balance values, the following values might be needed
|
|
||||||
|
|
||||||
// Foreign balance should represent all UserRequestForAffirmation events up to block `N - requiredBlockConfirmation()`
|
|
||||||
// and all RelayedMessage events up to block `N`.
|
|
||||||
// This constant tells the difference between bridge balance at block `N - requiredBlockConfirmation() + 1`
|
|
||||||
// and the actual value monitor is interested in.
|
|
||||||
const lateForeignConfirmationsTotalValue = BN.sum(
|
|
||||||
0,
|
|
||||||
...homeToForeignConfirmations.filter(e => e.blockNumber > foreignDelayedBlockNumber).map(e => e.value)
|
|
||||||
)
|
|
||||||
// Home balance should represent all UserRequestForSignature events up to block `M - requiredBlockConfirmation()`
|
|
||||||
// and all AffirmationCompleted events up to block `M`.
|
|
||||||
// This constant tells the difference between bridge balance at block `M - requiredBlockConfirmation() + 1`
|
|
||||||
// and the actual value monitor is interested in.
|
|
||||||
const lateHomeConfirmationsTotalValue = BN.sum(
|
|
||||||
0,
|
|
||||||
...foreignToHomeConfirmations.filter(e => e.blockNumber > homeDelayedBlockNumber).map(e => e.value)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (bridgeMode === BRIDGE_MODES.ERC_TO_ERC) {
|
if (bridgeMode === BRIDGE_MODES.ERC_TO_ERC) {
|
||||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
const erc20Address = await foreignBridge.methods.erc20token().call()
|
const erc20Address = await foreignBridge.methods.erc20token().call()
|
||||||
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
||||||
logger.debug('calling erc20Contract.methods.balanceOf')
|
logger.debug('calling erc20Contract.methods.balanceOf')
|
||||||
const foreignErc20Balance = await erc20Contract.methods
|
const foreignErc20Balance = await erc20Contract.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||||
.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS)
|
|
||||||
.call({}, foreignDelayedBlockNumber)
|
|
||||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
logger.debug('calling homeBridge.methods.erc677token')
|
logger.debug('calling homeBridge.methods.erc677token')
|
||||||
const tokenAddress = await homeBridge.methods.erc677token().call()
|
const tokenAddress = await homeBridge.methods.erc677token().call()
|
||||||
const tokenContract = new web3Home.eth.Contract(ERC677_ABI, tokenAddress)
|
const tokenContract = new web3Home.eth.Contract(ERC677_ABI, tokenAddress)
|
||||||
logger.debug('calling tokenContract.methods.totalSupply()')
|
logger.debug('calling tokenContract.methods.totalSupply()')
|
||||||
const totalSupply = await tokenContract.methods.totalSupply().call({}, homeDelayedBlockNumber)
|
const totalSupply = await tokenContract.methods.totalSupply().call()
|
||||||
const foreignBalanceBN = new BN(foreignErc20Balance).plus(lateForeignConfirmationsTotalValue)
|
const foreignBalanceBN = new BN(foreignErc20Balance)
|
||||||
const foreignTotalSupplyBN = new BN(totalSupply).plus(lateHomeConfirmationsTotalValue)
|
const foreignTotalSupplyBN = new BN(totalSupply)
|
||||||
const diff = foreignBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
const diff = foreignBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
||||||
logger.debug('Done')
|
logger.debug('Done')
|
||||||
return {
|
return {
|
||||||
@@ -78,12 +61,12 @@ async function main(bridgeMode, eventsInfo) {
|
|||||||
logger.debug('calling web3Home.eth.getBalance')
|
logger.debug('calling web3Home.eth.getBalance')
|
||||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
const erc20Address = await foreignBridge.methods.erc677token().call()
|
const erc20Address = await foreignBridge.methods.erc677token().call()
|
||||||
const homeBalance = await web3Home.eth.getBalance(COMMON_HOME_BRIDGE_ADDRESS, homeDelayedBlockNumber)
|
const homeBalance = await web3Home.eth.getBalance(COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
const tokenContract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
const tokenContract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
||||||
logger.debug('calling tokenContract.methods.totalSupply()')
|
logger.debug('calling tokenContract.methods.totalSupply()')
|
||||||
const totalSupply = await tokenContract.methods.totalSupply().call({}, foreignDelayedBlockNumber)
|
const totalSupply = await tokenContract.methods.totalSupply().call()
|
||||||
const homeBalanceBN = new BN(homeBalance).plus(lateHomeConfirmationsTotalValue)
|
const homeBalanceBN = new BN(homeBalance)
|
||||||
const foreignTotalSupplyBN = new BN(totalSupply).plus(lateForeignConfirmationsTotalValue)
|
const foreignTotalSupplyBN = new BN(totalSupply)
|
||||||
const diff = homeBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
const diff = homeBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
||||||
logger.debug('Done')
|
logger.debug('Done')
|
||||||
return {
|
return {
|
||||||
@@ -120,25 +103,21 @@ async function main(bridgeMode, eventsInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.debug('calling erc20Contract.methods.balanceOf')
|
logger.debug('calling erc20Contract.methods.balanceOf')
|
||||||
const foreignErc20Balance = await erc20Contract.methods
|
const foreignErc20Balance = await erc20Contract.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||||
.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS)
|
|
||||||
.call({}, foreignDelayedBlockNumber)
|
|
||||||
|
|
||||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_NATIVE_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_NATIVE_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
logger.debug('calling homeBridge.methods.blockRewardContract')
|
logger.debug('calling homeBridge.methods.blockRewardContract')
|
||||||
const blockRewardAddress = await homeBridge.methods.blockRewardContract().call()
|
const blockRewardAddress = await homeBridge.methods.blockRewardContract().call()
|
||||||
const blockRewardContract = new web3Home.eth.Contract(BLOCK_REWARD_ABI, blockRewardAddress)
|
const blockRewardContract = new web3Home.eth.Contract(BLOCK_REWARD_ABI, blockRewardAddress)
|
||||||
const homeBlockNumber = await getHomeBlockNumber()
|
|
||||||
logger.debug('calling blockReward.methods.mintedTotally')
|
logger.debug('calling blockReward.methods.mintedTotally')
|
||||||
const mintedCoins = await blockRewardContract.methods
|
const mintedCoins = await blockRewardContract.methods.mintedTotallyByBridge(COMMON_HOME_BRIDGE_ADDRESS).call()
|
||||||
.mintedTotallyByBridge(COMMON_HOME_BRIDGE_ADDRESS)
|
|
||||||
.call({}, homeBlockNumber)
|
|
||||||
logger.debug('calling homeBridge.methods.totalBurntCoins')
|
logger.debug('calling homeBridge.methods.totalBurntCoins')
|
||||||
const burntCoins = await homeBridge.methods.totalBurntCoins().call({}, homeDelayedBlockNumber)
|
const burntCoins = await homeBridge.methods.totalBurntCoins().call()
|
||||||
|
|
||||||
const mintedCoinsBN = new BN(mintedCoins)
|
const mintedCoinsBN = new BN(mintedCoins)
|
||||||
const burntCoinsBN = new BN(burntCoins)
|
const burntCoinsBN = new BN(burntCoins)
|
||||||
const totalSupplyBN = mintedCoinsBN.minus(burntCoinsBN)
|
const totalSupplyBN = mintedCoinsBN.minus(burntCoinsBN)
|
||||||
const foreignErc20BalanceBN = new BN(foreignErc20Balance).plus(lateForeignConfirmationsTotalValue)
|
const foreignErc20BalanceBN = new BN(foreignErc20Balance)
|
||||||
const investedAmountInDaiBN = new BN(investedAmountInDai)
|
const investedAmountInDaiBN = new BN(investedAmountInDai)
|
||||||
const bridgeDsrBalanceBN = new BN(bridgeDsrBalance)
|
const bridgeDsrBalanceBN = new BN(bridgeDsrBalance)
|
||||||
|
|
||||||
|
|||||||
@@ -1,36 +1,18 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const BN = require('bignumber.js')
|
const eventsInfo = require('./utils/events')
|
||||||
const Web3Utils = require('web3').utils
|
|
||||||
const {
|
|
||||||
eventWithoutReference,
|
|
||||||
deliveredMsgNotProcessed,
|
|
||||||
unclaimedHomeToForeignRequests,
|
|
||||||
manuallyProcessedAMBHomeToForeignRequests
|
|
||||||
} = require('./utils/message')
|
|
||||||
const { BRIDGE_MODES } = require('../commons')
|
const { BRIDGE_MODES } = require('../commons')
|
||||||
const { getHomeTxSender } = require('./utils/web3Cache')
|
|
||||||
|
|
||||||
const {
|
async function main(bridgeMode) {
|
||||||
MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST,
|
|
||||||
MONITOR_HOME_TO_FOREIGN_BLOCK_LIST,
|
|
||||||
MONITOR_HOME_TO_FOREIGN_CHECK_SENDER
|
|
||||||
} = process.env
|
|
||||||
|
|
||||||
async function main(bridgeMode, eventsInfo) {
|
|
||||||
const {
|
const {
|
||||||
homeToForeignConfirmations,
|
homeToForeignConfirmations,
|
||||||
homeToForeignRequests,
|
homeToForeignRequests,
|
||||||
foreignToHomeConfirmations,
|
foreignToHomeConfirmations,
|
||||||
foreignToHomeRequests
|
foreignToHomeRequests
|
||||||
} = eventsInfo
|
} = await eventsInfo(bridgeMode)
|
||||||
|
|
||||||
if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
||||||
const onlyInHomeRequests = homeToForeignRequests.filter(deliveredMsgNotProcessed(homeToForeignConfirmations))
|
|
||||||
const manuallyProcessedRequests = onlyInHomeRequests.filter(manuallyProcessedAMBHomeToForeignRequests())
|
|
||||||
return {
|
return {
|
||||||
fromHomeToForeignDiff:
|
fromHomeToForeignDiff: homeToForeignRequests.length - homeToForeignConfirmations.length,
|
||||||
homeToForeignRequests.length - homeToForeignConfirmations.length - manuallyProcessedRequests.length,
|
|
||||||
fromHomeToForeignPBUDiff: manuallyProcessedRequests.length,
|
|
||||||
fromForeignToHomeDiff: foreignToHomeConfirmations.length - foreignToHomeRequests.length,
|
fromForeignToHomeDiff: foreignToHomeConfirmations.length - foreignToHomeRequests.length,
|
||||||
home: {
|
home: {
|
||||||
toForeign: homeToForeignRequests.length,
|
toForeign: homeToForeignRequests.length,
|
||||||
@@ -42,26 +24,9 @@ async function main(bridgeMode, eventsInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const stats = {
|
|
||||||
depositsDiff: homeToForeignRequests.length - homeToForeignConfirmations.length,
|
|
||||||
withdrawalDiff: foreignToHomeConfirmations.length - foreignToHomeRequests.length
|
|
||||||
}
|
|
||||||
if (MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST || MONITOR_HOME_TO_FOREIGN_BLOCK_LIST) {
|
|
||||||
const onlyInHomeDeposits = homeToForeignRequests.filter(eventWithoutReference(homeToForeignConfirmations))
|
|
||||||
if (MONITOR_HOME_TO_FOREIGN_CHECK_SENDER === 'true') {
|
|
||||||
for (let i = 0; i < onlyInHomeDeposits.length; i++) {
|
|
||||||
onlyInHomeDeposits[i].sender = await getHomeTxSender(onlyInHomeDeposits[i].transactionHash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const unclaimedPool = onlyInHomeDeposits.filter(unclaimedHomeToForeignRequests())
|
|
||||||
|
|
||||||
stats.depositsDiff -= unclaimedPool.length
|
|
||||||
stats.unclaimedDiff = unclaimedPool.length
|
|
||||||
stats.unclaimedBalance = Web3Utils.fromWei(BN.sum(0, ...unclaimedPool.map(e => e.value)).toFixed())
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
...stats,
|
depositsDiff: homeToForeignRequests.length - homeToForeignConfirmations.length,
|
||||||
|
withdrawalDiff: foreignToHomeConfirmations.length - foreignToHomeRequests.length,
|
||||||
home: {
|
home: {
|
||||||
deposits: homeToForeignRequests.length,
|
deposits: homeToForeignRequests.length,
|
||||||
withdrawals: foreignToHomeConfirmations.length
|
withdrawals: foreignToHomeConfirmations.length
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const cors = require('cors')
|
|
||||||
const { readFile } = require('./utils/file')
|
const { readFile } = require('./utils/file')
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
const bridgeRouter = express.Router({ mergeParams: true })
|
const bridgeRouter = express.Router({ mergeParams: true })
|
||||||
|
|
||||||
app.use(cors())
|
|
||||||
|
|
||||||
app.get('/favicon.ico', (req, res) => res.sendStatus(204))
|
app.get('/favicon.ico', (req, res) => res.sendStatus(204))
|
||||||
app.use('/:bridgeName', bridgeRouter)
|
app.use('/:bridgeName', bridgeRouter)
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,11 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bignumber.js": "^9.0.1",
|
"bignumber.js": "^6.0.0",
|
||||||
"cors": "^2.8.5",
|
|
||||||
"dotenv": "^5.0.1",
|
"dotenv": "^5.0.1",
|
||||||
"express": "^4.16.3",
|
"express": "^4.16.3",
|
||||||
"node-fetch": "^2.1.2",
|
"node-fetch": "^2.1.2",
|
||||||
"web3": "^1.3.0"
|
"web3": "1.0.0-beta.34"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10.18"
|
"node": ">= 10.18"
|
||||||
|
|||||||
@@ -2,21 +2,17 @@
|
|||||||
|
|
||||||
CONFIGDIR="configs"
|
CONFIGDIR="configs"
|
||||||
RESPONSESDIR="responses"
|
RESPONSESDIR="responses"
|
||||||
ACLDIR="access-lists"
|
|
||||||
ALLOWANCEFILE="allowance_list.txt"
|
|
||||||
BLOCKFILE="block_list.txt"
|
|
||||||
CACHEDIR="cache"
|
|
||||||
IMAGETAG="latest"
|
IMAGETAG="latest"
|
||||||
|
|
||||||
cd $(dirname $0)/..
|
cd $(dirname $0)/..
|
||||||
|
|
||||||
if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
||||||
tstart=`date +"%s"`
|
tstart=`date +"%s"`
|
||||||
|
|
||||||
for file in ${CONFIGDIR}/*.env
|
for file in ${CONFIGDIR}/*.env
|
||||||
do
|
do
|
||||||
echo "${file} handling..."
|
echo "${file} handling..."
|
||||||
|
|
||||||
bridgename=`source ${file} && echo ${MONITOR_BRIDGE_NAME}`
|
bridgename=`source ${file} && echo ${MONITOR_BRIDGE_NAME}`
|
||||||
reportdir=${RESPONSESDIR}"/"${bridgename}
|
reportdir=${RESPONSESDIR}"/"${bridgename}
|
||||||
if [ ! -d ${reportdir} ]; then
|
if [ ! -d ${reportdir} ]; then
|
||||||
@@ -30,18 +26,10 @@ if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
alist=`source ${file} && echo ${MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST}`
|
|
||||||
blist=`source ${file} && echo ${MONITOR_HOME_TO_FOREIGN_BLOCK_LIST}`
|
|
||||||
al_param="$(pwd)/${ACLDIR}/${bridgename}/${ALLOWANCEFILE}:/mono/monitor/access-lists/allowance_list.txt"
|
|
||||||
bl_param="$(pwd)/${ACLDIR}/${bridgename}/${BLOCKFILE}:/mono/monitor/access-lists/block_list.txt"
|
|
||||||
|
|
||||||
containername=${bridgename}"-checker"
|
containername=${bridgename}"-checker"
|
||||||
docker container stats --no-stream ${containername} 2>/dev/null 1>&2
|
docker container stats --no-stream ${containername} 2>/dev/null 1>&2
|
||||||
if [ ! "$?" == "0" ]; then
|
if [ ! "$?" == "0" ]; then
|
||||||
mkdir -p "$(pwd)/$CACHEDIR/$bridgename"
|
|
||||||
docker run --rm --env-file $file -v $(pwd)/${RESPONSESDIR}:/mono/monitor/responses \
|
docker run --rm --env-file $file -v $(pwd)/${RESPONSESDIR}:/mono/monitor/responses \
|
||||||
${alist:+"-v"} ${alist:+"$al_param"} ${blist:+"-v"} ${blist:+"$bl_param"} \
|
|
||||||
-v $(pwd)/${CACHEDIR}/${bridgename}:/mono/monitor/cache/${bridgename} \
|
|
||||||
--name ${containername} poanetwork/tokenbridge-monitor:${IMAGETAG} \
|
--name ${containername} poanetwork/tokenbridge-monitor:${IMAGETAG} \
|
||||||
/bin/bash -c 'yarn check-all'
|
/bin/bash -c 'yarn check-all'
|
||||||
shasum -a 256 -s -c ${checksumfile}
|
shasum -a 256 -s -c ${checksumfile}
|
||||||
@@ -58,15 +46,15 @@ if /usr/local/bin/docker-compose ps | grep -q -i 'monitor'; then
|
|||||||
else
|
else
|
||||||
echo "${containername} have not finished yet" >&2
|
echo "${containername} have not finished yet" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm ${checksumfile}
|
rm ${checksumfile}
|
||||||
echo "========================================"
|
echo "========================================"
|
||||||
done
|
done
|
||||||
|
|
||||||
tend=`date +"%s"`
|
tend=`date +"%s"`
|
||||||
tdiff=`expr ${tend} - ${tstart}`
|
tdiff=`expr ${tend} - ${tstart}`
|
||||||
echo "Total time to run: ${tdiff}"
|
echo "Total time to run: ${tdiff}"
|
||||||
|
|
||||||
else
|
else
|
||||||
echo "Monitor is not running, skipping checks."
|
echo "Monitor is not running, skipping checks."
|
||||||
fi
|
fi
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
const Web3 = require('web3')
|
||||||
const logger = require('./logger')('stuckTransfers.js')
|
const logger = require('./logger')('stuckTransfers.js')
|
||||||
const { FOREIGN_V1_ABI } = require('../commons/abis')
|
const { FOREIGN_V1_ABI } = require('../commons/abis')
|
||||||
const { web3Foreign, getForeignBlockNumber } = require('./utils/web3')
|
|
||||||
const { getPastEvents } = require('./utils/web3Cache')
|
|
||||||
|
|
||||||
const { COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
const { COMMON_FOREIGN_RPC_URL, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
||||||
const MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
|
const MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
|
||||||
|
|
||||||
|
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
||||||
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
const ABITransferWithoutData = [
|
const ABITransferWithoutData = [
|
||||||
{
|
{
|
||||||
anonymous: false,
|
anonymous: false,
|
||||||
@@ -62,39 +64,38 @@ const ABIWithData = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
function transferWithoutCallback(transfersNormal) {
|
function compareTransfers(transfersNormal) {
|
||||||
const txHashes = new Set()
|
return withData => {
|
||||||
transfersNormal.forEach(transfer => txHashes.add(transfer.transactionHash))
|
return (
|
||||||
return withData => !txHashes.has(withData.transactionHash)
|
transfersNormal.filter(normal => {
|
||||||
|
return normal.transactionHash === withData.transactionHash
|
||||||
|
}).length === 0
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_V1_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_V1_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
logger.debug('calling foreignBridge.methods.erc677token')
|
|
||||||
const erc20Address = await foreignBridge.methods.erc677token().call()
|
const erc20Address = await foreignBridge.methods.erc677token().call()
|
||||||
const tokenContract = new web3Foreign.eth.Contract(ABITransferWithoutData, erc20Address)
|
const tokenContract = new web3Foreign.eth.Contract(ABITransferWithoutData, erc20Address)
|
||||||
const tokenContractWithData = new web3Foreign.eth.Contract(ABIWithData, erc20Address)
|
const tokenContractWithData = new web3Foreign.eth.Contract(ABIWithData, erc20Address)
|
||||||
logger.debug('getting last block number')
|
|
||||||
const foreignBlockNumber = await getForeignBlockNumber()
|
|
||||||
const foreignConfirmations = await foreignBridge.methods.requiredBlockConfirmations().call()
|
|
||||||
const foreignDelayedBlockNumber = foreignBlockNumber - foreignConfirmations
|
|
||||||
logger.debug('calling tokenContract.getPastEvents Transfer')
|
logger.debug('calling tokenContract.getPastEvents Transfer')
|
||||||
const options = {
|
const transfersNormal = await tokenContract.getPastEvents('Transfer', {
|
||||||
event: 'Transfer',
|
filter: {
|
||||||
options: {
|
to: COMMON_FOREIGN_BRIDGE_ADDRESS
|
||||||
filter: {
|
|
||||||
to: COMMON_FOREIGN_BRIDGE_ADDRESS
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignBlockNumber,
|
toBlock: 'latest'
|
||||||
chain: 'foreign',
|
})
|
||||||
safeToBlock: foreignDelayedBlockNumber
|
|
||||||
}
|
|
||||||
const transfersNormal = await getPastEvents(tokenContract, options)
|
|
||||||
logger.debug('calling tokenContractWithData.getPastEvents Transfer')
|
logger.debug('calling tokenContractWithData.getPastEvents Transfer')
|
||||||
const transfersWithData = await getPastEvents(tokenContractWithData, options)
|
const transfersWithData = await tokenContractWithData.getPastEvents('Transfer', {
|
||||||
const stuckTransfers = transfersNormal.filter(transferWithoutCallback(transfersWithData))
|
filter: {
|
||||||
|
to: COMMON_FOREIGN_BRIDGE_ADDRESS
|
||||||
|
},
|
||||||
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
|
toBlock: 'latest'
|
||||||
|
})
|
||||||
|
const stuckTransfers = transfersNormal.filter(compareTransfers(transfersWithData))
|
||||||
logger.debug('Done')
|
logger.debug('Done')
|
||||||
return {
|
return {
|
||||||
stuckTransfers,
|
stuckTransfers,
|
||||||
|
|||||||
11
monitor/utils/contract.js
Normal file
11
monitor/utils/contract.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
const { toBN } = require('web3').utils
|
||||||
|
|
||||||
|
const getBlockNumberCall = web3 => web3.eth.getBlockNumber()
|
||||||
|
|
||||||
|
async function getBlockNumber(web3Home, web3Foreign) {
|
||||||
|
return (await Promise.all([web3Home, web3Foreign].map(getBlockNumberCall))).map(toBN)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getBlockNumber
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
const Web3 = require('web3')
|
||||||
|
const { toBN } = require('web3').utils
|
||||||
const logger = require('../logger')('eventsUtils')
|
const logger = require('../logger')('eventsUtils')
|
||||||
const {
|
const {
|
||||||
BRIDGE_MODES,
|
BRIDGE_MODES,
|
||||||
@@ -9,6 +11,7 @@ const {
|
|||||||
ERC20_ABI,
|
ERC20_ABI,
|
||||||
ERC677_BRIDGE_TOKEN_ABI,
|
ERC677_BRIDGE_TOKEN_ABI,
|
||||||
getTokenType,
|
getTokenType,
|
||||||
|
getPastEvents,
|
||||||
ZERO_ADDRESS,
|
ZERO_ADDRESS,
|
||||||
OLD_AMB_USER_REQUEST_FOR_SIGNATURE_ABI,
|
OLD_AMB_USER_REQUEST_FOR_SIGNATURE_ABI,
|
||||||
OLD_AMB_USER_REQUEST_FOR_AFFIRMATION_ABI
|
OLD_AMB_USER_REQUEST_FOR_AFFIRMATION_ABI
|
||||||
@@ -16,12 +19,24 @@ const {
|
|||||||
const { normalizeEventInformation } = require('./message')
|
const { normalizeEventInformation } = require('./message')
|
||||||
const { filterTransferBeforeES } = require('./tokenUtils')
|
const { filterTransferBeforeES } = require('./tokenUtils')
|
||||||
const { writeFile, readCacheFile } = require('./file')
|
const { writeFile, readCacheFile } = require('./file')
|
||||||
const { web3Home, web3Foreign, getHomeBlockNumber, getForeignBlockNumber } = require('./web3')
|
|
||||||
const { getPastEvents } = require('./web3Cache')
|
|
||||||
|
|
||||||
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS, MONITOR_CACHE_EVENTS } = process.env
|
const {
|
||||||
const MONITOR_HOME_START_BLOCK = Number(process.env.MONITOR_HOME_START_BLOCK) || 0
|
COMMON_HOME_RPC_URL,
|
||||||
const MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
|
COMMON_FOREIGN_RPC_URL,
|
||||||
|
COMMON_HOME_BRIDGE_ADDRESS,
|
||||||
|
COMMON_FOREIGN_BRIDGE_ADDRESS,
|
||||||
|
MONITOR_CACHE_EVENTS
|
||||||
|
} = process.env
|
||||||
|
const MONITOR_HOME_START_BLOCK = toBN(Number(process.env.MONITOR_HOME_START_BLOCK) || 0)
|
||||||
|
const MONITOR_FOREIGN_START_BLOCK = toBN(Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0)
|
||||||
|
|
||||||
|
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
||||||
|
const web3Home = new Web3(homeProvider)
|
||||||
|
|
||||||
|
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
||||||
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
|
const { getBlockNumber } = require('./contract')
|
||||||
|
|
||||||
const cacheFilePath = '/tmp/cachedEvents.json'
|
const cacheFilePath = '/tmp/cachedEvents.json'
|
||||||
async function main(mode) {
|
async function main(mode) {
|
||||||
@@ -58,13 +73,7 @@ async function main(mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.debug('getting last block numbers')
|
logger.debug('getting last block numbers')
|
||||||
const homeBlockNumber = await getHomeBlockNumber()
|
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
||||||
const foreignBlockNumber = await getForeignBlockNumber()
|
|
||||||
const homeConfirmations = await homeBridge.methods.requiredBlockConfirmations().call()
|
|
||||||
const foreignConfirmations = await foreignBridge.methods.requiredBlockConfirmations().call()
|
|
||||||
const homeDelayedBlockNumber = homeBlockNumber - homeConfirmations
|
|
||||||
const foreignDelayedBlockNumber = foreignBlockNumber - foreignConfirmations
|
|
||||||
|
|
||||||
let homeToForeignRequests = []
|
let homeToForeignRequests = []
|
||||||
let foreignToHomeRequests = []
|
let foreignToHomeRequests = []
|
||||||
let homeMigrationBlock = MONITOR_HOME_START_BLOCK
|
let homeMigrationBlock = MONITOR_HOME_START_BLOCK
|
||||||
@@ -81,24 +90,22 @@ 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: homeDelayedBlockNumber,
|
toBlock: homeBlockNumber
|
||||||
chain: 'home'
|
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
logger.debug(`found ${homeToForeignRequests.length} events`)
|
logger.debug(`found ${homeToForeignRequests.length} events`)
|
||||||
if (homeToForeignRequests.length > 0) {
|
if (homeToForeignRequests.length > 0) {
|
||||||
homeMigrationBlock = Math.max(...homeToForeignRequests.map(x => x.blockNumber))
|
homeMigrationBlock = toBN(Math.max(...homeToForeignRequests.map(x => x.blockNumber)))
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("calling oldForeignBridge.getPastEvents('UserRequestForAffirmation(bytes)')")
|
logger.debug("calling oldForeignBridge.getPastEvents('UserRequestForAffirmation(bytes)')")
|
||||||
foreignToHomeRequests = (await getPastEvents(oldForeignBridge, {
|
foreignToHomeRequests = (await getPastEvents(oldForeignBridge, {
|
||||||
event: 'UserRequestForAffirmation',
|
event: 'UserRequestForAffirmation',
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignDelayedBlockNumber,
|
toBlock: foreignBlockNumber
|
||||||
chain: 'foreign'
|
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
logger.debug(`found ${foreignToHomeRequests.length} events`)
|
logger.debug(`found ${foreignToHomeRequests.length} events`)
|
||||||
if (foreignToHomeRequests.length > 0) {
|
if (foreignToHomeRequests.length > 0) {
|
||||||
foreignMigrationBlock = Math.max(...foreignToHomeRequests.map(x => x.blockNumber))
|
foreignMigrationBlock = toBN(Math.max(...foreignToHomeRequests.map(x => x.blockNumber)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,8 +113,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: homeDelayedBlockNumber,
|
toBlock: homeBlockNumber
|
||||||
chain: 'home'
|
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
homeToForeignRequests = [...homeToForeignRequests, ...homeToForeignRequestsNew]
|
homeToForeignRequests = [...homeToForeignRequests, ...homeToForeignRequestsNew]
|
||||||
|
|
||||||
@@ -115,26 +121,21 @@ async function main(mode) {
|
|||||||
const homeToForeignConfirmations = (await getPastEvents(foreignBridge, {
|
const homeToForeignConfirmations = (await getPastEvents(foreignBridge, {
|
||||||
event: v1Bridge ? 'Deposit' : 'RelayedMessage',
|
event: v1Bridge ? 'Deposit' : 'RelayedMessage',
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignBlockNumber,
|
toBlock: foreignBlockNumber
|
||||||
chain: 'foreign',
|
|
||||||
safeToBlock: foreignDelayedBlockNumber
|
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
|
|
||||||
logger.debug("calling homeBridge.getPastEvents('AffirmationCompleted')")
|
logger.debug("calling homeBridge.getPastEvents('AffirmationCompleted')")
|
||||||
const foreignToHomeConfirmations = (await getPastEvents(homeBridge, {
|
const foreignToHomeConfirmations = (await getPastEvents(homeBridge, {
|
||||||
event: v1Bridge ? 'Withdraw' : 'AffirmationCompleted',
|
event: v1Bridge ? 'Withdraw' : 'AffirmationCompleted',
|
||||||
fromBlock: MONITOR_HOME_START_BLOCK,
|
fromBlock: MONITOR_HOME_START_BLOCK,
|
||||||
toBlock: homeBlockNumber,
|
toBlock: homeBlockNumber
|
||||||
chain: 'home',
|
|
||||||
safeToBlock: homeDelayedBlockNumber
|
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
|
|
||||||
logger.debug("calling foreignBridge.getPastEvents('UserRequestForAffirmation')")
|
logger.debug("calling foreignBridge.getPastEvents('UserRequestForAffirmation')")
|
||||||
const foreignToHomeRequestsNew = (await getPastEvents(foreignBridge, {
|
const foreignToHomeRequestsNew = (await getPastEvents(foreignBridge, {
|
||||||
event: v1Bridge ? 'Withdraw' : 'UserRequestForAffirmation',
|
event: v1Bridge ? 'Withdraw' : 'UserRequestForAffirmation',
|
||||||
fromBlock: foreignMigrationBlock,
|
fromBlock: foreignMigrationBlock,
|
||||||
toBlock: foreignDelayedBlockNumber,
|
toBlock: foreignBlockNumber
|
||||||
chain: 'foreign'
|
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
foreignToHomeRequests = [...foreignToHomeRequests, ...foreignToHomeRequestsNew]
|
foreignToHomeRequests = [...foreignToHomeRequests, ...foreignToHomeRequestsNew]
|
||||||
|
|
||||||
@@ -143,11 +144,10 @@ 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: foreignDelayedBlockNumber,
|
toBlock: foreignBlockNumber,
|
||||||
options: {
|
options: {
|
||||||
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
||||||
},
|
}
|
||||||
chain: 'foreign'
|
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
|
|
||||||
let directTransfers = transferEvents
|
let directTransfers = transferEvents
|
||||||
@@ -158,9 +158,7 @@ async function main(mode) {
|
|||||||
const tokensSwappedEvents = await getPastEvents(foreignBridge, {
|
const tokensSwappedEvents = await getPastEvents(foreignBridge, {
|
||||||
event: 'TokensSwapped',
|
event: 'TokensSwapped',
|
||||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||||
toBlock: foreignBlockNumber,
|
toBlock: foreignBlockNumber
|
||||||
chain: 'foreign',
|
|
||||||
safeToBlock: foreignDelayedBlockNumber
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Get token swap events emitted by foreign bridge
|
// Get token swap events emitted by foreign bridge
|
||||||
@@ -196,11 +194,10 @@ 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: foreignDelayedBlockNumber,
|
toBlock: foreignBlockNumber,
|
||||||
options: {
|
options: {
|
||||||
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
filter: { to: COMMON_FOREIGN_BRIDGE_ADDRESS }
|
||||||
},
|
}
|
||||||
chain: 'foreign'
|
|
||||||
})).map(normalizeEvent)
|
})).map(normalizeEvent)
|
||||||
|
|
||||||
// Remove events after the ES
|
// Remove events after the ES
|
||||||
@@ -235,9 +232,7 @@ async function main(mode) {
|
|||||||
foreignToHomeConfirmations,
|
foreignToHomeConfirmations,
|
||||||
foreignToHomeRequests,
|
foreignToHomeRequests,
|
||||||
isExternalErc20,
|
isExternalErc20,
|
||||||
bridgeMode,
|
bridgeMode
|
||||||
homeDelayedBlockNumber,
|
|
||||||
foreignDelayedBlockNumber
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MONITOR_CACHE_EVENTS === 'true') {
|
if (MONITOR_CACHE_EVENTS === 'true') {
|
||||||
|
|||||||
@@ -38,25 +38,9 @@ function readCacheFile(filePath) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeCacheFile(filePath, object) {
|
|
||||||
fs.mkdirSync(path.dirname(filePath), { recursive: true })
|
|
||||||
fs.writeFileSync(filePath, JSON.stringify(object))
|
|
||||||
}
|
|
||||||
|
|
||||||
function readAccessListFile(filePath) {
|
|
||||||
const data = fs.readFileSync(filePath)
|
|
||||||
return data
|
|
||||||
.toString()
|
|
||||||
.split('\n')
|
|
||||||
.map(addr => addr.trim().toLowerCase())
|
|
||||||
.filter(addr => addr.length === 42)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
readFile,
|
readFile,
|
||||||
writeFile,
|
writeFile,
|
||||||
createDir,
|
createDir,
|
||||||
readCacheFile,
|
readCacheFile
|
||||||
writeCacheFile,
|
|
||||||
readAccessListFile
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
const { REWARDABLE_VALIDATORS_ABI, processValidatorsEvents } = require('../../commons')
|
|
||||||
const { getPastEvents } = require('./web3Cache')
|
|
||||||
|
|
||||||
const VALIDATORS_INDEXED_EVENTS_ABI = [
|
|
||||||
{
|
|
||||||
anonymous: false,
|
|
||||||
inputs: [
|
|
||||||
{
|
|
||||||
indexed: true,
|
|
||||||
name: 'validator',
|
|
||||||
type: 'address'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
name: 'ValidatorRemoved',
|
|
||||||
type: 'event'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
anonymous: false,
|
|
||||||
inputs: [
|
|
||||||
{
|
|
||||||
indexed: true,
|
|
||||||
name: 'validator',
|
|
||||||
type: 'address'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
name: 'ValidatorAdded',
|
|
||||||
type: 'event'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
anonymous: false,
|
|
||||||
inputs: [
|
|
||||||
{
|
|
||||||
indexed: true,
|
|
||||||
name: 'validator',
|
|
||||||
type: 'address'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
indexed: true,
|
|
||||||
name: 'reward',
|
|
||||||
type: 'address'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
name: 'ValidatorAdded',
|
|
||||||
type: 'event'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const tryCall = async (method, fallbackValue) => {
|
|
||||||
try {
|
|
||||||
return await method.call()
|
|
||||||
} catch (e) {
|
|
||||||
return fallbackValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getValidatorList = async (address, eth, options) => {
|
|
||||||
const { logger } = options
|
|
||||||
logger.debug('getting validatorList')
|
|
||||||
|
|
||||||
const validatorsContract = new eth.Contract(REWARDABLE_VALIDATORS_ABI, address) // in monitor, BRIDGE_VALIDATORS_ABI was used
|
|
||||||
const validators = await tryCall(validatorsContract.methods.validatorList(), [])
|
|
||||||
|
|
||||||
if (validators.length) {
|
|
||||||
return validators
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug('getting validatorsEvents')
|
|
||||||
|
|
||||||
options.fromBlock = Number(await tryCall(validatorsContract.methods.deployedAtBlock(), 0))
|
|
||||||
|
|
||||||
const contract = new eth.Contract(VALIDATORS_INDEXED_EVENTS_ABI, address)
|
|
||||||
|
|
||||||
const validatorsEvents = [
|
|
||||||
...(await getPastEvents(contract, {
|
|
||||||
event: 'ValidatorAdded(address)',
|
|
||||||
...options
|
|
||||||
})),
|
|
||||||
...(await getPastEvents(contract, {
|
|
||||||
event: 'ValidatorAdded(address,address)',
|
|
||||||
...options
|
|
||||||
})),
|
|
||||||
...(await getPastEvents(contract, {
|
|
||||||
event: 'ValidatorRemoved(address)',
|
|
||||||
...options
|
|
||||||
}))
|
|
||||||
].sort((a, b) => a.blockNumber - b.blockNumber || a.transactionIndex - b.transactionIndex)
|
|
||||||
|
|
||||||
return processValidatorsEvents(validatorsEvents)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getValidatorList
|
|
||||||
}
|
|
||||||
@@ -1,30 +1,44 @@
|
|||||||
|
const web3Utils = require('web3').utils
|
||||||
const { parseAMBMessage } = require('../../commons')
|
const { parseAMBMessage } = require('../../commons')
|
||||||
const { readAccessListFile } = require('./file')
|
|
||||||
|
|
||||||
const { MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST, MONITOR_HOME_TO_FOREIGN_BLOCK_LIST } = process.env
|
|
||||||
|
|
||||||
const keyAMB = e => [e.messageId, e.sender, e.executor].join(',').toLowerCase()
|
|
||||||
|
|
||||||
const normalizeAMBMessage = e => {
|
|
||||||
let msgData = e.returnValues.encodedData
|
|
||||||
if (!e.returnValues.messageId) {
|
|
||||||
// append tx hash to an old message, where message id was not used
|
|
||||||
// for old messages, e.messageId is a corresponding transactionHash
|
|
||||||
msgData = e.transactionHash + msgData.slice(2)
|
|
||||||
}
|
|
||||||
return parseAMBMessage(msgData)
|
|
||||||
}
|
|
||||||
|
|
||||||
function deliveredMsgNotProcessed(processedList) {
|
function deliveredMsgNotProcessed(processedList) {
|
||||||
const keys = new Set()
|
return deliveredMsg => {
|
||||||
processedList.forEach(processedMsg => keys.add(keyAMB(processedMsg.returnValues)))
|
let msgData = deliveredMsg.returnValues.encodedData
|
||||||
return deliveredMsg => !keys.has(keyAMB(normalizeAMBMessage(deliveredMsg)))
|
if (!deliveredMsg.returnValues.messageId) {
|
||||||
|
// append tx hash to an old message, where message id was not used
|
||||||
|
msgData = deliveredMsg.transactionHash + msgData.slice(2)
|
||||||
|
}
|
||||||
|
const msg = parseAMBMessage(msgData)
|
||||||
|
return (
|
||||||
|
processedList.filter(processedMsg => {
|
||||||
|
return messageEqualsEvent(msg, processedMsg.returnValues)
|
||||||
|
}).length === 0
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function processedMsgNotDelivered(deliveredList) {
|
function processedMsgNotDelivered(deliveredList) {
|
||||||
const keys = new Set()
|
return processedMsg => {
|
||||||
deliveredList.forEach(deliveredMsg => keys.add(keyAMB(normalizeAMBMessage(deliveredMsg))))
|
return (
|
||||||
return processedMsg => !keys.has(keyAMB(processedMsg.returnValues))
|
deliveredList.filter(deliveredMsg => {
|
||||||
|
let msgData = deliveredMsg.returnValues.encodedData
|
||||||
|
if (!deliveredMsg.returnValues.messageId) {
|
||||||
|
// append tx hash to an old message, where message id was not used
|
||||||
|
msgData = deliveredMsg.transactionHash + msgData.slice(2)
|
||||||
|
}
|
||||||
|
const msg = parseAMBMessage(msgData)
|
||||||
|
return messageEqualsEvent(msg, processedMsg.returnValues)
|
||||||
|
}).length === 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function messageEqualsEvent(parsedMsg, event) {
|
||||||
|
return (
|
||||||
|
web3Utils.toChecksumAddress(parsedMsg.sender) === event.sender &&
|
||||||
|
web3Utils.toChecksumAddress(parsedMsg.executor) === event.executor &&
|
||||||
|
parsedMsg.messageId === event.messageId // for an old messages, event.messageId is actually a transactionHash
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,49 +60,13 @@ const normalizeEventInformation = event => ({
|
|||||||
value: event.returnValues.value
|
value: event.returnValues.value
|
||||||
})
|
})
|
||||||
|
|
||||||
const key = e => [e.referenceTx, e.recipient, e.value].join(',').toLowerCase()
|
const eventWithoutReference = otherSideEvents => e =>
|
||||||
|
otherSideEvents.filter(a => a.referenceTx === e.referenceTx && a.recipient === e.recipient && a.value === e.value)
|
||||||
const eventWithoutReference = otherSideEvents => {
|
.length === 0
|
||||||
const keys = new Set()
|
|
||||||
otherSideEvents.forEach(e => keys.add(key(e)))
|
|
||||||
return e => !keys.has(key(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
const unclaimedHomeToForeignRequests = () => {
|
|
||||||
if (MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST) {
|
|
||||||
const allowanceList = readAccessListFile(MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST)
|
|
||||||
return e => !allowanceList.includes(e.recipient.toLowerCase()) && !(e.sender && allowanceList.includes(e.sender))
|
|
||||||
} else if (MONITOR_HOME_TO_FOREIGN_BLOCK_LIST) {
|
|
||||||
const blockList = readAccessListFile(MONITOR_HOME_TO_FOREIGN_BLOCK_LIST)
|
|
||||||
return e => blockList.includes(e.recipient.toLowerCase()) || (e.sender && blockList.includes(e.sender))
|
|
||||||
} else {
|
|
||||||
return () => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const manuallyProcessedAMBHomeToForeignRequests = () => {
|
|
||||||
if (MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST) {
|
|
||||||
const allowanceList = readAccessListFile(MONITOR_HOME_TO_FOREIGN_ALLOWANCE_LIST)
|
|
||||||
return e => {
|
|
||||||
const { sender, executor, decodedDataType } = normalizeAMBMessage(e)
|
|
||||||
return (!allowanceList.includes(sender) && !allowanceList.includes(executor)) || decodedDataType.manualLane
|
|
||||||
}
|
|
||||||
} else if (MONITOR_HOME_TO_FOREIGN_BLOCK_LIST) {
|
|
||||||
const blockList = readAccessListFile(MONITOR_HOME_TO_FOREIGN_BLOCK_LIST)
|
|
||||||
return e => {
|
|
||||||
const { sender, executor, decodedDataType } = normalizeAMBMessage(e)
|
|
||||||
return blockList.includes(sender) || blockList.includes(executor) || decodedDataType.manualLane
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return e => normalizeAMBMessage(e).decodedDataType.manualLane
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
deliveredMsgNotProcessed,
|
deliveredMsgNotProcessed,
|
||||||
processedMsgNotDelivered,
|
processedMsgNotDelivered,
|
||||||
normalizeEventInformation,
|
normalizeEventInformation,
|
||||||
eventWithoutReference,
|
eventWithoutReference
|
||||||
unclaimedHomeToForeignRequests,
|
|
||||||
manuallyProcessedAMBHomeToForeignRequests
|
|
||||||
}
|
}
|
||||||
|
|||||||
16
monitor/utils/serverUtils.js
Normal file
16
monitor/utils/serverUtils.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
require('dotenv').config()
|
|
||||||
const Web3 = require('web3')
|
|
||||||
|
|
||||||
const { COMMON_HOME_RPC_URL, COMMON_FOREIGN_RPC_URL } = process.env
|
|
||||||
|
|
||||||
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
|
||||||
const web3Home = new Web3(homeProvider)
|
|
||||||
|
|
||||||
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
|
||||||
const web3Foreign = new Web3(foreignProvider)
|
|
||||||
|
|
||||||
function blockNumberWrapper(web3) {
|
|
||||||
let blockNumber = null
|
|
||||||
return async () => {
|
|
||||||
if (!blockNumber) {
|
|
||||||
blockNumber = await web3.eth.getBlockNumber()
|
|
||||||
}
|
|
||||||
return blockNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
web3Home,
|
|
||||||
web3Foreign,
|
|
||||||
getHomeBlockNumber: blockNumberWrapper(web3Home),
|
|
||||||
getForeignBlockNumber: blockNumberWrapper(web3Foreign)
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
const logger = require('../logger')('web3Cache')
|
|
||||||
const { readCacheFile, writeCacheFile } = require('./file')
|
|
||||||
const { web3Home } = require('./web3')
|
|
||||||
const { getPastEvents: commonGetPastEvents } = require('../../commons')
|
|
||||||
|
|
||||||
const { MONITOR_BRIDGE_NAME, MONITOR_CACHE_EVENTS } = process.env
|
|
||||||
|
|
||||||
let isDirty = false
|
|
||||||
|
|
||||||
const homeTxSendersCacheFile = `./cache/${MONITOR_BRIDGE_NAME}/home/txSenders.json`
|
|
||||||
const cachedHomeTxSenders = readCacheFile(homeTxSendersCacheFile) || {}
|
|
||||||
|
|
||||||
async function getHomeTxSender(txHash) {
|
|
||||||
if (!cachedHomeTxSenders[txHash]) {
|
|
||||||
logger.debug(`Fetching sender for tx ${txHash}`)
|
|
||||||
cachedHomeTxSenders[txHash] = (await web3Home.eth.getTransaction(txHash)).from.toLowerCase()
|
|
||||||
isDirty = true
|
|
||||||
}
|
|
||||||
return cachedHomeTxSenders[txHash]
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getPastEvents(contract, options) {
|
|
||||||
if (MONITOR_CACHE_EVENTS !== 'true') {
|
|
||||||
return commonGetPastEvents(contract, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
const contractAddr = contract.options.address
|
|
||||||
|
|
||||||
let eventSignature
|
|
||||||
if (options.event.includes('(')) {
|
|
||||||
eventSignature = options.event
|
|
||||||
options.event = web3Home.utils.sha3(eventSignature)
|
|
||||||
const eventABI = contract.options.jsonInterface.find(e => e.type === 'event' && e.signature === options.event)
|
|
||||||
if (!eventABI) {
|
|
||||||
throw new Error(`Event ${eventSignature} not found`)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const eventABI = contract.options.jsonInterface.find(
|
|
||||||
e => e.type === 'event' && (e.name === options.event || e.signature === options.event)
|
|
||||||
)
|
|
||||||
if (!eventABI) {
|
|
||||||
throw new Error(`Event ${options.event} not found`)
|
|
||||||
}
|
|
||||||
eventSignature = `${eventABI.name}(${eventABI.inputs.map(i => i.type).join(',')})`
|
|
||||||
}
|
|
||||||
|
|
||||||
const cacheFile = `./cache/${MONITOR_BRIDGE_NAME}/${options.chain}/${contractAddr}/${eventSignature}.json`
|
|
||||||
|
|
||||||
const { fromBlock, toBlock } = options
|
|
||||||
const { fromBlock: cachedFromBlock, toBlock: cachedToBlock, events: cachedEvents } = readCacheFile(cacheFile) || {
|
|
||||||
fromBlock: 0,
|
|
||||||
toBlock: 0,
|
|
||||||
events: []
|
|
||||||
}
|
|
||||||
|
|
||||||
let result
|
|
||||||
if (cachedFromBlock > toBlock || fromBlock > cachedToBlock) {
|
|
||||||
// requested: A...B
|
|
||||||
// cached: C...D
|
|
||||||
// OR
|
|
||||||
// requested: A...B
|
|
||||||
// cached: C...D
|
|
||||||
logger.debug(`Fetching events for blocks ${fromBlock}...${toBlock}`)
|
|
||||||
result = await commonGetPastEvents(contract, options)
|
|
||||||
} else if (fromBlock < cachedFromBlock && toBlock <= cachedToBlock) {
|
|
||||||
// requested: A...B
|
|
||||||
// cached: C...D
|
|
||||||
logger.debug(`Cache hit for blocks ${cachedFromBlock}...${toBlock}`)
|
|
||||||
logger.debug(`Fetching events for blocks ${fromBlock}...${cachedFromBlock - 1}`)
|
|
||||||
result = [
|
|
||||||
...(await commonGetPastEvents(contract, { ...options, toBlock: cachedFromBlock - 1 })),
|
|
||||||
...cachedEvents.filter(e => e.blockNumber <= toBlock)
|
|
||||||
]
|
|
||||||
} else if (fromBlock < cachedFromBlock && cachedToBlock < toBlock) {
|
|
||||||
// requested: A.....B
|
|
||||||
// cached: C.D
|
|
||||||
logger.debug(`Cache hit for blocks ${cachedFromBlock}...${cachedToBlock}`)
|
|
||||||
logger.debug(`Fetching events for blocks ${fromBlock}...${cachedFromBlock - 1}`)
|
|
||||||
logger.debug(`Fetching events for blocks ${cachedToBlock + 1}...${toBlock}`)
|
|
||||||
result = [
|
|
||||||
...(await commonGetPastEvents(contract, { ...options, toBlock: cachedFromBlock - 1 })),
|
|
||||||
...cachedEvents,
|
|
||||||
...(await commonGetPastEvents(contract, { ...options, fromBlock: cachedToBlock + 1 }))
|
|
||||||
]
|
|
||||||
} else if (cachedFromBlock <= fromBlock && toBlock <= cachedToBlock) {
|
|
||||||
// requested: A.B
|
|
||||||
// cached: C.....D
|
|
||||||
logger.debug(`Cache hit for blocks ${fromBlock}...${toBlock}`)
|
|
||||||
result = cachedEvents.filter(e => fromBlock <= e.blockNumber && e.blockNumber <= toBlock)
|
|
||||||
} else if (fromBlock >= cachedFromBlock && toBlock > cachedToBlock) {
|
|
||||||
// requested: A...B
|
|
||||||
// cached: C...D
|
|
||||||
logger.debug(`Cache hit for blocks ${fromBlock}...${cachedToBlock}`)
|
|
||||||
logger.debug(`Fetching events for blocks ${cachedToBlock + 1}...${toBlock}`)
|
|
||||||
result = [
|
|
||||||
...cachedEvents.filter(e => e.blockNumber >= fromBlock),
|
|
||||||
...(await commonGetPastEvents(contract, { ...options, fromBlock: cachedToBlock + 1 }))
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`Something is broken with cache resolution for getPastEvents,
|
|
||||||
requested blocks ${fromBlock}...${toBlock},
|
|
||||||
cached blocks ${cachedFromBlock}...${cachedToBlock}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// it is not safe to cache events with too low block confirmations
|
|
||||||
// so, only events from finalized blocks are included into the cache
|
|
||||||
const safeToBlock = options.safeToBlock || toBlock
|
|
||||||
const cacheToSave = result.filter(e => e.blockNumber <= safeToBlock)
|
|
||||||
logger.debug(
|
|
||||||
`Saving events cache for ${MONITOR_BRIDGE_NAME}/${options.chain}/${contractAddr}/${eventSignature} on disk`
|
|
||||||
)
|
|
||||||
writeCacheFile(cacheFile, {
|
|
||||||
fromBlock,
|
|
||||||
toBlock: safeToBlock,
|
|
||||||
events: cacheToSave
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveCache() {
|
|
||||||
if (isDirty) {
|
|
||||||
logger.debug('Saving cache on disk')
|
|
||||||
writeCacheFile(homeTxSendersCacheFile, cachedHomeTxSenders)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
getHomeTxSender,
|
|
||||||
getPastEvents,
|
|
||||||
saveCache
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const Web3Utils = require('web3').utils
|
const Web3 = require('web3')
|
||||||
const fetch = require('node-fetch')
|
const fetch = require('node-fetch')
|
||||||
const logger = require('./logger')('validators')
|
const logger = require('./logger')('validators')
|
||||||
const { getBridgeABIs, BRIDGE_VALIDATORS_ABI, gasPriceFromSupplier } = require('../commons')
|
const { getBridgeABIs, BRIDGE_VALIDATORS_ABI, getValidatorList, gasPriceFromSupplier } = require('../commons')
|
||||||
const { web3Home, web3Foreign, getHomeBlockNumber, getForeignBlockNumber } = require('./utils/web3')
|
const { getBlockNumber } = require('./utils/contract')
|
||||||
const { getValidatorList } = require('./utils/getValidatorsList')
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
COMMON_HOME_RPC_URL,
|
||||||
|
COMMON_FOREIGN_RPC_URL,
|
||||||
COMMON_HOME_BRIDGE_ADDRESS,
|
COMMON_HOME_BRIDGE_ADDRESS,
|
||||||
COMMON_FOREIGN_BRIDGE_ADDRESS,
|
COMMON_FOREIGN_BRIDGE_ADDRESS,
|
||||||
COMMON_HOME_GAS_PRICE_SUPPLIER_URL,
|
COMMON_HOME_GAS_PRICE_SUPPLIER_URL,
|
||||||
@@ -18,9 +19,19 @@ const {
|
|||||||
COMMON_FOREIGN_GAS_PRICE_FALLBACK,
|
COMMON_FOREIGN_GAS_PRICE_FALLBACK,
|
||||||
COMMON_FOREIGN_GAS_PRICE_FACTOR
|
COMMON_FOREIGN_GAS_PRICE_FACTOR
|
||||||
} = process.env
|
} = process.env
|
||||||
|
const MONITOR_HOME_START_BLOCK = Number(process.env.MONITOR_HOME_START_BLOCK) || 0
|
||||||
|
const MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
|
||||||
const MONITOR_VALIDATOR_HOME_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_HOME_TX_LIMIT) || 0
|
const MONITOR_VALIDATOR_HOME_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_HOME_TX_LIMIT) || 0
|
||||||
const MONITOR_VALIDATOR_FOREIGN_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_FOREIGN_TX_LIMIT) || 0
|
const MONITOR_VALIDATOR_FOREIGN_TX_LIMIT = Number(process.env.MONITOR_VALIDATOR_FOREIGN_TX_LIMIT) || 0
|
||||||
|
|
||||||
|
const Web3Utils = Web3.utils
|
||||||
|
|
||||||
|
const homeProvider = new Web3.providers.HttpProvider(COMMON_HOME_RPC_URL)
|
||||||
|
const web3Home = new Web3(homeProvider)
|
||||||
|
|
||||||
|
const foreignProvider = new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL)
|
||||||
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
const homeGasPriceSupplierOpts = {
|
const homeGasPriceSupplierOpts = {
|
||||||
speedType: COMMON_HOME_GAS_PRICE_SPEED_TYPE,
|
speedType: COMMON_HOME_GAS_PRICE_SPEED_TYPE,
|
||||||
factor: COMMON_HOME_GAS_PRICE_FACTOR,
|
factor: COMMON_HOME_GAS_PRICE_FACTOR,
|
||||||
@@ -47,12 +58,7 @@ async function main(bridgeMode) {
|
|||||||
const homeBridgeValidators = new web3Home.eth.Contract(BRIDGE_VALIDATORS_ABI, homeValidatorsAddress)
|
const homeBridgeValidators = new web3Home.eth.Contract(BRIDGE_VALIDATORS_ABI, homeValidatorsAddress)
|
||||||
|
|
||||||
logger.debug('getting last block numbers')
|
logger.debug('getting last block numbers')
|
||||||
const homeBlockNumber = await getHomeBlockNumber()
|
const [homeBlockNumber, foreignBlockNumber] = await getBlockNumber(web3Home, web3Foreign)
|
||||||
const foreignBlockNumber = await getForeignBlockNumber()
|
|
||||||
const homeConfirmations = await homeBridge.methods.requiredBlockConfirmations().call()
|
|
||||||
const foreignConfirmations = await foreignBridge.methods.requiredBlockConfirmations().call()
|
|
||||||
const homeDelayedBlockNumber = homeBlockNumber - homeConfirmations
|
|
||||||
const foreignDelayedBlockNumber = foreignBlockNumber - foreignConfirmations
|
|
||||||
|
|
||||||
logger.debug('calling foreignBridge.methods.validatorContract().call()')
|
logger.debug('calling foreignBridge.methods.validatorContract().call()')
|
||||||
const foreignValidatorsAddress = await foreignBridge.methods.validatorContract().call()
|
const foreignValidatorsAddress = await foreignBridge.methods.validatorContract().call()
|
||||||
@@ -60,18 +66,16 @@ async function main(bridgeMode) {
|
|||||||
|
|
||||||
logger.debug('calling foreignBridgeValidators getValidatorList()')
|
logger.debug('calling foreignBridgeValidators getValidatorList()')
|
||||||
const foreignValidators = (await getValidatorList(foreignValidatorsAddress, web3Foreign.eth, {
|
const foreignValidators = (await getValidatorList(foreignValidatorsAddress, web3Foreign.eth, {
|
||||||
toBlock: foreignBlockNumber,
|
from: MONITOR_FOREIGN_START_BLOCK,
|
||||||
logger,
|
to: foreignBlockNumber,
|
||||||
chain: 'foreign',
|
logger
|
||||||
safeToBlock: foreignDelayedBlockNumber
|
|
||||||
})).map(web3Foreign.utils.toChecksumAddress)
|
})).map(web3Foreign.utils.toChecksumAddress)
|
||||||
|
|
||||||
logger.debug('calling homeBridgeValidators getValidatorList()')
|
logger.debug('calling homeBridgeValidators getValidatorList()')
|
||||||
const homeValidators = (await getValidatorList(homeValidatorsAddress, web3Home.eth, {
|
const homeValidators = (await getValidatorList(homeValidatorsAddress, web3Home.eth, {
|
||||||
toBlock: homeBlockNumber,
|
from: MONITOR_HOME_START_BLOCK,
|
||||||
logger,
|
to: homeBlockNumber,
|
||||||
chain: 'home',
|
logger
|
||||||
safeToBlock: homeDelayedBlockNumber
|
|
||||||
})).map(web3Home.utils.toChecksumAddress)
|
})).map(web3Home.utils.toChecksumAddress)
|
||||||
|
|
||||||
const foreignVBalances = {}
|
const foreignVBalances = {}
|
||||||
|
|||||||
@@ -1,24 +1,8 @@
|
|||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
|
|
||||||
mode="$1"
|
../e2e-commons/up.sh deploy blocks oracle oracle-validator-2 oracle-validator-3
|
||||||
case "$mode" in
|
|
||||||
amb)
|
|
||||||
script=./test/amb.js
|
|
||||||
;;
|
|
||||||
native-to-erc)
|
|
||||||
script=./test/nativeToErc.js
|
|
||||||
;;
|
|
||||||
erc-to-erc)
|
|
||||||
script=./test/ercToErc.js
|
|
||||||
;;
|
|
||||||
erc-to-native)
|
|
||||||
script=./test/ercToNative.js
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
MODE="$mode" ../e2e-commons/up.sh deploy blocks oracle oracle-validator-2 oracle-validator-3
|
docker-compose -f ../e2e-commons/docker-compose.yml run e2e yarn workspace oracle-e2e run start
|
||||||
|
|
||||||
docker-compose -f ../e2e-commons/docker-compose.yml run e2e yarn workspace oracle-e2e run start $script
|
|
||||||
rc=$?
|
rc=$?
|
||||||
|
|
||||||
../e2e-commons/down.sh
|
../e2e-commons/down.sh
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const assert = require('assert')
|
|||||||
const { user, homeRPC, foreignRPC, amb, validator } = require('../../e2e-commons/constants.json')
|
const { user, homeRPC, foreignRPC, amb, validator } = require('../../e2e-commons/constants.json')
|
||||||
const { uniformRetry } = require('../../e2e-commons/utils')
|
const { uniformRetry } = require('../../e2e-commons/utils')
|
||||||
const { BOX_ABI, HOME_AMB_ABI, FOREIGN_AMB_ABI } = require('../../commons')
|
const { BOX_ABI, HOME_AMB_ABI, FOREIGN_AMB_ABI } = require('../../commons')
|
||||||
const { delay, setRequiredSignatures } = require('./utils')
|
const { setRequiredSignatures } = require('./utils')
|
||||||
|
|
||||||
const { toBN } = Web3.utils
|
const { toBN } = Web3.utils
|
||||||
|
|
||||||
@@ -19,17 +19,14 @@ foreignWeb3.eth.accounts.wallet.add(user.privateKey)
|
|||||||
foreignWeb3.eth.accounts.wallet.add(validator.privateKey)
|
foreignWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||||
|
|
||||||
const homeBox = new homeWeb3.eth.Contract(BOX_ABI, amb.homeBox)
|
const homeBox = new homeWeb3.eth.Contract(BOX_ABI, amb.homeBox)
|
||||||
const blockHomeBox = new homeWeb3.eth.Contract(BOX_ABI, amb.blockedHomeBox)
|
|
||||||
const foreignBox = new foreignWeb3.eth.Contract(BOX_ABI, amb.foreignBox)
|
const foreignBox = new foreignWeb3.eth.Contract(BOX_ABI, amb.foreignBox)
|
||||||
const homeBridge = new homeWeb3.eth.Contract(HOME_AMB_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const homeBridge = new homeWeb3.eth.Contract(HOME_AMB_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
const foreignBridge = new foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const foreignBridge = new foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
|
|
||||||
describe('arbitrary message bridging', () => {
|
describe('arbitrary message bridging', () => {
|
||||||
let requiredSignatures = 1
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
// Only 1 validator is used in ultimate tests
|
// Only 1 validator is used in ultimate tests
|
||||||
if (process.env.ULTIMATE !== 'true') {
|
if (process.env.ULTIMATE !== 'true') {
|
||||||
requiredSignatures = 2
|
|
||||||
// Set 2 required signatures for home bridge
|
// Set 2 required signatures for home bridge
|
||||||
await setRequiredSignatures({
|
await setRequiredSignatures({
|
||||||
bridgeContract: homeBridge,
|
bridgeContract: homeBridge,
|
||||||
@@ -79,85 +76,6 @@ describe('arbitrary message bridging', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// allowance/block lists files are not mounted to the host during the ultimate test
|
|
||||||
if (process.env.ULTIMATE !== 'true') {
|
|
||||||
it('should confirm but not relay message from blocked contract', async () => {
|
|
||||||
const newValue = 4
|
|
||||||
|
|
||||||
const initialValue = await foreignBox.methods.value().call()
|
|
||||||
assert(!toBN(initialValue).eq(toBN(newValue)), 'initial value should be different from new value')
|
|
||||||
|
|
||||||
const signatures = await homeBridge.getPastEvents('SignedForUserRequest', {
|
|
||||||
fromBlock: 0,
|
|
||||||
toBlock: 'latest'
|
|
||||||
})
|
|
||||||
|
|
||||||
await blockHomeBox.methods
|
|
||||||
.setValueOnOtherNetwork(newValue, amb.home, amb.foreignBox)
|
|
||||||
.send({
|
|
||||||
from: user.address,
|
|
||||||
gas: '400000'
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(5000)
|
|
||||||
|
|
||||||
const newSignatures = await homeBridge.getPastEvents('SignedForUserRequest', {
|
|
||||||
fromBlock: 0,
|
|
||||||
toBlock: 'latest'
|
|
||||||
})
|
|
||||||
|
|
||||||
assert(
|
|
||||||
newSignatures.length === signatures.length + requiredSignatures,
|
|
||||||
`Incorrect amount of signatures submitted, got ${newSignatures.length}, expected ${signatures.length +
|
|
||||||
requiredSignatures}`
|
|
||||||
)
|
|
||||||
|
|
||||||
const value = await foreignBox.methods.value().call()
|
|
||||||
assert(!toBN(value).eq(toBN(newValue)), 'Message should not be relayed by oracle automatically')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should confirm but not relay message from manual lane', async () => {
|
|
||||||
const newValue = 5
|
|
||||||
|
|
||||||
const initialValue = await foreignBox.methods.value().call()
|
|
||||||
assert(!toBN(initialValue).eq(toBN(newValue)), 'initial value should be different from new value')
|
|
||||||
|
|
||||||
const signatures = await homeBridge.getPastEvents('SignedForUserRequest', {
|
|
||||||
fromBlock: 0,
|
|
||||||
toBlock: 'latest'
|
|
||||||
})
|
|
||||||
|
|
||||||
await homeBox.methods
|
|
||||||
.setValueOnOtherNetworkUsingManualLane(newValue, amb.home, amb.foreignBox)
|
|
||||||
.send({
|
|
||||||
from: user.address,
|
|
||||||
gas: '400000'
|
|
||||||
})
|
|
||||||
.catch(e => {
|
|
||||||
console.error(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
await delay(5000)
|
|
||||||
|
|
||||||
const newSignatures = await homeBridge.getPastEvents('SignedForUserRequest', {
|
|
||||||
fromBlock: 0,
|
|
||||||
toBlock: 'latest'
|
|
||||||
})
|
|
||||||
|
|
||||||
assert(
|
|
||||||
newSignatures.length === signatures.length + requiredSignatures,
|
|
||||||
`Incorrect amount of signatures submitted, got ${newSignatures.length}, expected ${signatures.length +
|
|
||||||
requiredSignatures}`
|
|
||||||
)
|
|
||||||
|
|
||||||
const value = await foreignBox.methods.value().call()
|
|
||||||
assert(!toBN(value).eq(toBN(newValue)), 'Message should not be relayed by oracle automatically')
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
describe('Foreign to Home', () => {
|
describe('Foreign to Home', () => {
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
const { BRIDGE_VALIDATORS_ABI } = require('../../commons')
|
const { BRIDGE_VALIDATORS_ABI } = require('../../commons')
|
||||||
|
|
||||||
async function delay(ms) {
|
|
||||||
return new Promise(res => setTimeout(res, ms))
|
|
||||||
}
|
|
||||||
|
|
||||||
const setRequiredSignatures = async ({ bridgeContract, web3, requiredSignatures, options }) => {
|
const setRequiredSignatures = async ({ bridgeContract, web3, requiredSignatures, options }) => {
|
||||||
const validatorAddress = await bridgeContract.methods.validatorContract().call()
|
const validatorAddress = await bridgeContract.methods.validatorContract().call()
|
||||||
const validatorContract = new web3.eth.Contract(BRIDGE_VALIDATORS_ABI, validatorAddress)
|
const validatorContract = new web3.eth.Contract(BRIDGE_VALIDATORS_ABI, validatorAddress)
|
||||||
@@ -12,6 +8,5 @@ const setRequiredSignatures = async ({ bridgeContract, web3, requiredSignatures,
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
delay,
|
|
||||||
setRequiredSignatures
|
setRequiredSignatures
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ ORACLE_FOREIGN_START_BLOCK=
|
|||||||
|
|
||||||
ORACLE_LOG_LEVEL=debug
|
ORACLE_LOG_LEVEL=debug
|
||||||
ORACLE_MAX_PROCESSING_TIME=20000
|
ORACLE_MAX_PROCESSING_TIME=20000
|
||||||
ORACLE_RPC_REQUEST_TIMEOUT=5000
|
|
||||||
|
|
||||||
ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST=access-lists/allowance_list.txt
|
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_BLOCK_LIST=access-lists/block_list.txt
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const baseConfig = require('./base.config')
|
const baseConfig = require('./base.config')
|
||||||
|
|
||||||
const { web3Foreign, web3ForeignRedundant } = require('../src/services/web3')
|
const { web3Foreign } = require('../src/services/web3')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...baseConfig.bridgeConfig,
|
...baseConfig.bridgeConfig,
|
||||||
@@ -8,6 +8,5 @@ module.exports = {
|
|||||||
oldQueue: 'foreign',
|
oldQueue: 'foreign',
|
||||||
id: 'foreign',
|
id: 'foreign',
|
||||||
name: 'sender-foreign',
|
name: 'sender-foreign',
|
||||||
web3: web3Foreign,
|
web3: web3Foreign
|
||||||
web3Redundant: web3ForeignRedundant
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
const baseConfig = require('./base.config')
|
const baseConfig = require('./base.config')
|
||||||
|
|
||||||
const { web3Home, web3HomeRedundant } = require('../src/services/web3')
|
const { web3Home } = require('../src/services/web3')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...baseConfig.bridgeConfig,
|
...baseConfig.bridgeConfig,
|
||||||
@@ -8,6 +8,5 @@ module.exports = {
|
|||||||
oldQueue: 'home',
|
oldQueue: 'home',
|
||||||
id: 'home',
|
id: 'home',
|
||||||
name: 'sender-home',
|
name: 'sender-home',
|
||||||
web3: web3Home,
|
web3: web3Home
|
||||||
web3Redundant: web3HomeRedundant
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,15 @@
|
|||||||
"amqplib": "^0.5.2",
|
"amqplib": "^0.5.2",
|
||||||
"bignumber.js": "^7.2.1",
|
"bignumber.js": "^7.2.1",
|
||||||
"dotenv": "^5.0.1",
|
"dotenv": "^5.0.1",
|
||||||
|
"http-list-provider": "0.0.5",
|
||||||
"ioredis": "^3.2.2",
|
"ioredis": "^3.2.2",
|
||||||
"node-fetch": "^2.1.2",
|
"node-fetch": "^2.1.2",
|
||||||
"pino": "^4.17.3",
|
"pino": "^4.17.3",
|
||||||
"pino-pretty": "^2.0.1",
|
"pino-pretty": "^2.0.1",
|
||||||
"promise-limit": "^2.7.0",
|
"promise-limit": "^2.7.0",
|
||||||
"promise-retry": "^1.1.1",
|
"promise-retry": "^1.1.1",
|
||||||
"web3": "^1.3.0"
|
"web3": "1.0.0-beta.34",
|
||||||
|
"web3-utils": "1.0.0-beta.34"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bn-chai": "^1.0.1",
|
"bn-chai": "^1.0.1",
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
require('../../env')
|
require('../../env')
|
||||||
const { toWei } = require('web3').utils
|
const Web3 = require('web3')
|
||||||
const { web3Foreign } = require('../../src/services/web3')
|
const Web3Utils = require('web3-utils')
|
||||||
const { sendTx } = require('../../src/tx/sendTx')
|
const rpcUrlsManager = require('../../src/services/getRpcUrlsManager')
|
||||||
|
const { sendTx, sendRawTx } = require('../../src/tx/sendTx')
|
||||||
const { ERC20_ABI } = require('../../../commons')
|
const { ERC20_ABI } = require('../../../commons')
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -16,23 +17,37 @@ const NUMBER_OF_DEPOSITS_TO_SEND = process.argv[2] || process.env.NUMBER_OF_DEPO
|
|||||||
|
|
||||||
const { FOREIGN_ERC_TO_ERC_ABI } = require('../../../commons')
|
const { FOREIGN_ERC_TO_ERC_ABI } = require('../../../commons')
|
||||||
|
|
||||||
|
const foreignRpcUrl = rpcUrlsManager.foreignUrls[0]
|
||||||
|
const foreignProvider = new Web3.providers.HttpProvider(foreignRpcUrl)
|
||||||
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const bridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const bridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
const bridgeableTokenAddress = await bridge.methods.erc20token().call()
|
const bridgeableTokenAddress = await bridge.methods.erc20token().call()
|
||||||
const poa20 = new web3Foreign.eth.Contract(ERC20_ABI, bridgeableTokenAddress)
|
const poa20 = new web3Foreign.eth.Contract(ERC20_ABI, bridgeableTokenAddress)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const foreignChainId = await web3Foreign.eth.getChainId()
|
const foreignChainId = await sendRawTx({
|
||||||
let nonce = await web3Foreign.eth.getTransactionCount(USER_ADDRESS)
|
chain: 'foreign',
|
||||||
|
params: [],
|
||||||
|
method: 'net_version'
|
||||||
|
})
|
||||||
|
let nonce = await sendRawTx({
|
||||||
|
chain: 'foreign',
|
||||||
|
method: 'eth_getTransactionCount',
|
||||||
|
params: [USER_ADDRESS, 'latest']
|
||||||
|
})
|
||||||
|
nonce = Web3Utils.hexToNumber(nonce)
|
||||||
let actualSent = 0
|
let actualSent = 0
|
||||||
for (let i = 0; i < Number(NUMBER_OF_DEPOSITS_TO_SEND); i++) {
|
for (let i = 0; i < Number(NUMBER_OF_DEPOSITS_TO_SEND); i++) {
|
||||||
const gasLimit = await poa20.methods
|
const gasLimit = await poa20.methods
|
||||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, Web3Utils.toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
||||||
.estimateGas({ from: USER_ADDRESS })
|
.estimateGas({ from: USER_ADDRESS })
|
||||||
const data = await poa20.methods
|
const data = await poa20.methods
|
||||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, Web3Utils.toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
||||||
.encodeABI({ from: USER_ADDRESS })
|
.encodeABI({ from: USER_ADDRESS })
|
||||||
const txHash = await sendTx({
|
const txHash = await sendTx({
|
||||||
|
chain: 'foreign',
|
||||||
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
||||||
data,
|
data,
|
||||||
nonce,
|
nonce,
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
require('../../env')
|
require('../../env')
|
||||||
const { toWei } = require('web3').utils
|
const Web3 = require('web3')
|
||||||
const { web3Home } = require('../../src/services/web3')
|
const Web3Utils = require('web3-utils')
|
||||||
const { sendTx } = require('../../src/tx/sendTx')
|
const rpcUrlsManager = require('../../src/services/getRpcUrlsManager')
|
||||||
|
const { sendTx, sendRawTx } = require('../../src/tx/sendTx')
|
||||||
const { isValidAmount } = require('../utils/utils')
|
const { isValidAmount } = require('../utils/utils')
|
||||||
const { HOME_ERC_TO_ERC_ABI } = require('../../../commons')
|
const { HOME_ERC_TO_ERC_ABI } = require('../../../commons')
|
||||||
|
|
||||||
@@ -45,6 +46,10 @@ const BRIDGEABLE_TOKEN_ABI = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const homeRpcUrl = rpcUrlsManager.homeUrls[0]
|
||||||
|
const homeProvider = new Web3.providers.HttpProvider(homeRpcUrl)
|
||||||
|
const web3Home = new Web3(homeProvider)
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const bridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
const bridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||||
const BRIDGEABLE_TOKEN_ADDRESS = await bridge.methods.erc677token().call()
|
const BRIDGEABLE_TOKEN_ADDRESS = await bridge.methods.erc677token().call()
|
||||||
@@ -53,17 +58,27 @@ async function main() {
|
|||||||
try {
|
try {
|
||||||
await isValidAmount(HOME_MIN_AMOUNT_PER_TX, bridge)
|
await isValidAmount(HOME_MIN_AMOUNT_PER_TX, bridge)
|
||||||
|
|
||||||
const homeChainId = await web3Home.eth.getChainId()
|
const homeChainId = await sendRawTx({
|
||||||
let nonce = await web3Home.eth.getTransactionCount(USER_ADDRESS)
|
chain: 'home',
|
||||||
|
params: [],
|
||||||
|
method: 'net_version'
|
||||||
|
})
|
||||||
|
let nonce = await sendRawTx({
|
||||||
|
chain: 'home',
|
||||||
|
method: 'eth_getTransactionCount',
|
||||||
|
params: [USER_ADDRESS, 'latest']
|
||||||
|
})
|
||||||
|
nonce = Web3Utils.hexToNumber(nonce)
|
||||||
let actualSent = 0
|
let actualSent = 0
|
||||||
for (let i = 0; i < Number(NUMBER_OF_WITHDRAWALS_TO_SEND); i++) {
|
for (let i = 0; i < Number(NUMBER_OF_WITHDRAWALS_TO_SEND); i++) {
|
||||||
const gasLimit = await erc677.methods
|
const gasLimit = await erc677.methods
|
||||||
.transferAndCall(COMMON_HOME_BRIDGE_ADDRESS, toWei(HOME_MIN_AMOUNT_PER_TX), '0x')
|
.transferAndCall(COMMON_HOME_BRIDGE_ADDRESS, Web3Utils.toWei(HOME_MIN_AMOUNT_PER_TX), '0x')
|
||||||
.estimateGas({ from: USER_ADDRESS })
|
.estimateGas({ from: USER_ADDRESS })
|
||||||
const data = await erc677.methods
|
const data = await erc677.methods
|
||||||
.transferAndCall(COMMON_HOME_BRIDGE_ADDRESS, toWei(HOME_MIN_AMOUNT_PER_TX), '0x')
|
.transferAndCall(COMMON_HOME_BRIDGE_ADDRESS, Web3Utils.toWei(HOME_MIN_AMOUNT_PER_TX), '0x')
|
||||||
.encodeABI({ from: USER_ADDRESS })
|
.encodeABI({ from: USER_ADDRESS })
|
||||||
const txHash = await sendTx({
|
const txHash = await sendTx({
|
||||||
|
chain: 'home',
|
||||||
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
||||||
data,
|
data,
|
||||||
nonce,
|
nonce,
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
require('../../env')
|
require('../../env')
|
||||||
const { toWei } = require('web3').utils
|
const Web3 = require('web3')
|
||||||
const { web3Foreign } = require('../../src/services/web3')
|
const Web3Utils = require('web3-utils')
|
||||||
const { sendTx } = require('../../src/tx/sendTx')
|
const rpcUrlsManager = require('../../src/services/getRpcUrlsManager')
|
||||||
|
const { sendTx, sendRawTx } = require('../../src/tx/sendTx')
|
||||||
|
|
||||||
const {
|
const {
|
||||||
USER_ADDRESS,
|
USER_ADDRESS,
|
||||||
@@ -15,23 +16,37 @@ const NUMBER_OF_DEPOSITS_TO_SEND = process.argv[2] || process.env.NUMBER_OF_DEPO
|
|||||||
|
|
||||||
const { ERC20_ABI, FOREIGN_ERC_TO_NATIVE_ABI } = require('../../../commons')
|
const { ERC20_ABI, FOREIGN_ERC_TO_NATIVE_ABI } = require('../../../commons')
|
||||||
|
|
||||||
|
const foreignRpcUrl = rpcUrlsManager.foreignUrls[0]
|
||||||
|
const foreignProvider = new Web3.providers.HttpProvider(foreignRpcUrl)
|
||||||
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const bridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const bridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
const bridgeableTokenAddress = await bridge.methods.erc20token().call()
|
const bridgeableTokenAddress = await bridge.methods.erc20token().call()
|
||||||
const poa20 = new web3Foreign.eth.Contract(ERC20_ABI, bridgeableTokenAddress)
|
const poa20 = new web3Foreign.eth.Contract(ERC20_ABI, bridgeableTokenAddress)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const foreignChainId = await web3Foreign.eth.getChainId()
|
const foreignChainId = await sendRawTx({
|
||||||
let nonce = await web3Foreign.eth.getTransactionCount(USER_ADDRESS)
|
chain: 'foreign',
|
||||||
|
params: [],
|
||||||
|
method: 'net_version'
|
||||||
|
})
|
||||||
|
let nonce = await sendRawTx({
|
||||||
|
chain: 'foreign',
|
||||||
|
method: 'eth_getTransactionCount',
|
||||||
|
params: [USER_ADDRESS, 'latest']
|
||||||
|
})
|
||||||
|
nonce = Web3Utils.hexToNumber(nonce)
|
||||||
let actualSent = 0
|
let actualSent = 0
|
||||||
for (let i = 0; i < Number(NUMBER_OF_DEPOSITS_TO_SEND); i++) {
|
for (let i = 0; i < Number(NUMBER_OF_DEPOSITS_TO_SEND); i++) {
|
||||||
const gasLimit = await poa20.methods
|
const gasLimit = await poa20.methods
|
||||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, Web3Utils.toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
||||||
.estimateGas({ from: USER_ADDRESS })
|
.estimateGas({ from: USER_ADDRESS })
|
||||||
const data = await poa20.methods
|
const data = await poa20.methods
|
||||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, Web3Utils.toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
||||||
.encodeABI({ from: USER_ADDRESS })
|
.encodeABI({ from: USER_ADDRESS })
|
||||||
const txHash = await sendTx({
|
const txHash = await sendTx({
|
||||||
|
chain: 'foreign',
|
||||||
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
||||||
data,
|
data,
|
||||||
nonce,
|
nonce,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
require('../../env')
|
require('../../env')
|
||||||
|
const Web3Utils = require('web3-utils')
|
||||||
const { web3Home } = require('../../src/services/web3')
|
const { web3Home } = require('../../src/services/web3')
|
||||||
const { sendTx } = require('../../src/tx/sendTx')
|
const { sendTx, sendRawTx } = require('../../src/tx/sendTx')
|
||||||
const { isValidAmount } = require('../utils/utils')
|
const { isValidAmount } = require('../utils/utils')
|
||||||
const { HOME_ERC_TO_NATIVE_ABI } = require('../../../commons')
|
const { HOME_ERC_TO_NATIVE_ABI } = require('../../../commons')
|
||||||
|
|
||||||
@@ -20,11 +21,21 @@ async function main() {
|
|||||||
try {
|
try {
|
||||||
await isValidAmount(HOME_MIN_AMOUNT_PER_TX, bridge)
|
await isValidAmount(HOME_MIN_AMOUNT_PER_TX, bridge)
|
||||||
|
|
||||||
const homeChainId = await web3Home.eth.getChainId()
|
const homeChainId = await sendRawTx({
|
||||||
let nonce = await web3Home.eth.getTransactionCount(USER_ADDRESS)
|
chain: 'home',
|
||||||
|
params: [],
|
||||||
|
method: 'net_version'
|
||||||
|
})
|
||||||
|
let nonce = await sendRawTx({
|
||||||
|
chain: 'home',
|
||||||
|
method: 'eth_getTransactionCount',
|
||||||
|
params: [USER_ADDRESS, 'latest']
|
||||||
|
})
|
||||||
|
nonce = Web3Utils.hexToNumber(nonce)
|
||||||
let actualSent = 0
|
let actualSent = 0
|
||||||
for (let i = 0; i < Number(NUMBER_OF_DEPOSITS_TO_SEND); i++) {
|
for (let i = 0; i < Number(NUMBER_OF_DEPOSITS_TO_SEND); i++) {
|
||||||
const txHash = await sendTx({
|
const txHash = await sendTx({
|
||||||
|
chain: 'home',
|
||||||
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
||||||
data: '0x',
|
data: '0x',
|
||||||
nonce,
|
nonce,
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
require('../env')
|
require('../env')
|
||||||
|
const Web3 = require('web3')
|
||||||
|
|
||||||
const { BRIDGE_VALIDATORS_ABI } = require('../../commons')
|
const { BRIDGE_VALIDATORS_ABI } = require('../../commons')
|
||||||
const { web3Home, web3Foreign } = require('../src/services/web3')
|
const rpcUrlsManager = require('../src/services/getRpcUrlsManager')
|
||||||
const { bridgeConfig } = require('../config/base.config')
|
const { bridgeConfig } = require('../config/base.config')
|
||||||
|
|
||||||
const homeABI = bridgeConfig.homeBridgeAbi
|
const homeABI = bridgeConfig.homeBridgeAbi
|
||||||
const foreignABI = bridgeConfig.foreignBridgeAbi
|
const foreignABI = bridgeConfig.foreignBridgeAbi
|
||||||
|
|
||||||
async function getStartBlock(web3, bridgeAddress, bridgeAbi) {
|
async function getStartBlock(rpcUrl, bridgeAddress, bridgeAbi) {
|
||||||
try {
|
try {
|
||||||
const bridgeContract = new web3.eth.Contract(bridgeAbi, bridgeAddress)
|
const web3Provider = new Web3.providers.HttpProvider(rpcUrl)
|
||||||
|
const web3Instance = new Web3(web3Provider)
|
||||||
|
const bridgeContract = new web3Instance.eth.Contract(bridgeAbi, bridgeAddress)
|
||||||
|
|
||||||
const deployedAtBlock = await bridgeContract.methods.deployedAtBlock().call()
|
const deployedAtBlock = await bridgeContract.methods.deployedAtBlock().call()
|
||||||
|
|
||||||
const validatorContractAddress = await bridgeContract.methods.validatorContract().call()
|
const validatorContractAddress = await bridgeContract.methods.validatorContract().call()
|
||||||
const validatorContract = new web3.eth.Contract(BRIDGE_VALIDATORS_ABI, validatorContractAddress)
|
const validatorContract = new web3Instance.eth.Contract(BRIDGE_VALIDATORS_ABI, validatorContractAddress)
|
||||||
|
|
||||||
const validatorDeployedAtBlock = await validatorContract.methods.deployedAtBlock().call()
|
const validatorDeployedAtBlock = await validatorContract.methods.deployedAtBlock().call()
|
||||||
|
|
||||||
@@ -32,8 +35,10 @@ async function getStartBlock(web3, bridgeAddress, bridgeAbi) {
|
|||||||
async function main() {
|
async function main() {
|
||||||
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
||||||
|
|
||||||
const homeStartBlock = await getStartBlock(web3Home, COMMON_HOME_BRIDGE_ADDRESS, homeABI)
|
const homeRpcUrl = rpcUrlsManager.homeUrls[0]
|
||||||
const foreignStartBlock = await getStartBlock(web3Foreign, COMMON_FOREIGN_BRIDGE_ADDRESS, foreignABI)
|
const foreignRpcUrl = rpcUrlsManager.foreignUrls[0]
|
||||||
|
const homeStartBlock = await getStartBlock(homeRpcUrl, COMMON_HOME_BRIDGE_ADDRESS, homeABI)
|
||||||
|
const foreignStartBlock = await getStartBlock(foreignRpcUrl, COMMON_FOREIGN_BRIDGE_ADDRESS, foreignABI)
|
||||||
const result = {
|
const result = {
|
||||||
homeStartBlock,
|
homeStartBlock,
|
||||||
foreignStartBlock
|
foreignStartBlock
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
require('../env')
|
require('../env')
|
||||||
|
const Web3 = require('web3')
|
||||||
const { getTokensState } = require('../src/utils/tokenState')
|
const { getTokensState } = require('../src/utils/tokenState')
|
||||||
const {
|
const {
|
||||||
ERC677_BRIDGE_TOKEN_ABI,
|
ERC677_BRIDGE_TOKEN_ABI,
|
||||||
@@ -6,7 +7,6 @@ const {
|
|||||||
FOREIGN_ERC_TO_NATIVE_ABI,
|
FOREIGN_ERC_TO_NATIVE_ABI,
|
||||||
getTokenType
|
getTokenType
|
||||||
} = require('../../commons')
|
} = require('../../commons')
|
||||||
const { web3Foreign } = require('../src/services/web3')
|
|
||||||
|
|
||||||
const emptyLogger = {
|
const emptyLogger = {
|
||||||
debug: () => {},
|
debug: () => {},
|
||||||
@@ -14,25 +14,26 @@ const emptyLogger = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function initialChecks() {
|
async function initialChecks() {
|
||||||
const { ORACLE_BRIDGE_MODE, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
const { ORACLE_BRIDGE_MODE, COMMON_FOREIGN_RPC_URL, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
||||||
let result = {}
|
let result = {}
|
||||||
|
const foreignWeb3 = new Web3(new Web3.providers.HttpProvider(COMMON_FOREIGN_RPC_URL))
|
||||||
|
|
||||||
if (ORACLE_BRIDGE_MODE === 'ERC_TO_ERC') {
|
if (ORACLE_BRIDGE_MODE === 'ERC_TO_ERC') {
|
||||||
const bridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const bridge = new foreignWeb3.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
result.bridgeableTokenAddress = await bridge.methods.erc20token().call()
|
result.bridgeableTokenAddress = await bridge.methods.erc20token().call()
|
||||||
} else if (ORACLE_BRIDGE_MODE === 'ERC_TO_NATIVE') {
|
} else if (ORACLE_BRIDGE_MODE === 'ERC_TO_NATIVE') {
|
||||||
const bridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
const bridge = new foreignWeb3.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
result = await getTokensState(bridge, emptyLogger)
|
result = await getTokensState(bridge, emptyLogger)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ORACLE_BRIDGE_MODE === 'ERC_TO_ERC') {
|
if (ORACLE_BRIDGE_MODE === 'ERC_TO_ERC') {
|
||||||
const bridgeTokenContract = new web3Foreign.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, result.bridgeableTokenAddress)
|
const bridgeTokenContract = new foreignWeb3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, result.bridgeableTokenAddress)
|
||||||
result.foreignERC = await getTokenType(bridgeTokenContract, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
result.foreignERC = await getTokenType(bridgeTokenContract, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||||
}
|
}
|
||||||
console.log(JSON.stringify(result))
|
console.log(JSON.stringify(result))
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = initialChecks()
|
initialChecks()
|
||||||
|
|
||||||
module.exports = result
|
module.exports = initialChecks
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
require('../../env')
|
require('../../env')
|
||||||
const { toWei } = require('web3').utils
|
const Web3Utils = require('web3-utils')
|
||||||
const { web3Foreign } = require('../../src/services/web3')
|
const { web3Foreign } = require('../../src/services/web3')
|
||||||
const { sendTx } = require('../../src/tx/sendTx')
|
const { sendTx, sendRawTx } = require('../../src/tx/sendTx')
|
||||||
const { isValidAmount } = require('../utils/utils')
|
const { isValidAmount } = require('../utils/utils')
|
||||||
const { FOREIGN_NATIVE_TO_ERC_ABI } = require('../../../commons')
|
const { FOREIGN_NATIVE_TO_ERC_ABI } = require('../../../commons')
|
||||||
|
|
||||||
@@ -53,17 +53,27 @@ async function main() {
|
|||||||
try {
|
try {
|
||||||
await isValidAmount(FOREIGN_MIN_AMOUNT_PER_TX, bridge)
|
await isValidAmount(FOREIGN_MIN_AMOUNT_PER_TX, bridge)
|
||||||
|
|
||||||
const foreignChainId = await web3Foreign.eth.getChainId()
|
const foreignChainId = await sendRawTx({
|
||||||
let nonce = await web3Foreign.eth.getTransactionCount(USER_ADDRESS)
|
chain: 'foreign',
|
||||||
|
params: [],
|
||||||
|
method: 'net_version'
|
||||||
|
})
|
||||||
|
let nonce = await sendRawTx({
|
||||||
|
chain: 'foreign',
|
||||||
|
method: 'eth_getTransactionCount',
|
||||||
|
params: [USER_ADDRESS, 'latest']
|
||||||
|
})
|
||||||
|
nonce = Web3Utils.hexToNumber(nonce)
|
||||||
let actualSent = 0
|
let actualSent = 0
|
||||||
for (let i = 0; i < Number(NUMBER_OF_WITHDRAWALS_TO_SEND); i++) {
|
for (let i = 0; i < Number(NUMBER_OF_WITHDRAWALS_TO_SEND); i++) {
|
||||||
const gasLimit = await poa20.methods
|
const gasLimit = await poa20.methods
|
||||||
.transferAndCall(COMMON_FOREIGN_BRIDGE_ADDRESS, toWei(FOREIGN_MIN_AMOUNT_PER_TX), '0x')
|
.transferAndCall(COMMON_FOREIGN_BRIDGE_ADDRESS, Web3Utils.toWei(FOREIGN_MIN_AMOUNT_PER_TX), '0x')
|
||||||
.estimateGas({ from: USER_ADDRESS })
|
.estimateGas({ from: USER_ADDRESS })
|
||||||
const data = await poa20.methods
|
const data = await poa20.methods
|
||||||
.transferAndCall(COMMON_FOREIGN_BRIDGE_ADDRESS, toWei(FOREIGN_MIN_AMOUNT_PER_TX), '0x')
|
.transferAndCall(COMMON_FOREIGN_BRIDGE_ADDRESS, Web3Utils.toWei(FOREIGN_MIN_AMOUNT_PER_TX), '0x')
|
||||||
.encodeABI({ from: USER_ADDRESS })
|
.encodeABI({ from: USER_ADDRESS })
|
||||||
const txHash = await sendTx({
|
const txHash = await sendTx({
|
||||||
|
chain: 'foreign',
|
||||||
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
||||||
data,
|
data,
|
||||||
nonce,
|
nonce,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
require('../../env')
|
require('../../env')
|
||||||
|
const Web3Utils = require('web3-utils')
|
||||||
const { web3Home } = require('../../src/services/web3')
|
const { web3Home } = require('../../src/services/web3')
|
||||||
const { sendTx } = require('../../src/tx/sendTx')
|
const { sendTx, sendRawTx } = require('../../src/tx/sendTx')
|
||||||
const { isValidAmount } = require('../utils/utils')
|
const { isValidAmount } = require('../utils/utils')
|
||||||
const { HOME_NATIVE_TO_ERC_ABI } = require('../../../commons')
|
const { HOME_NATIVE_TO_ERC_ABI } = require('../../../commons')
|
||||||
|
|
||||||
@@ -20,11 +21,21 @@ async function main() {
|
|||||||
try {
|
try {
|
||||||
await isValidAmount(HOME_MIN_AMOUNT_PER_TX, bridge)
|
await isValidAmount(HOME_MIN_AMOUNT_PER_TX, bridge)
|
||||||
|
|
||||||
const homeChainId = await web3Home.eth.getChainId()
|
const homeChainId = await sendRawTx({
|
||||||
let nonce = await web3Home.eth.getTransactionCount(USER_ADDRESS)
|
chain: 'home',
|
||||||
|
params: [],
|
||||||
|
method: 'net_version'
|
||||||
|
})
|
||||||
|
let nonce = await sendRawTx({
|
||||||
|
chain: 'home',
|
||||||
|
method: 'eth_getTransactionCount',
|
||||||
|
params: [USER_ADDRESS, 'latest']
|
||||||
|
})
|
||||||
|
nonce = Web3Utils.hexToNumber(nonce)
|
||||||
let actualSent = 0
|
let actualSent = 0
|
||||||
for (let i = 0; i < Number(NUMBER_OF_DEPOSITS_TO_SEND); i++) {
|
for (let i = 0; i < Number(NUMBER_OF_DEPOSITS_TO_SEND); i++) {
|
||||||
const txHash = await sendTx({
|
const txHash = await sendTx({
|
||||||
|
chain: 'home',
|
||||||
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
||||||
data: '0x',
|
data: '0x',
|
||||||
nonce,
|
nonce,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
const { fromWei } = require('web3').utils
|
const Web3Utils = require('web3-utils')
|
||||||
|
|
||||||
async function getMinPerTxLimit(bridge) {
|
async function getMinPerTxLimit(bridge) {
|
||||||
const minPerTx = await bridge.methods.minPerTx().call()
|
const minPerTx = await bridge.methods.minPerTx().call()
|
||||||
return fromWei(minPerTx)
|
return Web3Utils.fromWei(minPerTx)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function isValidAmount(amount, bridge) {
|
async function isValidAmount(amount, bridge) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ const path = require('path')
|
|||||||
const { isAttached, connectWatcherToQueue, connection } = require('./services/amqpClient')
|
const { isAttached, connectWatcherToQueue, connection } = require('./services/amqpClient')
|
||||||
const logger = require('./services/logger')
|
const logger = require('./services/logger')
|
||||||
const GasPrice = require('./services/gasPrice')
|
const GasPrice = require('./services/gasPrice')
|
||||||
|
const rpcUrlsManager = require('./services/getRpcUrlsManager')
|
||||||
const { getNonce, getChainId, getEventsFromTx } = require('./tx/web3')
|
const { getNonce, getChainId, getEventsFromTx } = require('./tx/web3')
|
||||||
const { sendTx } = require('./tx/sendTx')
|
const { sendTx } = require('./tx/sendTx')
|
||||||
const { checkHTTPS, watchdog, syncForEach, addExtraGas } = require('./utils/utils')
|
const { checkHTTPS, watchdog, syncForEach, addExtraGas } = require('./utils/utils')
|
||||||
@@ -36,7 +37,8 @@ async function initialize() {
|
|||||||
try {
|
try {
|
||||||
const checkHttps = checkHTTPS(ORACLE_ALLOW_HTTP_FOR_RPC, logger)
|
const checkHttps = checkHTTPS(ORACLE_ALLOW_HTTP_FOR_RPC, logger)
|
||||||
|
|
||||||
web3Instance.currentProvider.urls.forEach(checkHttps(config.chain))
|
rpcUrlsManager.homeUrls.forEach(checkHttps('home'))
|
||||||
|
rpcUrlsManager.foreignUrls.forEach(checkHttps('foreign'))
|
||||||
|
|
||||||
attached = await isAttached()
|
attached = await isAttached()
|
||||||
if (attached) {
|
if (attached) {
|
||||||
@@ -137,7 +139,7 @@ async function main({ sendJob, txHash }) {
|
|||||||
|
|
||||||
async function sendJobTx(jobs) {
|
async function sendJobTx(jobs) {
|
||||||
const gasPrice = await GasPrice.start(config.chain, true)
|
const gasPrice = await GasPrice.start(config.chain, true)
|
||||||
const chainId = await getChainId(web3Instance)
|
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 => {
|
||||||
@@ -151,6 +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.chain,
|
||||||
data: job.data,
|
data: job.data,
|
||||||
nonce,
|
nonce,
|
||||||
gasPrice: gasPrice.toString(10),
|
gasPrice: gasPrice.toString(10),
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors')
|
const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors')
|
||||||
const logger = require('../../services/logger').child({
|
const logger = require('../../services/logger').child({
|
||||||
module: 'processAffirmationRequests:estimateGas'
|
module: 'processAffirmationRequests:estimateGas'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const promiseLimit = require('promise-limit')
|
const promiseLimit = require('promise-limit')
|
||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
|
||||||
const rootLogger = require('../../services/logger')
|
const rootLogger = require('../../services/logger')
|
||||||
const { web3Home } = require('../../services/web3')
|
const { web3Home } = require('../../services/web3')
|
||||||
const bridgeValidatorsABI = require('../../../../contracts/build/contracts/BridgeValidators').abi
|
const bridgeValidatorsABI = require('../../../../contracts/build/contracts/BridgeValidators').abi
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors')
|
const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors')
|
||||||
const logger = require('../../services/logger').child({
|
const logger = require('../../services/logger').child({
|
||||||
module: 'processCollectedSignatures:estimateGas'
|
module: 'processCollectedSignatures:estimateGas'
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const promiseLimit = require('promise-limit')
|
const promiseLimit = require('promise-limit')
|
||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const bridgeValidatorsABI = require('../../../../contracts/build/contracts/BridgeValidators').abi
|
const bridgeValidatorsABI = require('../../../../contracts/build/contracts/BridgeValidators').abi
|
||||||
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 } = require('../../utils/message')
|
||||||
const { readAccessListFile } = require('../../utils/utils')
|
|
||||||
const { parseAMBMessage } = require('../../../../commons')
|
const { parseAMBMessage } = require('../../../../commons')
|
||||||
const estimateGas = require('./estimateGas')
|
const estimateGas = require('./estimateGas')
|
||||||
const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors')
|
const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors')
|
||||||
@@ -13,11 +12,7 @@ const { MAX_CONCURRENT_EVENTS, EXTRA_GAS_ABSOLUTE } = require('../../utils/const
|
|||||||
|
|
||||||
const limit = promiseLimit(MAX_CONCURRENT_EVENTS)
|
const limit = promiseLimit(MAX_CONCURRENT_EVENTS)
|
||||||
|
|
||||||
const {
|
const { ORACLE_ALWAYS_RELAY_SIGNATURES } = process.env
|
||||||
ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST,
|
|
||||||
ORACLE_HOME_TO_FOREIGN_BLOCK_LIST,
|
|
||||||
ORACLE_ALWAYS_RELAY_SIGNATURES
|
|
||||||
} = process.env
|
|
||||||
|
|
||||||
let validatorContract = null
|
let validatorContract = null
|
||||||
|
|
||||||
@@ -55,41 +50,6 @@ 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()
|
||||||
const parsedMessage = parseAMBMessage(message)
|
|
||||||
|
|
||||||
if (ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST || ORACLE_HOME_TO_FOREIGN_BLOCK_LIST) {
|
|
||||||
const sender = parsedMessage.sender.toLowerCase()
|
|
||||||
const executor = parsedMessage.executor.toLowerCase()
|
|
||||||
|
|
||||||
if (ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST) {
|
|
||||||
const allowanceList = await readAccessListFile(ORACLE_HOME_TO_FOREIGN_ALLOWANCE_LIST, logger)
|
|
||||||
if (!allowanceList.includes(executor) && !allowanceList.includes(sender)) {
|
|
||||||
logger.info(
|
|
||||||
{ sender, executor },
|
|
||||||
'Validator skips a message. Neither sender nor executor addresses are 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.includes(executor)) {
|
|
||||||
logger.info({ executor }, 'Validator skips a message. Executor address is in the block list.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (blockList.includes(sender)) {
|
|
||||||
logger.info({ sender }, 'Validator skips a message. Sender address is in the block list.')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parsedMessage.decodedDataType.manualLane) {
|
|
||||||
logger.info(
|
|
||||||
{ dataType: parsedMessage.dataType },
|
|
||||||
'Validator skips a message. Message was forwarded to the manual lane by the extension'
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.debug({ NumberOfCollectedSignatures }, 'Number of signatures to get')
|
logger.debug({ NumberOfCollectedSignatures }, 'Number of signatures to get')
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
require('dotenv').config()
|
require('dotenv').config()
|
||||||
const promiseLimit = require('promise-limit')
|
const promiseLimit = require('promise-limit')
|
||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const bridgeValidatorsABI = require('../../../../contracts/build/contracts/BridgeValidators').abi
|
const bridgeValidatorsABI = require('../../../../contracts/build/contracts/BridgeValidators').abi
|
||||||
const rootLogger = require('../../services/logger')
|
const rootLogger = require('../../services/logger')
|
||||||
const { web3Home } = require('../../services/web3')
|
const { web3Home } = require('../../services/web3')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors')
|
const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors')
|
||||||
const logger = require('../../services/logger').child({
|
const logger = require('../../services/logger').child({
|
||||||
module: 'processAffirmationRequests:estimateGas'
|
module: 'processAffirmationRequests:estimateGas'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
require('../../../env')
|
require('../../../env')
|
||||||
const promiseLimit = require('promise-limit')
|
const promiseLimit = require('promise-limit')
|
||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const rootLogger = require('../../services/logger')
|
const rootLogger = require('../../services/logger')
|
||||||
const { web3Home } = require('../../services/web3')
|
const { web3Home } = require('../../services/web3')
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors')
|
const { AlreadyProcessedError, IncompatibleContractError, InvalidValidatorError } = require('../../utils/errors')
|
||||||
const { parseMessage } = require('../../utils/message')
|
const { parseMessage } = require('../../utils/message')
|
||||||
const logger = require('../../services/logger').child({
|
const logger = require('../../services/logger').child({
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
require('../../../env')
|
require('../../../env')
|
||||||
const promiseLimit = require('promise-limit')
|
const promiseLimit = require('promise-limit')
|
||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
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')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors')
|
const { AlreadyProcessedError, AlreadySignedError, InvalidValidatorError } = require('../../utils/errors')
|
||||||
const logger = require('../../services/logger').child({
|
const logger = require('../../services/logger').child({
|
||||||
module: 'processSignatureRequests:estimateGas'
|
module: 'processSignatureRequests:estimateGas'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
require('../../../env')
|
require('../../../env')
|
||||||
const promiseLimit = require('promise-limit')
|
const promiseLimit = require('promise-limit')
|
||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
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 } = require('../../services/web3')
|
const { web3Home } = require('../../services/web3')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
require('../../../env')
|
require('../../../env')
|
||||||
const promiseLimit = require('promise-limit')
|
const promiseLimit = require('promise-limit')
|
||||||
const { HttpListProviderError } = require('../../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const { BRIDGE_VALIDATORS_ABI, ZERO_ADDRESS } = require('../../../../commons')
|
const { BRIDGE_VALIDATORS_ABI, ZERO_ADDRESS } = require('../../../../commons')
|
||||||
const rootLogger = require('../../services/logger')
|
const rootLogger = require('../../services/logger')
|
||||||
const { web3Home, web3Foreign } = require('../../services/web3')
|
const { web3Home, web3Foreign } = require('../../services/web3')
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const { connectSenderToQueue } = require('./services/amqpClient')
|
|||||||
const { redis } = require('./services/redisClient')
|
const { redis } = require('./services/redisClient')
|
||||||
const GasPrice = require('./services/gasPrice')
|
const GasPrice = require('./services/gasPrice')
|
||||||
const logger = require('./services/logger')
|
const logger = require('./services/logger')
|
||||||
|
const rpcUrlsManager = require('./services/getRpcUrlsManager')
|
||||||
const { sendTx } = require('./tx/sendTx')
|
const { sendTx } = require('./tx/sendTx')
|
||||||
const { getNonce, getChainId } = require('./tx/web3')
|
const { getNonce, getChainId } = require('./tx/web3')
|
||||||
const {
|
const {
|
||||||
@@ -17,7 +18,7 @@ const {
|
|||||||
} = require('./utils/utils')
|
} = require('./utils/utils')
|
||||||
const { EXIT_CODES, EXTRA_GAS_PERCENTAGE, MAX_GAS_LIMIT } = require('./utils/constants')
|
const { EXIT_CODES, EXTRA_GAS_PERCENTAGE, MAX_GAS_LIMIT } = require('./utils/constants')
|
||||||
|
|
||||||
const { ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY, ORACLE_TX_REDUNDANCY } = process.env
|
const { ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY } = process.env
|
||||||
|
|
||||||
const ORACLE_VALIDATOR_ADDRESS = privateKeyToAddress(ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY)
|
const ORACLE_VALIDATOR_ADDRESS = privateKeyToAddress(ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY)
|
||||||
|
|
||||||
@@ -29,7 +30,6 @@ if (process.argv.length < 3) {
|
|||||||
const config = require(path.join('../config/', process.argv[2]))
|
const config = require(path.join('../config/', process.argv[2]))
|
||||||
|
|
||||||
const web3Instance = config.web3
|
const web3Instance = config.web3
|
||||||
const web3Redundant = ORACLE_TX_REDUNDANCY === 'true' ? config.web3Redundant : config.web3
|
|
||||||
const nonceKey = `${config.id}:nonce`
|
const nonceKey = `${config.id}:nonce`
|
||||||
let chainId = 0
|
let chainId = 0
|
||||||
|
|
||||||
@@ -37,11 +37,12 @@ async function initialize() {
|
|||||||
try {
|
try {
|
||||||
const checkHttps = checkHTTPS(process.env.ORACLE_ALLOW_HTTP_FOR_RPC, logger)
|
const checkHttps = checkHTTPS(process.env.ORACLE_ALLOW_HTTP_FOR_RPC, logger)
|
||||||
|
|
||||||
web3Instance.currentProvider.urls.forEach(checkHttps(config.chain))
|
rpcUrlsManager.homeUrls.forEach(checkHttps('home'))
|
||||||
|
rpcUrlsManager.foreignUrls.forEach(checkHttps('foreign'))
|
||||||
|
|
||||||
GasPrice.start(config.id)
|
GasPrice.start(config.id)
|
||||||
|
|
||||||
chainId = await getChainId(web3Instance)
|
chainId = await getChainId(config.id)
|
||||||
connectSenderToQueue({
|
connectSenderToQueue({
|
||||||
queueName: config.queue,
|
queueName: config.queue,
|
||||||
oldQueueName: config.oldQueue,
|
oldQueueName: config.oldQueue,
|
||||||
@@ -79,17 +80,13 @@ 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.warn("Nonce wasn't found in the DB")
|
logger.debug("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) {
|
||||||
if (typeof nonce !== 'number') {
|
return redis.set(nonceKey, nonce)
|
||||||
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, scheduleTransactionResend }) {
|
async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleTransactionResend }) {
|
||||||
@@ -101,13 +98,13 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleT
|
|||||||
|
|
||||||
const txArray = JSON.parse(msg.content)
|
const txArray = JSON.parse(msg.content)
|
||||||
logger.debug(`Msg received with ${txArray.length} Tx to send`)
|
logger.debug(`Msg received with ${txArray.length} Tx to send`)
|
||||||
const gasPrice = GasPrice.getPrice().toString(10)
|
const gasPrice = GasPrice.getPrice()
|
||||||
|
|
||||||
let nonce
|
let nonce
|
||||||
let insufficientFunds = false
|
let insufficientFunds = false
|
||||||
let minimumBalance = null
|
let minimumBalance = null
|
||||||
const failedTx = []
|
const failedTx = []
|
||||||
const resendJobs = []
|
const sentTx = []
|
||||||
|
|
||||||
const isResend = txArray.length > 0 && !!txArray[0].txHash
|
const isResend = txArray.length > 0 && !!txArray[0].txHash
|
||||||
|
|
||||||
@@ -139,31 +136,30 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleT
|
|||||||
nonce = await readNonce(true)
|
nonce = await readNonce(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`Transaction ${job.txHash} was not mined, updating gasPrice: ${job.gasPrice} -> ${gasPrice}`)
|
logger.info(
|
||||||
|
`Transaction ${job.txHash} was not mined, updating gasPrice: ${job.gasPrice} -> ${gasPrice.toString(10)}`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
logger.info(`Sending transaction with nonce ${nonce}`)
|
logger.info(`Sending transaction with nonce ${nonce}`)
|
||||||
const txHash = await sendTx({
|
job.gasPrice = gasPrice.toString(10)
|
||||||
|
job.txHash = await sendTx({
|
||||||
|
chain: config.id,
|
||||||
data: job.data,
|
data: job.data,
|
||||||
nonce,
|
nonce,
|
||||||
gasPrice,
|
gasPrice: job.gasPrice,
|
||||||
amount: '0',
|
amount: '0',
|
||||||
gasLimit,
|
gasLimit,
|
||||||
privateKey: ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY,
|
privateKey: ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY,
|
||||||
to: job.to,
|
to: job.to,
|
||||||
chainId,
|
chainId,
|
||||||
web3: web3Redundant
|
web3: web3Instance
|
||||||
})
|
})
|
||||||
const resendJob = {
|
sentTx.push(job)
|
||||||
...job,
|
|
||||||
txHash,
|
|
||||||
gasPrice
|
|
||||||
}
|
|
||||||
resendJobs.push(resendJob)
|
|
||||||
|
|
||||||
nonce++
|
nonce++
|
||||||
logger.info(
|
logger.info(
|
||||||
{ eventTransactionHash: job.transactionReference, generatedTransactionHash: txHash },
|
{ eventTransactionHash: job.transactionReference, generatedTransactionHash: job.txHash },
|
||||||
`Tx generated ${txHash} for event Tx ${job.transactionReference}`
|
`Tx generated ${job.txHash} for event Tx ${job.transactionReference}`
|
||||||
)
|
)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(
|
logger.error(
|
||||||
@@ -172,11 +168,7 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleT
|
|||||||
e.message
|
e.message
|
||||||
)
|
)
|
||||||
if (!e.message.toLowerCase().includes('transaction with the same hash was already imported')) {
|
if (!e.message.toLowerCase().includes('transaction with the same hash was already imported')) {
|
||||||
if (isResend) {
|
failedTx.push(job)
|
||||||
resendJobs.push(job)
|
|
||||||
} else {
|
|
||||||
failedTx.push(job)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.message.toLowerCase().includes('insufficient funds')) {
|
if (e.message.toLowerCase().includes('insufficient funds')) {
|
||||||
@@ -192,18 +184,16 @@ async function main({ msg, ackMsg, nackMsg, channel, scheduleForRetry, scheduleT
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
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) {
|
if (sentTx.length) {
|
||||||
logger.info(`Sending ${resendJobs.length} Tx Delayed Resend Requests to Queue`)
|
logger.info(`Sending ${sentTx.length} Tx Delayed Resend Requests to Queue`)
|
||||||
await scheduleTransactionResend(resendJobs)
|
await scheduleTransactionResend(sentTx)
|
||||||
}
|
}
|
||||||
ackMsg(msg)
|
ackMsg(msg)
|
||||||
logger.debug(`Finished processing msg`)
|
logger.debug(`Finished processing msg`)
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
const fetch = require('node-fetch')
|
|
||||||
const promiseRetry = require('promise-retry')
|
|
||||||
|
|
||||||
const defaultOptions = {
|
|
||||||
requestTimeout: 0,
|
|
||||||
retry: {
|
|
||||||
retries: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class HttpListProviderError extends Error {
|
|
||||||
constructor(message, errors) {
|
|
||||||
super(message)
|
|
||||||
this.errors = errors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function HttpListProvider(urls, options = {}) {
|
|
||||||
if (!(this instanceof HttpListProvider)) {
|
|
||||||
return new HttpListProvider(urls)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!urls || !urls.length) {
|
|
||||||
throw new TypeError(`Invalid URLs: '${urls}'`)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.urls = urls
|
|
||||||
this.options = { ...defaultOptions, ...options }
|
|
||||||
this.currentIndex = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpListProvider.prototype.send = async function send(payload, callback) {
|
|
||||||
// save the currentIndex to avoid race condition
|
|
||||||
const { currentIndex } = this
|
|
||||||
|
|
||||||
try {
|
|
||||||
const [result, index] = await promiseRetry(retry => {
|
|
||||||
return trySend(payload, this.urls, currentIndex, this.options).catch(retry)
|
|
||||||
}, this.options.retry)
|
|
||||||
this.currentIndex = index
|
|
||||||
callback(null, result)
|
|
||||||
} catch (e) {
|
|
||||||
callback(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function send(url, payload, options) {
|
|
||||||
return fetch(url, {
|
|
||||||
headers: {
|
|
||||||
'Content-type': 'application/json'
|
|
||||||
},
|
|
||||||
method: 'POST',
|
|
||||||
body: JSON.stringify(payload),
|
|
||||||
timeout: options.requestTimeout
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
if (response.ok) {
|
|
||||||
return response
|
|
||||||
} else {
|
|
||||||
throw new Error(response.statusText)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
}
|
|
||||||
|
|
||||||
async function trySend(payload, urls, initialIndex, options) {
|
|
||||||
const errors = []
|
|
||||||
|
|
||||||
let index = initialIndex
|
|
||||||
for (let count = 0; count < urls.length; count++) {
|
|
||||||
const url = urls[index]
|
|
||||||
try {
|
|
||||||
const result = await send(url, payload, options)
|
|
||||||
return [result, index]
|
|
||||||
} catch (e) {
|
|
||||||
errors.push(e)
|
|
||||||
}
|
|
||||||
index = (index + 1) % urls.length
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new HttpListProviderError('Request failed for all urls', errors)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
HttpListProvider,
|
|
||||||
HttpListProviderError,
|
|
||||||
defaultOptions,
|
|
||||||
send
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
const promiseRetry = require('promise-retry')
|
|
||||||
const { promiseAny } = require('../utils/utils')
|
|
||||||
const { defaultOptions, HttpListProviderError, send } = require('./HttpListProvider')
|
|
||||||
|
|
||||||
function RedundantHttpListProvider(urls, options = {}) {
|
|
||||||
if (!(this instanceof RedundantHttpListProvider)) {
|
|
||||||
return new RedundantHttpListProvider(urls)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!urls || !urls.length) {
|
|
||||||
throw new TypeError(`Invalid URLs: '${urls}'`)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.urls = urls
|
|
||||||
this.options = { ...defaultOptions, ...options }
|
|
||||||
this.currentIndex = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
RedundantHttpListProvider.prototype.send = async function send(payload, callback) {
|
|
||||||
try {
|
|
||||||
const result = await promiseRetry(retry => {
|
|
||||||
return trySend(payload, this.urls, this.options).catch(retry)
|
|
||||||
}, this.options.retry)
|
|
||||||
callback(null, result)
|
|
||||||
} catch (e) {
|
|
||||||
callback(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function trySend(payload, urls, options) {
|
|
||||||
try {
|
|
||||||
return await promiseAny(urls.map(url => send(url, payload, options)))
|
|
||||||
} catch (errors) {
|
|
||||||
throw new HttpListProviderError('Request failed for all urls', errors)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
RedundantHttpListProvider
|
|
||||||
}
|
|
||||||
50
oracle/src/services/RpcUrlsManager.js
Normal file
50
oracle/src/services/RpcUrlsManager.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
const promiseRetry = require('promise-retry')
|
||||||
|
const tryEach = require('../utils/tryEach')
|
||||||
|
const { RETRY_CONFIG } = require('../utils/constants')
|
||||||
|
const { promiseAny } = require('../utils/utils')
|
||||||
|
|
||||||
|
function RpcUrlsManager(homeUrls, foreignUrls) {
|
||||||
|
if (!homeUrls) {
|
||||||
|
throw new Error(`Invalid homeUrls: '${homeUrls}'`)
|
||||||
|
}
|
||||||
|
if (!foreignUrls) {
|
||||||
|
throw new Error(`Invalid foreignUrls: '${foreignUrls}'`)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.homeUrls = homeUrls.split(' ')
|
||||||
|
this.foreignUrls = foreignUrls.split(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
RpcUrlsManager.prototype.tryEach = async function(chain, f, redundant = false) {
|
||||||
|
if (chain !== 'home' && chain !== 'foreign') {
|
||||||
|
throw new Error(`Invalid argument chain: '${chain}'`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// save urls to avoid race condition
|
||||||
|
const urls = chain === 'home' ? [...this.homeUrls] : [...this.foreignUrls]
|
||||||
|
|
||||||
|
if (redundant) {
|
||||||
|
// result from first responded node will be returned immediately
|
||||||
|
// remaining nodes will continue to retry queries in separate promises
|
||||||
|
// promiseAny will throw only if all urls reached max retry number
|
||||||
|
return promiseAny(urls.map(url => promiseRetry(retry => f(url).catch(retry), RETRY_CONFIG)))
|
||||||
|
}
|
||||||
|
|
||||||
|
const [result, index] = await promiseRetry(retry => tryEach(urls, f).catch(retry), RETRY_CONFIG)
|
||||||
|
|
||||||
|
if (index > 0) {
|
||||||
|
// rotate urls
|
||||||
|
const failed = urls.splice(0, index)
|
||||||
|
urls.push(...failed)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chain === 'home') {
|
||||||
|
this.homeUrls = urls
|
||||||
|
} else {
|
||||||
|
this.foreignUrls = urls
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = RpcUrlsManager
|
||||||
3
oracle/src/services/getRpcUrlsManager.js
Normal file
3
oracle/src/services/getRpcUrlsManager.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
const RpcUrlsManager = require('./RpcUrlsManager')
|
||||||
|
|
||||||
|
module.exports = new RpcUrlsManager(process.env.COMMON_HOME_RPC_URL, process.env.COMMON_FOREIGN_RPC_URL)
|
||||||
@@ -1,55 +1,19 @@
|
|||||||
|
const HttpListProvider = require('http-list-provider')
|
||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
const { HttpListProvider } = require('./HttpListProvider')
|
const rpcUrlsManager = require('./getRpcUrlsManager')
|
||||||
const { RedundantHttpListProvider } = require('./RedundantHttpListProvider')
|
|
||||||
const { RETRY_CONFIG } = require('../utils/constants')
|
const { RETRY_CONFIG } = require('../utils/constants')
|
||||||
|
|
||||||
const {
|
const homeProvider = new HttpListProvider(rpcUrlsManager.homeUrls, {
|
||||||
COMMON_HOME_RPC_URL,
|
|
||||||
COMMON_FOREIGN_RPC_URL,
|
|
||||||
ORACLE_RPC_REQUEST_TIMEOUT,
|
|
||||||
ORACLE_HOME_RPC_POLLING_INTERVAL,
|
|
||||||
ORACLE_FOREIGN_RPC_POLLING_INTERVAL
|
|
||||||
} = process.env
|
|
||||||
|
|
||||||
if (!COMMON_HOME_RPC_URL) {
|
|
||||||
throw new Error(`Invalid homeUrls: '${COMMON_HOME_RPC_URL}'`)
|
|
||||||
}
|
|
||||||
if (!COMMON_FOREIGN_RPC_URL) {
|
|
||||||
throw new Error(`Invalid foreignUrls: '${COMMON_FOREIGN_RPC_URL}'`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const homeUrls = COMMON_HOME_RPC_URL.split(' ').filter(url => url.length > 0)
|
|
||||||
const foreignUrls = COMMON_FOREIGN_RPC_URL.split(' ').filter(url => url.length > 0)
|
|
||||||
|
|
||||||
const homeDefaultTimeout = parseInt(ORACLE_HOME_RPC_POLLING_INTERVAL, 10) * 2
|
|
||||||
const foreignDefaultTimeout = parseInt(ORACLE_FOREIGN_RPC_POLLING_INTERVAL, 10) * 2
|
|
||||||
const configuredTimeout = parseInt(ORACLE_RPC_REQUEST_TIMEOUT, 10)
|
|
||||||
|
|
||||||
const homeOptions = {
|
|
||||||
requestTimeout: configuredTimeout || homeDefaultTimeout,
|
|
||||||
retry: RETRY_CONFIG
|
retry: RETRY_CONFIG
|
||||||
}
|
})
|
||||||
|
|
||||||
const foreignOptions = {
|
|
||||||
requestTimeout: configuredTimeout || foreignDefaultTimeout,
|
|
||||||
retry: RETRY_CONFIG
|
|
||||||
}
|
|
||||||
|
|
||||||
const homeProvider = new HttpListProvider(homeUrls, homeOptions)
|
|
||||||
const web3Home = new Web3(homeProvider)
|
const web3Home = new Web3(homeProvider)
|
||||||
|
|
||||||
const foreignProvider = new HttpListProvider(foreignUrls, foreignOptions)
|
const foreignProvider = new HttpListProvider(rpcUrlsManager.foreignUrls, {
|
||||||
|
retry: RETRY_CONFIG
|
||||||
|
})
|
||||||
const web3Foreign = new Web3(foreignProvider)
|
const web3Foreign = new Web3(foreignProvider)
|
||||||
|
|
||||||
const redundantHomeProvider = new RedundantHttpListProvider(homeUrls, homeOptions)
|
|
||||||
const web3HomeRedundant = new Web3(redundantHomeProvider)
|
|
||||||
|
|
||||||
const redundantForeignProvider = new RedundantHttpListProvider(foreignUrls, foreignOptions)
|
|
||||||
const web3ForeignRedundant = new Web3(redundantForeignProvider)
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
web3Home,
|
web3Home,
|
||||||
web3Foreign,
|
web3Foreign
|
||||||
web3HomeRedundant,
|
|
||||||
web3ForeignRedundant
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,67 @@
|
|||||||
const { toWei } = require('web3').utils
|
const Web3Utils = require('web3-utils')
|
||||||
|
const fetch = require('node-fetch')
|
||||||
|
const rpcUrlsManager = require('../services/getRpcUrlsManager')
|
||||||
|
|
||||||
async function sendTx({ privateKey, data, nonce, gasPrice, amount, gasLimit, to, chainId, web3 }) {
|
const { ORACLE_TX_REDUNDANCY } = process.env
|
||||||
|
|
||||||
|
// eslint-disable-next-line consistent-return
|
||||||
|
async function sendTx({ chain, privateKey, data, nonce, gasPrice, amount, gasLimit, to, chainId, web3 }) {
|
||||||
const serializedTx = await web3.eth.accounts.signTransaction(
|
const serializedTx = await web3.eth.accounts.signTransaction(
|
||||||
{
|
{
|
||||||
nonce: Number(nonce),
|
nonce: Number(nonce),
|
||||||
chainId,
|
chainId,
|
||||||
to,
|
to,
|
||||||
data,
|
data,
|
||||||
value: toWei(amount),
|
value: Web3Utils.toWei(amount),
|
||||||
gasPrice,
|
gasPrice,
|
||||||
gas: gasLimit
|
gas: gasLimit
|
||||||
},
|
},
|
||||||
`0x${privateKey}`
|
`0x${privateKey}`
|
||||||
)
|
)
|
||||||
|
|
||||||
return new Promise((res, rej) =>
|
return sendRawTx({
|
||||||
web3.eth
|
chain,
|
||||||
.sendSignedTransaction(serializedTx.rawTransaction)
|
method: 'eth_sendRawTransaction',
|
||||||
.once('transactionHash', res)
|
params: [serializedTx.rawTransaction]
|
||||||
.once('error', rej)
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line consistent-return
|
||||||
|
async function sendRawTx({ chain, params, method }) {
|
||||||
|
const result = await rpcUrlsManager.tryEach(
|
||||||
|
chain,
|
||||||
|
async url => {
|
||||||
|
// curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":[{see above}],"id":1}'
|
||||||
|
const response = await fetch(url, {
|
||||||
|
headers: {
|
||||||
|
'Content-type': 'application/json'
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
id: Math.floor(Math.random() * 100) + 1
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(response.statusText)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response
|
||||||
|
},
|
||||||
|
ORACLE_TX_REDUNDANCY === 'true' && method === 'eth_sendRawTransaction'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const json = await result.json()
|
||||||
|
if (json.error) {
|
||||||
|
throw json.error
|
||||||
|
}
|
||||||
|
return json.result
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sendTx
|
sendTx,
|
||||||
|
sendRawTx
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
const { hexToNumber } = require('web3-utils')
|
||||||
const logger = require('../services/logger').child({
|
const logger = require('../services/logger').child({
|
||||||
module: 'web3'
|
module: 'web3'
|
||||||
})
|
})
|
||||||
|
const { sendRawTx } = require('./sendTx')
|
||||||
|
|
||||||
async function getNonce(web3, address) {
|
async function getNonce(web3, address) {
|
||||||
try {
|
try {
|
||||||
@@ -24,10 +26,15 @@ async function getBlockNumber(web3) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getChainId(web3) {
|
async function getChainId(chain) {
|
||||||
try {
|
try {
|
||||||
logger.debug('Getting chain id')
|
logger.debug('Getting chain id')
|
||||||
const chainId = await web3.eth.getChainId()
|
const chainIdHex = await sendRawTx({
|
||||||
|
chain,
|
||||||
|
method: 'eth_chainId',
|
||||||
|
params: []
|
||||||
|
})
|
||||||
|
const chainId = hexToNumber(chainIdHex)
|
||||||
logger.debug({ chainId }, 'Chain id obtained')
|
logger.debug({ chainId }, 'Chain id obtained')
|
||||||
return chainId
|
return chainId
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
const assert = require('assert')
|
const assert = require('assert')
|
||||||
const { toHex, numberToHex, padLeft } = require('web3').utils
|
const Web3Utils = require('web3-utils')
|
||||||
const { strip0x } = require('../../../commons')
|
const { strip0x } = require('../../../commons')
|
||||||
|
|
||||||
function createMessage({ recipient, value, transactionHash, bridgeAddress, expectedMessageLength }) {
|
function createMessage({ recipient, value, transactionHash, bridgeAddress, expectedMessageLength }) {
|
||||||
recipient = strip0x(recipient)
|
recipient = strip0x(recipient)
|
||||||
assert.strictEqual(recipient.length, 20 * 2)
|
assert.strictEqual(recipient.length, 20 * 2)
|
||||||
|
|
||||||
value = numberToHex(value)
|
value = Web3Utils.numberToHex(value)
|
||||||
value = padLeft(value, 32 * 2)
|
value = Web3Utils.padLeft(value, 32 * 2)
|
||||||
|
|
||||||
value = strip0x(value)
|
value = strip0x(value)
|
||||||
assert.strictEqual(value.length, 64)
|
assert.strictEqual(value.length, 64)
|
||||||
@@ -60,7 +60,7 @@ function signatureToVRS(rawSignature) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function packSignatures(array) {
|
function packSignatures(array) {
|
||||||
const length = strip0x(toHex(array.length))
|
const length = strip0x(Web3Utils.toHex(array.length))
|
||||||
const msgLength = length.length === 1 ? `0${length}` : length
|
const msgLength = length.length === 1 ? `0${length}` : length
|
||||||
let v = ''
|
let v = ''
|
||||||
let r = ''
|
let r = ''
|
||||||
|
|||||||
@@ -118,10 +118,7 @@ async function readAccessListFile(fileName, logger) {
|
|||||||
.split('\n')
|
.split('\n')
|
||||||
.map(addr => addr.trim().toLowerCase())
|
.map(addr => addr.trim().toLowerCase())
|
||||||
.filter(addr => addr.length === 42)
|
.filter(addr => addr.length === 42)
|
||||||
logger.info(
|
logger.info({ fileName }, `Access list was read successfully, ${data.length} addresses found`)
|
||||||
{ fileName },
|
|
||||||
`Access list was read successfully, ${readAccessLists[fileName].length} addresses found`
|
|
||||||
)
|
|
||||||
logger.debug({ addresses: readAccessLists[fileName] }, `Read addresses from the file`)
|
logger.debug({ addresses: readAccessLists[fileName] }, `Read addresses from the file`)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
readAccessLists[fileName] = []
|
readAccessLists[fileName] = []
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const { connectWatcherToQueue, connection } = require('./services/amqpClient')
|
|||||||
const { getBlockNumber } = require('./tx/web3')
|
const { getBlockNumber } = require('./tx/web3')
|
||||||
const { redis } = require('./services/redisClient')
|
const { redis } = require('./services/redisClient')
|
||||||
const logger = require('./services/logger')
|
const logger = require('./services/logger')
|
||||||
|
const rpcUrlsManager = require('./services/getRpcUrlsManager')
|
||||||
const { getRequiredBlockConfirmations, getEvents } = require('./tx/web3')
|
const { getRequiredBlockConfirmations, getEvents } = require('./tx/web3')
|
||||||
const { checkHTTPS, watchdog } = require('./utils/utils')
|
const { checkHTTPS, watchdog } = require('./utils/utils')
|
||||||
const { EXIT_CODES } = require('./utils/constants')
|
const { EXIT_CODES } = require('./utils/constants')
|
||||||
@@ -41,7 +42,8 @@ async function initialize() {
|
|||||||
try {
|
try {
|
||||||
const checkHttps = checkHTTPS(process.env.ORACLE_ALLOW_HTTP_FOR_RPC, logger)
|
const checkHttps = checkHTTPS(process.env.ORACLE_ALLOW_HTTP_FOR_RPC, logger)
|
||||||
|
|
||||||
web3Instance.currentProvider.urls.forEach(checkHttps(config.chain))
|
rpcUrlsManager.homeUrls.forEach(checkHttps('home'))
|
||||||
|
rpcUrlsManager.foreignUrls.forEach(checkHttps('foreign'))
|
||||||
|
|
||||||
await getLastProcessedBlock()
|
await getLastProcessedBlock()
|
||||||
connectWatcherToQueue({
|
connectWatcherToQueue({
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const logger = require('./services/logger')
|
const logger = require('./services/logger')
|
||||||
|
const rpcUrlsManager = require('./services/getRpcUrlsManager')
|
||||||
const { checkHTTPS, watchdog } = require('./utils/utils')
|
const { checkHTTPS, watchdog } = require('./utils/utils')
|
||||||
const { EXIT_CODES } = require('./utils/constants')
|
const { EXIT_CODES } = require('./utils/constants')
|
||||||
const { connectWorkerToQueue } = require('./services/amqpClient')
|
const { connectWorkerToQueue } = require('./services/amqpClient')
|
||||||
@@ -8,13 +9,12 @@ const config = require(path.join('../config/', process.argv[2]))
|
|||||||
|
|
||||||
const convertToChai = require('./workers/convertToChai')(config)
|
const convertToChai = require('./workers/convertToChai')(config)
|
||||||
|
|
||||||
const web3Instance = config.web3
|
|
||||||
|
|
||||||
async function initialize() {
|
async function initialize() {
|
||||||
try {
|
try {
|
||||||
const checkHttps = checkHTTPS(process.env.ORACLE_ALLOW_HTTP_FOR_RPC, logger)
|
const checkHttps = checkHTTPS(process.env.ORACLE_ALLOW_HTTP_FOR_RPC, logger)
|
||||||
|
|
||||||
web3Instance.currentProvider.urls.forEach(checkHttps(config.chain))
|
rpcUrlsManager.homeUrls.forEach(checkHttps('home'))
|
||||||
|
rpcUrlsManager.foreignUrls.forEach(checkHttps('foreign'))
|
||||||
|
|
||||||
connectWorkerToQueue({
|
connectWorkerToQueue({
|
||||||
queueName: config.workerQueue,
|
queueName: config.workerQueue,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
require('../../env')
|
require('../../env')
|
||||||
const { HttpListProviderError } = require('../services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const rootLogger = require('../services/logger')
|
const rootLogger = require('../services/logger')
|
||||||
const { web3Foreign } = require('../services/web3')
|
const { web3Foreign } = require('../services/web3')
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const chai = require('chai')
|
|||||||
const chaiAsPromised = require('chai-as-promised')
|
const chaiAsPromised = require('chai-as-promised')
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
const { HttpListProviderError } = require('../src/services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const estimateGas = require('../src/events/processAffirmationRequests/estimateGas')
|
const estimateGas = require('../src/events/processAffirmationRequests/estimateGas')
|
||||||
const errors = require('../src/utils/errors')
|
const errors = require('../src/utils/errors')
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const { expect } = require('chai').use(require('chai-as-promised'))
|
const { expect } = require('chai').use(require('chai-as-promised'))
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
const { HttpListProviderError } = require('../src/services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const { createMessage, signatureToVRS } = require('../src/utils/message')
|
const { createMessage, signatureToVRS } = require('../src/utils/message')
|
||||||
const estimateGas = require('../src/events/processCollectedSignatures/estimateGas')
|
const estimateGas = require('../src/events/processCollectedSignatures/estimateGas')
|
||||||
const errors = require('../src/utils/errors')
|
const errors = require('../src/utils/errors')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const chai = require('chai')
|
|||||||
const chaiAsPromised = require('chai-as-promised')
|
const chaiAsPromised = require('chai-as-promised')
|
||||||
const sinon = require('sinon')
|
const sinon = require('sinon')
|
||||||
const Web3 = require('web3')
|
const Web3 = require('web3')
|
||||||
const { HttpListProviderError } = require('../src/services/HttpListProvider')
|
const { HttpListProviderError } = require('http-list-provider')
|
||||||
const estimateGas = require('../src/events/processSignatureRequests/estimateGas')
|
const estimateGas = require('../src/events/processSignatureRequests/estimateGas')
|
||||||
const errors = require('../src/utils/errors')
|
const errors = require('../src/utils/errors')
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
"build:ui": "yarn workspace ui run build",
|
"build:ui": "yarn workspace ui run build",
|
||||||
"build:alm": "yarn workspace alm run build",
|
"build:alm": "yarn workspace alm run build",
|
||||||
"build:plugin": "yarn workspace burner-wallet-plugin run build",
|
"build:plugin": "yarn workspace burner-wallet-plugin run build",
|
||||||
"lint": "yarn wsrun --exclude tokenbridge-contracts lint",
|
"lint": "yarn wsrun --exclude token-bridge-contracts lint",
|
||||||
"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",
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
"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",
|
||||||
"compile:contracts": "yarn workspace tokenbridge-contracts run compile",
|
"compile:contracts": "yarn workspace token-bridge-contracts run compile",
|
||||||
"install:deploy": "cd contracts/deploy && npm install --unsafe-perm --silent",
|
"install:deploy": "cd contracts/deploy && npm install --unsafe-perm --silent",
|
||||||
"postinstall": "test -n \"$NOYARNPOSTINSTALL\" || ln -sf $(pwd)/node_modules/openzeppelin-solidity/ contracts/node_modules/openzeppelin-solidity"
|
"postinstall": "test -n \"$NOYARNPOSTINSTALL\" || ln -sf $(pwd)/node_modules/openzeppelin-solidity/ contracts/node_modules/openzeppelin-solidity"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user