Add UI e2e and ultimate tests for stake mediators and fix transfer finalization detection (#347)

This commit is contained in:
Gerardo Nardelli 2020-06-01 14:58:03 -03:00 committed by GitHub
parent 8d6acd0339
commit 4db62d721d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 538 additions and 14 deletions

@ -314,3 +314,8 @@ workflows:
scenario-name: amb scenario-name: amb
redis-key: amb-collected-signatures:lastProcessedBlock redis-key: amb-collected-signatures:lastProcessedBlock
oracle-e2e-script: "amb" oracle-e2e-script: "amb"
- ultimate:
name: "ultimate: amb stake erc to erc"
scenario-name: ultimate-amb-stake-erc-to-erc
redis-key: amb-collected-signatures:lastProcessedBlock
ui-e2e-grep: "AMB-STAKE-ERC-TO-ERC"

@ -0,0 +1,14 @@
# 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

@ -0,0 +1,54 @@
---
driver:
name: docker
platforms:
- name: oracle-amb-host
groups:
- ultimate
- amb
children:
- oracle
image: ubuntu:16.04
privileged: true
network_mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- name: ui-amb-stake-erc-to-erc-host
groups:
- ultimate
- amb-stake-erc-to-erc
children:
- ui
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-amb-host:
COMMON_HOME_RPC_URL: "http://parity1:8545"
COMMON_FOREIGN_RPC_URL: "http://parity2:8545"
ORACLE_VALIDATOR_ADDRESS: "0xaaB52d66283F7A1D5978bcFcB55721ACB467384b"
ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY: "8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9"
ui-amb-stake-erc-to-erc-host:
COMMON_HOME_RPC_URL: "http://localhost:8541"
COMMON_FOREIGN_RPC_URL: "http://localhost:8542"
verifier:
name: testinfra
lint:
name: flake8
scenario:
name: ultimate-amb-stake-erc-to-erc
test_sequence:
- cleanup
- destroy
- syntax
- create
- prepare
- converge

@ -0,0 +1,4 @@
---
COMMON_HOME_BRIDGE_ADDRESS: "0xc26Aa60Ff574f157616D3aEE70e08aAC129E1dFC"
COMMON_FOREIGN_BRIDGE_ADDRESS: "0xc26Aa60Ff574f157616D3aEE70e08aAC129E1dFC"
UI_PORT: 3003

@ -21,3 +21,5 @@ COMMON_FOREIGN_GAS_PRICE_FACTOR=1
ORACLE_HOME_RPC_POLLING_INTERVAL=500 ORACLE_HOME_RPC_POLLING_INTERVAL=500
ORACLE_FOREIGN_RPC_POLLING_INTERVAL=500 ORACLE_FOREIGN_RPC_POLLING_INTERVAL=500
ORACLE_ALLOW_HTTP_FOR_RPC=yes ORACLE_ALLOW_HTTP_FOR_RPC=yes
ORACLE_HOME_START_BLOCK=1
ORACLE_FOREIGN_START_BLOCK=1

@ -21,3 +21,5 @@ COMMON_FOREIGN_GAS_PRICE_FACTOR=0.1
ORACLE_HOME_RPC_POLLING_INTERVAL=500 ORACLE_HOME_RPC_POLLING_INTERVAL=500
ORACLE_FOREIGN_RPC_POLLING_INTERVAL=500 ORACLE_FOREIGN_RPC_POLLING_INTERVAL=500
ORACLE_ALLOW_HTTP_FOR_RPC=yes ORACLE_ALLOW_HTTP_FOR_RPC=yes
ORACLE_HOME_START_BLOCK=1
ORACLE_FOREIGN_START_BLOCK=1

@ -21,3 +21,5 @@ COMMON_FOREIGN_GAS_PRICE_FACTOR=0.1
ORACLE_HOME_RPC_POLLING_INTERVAL=500 ORACLE_HOME_RPC_POLLING_INTERVAL=500
ORACLE_FOREIGN_RPC_POLLING_INTERVAL=500 ORACLE_FOREIGN_RPC_POLLING_INTERVAL=500
ORACLE_ALLOW_HTTP_FOR_RPC=yes ORACLE_ALLOW_HTTP_FOR_RPC=yes
ORACLE_HOME_START_BLOCK=1
ORACLE_FOREIGN_START_BLOCK=1

@ -0,0 +1,23 @@
COMMON_HOME_BRIDGE_ADDRESS=0xc26Aa60Ff574f157616D3aEE70e08aAC129E1dFC
COMMON_FOREIGN_BRIDGE_ADDRESS=0xc26Aa60Ff574f157616D3aEE70e08aAC129E1dFC
COMMON_FOREIGN_RPC_URL=http://localhost:8542
COMMON_HOME_RPC_URL=http://localhost:8541
UI_NATIVE_TOKEN_DISPLAY_NAME=POA
UI_HOME_NETWORK_DISPLAY_NAME=Sokol
UI_FOREIGN_NETWORK_DISPLAY_NAME=Kovan
UI_HOME_EXPLORER_TX_TEMPLATE=https://blockscout.com/poa/sokol/tx//%s
UI_FOREIGN_EXPLORER_TX_TEMPLATE=https://blockscout.com/eth/kovan/tx/%s
UI_HOME_EXPLORER_ADDRESS_TEMPLATE=https://blockscout.com/poa/sokol/address/%s
UI_FOREIGN_EXPLORER_ADDRESS_TEMPLATE=https://blockscout.com/eth/kovan/address/%s
COMMON_HOME_GAS_PRICE_SUPPLIER_URL=https://gasprice.poa.network/
COMMON_HOME_GAS_PRICE_SPEED_TYPE=standard
COMMON_HOME_GAS_PRICE_FALLBACK=5000000000
UI_HOME_GAS_PRICE_UPDATE_INTERVAL=15000
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=5000000000
UI_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=15000
COMMON_FOREIGN_GAS_PRICE_FACTOR=1
UI_PORT=3000
UI_STYLES=stake

@ -20,3 +20,4 @@ COMMON_FOREIGN_GAS_PRICE_FALLBACK=5000000000
UI_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=15000 UI_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=15000
COMMON_FOREIGN_GAS_PRICE_FACTOR=1 COMMON_FOREIGN_GAS_PRICE_FACTOR=1
UI_PORT=3000 UI_PORT=3000
UI_STYLES=core

@ -20,3 +20,4 @@ COMMON_FOREIGN_GAS_PRICE_FALLBACK=5000000000
UI_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=15000 UI_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=15000
COMMON_FOREIGN_GAS_PRICE_FACTOR=1 COMMON_FOREIGN_GAS_PRICE_FACTOR=1
UI_PORT=3000 UI_PORT=3000
UI_STYLES=core

@ -20,3 +20,4 @@ COMMON_FOREIGN_GAS_PRICE_FALLBACK=5000000000
UI_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=15000 UI_FOREIGN_GAS_PRICE_UPDATE_INTERVAL=15000
COMMON_FOREIGN_GAS_PRICE_FACTOR=1 COMMON_FOREIGN_GAS_PRICE_FACTOR=1
UI_PORT=3000 UI_PORT=3000
UI_STYLES=core

@ -63,6 +63,14 @@
"foreignBox": "0x6C4EaAb8756d53Bf599FFe2347FAFF1123D6C8A1", "foreignBox": "0x6C4EaAb8756d53Bf599FFe2347FAFF1123D6C8A1",
"monitor": "http://monitor-amb:3013/bridge" "monitor": "http://monitor-amb:3013/bridge"
}, },
"ambStakeErcToErc": {
"home": "0xc26Aa60Ff574f157616D3aEE70e08aAC129E1dFC",
"foreign": "0xc26Aa60Ff574f157616D3aEE70e08aAC129E1dFC",
"homeToken": "0x6f359aC418a5f7538F7755A33C9c7dDf38785524",
"foreignToken": "0x6f359aC418a5f7538F7755A33C9c7dDf38785524",
"blockReward": "0xF9698Eb93702dfdd0e2d802088d4c21822a8A977",
"ui": "http://localhost:3003"
},
"homeRPC": { "homeRPC": {
"URL": "http://parity1:8545", "URL": "http://parity1:8545",
"ID": "77" "ID": "77"

@ -0,0 +1,30 @@
BRIDGE_MODE=STAKE_AMB_ERC_TO_ERC
DEPLOYMENT_ACCOUNT_PRIVATE_KEY=8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9
DEPLOYMENT_GAS_LIMIT_EXTRA=0.2
HOME_DEPLOYMENT_GAS_PRICE=10000000000
FOREIGN_DEPLOYMENT_GAS_PRICE=10000000000
GET_RECEIPT_INTERVAL_IN_MILLISECONDS=50
HOME_STAKE_TOKEN_ADDRESS=0x6f359aC418a5f7538F7755A33C9c7dDf38785524
FOREIGN_STAKE_TOKEN_ADDRESS=0x6f359aC418a5f7538F7755A33C9c7dDf38785524
BLOCK_REWARD_ADDRESS=0xF9698Eb93702dfdd0e2d802088d4c21822a8A977
HOME_RPC_URL=http://parity1:8545
HOME_BRIDGE_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
HOME_UPGRADEABLE_ADMIN=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
HOME_DAILY_LIMIT=30000000000000000000000000
HOME_MAX_AMOUNT_PER_TX=1500000000000000000000000
HOME_MIN_AMOUNT_PER_TX=10000000000000000
HOME_TRANSACTIONS_FEE=0
FOREIGN_RPC_URL=http://parity2:8545
FOREIGN_BRIDGE_OWNER=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
FOREIGN_UPGRADEABLE_ADMIN=0xaaB52d66283F7A1D5978bcFcB55721ACB467384b
FOREIGN_DAILY_LIMIT=15000000000000000000000000
FOREIGN_MAX_AMOUNT_PER_TX=750000000000000000000000
FOREIGN_MIN_AMOUNT_PER_TX=10000000000000000
HOME_AMB_BRIDGE=0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0
FOREIGN_AMB_BRIDGE=0x0AEe1FCD12dDFab6265F7f8956e6E012A9Fe4Aa0
HOME_MEDIATOR_REQUEST_GAS_LIMIT=2000000
FOREIGN_MEDIATOR_REQUEST_GAS_LIMIT=2000000
BRIDGEABLE_TOKEN_NAME='not used'
BRIDGEABLE_TOKEN_SYMBOL='not used'
BRIDGEABLE_TOKEN_DECIMALS='18'

@ -93,6 +93,15 @@ services:
command: "true" command: "true"
networks: networks:
- ultimate - ultimate
ui-amb-stake-erc20-erc20:
build:
context: ..
dockerfile: ui/Dockerfile
args:
DOT_ENV_PATH: e2e-commons/components-envs/ui-amb-stake-erc20-erc20.env
command: "true"
networks:
- ultimate
monitor: monitor:
build: build:
context: .. context: ..

@ -43,3 +43,13 @@ echo -e "\n\n############ Deploying test contract for amb ############\n"
cd "$DEPLOY_PATH" cd "$DEPLOY_PATH"
node src/utils/deployTestBox.js node src/utils/deployTestBox.js
cd - > /dev/null cd - > /dev/null
echo -e "\n\n############ Deploying amb stake erc to erc ############\n"
cp "$ENVS_PATH/amb-stake-erc-to-erc.env" "$DEPLOY_PATH/.env"
node deployMultiBridgeToken.js
node deployBridgeTokenRewardable.js
cd "$DEPLOY_PATH"
node deploy.js
cd - > /dev/null
node setupStakeTokens.js
cd - > /dev/null

@ -0,0 +1,43 @@
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()

@ -0,0 +1,43 @@
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()

@ -0,0 +1,111 @@
const path = require('path')
const { ambStakeErcToErc, validator, secondValidator, thirdValidator } = require('../constants.json')
const contractsPath = '../../contracts'
require('dotenv').config({
path: path.join(__dirname, contractsPath, '/deploy/.env')
})
const { sendRawTxHome, sendRawTxForeign, privateKeyToAddress } = require(`${contractsPath}/deploy/src/deploymentUtils`)
const { web3Home, web3Foreign, deploymentPrivateKey } = require(`${contractsPath}/deploy/src/web3`)
const BlockReward = require(`${contractsPath}/build/contracts/BlockReward.json`)
const ERC677BridgeTokenRewardable = require(`${contractsPath}/build/contracts/ERC677BridgeTokenRewardable.json`)
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 setupStakeTokens() {
try {
let homeNonce = await web3Home.eth.getTransactionCount(DEPLOYMENT_ACCOUNT_ADDRESS)
const blockReward = new web3Home.eth.Contract(BlockReward.abi, ambStakeErcToErc.blockReward)
console.log('\n[Home] Set token in block reward')
const setTokenData = await blockReward.methods.setToken(ambStakeErcToErc.homeToken).encodeABI()
await sendRawTxHome({
data: setTokenData,
nonce: homeNonce,
to: blockReward.options.address,
privateKey: deploymentPrivateKey,
url: process.env.HOME_RPC_URL
})
homeNonce++
console.log('\n[Home] Set validators rewards in block reward')
const setValidatorsRewardsData = await blockReward.methods
.setValidatorsRewards([validator.address, secondValidator.address, thirdValidator.address])
.encodeABI()
await sendRawTxHome({
data: setValidatorsRewardsData,
nonce: homeNonce,
to: blockReward.options.address,
privateKey: deploymentPrivateKey,
url: process.env.HOME_RPC_URL
})
homeNonce++
const homeToken = new web3Home.eth.Contract(ERC677BridgeTokenRewardable.abi, ambStakeErcToErc.homeToken)
console.log('\n[Home] Set block reward in token')
const setBlockRewardData = await homeToken.methods.setBlockRewardContract(ambStakeErcToErc.blockReward).encodeABI()
await sendRawTxHome({
data: setBlockRewardData,
nonce: homeNonce,
to: homeToken.options.address,
privateKey: deploymentPrivateKey,
url: process.env.HOME_RPC_URL
})
homeNonce++
console.log('\n[Home] Add bridge in token')
const addBridgeData = await homeToken.methods.addBridge(ambStakeErcToErc.home).encodeABI()
await sendRawTxHome({
data: addBridgeData,
nonce: homeNonce,
to: homeToken.options.address,
privateKey: deploymentPrivateKey,
url: process.env.HOME_RPC_URL
})
homeNonce++
console.log('\n[Home] transfer token ownership to mediator')
const transferOwnershipData = await homeToken.methods.transferOwnership(ambStakeErcToErc.home).encodeABI()
await sendRawTxHome({
data: transferOwnershipData,
nonce: homeNonce,
to: homeToken.options.address,
privateKey: deploymentPrivateKey,
url: process.env.HOME_RPC_URL
})
homeNonce++
let foreignNonce = await web3Foreign.eth.getTransactionCount(DEPLOYMENT_ACCOUNT_ADDRESS)
const foreignToken = new web3Foreign.eth.Contract(ERC677MultiBridgeToken.abi, ambStakeErcToErc.foreignToken)
console.log('\n[Foreign] Add bridge in token')
const addBridgeForeignData = await homeToken.methods.addBridge(ambStakeErcToErc.foreign).encodeABI()
await sendRawTxForeign({
data: addBridgeForeignData,
nonce: foreignNonce,
to: foreignToken.options.address,
privateKey: deploymentPrivateKey,
url: process.env.FOREIGN_RPC_URL
})
foreignNonce++
console.log('\n[Foreign] transfer token ownership to mediator')
const transferOwnershipForeignData = await homeToken.methods.transferOwnership(ambStakeErcToErc.foreign).encodeABI()
await sendRawTxForeign({
data: transferOwnershipForeignData,
nonce: foreignNonce,
to: foreignToken.options.address,
privateKey: deploymentPrivateKey,
url: process.env.FOREIGN_RPC_URL
})
foreignNonce++
} catch (e) {
console.log(e)
throw e
}
}
setupStakeTokens()

@ -74,11 +74,12 @@ while [ "$1" != "" ]; do
fi fi
if [ "$1" == "ui" ]; then if [ "$1" == "ui" ]; then
docker-compose up -d ui ui-erc20 ui-erc20-native docker-compose up -d ui ui-erc20 ui-erc20-native ui-amb-stake-erc20-erc20
docker-compose run -d -p 3000:3000 ui yarn start docker-compose run -d -p 3000:3000 ui yarn start
docker-compose run -d -p 3001:3000 ui-erc20 yarn start docker-compose run -d -p 3001:3000 ui-erc20 yarn start
docker-compose run -d -p 3002:3000 ui-erc20-native yarn start docker-compose run -d -p 3002:3000 ui-erc20-native yarn start
docker-compose run -d -p 3003:3000 ui-amb-stake-erc20-erc20 yarn start
fi fi
if [ "$1" == "deploy" ]; then if [ "$1" == "deploy" ]; then
@ -109,5 +110,9 @@ while [ "$1" != "" ]; do
../deployment-e2e/molecule.sh ultimate-amb ../deployment-e2e/molecule.sh ultimate-amb
fi fi
if [ "$1" == "ultimate-amb-stake-erc-to-erc" ]; then
../deployment-e2e/molecule.sh ultimate-amb-stake-erc-to-erc
fi
shift # Shift all the parameters down by one shift # Shift all the parameters down by one
done done

@ -5,6 +5,7 @@ const {
nativeToErcBridge, nativeToErcBridge,
ercToErcBridge, ercToErcBridge,
ercToNativeBridge, ercToNativeBridge,
ambStakeErcToErc,
homeRPC, homeRPC,
foreignRPC foreignRPC
} = require('../e2e-commons/constants.json') } = require('../e2e-commons/constants.json')
@ -38,6 +39,10 @@ class Utils {
return ercToNativeBridge.ui return ercToNativeBridge.ui
} }
static async getAMBStakeStartURL() {
return ambStakeErcToErc.ui
}
static async startBrowserWithMetamask() { static async startBrowserWithMetamask() {
const source = './MetaMask.crx' const source = './MetaMask.crx'
const options = new chrome.Options() const options = new chrome.Options()

@ -2,7 +2,7 @@ const { By } = require('selenium-webdriver/lib/by')
const { Page } = require('./Page.js') const { Page } = require('./Page.js')
const fieldAmount = By.id('amount') const fieldAmount = By.id('amount')
const buttonTransfer = By.className('bridge-form-button ') const buttonTransfer = By.className('bridge-form-button')
const buttonOk = By.className('swal-button swal-button--confirm') const buttonOk = By.className('swal-button swal-button--confirm')
const fieldsBalance = By.className('network-balance') const fieldsBalance = By.className('network-balance')
const classWeb3Loaded = By.className('web3-loaded') const classWeb3Loaded = By.className('web3-loaded')

@ -308,4 +308,94 @@ test.describe('e2e-test for bridge.poa, version 1.5.0', async function() {
return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction') return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction')
}) })
}) })
test.describe('AMB-STAKE-ERC-TO-ERC', async () => {
test.it('User is able to open main page of bridge-ui ', async () => {
startURL = await Utils.getAMBStakeStartURL()
const result = await mainPage.open(startURL)
console.log('Test URL: ' + startURL)
return await assert.strictEqual(result, true, 'Test FAILED. Build failed.')
})
test.it('Home page: disclaimer is displayed ', async () => {
const result = await mainPage.confirmDisclaimer()
return await assert.strictEqual(result, true, 'Test FAILED. Disclaimer is not displayed')
})
test.it('Main page: foreign erc20 balance is displayed', async () => {
await foreignAccount.setMetaMaskNetwork()
foreignBalanceBefore = await mainPage.getForeignPOABalance()
console.log('foreignBalanceBefore = ' + foreignBalanceBefore)
const result = foreignBalanceBefore !== 0
return await assert.strictEqual(result, true, 'Test FAILED. Foreign erc20 balance is zero')
})
test.it('Main page: home erc20 balance is displayed', async () => {
homeBalanceBefore = await mainPage.getHomePOABalance()
console.log('homeBalanceBefore = ' + homeBalanceBefore)
const result = homeBalanceBefore !== 0
return await assert.strictEqual(result, true, 'Test FAILED. Home erc20 balance is zero or not displayed ')
})
test.it('User is able to send tokens from Foreign account to Home account', async () => {
homeBalanceBefore = await mainPage.getForeignPOABalance()
foreignBalanceBefore = await mainPage.getHomePOABalance()
const result = await foreignAccount.transferTokens(maxAmountPerTransactionLimit)
return await assert.strictEqual(
result,
true,
'Test FAILED. User is able send tokens from Foreign account to Home account'
)
})
test.it('Foreign POA balance has correctly changed after transaction', async () => {
const newForeignBalance = await mainPage.getHomePOABalance()
const shouldBe = foreignBalanceBefore - maxAmountPerTransactionLimit
console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100
return await assert.strictEqual(result, true, 'Test FAILED.Foreign POA balance is not correct after transaction')
})
test.it('Home account has received correct amount of tokens after transaction', async () => {
const newHomeBalance = await mainPage.getForeignPOABalance()
const shouldBe = homeBalanceBefore + maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
})
test.it('User is able to send tokens from Home account to Foreign account', async () => {
await homeAccount.setMetaMaskNetwork()
homeBalanceBefore = await mainPage.getHomePOABalance()
foreignBalanceBefore = await mainPage.getForeignPOABalance()
const result = await homeAccount.transferTokens(maxAmountPerTransactionLimit)
return await assert.strictEqual(
result,
true,
'Test FAILED. User is able send tokens from Home account to Foreign account'
)
})
test.it('Home POA balance has correctly changed after transaction', async () => {
const newHomeBalance = await mainPage.getHomePOABalance()
const shouldBe = homeBalanceBefore - maxAmountPerTransactionLimit
console.log('newHomeBalance = ' + newHomeBalance)
console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newHomeBalance) < maxAmountPerTransactionLimit / 100
homeBalanceBefore = newHomeBalance
return await assert.strictEqual(result, true, 'Test FAILED.Home POA balance is not correct after transaction')
})
test.it('Foreign account has received correct amount of tokens after transaction', async () => {
const newForeignBalance = await mainPage.getForeignPOABalance()
const shouldBe = foreignBalanceBefore + maxAmountPerTransactionLimit
console.log('newForeignBalance = ' + newForeignBalance)
console.log('shouldBe = ' + shouldBe)
const result = Math.abs(shouldBe - newForeignBalance) < maxAmountPerTransactionLimit / 100
return await assert.strictEqual(result, true, 'Test FAILED. Foreign POA balance is not correct after transaction')
})
})
}) })

