Merge the develop branch to the master branch, preparation to v3.0.0-rc0
This merge contains the following set of changes: * [Oracle, Improvement] Oracle watcher for AMB async calls (#509), * [Common, Other] Update the contract's submodule to the release 6.0.0-rc0 (#562)
This commit is contained in:
commit
3b959776f3
18
.github/workflows/main.yml
vendored
18
.github/workflows/main.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 10
|
||||
node-version: 12
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
@ -48,7 +48,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 10
|
||||
node-version: 12
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
@ -70,7 +70,7 @@ jobs:
|
||||
- name: Evaluate e2e docker images tags
|
||||
run: |
|
||||
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 "E2E_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e', 'e2e-commons') }}" >> $GITHUB_ENV
|
||||
echo "ORACLE_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}" >> $GITHUB_ENV
|
||||
echo "MONITOR_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}" >> $GITHUB_ENV
|
||||
echo "ALM_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}" >> $GITHUB_ENV
|
||||
@ -81,8 +81,8 @@ jobs:
|
||||
}
|
||||
updated=()
|
||||
if ! check_if_image_exists e2e ${E2E_TAG}; then updated+=("e2e"); fi
|
||||
if ! check_if_image_exists oracle ${ORACLE_TAG}; then updated+=("oracle"); fi
|
||||
if ! check_if_image_exists monitor ${MONITOR_TAG}; then updated+=("monitor"); fi
|
||||
if ! check_if_image_exists oracle ${ORACLE_TAG}; then updated+=("oracle-amb"); fi
|
||||
if ! check_if_image_exists monitor ${MONITOR_TAG}; then updated+=("monitor-amb"); fi
|
||||
if ! check_if_image_exists alm ${ALM_TAG}; then updated+=("alm"); fi
|
||||
if [ ${#updated[@]} -gt 0 ]; then
|
||||
echo "Updated services: ${updated[@]}"
|
||||
@ -133,7 +133,7 @@ jobs:
|
||||
- name: Evaluate e2e docker images tags
|
||||
run: |
|
||||
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 "E2E_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e', 'e2e-commons') }}" >> $GITHUB_ENV
|
||||
echo "ORACLE_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}" >> $GITHUB_ENV
|
||||
echo "MONITOR_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}" >> $GITHUB_ENV
|
||||
echo "ALM_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}" >> $GITHUB_ENV
|
||||
@ -176,7 +176,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
task: [amb, erc-to-erc, erc-to-native, native-to-erc]
|
||||
task: [amb, erc-to-native]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
@ -184,7 +184,7 @@ jobs:
|
||||
- name: Evaluate e2e docker images tags
|
||||
run: |
|
||||
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 "E2E_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'Dockerfile.e2e', 'commons', 'oracle-e2e', 'monitor-e2e', 'e2e-commons') }}" >> $GITHUB_ENV
|
||||
echo "ORACLE_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'oracle') }}" >> $GITHUB_ENV
|
||||
echo "MONITOR_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'monitor') }}" >> $GITHUB_ENV
|
||||
echo "ALM_TAG=${{ hashFiles('yarn.lock', 'package.json', 'submodule.status', 'commons', 'alm') }}" >> $GITHUB_ENV
|
||||
@ -202,7 +202,7 @@ jobs:
|
||||
run: ${{ steps.cache-repo.outputs.cache-hit }} && e2e-commons/up.sh deploy blocks
|
||||
- name: Pull e2e oracle image
|
||||
run: |
|
||||
docker-compose -f ./e2e-commons/docker-compose.yml pull oracle
|
||||
docker-compose -f ./e2e-commons/docker-compose.yml pull oracle-amb
|
||||
docker tag ${DOCKER_IMAGE_BASE}/tokenbridge-e2e-oracle:${ORACLE_TAG} poanetwork/tokenbridge-oracle:latest
|
||||
- name: Deploy oracle
|
||||
run: deployment-e2e/molecule.sh ultimate-${{ matrix.task }}
|
||||
|
2
.nvmrc
2
.nvmrc
@ -1 +1 @@
|
||||
10.22
|
||||
12.22
|
||||
|
@ -22,7 +22,7 @@ COMMON_FOREIGN_GAS_PRICE_FACTOR | A value that will multiply the gas price of th
|
||||
|
||||
name | description | value
|
||||
--- | --- | ---
|
||||
ORACLE_BRIDGE_MODE | The bridge mode. The bridge starts listening to a different set of events based on this parameter. | NATIVE_TO_ERC / ERC_TO_ERC / ERC_TO_NATIVE / ARBITRARY_MESSAGE
|
||||
ORACLE_BRIDGE_MODE | The bridge mode. The bridge starts listening to a different set of events based on this parameter. | ERC_TO_NATIVE / ARBITRARY_MESSAGE
|
||||
ORACLE_ALLOW_HTTP_FOR_RPC | **Only use in test environments - must be omitted in production environments.**. If this parameter is specified and set to `yes`, RPC URLs can be specified in form of HTTP links. A warning that the connection is insecure will be written to the logs. | `yes` / `no`
|
||||
ORACLE_HOME_RPC_POLLING_INTERVAL | The interval in milliseconds used to request the RPC node in the Home network for new blocks. The interval should match the average production time for a new block. | integer
|
||||
ORACLE_FOREIGN_RPC_POLLING_INTERVAL | The interval in milliseconds used to request the RPC node in the Foreign network for new blocks. The interval should match the average production time for a new block. | integer
|
||||
@ -47,6 +47,7 @@ ORACLE_FOREIGN_TX_RESEND_INTERVAL | Interval in milliseconds for automatic resen
|
||||
ORACLE_SHUTDOWN_SERVICE_URL | Optional external URL to some other service/monitor/configuration manager that controls the remote shutdown process. GET request should return `application/json` message with the following schema: `{ shutdown: true/false }`. | URL
|
||||
ORACLE_SHUTDOWN_SERVICE_POLLING_INTERVAL | Optional interval in milliseconds used to request the side RPC node or external shutdown service. Default is 120000. | integer
|
||||
ORACLE_SIDE_RPC_URL | Optional HTTPS URL(s) for communication with the external shutdown service or side RPC nodes, used for shutdown manager activities. Several URLs can be specified, delimited by spaces. If the connection to one of these nodes is lost the next URL is used for connection. | URL(s)
|
||||
ORACLE_FOREIGN_ARCHIVE_RPC_URL | Optional HTTPS URL(s) for communication with the archive nodes on the foreign network. Only used in AMB bridge mode for async information request processing. Several URLs can be specified, delimited by spaces. If the connection to one of these nodes is lost the next URL is used for connection. | URL(s)
|
||||
ORACLE_SHUTDOWN_CONTRACT_ADDRESS | Optional contract address in the side chain accessible through `ORACLE_SIDE_RPC_URL`, where the method passed in `ORACLE_SHUTDOWN_CONTRACT_METHOD` is implemented. | `address`
|
||||
ORACLE_SHUTDOWN_CONTRACT_METHOD | Method signature to be used in the side chain to identify the current shutdown status. Method should return boolean. Default value is `isShutdown()`. | `function signature`
|
||||
ORACLE_FOREIGN_RPC_BLOCK_POLLING_LIMIT | Max length for the block range used in `eth_getLogs` requests for polling contract events for the Foreign chain. Infinite, if not provided. | `integer`
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM node:10 as contracts
|
||||
FROM node:12 as contracts
|
||||
|
||||
WORKDIR /mono
|
||||
|
||||
@ -11,7 +11,7 @@ COPY ./contracts/truffle-config.js ./
|
||||
COPY ./contracts/contracts ./contracts
|
||||
RUN npm run compile
|
||||
|
||||
FROM node:10
|
||||
FROM node:12
|
||||
|
||||
WORKDIR /mono
|
||||
COPY package.json .
|
||||
|
@ -54,8 +54,6 @@ Additionally there are [Smart Contracts](https://github.com/poanetwork/tokenbrid
|
||||
|
||||
The POA TokenBridge provides four operational modes:
|
||||
|
||||
- [x] `Native-to-ERC20` **Coins** on a Home network can be converted to ERC20-compatible **tokens** on a Foreign network. Coins are locked on the Home side and the corresponding amount of ERC20 tokens are minted on the Foreign side. When the operation is reversed, tokens are burnt on the Foreign side and unlocked in the Home network. **More Information: [POA-to-POA20 Bridge](https://medium.com/poa-network/introducing-poa-bridge-and-poa20-55d8b78058ac)**
|
||||
- [x] `ERC20-to-ERC20` ERC20-compatible tokens on the Foreign network are locked and minted as ERC20-compatible tokens (ERC677 tokens) on the Home network. When transferred from Home to Foreign, they are burnt on the Home side and unlocked in the Foreign network. This can be considered a form of atomic swap when a user swaps the token "X" in network "A" to the token "Y" in network "B". **More Information: [ERC20-to-ERC20](https://medium.com/poa-network/introducing-the-erc20-to-erc20-tokenbridge-ce266cc1a2d0)**
|
||||
- [x] `ERC20-to-Native`: Pre-existing **tokens** in the Foreign network are locked and **coins** are minted in the `Home` network. In this mode, the Home network consensus engine invokes [Parity's Block Reward contract](https://wiki.parity.io/Block-Reward-Contract.html) to mint coins per the bridge contract request. **More Information: [xDai Chain](https://medium.com/poa-network/poa-network-partners-with-makerdao-on-xdai-chain-the-first-ever-usd-stable-blockchain-65a078c41e6a)**
|
||||
- [x] `Arbitrary-Message`: Transfer arbitrary data between two networks as so the data could be interpreted as an arbitrary contract method invocation.
|
||||
|
||||
|
@ -19,6 +19,6 @@
|
||||
"eslint-plugin-jest": "^23.18.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.18"
|
||||
"node": ">= 12.22"
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ jest.setTimeout(60000)
|
||||
const statusText = 'Success'
|
||||
const statusSelector = 'label[data-id="status"]'
|
||||
|
||||
const homeToForeignTxURL = 'http://localhost:3004/77/0x58e7d63368335b9591d4dbb43889084f698fcee93ab7656fd7a39d8c66bc4b60'
|
||||
const foreignToHomeTxURL = 'http://localhost:3004/42/0x592bf28fc896419d2838f71cd0388775814b692688f1ecd5b1519081566b994a'
|
||||
const homeToForeignTxURL = 'http://localhost:3004/77/0xbc83d43bdc675a615a2b820e43e52d25857aa5fdd77acf2dd92cd247af2c693c'
|
||||
const foreignToHomeTxURL = 'http://localhost:3004/42/0x09dfb947dbd17e27bcc117773b6e133829f7cef9646199a93ef019c4f7c0fec6'
|
||||
|
||||
describe('ALM', () => {
|
||||
let browser
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM node:10 as contracts
|
||||
FROM node:12 as contracts
|
||||
|
||||
WORKDIR /mono
|
||||
|
||||
|
@ -1,13 +1,7 @@
|
||||
const HOME_NATIVE_TO_ERC_ABI = require('../contracts/build/contracts/HomeBridgeNativeToErc').abi
|
||||
const FOREIGN_NATIVE_TO_ERC_ABI = require('../contracts/build/contracts/ForeignBridgeNativeToErc').abi
|
||||
const HOME_ERC_TO_ERC_ABI = require('../contracts/build/contracts/HomeBridgeErcToErc').abi
|
||||
const FOREIGN_ERC_TO_ERC_ABI = require('../contracts/build/contracts/ForeignBridgeErc677ToErc677').abi
|
||||
const HOME_ERC_TO_NATIVE_ABI = require('../contracts/build/contracts/HomeBridgeErcToNative').abi
|
||||
const FOREIGN_ERC_TO_NATIVE_ABI = require('../contracts/build/contracts/ForeignBridgeErcToNative').abi
|
||||
const ERC20_ABI = require('../contracts/build/contracts/ERC20').abi
|
||||
const ERC677_ABI = require('../contracts/build/contracts/ERC677').abi
|
||||
const ERC677_BRIDGE_TOKEN_ABI = require('../contracts/build/contracts/ERC677BridgeToken').abi
|
||||
const BLOCK_REWARD_ABI = require('../contracts/build/contracts/BlockReward').abi
|
||||
const BLOCK_REWARD_ABI = require('../contracts/build/contracts/BlockRewardMock').abi
|
||||
const BRIDGE_VALIDATORS_ABI = require('../contracts/build/contracts/BridgeValidators').abi
|
||||
const REWARDABLE_VALIDATORS_ABI = require('../contracts/build/contracts/RewardableValidators').abi
|
||||
const HOME_AMB_ABI = require('../contracts/build/contracts/HomeAMB').abi
|
||||
@ -15,43 +9,9 @@ const FOREIGN_AMB_ABI = require('../contracts/build/contracts/ForeignAMB').abi
|
||||
const BOX_ABI = require('../contracts/build/contracts/Box').abi
|
||||
const HOME_AMB_ERC_TO_ERC_ABI = require('../contracts/build/contracts/HomeAMBErc677ToErc677').abi
|
||||
const FOREIGN_AMB_ERC_TO_ERC_ABI = require('../contracts/build/contracts/ForeignAMBErc677ToErc677').abi
|
||||
const HOME_STAKE_ERC_TO_ERC_ABI = require('../contracts/build/contracts/HomeStakeTokenMediator').abi
|
||||
const FOREIGN_STAKE_ERC_TO_ERC_ABI = require('../contracts/build/contracts/ForeignStakeTokenMediator').abi
|
||||
|
||||
const { HOME_V1_ABI, FOREIGN_V1_ABI } = require('./v1Abis')
|
||||
const { BRIDGE_MODES } = require('./constants')
|
||||
|
||||
const ERC20_BYTES32_ABI = [
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'name',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'bytes32'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
},
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'symbol',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'bytes32'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
}
|
||||
]
|
||||
|
||||
const OLD_AMB_USER_REQUEST_FOR_SIGNATURE_ABI = [
|
||||
{
|
||||
anonymous: false,
|
||||
@ -85,27 +45,15 @@ const OLD_AMB_USER_REQUEST_FOR_AFFIRMATION_ABI = [
|
||||
function getBridgeABIs(bridgeMode) {
|
||||
let HOME_ABI = null
|
||||
let FOREIGN_ABI = null
|
||||
if (bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC) {
|
||||
HOME_ABI = HOME_NATIVE_TO_ERC_ABI
|
||||
FOREIGN_ABI = FOREIGN_NATIVE_TO_ERC_ABI
|
||||
} else if (bridgeMode === BRIDGE_MODES.ERC_TO_ERC) {
|
||||
HOME_ABI = HOME_ERC_TO_ERC_ABI
|
||||
FOREIGN_ABI = FOREIGN_ERC_TO_ERC_ABI
|
||||
} else if (bridgeMode === BRIDGE_MODES.ERC_TO_NATIVE) {
|
||||
if (bridgeMode === BRIDGE_MODES.ERC_TO_NATIVE) {
|
||||
HOME_ABI = HOME_ERC_TO_NATIVE_ABI
|
||||
FOREIGN_ABI = FOREIGN_ERC_TO_NATIVE_ABI
|
||||
} else if (bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC_V1) {
|
||||
HOME_ABI = HOME_V1_ABI
|
||||
FOREIGN_ABI = FOREIGN_V1_ABI
|
||||
} else if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
||||
HOME_ABI = HOME_AMB_ABI
|
||||
FOREIGN_ABI = FOREIGN_AMB_ABI
|
||||
} else if (bridgeMode === BRIDGE_MODES.AMB_ERC_TO_ERC) {
|
||||
HOME_ABI = HOME_AMB_ERC_TO_ERC_ABI
|
||||
FOREIGN_ABI = FOREIGN_AMB_ERC_TO_ERC_ABI
|
||||
} else if (bridgeMode === BRIDGE_MODES.STAKE_AMB_ERC_TO_ERC) {
|
||||
HOME_ABI = HOME_STAKE_ERC_TO_ERC_ABI
|
||||
FOREIGN_ABI = FOREIGN_STAKE_ERC_TO_ERC_ABI
|
||||
} else {
|
||||
throw new Error(`Unrecognized bridge mode: ${bridgeMode}`)
|
||||
}
|
||||
@ -115,26 +63,15 @@ function getBridgeABIs(bridgeMode) {
|
||||
|
||||
module.exports = {
|
||||
getBridgeABIs,
|
||||
HOME_NATIVE_TO_ERC_ABI,
|
||||
FOREIGN_NATIVE_TO_ERC_ABI,
|
||||
HOME_ERC_TO_ERC_ABI,
|
||||
FOREIGN_ERC_TO_ERC_ABI,
|
||||
HOME_ERC_TO_NATIVE_ABI,
|
||||
FOREIGN_ERC_TO_NATIVE_ABI,
|
||||
ERC20_ABI,
|
||||
ERC677_ABI,
|
||||
ERC677_BRIDGE_TOKEN_ABI,
|
||||
BLOCK_REWARD_ABI,
|
||||
BRIDGE_VALIDATORS_ABI,
|
||||
REWARDABLE_VALIDATORS_ABI,
|
||||
HOME_V1_ABI,
|
||||
FOREIGN_V1_ABI,
|
||||
ERC20_BYTES32_ABI,
|
||||
HOME_AMB_ABI,
|
||||
FOREIGN_AMB_ABI,
|
||||
OLD_AMB_USER_REQUEST_FOR_AFFIRMATION_ABI,
|
||||
OLD_AMB_USER_REQUEST_FOR_SIGNATURE_ABI,
|
||||
BOX_ABI,
|
||||
HOME_STAKE_ERC_TO_ERC_ABI,
|
||||
FOREIGN_STAKE_ERC_TO_ERC_ABI
|
||||
BOX_ABI
|
||||
}
|
||||
|
@ -1,30 +1,12 @@
|
||||
const BRIDGE_MODES = {
|
||||
NATIVE_TO_ERC: 'NATIVE_TO_ERC',
|
||||
ERC_TO_ERC: 'ERC_TO_ERC',
|
||||
ERC_TO_NATIVE: 'ERC_TO_NATIVE',
|
||||
NATIVE_TO_ERC_V1: 'NATIVE_TO_ERC_V1',
|
||||
ARBITRARY_MESSAGE: 'ARBITRARY_MESSAGE',
|
||||
AMB_ERC_TO_ERC: 'AMB_ERC_TO_ERC',
|
||||
STAKE_AMB_ERC_TO_ERC: 'STAKE_AMB_ERC_TO_ERC'
|
||||
}
|
||||
|
||||
const ERC_TYPES = {
|
||||
ERC20: 'ERC20',
|
||||
ERC677: 'ERC677'
|
||||
}
|
||||
|
||||
const FEE_MANAGER_MODE = {
|
||||
ONE_DIRECTION: 'ONE_DIRECTION',
|
||||
BOTH_DIRECTIONS: 'BOTH_DIRECTIONS',
|
||||
ONE_DIRECTION_STAKE: 'ONE_DIRECTION_STAKE',
|
||||
UNDEFINED: 'UNDEFINED'
|
||||
AMB_ERC_TO_ERC: 'AMB_ERC_TO_ERC'
|
||||
}
|
||||
|
||||
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
|
||||
|
||||
module.exports = {
|
||||
BRIDGE_MODES,
|
||||
ERC_TYPES,
|
||||
FEE_MANAGER_MODE,
|
||||
ZERO_ADDRESS
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"gas-price-oracle": "^0.1.5",
|
||||
"web3-utils": "1.0.0-beta.34"
|
||||
"web3-utils": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bn-chai": "^1.0.1",
|
||||
|
@ -1,12 +1,8 @@
|
||||
const { expect } = require('chai')
|
||||
const { BRIDGE_MODES, ERC_TYPES } = require('../constants')
|
||||
const { BRIDGE_MODES } = require('../constants')
|
||||
|
||||
describe('constants', () => {
|
||||
it('should contain correct number of bridge types', () => {
|
||||
expect(Object.keys(BRIDGE_MODES).length).to.be.equal(7)
|
||||
})
|
||||
|
||||
it('should contain correct number of erc types', () => {
|
||||
expect(Object.keys(ERC_TYPES).length).to.be.equal(2)
|
||||
expect(Object.keys(BRIDGE_MODES).length).to.be.equal(3)
|
||||
})
|
||||
})
|
||||
|
@ -1,159 +0,0 @@
|
||||
const { expect } = require('chai')
|
||||
const { getTokenType, ERC_TYPES } = require('..')
|
||||
|
||||
describe('getTokenType', () => {
|
||||
it('should return ERC677 if bridgeContract is equal to bridgeAddress', async () => {
|
||||
// Given
|
||||
const bridgeAddress = '0xCecBE80Ed3548dE11D7d2D922a36576eA40C4c26'
|
||||
const contract = {
|
||||
methods: {
|
||||
bridgeContract: () => {
|
||||
return {
|
||||
call: () => Promise.resolve(bridgeAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
const type = await getTokenType(contract, bridgeAddress)
|
||||
|
||||
// Then
|
||||
expect(type).to.equal(ERC_TYPES.ERC677)
|
||||
})
|
||||
|
||||
it('should return ERC20 if bridgeContract is not equal to bridgeAddress', async () => {
|
||||
// Given
|
||||
const bridgeAddress = '0xCecBE80Ed3548dE11D7d2D922a36576eA40C4c26'
|
||||
const contract = {
|
||||
methods: {
|
||||
bridgeContract: () => {
|
||||
return {
|
||||
call: () => Promise.resolve('0xBFCb120F7B1de491262CA4D9D8Eba70438b6896E')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
const type = await getTokenType(contract, bridgeAddress)
|
||||
|
||||
// Then
|
||||
expect(type).to.equal(ERC_TYPES.ERC20)
|
||||
})
|
||||
|
||||
it('should return ERC20 if bridgeContract is not present', async () => {
|
||||
// Given
|
||||
const bridgeAddress = '0xCecBE80Ed3548dE11D7d2D922a36576eA40C4c26'
|
||||
const contract = {
|
||||
methods: {
|
||||
bridgeContract: () => {
|
||||
return {
|
||||
call: () => Promise.reject()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
const type = await getTokenType(contract, bridgeAddress)
|
||||
|
||||
// Then
|
||||
expect(type).to.equal(ERC_TYPES.ERC20)
|
||||
})
|
||||
|
||||
it('should return ERC20 if bridgeContract and isBridge are not present', async () => {
|
||||
// Given
|
||||
const bridgeAddress = '0xCecBE80Ed3548dE11D7d2D922a36576eA40C4c26'
|
||||
const contract = {
|
||||
methods: {
|
||||
bridgeContract: () => {
|
||||
return {
|
||||
call: () => Promise.reject()
|
||||
}
|
||||
},
|
||||
isBridge: () => {
|
||||
return {
|
||||
call: () => Promise.reject()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
const type = await getTokenType(contract, bridgeAddress)
|
||||
|
||||
// Then
|
||||
expect(type).to.equal(ERC_TYPES.ERC20)
|
||||
})
|
||||
|
||||
it('should return ERC677 if isBridge returns true', async () => {
|
||||
// Given
|
||||
const bridgeAddress = '0xCecBE80Ed3548dE11D7d2D922a36576eA40C4c26'
|
||||
const contract = {
|
||||
methods: {
|
||||
bridgeContract: () => {
|
||||
return {
|
||||
call: () => Promise.reject()
|
||||
}
|
||||
},
|
||||
isBridge: () => {
|
||||
return {
|
||||
call: () => Promise.resolve(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
const type = await getTokenType(contract, bridgeAddress)
|
||||
|
||||
// Then
|
||||
expect(type).to.equal(ERC_TYPES.ERC677)
|
||||
})
|
||||
|
||||
it('should return ERC677 if isBridge returns true and bridgeContract not present', async () => {
|
||||
// Given
|
||||
const bridgeAddress = '0xCecBE80Ed3548dE11D7d2D922a36576eA40C4c26'
|
||||
const contract = {
|
||||
methods: {
|
||||
isBridge: () => {
|
||||
return {
|
||||
call: () => Promise.resolve(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
const type = await getTokenType(contract, bridgeAddress)
|
||||
|
||||
// Then
|
||||
expect(type).to.equal(ERC_TYPES.ERC677)
|
||||
})
|
||||
|
||||
it('should return ERC20 if isBridge returns false', async () => {
|
||||
// Given
|
||||
const bridgeAddress = '0xCecBE80Ed3548dE11D7d2D922a36576eA40C4c26'
|
||||
const contract = {
|
||||
methods: {
|
||||
bridgeContract: () => {
|
||||
return {
|
||||
call: () => Promise.reject()
|
||||
}
|
||||
},
|
||||
isBridge: () => {
|
||||
return {
|
||||
call: () => Promise.resolve(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When
|
||||
const type = await getTokenType(contract, bridgeAddress)
|
||||
|
||||
// Then
|
||||
expect(type).to.equal(ERC_TYPES.ERC20)
|
||||
})
|
||||
})
|
@ -1,22 +1,16 @@
|
||||
const { toWei, toBN, BN } = require('web3-utils')
|
||||
const { GasPriceOracle } = require('gas-price-oracle')
|
||||
const { BRIDGE_MODES, FEE_MANAGER_MODE, ERC_TYPES } = require('./constants')
|
||||
const { BRIDGE_MODES } = require('./constants')
|
||||
const { REWARDABLE_VALIDATORS_ABI } = require('./abis')
|
||||
|
||||
const gasPriceOracle = new GasPriceOracle()
|
||||
|
||||
function decodeBridgeMode(bridgeModeHash) {
|
||||
switch (bridgeModeHash) {
|
||||
case '0x92a8d7fe':
|
||||
return BRIDGE_MODES.NATIVE_TO_ERC
|
||||
case '0xba4690f5':
|
||||
return BRIDGE_MODES.ERC_TO_ERC
|
||||
case '0x18762d46':
|
||||
return BRIDGE_MODES.ERC_TO_NATIVE
|
||||
case '0x2544fbb9':
|
||||
return BRIDGE_MODES.ARBITRARY_MESSAGE
|
||||
case '0x16ea01e9':
|
||||
return BRIDGE_MODES.STAKE_AMB_ERC_TO_ERC
|
||||
case '0x76595b56':
|
||||
return BRIDGE_MODES.AMB_ERC_TO_ERC
|
||||
default:
|
||||
@ -24,80 +18,9 @@ function decodeBridgeMode(bridgeModeHash) {
|
||||
}
|
||||
}
|
||||
|
||||
const decodeFeeManagerMode = managerModeHash => {
|
||||
switch (managerModeHash) {
|
||||
case '0xf2aed8f7':
|
||||
return FEE_MANAGER_MODE.ONE_DIRECTION
|
||||
case '0xd7de965f':
|
||||
return FEE_MANAGER_MODE.BOTH_DIRECTIONS
|
||||
default:
|
||||
throw new Error(`Unrecognized fee manager mode hash: '${managerModeHash}'`)
|
||||
}
|
||||
}
|
||||
|
||||
async function getBridgeMode(contract) {
|
||||
try {
|
||||
const bridgeModeHash = await contract.methods.getBridgeMode().call()
|
||||
return decodeBridgeMode(bridgeModeHash)
|
||||
} catch (e) {
|
||||
return BRIDGE_MODES.NATIVE_TO_ERC_V1
|
||||
}
|
||||
}
|
||||
|
||||
const getTokenType = async (bridgeTokenContract, bridgeAddress) => {
|
||||
try {
|
||||
const resultBridgeAddress = await bridgeTokenContract.methods.bridgeContract().call()
|
||||
if (resultBridgeAddress === bridgeAddress) {
|
||||
return ERC_TYPES.ERC677
|
||||
} else {
|
||||
return ERC_TYPES.ERC20
|
||||
}
|
||||
} catch (e) {
|
||||
try {
|
||||
const isBridge = await bridgeTokenContract.methods.isBridge(bridgeAddress).call()
|
||||
if (isBridge) {
|
||||
return ERC_TYPES.ERC677
|
||||
} else {
|
||||
return ERC_TYPES.ERC20
|
||||
}
|
||||
} catch (e) {
|
||||
return ERC_TYPES.ERC20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const isErcToErcMode = bridgeMode => {
|
||||
return (
|
||||
bridgeMode === BRIDGE_MODES.ERC_TO_ERC ||
|
||||
bridgeMode === BRIDGE_MODES.AMB_ERC_TO_ERC ||
|
||||
bridgeMode === BRIDGE_MODES.STAKE_AMB_ERC_TO_ERC
|
||||
)
|
||||
}
|
||||
|
||||
const isMediatorMode = bridgeMode => {
|
||||
return bridgeMode === BRIDGE_MODES.AMB_ERC_TO_ERC || bridgeMode === BRIDGE_MODES.STAKE_AMB_ERC_TO_ERC
|
||||
}
|
||||
|
||||
const getUnit = bridgeMode => {
|
||||
let unitHome = null
|
||||
let unitForeign = null
|
||||
if (bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC) {
|
||||
unitHome = 'Native coins'
|
||||
unitForeign = 'Tokens'
|
||||
} else if (bridgeMode === BRIDGE_MODES.ERC_TO_ERC) {
|
||||
unitHome = 'Tokens'
|
||||
unitForeign = 'Tokens'
|
||||
} else if (bridgeMode === BRIDGE_MODES.ERC_TO_NATIVE) {
|
||||
unitHome = 'Native coins'
|
||||
unitForeign = 'Tokens'
|
||||
} else if (bridgeMode === BRIDGE_MODES.STAKE_AMB_ERC_TO_ERC) {
|
||||
unitHome = 'Tokens'
|
||||
unitForeign = 'Tokens'
|
||||
} else {
|
||||
throw new Error(`Unrecognized bridge mode: ${bridgeMode}`)
|
||||
}
|
||||
|
||||
return { unitHome, unitForeign }
|
||||
const bridgeModeHash = await contract.methods.getBridgeMode().call()
|
||||
return decodeBridgeMode(bridgeModeHash)
|
||||
}
|
||||
|
||||
const parseValidatorEvent = event => {
|
||||
@ -306,10 +229,7 @@ const gasPriceFromContract = async (bridgeContract, options = {}) => {
|
||||
|
||||
module.exports = {
|
||||
decodeBridgeMode,
|
||||
decodeFeeManagerMode,
|
||||
getBridgeMode,
|
||||
getTokenType,
|
||||
getUnit,
|
||||
parseValidatorEvent,
|
||||
processValidatorsEvents,
|
||||
getValidatorList,
|
||||
@ -318,7 +238,5 @@ module.exports = {
|
||||
normalizeGasPrice,
|
||||
gasPriceFromSupplier,
|
||||
gasPriceFromContract,
|
||||
gasPriceWithinLimits,
|
||||
isErcToErcMode,
|
||||
isMediatorMode
|
||||
gasPriceWithinLimits
|
||||
}
|
||||
|
@ -1,191 +0,0 @@
|
||||
const homeV1Abi = [
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'validatorContract',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'address'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: false,
|
||||
name: 'recipient',
|
||||
type: 'address'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'value',
|
||||
type: 'uint256'
|
||||
}
|
||||
],
|
||||
name: 'Deposit',
|
||||
type: 'event'
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: false,
|
||||
name: 'recipient',
|
||||
type: 'address'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'value',
|
||||
type: 'uint256'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'transactionHash',
|
||||
type: 'bytes32'
|
||||
}
|
||||
],
|
||||
name: 'Withdraw',
|
||||
type: 'event'
|
||||
},
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'deployedAtBlock',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'uint256'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
},
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'requiredBlockConfirmations',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'uint256'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
}
|
||||
]
|
||||
|
||||
const foreignViAbi = [
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'validatorContract',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'address'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: false,
|
||||
name: 'recipient',
|
||||
type: 'address'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'value',
|
||||
type: 'uint256'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'transactionHash',
|
||||
type: 'bytes32'
|
||||
}
|
||||
],
|
||||
name: 'Deposit',
|
||||
type: 'event'
|
||||
},
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: false,
|
||||
name: 'recipient',
|
||||
type: 'address'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'value',
|
||||
type: 'uint256'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'homeGasPrice',
|
||||
type: 'uint256'
|
||||
}
|
||||
],
|
||||
name: 'Withdraw',
|
||||
type: 'event'
|
||||
},
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'deployedAtBlock',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'uint256'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
},
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'erc677token',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'address'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
},
|
||||
{
|
||||
constant: true,
|
||||
inputs: [],
|
||||
name: 'requiredBlockConfirmations',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'uint256'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'view',
|
||||
type: 'function'
|
||||
}
|
||||
]
|
||||
|
||||
module.exports = {
|
||||
HOME_V1_ABI: homeV1Abi,
|
||||
FOREIGN_V1_ABI: foreignViAbi
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit c9377114f7bcf04cd12a30d9eca0a63362dcaedc
|
||||
Subproject commit 004d466a3d593e6304e52c74e6c3e801b6a33b32
|
@ -9,15 +9,17 @@
|
||||
- oracle_net_db_bridge_request
|
||||
- oracle_net_db_bridge_collected
|
||||
- oracle_net_db_bridge_affirmation
|
||||
- oracle_net_db_bridge_information
|
||||
- oracle_net_db_bridge_transfer
|
||||
- oracle_net_db_bridge_senderhome
|
||||
- oracle_net_db_bridge_senderforeign
|
||||
- oracle_net_db_bridge_shutdown
|
||||
- oracle_net_rabbit_bridge_request
|
||||
- oracle_net_rabbit_bridge_collected
|
||||
- oracle_net_rabbit_bridge_affirmation
|
||||
- oracle_net_rabbit_bridge_information
|
||||
- oracle_net_rabbit_bridge_transfer
|
||||
- oracle_net_rabbit_bridge_senderhome
|
||||
- oracle_net_rabbit_bridge_senderforeign
|
||||
- oracle_net_rabbit_bridge_convert_to_chai_worker
|
||||
delegate_to: 127.0.0.1
|
||||
become: false
|
||||
|
@ -1,14 +0,0 @@
|
||||
# Molecule managed
|
||||
|
||||
{% if item.registry is defined %}
|
||||
FROM {{ item.registry.url }}/{{ item.image }}
|
||||
{% else %}
|
||||
FROM {{ item.image }}
|
||||
{% endif %}
|
||||
|
||||
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
|
||||
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash && dnf clean all; \
|
||||
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
|
||||
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml && zypper clean -a; \
|
||||
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
|
||||
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi
|
@ -1,38 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: oracle-erc-to-erc-host
|
||||
groups:
|
||||
- ultimate
|
||||
- erc-to-erc
|
||||
children:
|
||||
- oracle
|
||||
image: ubuntu:16.04
|
||||
privileged: true
|
||||
network_mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../prepare.yml
|
||||
converge: ../ultimate-commons/converge.yml
|
||||
inventory:
|
||||
host_vars:
|
||||
oracle-erc-to-erc-host:
|
||||
ORACLE_VALIDATOR_ADDRESS: "0xaaB52d66283F7A1D5978bcFcB55721ACB467384b"
|
||||
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY: "8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9"
|
||||
verifier:
|
||||
name: testinfra
|
||||
lint:
|
||||
name: flake8
|
||||
scenario:
|
||||
name: ultimate-erc-to-erc
|
||||
test_sequence:
|
||||
- cleanup
|
||||
- destroy
|
||||
- syntax
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
@ -1,14 +0,0 @@
|
||||
# Molecule managed
|
||||
|
||||
{% if item.registry is defined %}
|
||||
FROM {{ item.registry.url }}/{{ item.image }}
|
||||
{% else %}
|
||||
FROM {{ item.image }}
|
||||
{% endif %}
|
||||
|
||||
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
|
||||
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash && dnf clean all; \
|
||||
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
|
||||
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml && zypper clean -a; \
|
||||
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
|
||||
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi
|
@ -1,38 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: oracle-native-to-erc-host
|
||||
groups:
|
||||
- ultimate
|
||||
- native-to-erc
|
||||
children:
|
||||
- oracle
|
||||
image: ubuntu:16.04
|
||||
privileged: true
|
||||
network_mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../prepare.yml
|
||||
converge: ../ultimate-commons/converge.yml
|
||||
inventory:
|
||||
host_vars:
|
||||
oracle-native-to-erc-host:
|
||||
ORACLE_VALIDATOR_ADDRESS: "0xaaB52d66283F7A1D5978bcFcB55721ACB467384b"
|
||||
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY: "8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9"
|
||||
verifier:
|
||||
name: testinfra
|
||||
lint:
|
||||
name: flake8
|
||||
scenario:
|
||||
name: ultimate-native-to-erc
|
||||
test_sequence:
|
||||
- cleanup
|
||||
- destroy
|
||||
- syntax
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
ORACLE_BRIDGE_MODE: "ARBITRARY_MESSAGE"
|
||||
COMMON_HOME_BRIDGE_ADDRESS: "0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0"
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS: "0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0"
|
||||
COMMON_HOME_BRIDGE_ADDRESS: "0x8397be90BCF57b0B71219f555Fe121b22e5a994C"
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS: "0x1feB40aD9420b186F019A717c37f5546165d411E"
|
||||
MONITOR_PORT: 3013
|
||||
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
ORACLE_BRIDGE_MODE: "ERC_TO_ERC"
|
||||
COMMON_HOME_BRIDGE_ADDRESS: "0x1feB40aD9420b186F019A717c37f5546165d411E"
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS: "0x4a58D6d8D416a5fBCAcf3dC52eb8bE8948E25127"
|
||||
MONITOR_PORT: 3011
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
ORACLE_BRIDGE_MODE: "ERC_TO_NATIVE"
|
||||
COMMON_HOME_BRIDGE_ADDRESS: "0x488Af810997eD1730cB3a3918cD83b3216E6eAda"
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS: "0x488Af810997eD1730cB3a3918cD83b3216E6eAda"
|
||||
COMMON_HOME_BRIDGE_ADDRESS: "0x5118AC62AE912Dd5B51EEfF7338c4fcb0248Ba8c"
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS: "0x32198D570fffC7033641F8A9094FFDCaAEF42624"
|
||||
MONITOR_PORT: 3012
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
## General settings
|
||||
ORACLE_BRIDGE_MODE: "NATIVE_TO_ERC"
|
||||
ORACLE_BRIDGE_MODE: "ARBITRARY_MESSAGE"
|
||||
ORACLE_LOG_LEVEL: debug
|
||||
|
||||
## Home contract
|
||||
|
@ -1,5 +0,0 @@
|
||||
---
|
||||
ORACLE_BRIDGE_MODE: "NATIVE_TO_ERC"
|
||||
COMMON_HOME_BRIDGE_ADDRESS: "0x32198D570fffC7033641F8A9094FFDCaAEF42624"
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS: "0x2B6871b9B02F73fa24F4864322CdC78604207769"
|
||||
MONITOR_PORT: 3010
|
@ -1,37 +0,0 @@
|
||||
---
|
||||
## General settings
|
||||
ORACLE_BRIDGE_MODE: "NATIVE_TO_ERC"
|
||||
|
||||
## Home contract
|
||||
COMMON_HOME_RPC_URL: "https://www.ethercluster.com/etc"
|
||||
COMMON_HOME_BRIDGE_ADDRESS: "0x073081832B4Ecdce79d4D6753565c85Ba4b3BeA9"
|
||||
ORACLE_HOME_RPC_POLLING_INTERVAL: 7000
|
||||
|
||||
## Foreign contract
|
||||
COMMON_FOREIGN_RPC_URL: "https://mainnet.infura.io/"
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS: "0x0cB781EE62F815bdD9CD4c2210aE8600d43e7040"
|
||||
ORACLE_FOREIGN_RPC_POLLING_INTERVAL: 7000
|
||||
|
||||
## Home Gasprice
|
||||
COMMON_HOME_GAS_PRICE_SUPPLIER_URL: "https://gasprice-etc.poa.network/"
|
||||
COMMON_HOME_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
COMMON_HOME_GAS_PRICE_FALLBACK: 15000000000 # in wei
|
||||
ORACLE_HOME_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
COMMON_HOME_GAS_PRICE_FACTOR: 1
|
||||
|
||||
## Foreign Gasprice
|
||||
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL: "https://gasprice.poa.network/"
|
||||
COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
COMMON_FOREIGN_GAS_PRICE_FALLBACK: 10000000000 # in wei
|
||||
ORACLE_FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
COMMON_FOREIGN_GAS_PRICE_FACTOR: 1
|
||||
|
||||
## Monitor
|
||||
MONITOR_BRIDGE_NAME: "wetc"
|
||||
MONITOR_PORT: 3003
|
||||
MONITOR_CACHE_EVENTS: "true"
|
||||
MONITOR_HOME_START_BLOCK: 7703292
|
||||
MONITOR_FOREIGN_START_BLOCK: 7412459
|
||||
MONITOR_VALIDATOR_HOME_TX_LIMIT: 300000
|
||||
MONITOR_VALIDATOR_FOREIGN_TX_LIMIT: 300000
|
||||
MONITOR_TX_NUMBER_THRESHOLD: 100
|
@ -3,7 +3,7 @@
|
||||
with_items:
|
||||
- docker-compose
|
||||
- docker-compose-transfer
|
||||
- docker-compose-erc-native
|
||||
- docker-compose-amb
|
||||
loop_control:
|
||||
loop_var: file
|
||||
|
||||
|
@ -38,14 +38,14 @@
|
||||
set_fact:
|
||||
FOREIGN_ERC_TYPE: "{{ (ERCTYPE.stdout).foreignERC | default('') }}"
|
||||
|
||||
- name: Extend docker compose file
|
||||
set_fact: composefileoverride="-f docker-compose-transfer.yml"
|
||||
when: ORACLE_BRIDGE_MODE == "ERC_TO_ERC" and FOREIGN_ERC_TYPE != "ERC677"
|
||||
|
||||
- name: Extend docker compose file for erc to native
|
||||
set_fact: composefileoverride="-f docker-compose-erc-native.yml"
|
||||
set_fact: composefileoverride="-f docker-compose-transfer.yml"
|
||||
when: ORACLE_BRIDGE_MODE == "ERC_TO_NATIVE"
|
||||
|
||||
- name: Extend docker compose file for amb
|
||||
set_fact: composefileoverride="-f docker-compose-amb.yml"
|
||||
when: ORACLE_BRIDGE_MODE == "ARBITRARY_MESSAGE"
|
||||
|
||||
- name: Install .key config
|
||||
template:
|
||||
src: key.j2
|
||||
|
@ -20,4 +20,4 @@
|
||||
with_items:
|
||||
- docker-compose.yml
|
||||
- docker-compose-transfer.yml
|
||||
- docker-compose-erc-native.yml
|
||||
- docker-compose-amb.yml
|
||||
|
@ -26,9 +26,7 @@ Shut down and cleans up containers, networks, services, running scripts:
|
||||
| oracle-validator-3 | Launches Oracle containers for third validator |
|
||||
| blocks | Auto mines blocks |
|
||||
| monitor | Launches Monitor containers |
|
||||
| native-to-erc | Creates infrastructure for ultimate e2e testing, for native-to-erc type of bridge |
|
||||
| erc-to-native | Creates infrastructure for ultimate e2e testing, for erc-to-native type of bridge |
|
||||
| erc-to-erc | Creates infrastructure for ultimate e2e testing, for erc-to-erc type of bridge |
|
||||
| amb | Creates infrastructure for ultimate e2e testing, for arbitrary message type of bridge |
|
||||
|
||||
#### Ultimate e2e testing
|
||||
|
@ -4,7 +4,7 @@ Documentation regarding the Ultimate end-to-end tests.
|
||||
|
||||
## Overview
|
||||
|
||||
The ultimate e2e test scenario covers native-to-erc type of bridge.
|
||||
The ultimate e2e test scenario covers erc-to-native and amb types of bridges.
|
||||
It runs the e2e tests on components deployed using the deployment playbooks.
|
||||
|
||||
|
||||
@ -16,14 +16,14 @@ Run the Parity nodes, deploy the bridge contracts, deploy Oracle using the deplo
|
||||
|
||||
```bash
|
||||
./e2e-commons/up.sh deploy blocks
|
||||
./deployment-e2e/molecule.sh ultimate-native-to-erc
|
||||
./deployment-e2e/molecule.sh ultimate-erc-to-native
|
||||
```
|
||||
|
||||
### 2. Run the E2E tests
|
||||
|
||||
```bash
|
||||
cd e2e-commons
|
||||
docker-compose run -e ULTIMATE=true e2e yarn workspace oracle-e2e run native-to-erc
|
||||
docker-compose run -e ULTIMATE=true e2e yarn workspace oracle-e2e run erc-to-native
|
||||
```
|
||||
|
||||
## Diagram
|
||||
|
@ -1,2 +1,2 @@
|
||||
0xc9e38bfdB9c635F0796ad83CC8705dc379F41c04
|
||||
0x6f359aC418a5f7538F7755A33C9c7dDf38785524
|
||||
0xF9698Eb93702dfdd0e2d802088d4c21822a8A977
|
||||
|
@ -5,9 +5,11 @@ set -e # exit when any command fails
|
||||
docker-compose build e2e
|
||||
while [ "$1" != "" ]; do
|
||||
if [ "$1" == "oracle" ]; then
|
||||
docker-compose build oracle
|
||||
docker-compose build oracle-amb
|
||||
elif [ "$1" == "alm-e2e" ]; then
|
||||
docker-compose build oracle-amb
|
||||
elif [ "$1" == "monitor" ]; then
|
||||
docker-compose build monitor
|
||||
docker-compose build monitor-amb
|
||||
elif [ "$1" == "alm" ]; then
|
||||
docker-compose build alm
|
||||
fi
|
||||
|
@ -1,5 +1,5 @@
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x8397be90BCF57b0B71219f555Fe121b22e5a994C
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x1feB40aD9420b186F019A717c37f5546165d411E
|
||||
|
||||
COMMON_HOME_RPC_URL=http://localhost:8541
|
||||
COMMON_FOREIGN_RPC_URL=http://localhost:8542
|
||||
|
@ -1,7 +1,7 @@
|
||||
COMMON_HOME_RPC_URL=http://parity1:8545
|
||||
COMMON_FOREIGN_RPC_URL=http://parity2:8545
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x8397be90BCF57b0B71219f555Fe121b22e5a994C
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x1feB40aD9420b186F019A717c37f5546165d411E
|
||||
MONITOR_HOME_START_BLOCK=0
|
||||
MONITOR_FOREIGN_START_BLOCK=0
|
||||
MONITOR_VALIDATOR_HOME_TX_LIMIT=300000
|
||||
|
@ -1,7 +1,7 @@
|
||||
COMMON_HOME_RPC_URL=http://parity1:8545
|
||||
COMMON_FOREIGN_RPC_URL=http://parity2:8545
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x488Af810997eD1730cB3a3918cD83b3216E6eAda
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x488Af810997eD1730cB3a3918cD83b3216E6eAda
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x5118AC62AE912Dd5B51EEfF7338c4fcb0248Ba8c
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x32198D570fffC7033641F8A9094FFDCaAEF42624
|
||||
MONITOR_HOME_START_BLOCK=0
|
||||
MONITOR_FOREIGN_START_BLOCK=0
|
||||
MONITOR_VALIDATOR_HOME_TX_LIMIT=300000
|
||||
|
@ -1,20 +0,0 @@
|
||||
COMMON_HOME_RPC_URL=http://parity1:8545
|
||||
COMMON_FOREIGN_RPC_URL=http://parity2:8545
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x1feB40aD9420b186F019A717c37f5546165d411E
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x4a58D6d8D416a5fBCAcf3dC52eb8bE8948E25127
|
||||
MONITOR_HOME_START_BLOCK=0
|
||||
MONITOR_FOREIGN_START_BLOCK=0
|
||||
MONITOR_VALIDATOR_HOME_TX_LIMIT=300000
|
||||
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
COMMON_HOME_GAS_PRICE_SPEED_TYPE=standard
|
||||
COMMON_HOME_GAS_PRICE_FALLBACK=1000000000
|
||||
COMMON_HOME_GAS_PRICE_FACTOR=1
|
||||
MONITOR_VALIDATOR_FOREIGN_TX_LIMIT=300000
|
||||
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE=standard
|
||||
COMMON_FOREIGN_GAS_PRICE_FALLBACK=1000000000
|
||||
COMMON_FOREIGN_GAS_PRICE_FACTOR=1
|
||||
MONITOR_TX_NUMBER_THRESHOLD=100
|
||||
MONITOR_PORT=3011
|
||||
MONITOR_BRIDGE_NAME=bridge
|
||||
MONITOR_CACHE_EVENTS=false
|
@ -1,20 +0,0 @@
|
||||
COMMON_HOME_RPC_URL=http://parity1:8545
|
||||
COMMON_FOREIGN_RPC_URL=http://parity2:8545
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x32198D570fffC7033641F8A9094FFDCaAEF42624
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x2B6871b9B02F73fa24F4864322CdC78604207769
|
||||
MONITOR_HOME_START_BLOCK=0
|
||||
MONITOR_FOREIGN_START_BLOCK=0
|
||||
MONITOR_VALIDATOR_HOME_TX_LIMIT=300000
|
||||
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
COMMON_HOME_GAS_PRICE_SPEED_TYPE=standard
|
||||
COMMON_HOME_GAS_PRICE_FALLBACK=1000000000
|
||||
COMMON_HOME_GAS_PRICE_FACTOR=1
|
||||
MONITOR_VALIDATOR_FOREIGN_TX_LIMIT=300000
|
||||
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE=standard
|
||||
COMMON_FOREIGN_GAS_PRICE_FALLBACK=1000000000
|
||||
COMMON_FOREIGN_GAS_PRICE_FACTOR=1
|
||||
MONITOR_TX_NUMBER_THRESHOLD=100
|
||||
MONITOR_PORT=3010
|
||||
MONITOR_BRIDGE_NAME=bridge
|
||||
MONITOR_CACHE_EVENTS=false
|
@ -4,8 +4,8 @@ ORACLE_QUEUE_URL=amqp://rabbit
|
||||
ORACLE_REDIS_URL=redis://redis
|
||||
COMMON_HOME_RPC_URL=http://parity1:8545
|
||||
COMMON_FOREIGN_RPC_URL=http://parity2:8545
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x8397be90BCF57b0B71219f555Fe121b22e5a994C
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x1feB40aD9420b186F019A717c37f5546165d411E
|
||||
ORACLE_VALIDATOR_ADDRESS=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9
|
||||
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
@ -24,3 +24,4 @@ ORACLE_ALLOW_HTTP_FOR_RPC=yes
|
||||
ORACLE_HOME_START_BLOCK=1
|
||||
ORACLE_FOREIGN_START_BLOCK=1
|
||||
ORACLE_HOME_TO_FOREIGN_BLOCK_LIST=/mono/oracle/access-lists/block_list.txt
|
||||
ORACLE_FOREIGN_ARCHIVE_RPC_URL=http://parity2:8545
|
||||
|
@ -4,8 +4,8 @@ ORACLE_QUEUE_URL=amqp://rabbit
|
||||
ORACLE_REDIS_URL=redis://redis
|
||||
COMMON_HOME_RPC_URL=http://parity1:8545
|
||||
COMMON_FOREIGN_RPC_URL=http://parity2:8545
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x488Af810997eD1730cB3a3918cD83b3216E6eAda
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x488Af810997eD1730cB3a3918cD83b3216E6eAda
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x5118AC62AE912Dd5B51EEfF7338c4fcb0248Ba8c
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x32198D570fffC7033641F8A9094FFDCaAEF42624
|
||||
ORACLE_VALIDATOR_ADDRESS=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9
|
||||
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
|
@ -1,25 +0,0 @@
|
||||
|
||||
ORACLE_BRIDGE_MODE=ERC_TO_ERC
|
||||
ORACLE_QUEUE_URL=amqp://rabbit
|
||||
ORACLE_REDIS_URL=redis://redis
|
||||
COMMON_HOME_RPC_URL=http://parity1:8545
|
||||
COMMON_FOREIGN_RPC_URL=http://parity2:8545
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x1feB40aD9420b186F019A717c37f5546165d411E
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x4a58D6d8D416a5fBCAcf3dC52eb8bE8948E25127
|
||||
ORACLE_VALIDATOR_ADDRESS=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9
|
||||
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
COMMON_HOME_GAS_PRICE_SPEED_TYPE=standard
|
||||
COMMON_HOME_GAS_PRICE_FALLBACK=1
|
||||
ORACLE_HOME_GAS_PRICE_UPDATE_INTERVAL=600000
|
||||
COMMON_HOME_GAS_PRICE_FACTOR=1
|
||||
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE=standard
|
||||
COMMON_FOREIGN_GAS_PRICE_FALLBACK=1
|
||||
ORACLE_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=600000
|
||||
COMMON_FOREIGN_GAS_PRICE_FACTOR=0.1
|
||||
ORACLE_HOME_RPC_POLLING_INTERVAL=500
|
||||
ORACLE_FOREIGN_RPC_POLLING_INTERVAL=500
|
||||
ORACLE_ALLOW_HTTP_FOR_RPC=yes
|
||||
ORACLE_HOME_START_BLOCK=1
|
||||
ORACLE_FOREIGN_START_BLOCK=1
|
@ -1,25 +0,0 @@
|
||||
|
||||
ORACLE_BRIDGE_MODE=NATIVE_TO_ERC
|
||||
ORACLE_QUEUE_URL=amqp://rabbit
|
||||
ORACLE_REDIS_URL=redis://redis
|
||||
COMMON_HOME_RPC_URL=http://parity1:8545
|
||||
COMMON_FOREIGN_RPC_URL=http://parity2:8545
|
||||
COMMON_HOME_BRIDGE_ADDRESS=0x32198D570fffC7033641F8A9094FFDCaAEF42624
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS=0x2B6871b9B02F73fa24F4864322CdC78604207769
|
||||
ORACLE_VALIDATOR_ADDRESS=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9
|
||||
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
COMMON_HOME_GAS_PRICE_SPEED_TYPE=standard
|
||||
COMMON_HOME_GAS_PRICE_FALLBACK=1
|
||||
ORACLE_HOME_GAS_PRICE_UPDATE_INTERVAL=600000
|
||||
COMMON_HOME_GAS_PRICE_FACTOR=1
|
||||
COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
|
||||
COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE=standard
|
||||
COMMON_FOREIGN_GAS_PRICE_FALLBACK=1
|
||||
ORACLE_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=600000
|
||||
COMMON_FOREIGN_GAS_PRICE_FACTOR=0.1
|
||||
ORACLE_HOME_RPC_POLLING_INTERVAL=500
|
||||
ORACLE_FOREIGN_RPC_POLLING_INTERVAL=500
|
||||
ORACLE_ALLOW_HTTP_FOR_RPC=yes
|
||||
ORACLE_HOME_START_BLOCK=1
|
||||
ORACLE_FOREIGN_START_BLOCK=1
|
@ -35,32 +35,18 @@
|
||||
"address": "0xB4579fd5AfEaB60B03Db3F408AAdD315035943f7",
|
||||
"privateKey": "0xd6143d390d8b28c33601bb0fe29392fb1c35c24ccfe8722c09c2bdd6ada2699f"
|
||||
},
|
||||
"nativeToErcBridge": {
|
||||
"home": "0x32198D570fffC7033641F8A9094FFDCaAEF42624",
|
||||
"foreign": "0x2B6871b9B02F73fa24F4864322CdC78604207769",
|
||||
"foreignToken": "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B",
|
||||
"monitor": "http://monitor:3010/bridge"
|
||||
},
|
||||
"ercToErcBridge": {
|
||||
"home": "0x1feB40aD9420b186F019A717c37f5546165d411E",
|
||||
"foreign": "0x4a58D6d8D416a5fBCAcf3dC52eb8bE8948E25127",
|
||||
"homeToken": "0x792455a6bCb62Ed4C4362D323E0590654CA4765c",
|
||||
"foreignToken": "0x3C665A31199694Bf723fD08844AD290207B5797f",
|
||||
"monitor": "http://monitor-erc20:3011/bridge"
|
||||
},
|
||||
"ercToNativeBridge": {
|
||||
"home": "0x488Af810997eD1730cB3a3918cD83b3216E6eAda",
|
||||
"foreign": "0x488Af810997eD1730cB3a3918cD83b3216E6eAda",
|
||||
"home": "0x5118AC62AE912Dd5B51EEfF7338c4fcb0248Ba8c",
|
||||
"foreign": "0x32198D570fffC7033641F8A9094FFDCaAEF42624",
|
||||
"foreignToken": "0x7cc4b1851c35959d34e635a470f6b5c43ba3c9c9",
|
||||
"chaiToken": "0x06af07097c9eeb7fd685c692751d5c66db49c215",
|
||||
"monitor": "http://monitor-erc20-native:3012/bridge"
|
||||
},
|
||||
"amb": {
|
||||
"home": "0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0",
|
||||
"foreign": "0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0",
|
||||
"homeBox": "0x6C4EaAb8756d53Bf599FFe2347FAFF1123D6C8A1",
|
||||
"foreignBox": "0x6C4EaAb8756d53Bf599FFe2347FAFF1123D6C8A1",
|
||||
"blockedHomeBox": "0x6f359aC418a5f7538F7755A33C9c7dDf38785524",
|
||||
"home": "0x8397be90BCF57b0B71219f555Fe121b22e5a994C",
|
||||
"foreign": "0x1feB40aD9420b186F019A717c37f5546165d411E",
|
||||
"homeBox": "0xb008E9076fCbDB2C3AF84225Bc07Eb35B2bE5ECD",
|
||||
"foreignBox": "0x4a58D6d8D416a5fBCAcf3dC52eb8bE8948E25127",
|
||||
"blockedHomeBox": "0xF9698Eb93702dfdd0e2d802088d4c21822a8A977",
|
||||
"monitor": "http://monitor-amb:3013/bridge"
|
||||
},
|
||||
"homeRPC": {
|
||||
|
@ -9,7 +9,7 @@ HOME_RPC_URL=http://parity1:8545
|
||||
HOME_BRIDGE_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
HOME_VALIDATORS_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
HOME_UPGRADEABLE_ADMIN=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
HOME_MAX_AMOUNT_PER_TX=8000000
|
||||
HOME_MAX_AMOUNT_PER_TX=2000000
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS=1
|
||||
HOME_GAS_PRICE=1000000000
|
||||
|
||||
@ -17,7 +17,7 @@ FOREIGN_RPC_URL=http://parity2:8545
|
||||
FOREIGN_BRIDGE_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
FOREIGN_VALIDATORS_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
FOREIGN_UPGRADEABLE_ADMIN=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
FOREIGN_MAX_AMOUNT_PER_TX=8000000
|
||||
FOREIGN_MAX_AMOUNT_PER_TX=2000000
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS=1
|
||||
FOREIGN_GAS_PRICE=10000000000
|
||||
|
||||
|
@ -1,40 +0,0 @@
|
||||
BRIDGE_MODE=ERC_TO_ERC
|
||||
DEPLOYMENT_ACCOUNT_PRIVATE_KEY=8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9
|
||||
HOME_DEPLOYMENT_GAS_PRICE=10000000000
|
||||
FOREIGN_DEPLOYMENT_GAS_PRICE=10000000000
|
||||
GET_RECEIPT_INTERVAL_IN_MILLISECONDS=50
|
||||
DEPLOYMENT_GAS_LIMIT_EXTRA=0.2
|
||||
DEPLOY_REWARDABLE_TOKEN=false
|
||||
|
||||
BRIDGEABLE_TOKEN_NAME="Your New Bridged Token"
|
||||
BRIDGEABLE_TOKEN_SYMBOL="TEST"
|
||||
BRIDGEABLE_TOKEN_DECIMALS="18"
|
||||
|
||||
HOME_RPC_URL=http://parity1:8545
|
||||
HOME_BRIDGE_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
HOME_VALIDATORS_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
HOME_UPGRADEABLE_ADMIN=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
HOME_DAILY_LIMIT=30000000000000000000000000
|
||||
HOME_MAX_AMOUNT_PER_TX=1500000000000000000000000
|
||||
HOME_MIN_AMOUNT_PER_TX=10000000000000000
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS=1
|
||||
HOME_GAS_PRICE=1000000000
|
||||
HOME_REWARDABLE=false
|
||||
|
||||
FOREIGN_RPC_URL=http://parity2:8545
|
||||
FOREIGN_BRIDGE_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
FOREIGN_VALIDATORS_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
FOREIGN_UPGRADEABLE_ADMIN=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
FOREIGN_DAILY_LIMIT=15000000000000000000000000
|
||||
FOREIGN_MAX_AMOUNT_PER_TX=750000000000000000000000
|
||||
FOREIGN_MIN_AMOUNT_PER_TX=10000000000000000
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS=1
|
||||
FOREIGN_GAS_PRICE=10000000000
|
||||
FOREIGN_REWARDABLE=false
|
||||
ERC20_TOKEN_ADDRESS=0x3C665A31199694Bf723fD08844AD290207B5797f
|
||||
|
||||
REQUIRED_NUMBER_OF_VALIDATORS=1
|
||||
VALIDATORS="0xaaB52d66283F7A1D5978bcFcB55721ACB467384b 0xdCC784657C78054aa61FbcFFd2605F32374816A4 0xDcef88209a20D52165230104B245803C3269454d"
|
||||
BLOCK_REWARD_ADDRESS=0x0000000000000000000000000000000000000000
|
||||
DPOS_STAKING_ADDRESS=0x0000000000000000000000000000000000000000
|
||||
ERC20_EXTENDED_BY_ERC677=false
|
@ -31,7 +31,7 @@ FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS=1
|
||||
FOREIGN_GAS_PRICE=10000000000
|
||||
FOREIGN_REWARDABLE=false
|
||||
|
||||
BLOCK_REWARD_ADDRESS=0xF9698Eb93702dfdd0e2d802088d4c21822a8A977
|
||||
BLOCK_REWARD_ADDRESS=0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B
|
||||
ERC20_TOKEN_ADDRESS=0x7cc4b1851c35959d34e635a470f6b5c43ba3c9c9
|
||||
|
||||
REQUIRED_NUMBER_OF_VALIDATORS=1
|
||||
|
@ -1,38 +0,0 @@
|
||||
BRIDGE_MODE=NATIVE_TO_ERC
|
||||
DEPLOYMENT_ACCOUNT_ADDRESS=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
DEPLOYMENT_ACCOUNT_PRIVATE_KEY=8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9
|
||||
HOME_DEPLOYMENT_GAS_PRICE=10000000000
|
||||
FOREIGN_DEPLOYMENT_GAS_PRICE=10000000000
|
||||
GET_RECEIPT_INTERVAL_IN_MILLISECONDS=50
|
||||
DEPLOYMENT_GAS_LIMIT_EXTRA=0.2
|
||||
DEPLOY_REWARDABLE_TOKEN=false
|
||||
|
||||
BRIDGEABLE_TOKEN_NAME="Your New Bridged Token"
|
||||
BRIDGEABLE_TOKEN_SYMBOL="TEST"
|
||||
BRIDGEABLE_TOKEN_DECIMALS="18"
|
||||
|
||||
HOME_RPC_URL=http://parity1:8545
|
||||
HOME_BRIDGE_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
HOME_VALIDATORS_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
HOME_UPGRADEABLE_ADMIN=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
HOME_DAILY_LIMIT=30000000000000000000000000
|
||||
HOME_MAX_AMOUNT_PER_TX=1500000000000000000000000
|
||||
HOME_MIN_AMOUNT_PER_TX=10000000000000000
|
||||
HOME_REQUIRED_BLOCK_CONFIRMATIONS=1
|
||||
HOME_GAS_PRICE=1000000000
|
||||
HOME_REWARDABLE=false
|
||||
|
||||
FOREIGN_RPC_URL=http://parity2:8545
|
||||
FOREIGN_BRIDGE_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
FOREIGN_VALIDATORS_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
FOREIGN_UPGRADEABLE_ADMIN=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
|
||||
FOREIGN_DAILY_LIMIT=15000000000000000000000000
|
||||
FOREIGN_MAX_AMOUNT_PER_TX=750000000000000000000000
|
||||
FOREIGN_MIN_AMOUNT_PER_TX=10000000000000000
|
||||
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS=1
|
||||
FOREIGN_GAS_PRICE=10000000000
|
||||
FOREIGN_REWARDABLE=false
|
||||
|
||||
REQUIRED_NUMBER_OF_VALIDATORS=1
|
||||
VALIDATORS="0xaaB52d66283F7A1D5978bcFcB55721ACB467384b 0xdCC784657C78054aa61FbcFFd2605F32374816A4 0xDcef88209a20D52165230104B245803C3269454d"
|
||||
BLOCK_REWARD_ADDRESS=0x0000000000000000000000000000000000000000
|
@ -27,25 +27,6 @@ services:
|
||||
image: "rabbitmq:3-management"
|
||||
networks:
|
||||
- ultimate
|
||||
oracle:
|
||||
image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-oracle:${ORACLE_TAG:-local}
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: oracle/Dockerfile
|
||||
env_file: ../e2e-commons/components-envs/oracle.env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
command: "true"
|
||||
networks:
|
||||
- ultimate
|
||||
oracle-erc20:
|
||||
image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-oracle:${ORACLE_TAG:-local}
|
||||
env_file: ../e2e-commons/components-envs/oracle-erc20.env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
command: "true"
|
||||
networks:
|
||||
- ultimate
|
||||
oracle-erc20-native:
|
||||
image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-oracle:${ORACLE_TAG:-local}
|
||||
env_file: ../e2e-commons/components-envs/oracle-erc20-native.env
|
||||
@ -59,6 +40,9 @@ services:
|
||||
- ultimate
|
||||
oracle-amb:
|
||||
image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-oracle:${ORACLE_TAG:-local}
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: oracle/Dockerfile
|
||||
env_file: ../e2e-commons/components-envs/oracle-amb.env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
@ -78,25 +62,6 @@ services:
|
||||
command: "true"
|
||||
networks:
|
||||
- ultimate
|
||||
monitor:
|
||||
image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-monitor:${MONITOR_TAG:-local}
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: monitor/Dockerfile
|
||||
env_file: ../e2e-commons/components-envs/monitor.env
|
||||
entrypoint: yarn check-and-start
|
||||
ports:
|
||||
- "3010:3010"
|
||||
networks:
|
||||
- ultimate
|
||||
monitor-erc20:
|
||||
image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-monitor:${MONITOR_TAG:-local}
|
||||
env_file: ../e2e-commons/components-envs/monitor-erc20.env
|
||||
entrypoint: yarn check-and-start
|
||||
ports:
|
||||
- "3011:3011"
|
||||
networks:
|
||||
- ultimate
|
||||
monitor-erc20-native:
|
||||
image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-monitor:${MONITOR_TAG:-local}
|
||||
env_file: ../e2e-commons/components-envs/monitor-erc20-native.env
|
||||
@ -107,6 +72,9 @@ services:
|
||||
- ultimate
|
||||
monitor-amb:
|
||||
image: ${DOCKER_IMAGE_BASE:-tokenbridge}/tokenbridge-e2e-monitor:${MONITOR_TAG:-local}
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: monitor/Dockerfile
|
||||
env_file: ../e2e-commons/components-envs/monitor-amb.env
|
||||
entrypoint: yarn check-and-start
|
||||
ports:
|
||||
|
@ -5,6 +5,7 @@ if [ $CI ]; then exit $rc; fi
|
||||
|
||||
ps | grep node | grep -v grep | grep -v yarn | awk '{print "kill " $1}' | /bin/bash
|
||||
docker-compose down
|
||||
docker-compose -p validator1 down
|
||||
docker-compose -p validator2 down
|
||||
docker-compose -p validator3 down
|
||||
docker network rm ultimate || true
|
||||
|
@ -5,9 +5,11 @@ set -e # exit when any command fails
|
||||
docker-compose pull e2e
|
||||
while [ "$1" != "" ]; do
|
||||
if [ "$1" == "oracle" ]; then
|
||||
docker-compose pull oracle
|
||||
docker-compose pull oracle-amb
|
||||
elif [ "$1" == "alm-e2e" ]; then
|
||||
docker-compose pull oracle-amb
|
||||
elif [ "$1" == "monitor" ]; then
|
||||
docker-compose pull monitor
|
||||
docker-compose pull monitor-amb
|
||||
elif [ "$1" == "alm" ]; then
|
||||
docker-compose pull alm
|
||||
fi
|
||||
|
@ -9,26 +9,13 @@ ENVS_PATH="../contracts-envs"
|
||||
# mock bridge validators contract with the one with deterministic isValidatorDuty
|
||||
mv "$CONTRACTS_PATH/build/contracts/BridgeValidatorsDeterministic.json" "$CONTRACTS_PATH/build/contracts/BridgeValidators.json"
|
||||
|
||||
echo -e "\n\n############ Deploying native-to-erc ############\n"
|
||||
cp "$ENVS_PATH/native-to-erc.env" "$DEPLOY_PATH/.env"
|
||||
cd "$DEPLOY_PATH"
|
||||
node deploy.js
|
||||
cd - > /dev/null
|
||||
|
||||
echo -e "\n\n############ Deploying erc20 and erc-to-erc ############\n"
|
||||
node deployERC20.js
|
||||
cp "$ENVS_PATH/erc-to-erc.env" "$DEPLOY_PATH/.env"
|
||||
cd "$DEPLOY_PATH"
|
||||
node deploy.js
|
||||
cd - > /dev/null
|
||||
|
||||
echo -e "\n\n############ Deploying block reward ############\n"
|
||||
cp "$ENVS_PATH/erc-to-native.env" "$DEPLOY_PATH/.env"
|
||||
cd "$DEPLOY_PATH"
|
||||
node src/utils/deployBlockReward.js
|
||||
cd - > /dev/null
|
||||
|
||||
echo -e "\n\n############ Deploying erc-to-native ############\n"
|
||||
cp "$ENVS_PATH/erc-to-native.env" "$DEPLOY_PATH/.env"
|
||||
cd "$DEPLOY_PATH"
|
||||
node deploy.js
|
||||
cd - > /dev/null
|
||||
|
@ -1,43 +0,0 @@
|
||||
const path = require('path')
|
||||
const { user } = require('../constants.json')
|
||||
const contractsPath = '../../contracts'
|
||||
require('dotenv').config({
|
||||
path: path.join(__dirname, contractsPath, '/deploy/.env')
|
||||
})
|
||||
|
||||
const { deployContract, sendRawTxHome, privateKeyToAddress } = require(`${contractsPath}/deploy/src/deploymentUtils`)
|
||||
const { web3Home, deploymentPrivateKey } = require(`${contractsPath}/deploy/src/web3`)
|
||||
const ERC677BridgeTokenRewardable = require(`${contractsPath}/build/contracts/ERC677BridgeTokenRewardable.json`)
|
||||
|
||||
const { DEPLOYMENT_ACCOUNT_PRIVATE_KEY } = process.env
|
||||
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
|
||||
|
||||
async function deployBridgeTokenRewardable() {
|
||||
try {
|
||||
let homeNonce = await web3Home.eth.getTransactionCount(DEPLOYMENT_ACCOUNT_ADDRESS)
|
||||
console.log('\n[Home] Deploying ERC677BridgeTokenRewardable Test token')
|
||||
const stakeToken = await deployContract(ERC677BridgeTokenRewardable, ['STAKE', 'STAKE', '18', '77'], {
|
||||
from: DEPLOYMENT_ACCOUNT_ADDRESS,
|
||||
network: 'home',
|
||||
nonce: homeNonce
|
||||
})
|
||||
homeNonce++
|
||||
console.log('[Home] Stake Token: ', stakeToken.options.address)
|
||||
|
||||
const mintData = await stakeToken.methods
|
||||
.mint(user.address, '500000000000000000000')
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
await sendRawTxHome({
|
||||
data: mintData,
|
||||
nonce: homeNonce,
|
||||
to: stakeToken.options.address,
|
||||
privateKey: deploymentPrivateKey,
|
||||
url: process.env.HOME_RPC_URL
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
deployBridgeTokenRewardable()
|
@ -1,51 +0,0 @@
|
||||
/* eslint import/no-unresolved: 0 node/no-missing-require: 0 */
|
||||
const path = require('path')
|
||||
const {user} = require('../constants.json')
|
||||
const contractsPath = '../../contracts';
|
||||
require('dotenv').config({
|
||||
path: path.join(__dirname, contractsPath, '/deploy/.env')
|
||||
})
|
||||
|
||||
const {
|
||||
deployContract,
|
||||
sendRawTxForeign,
|
||||
privateKeyToAddress
|
||||
} = require(`${contractsPath}/deploy/src/deploymentUtils`)
|
||||
const {
|
||||
web3Foreign,
|
||||
deploymentPrivateKey
|
||||
} = require(`${contractsPath}/deploy/src/web3`)
|
||||
const POA20 = require(`${contractsPath}/build/contracts/ERC677BridgeToken.json`)
|
||||
|
||||
const { DEPLOYMENT_ACCOUNT_PRIVATE_KEY } = process.env
|
||||
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
|
||||
|
||||
async function deployErc20() {
|
||||
try {
|
||||
let foreignNonce = await web3Foreign.eth.getTransactionCount(DEPLOYMENT_ACCOUNT_ADDRESS)
|
||||
console.log('\n[Foreign] Deploying POA20 Test token')
|
||||
const poa20foreign = await deployContract(POA20, ['POA ERC20 Test', 'POA20', 18], {
|
||||
from: DEPLOYMENT_ACCOUNT_ADDRESS,
|
||||
network: 'foreign',
|
||||
nonce: foreignNonce
|
||||
})
|
||||
foreignNonce++
|
||||
console.log('[Foreign] POA20 Test: ', poa20foreign.options.address)
|
||||
|
||||
const mintData = await poa20foreign.methods
|
||||
.mint(user.address, '500000000000000000000')
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
await sendRawTxForeign({
|
||||
data: mintData,
|
||||
nonce: foreignNonce,
|
||||
to: poa20foreign.options.address,
|
||||
privateKey: deploymentPrivateKey,
|
||||
url: process.env.FOREIGN_RPC_URL
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
deployErc20()
|
@ -1,43 +0,0 @@
|
||||
const path = require('path')
|
||||
const { user } = require('../constants.json')
|
||||
const contractsPath = '../../contracts'
|
||||
require('dotenv').config({
|
||||
path: path.join(__dirname, contractsPath, '/deploy/.env')
|
||||
})
|
||||
|
||||
const { deployContract, sendRawTxForeign, privateKeyToAddress } = require(`${contractsPath}/deploy/src/deploymentUtils`)
|
||||
const { web3Foreign, deploymentPrivateKey } = require(`${contractsPath}/deploy/src/web3`)
|
||||
const ERC677MultiBridgeToken = require(`${contractsPath}/build/contracts/ERC677MultiBridgeToken.json`)
|
||||
|
||||
const { DEPLOYMENT_ACCOUNT_PRIVATE_KEY } = process.env
|
||||
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
|
||||
|
||||
async function deployMultiBridgeToken() {
|
||||
try {
|
||||
let foreignNonce = await web3Foreign.eth.getTransactionCount(DEPLOYMENT_ACCOUNT_ADDRESS)
|
||||
console.log('\n[Foreign] Deploying ERC677MultiBridgeToken Test token')
|
||||
const stakeToken = await deployContract(ERC677MultiBridgeToken, ['STAKE', 'STAKE', '18', '42'], {
|
||||
from: DEPLOYMENT_ACCOUNT_ADDRESS,
|
||||
network: 'foreign',
|
||||
nonce: foreignNonce
|
||||
})
|
||||
foreignNonce++
|
||||
console.log('[Foreign] Stake Token: ', stakeToken.options.address)
|
||||
|
||||
const mintData = await stakeToken.methods
|
||||
.mint(user.address, '500000000000000000000')
|
||||
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
|
||||
await sendRawTxForeign({
|
||||
data: mintData,
|
||||
nonce: foreignNonce,
|
||||
to: stakeToken.options.address,
|
||||
privateKey: deploymentPrivateKey,
|
||||
url: process.env.FOREIGN_RPC_URL
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
deployMultiBridgeToken()
|
@ -15,64 +15,42 @@ docker network create --driver bridge ultimate || true
|
||||
docker-compose up -d parity1 parity2 e2e
|
||||
|
||||
startValidator () {
|
||||
docker-compose $1 run -d --name $4 redis
|
||||
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:collected-signatures
|
||||
docker-compose $1 run $2 $3 -d oracle yarn watcher:affirmation-request
|
||||
fi
|
||||
if [[ -z "$MODE" || "$MODE" == erc-to-erc ]]; then
|
||||
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:signature-request
|
||||
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:collected-signatures
|
||||
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:affirmation-request
|
||||
docker-compose $1 run $2 $3 -d oracle-erc20 yarn watcher:transfer
|
||||
fi
|
||||
db_env="-e ORACLE_QUEUE_URL=amqp://$4 -e ORACLE_REDIS_URL=redis://$3"
|
||||
|
||||
docker-compose $1 run -d --name $3 redis
|
||||
docker-compose $1 run -d --name $4 rabbit
|
||||
|
||||
if [[ -z "$MODE" || "$MODE" == erc-to-native ]]; then
|
||||
docker-compose $1 run $2 $3 -d oracle-erc20-native 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-erc20-native 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
|
||||
docker-compose $1 run $2 $db_env -d oracle-erc20-native yarn watcher:signature-request
|
||||
docker-compose $1 run $2 $db_env -d oracle-erc20-native yarn watcher:collected-signatures
|
||||
docker-compose $1 run $2 $db_env -d oracle-erc20-native yarn watcher:affirmation-request
|
||||
docker-compose $1 run $2 $db_env -d oracle-erc20-native yarn watcher:transfer
|
||||
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
|
||||
docker-compose $1 run $2 $db_env -d oracle-amb yarn watcher:signature-request
|
||||
docker-compose $1 run $2 $db_env -d oracle-amb yarn watcher:collected-signatures
|
||||
docker-compose $1 run $2 $db_env -d oracle-amb yarn watcher:affirmation-request
|
||||
docker-compose $1 run $2 $db_env -d oracle-amb yarn watcher:information-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:foreign
|
||||
docker-compose $1 run $2 $3 -d oracle yarn manager:shutdown
|
||||
}
|
||||
|
||||
startAMBValidator () {
|
||||
docker-compose $1 run -d --name $4 redis
|
||||
docker-compose $1 run -d --name $5 rabbit
|
||||
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
|
||||
docker-compose $1 run $2 $3 -d oracle-amb yarn sender:home
|
||||
docker-compose $1 run $2 $3 -d oracle-amb yarn sender:foreign
|
||||
docker-compose $1 run $2 $3 -d oracle-amb yarn manager:shutdown
|
||||
docker-compose $1 run $2 $db_env -d oracle-amb yarn sender:home
|
||||
docker-compose $1 run $2 $db_env -d oracle-amb yarn sender:foreign
|
||||
docker-compose $1 run $2 $db_env -d oracle-amb yarn manager:shutdown
|
||||
}
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
if [ "$1" == "oracle" ]; then
|
||||
startValidator "" "" "" "redis" "rabbit"
|
||||
startValidator "-p validator1" "" redis rabbit
|
||||
fi
|
||||
|
||||
if [ "$1" == "oracle-validator-2" ]; then
|
||||
oracle2name="-p validator2"
|
||||
oracle2Values="-e ORACLE_VALIDATOR_ADDRESS=0xdCC784657C78054aa61FbcFFd2605F32374816A4 -e ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=5a5c3645d0f04e9eb4f27f94ed4c244a225587405b8838e7456f7781ce3a9513"
|
||||
oracle2comp="-e ORACLE_QUEUE_URL=amqp://rabbit2 -e ORACLE_REDIS_URL=redis://redis2"
|
||||
startValidator "$oracle2name" "$oracle2Values" "$oracle2comp" "redis2" "rabbit2"
|
||||
startValidator "-p validator2" "$oracle2Values" redis2 rabbit2
|
||||
fi
|
||||
|
||||
if [ "$1" == "oracle-validator-3" ]; then
|
||||
oracle3name="-p validator3"
|
||||
oracle3Values="-e ORACLE_VALIDATOR_ADDRESS=0xDcef88209a20D52165230104B245803C3269454d -e ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=f877f62a1c19f852cff1d29f0fb1ecac18821c0080d4cc0520c60c098293dca1"
|
||||
oracle3comp="-e ORACLE_QUEUE_URL=amqp://rabbit3 -e ORACLE_REDIS_URL=redis://redis3"
|
||||
startValidator "$oracle3name" "$oracle3Values" "$oracle3comp" "redis3" "rabbit3"
|
||||
startValidator "-p validator3" "$oracle3Values" redis3 rabbit3
|
||||
fi
|
||||
|
||||
if [ "$1" == "alm" ]; then
|
||||
@ -94,33 +72,25 @@ while [ "$1" != "" ]; do
|
||||
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
|
||||
docker-compose up -d monitor-erc20-native monitor-amb
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ "$1" == "alm-e2e" ]; then
|
||||
startAMBValidator "" "" "" "redis" "rabbit"
|
||||
MODE=amb
|
||||
|
||||
startValidator "-p validator1" "" redis rabbit
|
||||
|
||||
oracle2name="-p validator2"
|
||||
oracle2Values="-e ORACLE_VALIDATOR_ADDRESS=0xdCC784657C78054aa61FbcFFd2605F32374816A4 -e ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=5a5c3645d0f04e9eb4f27f94ed4c244a225587405b8838e7456f7781ce3a9513"
|
||||
oracle2comp="-e ORACLE_QUEUE_URL=amqp://rabbit2 -e ORACLE_REDIS_URL=redis://redis2"
|
||||
startAMBValidator "$oracle2name" "$oracle2Values" "$oracle2comp" "redis2" "rabbit2"
|
||||
startValidator "-p validator2" "$oracle2Values" redis2 rabbit2
|
||||
|
||||
oracle3name="-p validator3"
|
||||
oracle3Values="-e ORACLE_VALIDATOR_ADDRESS=0xDcef88209a20D52165230104B245803C3269454d -e ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=f877f62a1c19f852cff1d29f0fb1ecac18821c0080d4cc0520c60c098293dca1"
|
||||
oracle3comp="-e ORACLE_QUEUE_URL=amqp://rabbit3 -e ORACLE_REDIS_URL=redis://redis3"
|
||||
startAMBValidator "$oracle3name" "$oracle3Values" "$oracle3comp" "redis3" "rabbit3"
|
||||
startValidator "-p validator3" "$oracle3Values" redis3 rabbit3
|
||||
fi
|
||||
|
||||
shift # Shift all the parameters down by one
|
||||
|
@ -14,7 +14,7 @@
|
||||
"axios": "0.19.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.18"
|
||||
"node": ">= 12.22"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
||||
|
@ -1,15 +1,9 @@
|
||||
while true; do
|
||||
docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor yarn check-all
|
||||
pid1=$!
|
||||
docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20 yarn check-all
|
||||
pid2=$!
|
||||
docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-erc20-native yarn check-all
|
||||
pid3=$!
|
||||
pid1=$!
|
||||
docker-compose -f ../e2e-commons/docker-compose.yml exec -T monitor-amb yarn check-all
|
||||
pid4=$!
|
||||
pid2=$!
|
||||
|
||||
wait $pid1
|
||||
wait $pid2
|
||||
wait $pid3
|
||||
wait $pid4
|
||||
done
|
||||
|
@ -5,12 +5,6 @@ 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
|
||||
;;
|
||||
|
@ -1,12 +1,8 @@
|
||||
const assert = require('assert')
|
||||
const axios = require('axios')
|
||||
const { nativeToErcBridge, ercToErcBridge, ercToNativeBridge, validator } = require('../../e2e-commons/constants.json')
|
||||
const { ercToNativeBridge, validator } = require('../../e2e-commons/constants.json')
|
||||
|
||||
const types = [
|
||||
{ description: 'NATIVE TO ERC', baseUrl: nativeToErcBridge.monitor },
|
||||
{ description: 'ERC TO ERC', baseUrl: ercToErcBridge.monitor },
|
||||
{ description: 'ERC TO NATIVE', baseUrl: ercToNativeBridge.monitor }
|
||||
]
|
||||
const types = [{ description: 'ERC TO NATIVE', baseUrl: ercToNativeBridge.monitor }]
|
||||
|
||||
types.forEach(type => {
|
||||
describe(type.description, () => {
|
||||
|
@ -1,43 +0,0 @@
|
||||
const assert = require('assert')
|
||||
const axios = require('axios')
|
||||
const { ercToErcBridge, user, foreignRPC, validator } = require('../../e2e-commons/constants.json')
|
||||
const { waitUntil, sendTokens, addValidator } = require('../utils')
|
||||
|
||||
const baseUrl = ercToErcBridge.monitor
|
||||
|
||||
describe('ERC TO ERC', () => {
|
||||
let data
|
||||
|
||||
before(async () => {
|
||||
;({ data } = await axios.get(`${baseUrl}`))
|
||||
})
|
||||
|
||||
it('balance', () => assert(parseInt(data.foreign.erc20Balance, 10) >= 0))
|
||||
it('should contain totalSupply', () => assert(data.home.totalSupply === '0'))
|
||||
})
|
||||
|
||||
describe('ERC TO ERC with changing state of contracts', () => {
|
||||
let data
|
||||
|
||||
before(async () => {
|
||||
assert((await axios.get(`${baseUrl}`)).data.balanceDiff === 0)
|
||||
assert((await axios.get(`${baseUrl}/validators`)).data.validatorsMatch === true)
|
||||
})
|
||||
|
||||
it('should change balanceDiff', async () => {
|
||||
await sendTokens(foreignRPC.URL, user, ercToErcBridge.foreignToken, ercToErcBridge.foreign)
|
||||
|
||||
await waitUntil(async () => {
|
||||
;({ data } = await axios.get(`${baseUrl}`))
|
||||
return data.balanceDiff !== 0
|
||||
})
|
||||
})
|
||||
|
||||
it('should change validatorsMatch', async () => {
|
||||
await addValidator(foreignRPC.URL, validator, ercToErcBridge.foreign)
|
||||
await waitUntil(async () => {
|
||||
;({ data } = await axios.get(`${baseUrl}/validators`))
|
||||
return data.validatorsMatch === false
|
||||
})
|
||||
})
|
||||
})
|
@ -1,14 +1,7 @@
|
||||
const assert = require('assert')
|
||||
const axios = require('axios')
|
||||
const { ercToNativeBridge, user, foreignRPC, validator } = require('../../e2e-commons/constants.json')
|
||||
const {
|
||||
waitUntil,
|
||||
sendTokens,
|
||||
addValidator,
|
||||
initializeChaiToken,
|
||||
convertDaiToChai,
|
||||
setMinDaiTokenBalance
|
||||
} = require('../utils')
|
||||
const { waitUntil, sendTokens, addValidator } = require('../utils')
|
||||
|
||||
const baseUrl = ercToNativeBridge.monitor
|
||||
|
||||
@ -52,58 +45,4 @@ describe('ERC TO NATIVE with changing state of contracts', () => {
|
||||
return data.validatorsMatch === false
|
||||
})
|
||||
})
|
||||
|
||||
it('should consider chai token balance', async function() {
|
||||
this.timeout(120000)
|
||||
await initializeChaiToken(foreignRPC.URL, ercToNativeBridge.foreign)
|
||||
await sendTokens(foreignRPC.URL, user, ercToNativeBridge.foreignToken, ercToNativeBridge.foreign)
|
||||
|
||||
await waitUntil(async () => {
|
||||
;({ data } = await axios.get(`${baseUrl}`))
|
||||
if (!data.foreign) {
|
||||
return false
|
||||
}
|
||||
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
|
||||
return (
|
||||
data.balanceDiff === 0.02 &&
|
||||
erc20Balance === '0.02' &&
|
||||
investedErc20Balance === '0' &&
|
||||
accumulatedInterest === '0.001' // value of dsrBalance() is initially defined in genesis block as 0.001
|
||||
)
|
||||
})
|
||||
|
||||
await setMinDaiTokenBalance(foreignRPC.URL, ercToNativeBridge.foreign, '0.01')
|
||||
await convertDaiToChai(foreignRPC.URL, ercToNativeBridge.foreign)
|
||||
|
||||
await waitUntil(async () => {
|
||||
;({ data } = await axios.get(`${baseUrl}`))
|
||||
if (!data.foreign) {
|
||||
return false
|
||||
}
|
||||
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
|
||||
return (
|
||||
data.balanceDiff === 0.02 &&
|
||||
erc20Balance === '0.01' &&
|
||||
investedErc20Balance === '0.01' &&
|
||||
accumulatedInterest === '0.001'
|
||||
)
|
||||
})
|
||||
|
||||
await setMinDaiTokenBalance(foreignRPC.URL, ercToNativeBridge.foreign, '0.005')
|
||||
await convertDaiToChai(foreignRPC.URL, ercToNativeBridge.foreign)
|
||||
|
||||
await waitUntil(async () => {
|
||||
;({ data } = await axios.get(`${baseUrl}`))
|
||||
if (!data.foreign) {
|
||||
return false
|
||||
}
|
||||
const { erc20Balance, investedErc20Balance, accumulatedInterest } = data.foreign
|
||||
return (
|
||||
data.balanceDiff === 0.02 &&
|
||||
erc20Balance === '0.005' &&
|
||||
investedErc20Balance === '0.015' &&
|
||||
accumulatedInterest === '0.001'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,43 +0,0 @@
|
||||
const assert = require('assert')
|
||||
const axios = require('axios')
|
||||
const { nativeToErcBridge, user, homeRPC, foreignRPC, validator } = require('../../e2e-commons/constants.json')
|
||||
const { waitUntil, sendEther, addValidator } = require('../utils')
|
||||
|
||||
const baseUrl = nativeToErcBridge.monitor
|
||||
|
||||
describe('NATIVE TO ERC', () => {
|
||||
let data
|
||||
|
||||
before(async () => {
|
||||
;({ data } = await axios.get(`${baseUrl}`))
|
||||
})
|
||||
|
||||
it('balance', () => assert(parseInt(data.home.balance, 10) >= 0))
|
||||
it('should contain totalSupply', () => assert(data.foreign.totalSupply === '0'))
|
||||
})
|
||||
|
||||
describe('NATIVE TO ERC with changing state of contracts', () => {
|
||||
let data
|
||||
|
||||
before(async () => {
|
||||
assert((await axios.get(`${baseUrl}`)).data.balanceDiff === 0)
|
||||
assert((await axios.get(`${baseUrl}/validators`)).data.validatorsMatch === true)
|
||||
})
|
||||
|
||||
it('should change balanceDiff', async () => {
|
||||
await sendEther(homeRPC.URL, user, nativeToErcBridge.home)
|
||||
|
||||
await waitUntil(async () => {
|
||||
;({ data } = await axios.get(`${baseUrl}`))
|
||||
return data.balanceDiff !== 0
|
||||
})
|
||||
})
|
||||
|
||||
it('should change validatorsMatch', async () => {
|
||||
await addValidator(foreignRPC.URL, validator, nativeToErcBridge.foreign)
|
||||
await waitUntil(async () => {
|
||||
;({ data } = await axios.get(`${baseUrl}/validators`))
|
||||
return data.validatorsMatch === false
|
||||
})
|
||||
})
|
||||
})
|
@ -1,12 +1,5 @@
|
||||
const Web3 = require('web3')
|
||||
const {
|
||||
ERC677_BRIDGE_TOKEN_ABI,
|
||||
BRIDGE_VALIDATORS_ABI,
|
||||
FOREIGN_NATIVE_TO_ERC_ABI,
|
||||
FOREIGN_ERC_TO_NATIVE_ABI,
|
||||
BOX_ABI
|
||||
} = require('../commons')
|
||||
const { validator } = require('../e2e-commons/constants')
|
||||
const { ERC20_ABI, BRIDGE_VALIDATORS_ABI, FOREIGN_ERC_TO_NATIVE_ABI, BOX_ABI } = require('../commons')
|
||||
|
||||
const waitUntil = async (predicate, step = 100, timeout = 60000) => {
|
||||
const stopTime = Date.now() + timeout
|
||||
@ -36,7 +29,7 @@ const sendEther = async (rpcUrl, account, to) => {
|
||||
const sendTokens = async (rpcUrl, account, tokenAddress, recipientAddress) => {
|
||||
const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl))
|
||||
web3.eth.accounts.wallet.add(account.privateKey)
|
||||
const erc20Token = new web3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, tokenAddress)
|
||||
const erc20Token = new web3.eth.Contract(ERC20_ABI, tokenAddress)
|
||||
|
||||
await erc20Token.methods.transfer(recipientAddress, web3.utils.toWei('0.01')).send({
|
||||
from: account.address,
|
||||
@ -62,7 +55,7 @@ const sendAMBMessage = async (rpcUrl, account, boxAddress, bridgeAddress, boxOth
|
||||
const addValidator = async (rpcUrl, account, bridgeAddress) => {
|
||||
const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl))
|
||||
web3.eth.accounts.wallet.add(account.privateKey)
|
||||
const bridgeContract = new web3.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, bridgeAddress)
|
||||
const bridgeContract = new web3.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, bridgeAddress)
|
||||
const foreignValidatorsAddress = await bridgeContract.methods.validatorContract().call()
|
||||
const foreignBridgeValidators = new web3.eth.Contract(BRIDGE_VALIDATORS_ABI, foreignValidatorsAddress)
|
||||
await foreignBridgeValidators.methods.addValidator('0xE71FBa5db00172bb0C93d649362B006300000935').send({
|
||||
@ -71,46 +64,10 @@ const addValidator = async (rpcUrl, account, bridgeAddress) => {
|
||||
})
|
||||
}
|
||||
|
||||
const initializeChaiToken = async (rpcUrl, bridgeAddress) => {
|
||||
const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl))
|
||||
web3.eth.accounts.wallet.add(validator.privateKey)
|
||||
const bridgeContract = new web3.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, bridgeAddress)
|
||||
|
||||
await bridgeContract.methods.initializeChaiToken().send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
}
|
||||
|
||||
const setMinDaiTokenBalance = async (rpcUrl, bridgeAddress, limit) => {
|
||||
const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl))
|
||||
web3.eth.accounts.wallet.add(validator.privateKey)
|
||||
const bridgeContract = new web3.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, bridgeAddress)
|
||||
|
||||
await bridgeContract.methods.setMinDaiTokenBalance(web3.utils.toWei(limit)).send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
}
|
||||
|
||||
const convertDaiToChai = async (rpcUrl, bridgeAddress) => {
|
||||
const web3 = new Web3(new Web3.providers.HttpProvider(rpcUrl))
|
||||
web3.eth.accounts.wallet.add(validator.privateKey)
|
||||
const bridgeContract = new web3.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, bridgeAddress)
|
||||
|
||||
await bridgeContract.methods.convertDaiToChai().send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
waitUntil,
|
||||
sendEther,
|
||||
sendTokens,
|
||||
addValidator,
|
||||
sendAMBMessage,
|
||||
initializeChaiToken,
|
||||
setMinDaiTokenBalance,
|
||||
convertDaiToChai
|
||||
sendAMBMessage
|
||||
}
|
||||
|
@ -6,12 +6,6 @@ check_files_exist() {
|
||||
rc=0
|
||||
for f in "${FILES[@]}"; do
|
||||
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
|
||||
fi
|
||||
if [[ -z "$MODE" || "$MODE" == erc-to-erc ]]; then
|
||||
(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
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM node:10 as contracts
|
||||
FROM node:12 as contracts
|
||||
|
||||
WORKDIR /mono
|
||||
|
||||
@ -11,7 +11,7 @@ COPY ./contracts/truffle-config.js ./
|
||||
COPY ./contracts/contracts ./contracts
|
||||
RUN npm run compile
|
||||
|
||||
FROM node:10
|
||||
FROM node:12
|
||||
|
||||
WORKDIR /mono
|
||||
COPY package.json .
|
||||
|
@ -12,12 +12,12 @@ const { web3Home } = require('./utils/web3')
|
||||
|
||||
const { COMMON_HOME_BRIDGE_ADDRESS, MONITOR_BRIDGE_NAME } = process.env
|
||||
|
||||
const { HOME_ERC_TO_ERC_ABI } = require('../commons')
|
||||
const { HOME_ERC_TO_NATIVE_ABI } = require('../commons')
|
||||
|
||||
async function checkWorker() {
|
||||
try {
|
||||
createDir(`/responses/${MONITOR_BRIDGE_NAME}`)
|
||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_NATIVE_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const bridgeMode = await getBridgeMode(homeBridge)
|
||||
logger.debug('Bridge mode:', bridgeMode)
|
||||
logger.debug('calling getEventsInfo()')
|
||||
|
@ -1,6 +1,5 @@
|
||||
require('dotenv').config()
|
||||
const logger = require('./logger')('checkWorker3')
|
||||
const stuckTransfers = require('./stuckTransfers')
|
||||
const detectMediators = require('./detectMediators')
|
||||
const detectFailures = require('./detectFailures')
|
||||
const { writeFile, createDir } = require('./utils/file')
|
||||
@ -8,22 +7,13 @@ const { web3Home } = require('./utils/web3')
|
||||
const { saveCache } = require('./utils/web3Cache')
|
||||
|
||||
const { MONITOR_BRIDGE_NAME, COMMON_HOME_BRIDGE_ADDRESS } = process.env
|
||||
const { getBridgeMode, HOME_NATIVE_TO_ERC_ABI, BRIDGE_MODES } = require('../commons')
|
||||
const { getBridgeMode, HOME_ERC_TO_NATIVE_ABI, BRIDGE_MODES } = require('../commons')
|
||||
|
||||
async function checkWorker3() {
|
||||
try {
|
||||
const homeBridge = new web3Home.eth.Contract(HOME_NATIVE_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_NATIVE_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const bridgeMode = await getBridgeMode(homeBridge)
|
||||
if (bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC_V1) {
|
||||
createDir(`/responses/${MONITOR_BRIDGE_NAME}`)
|
||||
logger.debug('calling stuckTransfers()')
|
||||
const transfers = await stuckTransfers()
|
||||
if (!transfers) throw new Error('transfers is empty: ' + JSON.stringify(transfers))
|
||||
transfers.ok = transfers.total.length === 0
|
||||
transfers.health = true
|
||||
writeFile(`/responses/${MONITOR_BRIDGE_NAME}/stuckTransfers.json`, transfers)
|
||||
logger.debug('Done')
|
||||
} else if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
||||
if (bridgeMode === BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
||||
createDir(`/responses/${MONITOR_BRIDGE_NAME}`)
|
||||
|
||||
logger.debug('calling detectMediators()')
|
||||
|
@ -12,23 +12,13 @@ const {
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS
|
||||
} = process.env
|
||||
|
||||
const {
|
||||
ERC20_ABI,
|
||||
ERC677_ABI,
|
||||
BLOCK_REWARD_ABI,
|
||||
HOME_ERC_TO_ERC_ABI,
|
||||
HOME_ERC_TO_NATIVE_ABI,
|
||||
FOREIGN_ERC_TO_ERC_ABI,
|
||||
FOREIGN_ERC_TO_NATIVE_ABI,
|
||||
FOREIGN_NATIVE_TO_ERC_ABI
|
||||
} = require('../commons')
|
||||
const { ERC20_ABI, BLOCK_REWARD_ABI, HOME_ERC_TO_NATIVE_ABI, FOREIGN_ERC_TO_NATIVE_ABI } = require('../commons')
|
||||
|
||||
async function main(bridgeMode, eventsInfo) {
|
||||
const {
|
||||
homeBlockNumber,
|
||||
foreignBlockNumber,
|
||||
homeToForeignConfirmations,
|
||||
foreignToHomeConfirmations,
|
||||
homeDelayedBlockNumber,
|
||||
foreignDelayedBlockNumber
|
||||
} = eventsInfo
|
||||
@ -44,14 +34,6 @@ async function main(bridgeMode, eventsInfo) {
|
||||
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)
|
||||
)
|
||||
|
||||
const blockRanges = {
|
||||
startBlockHome: MONITOR_HOME_START_BLOCK,
|
||||
@ -60,59 +42,7 @@ async function main(bridgeMode, eventsInfo) {
|
||||
endBlockForeign: foreignBlockNumber
|
||||
}
|
||||
|
||||
if (bridgeMode === BRIDGE_MODES.ERC_TO_ERC) {
|
||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
const erc20Address = await foreignBridge.methods.erc20token().call()
|
||||
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
||||
logger.debug('calling erc20Contract.methods.balanceOf')
|
||||
const foreignErc20Balance = await erc20Contract.methods
|
||||
.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
.call({}, foreignDelayedBlockNumber)
|
||||
const homeBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
logger.debug('calling homeBridge.methods.erc677token')
|
||||
const tokenAddress = await homeBridge.methods.erc677token().call()
|
||||
const tokenContract = new web3Home.eth.Contract(ERC677_ABI, tokenAddress)
|
||||
logger.debug('calling tokenContract.methods.totalSupply()')
|
||||
const totalSupply = await tokenContract.methods.totalSupply().call({}, homeDelayedBlockNumber)
|
||||
const foreignBalanceBN = new BN(foreignErc20Balance).plus(lateForeignConfirmationsTotalValue)
|
||||
const foreignTotalSupplyBN = new BN(totalSupply).plus(lateHomeConfirmationsTotalValue)
|
||||
const diff = foreignBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
||||
logger.debug('Done')
|
||||
return {
|
||||
home: {
|
||||
totalSupply: Web3Utils.fromWei(totalSupply)
|
||||
},
|
||||
foreign: {
|
||||
erc20Balance: Web3Utils.fromWei(foreignErc20Balance)
|
||||
},
|
||||
balanceDiff: Number(Web3Utils.fromWei(diff)),
|
||||
...blockRanges,
|
||||
lastChecked: Math.floor(Date.now() / 1000)
|
||||
}
|
||||
} else if (bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC || bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC_V1) {
|
||||
logger.debug('calling web3Home.eth.getBalance')
|
||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
const erc20Address = await foreignBridge.methods.erc677token().call()
|
||||
const homeBalance = await web3Home.eth.getBalance(COMMON_HOME_BRIDGE_ADDRESS, homeDelayedBlockNumber)
|
||||
const tokenContract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
||||
logger.debug('calling tokenContract.methods.totalSupply()')
|
||||
const totalSupply = await tokenContract.methods.totalSupply().call({}, foreignDelayedBlockNumber)
|
||||
const homeBalanceBN = new BN(homeBalance).plus(lateHomeConfirmationsTotalValue)
|
||||
const foreignTotalSupplyBN = new BN(totalSupply).plus(lateForeignConfirmationsTotalValue)
|
||||
const diff = homeBalanceBN.minus(foreignTotalSupplyBN).toString(10)
|
||||
logger.debug('Done')
|
||||
return {
|
||||
home: {
|
||||
balance: Web3Utils.fromWei(homeBalance)
|
||||
},
|
||||
foreign: {
|
||||
totalSupply: Web3Utils.fromWei(totalSupply)
|
||||
},
|
||||
balanceDiff: Number(Web3Utils.fromWei(diff)),
|
||||
...blockRanges,
|
||||
lastChecked: Math.floor(Date.now() / 1000)
|
||||
}
|
||||
} else if (bridgeMode === BRIDGE_MODES.ERC_TO_NATIVE) {
|
||||
if (bridgeMode === BRIDGE_MODES.ERC_TO_NATIVE) {
|
||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
const erc20Address = await foreignBridge.methods.erc20token().call()
|
||||
const erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
||||
|
@ -22,7 +22,7 @@
|
||||
"web3": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.18"
|
||||
"node": ">= 12.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0"
|
||||
|
@ -39,7 +39,7 @@ async function getPrometheusMetrics(bridgeName) {
|
||||
const { home, foreign, ...commonBalances } = balancesFile
|
||||
|
||||
const balanceMetrics = {
|
||||
// ERC_TO_ERC or ERC_TO_NATIVE mode
|
||||
// ERC_TO_NATIVE mode
|
||||
balances_home_value: home.totalSupply,
|
||||
balances_home_txs_deposit: home.deposits,
|
||||
balances_home_txs_withdrawal: home.withdrawals,
|
||||
|
@ -1,105 +0,0 @@
|
||||
require('dotenv').config()
|
||||
const logger = require('./logger')('stuckTransfers.js')
|
||||
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 MONITOR_FOREIGN_START_BLOCK = Number(process.env.MONITOR_FOREIGN_START_BLOCK) || 0
|
||||
|
||||
const ABITransferWithoutData = [
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: true,
|
||||
name: 'from',
|
||||
type: 'address'
|
||||
},
|
||||
{
|
||||
indexed: true,
|
||||
name: 'to',
|
||||
type: 'address'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'value',
|
||||
type: 'uint256'
|
||||
}
|
||||
],
|
||||
name: 'Transfer',
|
||||
type: 'event'
|
||||
}
|
||||
]
|
||||
|
||||
const ABIWithData = [
|
||||
{
|
||||
anonymous: false,
|
||||
inputs: [
|
||||
{
|
||||
indexed: true,
|
||||
name: 'from',
|
||||
type: 'address'
|
||||
},
|
||||
{
|
||||
indexed: true,
|
||||
name: 'to',
|
||||
type: 'address'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'value',
|
||||
type: 'uint256'
|
||||
},
|
||||
{
|
||||
indexed: false,
|
||||
name: 'data',
|
||||
type: 'bytes'
|
||||
}
|
||||
],
|
||||
name: 'Transfer',
|
||||
type: 'event'
|
||||
}
|
||||
]
|
||||
|
||||
function transferWithoutCallback(transfersNormal) {
|
||||
const txHashes = new Set()
|
||||
transfersNormal.forEach(transfer => txHashes.add(transfer.transactionHash))
|
||||
return withData => !txHashes.has(withData.transactionHash)
|
||||
}
|
||||
|
||||
async function main() {
|
||||
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 tokenContract = new web3Foreign.eth.Contract(ABITransferWithoutData, 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')
|
||||
const options = {
|
||||
event: 'Transfer',
|
||||
options: {
|
||||
filter: {
|
||||
to: COMMON_FOREIGN_BRIDGE_ADDRESS
|
||||
}
|
||||
},
|
||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||
toBlock: foreignBlockNumber,
|
||||
chain: 'foreign',
|
||||
safeToBlock: foreignDelayedBlockNumber
|
||||
}
|
||||
const transfersNormal = await getPastEvents(tokenContract, options)
|
||||
logger.debug('calling tokenContractWithData.getPastEvents Transfer')
|
||||
const transfersWithData = await getPastEvents(tokenContractWithData, options)
|
||||
const stuckTransfers = transfersNormal.filter(transferWithoutCallback(transfersWithData))
|
||||
logger.debug('Done')
|
||||
return {
|
||||
stuckTransfers,
|
||||
total: stuckTransfers.length,
|
||||
lastChecked: Math.floor(Date.now() / 1000)
|
||||
}
|
||||
}
|
||||
module.exports = main
|
@ -2,13 +2,10 @@ require('dotenv').config()
|
||||
const logger = require('../logger')('eventsUtils')
|
||||
const {
|
||||
BRIDGE_MODES,
|
||||
ERC_TYPES,
|
||||
getBridgeABIs,
|
||||
getBridgeMode,
|
||||
HOME_ERC_TO_ERC_ABI,
|
||||
HOME_ERC_TO_NATIVE_ABI,
|
||||
ERC20_ABI,
|
||||
ERC677_BRIDGE_TOKEN_ABI,
|
||||
getTokenType,
|
||||
ZERO_ADDRESS,
|
||||
OLD_AMB_USER_REQUEST_FOR_SIGNATURE_ABI,
|
||||
OLD_AMB_USER_REQUEST_FOR_AFFIRMATION_ABI
|
||||
@ -34,24 +31,18 @@ async function main(mode) {
|
||||
}
|
||||
}
|
||||
|
||||
const homeErcBridge = new web3Home.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const homeErcBridge = new web3Home.eth.Contract(HOME_ERC_TO_NATIVE_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const bridgeMode = mode || (await getBridgeMode(homeErcBridge))
|
||||
const { HOME_ABI, FOREIGN_ABI } = getBridgeABIs(bridgeMode)
|
||||
const homeBridge = new web3Home.eth.Contract(HOME_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const foreignBridge = new web3Foreign.eth.Contract(FOREIGN_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
const v1Bridge = bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC_V1
|
||||
let isExternalErc20
|
||||
let isExternalErc20 = false
|
||||
let erc20Contract
|
||||
let erc20Address
|
||||
let normalizeEvent = normalizeEventInformation
|
||||
if (bridgeMode !== BRIDGE_MODES.ARBITRARY_MESSAGE) {
|
||||
const erc20MethodName = bridgeMode === BRIDGE_MODES.NATIVE_TO_ERC || v1Bridge ? 'erc677token' : 'erc20token'
|
||||
erc20Address = await foreignBridge.methods[erc20MethodName]().call()
|
||||
const tokenType = await getTokenType(
|
||||
new web3Foreign.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, erc20Address),
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS
|
||||
)
|
||||
isExternalErc20 = tokenType === ERC_TYPES.ERC20
|
||||
erc20Address = await foreignBridge.methods.erc20token().call()
|
||||
isExternalErc20 = true
|
||||
erc20Contract = new web3Foreign.eth.Contract(ERC20_ABI, erc20Address)
|
||||
} else {
|
||||
normalizeEvent = e => e
|
||||
@ -104,7 +95,7 @@ async function main(mode) {
|
||||
|
||||
logger.debug("calling homeBridge.getPastEvents('UserRequestForSignature')")
|
||||
const homeToForeignRequestsNew = (await getPastEvents(homeBridge, {
|
||||
event: v1Bridge ? 'Deposit' : 'UserRequestForSignature',
|
||||
event: 'UserRequestForSignature',
|
||||
fromBlock: homeMigrationBlock,
|
||||
toBlock: homeDelayedBlockNumber,
|
||||
chain: 'home'
|
||||
@ -113,7 +104,7 @@ async function main(mode) {
|
||||
|
||||
logger.debug("calling foreignBridge.getPastEvents('RelayedMessage')")
|
||||
const homeToForeignConfirmations = (await getPastEvents(foreignBridge, {
|
||||
event: v1Bridge ? 'Deposit' : 'RelayedMessage',
|
||||
event: 'RelayedMessage',
|
||||
fromBlock: MONITOR_FOREIGN_START_BLOCK,
|
||||
toBlock: foreignBlockNumber,
|
||||
chain: 'foreign',
|
||||
@ -122,7 +113,7 @@ async function main(mode) {
|
||||
|
||||
logger.debug("calling homeBridge.getPastEvents('AffirmationCompleted')")
|
||||
const foreignToHomeConfirmations = (await getPastEvents(homeBridge, {
|
||||
event: v1Bridge ? 'Withdraw' : 'AffirmationCompleted',
|
||||
event: 'AffirmationCompleted',
|
||||
fromBlock: MONITOR_HOME_START_BLOCK,
|
||||
toBlock: homeBlockNumber,
|
||||
chain: 'home',
|
||||
@ -131,7 +122,7 @@ async function main(mode) {
|
||||
|
||||
logger.debug("calling foreignBridge.getPastEvents('UserRequestForAffirmation')")
|
||||
const foreignToHomeRequestsNew = (await getPastEvents(foreignBridge, {
|
||||
event: v1Bridge ? 'Withdraw' : 'UserRequestForAffirmation',
|
||||
event: 'UserRequestForAffirmation',
|
||||
fromBlock: foreignMigrationBlock,
|
||||
toBlock: foreignDelayedBlockNumber,
|
||||
chain: 'foreign'
|
||||
|
@ -4,11 +4,9 @@
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "mocha",
|
||||
"start": "mocha --exit",
|
||||
"lint": "eslint . --ignore-path ../.eslintignore",
|
||||
"amb": "mocha test/amb.js",
|
||||
"native-to-erc": "mocha test/nativeToErc.js",
|
||||
"erc-to-erc": "mocha test/ercToErc.js",
|
||||
"erc-to-native": "mocha test/ercToNative.js",
|
||||
"alm": "mocha test/amb.js"
|
||||
},
|
||||
@ -21,11 +19,11 @@
|
||||
"promise-retry": "^1.1.1",
|
||||
"shelljs": "^0.8.2",
|
||||
"tree-kill": "^1.2.0",
|
||||
"web3": "1.0.0-beta.34",
|
||||
"web3": "^1.3.0",
|
||||
"websocket": "^1.0.28"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.18"
|
||||
"node": ">= 12.22"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
||||
|
@ -5,12 +5,6 @@ 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
|
||||
;;
|
||||
|
@ -10,23 +10,47 @@ const { toBN } = Web3.utils
|
||||
const homeWeb3 = new Web3(new Web3.providers.HttpProvider(homeRPC.URL))
|
||||
const foreignWeb3 = new Web3(new Web3.providers.HttpProvider(foreignRPC.URL))
|
||||
|
||||
const COMMON_HOME_BRIDGE_ADDRESS = amb.home
|
||||
const COMMON_FOREIGN_BRIDGE_ADDRESS = amb.foreign
|
||||
|
||||
homeWeb3.eth.accounts.wallet.add(user.privateKey)
|
||||
homeWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(user.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||
|
||||
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 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 opts = {
|
||||
from: user.address,
|
||||
gas: 400000,
|
||||
gasPrice: '1'
|
||||
}
|
||||
const homeBox = new homeWeb3.eth.Contract(BOX_ABI, amb.homeBox, opts)
|
||||
const blockHomeBox = new homeWeb3.eth.Contract(BOX_ABI, amb.blockedHomeBox, opts)
|
||||
const foreignBox = new foreignWeb3.eth.Contract(BOX_ABI, amb.foreignBox, opts)
|
||||
const homeBridge = new homeWeb3.eth.Contract(HOME_AMB_ABI, amb.home, opts)
|
||||
const foreignBridge = new foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, amb.foreign, opts)
|
||||
|
||||
describe('arbitrary message bridging', () => {
|
||||
let requiredSignatures = 1
|
||||
before(async () => {
|
||||
const allowedMethods = [
|
||||
'eth_call(address,bytes)',
|
||||
'eth_call(address,bytes,uint256)',
|
||||
'eth_call(address,address,uint256,bytes)',
|
||||
'eth_blockNumber()',
|
||||
'eth_getBlockByNumber()',
|
||||
'eth_getBlockByNumber(uint256)',
|
||||
'eth_getBlockByHash(bytes32)',
|
||||
'eth_getBalance(address)',
|
||||
'eth_getBalance(address,uint256)',
|
||||
'eth_getTransactionCount(address)',
|
||||
'eth_getTransactionCount(address,uint256)',
|
||||
'eth_getTransactionByHash(bytes32)',
|
||||
'eth_getTransactionReceipt(bytes32)',
|
||||
'eth_getStorageAt(address,bytes32)',
|
||||
'eth_getStorageAt(address,bytes32,uint256)'
|
||||
]
|
||||
for (const method of allowedMethods) {
|
||||
const selector = homeWeb3.utils.soliditySha3(method)
|
||||
await homeBridge.methods.enableAsyncRequestSelector(selector, true).send({ from: validator.address })
|
||||
}
|
||||
|
||||
// Only 1 validator is used in ultimate tests
|
||||
if (process.env.ULTIMATE === 'true') {
|
||||
return
|
||||
@ -66,10 +90,7 @@ describe('arbitrary message bridging', () => {
|
||||
|
||||
await homeBox.methods
|
||||
.setValueOnOtherNetwork(newValue, amb.home, amb.foreignBox)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '400000'
|
||||
})
|
||||
.send()
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
@ -98,10 +119,7 @@ describe('arbitrary message bridging', () => {
|
||||
|
||||
await blockHomeBox.methods
|
||||
.setValueOnOtherNetwork(newValue, amb.home, amb.foreignBox)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '400000'
|
||||
})
|
||||
.send()
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
@ -137,10 +155,7 @@ describe('arbitrary message bridging', () => {
|
||||
|
||||
await homeBox.methods
|
||||
.setValueOnOtherNetworkUsingManualLane(newValue, amb.home, amb.foreignBox)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '400000'
|
||||
})
|
||||
.send()
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
@ -173,10 +188,7 @@ describe('arbitrary message bridging', () => {
|
||||
|
||||
await foreignBox.methods
|
||||
.setValueOnOtherNetwork(newValue, amb.foreign, amb.homeBox)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '400000'
|
||||
})
|
||||
.send()
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
@ -191,4 +203,363 @@ describe('arbitrary message bridging', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('Home to Foreign Async Call', () => {
|
||||
async function makeAsyncCall(selector, data) {
|
||||
const prevMessageId = await homeBox.methods.messageId().call()
|
||||
|
||||
await homeBox.methods
|
||||
.makeAsyncCall(amb.home, selector, data)
|
||||
.send()
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
// check that value changed and balance decreased
|
||||
await uniformRetry(async retry => {
|
||||
const messageId = await homeBox.methods.messageId().call()
|
||||
if (messageId === prevMessageId) {
|
||||
retry()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
it('should make async eth_call', async () => {
|
||||
const foreignValue = await foreignBox.methods.value().call()
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_call(address,bytes)')
|
||||
const data = homeWeb3.eth.abi.encodeParameters(
|
||||
['address', 'bytes'],
|
||||
[amb.foreignBox, foreignBox.methods.value().encodeABI()]
|
||||
)
|
||||
|
||||
await makeAsyncCall(selector, data)
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
assert.strictEqual(
|
||||
await homeBox.methods.data().call(),
|
||||
homeWeb3.eth.abi.encodeParameters(['bytes'], [homeWeb3.eth.abi.encodeParameter('uint256', foreignValue)]),
|
||||
'returned data is incorrect'
|
||||
)
|
||||
})
|
||||
|
||||
it('should make async eth_call with 4 arguments', async () => {
|
||||
const foreignValue = await foreignBox.methods.value().call()
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_call(address,address,uint256,bytes)')
|
||||
const data1 = homeWeb3.eth.abi.encodeParameters(
|
||||
['address', 'address', 'uint256', 'bytes'],
|
||||
[amb.foreignBox, user.address, '100000', foreignBox.methods.value().encodeABI()]
|
||||
)
|
||||
|
||||
await makeAsyncCall(selector, data1)
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
assert.strictEqual(
|
||||
await homeBox.methods.data().call(),
|
||||
homeWeb3.eth.abi.encodeParameters(['bytes'], [homeWeb3.eth.abi.encodeParameter('uint256', foreignValue)]),
|
||||
'returned data is incorrect'
|
||||
)
|
||||
|
||||
const data2 = homeWeb3.eth.abi.encodeParameters(
|
||||
['address', 'address', 'uint256', 'bytes'],
|
||||
[amb.foreignBox, user.address, '1000', foreignBox.methods.value().encodeABI()]
|
||||
)
|
||||
|
||||
await makeAsyncCall(selector, data2)
|
||||
|
||||
assert(!(await homeBox.methods.status().call()), 'status is true')
|
||||
assert.strictEqual(await homeBox.methods.data().call(), null, 'returned data is incorrect')
|
||||
|
||||
const data3 = homeWeb3.eth.abi.encodeParameters(
|
||||
['address', 'address', 'uint256', 'bytes'],
|
||||
[amb.foreignBox, user.address, '21300', foreignBox.methods.value().encodeABI()]
|
||||
)
|
||||
|
||||
await makeAsyncCall(selector, data3)
|
||||
|
||||
assert(!(await homeBox.methods.status().call()), 'status is true')
|
||||
assert.strictEqual(await homeBox.methods.data().call(), null, 'returned data is incorrect')
|
||||
})
|
||||
|
||||
it('should make async eth_call for specific block', async () => {
|
||||
const foreignValue = await foreignBox.methods.value().call()
|
||||
const blockNumber = await foreignWeb3.eth.getBlockNumber()
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_call(address,bytes,uint256)')
|
||||
const data1 = homeWeb3.eth.abi.encodeParameters(
|
||||
['address', 'bytes', 'uint256'],
|
||||
[amb.foreignBox, foreignBox.methods.value().encodeABI(), 60]
|
||||
)
|
||||
const data2 = homeWeb3.eth.abi.encodeParameters(
|
||||
['address', 'bytes', 'uint256'],
|
||||
[amb.foreignBox, foreignBox.methods.value().encodeABI(), blockNumber - 2]
|
||||
)
|
||||
const data3 = homeWeb3.eth.abi.encodeParameters(
|
||||
['address', 'bytes', 'uint256'],
|
||||
[amb.foreignBox, foreignBox.methods.value().encodeABI(), blockNumber + 20]
|
||||
)
|
||||
|
||||
await makeAsyncCall(selector, data1)
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
assert.strictEqual(
|
||||
await homeBox.methods.data().call(),
|
||||
homeWeb3.eth.abi.encodeParameters(['bytes'], [homeWeb3.eth.abi.encodeParameter('uint256', 0)]),
|
||||
'returned data is incorrect'
|
||||
)
|
||||
|
||||
await makeAsyncCall(selector, data2)
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
assert.strictEqual(
|
||||
await homeBox.methods.data().call(),
|
||||
homeWeb3.eth.abi.encodeParameters(['bytes'], [homeWeb3.eth.abi.encodeParameter('uint256', foreignValue)]),
|
||||
'returned data is incorrect'
|
||||
)
|
||||
|
||||
await makeAsyncCall(selector, data3)
|
||||
|
||||
assert(!(await homeBox.methods.status().call()), 'status is true')
|
||||
})
|
||||
|
||||
it('should make async eth_blockNumber', async () => {
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_blockNumber()')
|
||||
|
||||
await makeAsyncCall(selector, '0x')
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
assert.strictEqual((await homeBox.methods.data().call()).length, 66, 'invalid block number')
|
||||
})
|
||||
|
||||
it('should make async eth_getBlockByNumber', async () => {
|
||||
const blockNumber = ((await foreignWeb3.eth.getBlockNumber()) - 5).toString()
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getBlockByNumber(uint256)')
|
||||
|
||||
await makeAsyncCall(selector, homeWeb3.eth.abi.encodeParameter('uint256', blockNumber))
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
const data = await homeBox.methods.data().call()
|
||||
assert.strictEqual(data.length, 2 + 64 * 3)
|
||||
const { 0: number, 1: hash, 2: miner } = homeWeb3.eth.abi.decodeParameters(
|
||||
['uint256', 'bytes32', 'address'],
|
||||
data
|
||||
)
|
||||
const block = await foreignWeb3.eth.getBlock(blockNumber)
|
||||
assert.strictEqual(number, blockNumber, 'wrong block number returned')
|
||||
assert.strictEqual(hash, block.hash, 'wrong block hash returned')
|
||||
assert.strictEqual(miner, block.miner, 'wrong block miner returned')
|
||||
})
|
||||
|
||||
it('should make async eth_getBlockByNumber and return latest block', async () => {
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getBlockByNumber()')
|
||||
|
||||
await makeAsyncCall(selector, '0x')
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
const data = await homeBox.methods.data().call()
|
||||
assert.strictEqual(data.length, 2 + 64 * 3)
|
||||
})
|
||||
|
||||
it('should make async eth_getBlockByHash', async () => {
|
||||
const blockNumber = ((await foreignWeb3.eth.getBlockNumber()) - 5).toString()
|
||||
const block = await foreignWeb3.eth.getBlock(blockNumber)
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getBlockByHash(bytes32)')
|
||||
|
||||
await makeAsyncCall(selector, block.hash)
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
const data = await homeBox.methods.data().call()
|
||||
assert.strictEqual(data.length, 2 + 64 * 3)
|
||||
|
||||
const { 0: number, 1: hash, 2: miner } = homeWeb3.eth.abi.decodeParameters(
|
||||
['uint256', 'bytes32', 'address'],
|
||||
data
|
||||
)
|
||||
|
||||
assert.strictEqual(number, blockNumber, 'wrong block number returned')
|
||||
assert.strictEqual(hash, block.hash, 'wrong block hash returned')
|
||||
assert.strictEqual(miner, block.miner, 'wrong block miner returned')
|
||||
})
|
||||
|
||||
it('should make async eth_getBalance', async () => {
|
||||
const balance = await foreignWeb3.eth.getBalance(user.address)
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getBalance(address)')
|
||||
|
||||
await makeAsyncCall(selector, homeWeb3.eth.abi.encodeParameter('address', user.address))
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
const data = await homeBox.methods.data().call()
|
||||
assert.strictEqual(data.length, 2 + 64)
|
||||
|
||||
assert.strictEqual(homeWeb3.eth.abi.decodeParameter('uint256', data), balance, 'wrong user balance returned')
|
||||
})
|
||||
|
||||
it('should make async eth_getBalance for specific block', async () => {
|
||||
const balance = await foreignWeb3.eth.getBalance(user.address)
|
||||
const { blockNumber } = await foreignWeb3.eth.sendTransaction({
|
||||
to: user.address,
|
||||
value: 1,
|
||||
from: user.address,
|
||||
gas: 21000
|
||||
})
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getBalance(address,uint256)')
|
||||
|
||||
const data1 = homeWeb3.eth.abi.encodeParameters(['address', 'uint256'], [user.address, blockNumber - 1])
|
||||
const data2 = homeWeb3.eth.abi.encodeParameters(['address', 'uint256'], [user.address, blockNumber])
|
||||
await makeAsyncCall(selector, data1)
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
let data = await homeBox.methods.data().call()
|
||||
assert.strictEqual(data.length, 2 + 64)
|
||||
|
||||
assert.strictEqual(homeWeb3.eth.abi.decodeParameter('uint256', data), balance, 'wrong user balance returned')
|
||||
|
||||
await makeAsyncCall(selector, data2)
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
data = await homeBox.methods.data().call()
|
||||
assert.strictEqual(data.length, 2 + 64)
|
||||
|
||||
assert.notStrictEqual(homeWeb3.eth.abi.decodeParameter('uint256', data), balance, 'wrong user balance returned')
|
||||
})
|
||||
|
||||
it('should make async eth_getTransactionCount', async () => {
|
||||
const nonce = (await foreignWeb3.eth.getTransactionCount(user.address)).toString()
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getTransactionCount(address)')
|
||||
|
||||
await makeAsyncCall(selector, homeWeb3.eth.abi.encodeParameter('address', user.address))
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
const data = await homeBox.methods.data().call()
|
||||
assert.strictEqual(data.length, 2 + 64)
|
||||
|
||||
assert.strictEqual(homeWeb3.eth.abi.decodeParameter('uint256', data), nonce, 'wrong user nonce returned')
|
||||
})
|
||||
|
||||
it('should make async eth_getTransactionCount for specific block', async () => {
|
||||
let nonce = (await foreignWeb3.eth.getTransactionCount(user.address)).toString()
|
||||
const { blockNumber } = await foreignWeb3.eth.sendTransaction({
|
||||
to: user.address,
|
||||
value: 1,
|
||||
from: user.address,
|
||||
gas: 21000
|
||||
})
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getTransactionCount(address,uint256)')
|
||||
|
||||
const data1 = homeWeb3.eth.abi.encodeParameters(['address', 'uint256'], [user.address, blockNumber - 1])
|
||||
const data2 = homeWeb3.eth.abi.encodeParameters(['address', 'uint256'], [user.address, blockNumber])
|
||||
|
||||
await makeAsyncCall(selector, data1)
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
let data = await homeBox.methods.data().call()
|
||||
assert.strictEqual(data.length, 2 + 64)
|
||||
|
||||
assert.strictEqual(homeWeb3.eth.abi.decodeParameter('uint256', data), nonce, 'wrong user nonce returned')
|
||||
|
||||
await makeAsyncCall(selector, data2)
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
data = await homeBox.methods.data().call()
|
||||
assert.strictEqual(data.length, 2 + 64)
|
||||
|
||||
nonce = (parseInt(nonce, 10) + 1).toString()
|
||||
assert.strictEqual(homeWeb3.eth.abi.decodeParameter('uint256', data), nonce, 'wrong user nonce returned')
|
||||
})
|
||||
|
||||
it('should make async eth_getTransactionByHash', async () => {
|
||||
const txHash = '0x09dfb947dbd17e27bcc117773b6e133829f7cef9646199a93ef019c4f7c0fec6'
|
||||
const tx = await foreignWeb3.eth.getTransaction(txHash)
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getTransactionByHash(bytes32)')
|
||||
|
||||
await makeAsyncCall(selector, txHash)
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
const data = await homeBox.methods.data().call()
|
||||
const dataTypes = [
|
||||
'bytes32',
|
||||
'uint256',
|
||||
'address',
|
||||
'address',
|
||||
'uint256',
|
||||
'uint256',
|
||||
'uint256',
|
||||
'uint256',
|
||||
'bytes'
|
||||
]
|
||||
const values = homeWeb3.eth.abi.decodeParameters(dataTypes, data)
|
||||
|
||||
assert.strictEqual(values[0], txHash, 'wrong txHash returned')
|
||||
assert.strictEqual(values[1], tx.blockNumber.toString(), 'wrong tx blockNumber returned')
|
||||
assert.strictEqual(values[2], tx.from, 'wrong tx from returned')
|
||||
assert.strictEqual(values[3], tx.to, 'wrong tx to returned')
|
||||
assert.strictEqual(values[4], tx.value, 'wrong tx value returned')
|
||||
assert.strictEqual(values[5], tx.nonce.toString(), 'wrong tx nonce returned')
|
||||
assert.strictEqual(values[6], tx.gas.toString(), 'wrong tx gas returned')
|
||||
assert.strictEqual(values[7], tx.gasPrice, 'wrong tx gasPrice returned')
|
||||
assert.strictEqual(values[8], tx.input, 'wrong tx data returned')
|
||||
})
|
||||
|
||||
it('should make async eth_getTransactionReceipt', async () => {
|
||||
const txHash = '0x09dfb947dbd17e27bcc117773b6e133829f7cef9646199a93ef019c4f7c0fec6'
|
||||
const receipt = await foreignWeb3.eth.getTransactionReceipt(txHash)
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getTransactionReceipt(bytes32)')
|
||||
|
||||
await makeAsyncCall(selector, txHash)
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
const data = await homeBox.methods.data().call()
|
||||
const dataTypes = ['bytes32', 'uint256', 'bool', '(address,bytes32[],bytes)[]']
|
||||
const values = homeWeb3.eth.abi.decodeParameters(dataTypes, data)
|
||||
|
||||
assert.strictEqual(values[0], txHash, 'wrong txHash returned')
|
||||
assert.strictEqual(values[1], receipt.blockNumber.toString(), 'wrong tx blockNumber returned')
|
||||
assert.strictEqual(values[2], receipt.status, 'wrong tx status returned')
|
||||
assert.strictEqual(values[3].length, 1, 'wrong logs length returned')
|
||||
assert.strictEqual(values[3][0][0], receipt.logs[0].address, 'wrong log address returned')
|
||||
assert.strictEqual(values[3][0][1].length, 2, 'wrong log topics length returned')
|
||||
assert.strictEqual(values[3][0][1][0], receipt.logs[0].topics[0], 'wrong event signature returned')
|
||||
assert.strictEqual(values[3][0][1][1], receipt.logs[0].topics[1], 'wrong message id returned')
|
||||
assert.strictEqual(values[3][0][2], receipt.logs[0].data, 'wrong log data returned')
|
||||
})
|
||||
|
||||
it('should make async eth_getStorageAt', async () => {
|
||||
// slot for uintStorage[MAX_GAS_PER_TX]
|
||||
const slot = '0x3d7fe2ee9790702383ef0118b516833ef2542132d3ca4ac6c77f62f1230fa610'
|
||||
const value = await foreignWeb3.eth.getStorageAt(amb.foreign, slot)
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getStorageAt(address,bytes32)')
|
||||
|
||||
await makeAsyncCall(selector, homeWeb3.eth.abi.encodeParameters(['address', 'bytes32'], [amb.foreign, slot]))
|
||||
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
const data = await homeBox.methods.data().call()
|
||||
|
||||
assert.strictEqual(data, value, 'wrong storage value returned')
|
||||
})
|
||||
|
||||
it('should make async eth_getStorageAt for specific block', async () => {
|
||||
// slot for uintStorage[MAX_GAS_PER_TX]
|
||||
const slot = '0x3d7fe2ee9790702383ef0118b516833ef2542132d3ca4ac6c77f62f1230fa610'
|
||||
const value = await foreignWeb3.eth.getStorageAt(amb.foreign, slot)
|
||||
const blockNumber = await foreignWeb3.eth.getBlockNumber()
|
||||
const selector = homeWeb3.utils.soliditySha3('eth_getStorageAt(address,bytes32,uint256)')
|
||||
|
||||
const data1 = homeWeb3.eth.abi.encodeParameters(
|
||||
['address', 'bytes32', 'uint256'],
|
||||
[amb.foreign, slot, blockNumber]
|
||||
)
|
||||
const data2 = homeWeb3.eth.abi.encodeParameters(['address', 'bytes32', 'uint256'], [amb.foreign, slot, 1])
|
||||
|
||||
await makeAsyncCall(selector, data1)
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
let data = await homeBox.methods.data().call()
|
||||
|
||||
assert.strictEqual(data, value, 'wrong storage value returned')
|
||||
|
||||
await makeAsyncCall(selector, data2)
|
||||
assert(await homeBox.methods.status().call(), 'status is false')
|
||||
data = await homeBox.methods.data().call()
|
||||
|
||||
assert.strictEqual(
|
||||
data,
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
||||
'wrong storage value returned'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -1,142 +0,0 @@
|
||||
const Web3 = require('web3')
|
||||
const assert = require('assert')
|
||||
const { user, secondUser, ercToErcBridge, homeRPC, foreignRPC, validator } = require('../../e2e-commons/constants.json')
|
||||
const { ERC677_BRIDGE_TOKEN_ABI, FOREIGN_ERC_TO_NATIVE_ABI, HOME_ERC_TO_ERC_ABI } = require('../../commons')
|
||||
const { uniformRetry } = require('../../e2e-commons/utils')
|
||||
const { setRequiredSignatures } = require('./utils')
|
||||
|
||||
const homeWeb3 = new Web3(new Web3.providers.HttpProvider(homeRPC.URL))
|
||||
const foreignWeb3 = new Web3(new Web3.providers.HttpProvider(foreignRPC.URL))
|
||||
|
||||
const COMMON_HOME_BRIDGE_ADDRESS = ercToErcBridge.home
|
||||
const COMMON_FOREIGN_BRIDGE_ADDRESS = ercToErcBridge.foreign
|
||||
|
||||
const { toBN } = foreignWeb3.utils
|
||||
|
||||
homeWeb3.eth.accounts.wallet.add(user.privateKey)
|
||||
homeWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(user.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||
|
||||
const erc20Token = new foreignWeb3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, ercToErcBridge.foreignToken)
|
||||
const foreignBridge = new foreignWeb3.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
const erc677Token = new homeWeb3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, ercToErcBridge.homeToken)
|
||||
const homeBridge = new homeWeb3.eth.Contract(HOME_ERC_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
|
||||
describe('erc to erc', () => {
|
||||
before(async () => {
|
||||
if (process.env.ULTIMATE === 'true') {
|
||||
return
|
||||
}
|
||||
console.log('Calling setRequiredSignatures(2)')
|
||||
|
||||
// Set 2 required signatures for home bridge
|
||||
await setRequiredSignatures({
|
||||
bridgeContract: homeBridge,
|
||||
web3: homeWeb3,
|
||||
requiredSignatures: 2,
|
||||
options: {
|
||||
from: validator.address,
|
||||
gas: '4000000'
|
||||
}
|
||||
})
|
||||
|
||||
// Set 2 required signatures for foreign bridge
|
||||
await setRequiredSignatures({
|
||||
bridgeContract: foreignBridge,
|
||||
web3: foreignWeb3,
|
||||
requiredSignatures: 2,
|
||||
options: {
|
||||
from: validator.address,
|
||||
gas: '4000000'
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should convert tokens in foreign to tokens in home', async () => {
|
||||
const balance = await erc20Token.methods.balanceOf(user.address).call()
|
||||
assert(!toBN(balance).isZero(), 'Account should have tokens')
|
||||
|
||||
const firstTransferValue = homeWeb3.utils.toWei('0.01')
|
||||
|
||||
// approve tokens to foreign bridge
|
||||
await erc20Token.methods
|
||||
.approve(COMMON_FOREIGN_BRIDGE_ADDRESS, firstTransferValue)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
// call bridge method to transfer tokens to a different recipient
|
||||
await foreignBridge.methods
|
||||
.relayTokens(secondUser.address, firstTransferValue)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
// check that balance increases
|
||||
await uniformRetry(async retry => {
|
||||
const balance = await erc677Token.methods.balanceOf(user.address).call()
|
||||
const recipientBalance = await erc677Token.methods.balanceOf(secondUser.address).call()
|
||||
assert(toBN(balance).isZero(), 'User balance should be the same')
|
||||
if (toBN(recipientBalance).isZero()) {
|
||||
retry()
|
||||
}
|
||||
})
|
||||
|
||||
const secondTransferValue = homeWeb3.utils.toWei('0.05')
|
||||
|
||||
// send tokens to foreign bridge
|
||||
await erc20Token.methods
|
||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, secondTransferValue)
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
// check that balance increases
|
||||
await uniformRetry(async retry => {
|
||||
const balance = await erc677Token.methods.balanceOf(user.address).call()
|
||||
if (toBN(balance).isZero()) {
|
||||
retry()
|
||||
} else {
|
||||
assert(toBN(balance).eq(toBN(secondTransferValue)), 'User balance should be increased only by second transfer')
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should convert tokens in home to tokens in foreign', async () => {
|
||||
const originalBalance = await erc20Token.methods.balanceOf(user.address).call()
|
||||
|
||||
// check that account has tokens in home chain
|
||||
const balance = await erc677Token.methods.balanceOf(user.address).call()
|
||||
assert(!toBN(balance).isZero(), 'Account should have tokens')
|
||||
|
||||
// send transaction to home bridge
|
||||
await erc677Token.methods
|
||||
.transferAndCall(COMMON_HOME_BRIDGE_ADDRESS, homeWeb3.utils.toWei('0.01'), '0x')
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
// check that balance increases
|
||||
await uniformRetry(async retry => {
|
||||
const balance = await erc20Token.methods.balanceOf(user.address).call()
|
||||
if (toBN(balance).lte(toBN(originalBalance))) {
|
||||
retry()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
@ -1,6 +1,5 @@
|
||||
const Web3 = require('web3')
|
||||
const assert = require('assert')
|
||||
const promiseRetry = require('promise-retry')
|
||||
const {
|
||||
user,
|
||||
secondUser,
|
||||
@ -10,7 +9,7 @@ const {
|
||||
homeRPC,
|
||||
foreignRPC
|
||||
} = require('../../e2e-commons/constants.json')
|
||||
const { ERC677_BRIDGE_TOKEN_ABI, FOREIGN_ERC_TO_NATIVE_ABI, HOME_ERC_TO_NATIVE_ABI } = require('../../commons')
|
||||
const { ERC20_ABI, FOREIGN_ERC_TO_NATIVE_ABI, HOME_ERC_TO_NATIVE_ABI } = require('../../commons')
|
||||
const { uniformRetry, sleep } = require('../../e2e-commons/utils')
|
||||
const { setRequiredSignatures } = require('./utils')
|
||||
|
||||
@ -28,7 +27,7 @@ homeWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(user.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||
|
||||
const erc20Token = new foreignWeb3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, ercToNativeBridge.foreignToken)
|
||||
const erc20Token = new foreignWeb3.eth.Contract(ERC20_ABI, ercToNativeBridge.foreignToken)
|
||||
const foreignBridge = new foreignWeb3.eth.Contract(FOREIGN_ERC_TO_NATIVE_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
const homeBridge = new homeWeb3.eth.Contract(HOME_ERC_TO_NATIVE_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
|
||||
@ -196,211 +195,4 @@ describe('erc to native', () => {
|
||||
)
|
||||
})
|
||||
}
|
||||
it('should not invest dai when chai token is disabled', async () => {
|
||||
const bridgeDaiTokenBalance = await erc20Token.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||
|
||||
await foreignBridge.methods.setMinDaiTokenBalance(foreignWeb3.utils.toWei('2', 'ether')).send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
}) // set min limit for automatic investment to 2*2 dai
|
||||
|
||||
const valueToTransfer = foreignWeb3.utils.toWei('5', 'ether')
|
||||
|
||||
// this transfer won't trigger a call to convert to chai
|
||||
await erc20Token.methods.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, valueToTransfer).send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
|
||||
await promiseRetry(async (retry, number) => {
|
||||
if (number < 4) {
|
||||
retry()
|
||||
} else {
|
||||
const updatedBridgeDaiTokenBalance = await erc20Token.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||
assert(
|
||||
toBN(bridgeDaiTokenBalance)
|
||||
.add(toBN(valueToTransfer))
|
||||
.eq(toBN(updatedBridgeDaiTokenBalance)),
|
||||
'Dai tokens should not be when chai is disabled'
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should invest dai after enough tokens are collected on bridge account', async () => {
|
||||
await foreignBridge.methods.initializeChaiToken().send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
}) // initialize chai token
|
||||
await foreignBridge.methods.setMinDaiTokenBalance('0').send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
}) // set investing limit to 0
|
||||
await foreignBridge.methods.convertDaiToChai().send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
}) // convert all existing dai tokens on bridge account to chai, in order to start from zero balance
|
||||
await foreignBridge.methods.setMinDaiTokenBalance(foreignWeb3.utils.toWei('2', 'ether')).send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
}) // set investing limit to 2 dai, automatically invest should happen after 4 dai
|
||||
|
||||
const valueToTransfer = foreignWeb3.utils.toWei('3', 'ether')
|
||||
|
||||
// this transfer won't trigger a call to convert to chai
|
||||
await erc20Token.methods.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, valueToTransfer).send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
|
||||
await promiseRetry(async (retry, number) => {
|
||||
if (number < 4) {
|
||||
retry()
|
||||
} else {
|
||||
const bridgeDaiTokenBalance = await erc20Token.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||
assert(
|
||||
valueToTransfer === bridgeDaiTokenBalance,
|
||||
'Dai tokens should not be invested automatically before twice limit is reached'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
// this transfer will trigger call to convert to chai
|
||||
await erc20Token.methods.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, valueToTransfer).send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
|
||||
await promiseRetry(async retry => {
|
||||
const updatedBalance = await erc20Token.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||
if (toBN(updatedBalance).gte(toBN(valueToTransfer).add(toBN(valueToTransfer)))) {
|
||||
retry()
|
||||
} else {
|
||||
const updatedBalance = await erc20Token.methods.balanceOf(COMMON_FOREIGN_BRIDGE_ADDRESS).call()
|
||||
assert(
|
||||
toBN(updatedBalance).eq(toBN(foreignWeb3.utils.toWei('2', 'ether'))),
|
||||
'Dai bridge balance should be equal to limit'
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
if (process.env.ULTIMATE !== 'true') {
|
||||
describe('handling of chai swaps', async () => {
|
||||
before(async () => {
|
||||
// Next tests check validator nonces, this will force every validator to submit signature/affirmation
|
||||
// Set 3 required signatures for home bridge
|
||||
await setRequiredSignatures({
|
||||
bridgeContract: homeBridge,
|
||||
web3: homeWeb3,
|
||||
requiredSignatures: 3,
|
||||
options: {
|
||||
from: validator.address,
|
||||
gas: '4000000'
|
||||
}
|
||||
})
|
||||
|
||||
// Set 3 required signatures for foreign bridge
|
||||
await setRequiredSignatures({
|
||||
bridgeContract: foreignBridge,
|
||||
web3: foreignWeb3,
|
||||
requiredSignatures: 3,
|
||||
options: {
|
||||
from: validator.address,
|
||||
gas: '4000000'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should not handle transfer event in paying interest', async () => {
|
||||
await foreignBridge.methods.setInterestReceiver(user.address).send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
const initialNonce = await homeWeb3.eth.getTransactionCount(validator.address)
|
||||
await foreignBridge.methods.payInterest().send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
|
||||
await promiseRetry(async (retry, number) => {
|
||||
if (number < 6) {
|
||||
retry()
|
||||
} else {
|
||||
const nonce = await homeWeb3.eth.getTransactionCount(validator.address)
|
||||
assert(
|
||||
nonce === initialNonce,
|
||||
'Validator should not process transfer event originated during converting Chai => Dai'
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should not handle chai withdrawal transfer event in executeSignatures as a regular transfer', async () => {
|
||||
await foreignBridge.methods.setMinDaiTokenBalance('0').send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
}) // set investing limit to 0
|
||||
await foreignBridge.methods.convertDaiToChai().send({
|
||||
from: validator.address,
|
||||
gas: '1000000'
|
||||
}) // convert all existing dai tokens on bridge account to chai, in order to start from zero balance
|
||||
|
||||
const initialNonce = await homeWeb3.eth.getTransactionCount(validator.address)
|
||||
|
||||
const originalBalance = await erc20Token.methods.balanceOf(user.address).call()
|
||||
// send transaction to home bridge
|
||||
await homeWeb3.eth.sendTransaction({
|
||||
from: user.address,
|
||||
to: COMMON_HOME_BRIDGE_ADDRESS,
|
||||
gasPrice: '1',
|
||||
gas: '1000000',
|
||||
value: homeWeb3.utils.toWei('0.01')
|
||||
})
|
||||
|
||||
// check that balance increases
|
||||
await uniformRetry(async retry => {
|
||||
const balance = await erc20Token.methods.balanceOf(user.address).call()
|
||||
if (toBN(balance).lte(toBN(originalBalance))) {
|
||||
retry()
|
||||
}
|
||||
})
|
||||
|
||||
await promiseRetry(async (retry, number) => {
|
||||
if (number < 6) {
|
||||
retry()
|
||||
} else {
|
||||
const nonce = await homeWeb3.eth.getTransactionCount(validator.address)
|
||||
assert(
|
||||
nonce === initialNonce + 1,
|
||||
'Validator should not process transfer event originated during converting Chai => Dai'
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
after(async () => {
|
||||
// Set 2 required signatures for home bridge
|
||||
await setRequiredSignatures({
|
||||
bridgeContract: homeBridge,
|
||||
web3: homeWeb3,
|
||||
requiredSignatures: 2,
|
||||
options: {
|
||||
from: validator.address,
|
||||
gas: '4000000'
|
||||
}
|
||||
})
|
||||
|
||||
// Set 2 required signatures for foreign bridge
|
||||
await setRequiredSignatures({
|
||||
bridgeContract: foreignBridge,
|
||||
web3: foreignWeb3,
|
||||
requiredSignatures: 2,
|
||||
options: {
|
||||
from: validator.address,
|
||||
gas: '4000000'
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@ -1,212 +0,0 @@
|
||||
const Web3 = require('web3')
|
||||
const assert = require('assert')
|
||||
const {
|
||||
user,
|
||||
validator,
|
||||
secondValidator,
|
||||
thirdValidator,
|
||||
nativeToErcBridge,
|
||||
secondUser,
|
||||
thirdUser,
|
||||
fourthUser,
|
||||
homeRPC,
|
||||
foreignRPC
|
||||
} = require('../../e2e-commons/constants.json')
|
||||
const { ERC677_BRIDGE_TOKEN_ABI, HOME_NATIVE_TO_ERC_ABI, FOREIGN_NATIVE_TO_ERC_ABI } = require('../../commons')
|
||||
const { uniformRetry, sleep } = require('../../e2e-commons/utils')
|
||||
const { setRequiredSignatures } = require('./utils')
|
||||
|
||||
const homeWeb3 = new Web3(new Web3.providers.HttpProvider(homeRPC.URL))
|
||||
const foreignWeb3 = new Web3(new Web3.providers.HttpProvider(foreignRPC.URL))
|
||||
const { toBN } = foreignWeb3.utils
|
||||
|
||||
const COMMON_HOME_BRIDGE_ADDRESS = nativeToErcBridge.home
|
||||
const COMMON_FOREIGN_BRIDGE_ADDRESS = nativeToErcBridge.foreign
|
||||
|
||||
const validatorAddresses = [validator.address, secondValidator.address, thirdValidator.address]
|
||||
|
||||
homeWeb3.eth.accounts.wallet.add(user.privateKey)
|
||||
homeWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||
homeWeb3.eth.accounts.wallet.add(secondUser.privateKey)
|
||||
homeWeb3.eth.accounts.wallet.add(secondValidator.privateKey)
|
||||
homeWeb3.eth.accounts.wallet.add(thirdValidator.privateKey)
|
||||
homeWeb3.eth.accounts.wallet.add(thirdUser.privateKey)
|
||||
homeWeb3.eth.accounts.wallet.add(fourthUser.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(user.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(validator.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(secondUser.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(secondValidator.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(thirdValidator.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(thirdUser.privateKey)
|
||||
foreignWeb3.eth.accounts.wallet.add(fourthUser.privateKey)
|
||||
|
||||
const token = new foreignWeb3.eth.Contract(ERC677_BRIDGE_TOKEN_ABI, nativeToErcBridge.foreignToken)
|
||||
const homeBridge = new homeWeb3.eth.Contract(HOME_NATIVE_TO_ERC_ABI, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const foreignBridge = new foreignWeb3.eth.Contract(FOREIGN_NATIVE_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
|
||||
describe('native to erc', () => {
|
||||
before(async () => {
|
||||
if (process.env.ULTIMATE === 'true') {
|
||||
return
|
||||
}
|
||||
console.log('Calling setRequiredSignatures(2)')
|
||||
|
||||
// Set 2 required signatures for home bridge
|
||||
await setRequiredSignatures({
|
||||
bridgeContract: homeBridge,
|
||||
web3: homeWeb3,
|
||||
requiredSignatures: 2,
|
||||
options: {
|
||||
from: validator.address,
|
||||
gas: '4000000'
|
||||
}
|
||||
})
|
||||
|
||||
// Set 2 required signatures for foreign bridge
|
||||
await setRequiredSignatures({
|
||||
bridgeContract: foreignBridge,
|
||||
web3: foreignWeb3,
|
||||
requiredSignatures: 2,
|
||||
options: {
|
||||
from: validator.address,
|
||||
gas: '4000000'
|
||||
}
|
||||
})
|
||||
})
|
||||
it('should convert eth in home to tokens in foreign', async () => {
|
||||
// check that account has zero tokens in the foreign chain
|
||||
const balance = await token.methods.balanceOf(user.address).call()
|
||||
assert(toBN(balance).isZero(), 'Account should not have tokens yet')
|
||||
|
||||
// send transaction to home chain
|
||||
await homeWeb3.eth.sendTransaction({
|
||||
from: user.address,
|
||||
to: COMMON_HOME_BRIDGE_ADDRESS,
|
||||
gasPrice: '1',
|
||||
gas: '50000',
|
||||
value: '1000000000000000000'
|
||||
})
|
||||
|
||||
// check that account has tokens in the foreign chain
|
||||
await uniformRetry(async retry => {
|
||||
const balance = await token.methods.balanceOf(user.address).call()
|
||||
if (toBN(balance).isZero()) {
|
||||
retry()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should convert tokens in foreign to eth in home', async () => {
|
||||
const originalBalance = await homeWeb3.eth.getBalance(user.address)
|
||||
|
||||
// send tokens to foreign bridge
|
||||
await token.methods
|
||||
.transferAndCall(COMMON_FOREIGN_BRIDGE_ADDRESS, homeWeb3.utils.toWei('0.01'), '0x')
|
||||
.send({
|
||||
from: user.address,
|
||||
gas: '1000000'
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(e)
|
||||
})
|
||||
|
||||
// check that balance increases
|
||||
await uniformRetry(async retry => {
|
||||
const balance = await homeWeb3.eth.getBalance(user.address)
|
||||
if (toBN(balance).lte(toBN(originalBalance))) {
|
||||
retry()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should wait for funds if these are insufficient (Home)', async () => {
|
||||
// check that account has zero tokens in the foreign chain
|
||||
const originalBalance = toBN(await token.methods.balanceOf(user.address).call())
|
||||
|
||||
// empty validator funds
|
||||
await sendAllBalance(homeWeb3, validator.address, secondUser.address)
|
||||
await sendAllBalance(homeWeb3, secondValidator.address, thirdUser.address)
|
||||
await sendAllBalance(homeWeb3, thirdValidator.address, fourthUser.address)
|
||||
|
||||
const nonces = await Promise.all(validatorAddresses.map(homeWeb3.eth.getTransactionCount))
|
||||
// send transaction to home chain
|
||||
await homeWeb3.eth.sendTransaction({
|
||||
from: user.address,
|
||||
to: COMMON_HOME_BRIDGE_ADDRESS,
|
||||
gasPrice: '1',
|
||||
gas: '50000',
|
||||
value: '1000000000000000000'
|
||||
})
|
||||
|
||||
// wait two seconds, no new blocks should have been generated
|
||||
await sleep(2000)
|
||||
const newNonces = await Promise.all(validatorAddresses.map(homeWeb3.eth.getTransactionCount))
|
||||
const balance = toBN(await token.methods.balanceOf(user.address).call())
|
||||
assert.deepStrictEqual(nonces, newNonces, "Shouldn't sent new tx")
|
||||
assert(originalBalance.eq(balance), "Token balance shouldn't have changed")
|
||||
|
||||
// send funds back to validator
|
||||
await sendAllBalance(homeWeb3, secondUser.address, validator.address)
|
||||
await sendAllBalance(homeWeb3, thirdUser.address, secondValidator.address)
|
||||
await sendAllBalance(homeWeb3, fourthUser.address, thirdValidator.address)
|
||||
|
||||
// check that token balance was incremented in foreign chain
|
||||
await uniformRetry(async retry => {
|
||||
const balance = toBN(await token.methods.balanceOf(user.address).call())
|
||||
if (!balance.gt(originalBalance)) {
|
||||
retry()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('should wait for funds if these are insufficient (Foreign)', async () => {
|
||||
// get original tokens balance
|
||||
const originalBalance = toBN(await token.methods.balanceOf(user.address).call())
|
||||
|
||||
// empty foreign validator funds
|
||||
await sendAllBalance(foreignWeb3, validator.address, secondUser.address)
|
||||
await sendAllBalance(foreignWeb3, secondValidator.address, thirdUser.address)
|
||||
await sendAllBalance(foreignWeb3, thirdValidator.address, fourthUser.address)
|
||||
const nonces = await Promise.all(validatorAddresses.map(foreignWeb3.eth.getTransactionCount))
|
||||
|
||||
// send transaction to home chain
|
||||
await homeWeb3.eth.sendTransaction({
|
||||
from: user.address,
|
||||
to: COMMON_HOME_BRIDGE_ADDRESS,
|
||||
gasPrice: '1',
|
||||
gas: '50000',
|
||||
value: '1000000000000000000'
|
||||
})
|
||||
|
||||
// tokens shouldn't be generated in the foreign chain because the validator doesn't have funds
|
||||
await sleep(2000)
|
||||
const newNonces = await Promise.all(validatorAddresses.map(foreignWeb3.eth.getTransactionCount))
|
||||
assert.deepStrictEqual(nonces, newNonces, "Shouldn't sent new tx")
|
||||
|
||||
// send funds back to validator
|
||||
await sendAllBalance(foreignWeb3, secondUser.address, validator.address)
|
||||
await sendAllBalance(foreignWeb3, thirdUser.address, secondValidator.address)
|
||||
await sendAllBalance(foreignWeb3, fourthUser.address, thirdValidator.address)
|
||||
|
||||
// check that account has tokens in the foreign chain
|
||||
await uniformRetry(async retry => {
|
||||
const balance = toBN(await token.methods.balanceOf(user.address).call())
|
||||
if (balance.eq(originalBalance)) {
|
||||
retry()
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
async function sendAllBalance(web3, from, to) {
|
||||
const balance = await web3.eth.getBalance(from)
|
||||
const value = toBN(balance).sub(toBN('21000'))
|
||||
|
||||
return web3.eth.sendTransaction({
|
||||
from,
|
||||
to,
|
||||
value,
|
||||
gas: '21000',
|
||||
gasPrice: '1'
|
||||
})
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
],
|
||||
"plugins": ["node"],
|
||||
"rules": {
|
||||
"node/no-unpublished-require": "off"
|
||||
"node/no-unpublished-require": "off",
|
||||
"global-require": "off"
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM node:10 as contracts
|
||||
FROM node:12 as contracts
|
||||
|
||||
WORKDIR /mono
|
||||
|
||||
@ -11,7 +11,7 @@ COPY ./contracts/truffle-config.js ./
|
||||
COPY ./contracts/contracts ./contracts
|
||||
RUN npm run compile
|
||||
|
||||
FROM node:10
|
||||
FROM node:12
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y build-essential libc6-dev libc6-dev-i386 wget && \
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Binary file not shown.
Before Width: | Height: | Size: 30 KiB |
@ -10,13 +10,9 @@ The Oracle is deployed on specified validator nodes (only nodes whose private ke
|
||||
|
||||
## Architecture
|
||||
|
||||
### Native-to-ERC20 and Arbitrary-Message
|
||||
### ERC20-to-Native
|
||||
|
||||
![Native-to-ERC](Native-to-ERC.png)
|
||||
|
||||
### ERC20-to-ERC20 and ERC20-to-Native
|
||||
|
||||
![ERC-to-ERC](ERC-to-ERC.png)
|
||||
![ERC-to-Native](ERC_TO_NATIVE.png)
|
||||
|
||||
### Watcher
|
||||
A watcher listens for a certain event and creates proper jobs in the queue. These jobs contain the transaction data (without the nonce) and the transaction hash for the related event. The watcher runs on a given frequency, keeping track of the last processed block.
|
||||
@ -27,8 +23,8 @@ There are three Watchers:
|
||||
- **Signature Request Watcher**: Listens to `UserRequestForSignature` events on the Home network.
|
||||
- **Collected Signatures Watcher**: Listens to `CollectedSignatures` events on the Home network.
|
||||
- **Affirmation Request Watcher**: Depends on the bridge mode.
|
||||
- `Native-to-ERC20` and `Arbitrary-Message`: Listens to `UserRequestForAffirmation` raised by the bridge contract.
|
||||
- `ERC20-to-ERC20` and `ERC20-to-Native`: Listens to `Transfer` events raised by the token contract.
|
||||
- `Arbitrary-Message`: Listens to `UserRequestForAffirmation` raised by the bridge contract.
|
||||
- `ERC20-to-Native`: Listens to `Transfer` events raised by the token contract.
|
||||
|
||||
### Sender
|
||||
A sender subscribes to the queue and keeps track of the nonce. It takes jobs from the queue, extracts transaction data, adds the proper nonce, and sends it to the network.
|
||||
@ -59,32 +55,12 @@ For more information on the Redis/RabbitMQ requirements, see [#90](/../../issues
|
||||
|
||||
#### Output examples
|
||||
|
||||
`Native-to-ERC20` mode example:
|
||||
```json
|
||||
{
|
||||
"homeBridge": {
|
||||
"address": "0xc60daff55ec5b5ce5c3d2105a77e287ff638c35e",
|
||||
"deployedBlockNumber": 123321
|
||||
},
|
||||
"foreignBridge": {
|
||||
"address": "0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be",
|
||||
"deployedBlockNumber": 456654,
|
||||
"erc677": {
|
||||
"address": "0x41a29780309dc2582f080f6af89953be3435679a"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`ERC20-to-ERC20` mode example:
|
||||
`ERC20-to-Native` mode example:
|
||||
```json
|
||||
{
|
||||
"homeBridge": {
|
||||
"address": "0x765a0d90e5a5773deacbd94b2dc941cbb163bdab",
|
||||
"deployedBlockNumber": 789987,
|
||||
"erc677": {
|
||||
"address": "0x269f57f5ae5421d084686f9e353f5b7ee6af54c2"
|
||||
}
|
||||
"deployedBlockNumber": 789987
|
||||
},
|
||||
"foreignBridge": {
|
||||
"address": "0x7ae703ea88b0545eef1f0bf8f91d5276e39be2f7",
|
||||
@ -221,20 +197,6 @@ See the [E2E README](../oracle-e2e/README.md) for instructions.
|
||||
|
||||
*Notice*: for docker-based installations do not forget to add `docker-compose exec bridge_affirmation` before the test commands listed below.
|
||||
|
||||
### Native-to-ERC20 Mode Testing
|
||||
|
||||
When running the processes, the following commands can be used to test functionality.
|
||||
|
||||
- To send deposits to a home contract run `node scripts/native_to_erc20/sendHome.js <tx num>`, where `<tx num>` is how many tx will be sent out to deposit.
|
||||
|
||||
- To send withdrawals to a foreign contract run `node scripts/native_to_erc20/sendForeign.js <tx num>`, where `<tx num>` is how many tx will be sent out to withdraw.
|
||||
|
||||
### ERC20-to-ERC20 Mode Testing
|
||||
|
||||
- To deposit from a Foreign to a Home contract run `node scripts/erc20_to_erc20/sendForeign.js <tx num>`.
|
||||
|
||||
- To make withdrawal to Home from a Foreign contract run `node scripts/erc20_to_erc20/sendHome.js <tx num>`.
|
||||
|
||||
### ERC20-to-Native Mode Testing
|
||||
|
||||
- To deposit from a Foreign to a Home contract run `node scripts/erc20_to_native/sendForeign.js <tx num>`.
|
||||
|
@ -1,28 +1,10 @@
|
||||
const baseConfig = require('./base.config')
|
||||
const { ERC_TYPES } = require('../../commons')
|
||||
|
||||
const initialChecksJson = process.argv[3]
|
||||
|
||||
if (!initialChecksJson) {
|
||||
throw new Error('initial check parameter was not provided.')
|
||||
}
|
||||
|
||||
let initialChecks
|
||||
try {
|
||||
initialChecks = JSON.parse(initialChecksJson)
|
||||
} catch (e) {
|
||||
throw new Error('Error on decoding values from initial checks.')
|
||||
}
|
||||
|
||||
if (baseConfig.id === 'erc-erc' && initialChecks.foreignERC === ERC_TYPES.ERC677) {
|
||||
baseConfig.id = 'erc677-erc677'
|
||||
}
|
||||
|
||||
const id = `${baseConfig.id}-affirmation-request`
|
||||
|
||||
module.exports = {
|
||||
...baseConfig.bridgeConfig,
|
||||
...baseConfig.foreignConfig,
|
||||
...baseConfig,
|
||||
main: baseConfig.foreign,
|
||||
event: 'UserRequestForAffirmation',
|
||||
queue: 'home-prioritized',
|
||||
name: `watcher-${id}`,
|
||||
|
@ -1,12 +1,7 @@
|
||||
require('../env')
|
||||
|
||||
const { toBN } = require('web3').utils
|
||||
const {
|
||||
BRIDGE_MODES,
|
||||
HOME_NATIVE_TO_ERC_ABI,
|
||||
FOREIGN_NATIVE_TO_ERC_ABI,
|
||||
HOME_ERC_TO_ERC_ABI,
|
||||
FOREIGN_ERC_TO_ERC_ABI,
|
||||
HOME_ERC_TO_NATIVE_ABI,
|
||||
FOREIGN_ERC_TO_NATIVE_ABI,
|
||||
HOME_AMB_ABI,
|
||||
@ -15,23 +10,26 @@ const {
|
||||
const { web3Home, web3Foreign } = require('../src/services/web3')
|
||||
const { privateKeyToAddress } = require('../src/utils/utils')
|
||||
|
||||
const { ORACLE_VALIDATOR_ADDRESS, ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY } = process.env
|
||||
const {
|
||||
ORACLE_BRIDGE_MODE,
|
||||
ORACLE_VALIDATOR_ADDRESS,
|
||||
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY,
|
||||
ORACLE_MAX_PROCESSING_TIME,
|
||||
COMMON_HOME_BRIDGE_ADDRESS,
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS,
|
||||
ORACLE_HOME_RPC_POLLING_INTERVAL,
|
||||
ORACLE_FOREIGN_RPC_POLLING_INTERVAL,
|
||||
ORACLE_HOME_START_BLOCK,
|
||||
ORACLE_FOREIGN_START_BLOCK,
|
||||
ORACLE_HOME_RPC_BLOCK_POLLING_LIMIT,
|
||||
ORACLE_FOREIGN_RPC_BLOCK_POLLING_LIMIT
|
||||
} = process.env
|
||||
|
||||
let homeAbi
|
||||
let foreignAbi
|
||||
let id
|
||||
|
||||
switch (process.env.ORACLE_BRIDGE_MODE) {
|
||||
case BRIDGE_MODES.NATIVE_TO_ERC:
|
||||
homeAbi = HOME_NATIVE_TO_ERC_ABI
|
||||
foreignAbi = FOREIGN_NATIVE_TO_ERC_ABI
|
||||
id = 'native-erc'
|
||||
break
|
||||
case BRIDGE_MODES.ERC_TO_ERC:
|
||||
homeAbi = HOME_ERC_TO_ERC_ABI
|
||||
foreignAbi = FOREIGN_ERC_TO_ERC_ABI
|
||||
id = 'erc-erc'
|
||||
break
|
||||
switch (ORACLE_BRIDGE_MODE) {
|
||||
case BRIDGE_MODES.ERC_TO_NATIVE:
|
||||
homeAbi = HOME_ERC_TO_NATIVE_ABI
|
||||
foreignAbi = FOREIGN_ERC_TO_NATIVE_ABI
|
||||
@ -44,7 +42,7 @@ switch (process.env.ORACLE_BRIDGE_MODE) {
|
||||
break
|
||||
default:
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
throw new Error(`Bridge Mode: ${process.env.ORACLE_BRIDGE_MODE} not supported.`)
|
||||
throw new Error(`Bridge Mode: ${ORACLE_BRIDGE_MODE} not supported.`)
|
||||
} else {
|
||||
homeAbi = HOME_ERC_TO_NATIVE_ABI
|
||||
foreignAbi = FOREIGN_ERC_TO_NATIVE_ABI
|
||||
@ -52,56 +50,41 @@ switch (process.env.ORACLE_BRIDGE_MODE) {
|
||||
}
|
||||
}
|
||||
|
||||
let maxProcessingTime = null
|
||||
if (String(process.env.ORACLE_MAX_PROCESSING_TIME) === '0') {
|
||||
maxProcessingTime = 0
|
||||
} else if (!process.env.ORACLE_MAX_PROCESSING_TIME) {
|
||||
maxProcessingTime =
|
||||
4 * Math.max(process.env.ORACLE_HOME_RPC_POLLING_INTERVAL, process.env.ORACLE_FOREIGN_RPC_POLLING_INTERVAL)
|
||||
} else {
|
||||
maxProcessingTime = Number(process.env.ORACLE_MAX_PROCESSING_TIME)
|
||||
const homeContract = new web3Home.eth.Contract(homeAbi, COMMON_HOME_BRIDGE_ADDRESS)
|
||||
const homeConfig = {
|
||||
chain: 'home',
|
||||
bridgeAddress: COMMON_HOME_BRIDGE_ADDRESS,
|
||||
bridgeABI: homeAbi,
|
||||
pollingInterval: parseInt(ORACLE_HOME_RPC_POLLING_INTERVAL, 10),
|
||||
startBlock: parseInt(ORACLE_HOME_START_BLOCK, 10) || 0,
|
||||
blockPollingLimit: parseInt(ORACLE_HOME_RPC_BLOCK_POLLING_LIMIT, 10),
|
||||
web3: web3Home,
|
||||
bridgeContract: homeContract,
|
||||
eventContract: homeContract
|
||||
}
|
||||
|
||||
const bridgeConfig = {
|
||||
homeBridgeAddress: process.env.COMMON_HOME_BRIDGE_ADDRESS,
|
||||
homeBridgeAbi: homeAbi,
|
||||
foreignBridgeAddress: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS,
|
||||
foreignBridgeAbi: foreignAbi,
|
||||
const foreignContract = new web3Foreign.eth.Contract(foreignAbi, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
const foreignConfig = {
|
||||
chain: 'foreign',
|
||||
bridgeAddress: COMMON_FOREIGN_BRIDGE_ADDRESS,
|
||||
bridgeABI: foreignAbi,
|
||||
pollingInterval: parseInt(ORACLE_FOREIGN_RPC_POLLING_INTERVAL, 10),
|
||||
startBlock: parseInt(ORACLE_FOREIGN_START_BLOCK, 10) || 0,
|
||||
blockPollingLimit: parseInt(ORACLE_FOREIGN_RPC_BLOCK_POLLING_LIMIT, 10),
|
||||
web3: web3Foreign,
|
||||
bridgeContract: foreignContract,
|
||||
eventContract: foreignContract
|
||||
}
|
||||
|
||||
const maxProcessingTime =
|
||||
parseInt(ORACLE_MAX_PROCESSING_TIME, 10) || 4 * Math.max(homeConfig.pollingInterval, foreignConfig.pollingInterval)
|
||||
|
||||
module.exports = {
|
||||
eventFilter: {},
|
||||
validatorAddress: ORACLE_VALIDATOR_ADDRESS || privateKeyToAddress(ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY),
|
||||
maxProcessingTime,
|
||||
shutdownKey: 'oracle-shutdown'
|
||||
}
|
||||
|
||||
const toBNOrNull = x => (x ? toBN(x) : null)
|
||||
|
||||
const homeConfig = {
|
||||
chain: 'home',
|
||||
eventContractAddress: process.env.COMMON_HOME_BRIDGE_ADDRESS,
|
||||
eventAbi: homeAbi,
|
||||
bridgeContractAddress: process.env.COMMON_HOME_BRIDGE_ADDRESS,
|
||||
bridgeAbi: homeAbi,
|
||||
pollingInterval: process.env.ORACLE_HOME_RPC_POLLING_INTERVAL,
|
||||
startBlock: toBN(process.env.ORACLE_HOME_START_BLOCK || 0),
|
||||
blockPollingLimit: toBNOrNull(process.env.ORACLE_HOME_RPC_BLOCK_POLLING_LIMIT),
|
||||
web3: web3Home
|
||||
}
|
||||
|
||||
const foreignConfig = {
|
||||
chain: 'foreign',
|
||||
eventContractAddress: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS,
|
||||
eventAbi: foreignAbi,
|
||||
bridgeContractAddress: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS,
|
||||
bridgeAbi: foreignAbi,
|
||||
pollingInterval: process.env.ORACLE_FOREIGN_RPC_POLLING_INTERVAL,
|
||||
startBlock: toBN(process.env.ORACLE_FOREIGN_START_BLOCK || 0),
|
||||
blockPollingLimit: toBNOrNull(process.env.ORACLE_FOREIGN_RPC_BLOCK_POLLING_LIMIT),
|
||||
web3: web3Foreign
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
bridgeConfig,
|
||||
homeConfig,
|
||||
foreignConfig,
|
||||
shutdownKey: 'oracle-shutdown',
|
||||
home: homeConfig,
|
||||
foreign: foreignConfig,
|
||||
id
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ const baseConfig = require('./base.config')
|
||||
const id = `${baseConfig.id}-collected-signatures`
|
||||
|
||||
module.exports = {
|
||||
...baseConfig.bridgeConfig,
|
||||
...baseConfig.homeConfig,
|
||||
...baseConfig,
|
||||
main: baseConfig.home,
|
||||
event: 'CollectedSignatures',
|
||||
queue: 'foreign-prioritized',
|
||||
name: `watcher-${id}`,
|
||||
|
@ -1,20 +0,0 @@
|
||||
const baseConfig = require('./base.config')
|
||||
const { EXIT_CODES } = require('../src/utils/constants')
|
||||
|
||||
const id = `${baseConfig.id}-convert-to-chai`
|
||||
|
||||
const workerRequired = baseConfig.id === 'erc-native'
|
||||
|
||||
if (!workerRequired) {
|
||||
console.error(`Convert to chai tokens worker not required for bridge mode ${process.env.ORACLE_BRIDGE_MODE}`)
|
||||
process.exit(EXIT_CODES.WATCHER_NOT_REQUIRED)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
...baseConfig.bridgeConfig,
|
||||
...baseConfig.foreignConfig,
|
||||
workerQueue: 'convert-to-chai',
|
||||
senderQueue: 'foreign-prioritized',
|
||||
name: `worker-${id}`,
|
||||
id
|
||||
}
|
@ -6,7 +6,7 @@ const { web3Foreign, web3ForeignRedundant, web3ForeignFallback } = require('../s
|
||||
const { ORACLE_FOREIGN_TX_RESEND_INTERVAL } = process.env
|
||||
|
||||
module.exports = {
|
||||
...baseConfig.bridgeConfig,
|
||||
...baseConfig,
|
||||
queue: 'foreign-prioritized',
|
||||
oldQueue: 'foreign',
|
||||
id: 'foreign',
|
||||
|
@ -6,7 +6,7 @@ const { web3Home, web3HomeRedundant, web3HomeFallback } = require('../src/servic
|
||||
const { ORACLE_HOME_TX_RESEND_INTERVAL } = process.env
|
||||
|
||||
module.exports = {
|
||||
...baseConfig.bridgeConfig,
|
||||
...baseConfig,
|
||||
queue: 'home-prioritized',
|
||||
oldQueue: 'home',
|
||||
id: 'home',
|
||||
|
14
oracle/config/information-request-watcher.config.js
Normal file
14
oracle/config/information-request-watcher.config.js
Normal file
@ -0,0 +1,14 @@
|
||||
const baseConfig = require('./base.config')
|
||||
const { web3ForeignArchive } = require('../src/services/web3')
|
||||
|
||||
const id = `${baseConfig.id}-information-request`
|
||||
|
||||
module.exports = {
|
||||
...baseConfig,
|
||||
web3ForeignArchive: web3ForeignArchive || baseConfig.foreign.web3,
|
||||
main: baseConfig.home,
|
||||
event: 'UserRequestForInformation',
|
||||
queue: 'home-prioritized',
|
||||
name: `watcher-${id}`,
|
||||
id
|
||||
}
|
@ -8,7 +8,7 @@ const {
|
||||
} = process.env
|
||||
|
||||
module.exports = {
|
||||
...baseConfig.bridgeConfig,
|
||||
...baseConfig,
|
||||
id: 'shutdown-manager',
|
||||
name: 'shutdown-manager',
|
||||
pollingInterval: ORACLE_SHUTDOWN_SERVICE_POLLING_INTERVAL || 120000,
|
||||
@ -16,5 +16,6 @@ module.exports = {
|
||||
checksBeforeStop: 1,
|
||||
shutdownServiceURL: ORACLE_SHUTDOWN_SERVICE_URL,
|
||||
shutdownContractAddress: ORACLE_SHUTDOWN_CONTRACT_ADDRESS,
|
||||
shutdownMethod: (ORACLE_SHUTDOWN_CONTRACT_METHOD || 'isShutdown()').trim()
|
||||
shutdownMethod: (ORACLE_SHUTDOWN_CONTRACT_METHOD || 'isShutdown()').trim(),
|
||||
requestTimeout: 2000
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ const baseConfig = require('./base.config')
|
||||
const id = `${baseConfig.id}-signature-request`
|
||||
|
||||
module.exports = {
|
||||
...baseConfig.bridgeConfig,
|
||||
...baseConfig.homeConfig,
|
||||
...baseConfig,
|
||||
main: baseConfig.home,
|
||||
event: 'UserRequestForSignature',
|
||||
queue: 'home-prioritized',
|
||||
name: `watcher-${id}`,
|
||||
|
@ -1,5 +1,5 @@
|
||||
const baseConfig = require('./base.config')
|
||||
const { ERC20_ABI, ERC_TYPES } = require('../../commons')
|
||||
const { ERC20_ABI } = require('../../commons')
|
||||
const { EXIT_CODES } = require('../src/utils/constants')
|
||||
|
||||
const initialChecksJson = process.argv[3]
|
||||
@ -15,34 +15,22 @@ try {
|
||||
throw new Error('Error on decoding values from initial checks.')
|
||||
}
|
||||
|
||||
if (baseConfig.id === 'erc-erc' && initialChecks.foreignERC === ERC_TYPES.ERC677) {
|
||||
baseConfig.id = 'erc677-erc677'
|
||||
}
|
||||
|
||||
const id = `${baseConfig.id}-transfer`
|
||||
|
||||
const transferWatcherRequired =
|
||||
(baseConfig.id === 'erc-erc' && initialChecks.foreignERC === ERC_TYPES.ERC20) || baseConfig.id === 'erc-native'
|
||||
|
||||
if (!transferWatcherRequired) {
|
||||
if (baseConfig.id !== 'erc-native') {
|
||||
console.error(`Transfer watcher not required for bridge mode ${process.env.ORACLE_BRIDGE_MODE}`)
|
||||
process.exit(EXIT_CODES.WATCHER_NOT_REQUIRED)
|
||||
}
|
||||
|
||||
const workerQueueConfig = {}
|
||||
if (baseConfig.id === 'erc-native') {
|
||||
workerQueueConfig.workerQueue = 'convert-to-chai'
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
...baseConfig.bridgeConfig,
|
||||
...baseConfig.foreignConfig,
|
||||
...baseConfig,
|
||||
main: {
|
||||
...baseConfig.foreign,
|
||||
eventContract: new baseConfig.foreign.web3.eth.Contract(ERC20_ABI, initialChecks.bridgeableTokenAddress)
|
||||
},
|
||||
event: 'Transfer',
|
||||
eventContractAddress: initialChecks.bridgeableTokenAddress,
|
||||
eventAbi: ERC20_ABI,
|
||||
eventFilter: { to: process.env.COMMON_FOREIGN_BRIDGE_ADDRESS },
|
||||
queue: 'home-prioritized',
|
||||
...workerQueueConfig,
|
||||
name: `watcher-${id}`,
|
||||
id
|
||||
}
|
||||
|
@ -6,14 +6,13 @@ services:
|
||||
file: docker-compose.yml
|
||||
service: rabbit
|
||||
networks:
|
||||
- net_rabbit_bridge_transfer
|
||||
- net_rabbit_bridge_convert_to_chai_worker
|
||||
- net_rabbit_bridge_information
|
||||
redis:
|
||||
extends:
|
||||
file: docker-compose.yml
|
||||
service: redis
|
||||
networks:
|
||||
- net_db_bridge_transfer
|
||||
- net_db_bridge_information
|
||||
bridge_request:
|
||||
extends:
|
||||
file: docker-compose.yml
|
||||
@ -25,9 +24,6 @@ services:
|
||||
extends:
|
||||
file: docker-compose.yml
|
||||
service: bridge_collected
|
||||
volumes:
|
||||
- '~/bridge_data/access-lists/block_list.txt:/mono/oracle/access-lists/block_list.txt'
|
||||
- '~/bridge_data/access-lists/allowance_list.txt:/mono/oracle/access-lists/allowance_list.txt'
|
||||
networks:
|
||||
- net_db_bridge_request
|
||||
- net_rabbit_bridge_request
|
||||
@ -38,7 +34,7 @@ services:
|
||||
networks:
|
||||
- net_db_bridge_request
|
||||
- net_rabbit_bridge_request
|
||||
bridge_transfer:
|
||||
bridge_information:
|
||||
cpus: 0.1
|
||||
mem_limit: 500m
|
||||
image: poanetwork/tokenbridge-oracle:latest
|
||||
@ -47,22 +43,10 @@ services:
|
||||
- NODE_ENV=production
|
||||
- ORACLE_VALIDATOR_ADDRESS=${ORACLE_VALIDATOR_ADDRESS}
|
||||
restart: unless-stopped
|
||||
entrypoint: yarn watcher:transfer
|
||||
entrypoint: yarn watcher:information-request
|
||||
networks:
|
||||
- net_db_bridge_transfer
|
||||
- net_rabbit_bridge_transfer
|
||||
bridge_convert_to_chai_worker:
|
||||
cpus: 0.1
|
||||
mem_limit: 500m
|
||||
image: poanetwork/tokenbridge-oracle:latest
|
||||
env_file: ./.env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- ORACLE_VALIDATOR_ADDRESS=${ORACLE_VALIDATOR_ADDRESS}
|
||||
restart: unless-stopped
|
||||
entrypoint: yarn worker:convert-to-chai
|
||||
networks:
|
||||
- net_rabbit_bridge_convert_to_chai_worker
|
||||
- net_db_bridge_information
|
||||
- net_rabbit_bridge_information
|
||||
bridge_senderhome:
|
||||
extends:
|
||||
file: docker-compose.yml
|
||||
@ -91,25 +75,23 @@ networks:
|
||||
driver: bridge
|
||||
net_db_bridge_affirmation:
|
||||
driver: bridge
|
||||
net_db_bridge_transfer:
|
||||
net_db_bridge_information:
|
||||
driver: bridge
|
||||
net_db_bridge_senderhome:
|
||||
driver: bridge
|
||||
net_db_bridge_senderforeign:
|
||||
driver: bridge
|
||||
net_db_bridge_shutdown:
|
||||
driver: bridge
|
||||
net_rabbit_bridge_request:
|
||||
driver: bridge
|
||||
net_db_bridge_shutdown:
|
||||
driver: bridge
|
||||
net_rabbit_bridge_collected:
|
||||
driver: bridge
|
||||
net_rabbit_bridge_affirmation:
|
||||
driver: bridge
|
||||
net_rabbit_bridge_transfer:
|
||||
net_rabbit_bridge_information:
|
||||
driver: bridge
|
||||
net_rabbit_bridge_senderhome:
|
||||
driver: bridge
|
||||
net_rabbit_bridge_senderforeign:
|
||||
driver: bridge
|
||||
net_rabbit_bridge_convert_to_chai_worker:
|
||||
driver: bridge
|
@ -24,6 +24,9 @@ services:
|
||||
extends:
|
||||
file: docker-compose.yml
|
||||
service: bridge_collected
|
||||
volumes:
|
||||
- '~/bridge_data/access-lists/block_list.txt:/mono/oracle/access-lists/block_list.txt'
|
||||
- '~/bridge_data/access-lists/allowance_list.txt:/mono/oracle/access-lists/allowance_list.txt'
|
||||
networks:
|
||||
- net_db_bridge_request
|
||||
- net_rabbit_bridge_request
|
||||
|
@ -8,8 +8,8 @@
|
||||
"watcher:signature-request": "./scripts/start-worker.sh watcher signature-request-watcher",
|
||||
"watcher:collected-signatures": "./scripts/start-worker.sh watcher collected-signatures-watcher",
|
||||
"watcher:affirmation-request": "./scripts/start-worker.sh watcher affirmation-request-watcher",
|
||||
"watcher:information-request": "./scripts/start-worker.sh watcher information-request-watcher",
|
||||
"watcher:transfer": "./scripts/start-worker.sh watcher transfer-watcher",
|
||||
"worker:convert-to-chai": "./scripts/start-worker.sh worker convert-to-chai-worker",
|
||||
"sender:home": "./scripts/start-worker.sh sender home-sender",
|
||||
"sender:foreign": "./scripts/start-worker.sh sender foreign-sender",
|
||||
"confirm:transfer": "./scripts/start-worker.sh confirmRelay transfer-watcher",
|
||||
@ -47,6 +47,6 @@
|
||||
"sinon": "^6.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.18"
|
||||
"node": ">= 12.22"
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +0,0 @@
|
||||
require('../../env')
|
||||
const { toWei } = require('web3').utils
|
||||
const { web3Foreign } = require('../../src/services/web3')
|
||||
const { sendTx } = require('../../src/tx/sendTx')
|
||||
const { ERC20_ABI } = require('../../../commons')
|
||||
|
||||
const {
|
||||
USER_ADDRESS,
|
||||
USER_ADDRESS_PRIVATE_KEY,
|
||||
COMMON_FOREIGN_BRIDGE_ADDRESS,
|
||||
FOREIGN_MIN_AMOUNT_PER_TX,
|
||||
FOREIGN_TEST_TX_GAS_PRICE
|
||||
} = process.env
|
||||
|
||||
const NUMBER_OF_DEPOSITS_TO_SEND = process.argv[2] || process.env.NUMBER_OF_DEPOSITS_TO_SEND || 1
|
||||
|
||||
const { FOREIGN_ERC_TO_ERC_ABI } = require('../../../commons')
|
||||
|
||||
async function main() {
|
||||
const bridge = new web3Foreign.eth.Contract(FOREIGN_ERC_TO_ERC_ABI, COMMON_FOREIGN_BRIDGE_ADDRESS)
|
||||
const bridgeableTokenAddress = await bridge.methods.erc20token().call()
|
||||
const poa20 = new web3Foreign.eth.Contract(ERC20_ABI, bridgeableTokenAddress)
|
||||
|
||||
try {
|
||||
const foreignChainId = await web3Foreign.eth.getChainId()
|
||||
let nonce = await web3Foreign.eth.getTransactionCount(USER_ADDRESS)
|
||||
let actualSent = 0
|
||||
for (let i = 0; i < Number(NUMBER_OF_DEPOSITS_TO_SEND); i++) {
|
||||
const gasLimit = await poa20.methods
|
||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
||||
.estimateGas({ from: USER_ADDRESS })
|
||||
const data = await poa20.methods
|
||||
.transfer(COMMON_FOREIGN_BRIDGE_ADDRESS, toWei(FOREIGN_MIN_AMOUNT_PER_TX))
|
||||
.encodeABI({ from: USER_ADDRESS })
|
||||
const txHash = await sendTx({
|
||||
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
||||
data,
|
||||
nonce,
|
||||
gasPrice: FOREIGN_TEST_TX_GAS_PRICE,
|
||||
amount: '0',
|
||||
gasLimit,
|
||||
to: bridgeableTokenAddress,
|
||||
web3: web3Foreign,
|
||||
chainId: foreignChainId
|
||||
})
|
||||
if (txHash !== undefined) {
|
||||
nonce++
|
||||
actualSent++
|
||||
console.log(actualSent, ' # ', txHash)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
main()
|
@ -1,87 +0,0 @@
|
||||
require('../../env')
|
||||
const { toWei } = require('web3').utils
|
||||
const { web3Home } = require('../../src/services/web3')
|
||||
const { sendTx } = require('../../src/tx/sendTx')
|
||||
const { isValidAmount } = require('../utils/utils')
|
||||
const { HOME_ERC_TO_ERC_ABI } = require('../../../commons')
|
||||
|
||||
const {
|
||||
USER_ADDRESS,
|
||||
USER_ADDRESS_PRIVATE_KEY,
|
||||
COMMON_HOME_BRIDGE_ADDRESS,
|
||||
HOME_MIN_AMOUNT_PER_TX,
|
||||
HOME_TEST_TX_GAS_PRICE
|
||||
} = process.env
|
||||
|
||||
const NUMBER_OF_WITHDRAWALS_TO_SEND = process.argv[2] || process.env.NUMBER_OF_WITHDRAWALS_TO_SEND || 1
|
||||
|
||||
const BRIDGEABLE_TOKEN_ABI = [
|
||||
{
|
||||
constant: false,
|
||||
inputs: [
|
||||
{
|
||||
name: '_to',
|
||||
type: 'address'
|
||||
},
|
||||
{
|
||||
name: '_value',
|
||||
type: 'uint256'
|
||||
},
|
||||
{
|
||||
name: '_data',
|
||||
type: 'bytes'
|
||||
}
|
||||
],
|
||||
name: 'transferAndCall',
|
||||
outputs: [
|
||||
{
|
||||
name: '',
|
||||
type: 'bool'
|
||||
}
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'nonpayable',
|
||||
type: 'function'
|
||||
}
|
||||
]
|
||||
|
||||
async function main() {
|
||||
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 erc677 = new web3Home.eth.Contract(BRIDGEABLE_TOKEN_ABI, BRIDGEABLE_TOKEN_ADDRESS)
|
||||
|
||||
try {
|
||||
await isValidAmount(HOME_MIN_AMOUNT_PER_TX, bridge)
|
||||
|
||||
const homeChainId = await web3Home.eth.getChainId()
|
||||
let nonce = await web3Home.eth.getTransactionCount(USER_ADDRESS)
|
||||
let actualSent = 0
|
||||
for (let i = 0; i < Number(NUMBER_OF_WITHDRAWALS_TO_SEND); i++) {
|
||||
const gasLimit = await erc677.methods
|
||||
.transferAndCall(COMMON_HOME_BRIDGE_ADDRESS, toWei(HOME_MIN_AMOUNT_PER_TX), '0x')
|
||||
.estimateGas({ from: USER_ADDRESS })
|
||||
const data = await erc677.methods
|
||||
.transferAndCall(COMMON_HOME_BRIDGE_ADDRESS, toWei(HOME_MIN_AMOUNT_PER_TX), '0x')
|
||||
.encodeABI({ from: USER_ADDRESS })
|
||||
const txHash = await sendTx({
|
||||
privateKey: USER_ADDRESS_PRIVATE_KEY,
|
||||
data,
|
||||
nonce,
|
||||
gasPrice: HOME_TEST_TX_GAS_PRICE,
|
||||
amount: '0',
|
||||
gasLimit,
|
||||
to: BRIDGEABLE_TOKEN_ADDRESS,
|
||||
web3: web3Home,
|
||||
chainId: homeChainId
|
||||
})
|
||||
if (txHash !== undefined) {
|
||||
nonce++
|
||||
actualSent++
|
||||
console.log(actualSent, ' # ', txHash)
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
main()
|
@ -1,16 +1,10 @@
|
||||
require('../env')
|
||||
|
||||
const { BRIDGE_VALIDATORS_ABI } = require('../../commons')
|
||||
const { web3Home, web3Foreign } = require('../src/services/web3')
|
||||
const { bridgeConfig } = require('../config/base.config')
|
||||
const { home, foreign } = require('../config/base.config')
|
||||
|
||||
const homeABI = bridgeConfig.homeBridgeAbi
|
||||
const foreignABI = bridgeConfig.foreignBridgeAbi
|
||||
|
||||
async function getStartBlock(web3, bridgeAddress, bridgeAbi) {
|
||||
async function getStartBlock(bridgeContract, web3) {
|
||||
try {
|
||||
const bridgeContract = new web3.eth.Contract(bridgeAbi, bridgeAddress)
|
||||
|
||||
const deployedAtBlock = await bridgeContract.methods.deployedAtBlock().call()
|
||||
|
||||
const validatorContractAddress = await bridgeContract.methods.validatorContract().call()
|
||||
@ -30,10 +24,8 @@ async function getStartBlock(web3, bridgeAddress, bridgeAbi) {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { COMMON_HOME_BRIDGE_ADDRESS, COMMON_FOREIGN_BRIDGE_ADDRESS } = process.env
|
||||
|
||||
const homeStartBlock = await getStartBlock(web3Home, COMMON_HOME_BRIDGE_ADDRESS, homeABI)
|
||||
const foreignStartBlock = await getStartBlock(web3Foreign, COMMON_FOREIGN_BRIDGE_ADDRESS, foreignABI)
|
||||
const homeStartBlock = await getStartBlock(home.bridgeContract, home.web3)
|
||||
const foreignStartBlock = await getStartBlock(foreign.bridgeContract, foreign.web3)
|
||||
const result = {
|
||||
homeStartBlock,
|
||||
foreignStartBlock
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user