Merge branch 'master' into amb-oracle
# Conflicts: # oracle-e2e/deploy.js # oracle-e2e/docker-compose.yml # oracle-e2e/run-tests.sh # oracle/config/base.config.js # oracle/src/services/gasPrice.js # oracle/src/utils/utils.js # oracle/test/gasPrice.test.js
This commit is contained in:
commit
0694fc24e9
@ -35,6 +35,12 @@ jobs:
|
||||
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/project
|
||||
initialize-root:
|
||||
docker:
|
||||
- image: circleci/node:10.15
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo su - -c 'export CI=true && cd /home/circleci/project && yarn initialize && yarn test'
|
||||
build:
|
||||
docker:
|
||||
- image: circleci/node:10.15
|
||||
@ -49,18 +55,9 @@ jobs:
|
||||
- restore_cache:
|
||||
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn run lint
|
||||
ansible-lint:
|
||||
docker:
|
||||
- image: particlekit/ansible-lint
|
||||
steps:
|
||||
- checkout
|
||||
- run: ./deployment/lint.sh
|
||||
test:
|
||||
docker:
|
||||
- image: circleci/node:10.15
|
||||
environment:
|
||||
HOME_RPC_URL: http://example.com
|
||||
FOREIGN_RPC_URL: http://example.com
|
||||
steps:
|
||||
- restore_cache:
|
||||
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
|
||||
@ -101,6 +98,14 @@ jobs:
|
||||
paths:
|
||||
- ~/.cache/yarn
|
||||
- run: yarn run ui-e2e
|
||||
monitor-e2e:
|
||||
machine:
|
||||
image: circleci/classic:latest
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: git submodule update --init
|
||||
- run: ./monitor-e2e/run-tests.sh
|
||||
cover:
|
||||
docker:
|
||||
- image: circleci/node:10.15
|
||||
@ -109,11 +114,40 @@ jobs:
|
||||
key: initialize-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run: yarn workspace ui run coverage
|
||||
- run: yarn workspace ui run coveralls
|
||||
deployment-oracle:
|
||||
machine:
|
||||
image: circleci/classic:latest
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: deployment/molecule/molecule.sh oracle
|
||||
deployment-ui:
|
||||
machine:
|
||||
image: circleci/classic:latest
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: deployment/molecule/molecule.sh ui
|
||||
ultimate-native-to-erc:
|
||||
machine:
|
||||
image: circleci/classic:latest
|
||||
docker_layer_caching: true
|
||||
steps:
|
||||
- checkout
|
||||
- run: git submodule update --init
|
||||
- run:
|
||||
name: Prepare the infrastructure
|
||||
command: e2e-commons/up.sh deploy native-to-erc
|
||||
- run: 'echo "TODO - Run the e2e tests on top of the infrastructure created by previous step"'
|
||||
workflows:
|
||||
version: 2
|
||||
tokenbridge:
|
||||
jobs:
|
||||
- initialize
|
||||
- initialize-root:
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
- build:
|
||||
requires:
|
||||
- initialize
|
||||
@ -129,6 +163,9 @@ workflows:
|
||||
filters:
|
||||
branches:
|
||||
only: master
|
||||
- ansible-lint
|
||||
- oracle-e2e
|
||||
- ui-e2e
|
||||
- monitor-e2e
|
||||
- deployment-oracle
|
||||
- deployment-ui
|
||||
- ultimate-native-to-erc
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -43,6 +43,8 @@ hosts
|
||||
Vagrantfile
|
||||
vagrant-hosts.yml
|
||||
.vagrant
|
||||
deployment/venv
|
||||
__pycache__
|
||||
|
||||
#monitor
|
||||
monitor/responses/*
|
||||
|
@ -2,17 +2,11 @@ FROM node:10
|
||||
|
||||
WORKDIR /mono
|
||||
COPY package.json .
|
||||
COPY oracle/package.json ./oracle/
|
||||
COPY oracle-e2e/package.json ./oracle-e2e/
|
||||
COPY ui/package.json ./ui/
|
||||
COPY ui/lib/web3-eth/index.js ./ui/lib/web3-eth/index.js
|
||||
COPY ui-e2e/package.json ./ui-e2e/
|
||||
COPY monitor/package.json ./monitor/
|
||||
COPY contracts/package.json ./contracts/
|
||||
COPY ui/lib/web3-eth/index.js ./ui/lib/web3-eth/index.js
|
||||
|
||||
COPY yarn.lock .
|
||||
RUN yarn install
|
||||
RUN yarn install --frozen-lockfile
|
||||
COPY ./contracts ./contracts
|
||||
RUN yarn install:deploy
|
||||
RUN yarn compile:contracts
|
||||
|
45
README.md
45
README.md
@ -24,10 +24,23 @@ Sub-repositories maintained within this monorepo are listed below.
|
||||
| [Monitor](monitor/README.md) | Tool for checking balances and unprocessed events in bridged networks. |
|
||||
| [Deployment](deployment/README.md) | Ansible playbooks for deploying cross-chain bridges. |
|
||||
| [Oracle-E2E](oracle-e2e/README.md) | End to end tests for the Oracle |
|
||||
| [Monitor-E2E](monitor-e2e/README.md) | End to end tests for the Monitor |
|
||||
| [UI-E2E](ui-e2e/README.md) | End to end tests for the UI |
|
||||
| [Commons](commons/README.md) | Interfaces, constants and utilities shared between the sub-repositories |
|
||||
| [E2E-Commons](e2e-commons/README.md) | Common utilities and configuration used in end to end tests |
|
||||
|
||||
Additionally there are [Smart Contracts](https://github.com/poanetwork/poa-bridge-contracts) used to manage bridge validators, collect signatures, and confirm asset relay and disposal.
|
||||
|
||||
## Available deployments
|
||||
|
||||
| **Launched by POA** | **Launched by 3rd parties** |
|
||||
| ---------- | ---------- |
|
||||
| [POA20 Bridge](https://bridge.poa.net/) | [Ocean Token Bridge](https://bridge.oceanprotocol.com/) |
|
||||
| [xDai Bridge](https://dai-bridge.poa.network/) | [Thunder bridge](https://ui.stormdapps.com/) |
|
||||
| [WETC Bridge](https://wetc.app/) | [Volta Token Bridge](https://vt.volta.bridge.eth.events/) & [DAI bridge to Volta Chain](https://dai.volta.bridge.eth.events/) |
|
||||
| | [Artis Brige](https://bridge.artis.network/) |
|
||||
| | [Tenda bridge](https://bridge-mainnet.tenda.network) & [xDai-to-Tenda bridge](https://bridge-xdai.tenda.network/) |
|
||||
|
||||
## Network Definitions
|
||||
|
||||
Bridging occurs between two networks.
|
||||
@ -46,26 +59,14 @@ The POA TokenBridge provides three operational modes:
|
||||
|
||||
## Initializing the monorepository
|
||||
|
||||
Clone the repository with submodules:
|
||||
Clone the repository:
|
||||
```bash
|
||||
git clone --recursive https://github.com/poanetwork/tokenbridge
|
||||
|
||||
# or initialize submodules if already cloned without --recursive option:
|
||||
git submodule update --init
|
||||
git clone https://github.com/poanetwork/tokenbridge
|
||||
```
|
||||
|
||||
Install dependencies:
|
||||
|
||||
Initialize submodules, install dependencies, compile the Smart Contracts:
|
||||
```
|
||||
yarn install && yarn install:deploy
|
||||
```
|
||||
|
||||
_**Note**: The installation should be performed with an unprivileged Linux account or with the following flag: `yarn install --unsafe-perm`. [More information](https://docs.npmjs.com/misc/scripts#user)_
|
||||
|
||||
Compile the Smart Contracts
|
||||
|
||||
```
|
||||
yarn compile:contracts
|
||||
yarn initialize
|
||||
```
|
||||
|
||||
## Linting
|
||||
@ -76,14 +77,6 @@ Running linter for all JS projects:
|
||||
yarn lint
|
||||
```
|
||||
|
||||
Running linter for all Ansible playbooks:
|
||||
|
||||
- [ansible-lint](https://github.com/ansible/ansible-lint) is required
|
||||
|
||||
```
|
||||
yarn ansible-lint
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
Running tests for all projects:
|
||||
@ -96,6 +89,10 @@ Additionaly there are end-to-end tests for [Oracle](oracle-e2e/README.md) and [U
|
||||
|
||||
For details on building, running and developing please refer to respective READMEs in sub-repositories.
|
||||
|
||||
## Building, running and deploying
|
||||
|
||||
Please refer to the instructions in sub-directories.
|
||||
|
||||
## Contributing
|
||||
|
||||
See the [CONTRIBUTING](CONTRIBUTING.md) document for contribution, testing and pull request protocol.
|
||||
|
12
commons/.eslintrc
Normal file
12
commons/.eslintrc
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": [
|
||||
"airbnb-base",
|
||||
"../.eslintrc"
|
||||
],
|
||||
"rules": {
|
||||
"no-unused-expressions": "off"
|
||||
},
|
||||
"env": {
|
||||
"mocha": true
|
||||
}
|
||||
}
|
2
commons/README.md
Normal file
2
commons/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# POA Token Bridge / Commons
|
||||
Interfaces, constants and utilities shared between the sub-repositories
|
56
commons/abis.js
Normal file
56
commons/abis.js
Normal file
@ -0,0 +1,56 @@
|
||||
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/IBlockReward').abi
|
||||
const BRIDGE_VALIDATORS_ABI = require('../contracts/build/contracts/BridgeValidators').abi
|
||||
const REWARDABLE_VALIDATORS_ABI = require('../contracts/build/contracts/RewardableValidators').abi
|
||||
|
||||
const { homeV1Abi, foreignViAbi } = require('./v1Abis')
|
||||
const { BRIDGE_MODES } = require('./constants')
|
||||
|
||||
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) {
|
||||
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 = homeV1Abi
|
||||
FOREIGN_ABI = foreignViAbi
|
||||
} else {
|
||||
throw new Error(`Unrecognized bridge mode: ${bridgeMode}`)
|
||||
}
|
||||
|
||||
return { HOME_ABI, FOREIGN_ABI }
|
||||
}
|
||||
|
||||
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
|
||||
}
|
19
commons/constants.js
Normal file
19
commons/constants.js
Normal file
@ -0,0 +1,19 @@
|
||||
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'
|
||||
}
|
||||
|
||||
const ERC_TYPES = {
|
||||
ERC20: 'ERC20',
|
||||
ERC677: 'ERC677'
|
||||
}
|
||||
|
||||
const FEE_MANAGER_MODE = {
|
||||
ONE_DIRECTION: 'ONE_DIRECTION',
|
||||
BOTH_DIRECTIONS: 'BOTH_DIRECTIONS',
|
||||
UNDEFINED: 'UNDEFINED'
|
||||
}
|
||||
|
||||
module.exports = { BRIDGE_MODES, ERC_TYPES, FEE_MANAGER_MODE }
|
9
commons/index.js
Normal file
9
commons/index.js
Normal file
@ -0,0 +1,9 @@
|
||||
const constants = require('./constants')
|
||||
const abis = require('./abis')
|
||||
const utils = require('./utils')
|
||||
|
||||
module.exports = {
|
||||
...constants,
|
||||
...abis,
|
||||
...utils
|
||||
}
|
10
commons/package.json
Normal file
10
commons/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "commons",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"lint": "eslint . --ignore-path ../.eslintignore",
|
||||
"test": "NODE_ENV=test mocha"
|
||||
}
|
||||
}
|
12
commons/test/constants.js
Normal file
12
commons/test/constants.js
Normal file
@ -0,0 +1,12 @@
|
||||
const { expect } = require('chai')
|
||||
const { BRIDGE_MODES, ERC_TYPES } = require('../constants')
|
||||
|
||||
describe('constants', () => {
|
||||
it('should contain correct number of bridge types', () => {
|
||||
expect(Object.keys(BRIDGE_MODES).length).to.be.equal(4)
|
||||
})
|
||||
|
||||
it('should contain correct number of erc types', () => {
|
||||
expect(Object.keys(ERC_TYPES).length).to.be.equal(2)
|
||||
})
|
||||
})
|
60
commons/utils.js
Normal file
60
commons/utils.js
Normal file
@ -0,0 +1,60 @@
|
||||
const { BRIDGE_MODES, FEE_MANAGER_MODE } = require('./constants')
|
||||
|
||||
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
|
||||
default:
|
||||
throw new Error(`Unrecognized bridge mode hash: '${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 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 {
|
||||
throw new Error(`Unrecognized bridge mode: ${bridgeMode}`)
|
||||
}
|
||||
|
||||
return { unitHome, unitForeign }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
decodeBridgeMode,
|
||||
decodeFeeManagerMode,
|
||||
getBridgeMode,
|
||||
getUnit
|
||||
}
|
11
deployment/.yamllint
Normal file
11
deployment/.yamllint
Normal file
@ -0,0 +1,11 @@
|
||||
extends: default
|
||||
|
||||
rules:
|
||||
braces:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
brackets:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
line-length: disable
|
||||
truthy: disable
|
98
deployment/CONFIGURATION.md
Normal file
98
deployment/CONFIGURATION.md
Normal file
@ -0,0 +1,98 @@
|
||||
# POA Token Bridge / Deployment Configuration
|
||||
|
||||
Please see the [Oracle](../oracle/README.md) for additional configuration and execution details.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
A functional Ubuntu 16.04 server launched using a trusted hosting provider. For more information, see our tutorials on [setting up a validator node on AWS](https://github.com/poanetwork/wiki/wiki/Validator-Node-on-AWS) or [setting up on non-AWS](https://github.com/poanetwork/wiki/wiki/Validator-Node-Non-AWS).
|
||||
* Record the IP address (required for file setup).
|
||||
* Setup ssh access to your node via public+private keys (using passwords is less secure).
|
||||
* When creating the node, set a meaningful `hostname` that can identify you (e.g. `validator-0x...`).
|
||||
|
||||
## Initialization
|
||||
|
||||
1. Clone this repository and go to the `deployment` folder
|
||||
```
|
||||
git clone --recursive https://github.com/poanetwork/tokenbridge
|
||||
cd tokenbridge/deployment
|
||||
```
|
||||
2. Create the file `hosts.yml` from `hosts.yml.example`
|
||||
```
|
||||
cp hosts.yml.example hosts.yml
|
||||
```
|
||||
|
||||
`hosts.yml` should have the following structure:
|
||||
|
||||
```yaml
|
||||
<bridge_name>:
|
||||
children:
|
||||
oracle:
|
||||
hosts:
|
||||
<host_ip_A>:
|
||||
ansible_user: <user>
|
||||
VALIDATOR_ADDRESS_PRIVATE_KEY: "<private_key>"
|
||||
#syslog_server_port: "<protocol>://<ip>:<port>" # When this parameter is set all bridge logs will be redirected to <ip>:<port> address.
|
||||
<host_ip_B>:
|
||||
# (...)
|
||||
ui:
|
||||
hosts:
|
||||
<host_ip_B>:
|
||||
ansible_user: <user>
|
||||
#syslog_server_port: "<protocol>://<ip>:<port>"
|
||||
<host_ip_C>:
|
||||
ansible_user: <user>
|
||||
#syslog_server_port: "<protocol>://<ip>:<port>"
|
||||
monitor:
|
||||
hosts:
|
||||
<host_ip_B>:
|
||||
ansible_user: <user>
|
||||
```
|
||||
|
||||
The config above would install the Oracle on `<host_ip_A>`, UI on `<host_ip_C>`, and both Oracle, UI and Monitor on `<host_ip_B>`.
|
||||
|
||||
Example config for installing only UI:
|
||||
```yaml
|
||||
<bridge_name>:
|
||||
children:
|
||||
oracle:
|
||||
hosts:
|
||||
ui:
|
||||
hosts:
|
||||
<host_ip>:
|
||||
ansible_user: <user>
|
||||
```
|
||||
|
||||
| Value | Description |
|
||||
|:------------------------------------------------|:----------------------------------------------------------------------------------------------------------|
|
||||
| `<bridge_name>` | The bridge name which tells Ansible which file to use. This is located in `group_vars/<bridge_name>.yml`. |
|
||||
| `<host_ip>` | Remote server IP address. |
|
||||
| ansible_user: `<user>` | User that will ssh into the node. This is typically `ubuntu` or `root`. |
|
||||
| VALIDATOR_ADDRESS_PRIVATE_KEY: `"<private_key>"` | The private key for the specified validator address. |
|
||||
| syslog_server_port: `"<protocol>://<ip>:<port>"` | Optional port specification for bridge logs. This value will be provided by an administrator if required. |
|
||||
|
||||
`hosts.yml` can contain multiple bridge configurations at once.
|
||||
|
||||
3. Copy the bridge name(s) to the hosts.yml file.
|
||||
1. Go to the group_vars folder.
|
||||
`cd group_vars`
|
||||
2. Note the <bridge_name> and add it to the hosts.yml configuration. For example, if a bridge file is named sokol-kovan.yml, you would change the <bridge_name> value in hosts.yml to sokol-kovan.
|
||||
|
||||
## Administrator Configurations
|
||||
|
||||
1. The `group_vars/<bridge_name>.yml` file contains the public bridge parameters. This file is prepared by administrators for each bridge. The validator only needs to add the required bridge name in the hosts.yml file to tell Ansible which file to use.
|
||||
|
||||
`group_vars/example.yml` shows an example configuration for the POA/Sokol - POA/Sokol bridge. Parameter values should match values from the .env file for the Oracle. See [Configuration parameters](../../oracle/README.md#configuration-parameters) for details.
|
||||
|
||||
2. You can also add the following parameters in the `group_vars` to change the default behavior of the playbooks:
|
||||
|
||||
2.1 `compose_service_user` - specifies the user created by the playbooks. This user runs the Token Bridge Oracle.
|
||||
|
||||
2.2 `bridge_repo` contains the address of the Token Bridge Oracle repository. The default value is https://github.com/poanetwork/tokenbridge.
|
||||
|
||||
2.3 `bridge_repo_branch` points to the specific branch or commit to use with the `bridge_repo`. If `bridge_repo_branch` is not specified, the default (`master`) branch is used.
|
||||
|
||||
2.4 `bridge_path` sets the path where the Token Bridge Oracle is installed. By default, it points. to the home folder of `compose_service_user`
|
||||
|
||||
2.5 `docker_compose_version` - specifies a version of docker-compose to be installed.
|
||||
|
||||
2.6 `ALLOW_HTTP` (`no` by default) can be set to `yes` to allow bridge insecure connections to the network.
|
85
deployment/EXECUTION.md
Normal file
85
deployment/EXECUTION.md
Normal file
@ -0,0 +1,85 @@
|
||||
# POA Token Bridge / Deployment Execution
|
||||
|
||||
Please refer to the [Configuration](./CONFIGURATION.md) first.
|
||||
|
||||
## Dependencies
|
||||
|
||||
On your local machine install:
|
||||
* Python 2 (v2.6-v2.7)/Python3 (v3.5+)
|
||||
* [Ansible v2.3+](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)
|
||||
* Git
|
||||
|
||||
The playbook will automatically install `Docker`, `docker-compose`, `Python`, `Git` and it dependencies (such as `curl`, `ca-certificates`, `apt-transport-https`, etc.) to the node. Also this playbooks creates an additional non-sudo docker user to run service as.
|
||||
|
||||
## Running the playbook
|
||||
|
||||
```yaml
|
||||
ansible-playbook -i hosts.yml site.yml
|
||||
```
|
||||
|
||||
## Useful arguments
|
||||
|
||||
To be used with the ansible-playbook command, for example:
|
||||
|
||||
```yaml
|
||||
ansible-playbook -i hosts.yml site.yml --ask-become-pass
|
||||
```
|
||||
|
||||
* `--ask-pass` - ask for the password used to connect to the bridge VM.
|
||||
|
||||
* `--ask-become-pass` - ask for the `become` password used to execute some commands (such as Docker installation) with root privileges.
|
||||
|
||||
* `-i <file>` - use specified file as a `hosts.yml` file.
|
||||
|
||||
* `-e "<variable>=<value>"` - override default variable.
|
||||
|
||||
* `--private-key=<file_name>` - if private keyfile is required to connect to the ubuntu instance.
|
||||
|
||||
* `--user=<username>` - connect as this username
|
||||
|
||||
## Service commands
|
||||
|
||||
The deployed components have the following services:
|
||||
|
||||
Component | Service Name
|
||||
--- | ---
|
||||
Oracle | poabridge
|
||||
UI | tokenbridge-ui
|
||||
Monitor | tokenbridge-monitor
|
||||
|
||||
Use the default `SysVinit` commands to `start`, `stop`, `restart`, and `rebuild` the service and to check the `status` of the service.
|
||||
|
||||
Commands format:
|
||||
```bash
|
||||
sudo service <service_name> [start|stop|restart|status|rebuild]
|
||||
```
|
||||
|
||||
## Rollback the Last Processed Block in Redis
|
||||
|
||||
If the bridge does not handle an event properly (i.e. a transaction stalls due to a low gas price), the Redis DB can be rolled back. You must identify which watcher needs to re-run. For example, if the validator signatures were collected but the transaction with signatures was not sent to the Foreign network, the `collected-signatures` watcher must look at the block where the corresponding `CollectedSignatures` event was raised.
|
||||
|
||||
Execute the `reset-lastBlock.sh` script in the bridge root directory. For example, if you've installed your bridge with this deployment script and all the default parameters, use the following set of commands:
|
||||
|
||||
```shell
|
||||
$ sudo su poadocker
|
||||
$ cd ~/bridge
|
||||
$ docker-compose stop bridge_affirmation bridge_request bridge_collected
|
||||
$ docker-compose exec bridge_senderhome bash ./reset-lastBlock.sh <watcher> <block num>
|
||||
$ exit
|
||||
$ sudo service poabridge restart
|
||||
```
|
||||
where the _<watcher>_ could be one of the following:
|
||||
|
||||
- `signature-request`
|
||||
- `collected-signatures`
|
||||
- `affirmation-request`
|
||||
|
||||
## Logs
|
||||
|
||||
If the `syslog_server_port` option in the hosts.yml file is not set, all logs will be stored in `/var/log/docker/` folder in the set of folders with the `bridge_` prefix.
|
||||
|
||||
If the `syslog_server_port` is set, logs will be redirected to the specified server and cannot be accessed on the bridge machine.
|
||||
|
||||
```yaml
|
||||
syslog_server_port: "<protocol>://<ip>:<port>" # When this parameter is set all bridge logs will be redirected to the <ip>:<port> address.
|
||||
```
|
@ -4,30 +4,19 @@ Ansible playbooks for deploying cross-chain bridges.
|
||||
## Overview
|
||||
Please refer to the [POA Token Bridge](../README.md) overview first of all.
|
||||
|
||||
These playbooks are designed to automate the deployment process for cross-chain bridges on bridge validator nodes. This process installs the bridge as a service and sets .env configurations on a remote server. Playbooks for the current Token Bridge Oracle deployment are located in the [Oracle](oracle) folder.
|
||||
|
||||
## Dependencies
|
||||
|
||||
The playbooks automatically install `Docker`, `docker-compose`, `Python`, `Git`and it dependencies (such as `curl`, `ca-certificates`, `apt-transport-https`, etc.). Install [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) to launch playbooks.
|
||||
|
||||
## Linting
|
||||
|
||||
- [ansible-lint](https://github.com/ansible/ansible-lint) is required
|
||||
|
||||
`yarn ansible-lint`
|
||||
These playbooks are designed to automate the deployment process for cross-chain bridges on bridge validator nodes. This process installs the bridge as a service and sets .env configurations on a remote server.
|
||||
|
||||
## Configuration
|
||||
|
||||
Please see the [Oracle](../oracle/README.md) for configuration and execution details.
|
||||
Please refer to [Configuration](./CONFIGURATION.md).
|
||||
|
||||
## Bridge service commands
|
||||
## Execution
|
||||
|
||||
The Bridge service is named `poabridge`. Use the default `SysVinit` commands to `start`, `stop`, `restart`, and `rebuild` the service and to check the `status` of the service.
|
||||
Please refer to [Execution](./EXECUTION.md).
|
||||
|
||||
Commands format:
|
||||
```bash
|
||||
sudo service poabridge [start|stop|restart|status|rebuild]
|
||||
```
|
||||
## Testing
|
||||
|
||||
Please refer to [Testing](./molecule/TESTING.md).
|
||||
|
||||
## Contributing
|
||||
|
||||
|
54
deployment/group_vars/dai.yml
Normal file
54
deployment/group_vars/dai.yml
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
## General settings
|
||||
BRIDGE_MODE: "ERC_TO_NATIVE"
|
||||
HOME_NATIVE_NAME: "xDai"
|
||||
|
||||
## Home contract
|
||||
HOME_RPC_URL: "https://dai.poa.network"
|
||||
HOME_NAME: "xDai chain"
|
||||
HOME_WITHOUT_EVENTS: false
|
||||
HOME_BRIDGE_ADDRESS: "0x7301CFA0e1756B71869E93d4e4Dca5c7d0eb0AA6"
|
||||
HOME_POLLING_INTERVAL: 5000
|
||||
|
||||
## Foreign contract
|
||||
FOREIGN_RPC_URL: "https://mainnet.infura.io"
|
||||
FOREIGN_NAME: "Ethereum Mainnet"
|
||||
FOREIGN_WITHOUT_EVENTS: false
|
||||
FOREIGN_BRIDGE_ADDRESS: "0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016"
|
||||
ERC20_TOKEN_ADDRESS: "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
|
||||
FOREIGN_POLLING_INTERVAL: 5000
|
||||
|
||||
## Home Gasprice
|
||||
# HOME_GAS_PRICE_ORACLE_URL: "https://localhost:8888/"
|
||||
HOME_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
HOME_GAS_PRICE_FALLBACK: 0
|
||||
HOME_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
|
||||
## Foreign Gasprice
|
||||
FOREIGN_GAS_PRICE_ORACLE_URL: "https://gasprice.poa.network/"
|
||||
FOREIGN_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
FOREIGN_GAS_PRICE_FALLBACK: 10000000000
|
||||
FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
FOREIGN_GAS_PRICE_FACTOR: 1
|
||||
|
||||
## UI
|
||||
UI_TITLE: "TokenBridge UI app - %c"
|
||||
UI_DESCRIPTION: "The TokenBridge serves as a method of transferring MakerDAO stable tokens between the Ethereum network to xDai chain in a quick and cost-efficient manner."
|
||||
UI_PORT: 3001
|
||||
UI_HOME_EXPLORER_TX_TEMPLATE: https://blockscout.com/poa/dai/tx/%s
|
||||
UI_FOREIGN_EXPLORER_TX_TEMPLATE: https://blockscout.com/eth/mainnet/tx/%s
|
||||
UI_HOME_EXPLORER_ADDRESS_TEMPLATE: https://blockscout.com/poa/dai/address/%s
|
||||
UI_FOREIGN_EXPLORER_ADDRESS_TEMPLATE: https://blockscout.com/eth/mainnet/address/%s
|
||||
UI_HOME_GAS_PRICE_FALLBACK: 1000000000
|
||||
UI_FOREIGN_GAS_PRICE_FALLBACK: 10000000000
|
||||
|
||||
## Monitor
|
||||
MONITOR_PORT: 3003
|
||||
MONITOR_HOME_DEPLOYMENT_BLOCK: 759
|
||||
MONITOR_FOREIGN_DEPLOYMENT_BLOCK: 6478417
|
||||
MONITOR_HOME_GAS_LIMIT: 300000
|
||||
MONITOR_FOREIGN_GAS_LIMIT: 300000
|
||||
MONITOR_HOME_GAS_PRICE_FALLBACK: 0
|
||||
MONITOR_FOREIGN_GAS_PRICE_FALLBACK: 10000000000
|
||||
MONITOR_LEFT_TX_THRESHOLD: 100
|
||||
MONITOR_CRON_SCHEDULE: "* * * * *"
|
55
deployment/group_vars/example.yml
Normal file
55
deployment/group_vars/example.yml
Normal file
@ -0,0 +1,55 @@
|
||||
---
|
||||
## General settings
|
||||
BRIDGE_MODE: "NATIVE_TO_ERC"
|
||||
HOME_NATIVE_NAME: "POA"
|
||||
|
||||
## Home contract
|
||||
HOME_RPC_URL: "https://sokol.poa.network"
|
||||
HOME_NAME: "POA Sokol"
|
||||
HOME_WITHOUT_EVENTS: false
|
||||
HOME_BRIDGE_ADDRESS: "0x98aFdE294f1C46aA0a27Cc4049ED337F879d8976"
|
||||
HOME_POLLING_INTERVAL: 5000
|
||||
|
||||
## Foreign contract
|
||||
FOREIGN_RPC_URL: "https://sokol.poa.network"
|
||||
FOREIGN_NAME: "Kovan"
|
||||
FOREIGN_WITHOUT_EVENTS: false
|
||||
FOREIGN_BRIDGE_ADDRESS: "0x5a584f4C30B36f282848dAc9a2b20E7BEF481981"
|
||||
ERC20_TOKEN_ADDRESS: "0x6ef22442D600E1865AD8A8c254d6befCe7f4e6e4"
|
||||
FOREIGN_POLLING_INTERVAL: 1000
|
||||
|
||||
## Home Gasprice
|
||||
HOME_GAS_PRICE_ORACLE_URL: "https://gasprice.poa.network/"
|
||||
HOME_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
HOME_GAS_PRICE_FALLBACK: 1000000000 # in wei
|
||||
HOME_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
HOME_GAS_PRICE_FACTOR: 1
|
||||
|
||||
## Foreign Gasprice
|
||||
FOREIGN_GAS_PRICE_ORACLE_URL: "https://gasprice.poa.network/"
|
||||
FOREIGN_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
FOREIGN_GAS_PRICE_FALLBACK: 1000000000 # in wei
|
||||
FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
FOREIGN_GAS_PRICE_FACTOR: 1
|
||||
|
||||
## UI
|
||||
UI_TITLE: "TokenBridge UI app - %c"
|
||||
UI_DESCRIPTION: "The POA cross-chain bridge serves as a method of transferring POA native tokens from the POA Network to the Ethereum network in a quick and cost-efficient manner."
|
||||
UI_PORT: 3001
|
||||
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
|
||||
UI_HOME_GAS_PRICE_FALLBACK: 1000000000
|
||||
UI_FOREIGN_GAS_PRICE_FALLBACK: 1000000000
|
||||
|
||||
## Monitor
|
||||
MONITOR_PORT: 3003
|
||||
MONITOR_HOME_DEPLOYMENT_BLOCK: 0
|
||||
MONITOR_FOREIGN_DEPLOYMENT_BLOCK: 0
|
||||
MONITOR_HOME_GAS_LIMIT: 300000
|
||||
MONITOR_FOREIGN_GAS_LIMIT: 300000
|
||||
MONITOR_HOME_GAS_PRICE_FALLBACK: 1000000000
|
||||
MONITOR_FOREIGN_GAS_PRICE_FALLBACK: 1000000000
|
||||
MONITOR_LEFT_TX_THRESHOLD: 100
|
||||
MONITOR_CRON_SCHEDULE: "* * * * *"
|
55
deployment/group_vars/wetc.yml
Normal file
55
deployment/group_vars/wetc.yml
Normal file
@ -0,0 +1,55 @@
|
||||
---
|
||||
## General settings
|
||||
BRIDGE_MODE: "NATIVE_TO_ERC"
|
||||
HOME_NATIVE_NAME: "ETC"
|
||||
|
||||
## Home contract
|
||||
HOME_RPC_URL: "https://ethereumclassic.network"
|
||||
HOME_NAME: "Ethereum Classic"
|
||||
HOME_WITHOUT_EVENTS: false
|
||||
HOME_BRIDGE_ADDRESS: "0x073081832B4Ecdce79d4D6753565c85Ba4b3BeA9"
|
||||
HOME_POLLING_INTERVAL: 7000
|
||||
|
||||
## Foreign contract
|
||||
FOREIGN_RPC_URL: "https://mainnet.infura.io/"
|
||||
FOREIGN_NAME: "Ethereum Mainnet"
|
||||
FOREIGN_WITHOUT_EVENTS: false
|
||||
FOREIGN_BRIDGE_ADDRESS: "0x0cB781EE62F815bdD9CD4c2210aE8600d43e7040"
|
||||
ERC20_TOKEN_ADDRESS: "0x86aaBCc646f290b9Fc9Bd05CE17C3858d1511Da1"
|
||||
FOREIGN_POLLING_INTERVAL: 7000
|
||||
|
||||
## Home Gasprice
|
||||
HOME_GAS_PRICE_ORACLE_URL: "https://gasprice-etc.poa.network/"
|
||||
HOME_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
HOME_GAS_PRICE_FALLBACK: 15000000000 # in wei
|
||||
HOME_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
HOME_GAS_PRICE_FACTOR: 1
|
||||
|
||||
## Foreign Gasprice
|
||||
FOREIGN_GAS_PRICE_ORACLE_URL: "https://gasprice.poa.network/"
|
||||
FOREIGN_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
FOREIGN_GAS_PRICE_FALLBACK: 10000000000 # in wei
|
||||
FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
FOREIGN_GAS_PRICE_FACTOR: 1
|
||||
|
||||
## UI
|
||||
UI_TITLE: "TokenBridge UI app - %c"
|
||||
UI_DESCRIPTION: "The TokenBridge serves as a method of transferring native tokens from the Ethereum Classic Network to the Ethereum network in a quick and cost-efficient manner."
|
||||
UI_PORT: 3001
|
||||
UI_HOME_EXPLORER_TX_TEMPLATE: https://blockscout.com/etc/mainnet/tx/%s
|
||||
UI_FOREIGN_EXPLORER_TX_TEMPLATE: https://blockscout.com/eth/mainnet/tx/%s
|
||||
UI_HOME_EXPLORER_ADDRESS_TEMPLATE: https://blockscout.com/etc/mainnet/address/%s
|
||||
UI_FOREIGN_EXPLORER_ADDRESS_TEMPLATE: https://blockscout.com/eth/mainnet/address/%s
|
||||
UI_HOME_GAS_PRICE_FALLBACK: 15000000000
|
||||
UI_FOREIGN_GAS_PRICE_FALLBACK: 10000000000
|
||||
|
||||
## Monitor
|
||||
MONITOR_PORT: 3003
|
||||
MONITOR_HOME_DEPLOYMENT_BLOCK: 7703292
|
||||
MONITOR_FOREIGN_DEPLOYMENT_BLOCK: 7412459
|
||||
MONITOR_HOME_GAS_LIMIT: 300000
|
||||
MONITOR_FOREIGN_GAS_LIMIT: 300000
|
||||
MONITOR_HOME_GAS_PRICE_FALLBACK: 15000000000
|
||||
MONITOR_FOREIGN_GAS_PRICE_FALLBACK: 10000000000
|
||||
MONITOR_LEFT_TX_THRESHOLD: 100
|
||||
MONITOR_CRON_SCHEDULE: "* * * * *"
|
18
deployment/hosts.yml.example
Normal file
18
deployment/hosts.yml.example
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
sokol-kovan:
|
||||
children:
|
||||
oracle:
|
||||
hosts:
|
||||
127.0.0.1:
|
||||
ansible_user: ubuntu
|
||||
VALIDATOR_ADDRESS_PRIVATE_KEY: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
#syslog_server_port: "udp://127.0.0.1:514"
|
||||
ui:
|
||||
hosts:
|
||||
127.0.0.1:
|
||||
ansible_user: ubuntu
|
||||
#syslog_server_port: "udp://127.0.0.1:514"
|
||||
monitor:
|
||||
hosts:
|
||||
127.0.0.1:
|
||||
ansible_user: ubuntu
|
@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
cd $(dirname $0)
|
||||
ansible-lint -v -t bug ./oracle/roles/**
|
5
deployment/molecule/Dockerfile
Normal file
5
deployment/molecule/Dockerfile
Normal file
@ -0,0 +1,5 @@
|
||||
FROM python:3.7-stretch
|
||||
RUN curl -fsSL https://get.docker.com | sh
|
||||
RUN pip3 install docker molecule==2.22rc1 molecule[docker] flake8
|
||||
WORKDIR runner
|
||||
COPY . .
|
32
deployment/molecule/TESTING.md
Normal file
32
deployment/molecule/TESTING.md
Normal file
@ -0,0 +1,32 @@
|
||||
# POA Token Bridge / Deployment Testing
|
||||
|
||||
The deployment playbooks are tested using [Molecule](https://molecule.readthedocs.io).
|
||||
|
||||
## Push remote branch
|
||||
|
||||
The deployment playbooks are cloning the monorepository on target hosts, using your current local git branch name. If the branch does not exists on remote, you need to push it.
|
||||
|
||||
```
|
||||
git push
|
||||
```
|
||||
|
||||
Alternatively, if there are no changes except the playbooks, you can use the `master` branch:
|
||||
|
||||
```
|
||||
CIRCLE_BRANCH=master ./molecule.sh <scenario_name>
|
||||
```
|
||||
|
||||
In this case `master` branch will be used as a codebase for Monitor, UI, Oracle and Contracts deployed by your local playbook.
|
||||
|
||||
## Run the tests
|
||||
|
||||
```
|
||||
CIRCLE_BRANCH=master ./molecule.sh <scenario_name>
|
||||
```
|
||||
|
||||
Available scenarios:
|
||||
|
||||
Scenario | Description
|
||||
--- | ---
|
||||
oracle | Deploys and checks standalone Oracle on Ubuntu host
|
||||
ui | Deploys and checks standalone UI on Ubuntu host
|
12
deployment/molecule/docker-compose.yml
Normal file
12
deployment/molecule/docker-compose.yml
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
version: '3.0'
|
||||
services:
|
||||
molecule_runner:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: molecule/Dockerfile
|
||||
restart: 'no'
|
||||
privileged: true
|
||||
network_mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
12
deployment/molecule/molecule.sh
Executable file
12
deployment/molecule/molecule.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
cd $(dirname $0)
|
||||
set -e # exit when any command fails
|
||||
|
||||
CODEBASE_BRANCH=${CIRCLE_BRANCH-$(git symbolic-ref --short HEAD)}
|
||||
DOCKER_LOCALHOST=${DOCKER_LOCALHOST-localhost}
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
docker-compose build && docker-compose run -e CODEBASE_BRANCH=$CODEBASE_BRANCH -e DOCKER_LOCALHOST=$DOCKER_LOCALHOST molecule_runner /bin/bash -c "molecule test --scenario-name $1"
|
||||
|
||||
shift # Shift all the parameters down by one
|
||||
done
|
14
deployment/molecule/oracle/Dockerfile.j2
Normal file
14
deployment/molecule/oracle/Dockerfile.j2
Normal file
@ -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
|
57
deployment/molecule/oracle/molecule.yml
Normal file
57
deployment/molecule/oracle/molecule.yml
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
driver:
|
||||
name: docker
|
||||
lint:
|
||||
name: yamllint
|
||||
enabled: True
|
||||
options:
|
||||
config-data:
|
||||
ignore: ../../hosts.yml
|
||||
platforms:
|
||||
- name: oracle-host
|
||||
groups:
|
||||
- example
|
||||
children:
|
||||
- oracle
|
||||
image: ubuntu:16.04
|
||||
privileged: true
|
||||
network_mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
provisioner:
|
||||
name: ansible
|
||||
lint:
|
||||
name: ansible-lint
|
||||
enabled: True
|
||||
options:
|
||||
r: ["bug"]
|
||||
playbooks:
|
||||
prepare: ../prepare.yml
|
||||
converge: ../../site.yml
|
||||
inventory:
|
||||
host_vars:
|
||||
oracle-host:
|
||||
VALIDATOR_ADDRESS_PRIVATE_KEY: "8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9"
|
||||
syslog_server_port: "udp://127.0.0.1:514"
|
||||
bridge_repo_branch: $CODEBASE_BRANCH
|
||||
verifier:
|
||||
name: testinfra
|
||||
lint:
|
||||
name: flake8
|
||||
additional_files_or_dirs:
|
||||
- ../../tests/*
|
||||
scenario:
|
||||
name: oracle
|
||||
test_sequence:
|
||||
- lint
|
||||
- cleanup
|
||||
- destroy
|
||||
- dependency
|
||||
- syntax
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
||||
- verify
|
||||
- destroy
|
13
deployment/molecule/oracle/prepare.yml
Normal file
13
deployment/molecule/oracle/prepare.yml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: prepare
|
||||
hosts: all
|
||||
tasks:
|
||||
- name: install apt packages
|
||||
apt:
|
||||
name: "{{ packages }}"
|
||||
vars:
|
||||
packages:
|
||||
- apt-transport-https
|
||||
- rsyslog
|
||||
- shell: service rsyslog start
|
||||
- shell: groupadd docker && chgrp docker /var/run/docker.sock
|
38
deployment/molecule/oracle/tests/test_oracle.py
Normal file
38
deployment/molecule/oracle/tests/test_oracle.py
Normal file
@ -0,0 +1,38 @@
|
||||
import os
|
||||
import pytest
|
||||
import testinfra.utils.ansible_runner
|
||||
|
||||
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
|
||||
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('oracle')
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name", [
|
||||
("oracle_rabbit_1"),
|
||||
("oracle_redis_1"),
|
||||
("oracle_bridge_request_1"),
|
||||
("oracle_bridge_collected_1"),
|
||||
("oracle_bridge_affirmation_1"),
|
||||
("oracle_bridge_senderhome_1"),
|
||||
("oracle_bridge_senderforeign_1"),
|
||||
])
|
||||
def test_docker_containers(host, name):
|
||||
container = host.docker(name)
|
||||
assert container.is_running
|
||||
|
||||
|
||||
@pytest.mark.parametrize("service", [
|
||||
("poabridge"),
|
||||
("rsyslog")
|
||||
])
|
||||
def test_services(host, service):
|
||||
assert host.service(service).is_enabled
|
||||
assert host.service(service).is_running
|
||||
|
||||
|
||||
@pytest.mark.parametrize("filename", [
|
||||
("/etc/rsyslog.d/31-oracle-docker.conf"),
|
||||
("/etc/rsyslog.d/36-oracle-remote-logging.conf")
|
||||
])
|
||||
def test_logging(host, filename):
|
||||
assert host.file(filename).exists
|
||||
assert host.file(filename).mode == 0o0644
|
13
deployment/molecule/prepare.yml
Normal file
13
deployment/molecule/prepare.yml
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: prepare
|
||||
hosts: all
|
||||
tasks:
|
||||
- name: install apt packages
|
||||
apt:
|
||||
name: "{{ packages }}"
|
||||
vars:
|
||||
packages:
|
||||
- apt-transport-https
|
||||
- rsyslog
|
||||
- shell: service rsyslog start
|
||||
- shell: groupadd docker && chgrp docker /var/run/docker.sock
|
34
deployment/molecule/tests/test_all.py
Normal file
34
deployment/molecule/tests/test_all.py
Normal file
@ -0,0 +1,34 @@
|
||||
import os
|
||||
import pytest
|
||||
import testinfra.utils.ansible_runner
|
||||
|
||||
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
|
||||
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')
|
||||
|
||||
|
||||
def test_repo(host):
|
||||
assert host.file('/home/poadocker/bridge').exists
|
||||
assert host.file('/home/poadocker/bridge').is_directory
|
||||
assert host.file('/home/poadocker/bridge/package.json').exists
|
||||
|
||||
|
||||
def test_docker_group(host):
|
||||
assert host.group('docker').exists
|
||||
|
||||
|
||||
def test_user(host):
|
||||
assert host.user('poadocker').exists
|
||||
assert 'docker' in host.user('poadocker').groups
|
||||
|
||||
|
||||
@pytest.mark.parametrize("filename", [
|
||||
("/etc/rsyslog.d/30-docker.conf"),
|
||||
("/etc/rsyslog.d/35-docker-remote-logging.conf")
|
||||
])
|
||||
def test_logging(host, filename):
|
||||
assert host.file(filename).exists
|
||||
assert host.file(filename).mode == 0o0644
|
||||
|
||||
|
||||
def test_docker_config(host):
|
||||
assert host.file('/etc/docker/daemon.json').exists
|
14
deployment/molecule/ui/Dockerfile.j2
Normal file
14
deployment/molecule/ui/Dockerfile.j2
Normal file
@ -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
|
56
deployment/molecule/ui/molecule.yml
Normal file
56
deployment/molecule/ui/molecule.yml
Normal file
@ -0,0 +1,56 @@
|
||||
---
|
||||
dependency:
|
||||
name: galaxy
|
||||
driver:
|
||||
name: docker
|
||||
lint:
|
||||
name: yamllint
|
||||
enabled: True
|
||||
options:
|
||||
config-data:
|
||||
ignore: ../../hosts.yml
|
||||
platforms:
|
||||
- name: ui-host
|
||||
groups:
|
||||
- example
|
||||
children:
|
||||
- ui
|
||||
image: ubuntu:16.04
|
||||
privileged: true
|
||||
network_mode: host
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
provisioner:
|
||||
name: ansible
|
||||
lint:
|
||||
name: ansible-lint
|
||||
enabled: True
|
||||
options:
|
||||
r: ["bug"]
|
||||
playbooks:
|
||||
prepare: ../prepare.yml
|
||||
converge: ../../site.yml
|
||||
inventory:
|
||||
host_vars:
|
||||
ui-host:
|
||||
syslog_server_port: "udp://127.0.0.1:514"
|
||||
bridge_repo_branch: $CODEBASE_BRANCH
|
||||
verifier:
|
||||
name: testinfra
|
||||
lint:
|
||||
name: flake8
|
||||
additional_files_or_dirs:
|
||||
- ../../tests/*
|
||||
scenario:
|
||||
name: ui
|
||||
test_sequence:
|
||||
- lint
|
||||
- cleanup
|
||||
- destroy
|
||||
- dependency
|
||||
- syntax
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
||||
- verify
|
||||
- destroy
|
48
deployment/molecule/ui/tests/test_ui.py
Normal file
48
deployment/molecule/ui/tests/test_ui.py
Normal file
@ -0,0 +1,48 @@
|
||||
import os
|
||||
import pytest
|
||||
import testinfra.utils.ansible_runner
|
||||
|
||||
testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
|
||||
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('ui')
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name", [
|
||||
("ui_ui_1")
|
||||
])
|
||||
def test_docker_containers(host, name):
|
||||
container = host.docker(name)
|
||||
assert container.is_running
|
||||
|
||||
|
||||
@pytest.mark.parametrize("service", [
|
||||
("tokenbridge-ui"),
|
||||
("rsyslog")
|
||||
])
|
||||
def test_services(host, service):
|
||||
assert host.service(service).is_enabled
|
||||
assert host.service(service).is_running
|
||||
|
||||
|
||||
@pytest.mark.parametrize("filename", [
|
||||
("/etc/rsyslog.d/32-ui-docker.conf"),
|
||||
("/etc/rsyslog.d/37-ui-remote-logging.conf")
|
||||
])
|
||||
def test_logging(host, filename):
|
||||
assert host.file(filename).exists
|
||||
assert host.file(filename).mode == 0o0644
|
||||
|
||||
|
||||
def test_index_page_title(host):
|
||||
assert host.run_test(
|
||||
'curl -s http://localhost:3001 | '
|
||||
'grep "<title>" | '
|
||||
'grep -q "TokenBridge UI app"'
|
||||
)
|
||||
|
||||
|
||||
def test_index_page_error(host):
|
||||
assert host.run_expect(
|
||||
[1],
|
||||
'curl -s http://localhost:3001 | '
|
||||
'grep -i -q "error"'
|
||||
)
|
14
deployment/molecule/ultimate-native-to-erc/Dockerfile.j2
Normal file
14
deployment/molecule/ultimate-native-to-erc/Dockerfile.j2
Normal file
@ -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
|
47
deployment/molecule/ultimate-native-to-erc/molecule.yml
Normal file
47
deployment/molecule/ultimate-native-to-erc/molecule.yml
Normal file
@ -0,0 +1,47 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: oracle-native-to-erc-host
|
||||
groups:
|
||||
- example
|
||||
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: ../../site.yml
|
||||
inventory:
|
||||
host_vars:
|
||||
oracle-native-to-erc-host:
|
||||
bridge_repo_branch: $CODEBASE_BRANCH
|
||||
VALIDATOR_ADDRESS: "0xaaB52d66283F7A1D5978bcFcB55721ACB467384b"
|
||||
VALIDATOR_ADDRESS_PRIVATE_KEY: "8e829f695aed89a154550f30262f1529582cc49dc30eff74a6b491359e0230f9"
|
||||
HOME_BRIDGE_ADDRESS: "0x32198D570fffC7033641F8A9094FFDCaAEF42624"
|
||||
FOREIGN_BRIDGE_ADDRESS: "0x2B6871b9B02F73fa24F4864322CdC78604207769"
|
||||
ERC20_TOKEN_ADDRESS: "0xdbeE25CbE97e4A5CC6c499875774dc7067E9426B"
|
||||
QUEUE_URL: "amqp://$DOCKER_LOCALHOST"
|
||||
REDIS_URL: "redis://$DOCKER_LOCALHOST:6379"
|
||||
HOME_RPC_URL: "http://$DOCKER_LOCALHOST:8541"
|
||||
FOREIGN_RPC_URL: "http://$DOCKER_LOCALHOST:8542"
|
||||
ALLOW_HTTP: yes
|
||||
LOG_LEVEL: debug
|
||||
verifier:
|
||||
name: testinfra
|
||||
lint:
|
||||
name: flake8
|
||||
scenario:
|
||||
name: ultimate-native-to-erc
|
||||
test_sequence:
|
||||
- cleanup
|
||||
- destroy
|
||||
- syntax
|
||||
- create
|
||||
- prepare
|
||||
- converge
|
@ -1,138 +0,0 @@
|
||||
### Prerequisites
|
||||
1. A functional Ubuntu 16.04 server launched using a trusted hosting provider. For more information, see our tutorials on [setting up a validator node on AWS](https://github.com/poanetwork/wiki/wiki/Validator-Node-on-AWS) or [setting up on non-AWS](https://github.com/poanetwork/wiki/wiki/Validator-Node-Non-AWS).
|
||||
* Record the IP address (required for file setup).
|
||||
* Setup ssh access to your node via public+private keys (using passwords is less secure).
|
||||
* When creating the node, set a meaningful `hostname` that can identify you (e.g. `validator-0x...`).
|
||||
|
||||
2. On your local machine install:
|
||||
* Python 2 (v2.6-v2.7)/Python3 (v3.5+)
|
||||
* Ansible v2.3+
|
||||
* Git
|
||||
|
||||
### Configuration
|
||||
|
||||
1. Clone this repository and go to the `deployment/oracle` folder
|
||||
```
|
||||
git clone --recursive https://github.com/poanetwork/tokenbridge
|
||||
cd tokenbridge/deployment/oracle
|
||||
```
|
||||
2. Create the file `hosts.yml` from `hosts.yml.example`
|
||||
```
|
||||
cp hosts.yml.example hosts.yml
|
||||
```
|
||||
|
||||
`hosts.yml` should have the following structure:
|
||||
|
||||
```yaml
|
||||
<bridge_name>:
|
||||
hosts:
|
||||
<host_ip>:
|
||||
ansible_user: <user>
|
||||
VALIDATOR_ADDRESS_PRIVATE_KEY: "<private_key>"
|
||||
#syslog_server_port: "<protocol>://<ip>:<port>" # When this parameter is set all bridge logs will be redirected to <ip>:<port> address.
|
||||
```
|
||||
|
||||
| Value | Description |
|
||||
|:------------------------------------------------|:----------------------------------------------------------------------------------------------------------|
|
||||
| `<bridge_name>` | The bridge name which tells Ansible which file to use. This is located in `group_vars/<bridge_name>.yml`. |
|
||||
| `<host_ip>` | Remote server IP address. |
|
||||
| ansible_user: `<user>` | User that will ssh into the node. This is typically `ubuntu` or `root`. |
|
||||
| VALIDATOR_ADDRESS_PRIVATE_KEY: `"<private_key>"` | The private key for the specified validator address. |
|
||||
| syslog_server_port: `"<protocol>://<ip>:<port>"` | Optional port specification for bridge logs. This value will be provided by an administrator if required. |
|
||||
|
||||
|
||||
`hosts.yml` can contain multiple hosts and bridge configurations (groups) at once.
|
||||
|
||||
|
||||
3. Copy the bridge name(s) to the hosts.yml file.
|
||||
1. Go to the group_vars folder.
|
||||
`cd group_vars`
|
||||
2. Note the <bridge_name> and add it to the hosts.yml configuration. For example, if a bridge file is named sokol-kovan.yml, you would change the <bridge_name> value in hosts.yml to sokol-kovan.
|
||||
|
||||
#### Administrator Configurations
|
||||
|
||||
1. The `group_vars/<bridge_name>.yml` file contains the public bridge parameters. This file is prepared by administrators for each bridge. The validator only needs to add the required bridge name in the hosts.yml file to tell Ansible which file to use.
|
||||
|
||||
`group_vars/example.yml` shows an example configuration for the POA/Sokol - POA/Sokol bridge. Parameter values should match values from the .env file for the Oracle. See [Configuration parameters](../../oracle/README.md#configuration-parameters) for details.
|
||||
|
||||
2. You can also add the following parameters in the `group_vars` to change the default behavior of `deployment-bridge` playbooks:
|
||||
|
||||
2.1 `compose_service_user` - specifies users to be created by playbooks. This user will be used to run Token Bridge Oracle.
|
||||
|
||||
2.2 `bridge_repo` contains address of Token Bridge Oracle repository. The default value is https://github.com/poanetwork/tokenbridge.
|
||||
|
||||
2.3 `bridge_repo_branch` points to the specific branch or commit to use with the `bridge_repo`. If `bridge_repo_branch` is not specified, the default (`master`) branch is used.
|
||||
|
||||
2.4 `bridge_path` set the path where Token Bridge Oracle would be installed. By default it point to the home folder of `compose_service_user`
|
||||
|
||||
2.5 `docker_compose_version` - specifies a version of docker-compose to be installed.
|
||||
|
||||
2.6 `ALLOW_HTTP` (`no` by default) can be set to `yes` to allow bridge insecure connections to the network.
|
||||
|
||||
## Execution
|
||||
|
||||
The playbook can be executed once [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) is installed and all configuration variables are set.
|
||||
|
||||
It will automatically install `Docker`, `docker-compose`, `Python`, `Git` and it dependencies (such as `curl`, `ca-certificates`, `apt-transport-https`, etc.) to the node. Also this playbooks creates an additional non-sudo docker user to run service as.
|
||||
|
||||
```yaml
|
||||
ansible-playbook -i hosts.yml site.yml
|
||||
```
|
||||
|
||||
**Useful arguments:**
|
||||
|
||||
To be used with the ansible-playbook command, for example:
|
||||
|
||||
```yaml
|
||||
`ansible-playbook -i hosts.yml site.yml --ask-become-pass`
|
||||
```
|
||||
|
||||
* `--ask-pass` - ask for the password used to connect to the bridge VM.
|
||||
|
||||
* `--ask-become-pass` - ask for the `become` password used to execute some commands (such as Docker installation) with root privileges.
|
||||
|
||||
* `-i <file>` - use specified file as a `hosts.yml` file.
|
||||
|
||||
* `-e "<variable>=<value>"` - override default variable.
|
||||
|
||||
* `--private-key=<file_name>` - if private keyfile is required to connect to the ubuntu instance.
|
||||
|
||||
* `--user=<username>` - connect as this username
|
||||
|
||||
## Bridge service commands
|
||||
|
||||
The Bridge service is named `poabridge`. Use the default `SysVinit` commands to `start`, `stop`, `restart`, and `rebuild` the service and to check the `status` of the service.
|
||||
|
||||
Commands format:
|
||||
```bash
|
||||
sudo service poabridge [start|stop|restart|status|rebuild]
|
||||
```
|
||||
|
||||
## Rollback the Last Processed Block in Redis
|
||||
|
||||
If the bridge does not handle an event properly (i.e. a transaction stalls due to a low gas price), the Redis DB can be rolled back. You must identify which watcher needs to re-run. For example, if the validator signatures were collected but the transaction with signatures was not sent to the Foreign network, the `collected-signatures` watcher must look at the block where the corresponding `CollectedSignatures` event was raised.
|
||||
|
||||
Execute the `reset-lastBlock.sh` script in the bridge root directory. For example, if you've installed your bridge with this deployment script and all the default parameters, use the following set of commands:
|
||||
|
||||
```shell
|
||||
$ sudo su poadocker
|
||||
$ cd ~/bridge
|
||||
$ docker-compose exec bridge_affirmation bash ./reset-lastBlock.sh <watcher> <block num>
|
||||
$ exit
|
||||
$ sudo service poabridge restart
|
||||
```
|
||||
where the _<watcher>_ could be one of the following:
|
||||
|
||||
- `signature-request`
|
||||
- `collected-signatures`
|
||||
- `affirmation-request`
|
||||
|
||||
## Logs
|
||||
|
||||
If the `syslog_server_port` option in the hosts.yml file is not set, all logs will be stored in `/var/log/docker/` folder in the set of folders with the `bridge_` prefix.
|
||||
|
||||
If the `syslog_server_port` is set, logs will be redirected to the specified server and cannot be accessed on the bridge machine.
|
||||
|
||||
```yaml
|
||||
syslog_server_port: "<protocol>://<ip>:<port>" # When this parameter is set all bridge logs will be redirected to the <ip>:<port> address.
|
||||
```
|
@ -1,24 +0,0 @@
|
||||
## General settings
|
||||
BRIDGE_MODE: "ERC_TO_NATIVE"
|
||||
|
||||
## Home contract
|
||||
HOME_RPC_URL: "https://dai.poa.network"
|
||||
HOME_BRIDGE_ADDRESS: "0x7301CFA0e1756B71869E93d4e4Dca5c7d0eb0AA6"
|
||||
HOME_POLLING_INTERVAL: 5000
|
||||
|
||||
## Foreign contract
|
||||
FOREIGN_RPC_URL: "https://mainnet.infura.io"
|
||||
FOREIGN_BRIDGE_ADDRESS: "0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016"
|
||||
ERC20_TOKEN_ADDRESS: "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
|
||||
FOREIGN_POLLING_INTERVAL: 5000
|
||||
|
||||
## Gasprice
|
||||
#HOME_GAS_PRICE_ORACLE_URL: "https://localhost:8888/"
|
||||
HOME_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
HOME_GAS_PRICE_FALLBACK: 0
|
||||
HOME_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
|
||||
FOREIGN_GAS_PRICE_ORACLE_URL: "https://gasprice.poa.network/"
|
||||
FOREIGN_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
FOREIGN_GAS_PRICE_FALLBACK: 10000000000
|
||||
FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000
|
@ -1,24 +0,0 @@
|
||||
## General settings
|
||||
BRIDGE_MODE: "NATIVE_TO_ERC"
|
||||
|
||||
## Home contract
|
||||
HOME_RPC_URL: "https://sokol.poa.network"
|
||||
HOME_BRIDGE_ADDRESS: "0x98aFdE294f1C46aA0a27Cc4049ED337F879d8976"
|
||||
HOME_POLLING_INTERVAL: 5000
|
||||
|
||||
## Foreign contract
|
||||
FOREIGN_RPC_URL: "https://sokol.poa.network"
|
||||
FOREIGN_BRIDGE_ADDRESS: "0x5a584f4C30B36f282848dAc9a2b20E7BEF481981"
|
||||
ERC20_TOKEN_ADDRESS: "0x6ef22442D600E1865AD8A8c254d6befCe7f4e6e4"
|
||||
FOREIGN_POLLING_INTERVAL: 1000
|
||||
|
||||
## Gasprice
|
||||
HOME_GAS_PRICE_ORACLE_URL: "https://gasprice.poa.network/"
|
||||
HOME_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
HOME_GAS_PRICE_FALLBACK: 1000000000 # in wei
|
||||
HOME_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
|
||||
FOREIGN_GAS_PRICE_ORACLE_URL: "https://gasprice.poa.network/"
|
||||
FOREIGN_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
FOREIGN_GAS_PRICE_FALLBACK: 1000000000 # in wei
|
||||
FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000
|
@ -1,24 +0,0 @@
|
||||
## General settings
|
||||
BRIDGE_MODE: "NATIVE_TO_ERC"
|
||||
|
||||
## Home contract
|
||||
HOME_RPC_URL: "https://ethereumclassic.network"
|
||||
HOME_BRIDGE_ADDRESS: "0x073081832B4Ecdce79d4D6753565c85Ba4b3BeA9"
|
||||
HOME_POLLING_INTERVAL: 7000
|
||||
|
||||
## Foreign contract
|
||||
FOREIGN_RPC_URL: "https://mainnet.infura.io/"
|
||||
FOREIGN_BRIDGE_ADDRESS: "0x0cB781EE62F815bdD9CD4c2210aE8600d43e7040"
|
||||
ERC20_TOKEN_ADDRESS: "0x86aaBCc646f290b9Fc9Bd05CE17C3858d1511Da1"
|
||||
FOREIGN_POLLING_INTERVAL: 7000
|
||||
|
||||
## Gasprice
|
||||
HOME_GAS_PRICE_ORACLE_URL: "https://gasprice-etc.poa.network/"
|
||||
HOME_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
HOME_GAS_PRICE_FALLBACK: 15000000000 # in wei
|
||||
HOME_GAS_PRICE_UPDATE_INTERVAL: 600000
|
||||
|
||||
FOREIGN_GAS_PRICE_ORACLE_URL: "https://gasprice.poa.network/"
|
||||
FOREIGN_GAS_PRICE_SPEED_TYPE: "standard"
|
||||
FOREIGN_GAS_PRICE_FALLBACK: 10000000000 # in wei
|
||||
FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000
|
@ -1,6 +0,0 @@
|
||||
sokol-kovan:
|
||||
hosts:
|
||||
127.0.0.1:
|
||||
ansible_user: ubuntu
|
||||
VALIDATOR_ADDRESS_PRIVATE_KEY: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
#syslog_server_port: "udp://127.0.0.1:514"
|
@ -1,17 +0,0 @@
|
||||
This role installs required dependencies:
|
||||
|
||||
* apt-transport-https
|
||||
|
||||
* ca-certificates
|
||||
|
||||
* curl
|
||||
|
||||
* software-properties-common
|
||||
|
||||
* docker-ce (+python library)
|
||||
|
||||
* docker-compose (+python library)
|
||||
|
||||
* git
|
||||
|
||||
* python-pip
|
@ -1,2 +0,0 @@
|
||||
docker_compose_version: 1.22.0
|
||||
compose_service_user: poadocker
|
@ -1 +0,0 @@
|
||||
This role brings up a docker container using docker-compose.
|
@ -1 +0,0 @@
|
||||
bridge_path: "/home/{{ compose_service_user }}/bridge"
|
@ -1,4 +0,0 @@
|
||||
- name: Launch container
|
||||
shell: docker-compose up -d
|
||||
args:
|
||||
chdir: "{{ bridge_path }}/oracle"
|
@ -1 +0,0 @@
|
||||
This role sets up remote logging for services.
|
@ -1,2 +0,0 @@
|
||||
bridge_path: "/home/{{ compose_service_user }}/bridge"
|
||||
syslog_server_port: udp://127.0.0.1:514
|
@ -1 +0,0 @@
|
||||
This role gets the start blocks for both home and foreign networks.
|
@ -1 +0,0 @@
|
||||
bridge_path: "/home/{{ compose_service_user }}/bridge"
|
@ -1 +0,0 @@
|
||||
This role sets the .env config (excluding starting blocks).
|
@ -1 +0,0 @@
|
||||
This role clones the repo from a specified URL.
|
@ -1,5 +0,0 @@
|
||||
This role creates a poabridge service which is designed to manage docker-compose bridge deployment.
|
||||
|
||||
/etc/init.d/poabridge start, status, stop, restart - does what the services usually do in such cases.
|
||||
|
||||
/etc/init.d/poabridge rebuild - builds a new bridge deployment from scratch.
|
@ -1,4 +0,0 @@
|
||||
---
|
||||
# defaults
|
||||
bridge_path: "/home/{{ compose_service_user }}/bridge"
|
||||
keyfile_path: "/root/.key"
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
- name: "Set poabridge service"
|
||||
template:
|
||||
src: poabridge.j2
|
||||
dest: "/etc/init.d/poabridge"
|
||||
owner: root
|
||||
mode: 755
|
||||
|
||||
- name: "Start/Enable poabridge service"
|
||||
service:
|
||||
name: "poabridge"
|
||||
state: started
|
||||
enabled: yes
|
||||
use: service
|
@ -1,19 +0,0 @@
|
||||
- name: Install python if necessary
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
become: true
|
||||
tasks:
|
||||
- name: Install python
|
||||
raw: "test -e {{ ansible_python_interpreter | default ('/usr/bin/python') }} || (sudo apt -y update && sudo apt install -y python-minimal)"
|
||||
tags: install_dependencies
|
||||
|
||||
- name: Install bridge
|
||||
hosts: all
|
||||
roles:
|
||||
- { role: dependencies, tags: install_dependencies, become: true }
|
||||
- { role: repo, tags: clone_repo, become: true }
|
||||
- { role: pre_config, tags: pre_config, become: true }
|
||||
- { role: jumpbox, tags: launch_jumpbox, become: true }
|
||||
- { role: post_config, tags: post_config, become: true }
|
||||
- { role: logging, tags: set_logging, become: true}
|
||||
- { role: servinstall, tags: install_service, become: true }
|
4
deployment/requirements.txt
Normal file
4
deployment/requirements.txt
Normal file
@ -0,0 +1,4 @@
|
||||
# pre-release because it contains "CI Fixes for ansible 2.8"
|
||||
molecule==2.22rc1
|
||||
docker
|
||||
flake8
|
@ -1,3 +1,6 @@
|
||||
---
|
||||
docker_compose_version: 1.23.2
|
||||
compose_service_user: poadocker
|
||||
bridge_path: "/home/{{ compose_service_user }}/bridge"
|
||||
bridge_repo: https://github.com/poanetwork/tokenbridge.git
|
||||
bridge_repo_branch: master
|
0
deployment/oracle/roles/dependencies/files/daemon.json → deployment/roles/common/files/daemon.json
0
deployment/oracle/roles/dependencies/files/daemon.json → deployment/roles/common/files/daemon.json
1
deployment/oracle/roles/dependencies/handlers/main.yml → deployment/roles/common/handlers/main.yml
1
deployment/oracle/roles/dependencies/handlers/main.yml → deployment/roles/common/handlers/main.yml
@ -1,3 +1,4 @@
|
||||
---
|
||||
- name: restart rsyslog
|
||||
service:
|
||||
name: rsyslog
|
20
deployment/oracle/roles/dependencies/tasks/main.yml → deployment/roles/common/tasks/dependencies.yml
20
deployment/oracle/roles/dependencies/tasks/main.yml → deployment/roles/common/tasks/dependencies.yml
@ -1,8 +1,9 @@
|
||||
---
|
||||
- name: Install the gpg key for docker
|
||||
apt_key:
|
||||
url: "https://download.docker.com/linux/ubuntu/gpg"
|
||||
state: present
|
||||
|
||||
|
||||
- name: Install the docker repos
|
||||
apt_repository:
|
||||
repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
|
||||
@ -19,7 +20,8 @@
|
||||
- software-properties-common
|
||||
- docker-ce
|
||||
- git
|
||||
- "{{ (ansible_python_interpreter | default ('python')).split('/')[-1] }}-pip"
|
||||
- python3
|
||||
- python3-pip
|
||||
|
||||
- name: Install Docker Compose
|
||||
get_url:
|
||||
@ -29,13 +31,9 @@
|
||||
owner: "root"
|
||||
group: "root"
|
||||
mode: "0755"
|
||||
|
||||
|
||||
- name: Install python docker library
|
||||
pip:
|
||||
name: "{{ item }}"
|
||||
with_items:
|
||||
- docker
|
||||
- docker-compose
|
||||
shell: pip3 install docker docker-compose setuptools
|
||||
|
||||
- name: Add user to run docker-compose
|
||||
user:
|
||||
@ -52,7 +50,7 @@
|
||||
- name: Configure auditd
|
||||
blockinfile:
|
||||
path: /etc/audit/audit.rules
|
||||
block: |
|
||||
block: |
|
||||
-w /usr/bin/docker -p wa
|
||||
-w /var/lib/docker -p wa
|
||||
-w /etc/docker -p wa
|
||||
@ -61,13 +59,13 @@
|
||||
-w /etc/default/docker -p wa
|
||||
-w /etc/docker/daemon.json -p wa
|
||||
-w /usr/bin/docker-containerd -p wa
|
||||
-w /usr/bin/docker-runc -p wa
|
||||
-w /usr/bin/docker-runc -p wa
|
||||
notify: restart auditd
|
||||
|
||||
- name: Configure docker engine
|
||||
copy:
|
||||
src: daemon.json
|
||||
dest: /etc/docker/daemon.json
|
||||
dest: /etc/docker/
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0640
|
30
deployment/roles/common/tasks/logging.yml
Normal file
30
deployment/roles/common/tasks/logging.yml
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
- name: Set the local docker logs configuration file
|
||||
template:
|
||||
src: 30-docker.conf.j2
|
||||
dest: /etc/rsyslog.d/30-docker.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: Set the log configuration file to send docker logs to remote server
|
||||
template:
|
||||
src: 35-docker-remote-logging.conf.j2
|
||||
dest: /etc/rsyslog.d/35-docker-remote-logging.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
when: syslog_server_port is defined
|
||||
|
||||
- name: Set the logrotate config file
|
||||
template:
|
||||
src: docker-logs.j2
|
||||
dest: /etc/logrotate.d/docker-logs
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: restart rsyslog
|
||||
service:
|
||||
name: rsyslog
|
||||
state: restarted
|
4
deployment/roles/common/tasks/main.yml
Normal file
4
deployment/roles/common/tasks/main.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
- include_tasks: dependencies.yml
|
||||
- include_tasks: repo.yml
|
||||
- include_tasks: logging.yml
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
- name: Get bridge repo
|
||||
git:
|
||||
repo: "{{ bridge_repo }}"
|
||||
dest: "{{ bridge_path }}"
|
||||
force: yes
|
||||
force: no
|
||||
update: no
|
||||
version: "{{ bridge_repo_branch }}"
|
6
deployment/roles/common/templates/30-docker.conf.j2
Normal file
6
deployment/roles/common/templates/30-docker.conf.j2
Normal file
@ -0,0 +1,6 @@
|
||||
$FileCreateMode 0644
|
||||
|
||||
if $programname startswith 'docker' then \
|
||||
/var/log/docker/no_tag/docker.log
|
||||
|
||||
$FileCreateMode 0600
|
@ -11,7 +11,7 @@ template(name="RemoteForwardFormat" type="list") {
|
||||
property(name="msg")
|
||||
}
|
||||
|
||||
if $programname startswith 'oracle_bridge_' or $programname startswith 'docker' then {
|
||||
if $programname startswith 'docker' then {
|
||||
action(
|
||||
type="omfwd"
|
||||
protocol="{{ syslog_server_port.split(":")[0] }}"
|
||||
@ -25,4 +25,4 @@ action(
|
||||
queue.Type="LinkedList"
|
||||
ResendLastMSGOnReconnect="on"
|
||||
)
|
||||
}
|
||||
}
|
3
deployment/roles/monitor/meta/main.yml
Normal file
3
deployment/roles/monitor/meta/main.yml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- role: common
|
5
deployment/roles/monitor/tasks/jumpbox.yml
Normal file
5
deployment/roles/monitor/tasks/jumpbox.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Build the containers
|
||||
shell: docker-compose build
|
||||
args:
|
||||
chdir: "{{ bridge_path }}/monitor"
|
4
deployment/roles/monitor/tasks/main.yml
Normal file
4
deployment/roles/monitor/tasks/main.yml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
- include_tasks: pre_config.yml
|
||||
- include_tasks: jumpbox.yml
|
||||
- include_tasks: servinstall.yml
|
5
deployment/roles/monitor/tasks/pre_config.yml
Normal file
5
deployment/roles/monitor/tasks/pre_config.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Install .env config
|
||||
template:
|
||||
src: .env.j2
|
||||
dest: "{{ bridge_path }}/monitor/.env"
|
20
deployment/roles/monitor/tasks/servinstall.yml
Normal file
20
deployment/roles/monitor/tasks/servinstall.yml
Normal file
@ -0,0 +1,20 @@
|
||||
# This role creates a tokenbridge-monitor service which is designed to manage docker-compose monitor deployment.
|
||||
# /etc/init.d/tokenbridge-monitor start, status, stop, restart - does what the services usually do in such cases.
|
||||
# /etc/init.d/tokenbridge-monitor rebuild - builds a new monitor deployment from scratch.
|
||||
---
|
||||
- name: "Set the service"
|
||||
template:
|
||||
src: tokenbridge-monitor.j2
|
||||
dest: "/etc/init.d/tokenbridge-monitor"
|
||||
owner: root
|
||||
mode: 755
|
||||
|
||||
- name: "Enable the service"
|
||||
service:
|
||||
name: "tokenbridge-monitor"
|
||||
state: started
|
||||
enabled: yes
|
||||
use: service
|
||||
|
||||
- name: Start the service
|
||||
shell: service tokenbridge-monitor start
|
25
deployment/roles/monitor/templates/.env.j2
Normal file
25
deployment/roles/monitor/templates/.env.j2
Normal file
@ -0,0 +1,25 @@
|
||||
HOME_RPC_URL={{ HOME_RPC_URL }}
|
||||
FOREIGN_RPC_URL={{ FOREIGN_RPC_URL }}
|
||||
HOME_BRIDGE_ADDRESS={{ HOME_BRIDGE_ADDRESS }}
|
||||
FOREIGN_BRIDGE_ADDRESS={{ FOREIGN_BRIDGE_ADDRESS }}
|
||||
HOME_DEPLOYMENT_BLOCK={{ MONITOR_HOME_DEPLOYMENT_BLOCK }}
|
||||
FOREIGN_DEPLOYMENT_BLOCK={{ MONITOR_FOREIGN_DEPLOYMENT_BLOCK }}
|
||||
HOME_GAS_LIMIT={{ MONITOR_HOME_GAS_LIMIT }}
|
||||
{% if HOME_GAS_PRICE_ORACLE_URL | default('') != '' %}
|
||||
HOME_GAS_PRICE_ORACLE_URL={{ HOME_GAS_PRICE_ORACLE_URL }}
|
||||
{% endif %}
|
||||
{% if HOME_GAS_PRICE_SPEED_TYPE | default('') != '' %}
|
||||
HOME_GAS_PRICE_SPEED_TYPE={{ HOME_GAS_PRICE_SPEED_TYPE }}
|
||||
{% endif %}
|
||||
HOME_GAS_PRICE_FALLBACK={{ MONITOR_HOME_GAS_PRICE_FALLBACK }}
|
||||
{% if HOME_GAS_PRICE_FACTOR | default('') != '' %}
|
||||
HOME_GAS_PRICE_FACTOR={{ HOME_GAS_PRICE_FACTOR }}
|
||||
{% endif %}
|
||||
FOREIGN_GAS_LIMIT={{ MONITOR_FOREIGN_GAS_LIMIT }}
|
||||
FOREIGN_GAS_PRICE_ORACLE_URL={{ FOREIGN_GAS_PRICE_ORACLE_URL }}
|
||||
FOREIGN_GAS_PRICE_SPEED_TYPE={{ FOREIGN_GAS_PRICE_SPEED_TYPE }}
|
||||
FOREIGN_GAS_PRICE_FALLBACK={{ MONITOR_FOREIGN_GAS_PRICE_FALLBACK }}
|
||||
FOREIGN_GAS_PRICE_FACTOR={{ FOREIGN_GAS_PRICE_FACTOR }}
|
||||
LEFT_TX_THRESHOLD={{ MONITOR_LEFT_TX_THRESHOLD }}
|
||||
PORT={{ MONITOR_PORT }}
|
||||
CRON_SCHEDULE={{ MONITOR_CRON_SCHEDULE }}
|
76
deployment/roles/monitor/templates/tokenbridge-monitor.j2
Normal file
76
deployment/roles/monitor/templates/tokenbridge-monitor.j2
Normal file
@ -0,0 +1,76 @@
|
||||
#! /bin/bash
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: tokenbridge-monitor
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start daemon at boot time
|
||||
# Description: Enable service provided by daemon.
|
||||
### END INIT INFO
|
||||
|
||||
WORKDIR="{{ '/home/' + compose_service_user | default('poadocker') + '/' + bridge_path + '/monitor' if bridge_path[:1] != "/" else bridge_path + '/monitor' }}"
|
||||
|
||||
start(){
|
||||
echo "Starting TokenBridge Monitor.."
|
||||
cd $WORKDIR
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose down -v
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose rm -fv
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose up --detach
|
||||
}
|
||||
|
||||
stop(){
|
||||
echo "Stopping TokenBridge Monitor.."
|
||||
cd $WORKDIR
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose down -v
|
||||
sleep 2
|
||||
}
|
||||
|
||||
status(){
|
||||
echo "TokenBridge Monitor status:"
|
||||
cd $WORKDIR
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose ps
|
||||
}
|
||||
|
||||
rebuild(){
|
||||
echo "Rebuild TokenBridge Monitor.."
|
||||
cd $WORKDIR
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose down -v
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose rm -fv
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose up --detach --force-recreate --no-deps --build
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
|
||||
start)
|
||||
start
|
||||
;;
|
||||
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
|
||||
status)
|
||||
status
|
||||
;;
|
||||
|
||||
restart)
|
||||
echo "Restarting TokenBridge Monitor.."
|
||||
stop
|
||||
start
|
||||
;;
|
||||
|
||||
rebuild)
|
||||
rebuild
|
||||
;;
|
||||
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|restart|rebuild|status}"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
exit 0
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
bridge_path: "/home/{{ compose_service_user }}/bridge"
|
||||
|
||||
ALLOW_HTTP: no
|
||||
QUEUE_URL: amqp://rabbit
|
||||
REDIS_URL: redis://redis
|
||||
REDIS_LOCK_TTL: 1000
|
||||
syslog_server_port: udp://127.0.0.1:514
|
||||
keyfile_path: "/root/.key"
|
3
deployment/roles/oracle/meta/main.yml
Normal file
3
deployment/roles/oracle/meta/main.yml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- role: common
|
5
deployment/roles/oracle/tasks/jumpbox.yml
Normal file
5
deployment/roles/oracle/tasks/jumpbox.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Build the containers
|
||||
shell: docker-compose build
|
||||
args:
|
||||
chdir: "{{ bridge_path }}/oracle"
|
@ -1,17 +1,18 @@
|
||||
---
|
||||
- name: Slurp docker compose file
|
||||
slurp:
|
||||
src: "{{ bridge_path }}/oracle/docker-compose.yml"
|
||||
register: docker_compose_slurp
|
||||
|
||||
- name: Parse docker compose file
|
||||
set_fact:
|
||||
set_fact:
|
||||
docker_compose_parsed: "{{ docker_compose_slurp['content'] | b64decode | from_yaml }}"
|
||||
|
||||
- name: Set logger to remote server
|
||||
set_fact:
|
||||
docker_compose_parsed: "{{ docker_compose_parsed |combine({'services': {item: {'logging': {'driver': 'syslog','options': {'tag': '{{.Name}}/{{.ID}}'}}}}}, recursive=True) }}"
|
||||
with_items: "{{ docker_compose_parsed.services }}"
|
||||
|
||||
|
||||
- name: Write new docker-compose file
|
||||
copy:
|
||||
content: "{{ docker_compose_parsed | to_yaml }}"
|
||||
@ -19,29 +20,21 @@
|
||||
|
||||
- name: Set the local container logs configuration file
|
||||
template:
|
||||
src: 30-docker.conf.j2
|
||||
dest: /etc/rsyslog.d/30-docker.conf
|
||||
src: 31-oracle-docker.conf.j2
|
||||
dest: /etc/rsyslog.d/31-oracle-docker.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: Set the log configuration file to send container logs to remote server
|
||||
template:
|
||||
src: 35-remote-logging.conf.j2
|
||||
dest: /etc/rsyslog.d/35-remote-logging.conf
|
||||
src: 36-oracle-remote-logging.conf.j2
|
||||
dest: /etc/rsyslog.d/36-oracle-remote-logging.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
when: syslog_server_port is defined
|
||||
|
||||
- name: Set the logrotate config file
|
||||
template:
|
||||
src: docker-logs.j2
|
||||
dest: /etc/logrotate.d/docker-logs
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: Discarding unwanted messages in rsyslog
|
||||
blockinfile:
|
||||
path: /etc/rsyslog.conf
|
6
deployment/roles/oracle/tasks/main.yml
Normal file
6
deployment/roles/oracle/tasks/main.yml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
- include_tasks: pre_config.yml
|
||||
- include_tasks: logging.yml
|
||||
- include_tasks: jumpbox.yml
|
||||
- include_tasks: post_config.yml
|
||||
- include_tasks: servinstall.yml
|
5
deployment/oracle/roles/post_config/tasks/main.yml → deployment/roles/oracle/tasks/post_config.yml
5
deployment/oracle/roles/post_config/tasks/main.yml → deployment/roles/oracle/tasks/post_config.yml
@ -1,5 +1,6 @@
|
||||
---
|
||||
- name: Get blocks
|
||||
become_user: "{{ compose_service_user }}"
|
||||
become_user: "{{ compose_service_user }}"
|
||||
shell: docker-compose run --entrypoint "node scripts/getValidatorStartBlocks.js" bridge_affirmation
|
||||
args:
|
||||
chdir: "{{ bridge_path }}/oracle"
|
||||
@ -14,7 +15,7 @@
|
||||
FOREIGN_START_BLOCK={{ (BLOCKS.stdout | from_json).foreignStartBlock }}
|
||||
|
||||
- name: Get validator address
|
||||
become_user: "{{ compose_service_user }}"
|
||||
become_user: "{{ compose_service_user }}"
|
||||
shell: docker-compose run -e VALIDATOR_ADDRESS_PRIVATE_KEY="{{ VALIDATOR_ADDRESS_PRIVATE_KEY }}" --entrypoint "node scripts/privateKeyToAddress.js" bridge_affirmation
|
||||
args:
|
||||
chdir: "{{ bridge_path }}/oracle"
|
@ -1,3 +1,4 @@
|
||||
---
|
||||
- name: Install .env config
|
||||
template:
|
||||
src: .env.j2
|
20
deployment/roles/oracle/tasks/servinstall.yml
Normal file
20
deployment/roles/oracle/tasks/servinstall.yml
Normal file
@ -0,0 +1,20 @@
|
||||
# This role creates a poabridge service which is designed to manage docker-compose bridge deployment.
|
||||
# /etc/init.d/poabridge start, status, stop, restart - does what the services usually do in such cases.
|
||||
# /etc/init.d/poabridge rebuild - builds a new bridge deployment from scratch.
|
||||
---
|
||||
- name: "Set poabridge service"
|
||||
template:
|
||||
src: poabridge.j2
|
||||
dest: "/etc/init.d/poabridge"
|
||||
owner: root
|
||||
mode: 755
|
||||
|
||||
- name: "Enable the service"
|
||||
service:
|
||||
name: "poabridge"
|
||||
state: started
|
||||
enabled: yes
|
||||
use: service
|
||||
|
||||
- name: Start the service
|
||||
shell: service poabridge start
|
@ -23,6 +23,9 @@ HOME_GAS_PRICE_FALLBACK={{ HOME_GAS_PRICE_FALLBACK }}
|
||||
{% if HOME_GAS_PRICE_UPDATE_INTERVAL | default('') != '' %}
|
||||
HOME_GAS_PRICE_UPDATE_INTERVAL={{ HOME_GAS_PRICE_UPDATE_INTERVAL }}
|
||||
{% endif %}
|
||||
{% if HOME_GAS_PRICE_FACTOR | default('') != '' %}
|
||||
HOME_GAS_PRICE_FACTOR={{ HOME_GAS_PRICE_FACTOR }}
|
||||
{% endif %}
|
||||
|
||||
{% if FOREIGN_GAS_PRICE_ORACLE_URL | default('') != '' %}
|
||||
FOREIGN_GAS_PRICE_ORACLE_URL={{ FOREIGN_GAS_PRICE_ORACLE_URL }}
|
||||
@ -34,9 +37,11 @@ FOREIGN_GAS_PRICE_FALLBACK={{ FOREIGN_GAS_PRICE_FALLBACK }}
|
||||
{% if FOREIGN_GAS_PRICE_UPDATE_INTERVAL | default('') != '' %}
|
||||
FOREIGN_GAS_PRICE_UPDATE_INTERVAL={{ FOREIGN_GAS_PRICE_UPDATE_INTERVAL }}
|
||||
{% endif %}
|
||||
{% if FOREIGN_GAS_PRICE_FACTOR | default('') != '' %}
|
||||
FOREIGN_GAS_PRICE_FACTOR={{ FOREIGN_GAS_PRICE_FACTOR }}
|
||||
{% endif %}
|
||||
|
||||
## Transport configuration
|
||||
ALLOW_HTTP={{ "yes" if ALLOW_HTTP else "no" }}
|
||||
QUEUE_URL={{ QUEUE_URL }}
|
||||
REDIS_URL={{ REDIS_URL }}
|
||||
REDIS_LOCK_TTL={{ REDIS_LOCK_TTL }}
|
@ -1,12 +1,11 @@
|
||||
$FileCreateMode 0644
|
||||
template(name="DockerLogFileName" type="list") {
|
||||
template(name="DockerLogFileName_Oracle" type="list") {
|
||||
constant(value="/var/log/docker/")
|
||||
property(name="syslogtag" securepath="replace" regex.type="ERE" regex.submatch="1" regex.expression="bridge_(.*)\\/[a-zA-Z0-9]+\\[")
|
||||
constant(value="/docker.log")
|
||||
}
|
||||
|
||||
if $programname startswith 'oracle_bridge_' then \
|
||||
?DockerLogFileName
|
||||
else
|
||||
/var/log/docker/no_tag/docker.log
|
||||
?DockerLogFileName_Oracle
|
||||
|
||||
$FileCreateMode 0600
|
@ -0,0 +1,15 @@
|
||||
if $programname startswith 'oracle_bridge_' then {
|
||||
action(
|
||||
type="omfwd"
|
||||
protocol="{{ syslog_server_port.split(":")[0] }}"
|
||||
target="{{ (syslog_server_port.split(":")[1])[2:] }}"
|
||||
port="{{ syslog_server_port.split(":")[2] }}"
|
||||
template="RemoteForwardFormat"
|
||||
queue.SpoolDirectory="/var/spool/rsyslog"
|
||||
queue.FileName="remote"
|
||||
queue.MaxDiskSpace="1g"
|
||||
queue.SaveOnShutdown="on"
|
||||
queue.Type="LinkedList"
|
||||
ResendLastMSGOnReconnect="on"
|
||||
)
|
||||
}
|
3
deployment/roles/ui/meta/main.yml
Normal file
3
deployment/roles/ui/meta/main.yml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- role: common
|
5
deployment/roles/ui/tasks/jumpbox.yml
Normal file
5
deployment/roles/ui/tasks/jumpbox.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Build the containers
|
||||
shell: docker-compose build
|
||||
args:
|
||||
chdir: "{{ bridge_path }}/ui"
|
41
deployment/roles/ui/tasks/logging.yml
Normal file
41
deployment/roles/ui/tasks/logging.yml
Normal file
@ -0,0 +1,41 @@
|
||||
---
|
||||
- name: Slurp docker compose file
|
||||
slurp:
|
||||
src: "{{ bridge_path }}/ui/docker-compose.yml"
|
||||
register: docker_compose_slurp
|
||||
|
||||
- name: Parse docker compose file
|
||||
set_fact:
|
||||
docker_compose_parsed: "{{ docker_compose_slurp['content'] | b64decode | from_yaml }}"
|
||||
|
||||
- name: Set logger to remote server
|
||||
set_fact:
|
||||
docker_compose_parsed: "{{ docker_compose_parsed |combine({'services': {item: {'logging': {'driver': 'syslog','options': {'tag': '{{.Name}}/{{.ID}}'}}}}}, recursive=True) }}"
|
||||
with_items: "{{ docker_compose_parsed.services }}"
|
||||
|
||||
- name: Write new docker-compose file
|
||||
copy:
|
||||
content: "{{ docker_compose_parsed | to_yaml }}"
|
||||
dest: "{{ bridge_path }}/ui/docker-compose.yml"
|
||||
|
||||
- name: Set the local container logs configuration file
|
||||
template:
|
||||
src: 32-ui-docker.conf.j2
|
||||
dest: /etc/rsyslog.d/32-ui-docker.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: Set the log configuration file to send container logs to remote server
|
||||
template:
|
||||
src: 37-ui-remote-logging.conf.j2
|
||||
dest: /etc/rsyslog.d/37-ui-remote-logging.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
when: syslog_server_port is defined
|
||||
|
||||
- name: restart rsyslog
|
||||
service:
|
||||
name: rsyslog
|
||||
state: restarted
|
5
deployment/roles/ui/tasks/main.yml
Normal file
5
deployment/roles/ui/tasks/main.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- include_tasks: pre_config.yml
|
||||
- include_tasks: logging.yml
|
||||
- include_tasks: jumpbox.yml
|
||||
- include_tasks: servinstall.yml
|
5
deployment/roles/ui/tasks/pre_config.yml
Normal file
5
deployment/roles/ui/tasks/pre_config.yml
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
- name: Install .env config
|
||||
template:
|
||||
src: .env.j2
|
||||
dest: "{{ bridge_path }}/ui/.env"
|
20
deployment/roles/ui/tasks/servinstall.yml
Normal file
20
deployment/roles/ui/tasks/servinstall.yml
Normal file
@ -0,0 +1,20 @@
|
||||
# This role creates a tokenbridge-ui service which is designed to manage docker-compose ui deployment.
|
||||
# /etc/init.d/tokenbridge-ui start, status, stop, restart - does what the services usually do in such cases.
|
||||
# /etc/init.d/tokenbridge-ui rebuild - builds a new ui deployment from scratch.
|
||||
---
|
||||
- name: "Set the service"
|
||||
template:
|
||||
src: tokenbridge-ui.j2
|
||||
dest: "/etc/init.d/tokenbridge-ui"
|
||||
owner: root
|
||||
mode: 755
|
||||
|
||||
- name: "Enable the service"
|
||||
service:
|
||||
name: "tokenbridge-ui"
|
||||
state: started
|
||||
enabled: yes
|
||||
use: service
|
||||
|
||||
- name: Start the service
|
||||
shell: service tokenbridge-ui start
|
38
deployment/roles/ui/templates/.env.j2
Normal file
38
deployment/roles/ui/templates/.env.j2
Normal file
@ -0,0 +1,38 @@
|
||||
REACT_APP_HOME_BRIDGE_ADDRESS={{ HOME_BRIDGE_ADDRESS }}
|
||||
REACT_APP_FOREIGN_BRIDGE_ADDRESS={{ FOREIGN_BRIDGE_ADDRESS }}
|
||||
REACT_APP_FOREIGN_HTTP_PARITY_URL={{ FOREIGN_RPC_URL }}
|
||||
REACT_APP_HOME_HTTP_PARITY_URL={{ HOME_RPC_URL }}
|
||||
|
||||
REACT_APP_HOME_NATIVE_NAME={{ HOME_NATIVE_NAME }}
|
||||
|
||||
REACT_APP_HOME_NETWORK_NAME={{ HOME_NAME }}
|
||||
REACT_APP_FOREIGN_NETWORK_NAME={{ FOREIGN_NAME }}
|
||||
|
||||
REACT_APP_HOME_WITHOUT_EVENTS={{ HOME_WITHOUT_EVENTS }}
|
||||
REACT_APP_FOREIGN_WITHOUT_EVENTS={{ FOREIGN_WITHOUT_EVENTS }}
|
||||
|
||||
REACT_APP_HOME_EXPLORER_TX_TEMPLATE={{ UI_HOME_EXPLORER_TX_TEMPLATE }}
|
||||
REACT_APP_FOREIGN_EXPLORER_TX_TEMPLATE={{ UI_FOREIGN_EXPLORER_TX_TEMPLATE }}
|
||||
REACT_APP_HOME_EXPLORER_ADDRESS_TEMPLATE={{ UI_HOME_EXPLORER_ADDRESS_TEMPLATE }}
|
||||
REACT_APP_FOREIGN_EXPLORER_ADDRESS_TEMPLATE={{ UI_FOREIGN_EXPLORER_ADDRESS_TEMPLATE }}
|
||||
|
||||
{% if HOME_GAS_PRICE_ORACLE_URL | default('') != '' %}
|
||||
REACT_APP_HOME_GAS_PRICE_ORACLE_URL={{ HOME_GAS_PRICE_ORACLE_URL }}
|
||||
REACT_APP_HOME_GAS_PRICE_SPEED_TYPE={{ HOME_GAS_PRICE_SPEED_TYPE }}
|
||||
{% endif %}
|
||||
REACT_APP_HOME_GAS_PRICE_FALLBACK={{ UI_HOME_GAS_PRICE_FALLBACK }}
|
||||
REACT_APP_HOME_GAS_PRICE_UPDATE_INTERVAL={{ HOME_GAS_PRICE_UPDATE_INTERVAL }}
|
||||
{% if HOME_GAS_PRICE_FACTOR | default('') != '' %}
|
||||
REACT_APP_HOME_GAS_PRICE_FACTOR={{ HOME_GAS_PRICE_FACTOR }}
|
||||
{% endif %}
|
||||
|
||||
REACT_APP_FOREIGN_GAS_PRICE_ORACLE_URL={{ FOREIGN_GAS_PRICE_ORACLE_URL }}
|
||||
REACT_APP_FOREIGN_GAS_PRICE_SPEED_TYPE={{ FOREIGN_GAS_PRICE_SPEED_TYPE }}
|
||||
REACT_APP_FOREIGN_GAS_PRICE_FALLBACK={{ UI_FOREIGN_GAS_PRICE_FALLBACK }}
|
||||
REACT_APP_FOREIGN_GAS_PRICE_UPDATE_INTERVAL={{ FOREIGN_GAS_PRICE_UPDATE_INTERVAL }}
|
||||
REACT_APP_FOREIGN_GAS_PRICE_FACTOR={{ FOREIGN_GAS_PRICE_FACTOR }}
|
||||
|
||||
# Default
|
||||
REACT_APP_TITLE={{ UI_TITLE }}
|
||||
REACT_APP_DESCRIPTION={{ UI_DESCRIPTION }}
|
||||
PORT={{ UI_PORT }}
|
11
deployment/roles/ui/templates/32-ui-docker.conf.j2
Normal file
11
deployment/roles/ui/templates/32-ui-docker.conf.j2
Normal file
@ -0,0 +1,11 @@
|
||||
$FileCreateMode 0644
|
||||
template(name="DockerLogFileName_UI" type="list") {
|
||||
constant(value="/var/log/docker/")
|
||||
property(name="syslogtag" securepath="replace" regex.type="ERE" regex.submatch="1" regex.expression="ui_(.*)\\/[a-zA-Z0-9]+\\[")
|
||||
constant(value="/docker.log")
|
||||
}
|
||||
|
||||
if $programname startswith 'ui_' then \
|
||||
?DockerLogFileName_UI
|
||||
|
||||
$FileCreateMode 0600
|
15
deployment/roles/ui/templates/37-ui-remote-logging.conf.j2
Normal file
15
deployment/roles/ui/templates/37-ui-remote-logging.conf.j2
Normal file
@ -0,0 +1,15 @@
|
||||
if $programname startswith 'ui_' then {
|
||||
action(
|
||||
type="omfwd"
|
||||
protocol="{{ syslog_server_port.split(":")[0] }}"
|
||||
target="{{ (syslog_server_port.split(":")[1])[2:] }}"
|
||||
port="{{ syslog_server_port.split(":")[2] }}"
|
||||
template="RemoteForwardFormat"
|
||||
queue.SpoolDirectory="/var/spool/rsyslog"
|
||||
queue.FileName="remote"
|
||||
queue.MaxDiskSpace="1g"
|
||||
queue.SaveOnShutdown="on"
|
||||
queue.Type="LinkedList"
|
||||
ResendLastMSGOnReconnect="on"
|
||||
)
|
||||
}
|
76
deployment/roles/ui/templates/tokenbridge-ui.j2
Normal file
76
deployment/roles/ui/templates/tokenbridge-ui.j2
Normal file
@ -0,0 +1,76 @@
|
||||
#! /bin/bash
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: tokenbridge-ui
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start daemon at boot time
|
||||
# Description: Enable service provided by daemon.
|
||||
### END INIT INFO
|
||||
|
||||
WORKDIR="{{ '/home/' + compose_service_user | default('poadocker') + '/' + bridge_path + '/ui' if bridge_path[:1] != "/" else bridge_path + '/ui' }}"
|
||||
|
||||
start(){
|
||||
echo "Starting TokenBridge UI.."
|
||||
cd $WORKDIR
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose down -v
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose rm -fv
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose up --detach
|
||||
}
|
||||
|
||||
stop(){
|
||||
echo "Stopping TokenBridge UI.."
|
||||
cd $WORKDIR
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose down -v
|
||||
sleep 2
|
||||
}
|
||||
|
||||
status(){
|
||||
echo "TokenBridge UI status:"
|
||||
cd $WORKDIR
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose ps
|
||||
}
|
||||
|
||||
rebuild(){
|
||||
echo "Rebuild TokenBridge UI.."
|
||||
cd $WORKDIR
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose down -v
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose rm -fv
|
||||
sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose up --detach --force-recreate --no-deps --build
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
|
||||
start)
|
||||
start
|
||||
;;
|
||||
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
|
||||
status)
|
||||
status
|
||||
;;
|
||||
|
||||
restart)
|
||||
echo "Restarting TokenBridge UI.."
|
||||
stop
|
||||
start
|
||||
;;
|
||||
|
||||
rebuild)
|
||||
rebuild
|
||||
;;
|
||||
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|restart|rebuild|status}"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
exit 0
|
16
deployment/site.yml
Normal file
16
deployment/site.yml
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
- name: Install Oracle
|
||||
hosts: oracle
|
||||
become: true
|
||||
roles:
|
||||
- { role: oracle }
|
||||
- name: Install UI
|
||||
hosts: ui
|
||||
become: true
|
||||
roles:
|
||||
- { role: ui }
|
||||
- name: Install Monitor
|
||||
hosts: monitor
|
||||
become: true
|
||||
roles:
|
||||
- { role: monitor }
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user