@ -16,12 +16,10 @@ export default class NetworkSelect extends Component {
} }
displayList = () => { displayList = () => {
console.log('Display List!')
this.setState({ displayList: true }) this.setState({ displayList: true })
} }
hideList = () => { hideList = () => {
console.log('Hide List!')
this.setState({ displayList: false }) this.setState({ displayList: false })
} }

@ -12,7 +12,8 @@ import {
ERC20_BYTES32_ABI, ERC20_BYTES32_ABI,
getDeployedAtBlock, getDeployedAtBlock,
isMediatorMode, isMediatorMode,
FOREIGN_AMB_ABI FOREIGN_AMB_ABI,
HOME_AMB_ABI
} from '../../../commons' } from '../../../commons'
import { import {
getMaxPerTxLimit, getMaxPerTxLimit,
@ -35,7 +36,9 @@ import {
getRequiredSignatures, getRequiredSignatures,
getValidatorCount, getValidatorCount,
getRequiredBlockConfirmations, getRequiredBlockConfirmations,
getBridgeContract getBridgeContract,
getBridgeInterfacesVersion,
AMB_MULTIPLE_REQUESTS_PER_TX_VERSION
} from './utils/contract' } from './utils/contract'
import { balanceLoaded, removePendingTransaction } from './utils/testUtils' import { balanceLoaded, removePendingTransaction } from './utils/testUtils'
import sleep from './utils/sleep' import sleep from './utils/sleep'
@ -131,6 +134,7 @@ class ForeignStore {
explorerTxTemplate = process.env.REACT_APP_UI_FOREIGN_EXPLORER_TX_TEMPLATE || '' explorerTxTemplate = process.env.REACT_APP_UI_FOREIGN_EXPLORER_TX_TEMPLATE || ''
explorerAddressTemplate = process.env.REACT_APP_UI_FOREIGN_EXPLORER_ADDRESS_TEMPLATE || '' explorerAddressTemplate = process.env.REACT_APP_UI_FOREIGN_EXPLORER_ADDRESS_TEMPLATE || ''
ambBridgeContract = {} ambBridgeContract = {}
ambBridgeInterfaceVersion = {}
constructor(rootStore) { constructor(rootStore) {
this.web3Store = rootStore.web3Store this.web3Store = rootStore.web3Store
@ -367,8 +371,27 @@ class ForeignStore {
this.filter = value this.filter = value
} }
addWaitingForConfirmation(hash) { addWaitingForConfirmation(hash, txReceipt) {
this.waitingForConfirmation.add(hash) if (
isMediatorMode(this.rootStore.bridgeMode) &&
this.ambBridgeInterfaceVersion.major >= AMB_MULTIPLE_REQUESTS_PER_TX_VERSION.major
) {
const UserRequestForSignatureAbi = HOME_AMB_ABI.filter(
e => e.type === 'event' && e.name === 'UserRequestForSignature'
)[0]
const UserRequestForSignatureHash = this.foreignWeb3.eth.abi.encodeEventSignature(UserRequestForSignatureAbi)
// Get event in amb bridge
const ambRawEvent = txReceipt.logs.filter(
e =>
e.address === this.rootStore.homeStore.ambBridgeContract.options.address &&
e.topics[0] === UserRequestForSignatureHash
)[0]
const messageId = ambRawEvent.topics[1]
this.waitingForConfirmation.add(messageId)
} else {
this.waitingForConfirmation.add(hash)
}
this.setBlockFilter(0) this.setBlockFilter(0)
this.homeStore.setBlockFilter(0) this.homeStore.setBlockFilter(0)
} }
@ -518,6 +541,7 @@ class ForeignStore {
const foreignAMBBridgeContract = await getBridgeContract(this.foreignBridge) const foreignAMBBridgeContract = await getBridgeContract(this.foreignBridge)
this.ambBridgeContract = new this.foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, foreignAMBBridgeContract) this.ambBridgeContract = new this.foreignWeb3.eth.Contract(FOREIGN_AMB_ABI, foreignAMBBridgeContract)
this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.ambBridgeContract) this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.ambBridgeContract)
this.ambBridgeInterfaceVersion = await getBridgeInterfacesVersion(this.ambBridgeContract)
} else { } else {
this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.foreignBridge) this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.foreignBridge)
} }

