diff --git a/deployment-bridge/.gitignore b/deployment-bridge/.gitignore new file mode 100644 index 00000000..0dc8bbd7 --- /dev/null +++ b/deployment-bridge/.gitignore @@ -0,0 +1,7 @@ +*.retry +hosts.yml +hosts +*.log +Vagrantfile +vagrant-hosts.yml +.vagrant diff --git a/deployment-bridge/README.md b/deployment-bridge/README.md new file mode 100644 index 00000000..f1b15d33 --- /dev/null +++ b/deployment-bridge/README.md @@ -0,0 +1,51 @@ +# Ansible playbooks for deploying cross-chain bridges + +## Bridge Overview + +The POA Bridge allows users to transfer assets between two chains in the Ethereum ecosystem. It is composed of several elements which are located in different POA Network repositories: + +**Bridge Elements** +1. Deployment Playbooks. Configuration management instructions for validator nodes contained in this repository. +2. [Bridge Smart Contracts](https://github.com/poanetwork/poa-bridge-contracts). Solidity contracts used to manage bridge validators, collect signatures, and confirm asset relay and disposal. +3. [Token Bridge](https://github.com/poanetwork/token-bridge). The token bridge oracle written in NodeJS. +4. [Bridge UI Application](https://github.com/poanetwork/bridge-ui). A DApp interface to transfer tokens and coins between chains. +5. [Bridge Monitor](https://github.com/poanetwork/bridge-monitor). A tool for checking balances and unprocessed events in bridged networks. + + +## Playbooks Overview + +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 deployment are located in the [bridge-nodejs](bridge-nodejs) folder. + + +### Rust Bridge Playbooks + +The Rust bridge is not currently in production, but an Ansible playbook is developed for this implementation. It is available in the [upgradable-wo-parity](upgradable-wo-parity)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. + +## Configuration + +Please see the [bridge-nodejs README](bridge-nodejs/README.md) for configuration and execution details. + +## 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] +``` + +## Contributing + +See the [CONTRIBUTING](../CONTRIBUTING.md) document for contribution, testing and pull request protocol. + +## License + +[![License: LGPL v3.0](https://img.shields.io/badge/License-LGPL%20v3-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0) + +This project is licensed under the GNU Lesser General Public License v3.0. See the [LICENSE](../LICENSE) file for details. + + diff --git a/deployment-bridge/bridge-nodejs/.gitignore b/deployment-bridge/bridge-nodejs/.gitignore new file mode 100644 index 00000000..ccee6ffe --- /dev/null +++ b/deployment-bridge/bridge-nodejs/.gitignore @@ -0,0 +1,2 @@ +hosts.yml +hosts diff --git a/deployment-bridge/bridge-nodejs/README.md b/deployment-bridge/bridge-nodejs/README.md new file mode 100644 index 00000000..3099f1e3 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/README.md @@ -0,0 +1,136 @@ +### 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 `bridge-nodejs` folder +``` +git clone https://github.com/poanetwork/deployment-bridge.git +cd deployment-bridge/bridge-nodejs +``` +2. Create the file `hosts.yml` from `hosts.yml.example` +``` +cp hosts.yml.example hosts.yml +``` + +`hosts.yml` should have the following structure: + +```yaml +: + hosts: + : + ansible_user: + VALIDATOR_ADDRESS_PRIVATE_KEY: "" + #syslog_server_port: "://:" # When this parameter is set all bridge logs will be redirected to : address. +``` + +| Value | Description | +|:------------------------------------------------|:----------------------------------------------------------------------------------------------------------| +| `` | The bridge name which tells Ansible which file to use. This is located in `group_vars/.yml`. | +| `` | Remote server IP address. | +| ansible_user: `` | User that will ssh into the node. This is typically `ubuntu` or `root`. | +| VALIDATOR_ADDRESS_PRIVATE_KEY: `""` | The private key for the specified validator address. | +| syslog_server_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 and add it to the hosts.yml configuration. For example, if a bridge file is named sokol-kovan.yml, you would change the value in hosts.yml to sokol-kovan. + +#### Administrator Configurations + +1. The `group_vars/.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 token-bridge. See https://github.com/poanetwork/token-bridge#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 POA bridge. + +2.2 `bridge_repo` contains address of token-bridge repository. The default value is https://github.com/poanetwork/token-bridge. + +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 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 ` - use specified file as a `hosts.yml` file. + +* `-e "="` - override default variable. + +* `--private-key=` - if private keyfile is required to connect to the ubuntu instance. + +## 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 +$ exit +$ sudo service poabridge restart +``` +where the __ 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: "://:" # When this parameter is set all bridge logs will be redirected to the : address. +``` diff --git a/deployment-bridge/bridge-nodejs/ansible.cfg b/deployment-bridge/bridge-nodejs/ansible.cfg new file mode 100644 index 00000000..db134d0c --- /dev/null +++ b/deployment-bridge/bridge-nodejs/ansible.cfg @@ -0,0 +1,7 @@ +[defaults] +host_key_checking = False +stdout_callback = skippy +ANSIBLE_DEBUG=1 + +[ssh_connection] +pipelining=True diff --git a/deployment-bridge/bridge-nodejs/group_vars/dai.yml b/deployment-bridge/bridge-nodejs/group_vars/dai.yml new file mode 100644 index 00000000..2a0762ce --- /dev/null +++ b/deployment-bridge/bridge-nodejs/group_vars/dai.yml @@ -0,0 +1,24 @@ +## 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 diff --git a/deployment-bridge/bridge-nodejs/group_vars/example.yml b/deployment-bridge/bridge-nodejs/group_vars/example.yml new file mode 100644 index 00000000..8f4df614 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/group_vars/example.yml @@ -0,0 +1,24 @@ +## 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 diff --git a/deployment-bridge/bridge-nodejs/group_vars/wetc.yml b/deployment-bridge/bridge-nodejs/group_vars/wetc.yml new file mode 100644 index 00000000..013289af --- /dev/null +++ b/deployment-bridge/bridge-nodejs/group_vars/wetc.yml @@ -0,0 +1,24 @@ +## 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 diff --git a/deployment-bridge/bridge-nodejs/hosts.yml.example b/deployment-bridge/bridge-nodejs/hosts.yml.example new file mode 100644 index 00000000..7ef141fa --- /dev/null +++ b/deployment-bridge/bridge-nodejs/hosts.yml.example @@ -0,0 +1,6 @@ +sokol-kovan: + hosts: + 127.0.0.1: + ansible_user: ubuntu + VALIDATOR_ADDRESS_PRIVATE_KEY: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + #syslog_server_port: "udp://127.0.0.1:514" diff --git a/deployment-bridge/bridge-nodejs/roles/dependencies/README.md b/deployment-bridge/bridge-nodejs/roles/dependencies/README.md new file mode 100644 index 00000000..214cf1ac --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/dependencies/README.md @@ -0,0 +1,17 @@ +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 \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/dependencies/defaults/main.yml b/deployment-bridge/bridge-nodejs/roles/dependencies/defaults/main.yml new file mode 100644 index 00000000..246fbbb9 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/dependencies/defaults/main.yml @@ -0,0 +1,2 @@ +docker_compose_version: 1.22.0 +compose_service_user: poadocker diff --git a/deployment-bridge/bridge-nodejs/roles/dependencies/files/daemon.json b/deployment-bridge/bridge-nodejs/roles/dependencies/files/daemon.json new file mode 100644 index 00000000..89a39e30 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/dependencies/files/daemon.json @@ -0,0 +1,5 @@ +{ + "disable-legacy-registry": true, + "live-restore": true, + "no-new-privileges": true +} diff --git a/deployment-bridge/bridge-nodejs/roles/dependencies/handlers/main.yml b/deployment-bridge/bridge-nodejs/roles/dependencies/handlers/main.yml new file mode 100644 index 00000000..d39258e3 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/dependencies/handlers/main.yml @@ -0,0 +1,14 @@ +- name: restart rsyslog + service: + name: rsyslog + state: restarted + +- name: restart auditd + service: + name: auditd + state: restarted + +- name: restart docker + service: + name: docker + state: restarted diff --git a/deployment-bridge/bridge-nodejs/roles/dependencies/tasks/main.yml b/deployment-bridge/bridge-nodejs/roles/dependencies/tasks/main.yml new file mode 100644 index 00000000..77407ea1 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/dependencies/tasks/main.yml @@ -0,0 +1,74 @@ +- 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" + state: present + +- name: Install apt dependencies + apt: + update_cache: yes + name: "{{ item }}" + with_items: + - apt-transport-https + - ca-certificates + - curl + - software-properties-common + - docker-ce + - git + - "{{ (ansible_python_interpreter | default ('python')).split('/')[-1] }}-pip" + +- name: Install Docker Compose + get_url: + url: "https://github.com/docker/compose/releases/download/{{ docker_compose_version }}/docker-compose-Linux-x86_64" + dest: "/usr/local/bin/docker-compose" + force: True + owner: "root" + group: "root" + mode: "0755" + +- name: Install python docker library + pip: + name: "{{ item }}" + with_items: + - docker + - docker-compose + +- name: Add user to run docker-compose + user: + name: "{{ compose_service_user }}" + comment: user to run docker-compose + group: docker + createhome: yes + +- name: Install auditd + apt: + name: auditd + update_cache: yes + +- name: Configure auditd + blockinfile: + path: /etc/audit/audit.rules + block: | + -w /usr/bin/docker -p wa + -w /var/lib/docker -p wa + -w /etc/docker -p wa + -w /lib/systemd/system/docker.service -p wa + -w /lib/systemd/system/docker.socket -p wa + -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 + notify: restart auditd + +- name: Configure docker engine + copy: + src: daemon.json + dest: /etc/docker/daemon.json + owner: root + group: root + mode: 0640 + notify: restart docker diff --git a/deployment-bridge/bridge-nodejs/roles/jumpbox/README.md b/deployment-bridge/bridge-nodejs/roles/jumpbox/README.md new file mode 100644 index 00000000..ea214ea6 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/jumpbox/README.md @@ -0,0 +1 @@ +This role brings up a docker container using docker-compose. \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/jumpbox/defaults/main.yml b/deployment-bridge/bridge-nodejs/roles/jumpbox/defaults/main.yml new file mode 100644 index 00000000..5c3f6216 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/jumpbox/defaults/main.yml @@ -0,0 +1 @@ +bridge_path: "/home/{{ compose_service_user }}/bridge" diff --git a/deployment-bridge/bridge-nodejs/roles/jumpbox/tasks/main.yml b/deployment-bridge/bridge-nodejs/roles/jumpbox/tasks/main.yml new file mode 100644 index 00000000..c314edd5 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/jumpbox/tasks/main.yml @@ -0,0 +1,5 @@ +- name: Launch container + docker_service: + project_src: "{{ bridge_path }}" + state: present + build: yes \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/logging/README.md b/deployment-bridge/bridge-nodejs/roles/logging/README.md new file mode 100644 index 00000000..9a95125b --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/logging/README.md @@ -0,0 +1 @@ +This role sets up remote logging for services. \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/logging/defaults/main.yml b/deployment-bridge/bridge-nodejs/roles/logging/defaults/main.yml new file mode 100644 index 00000000..01a3b019 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/logging/defaults/main.yml @@ -0,0 +1,2 @@ +bridge_path: "/home/{{ compose_service_user }}/bridge" +syslog_server_port: udp://127.0.0.1:514 \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/logging/tasks/main.yml b/deployment-bridge/bridge-nodejs/roles/logging/tasks/main.yml new file mode 100644 index 00000000..aabf2d25 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/logging/tasks/main.yml @@ -0,0 +1,51 @@ +- name: Slurp docker compose file + slurp: + src: "{{ bridge_path }}/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 }}/docker-compose.yml" + +- name: Set the local container logs configuration file + template: + src: 30-docker.conf.j2 + dest: /etc/rsyslog.d/30-docker.conf + owner: root + group: root + mode: 644 + +- 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 + owner: root + group: root + mode: 644 + 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: 644 + +- name: Discarding unwanted messages in rsyslog + blockinfile: + path: /etc/rsyslog.conf + insertbefore: "# Where to place spool and state files" + marker: "#{mark} add string to discarding unwanted messages" + content: ':msg, contains, "VALIDATOR_ADDRESS_PRIVATE_KEY" ~' + notify: restart rsyslog \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/logging/templates/30-docker.conf.j2 b/deployment-bridge/bridge-nodejs/roles/logging/templates/30-docker.conf.j2 new file mode 100644 index 00000000..1bfbcf61 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/logging/templates/30-docker.conf.j2 @@ -0,0 +1,12 @@ +$FileCreateMode 0644 +template(name="DockerLogFileName" 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 'bridge_' then \ + ?DockerLogFileName +else + /var/log/docker/no_tag/docker.log +$FileCreateMode 0600 diff --git a/deployment-bridge/bridge-nodejs/roles/logging/templates/35-remote-logging.conf.j2 b/deployment-bridge/bridge-nodejs/roles/logging/templates/35-remote-logging.conf.j2 new file mode 100644 index 00000000..69c38f18 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/logging/templates/35-remote-logging.conf.j2 @@ -0,0 +1,28 @@ +template(name="RemoteForwardFormat" type="list") { + constant(value="<") + property(name="pri") + constant(value=">") + property(name="timestamp" dateFormat="rfc3339") + constant(value=" ") + property(name="hostname") + constant(value=" ") + property(name="syslogtag") + property(name="msg" spifno1stsp="on") + property(name="msg") +} + +if $programname startswith 'bridge_' or $programname startswith 'docker' 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" + ) +} \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/logging/templates/docker-logs.j2 b/deployment-bridge/bridge-nodejs/roles/logging/templates/docker-logs.j2 new file mode 100644 index 00000000..eb1a095c --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/logging/templates/docker-logs.j2 @@ -0,0 +1,16 @@ +/var/log/docker/*/docker.log { + rotate 5 + size 1G + compress + missingok + delaycompress + copytruncate +} +/var/log/docker/*.log { + rotate 5 + size 1G + compress + missingok + delaycompress + copytruncate +} diff --git a/deployment-bridge/bridge-nodejs/roles/post_config/README.md b/deployment-bridge/bridge-nodejs/roles/post_config/README.md new file mode 100644 index 00000000..35fa75d3 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/post_config/README.md @@ -0,0 +1 @@ +This role gets the start blocks for both home and foreign networks. \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/post_config/defaults/main.yml b/deployment-bridge/bridge-nodejs/roles/post_config/defaults/main.yml new file mode 100644 index 00000000..5c3f6216 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/post_config/defaults/main.yml @@ -0,0 +1 @@ +bridge_path: "/home/{{ compose_service_user }}/bridge" diff --git a/deployment-bridge/bridge-nodejs/roles/post_config/tasks/main.yml b/deployment-bridge/bridge-nodejs/roles/post_config/tasks/main.yml new file mode 100644 index 00000000..4031cde2 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/post_config/tasks/main.yml @@ -0,0 +1,33 @@ +- name: Get blocks + become_user: "{{ compose_service_user }}" + shell: docker-compose run --entrypoint "node scripts/getValidatorStartBlocks.js" bridge_affirmation + args: + chdir: "{{ bridge_path }}" + register: BLOCKS + +- name: Write blocks + blockinfile: + path: "{{ bridge_path }}/.env" + marker: "## {mark} Calculated by scripts/getValidatorStartBlocks.js" + block: | + HOME_START_BLOCK={{ (BLOCKS.stdout | from_json).homeStartBlock }} + FOREIGN_START_BLOCK={{ (BLOCKS.stdout | from_json).foreignStartBlock }} + +- name: Get validator address + 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 }}" + register: VADDRESS + +- name: Set VALIDATOR_ADDRESS variable + set_fact: + VALIDATOR_ADDRESS: "{{ VADDRESS.stdout }}" + +- name: Install .key config + template: + src: key.j2 + dest: "/root/.key" + owner: root + group: root + mode: 0600 diff --git a/deployment-bridge/bridge-nodejs/roles/post_config/templates/key.j2 b/deployment-bridge/bridge-nodejs/roles/post_config/templates/key.j2 new file mode 100644 index 00000000..2ee316da --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/post_config/templates/key.j2 @@ -0,0 +1,3 @@ +## Validator-specific options +VALIDATOR_ADDRESS={{ VALIDATOR_ADDRESS }} +VALIDATOR_ADDRESS_PRIVATE_KEY={{ VALIDATOR_ADDRESS_PRIVATE_KEY }} diff --git a/deployment-bridge/bridge-nodejs/roles/pre_config/README.md b/deployment-bridge/bridge-nodejs/roles/pre_config/README.md new file mode 100644 index 00000000..dbf0c115 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/pre_config/README.md @@ -0,0 +1 @@ +This role sets the .env config (excluding starting blocks). \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/pre_config/defaults/main.yml b/deployment-bridge/bridge-nodejs/roles/pre_config/defaults/main.yml new file mode 100644 index 00000000..689e71d5 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/pre_config/defaults/main.yml @@ -0,0 +1,6 @@ +bridge_path: "/home/{{ compose_service_user }}/bridge" + +ALLOW_HTTP: no +QUEUE_URL: amqp://rabbit +REDIS_URL: redis://redis +REDIS_LOCK_TTL: 1000 diff --git a/deployment-bridge/bridge-nodejs/roles/pre_config/tasks/main.yml b/deployment-bridge/bridge-nodejs/roles/pre_config/tasks/main.yml new file mode 100644 index 00000000..0097a48f --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/pre_config/tasks/main.yml @@ -0,0 +1,4 @@ +- name: Install .env config + template: + src: .env.j2 + dest: "{{ bridge_path }}/.env" diff --git a/deployment-bridge/bridge-nodejs/roles/pre_config/templates/.env.j2 b/deployment-bridge/bridge-nodejs/roles/pre_config/templates/.env.j2 new file mode 100644 index 00000000..58e4dc49 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/pre_config/templates/.env.j2 @@ -0,0 +1,42 @@ +## General settings +BRIDGE_MODE={{ BRIDGE_MODE }} + +## Home contract +HOME_RPC_URL={{ HOME_RPC_URL }} +HOME_BRIDGE_ADDRESS={{ HOME_BRIDGE_ADDRESS }} +HOME_POLLING_INTERVAL={{ HOME_POLLING_INTERVAL }} + +## Foreign contract +FOREIGN_RPC_URL={{ FOREIGN_RPC_URL }} +FOREIGN_BRIDGE_ADDRESS={{ FOREIGN_BRIDGE_ADDRESS }} +ERC20_TOKEN_ADDRESS={{ ERC20_TOKEN_ADDRESS }} +FOREIGN_POLLING_INTERVAL={{ FOREIGN_POLLING_INTERVAL }} + +## Gasprice +{% 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={{ HOME_GAS_PRICE_FALLBACK }} +{% if HOME_GAS_PRICE_UPDATE_INTERVAL | default('') != '' %} +HOME_GAS_PRICE_UPDATE_INTERVAL={{ HOME_GAS_PRICE_UPDATE_INTERVAL }} +{% endif %} + +{% if FOREIGN_GAS_PRICE_ORACLE_URL | default('') != '' %} +FOREIGN_GAS_PRICE_ORACLE_URL={{ FOREIGN_GAS_PRICE_ORACLE_URL }} +{% endif %} +{% if FOREIGN_GAS_PRICE_SPEED_TYPE | default('') != '' %} +FOREIGN_GAS_PRICE_SPEED_TYPE={{ FOREIGN_GAS_PRICE_SPEED_TYPE }} +{% endif %} +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 %} + +## Transport configuration +ALLOW_HTTP={{ "yes" if ALLOW_HTTP else "no" }} +QUEUE_URL={{ QUEUE_URL }} +REDIS_URL={{ REDIS_URL }} +REDIS_LOCK_TTL={{ REDIS_LOCK_TTL }} diff --git a/deployment-bridge/bridge-nodejs/roles/repo/README.md b/deployment-bridge/bridge-nodejs/roles/repo/README.md new file mode 100644 index 00000000..97ce36d0 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/repo/README.md @@ -0,0 +1 @@ +This role clones the repo from a specified URL. \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/repo/defaults/main.yml b/deployment-bridge/bridge-nodejs/roles/repo/defaults/main.yml new file mode 100644 index 00000000..59d51fea --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/repo/defaults/main.yml @@ -0,0 +1,3 @@ +bridge_path: "/home/{{ compose_service_user }}/bridge" +bridge_repo: https://github.com/poanetwork/token-bridge.git +bridge_repo_branch: master \ No newline at end of file diff --git a/deployment-bridge/bridge-nodejs/roles/repo/tasks/main.yml b/deployment-bridge/bridge-nodejs/roles/repo/tasks/main.yml new file mode 100644 index 00000000..7c32ee5b --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/repo/tasks/main.yml @@ -0,0 +1,6 @@ +- name: Get bridge repo + git: + repo: "{{ bridge_repo }}" + dest: "{{ bridge_path }}" + force: yes + version: "{{ bridge_repo_branch }}" diff --git a/deployment-bridge/bridge-nodejs/roles/servinstall/README.md b/deployment-bridge/bridge-nodejs/roles/servinstall/README.md new file mode 100644 index 00000000..983377c8 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/servinstall/README.md @@ -0,0 +1,5 @@ +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. diff --git a/deployment-bridge/bridge-nodejs/roles/servinstall/defaults/main.yml b/deployment-bridge/bridge-nodejs/roles/servinstall/defaults/main.yml new file mode 100644 index 00000000..61e145ac --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/servinstall/defaults/main.yml @@ -0,0 +1,4 @@ +--- +# defaults +bridge_path: "/home/{{ compose_service_user }}/bridge" +keyfile_path: "/root/.key" diff --git a/deployment-bridge/bridge-nodejs/roles/servinstall/tasks/main.yml b/deployment-bridge/bridge-nodejs/roles/servinstall/tasks/main.yml new file mode 100644 index 00000000..b9aa16c0 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/servinstall/tasks/main.yml @@ -0,0 +1,14 @@ +--- +- 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 diff --git a/deployment-bridge/bridge-nodejs/roles/servinstall/templates/poabridge.j2 b/deployment-bridge/bridge-nodejs/roles/servinstall/templates/poabridge.j2 new file mode 100644 index 00000000..2a27c312 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/roles/servinstall/templates/poabridge.j2 @@ -0,0 +1,94 @@ +#! /bin/bash + +### BEGIN INIT INFO +# Provides: poabridge +# 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 if bridge_path[:1] != "/" else bridge_path }}" + +#Getting path to private key file and variable name for parsing key file +keyfile="{{ keyfile_path }}" +vaddr="VALIDATOR_ADDRESS=" +vkey="VALIDATOR_ADDRESS_PRIVATE_KEY=" + +#Parsing file content and add key to variable +while read -r line +do + case $line in + $vaddr*) + vaddr=${line#$vaddr} + ;; + $vkey*) + vkey=${line#$vkey} + ;; + esac +done < $keyfile + +start(){ + echo "Starting bridge.." + 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 }}" VALIDATOR_ADDRESS=$vaddr VALIDATOR_ADDRESS_PRIVATE_KEY=$vkey /usr/local/bin/docker-compose up --detach +} + +stop(){ + echo "Stopping bridge.." + cd $WORKDIR + sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose down -v + sleep 2 +} + +status(){ + echo "Bridge status:" + cd $WORKDIR + sudo -u "{{ compose_service_user }}" /usr/local/bin/docker-compose ps +} + +rebuild(){ + echo "Rebuild bridge.." + 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 }}" VALIDATOR_ADDRESS=$vaddr VALIDATOR_ADDRESS_PRIVATE_KEY=$vkey /usr/local/bin/docker-compose up --detach --force-recreate --no-deps --build +} + + +case "$1" in + + start) + start + ;; + + stop) + stop + ;; + + status) + status + ;; + + restart) + echo "Restarting bridge.." + stop + start + ;; + + rebuild) + rebuild + ;; + + *) + echo $"Usage: $0 {start|stop|restart|rebuild|status}" + exit 1 + ;; + +esac + +exit 0 diff --git a/deployment-bridge/bridge-nodejs/site.yml b/deployment-bridge/bridge-nodejs/site.yml new file mode 100644 index 00000000..59009763 --- /dev/null +++ b/deployment-bridge/bridge-nodejs/site.yml @@ -0,0 +1,19 @@ +- 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 } diff --git a/deployment-bridge/upgradable-wo-parity/.gitignore b/deployment-bridge/upgradable-wo-parity/.gitignore new file mode 100644 index 00000000..95d71ea8 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/.gitignore @@ -0,0 +1,5 @@ +hosts.yml +*.retry +temp +test.js +output.txt diff --git a/deployment-bridge/upgradable-wo-parity/DETAILS.md b/deployment-bridge/upgradable-wo-parity/DETAILS.md new file mode 100644 index 00000000..6d7ec00d --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/DETAILS.md @@ -0,0 +1,119 @@ +Bridge-specific parameters should be stored in `group_vars/$BRIDGE_NAME.yml` so that they can be easily reused by selecting suitable bridge name in `hosts.yml`. However, for one-time testing purposes, these parameters can also be set directly in `hosts.yml` alongside other node-specific parametrs. + +## Details of the authority node setup +Installation consists of 2 parts: + +### 1. Preparing +1. A new user without sudo access is created. By default it's named `bridgeuser`, but can be controlled by `service_user` variable in `authority_node.yml` + +2. UFW is configured to allow inbound tcp connections only on ssh port (`22` by default) + +3. Syslog forwarding to remote server is setup by placing a config file in `/etc/rsyslog.d/tls-client.conf` file. This is done only if `syslog_server_port` is not empty + +4. Binaries and configuration files will be stored in the bridgeuser's home directory in `poa-bridge` folder, with the following structure: +``` +poa-bridge/ +└── bridge/ + ├── bridge* + ├── config.toml + ├── db.toml + ├── password.txt + └── keys/ + └── home-keystore.json +``` +here `*` means executable file, `/` means folder. Parity binary is downloaded both to home-node folder and foreign-node folder in case different versions might be required. + +### 2. Setting up bridge service +1. Bridge binary is downloaded from url specified in `bridge_bin_url` variable (default value is set in `roles/bridge/defaults/main.yml`). Binary's sha256-checksum is validated against the value from `bridge_bin_sha256`. So when changing default version **both** `bridge_bin_url` and `bridge_bin_sha256` should be updated + +2. Bridge `config.toml` is created based on `roles/bridge/templates/bridge.service.j2`, example: +``` +keystore = "keys" + +[home] +account = "0x006E27B6A72E1f34C626762F3C4761547Aff1421" +required_confirmations = 0 +poll_interval = 2 +rpc_host = "https://sokol.poa.network" +rpc_port = 443 +password = "password.txt" + +[foreign] +account = "0x006E27B6A72E1f34C626762F3C4761547Aff1421" +required_confirmations = 0 +poll_interval = 2 +rpc_host = "https://kovan.infura.io/mew" +rpc_port = 443 +password = "password.txt" + +[authorities] +accounts = [] +required_signatures = 1 + +[transactions] +deposit_relay = { gas = 3000000, gas_price = 1000000000 } +withdraw_relay = { gas = 3000000, gas_price = 1000000000 } +withdraw_confirm = { gas = 3000000, gas_price = 1000000000 } +``` + +3. Database `db.toml` file is created based on `roles/bridge/db.toml.j2`, example (in this case it will be the same for all newly-created nodes): +``` +home_contract_address = "0xad1dae0320717a288912ff7bae766ac87e7d14a5" +foreign_contract_address = "0xfd03be9947cbecb14a1ae8729936e23af7a0b50b" +checked_deposit_relay = 1768893 +checked_withdraw_relay = 6715777 +checked_withdraw_confirm = 6715777 +``` +**OR** `db.toml` can be copied from local machine, in this case `db_toml_location` variable should be set in `hosts.yml` to absolute path of the file + +4. Bridge service is installed for `systemd` so that it auto-start on startup and auto-restarts if bridge process fails. Example of `/etc/systemd/system/bridge.service` +``` +[Unit] +Description=bridge +After=network.target + +[Service] +User=bridgeuser +Group=bridgeuser +WorkingDirectory=/home/bridgeuser/poa-bridge/bridge +Environment=RUST_LOG=info +ExecStart=/home/bridgeuser/poa-bridge/bridge/bridge --config /home/bridgeuser/poa-bridge/bridge/config.toml --database /home/bridgeuser/poa-bridge/bridge/db.toml +Restart=always +RestartSec=3 + +[Install] +WantedBy=multi-user.target +``` +By default, restart delay is 3 seconds, this can be controlled by `restart_delay_sec` variable + +5. Logs are stored in `/var/log/syslog`. If you provided `syslog_server_port` variable (in format `host:port`) in `hosts.yml` during installation, logs from syslog will be duplicated to a central syslog server for analysis and monitoring + +## Useful commands +1. Restart services: +``` +sudo systemctl restart bridge +``` +Replace `restart` with `start` or `stop` if needed + +2. Get quick status of a service: +``` +sudo systemctl status bridge +``` +note if it's reported `active`, `running` or `dead` + +3. Tail bridge logs from `/var/log/syslog`: +``` +tail -F /var/log/syslog | grep bridge +``` + +4. Relogin as bridge user (user without sudo access for running bridge): +``` +sudo -i -u bridgeuser +``` +to go back +``` +exit +``` + +## URLs of bridge precompiled binary +Update `bridge_bin_url` and `bridge_bin_sha256` from `roles/bridge/defaults/main.yml` diff --git a/deployment-bridge/upgradable-wo-parity/NEW-BRIDGE.md b/deployment-bridge/upgradable-wo-parity/NEW-BRIDGE.md new file mode 100644 index 00000000..b2d0cb09 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/NEW-BRIDGE.md @@ -0,0 +1,48 @@ +## How to create group_vars file for a new bridge deployment + +If you deployed a new bridge and want it to be preconfigured for the future, you need to create an `.yml` file in `group_vars/` folder of this playbook. + +Basically, you can use `sokol-kovan.yml` as a template: +``` +### home side rpc +home_rpc_url: https://sokol.poa.network +home_rpc_port: 443 + +### foreign side rpc +foreign_rpc_url: https://kovan.infura.io/mew +foreign_rpc_port: 443 + +### bridge configs +bridge_deposit_relay_gas: 3000000 +bridge_withdraw_relay_gas: 3000000 +bridge_withdraw_confirm_gas: 3000000 + +bridge_deposit_relay_gas_price: 1000000000 +bridge_withdraw_relay_gas_price: 1000000000 +bridge_withdraw_confirm_gas_price: 1000000000 + +bridge_authorities_requires_signatures: 1 + +bridge_home_required_confirmations: 0 +bridge_foreign_required_confirmations: 0 + +bridge_home_contract_address: "0x98f7b68C0Ef6A7DA0Bb0E786144A87bfEcc5cbD1" +bridge_foreign_contract_address: "0x5c29759020Fa2251B6481A3Ac1Ee507Ddbdc075c" +bridge_home_contract_deploy: 2213129 +bridge_foreign_contract_deploy: 7066466 + +bridge_home_poll_interval: 4 +bridge_foreign_poll_interval: 3 + +bridge_home_default_gas_price: 1000000000 + +bridge_foreign_gas_price_oracle_url: https://gasprice.poa.network +bridge_foreign_gas_price_timeout: 10 +bridge_foreign_gas_price_speed: fast #other possible values: slow, standard, instant +bridge_foreign_default_gas_price: 21000000000 +``` + +Let's examine available options: +* `*_rpc_url`: url of the rpc endpoint of the home-side of the bridge +* `*_rpc_port`: port to use (for https use 443) +* `bridge_*` options are directly related to the values in `config.toml` and `db.toml`, see `roles/bridge/templates/config.toml.j2` and `roles/bridge/templates/db.toml.j2` for more details. diff --git a/deployment-bridge/upgradable-wo-parity/README.md b/deployment-bridge/upgradable-wo-parity/README.md new file mode 100644 index 00000000..e271c859 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/README.md @@ -0,0 +1,49 @@ +## Deploying bridge authority node + +### Prerequisites +1. Launch an Ubuntu 16.04 server on your favourite hosting provider and note its IP address. You should 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 + +### Preparing configuration file +1. Clone this repository and go to `upgradable-wo-parity` folder +``` +git clone https://github.com/poanetwork/deployment-bridge.git +cd upgradable-wo-parity +``` + +2. Create file `hosts.yml` from `hosts.yml.template` +``` +cp hosts.yml.template hosts.yml +``` +This file contains parameters specific to your node, so you need to edit it and replace/provide missing values. Let's review the parameters: +* `core-foundation` - name of the bridge you want to deploy. Unless deploying a custom bridge, you don't need to change this line +* `192.0.2.1` - replace with your node's IP address +* `ansible_user` - user to ssh into your node. Usually it's either `ubuntu` or `root` +* `ansible_python_interpreter` - path to python interpreter on your node. With Ubuntu 16.04 this should work with default value, however if running the playbook you get an error that `python3` is not found, try changing this to `/usr/bin/python` +* `signer_keyfile` - copy json content (`'{...}'`) of authority's keystore file +* `signer_password` - set this to authority's password +* `syslog_server_port` - set this to `server:port` of syslog server (should be provided to you) + +If you're a new validator joining an existing bridge setup, you may want to additionally set the following parameters in `hosts.yml`: +* `last_checked_deposit_relay` +* `last_checked_withdraw_relay` +* `last_checked_withdraw_confirm` +If set, these values overwrite initial block numbers in `db.toml`, so that your node won't be re-processing transactions that are already processed by existing validators. You should get exact values from other validators before running the playbook. + +### Installing the node +1. If ssh user can't execute `sudo` without password, you will need to add `--ask-become-pass` option below (without `[]` brackets) and provide sudo password when prompted by the playbook. +2. Run the playbook +``` +ansible-playbook -i hosts.yml [--ask-become-pass] authority-node.yml +``` +3. Playbook should complete without errors + +## Setup details +To get more details about the setup, [go here](./DETAILS.md) + +## Changes required for new bridges +To prepare configuration files for a newly deployed bridg, [go here](./NEW-BRIDGE.md) diff --git a/deployment-bridge/upgradable-wo-parity/ansible.cfg b/deployment-bridge/upgradable-wo-parity/ansible.cfg new file mode 100644 index 00000000..c58fea3c --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/ansible.cfg @@ -0,0 +1,2 @@ +[ssh_connection] +pipelining = True diff --git a/deployment-bridge/upgradable-wo-parity/authority-node.yml b/deployment-bridge/upgradable-wo-parity/authority-node.yml new file mode 100644 index 00000000..a7b7c038 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/authority-node.yml @@ -0,0 +1,17 @@ +--- +- hosts: all + become: yes + gather_facts: no + # vars: + # home_signer_address: "0x{{ (signer_keyfile|from_json).address }}" + # home_signer_keyfile: '{{ signer_keyfile }}' + # home_signer_password: "{{ signer_password }}" + # foreign_signer_address: "{{ home_signer_address }}" + # foreign_signer_keyfile: '{{ home_signer_keyfile }}' + # foreign_signer_password: "{{ home_signer_password }}" + # bridge_home_password_file: "password.txt" + # bridge_foreign_password_file: "password.txt" + roles: + - backward-compatibility + - authority-preconf + - bridge diff --git a/deployment-bridge/upgradable-wo-parity/group_vars/all.yml b/deployment-bridge/upgradable-wo-parity/group_vars/all.yml new file mode 100644 index 00000000..90cc02ff --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/group_vars/all.yml @@ -0,0 +1,6 @@ +### global settings +base_path: "/home/{{ service_user }}/poa-bridge" + +become_method: sudo + +service_user: bridgeuser \ No newline at end of file diff --git a/deployment-bridge/upgradable-wo-parity/group_vars/core-foundation.yml b/deployment-bridge/upgradable-wo-parity/group_vars/core-foundation.yml new file mode 100644 index 00000000..31fac906 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/group_vars/core-foundation.yml @@ -0,0 +1,32 @@ +### home side rpc +home_rpc_url: https://core.poa.network +home_rpc_port: 443 + +### foreign side rpc +foreign_rpc_url: https://mainnet.infura.io/metamask +foreign_rpc_port: 443 + +### bridge configs +bridge_deposit_relay_gas: 250000 +bridge_withdraw_relay_gas: 300000 +bridge_withdraw_confirm_gas: 300000 + +bridge_authorities_requires_signatures: 2 + +bridge_home_required_confirmations: 8 +bridge_foreign_required_confirmations: 8 + +bridge_home_contract_address: "0xB87b6077D59B01Ab9fa8cd5A1A21D02a4d60D358" +bridge_foreign_contract_address: "0xd819E948b14cA6AAD2b7Ffd333cCDf732b129EeD" +bridge_home_contract_deploy: 2477327 +bridge_foreign_contract_deploy: 5578725 + +bridge_home_poll_interval: 4 +bridge_foreign_poll_interval: 10 + +bridge_home_default_gas_price: 1000000000 + +bridge_foreign_gas_price_oracle_url: https://gasprice.poa.network +bridge_foreign_gas_price_timeout: 10 +bridge_foreign_gas_price_speed: fast #other possible values: slow, standard, instant +bridge_foreign_default_gas_price: 21000000000 diff --git a/deployment-bridge/upgradable-wo-parity/group_vars/sokol-kovan.yml b/deployment-bridge/upgradable-wo-parity/group_vars/sokol-kovan.yml new file mode 100644 index 00000000..eb7c2cc4 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/group_vars/sokol-kovan.yml @@ -0,0 +1,25 @@ +### home side rpc +home_rpc_url: https://sokol.poa.network +home_rpc_port: 443 + +### foreign side rpc +foreign_rpc_url: https://kovan.infura.io/mew +foreign_rpc_port: 443 + +### bridge configs +bridge_deposit_relay_gas: 3000000 +bridge_withdraw_relay_gas: 3000000 +bridge_withdraw_confirm_gas: 3000000 + +bridge_authorities_requires_signatures: 1 + +bridge_home_required_confirmations: 0 +bridge_foreign_required_confirmations: 0 + +bridge_home_contract_address: "0x98f7b68C0Ef6A7DA0Bb0E786144A87bfEcc5cbD1" +bridge_foreign_contract_address: "0x5c29759020Fa2251B6481A3Ac1Ee507Ddbdc075c" +bridge_home_contract_deploy: 2213129 +bridge_foreign_contract_deploy: 7066466 + +bridge_home_poll_interval: 4 +bridge_foreign_poll_interval: 3 diff --git a/deployment-bridge/upgradable-wo-parity/hosts.yml.template b/deployment-bridge/upgradable-wo-parity/hosts.yml.template new file mode 100644 index 00000000..ea7869b3 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/hosts.yml.template @@ -0,0 +1,13 @@ +--- +core-foundation: + hosts: + 192.0.2.1: + ansible_user: ubuntu + ansible_python_interpreter: "/usr/bin/python3" + signer_keyfile: '' + signer_password: "" + syslog_server_port: "" # this value should be provided to you + + # last_checked_deposit_relay: 1 # optional value, consult README + # last_checked_withdraw_relay: 1 # optional value, consult README + # last_checked_withdraw_confirm: 1 # optional value, consult README diff --git a/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/defaults/main.yml b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/defaults/main.yml new file mode 100644 index 00000000..f9c923dc --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/defaults/main.yml @@ -0,0 +1,7 @@ +###### Accepts the following parametrs: +# +# syslog_server_port server:port to forward syslog to (port is required, commonly port is 514) +# +--- +syslog_server_port: "" +custom_ssh_port: "" \ No newline at end of file diff --git a/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/handlers/main.yml b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/handlers/main.yml new file mode 100644 index 00000000..0ff560e9 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/handlers/main.yml @@ -0,0 +1,20 @@ +--- +- name: restart ufw + service: + name: ufw + state: restarted + +- name: restart chrony + service: + name: chrony + state: restarted + +- name: restart rsyslog + service: + name: rsyslog + state: restarted + +- name: restart sshd + service: + name: sshd + state: restarted \ No newline at end of file diff --git a/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/create-user.yml b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/create-user.yml new file mode 100644 index 00000000..e25c648d --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/create-user.yml @@ -0,0 +1,5 @@ +--- +- name: Preconf.Create user + user: + name: "{{ service_user }}" + shell: "/bin/bash" diff --git a/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/main.yml b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/main.yml new file mode 100644 index 00000000..0b30a12a --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/main.yml @@ -0,0 +1,28 @@ +--- +- name: Check if remote computer is listening on standard ssh port + become: no + wait_for: port="{{ ansible_port | default(22) }}" state="started" host="{{ inventory_hostname }}" connect_timeout="3" timeout="4" + delegate_to: "localhost" + ignore_errors: "yes" + register: port_used + +- name: Set inventory ansible_port to custom + set_fact: ansible_port="{{ custom_ssh_port }}" + when: port_used.state is undefined + +- name: Preconf - setup UFW firewall + import_tasks: ufw.yml + +- name: Preconf - sshd + import_tasks: sshd.yml + when: custom_ssh_port != "" and custom_ssh_port != ansible_port | default(22) + +- name: Preconf - create user + import_tasks: create-user.yml + +- name: Preconf - configure syslog forwarding + import_tasks: syslog-forward.yml + when: syslog_server_port != "" + +- name: Preconf - run handlers immediately + meta: flush_handlers diff --git a/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/sshd.yml b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/sshd.yml new file mode 100644 index 00000000..a9055e71 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/sshd.yml @@ -0,0 +1,33 @@ +- name: Save old SSH port to variable + set_fact: + old_port: "{{ ansible_port | default(22) }}" + +- name: Setup new SSH port + lineinfile: + dest: "/etc/ssh/sshd_config" + regexp: "^Port" + line: "Port {{ custom_ssh_port }}" + notify: restart sshd + +- name: Preconf - run handlers immediately + meta: flush_handlers + +- name: Doublecheck if computer is listening custom SSH port before removing old port access + become: no + wait_for: port="{{ custom_ssh_port }}" state="started" host="{{ inventory_hostname }}" connect_timeout="3" timeout="4" + delegate_to: "localhost" + register: port_used + +- name: Preconf.UFW - remove default ssh access + ufw: + delete: yes + rule: "allow" + port: "{{ old_port }}" + proto: "tcp" + when: port_used is defined and old_port!=custom_ssh_port + notify: + - restart ufw + +- name: Set inventory ansible_port to custom + set_fact: ansible_port="{{ custom_ssh_port }}" + \ No newline at end of file diff --git a/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/syslog-forward.yml b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/syslog-forward.yml new file mode 100644 index 00000000..8b426608 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/syslog-forward.yml @@ -0,0 +1,27 @@ +--- +- name: Preconf.Syslog forward - apt install rsyslog-gnutls package + apt: + name: rsyslog-gnutls + state: present + update_cache: yes + +- name: Preconf.Syslog forward - download papertrail CA + get_url: + url: "https://papertrailapp.com/tools/papertrail-bundle.pem" + checksum: "md5:ba3b40a34ec33ac0869fa5b17a0c80fc" + dest: "/etc/papertrail-bundle.pem" + mode: 0644 + owner: root + group: root + notify: + - restart rsyslog + +- name: Preconf.Syslog forward - create client config + template: + src: "rsyslog-tls-client.conf.j2" + dest: "/etc/rsyslog.d/tls-client.conf" + mode: 0644 + owner: root + group: root + notify: + - restart rsyslog diff --git a/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/ufw.yml b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/ufw.yml new file mode 100644 index 00000000..400dfbcb --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/tasks/ufw.yml @@ -0,0 +1,47 @@ +# to verify ufw configuration run: +# sudo ufw status verbose + +--- +- name: UFW + block: + - name: Preconf.UFW - install ufw + package: + name: ufw + state: present + + - name: Preconf.UFW - clean old rules + ufw: + state: reset + + - name: Preconf.UFW - configure defaults + ufw: + direction: "{{ item.direction }}" + policy: "{{ item.policy }}" + with_items: + - direction: "incoming" + policy: "deny" + - direction: "outgoing" + policy: "allow" + + - name: Preconf.UFW - allow ssh access + ufw: + rule: "allow" + port: "{{ ansible_port | default(22) }}" + proto: "tcp" + + - name: Preconf.UFW - allow custom port access + ufw: + rule: "allow" + port: "{{ custom_ssh_port }}" + proto: "tcp" + when: custom_ssh_port!="" and custom_ssh_port!=(ansible_port|default(22)) + + - name: Preconf.UFW - disable logging + ufw: + logging: off + + - name: Preconf.UFW - enable ufw to start on boot + ufw: + state: enabled + notify: + - restart ufw \ No newline at end of file diff --git a/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/templates/rsyslog-tls-client.conf.j2 b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/templates/rsyslog-tls-client.conf.j2 new file mode 100644 index 00000000..59931c5d --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/authority-preconf/templates/rsyslog-tls-client.conf.j2 @@ -0,0 +1,6 @@ +$DefaultNetstreamDriverCAFile /etc/papertrail-bundle.pem +$ActionSendStreamDriver gtls +$ActionSendStreamDriverMode 1 +$ActionSendStreamDriverAuthMode x509/name +$ActionSendStreamDriverPermittedPeer *.papertrailapp.com +*.* @@{{ syslog_server_port }} diff --git a/deployment-bridge/upgradable-wo-parity/roles/backward-compatibility/tasks/main.yml b/deployment-bridge/upgradable-wo-parity/roles/backward-compatibility/tasks/main.yml new file mode 100644 index 00000000..6ef1ccf2 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/backward-compatibility/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: BC - set home and foreign variables from signer + block: + - set_fact: + home_signer_address: "0x{{ (signer_keyfile|from_json).address }}" + home_signer_keyfile: '{{ signer_keyfile }}' + home_signer_password: "{{ signer_password }}" + - set_fact: + foreign_signer_address: "{{ home_signer_address }}" + foreign_signer_keyfile: '{{ home_signer_keyfile }}' + foreign_signer_password: "{{ home_signer_password }}" + - set_fact: + bridge_home_password_file: "password.txt" + bridge_foreign_password_file: "password.txt" + when: signer_keyfile|default("") != "" or signer_password|default("") != "" diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/defaults/main.yml b/deployment-bridge/upgradable-wo-parity/roles/bridge/defaults/main.yml new file mode 100644 index 00000000..9e43d613 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/defaults/main.yml @@ -0,0 +1,64 @@ +###### Accepts the following parametrs: +# +# bridge_path (*) path to the bridge folder (also used in templates) +# bridge_bin_url (*) url from which to download bridge binary +# bridge_bin_sha256 (*) sha256 checksum of the binary +# bridge_service_name (*) name to be used for bridge service +# bridge_deposit_relay_gas bridge config option (used only in templates) +# bridge_withdraw_relay_gas bridge config option (used only in templates) +# bridge_withdraw_confirm_gas bridge config option (used only in templates) +# bridge_home_required_confirmations bridge config option (used only in templates) +# bridge_home_poll_interval bridge config option (used only in templates) +# bridge_home_request_timeout bridge config option (used only in templates) +# bridge_foreign_required_confirmations bridge config option (used only in templates) +# bridge_foreign_poll_interval bridge config option (used only in templates) +# bridge_foreign_request_timeout bridge config option (used only in templates) +# db_toml_location path to bridge db.toml **on local machine** +# restart_delay_sec (*) delay in seconds between restarts of brige service. Set to 0 to omit this option (used only in templates) +# bridge_keystore_folder (*) folder to store keystore files +# bridge_home_password_file (*) name of the file with password +# bridge_foreign_password_file (*) name of the file with password +# home_rpc_url url of home-side rpc endpoint +# foreign_rpc_url url of foreign-sode rpc endpoint +# home_rpc_port port of home-side rpc endpoint +# foreign_rpc_port port of foreign-side rpc endpoint +# +--- +bridge_path: "{{ base_path }}/bridge" +bridge_bin_url: "https://s3.amazonaws.com/poa-bridge-iterim/release-v0.3.0/bridge" +bridge_bin_sha256: "4cfbba6f00fe6bbbd002b71ab4610c4bca06931496ee18fdbfd124d823b88bcb" +bridge_service_name: "bridge" +db_toml_location: "" + +home_rpc_port: 443 +foreign_rpc_port: 443 + +restart_delay_sec: 2 + +bridge_keystore_folder: "keys" +bridge_home_password_file: "home-password.txt" +bridge_foreign_password_file: "foreign-password.txt" + +# set to -1 to use bridge binary default values +bridge_home_request_timeout: 360 +bridge_foreign_request_timeout: 360 + +bridge_authorities: [] + +# set to empty string to use default value +bridge_home_gas_price_oracle_url: "" +# set to -1 to use default value +bridge_home_gas_price_timeout: -1 +# set to empty string to use default value +bridge_home_gas_price_speed: "" +# set to -1 to use default value +bridge_home_default_gas_price: -1 + +# set to empty string to use default value +bridge_foreign_gas_price_oracle_url: "" +# set to -1 to use default value +bridge_foreign_gas_price_timeout: -1 +# set to empty string to use default value +bridge_foreign_gas_price_speed: "" +# set to -1 to use default value +bridge_foreign_default_gas_price: -1 diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/handlers/main.yml b/deployment-bridge/upgradable-wo-parity/roles/bridge/handlers/main.yml new file mode 100644 index 00000000..8d12cd43 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: "restart {{ bridge_service_name }}" + service: + name: "{{ bridge_service_name }}" + state: restarted diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/tasks/main.yml b/deployment-bridge/upgradable-wo-parity/roles/bridge/tasks/main.yml new file mode 100644 index 00000000..a785e06e --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/tasks/main.yml @@ -0,0 +1,128 @@ +--- +- name: "Bridge - create bridge folder" + file: + path: "{{ bridge_path }}" + state: directory + mode: 0700 + owner: "{{ service_user }}" + group: "{{ service_user }}" + +- name: "Bridge - download bridge binary" + get_url: + url: "{{ bridge_bin_url }}" + checksum: "sha256:{{ bridge_bin_sha256 }}" + dest: "{{ bridge_path }}/bridge" + mode: "0700" + owner: "{{ service_user }}" + group: "{{ service_user }}" + notify: + - restart {{ bridge_service_name }} + +- name: "Bridge - create keystore folder" + file: + path: "{{ bridge_path }}/{{ bridge_keystore_folder }}" + state: directory + mode: 0700 + owner: "{{ service_user }}" + group: "{{ service_user }}" + +# - name: "Bridge - create keystore files" +# template: +# src: "{{ item }}.j2" +# dest: "{{ bridge_path }}/{{ bridge_keystore_folder }}/{{ item }}" +# with_items: +# - foreign-keystore.json +# - home-keystore.json +# notify: +# - restart bridge + +- name: "Bridge - create home keystore file" + template: + src: "home-keystore.json.j2" + dest: "{{ bridge_path }}/{{ bridge_keystore_folder }}/home-keystore.json" + mode: 0600 + owner: "{{ service_user }}" + group: "{{ service_user }}" + notify: + - restart bridge + +- name: "Bridge - create home password file" + template: + src: "home-password.txt.j2" + dest: "{{ bridge_path }}/{{ bridge_home_password_file }}" + mode: 0600 + owner: "{{ service_user }}" + group: "{{ service_user }}" + notify: + - restart bridge + +- name: "Bridge - create foreign keystore file" + template: + src: "foreign-keystore.json.j2" + dest: "{{ bridge_path }}/{{ bridge_keystore_folder }}/foreign-keystore.json" + mode: 0600 + owner: "{{ service_user }}" + group: "{{ service_user }}" + notify: + - restart bridge + when: home_signer_address != foreign_signer_address + +- name: "Bridge - create home password file" + template: + src: "foreign-password.txt.j2" + dest: "{{ bridge_path }}/{{ bridge_foreign_password_file }}" + mode: 0600 + owner: "{{ service_user }}" + group: "{{ service_user }}" + notify: + - restart bridge + when: bridge_home_password_file != bridge_foreign_password_file + +- name: "Bridge - create bridge config" + template: + src: config.toml.j2 + dest: "{{ bridge_path }}/config.toml" + mode: 0600 + owner: "{{ service_user }}" + group: "{{ service_user }}" + notify: + - restart bridge + +- name: "Bridge - create db.toml file from template" + template: + src: "db.toml.j2" + dest: "{{ bridge_path }}/db.toml" + mode: 0600 + owner: "{{ service_user }}" + group: "{{ service_user }}" + force: no + when: db_toml_location == "" + +- name: "Bridge - copy db.toml file from local machine" + copy: + src: "{{ db_toml_location }}" + dest: "{{ bridge_path }}/db.toml" + force: no + owner: "{{ service_user }}" + group: "{{ service_user }}" + mode: 0600 + when: db_toml_location != "" + +- name: "Bridge - install bridge service" + template: + src: bridge.service.j2 + dest: /etc/systemd/system/{{ bridge_service_name }}.service + owner: root + group: root + mode: 0644 + notify: + - restart {{ bridge_service_name }} + +- name: "Bridge - enable bridge service to start at boot" + command: "systemctl enable {{ bridge_service_name }}.service" + +- name: "Bridge - ensure bridge service is running" + systemd: + name: "{{ bridge_service_name }}.service" + state: started + enabled: yes diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/bridge.service.j2 b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/bridge.service.j2 new file mode 100644 index 00000000..f1d5e288 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/bridge.service.j2 @@ -0,0 +1,17 @@ +[Unit] +Description=bridge +After=network.target + +[Service] +User={{ service_user }} +Group={{ service_user }} +WorkingDirectory={{ bridge_path }} +Environment=RUST_LOG=info +ExecStart={{ bridge_path }}/bridge --config {{ bridge_path }}/config.toml --database {{ bridge_path }}/db.toml +Restart=always +{% if restart_delay_sec > 0 %} +RestartSec={{ restart_delay_sec }} +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/config.toml.j2 b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/config.toml.j2 new file mode 100644 index 00000000..1d6ea706 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/config.toml.j2 @@ -0,0 +1,57 @@ +keystore = "{{ bridge_keystore_folder }}" + +[home] +account = "{{ home_signer_address }}" +required_confirmations = {{ bridge_home_required_confirmations }} +poll_interval = {{ bridge_home_poll_interval }} +{% if bridge_home_request_timeout > -1 %} +request_timeout = {{ bridge_home_request_timeout }} +{% endif %} +rpc_host = "{{ home_rpc_url }}" +rpc_port = {{ home_rpc_port }} +password = "{{ bridge_home_password_file }}" + +{% if bridge_home_gas_price_oracle_url != "" %} +gas_price_oracle_url = "{{ bridge_home_gas_price_oracle_url }}" +{% if bridge_home_gas_price_timeout > -1 %} +gas_price_timeout = {{ bridge_home_gas_price_timeout }} +{% endif %} +{% if bridge_home_gas_price_speed != "" %} +gas_price_speed = "{{ bridge_home_gas_price_speed }}" +{% endif %} +{% endif %} +{% if bridge_home_default_gas_price > -1 %} +default_gas_price = {{ bridge_home_default_gas_price }} +{% endif %} + +[foreign] +account = "{{ foreign_signer_address }}" +required_confirmations = {{ bridge_foreign_required_confirmations }} +poll_interval = {{ bridge_foreign_poll_interval }} +{% if bridge_foreign_request_timeout > -1 %} +request_timeout = {{ bridge_foreign_request_timeout }} +{% endif %} +rpc_host = "{{ foreign_rpc_url }}" +rpc_port = {{ foreign_rpc_port }} +password = "{{ bridge_foreign_password_file }}" + +{% if bridge_foreign_gas_price_oracle_url != "" %} +gas_price_oracle_url = "{{ bridge_foreign_gas_price_oracle_url }}" +{% if bridge_foreign_gas_price_timeout > -1 %} +gas_price_timeout = {{ bridge_foreign_gas_price_timeout }} +{% endif %} +{% if bridge_foreign_gas_price_speed != "" %} +gas_price_speed = "{{ bridge_foreign_gas_price_speed }}" +{% endif %} +{% endif %} +{% if bridge_foreign_default_gas_price > -1 %} +default_gas_price = {{ bridge_foreign_default_gas_price }} +{% endif %} + +[authorities] +required_signatures = {{ bridge_authorities_requires_signatures }} + +[transactions] +deposit_relay = { gas = {{ bridge_deposit_relay_gas }} } +withdraw_relay = { gas = {{ bridge_withdraw_relay_gas }} } +withdraw_confirm = { gas = {{ bridge_withdraw_confirm_gas }} } diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/db.toml.j2 b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/db.toml.j2 new file mode 100644 index 00000000..691ab294 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/db.toml.j2 @@ -0,0 +1,5 @@ +home_contract_address = "{{ bridge_home_contract_address }}" +foreign_contract_address = "{{ bridge_foreign_contract_address }}" +checked_deposit_relay = {{ last_checked_deposit_relay|default(bridge_home_contract_deploy) }} +checked_withdraw_relay = {{ last_checked_withdraw_relay|default(bridge_foreign_contract_deploy) }} +checked_withdraw_confirm = {{ last_checked_withdraw_confirm|default(bridge_foreign_contract_deploy) }} diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/foreign-keystore.json.j2 b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/foreign-keystore.json.j2 new file mode 100644 index 00000000..e505ea6f --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/foreign-keystore.json.j2 @@ -0,0 +1 @@ +{{ (signer_keyfile|default("") != "") | ternary(foreign_signer_keyfile|to_json, foreign_signer_keyfile) }} diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/foreign-password.txt.j2 b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/foreign-password.txt.j2 new file mode 100644 index 00000000..dfadf801 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/foreign-password.txt.j2 @@ -0,0 +1 @@ +{{ foreign_signer_password }} diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/home-keystore.json.j2 b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/home-keystore.json.j2 new file mode 100644 index 00000000..b0d6fc73 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/home-keystore.json.j2 @@ -0,0 +1 @@ +{{ (signer_keyfile|default("") != "") | ternary(home_signer_keyfile|to_json, home_signer_keyfile) }} diff --git a/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/home-password.txt.j2 b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/home-password.txt.j2 new file mode 100644 index 00000000..51b57529 --- /dev/null +++ b/deployment-bridge/upgradable-wo-parity/roles/bridge/templates/home-password.txt.j2 @@ -0,0 +1 @@ +{{ home_signer_password }}