@ -15,7 +15,8 @@ import {
getDeployedAtBlock, getDeployedAtBlock,
isErcToErcMode, isErcToErcMode,
isMediatorMode, isMediatorMode,
HOME_AMB_ABI HOME_AMB_ABI,
FOREIGN_AMB_ABI
} from '../../../commons' } from '../../../commons'
import { import {
getMaxPerTxLimit, getMaxPerTxLimit,
@ -43,7 +44,9 @@ import {
getValidatorCount, getValidatorCount,
getFee, getFee,
getRequiredBlockConfirmations, getRequiredBlockConfirmations,
getBridgeContract getBridgeContract,
getBridgeInterfacesVersion,
AMB_MULTIPLE_REQUESTS_PER_TX_VERSION
} from './utils/contract' } from './utils/contract'
import { balanceLoaded, removePendingTransaction } from './utils/testUtils' import { balanceLoaded, removePendingTransaction } from './utils/testUtils'
import sleep from './utils/sleep' import sleep from './utils/sleep'
@ -167,6 +170,7 @@ class HomeStore {
tokenDecimals = 18 tokenDecimals = 18
blockRewardContract = {} blockRewardContract = {}
ambBridgeContract = {} ambBridgeContract = {}
ambBridgeInterfaceVersion = {}
constructor(rootStore) { constructor(rootStore) {
this.homeWeb3 = rootStore.web3Store.homeWeb3 this.homeWeb3 = rootStore.web3Store.homeWeb3
@ -434,8 +438,27 @@ class HomeStore {
} }
} }
addWaitingForConfirmation(hash) { addWaitingForConfirmation(hash, txReceipt) {
this.waitingForConfirmation.add(hash) if (
isMediatorMode(this.rootStore.bridgeMode) &&
this.ambBridgeInterfaceVersion.major >= AMB_MULTIPLE_REQUESTS_PER_TX_VERSION.major
) {
const userRequestForAffirmationAbi = FOREIGN_AMB_ABI.filter(
e => e.type === 'event' && e.name === 'UserRequestForAffirmation'
)[0]
const userRequestForAffirmationHash = this.homeWeb3.eth.abi.encodeEventSignature(userRequestForAffirmationAbi)
// Get event in amb bridge
const ambRawEvent = txReceipt.logs.filter(
e =>
e.address === this.rootStore.foreignStore.ambBridgeContract.options.address &&
e.topics[0] === userRequestForAffirmationHash
)[0]
const messageId = ambRawEvent.topics[1]
this.waitingForConfirmation.add(messageId)
} else {
this.waitingForConfirmation.add(hash)
}
this.setBlockFilter(0) this.setBlockFilter(0)
this.rootStore.foreignStore.setBlockFilter(0) this.rootStore.foreignStore.setBlockFilter(0)
} }
@ -652,6 +675,7 @@ class HomeStore {
const homeAMBBridgeContract = await getBridgeContract(this.homeBridge) const homeAMBBridgeContract = await getBridgeContract(this.homeBridge)
this.ambBridgeContract = new this.homeWeb3.eth.Contract(HOME_AMB_ABI, homeAMBBridgeContract) this.ambBridgeContract = new this.homeWeb3.eth.Contract(HOME_AMB_ABI, homeAMBBridgeContract)
this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.ambBridgeContract) this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.ambBridgeContract)
this.ambBridgeInterfaceVersion = await getBridgeInterfacesVersion(this.ambBridgeContract)
} else { } else {
this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.homeBridge) this.requiredBlockConfirmations = await getRequiredBlockConfirmations(this.homeBridge)
} }

@ -142,7 +142,7 @@ class TxStore {
removePendingTransaction() removePendingTransaction()
}) })
} else { } else {
this.foreignStore.addWaitingForConfirmation(hash) this.foreignStore.addWaitingForConfirmation(hash, res)
} }
} else { } else {
if (blockConfirmations > 0) { if (blockConfirmations > 0) {
@ -169,7 +169,7 @@ class TxStore {
removePendingTransaction() removePendingTransaction()
}) })
} else { } else {
this.homeStore.addWaitingForConfirmation(hash) this.homeStore.addWaitingForConfirmation(hash, res)
} }
} else { } else {
if (blockConfirmations > 0) { if (blockConfirmations > 0) {

@ -5,6 +5,12 @@ import { getValidatorList as commonGetValidatorList, getPastEvents as commonGetP
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
export const AMB_MULTIPLE_REQUESTS_PER_TX_VERSION = {
major: 5,
minor: 0,
patch: 0
}
export const getMaxPerTxLimit = async (contract, decimals) => { export const getMaxPerTxLimit = async (contract, decimals) => {
const maxPerTx = await contract.methods.maxPerTx().call() const maxPerTx = await contract.methods.maxPerTx().call()
return fromDecimals(maxPerTx, decimals) return fromDecimals(maxPerTx, decimals)
@ -109,3 +115,12 @@ export const getRequiredBlockConfirmations = async contract => {
} }
export const getBridgeContract = contract => contract.methods.bridgeContract().call() export const getBridgeContract = contract => contract.methods.bridgeContract().call()
export const getBridgeInterfacesVersion = async contract => {
const { major, minor, patch } = await contract.methods.getBridgeInterfacesVersion().call()
return {
major: parseInt(major),
minor: parseInt(minor),
patch: parseInt(patch)
}
}