Add-on: xDai and AMB bridge oracles on the same node
A step-by-step manual to deploy xDai bridge and Arbitrary Message Bridge oracles on the same node
There are several benefits to hosting the xDai bridge and Arbitrary Message Bridge oracles on the same node:
  • reduces the amount of hardware resources;
  • reduces required work for node administration and maintenance;
  • allows for local blockchain node sharing, increasing bridge security.
In general the process to prepare the node to serve the xDai and AMB bridges consists of the following phases:
  1. 1.
    Configure and deploy the xDai bridge oracle.
  2. 2.
    Modify the configuration on the xDai bridge oracle’s node to use the local OpenEthereum instance and to run AMB oracle’s workers.
  3. 3.
    Synchronize the local OpenEthereum instance.
  4. 4.
    Run the oracles.

Hardware Requirements

Minimums required to run xDai TokenBridge workers, OpenEthereum and the AMB workers on the same machine:
  • 4 CPU cores and 8 GBs RAM
  • 50 Gb disk memory

Phase 1. Configure and deploy the xDai bridge oracle

The oracle deployment procedure uses ansible playbooks, so two system are required. One hosts the oracle and a second deploys the oracle.
  1. 1.
    System for hosting the oracle:
    • when creating the node, set a meaningful hostname that can identify this oracle instance (e.g. bridge-ProjectName)
    • record the IP address (required for file setup)
    • setup ssh access to your node via public+private keys (using passwords is less secure)
  2. 2.
    System for deploying the oracle (will run ansible playbooks). Installation assumptions:
  3. 3.
    Copy the private key to access the oracle host to ~/.ssh/ directory.
  4. 4.
    Clone this repository and go to the deployment folder.
    1
    $ git clone https://github.com/poanetwork/tokenbridge.git
    2
    $ cd tokenbridge/deployment
    Copied!
  5. 5.
    Create the file hosts.yml from hosts.yml.example
    1
    $ cp hosts.yml.example hosts.yml
    Copied!
    hosts.yml should have the following structure:
    1
    ---
    2
    xdai-bridge:
    3
    children:
    4
    oracle:
    5
    hosts:
    6
    <ip.to.host>:
    7
    ansible_user: <username to ssh into the host node. Typically ubuntu or root>
    8
    ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY: "cafecafe...cafecafe"
    9
    syslog_server_port: "<destination to forward logs, e.g. papertrail>"
    Copied!
    Note: the private key specified here is for the xDai bridge not for the AMB bridge.
  6. 6.
    Prepare the Infura project ID used by the oracle as the main JSON RPC endpoint to get updates from the Ethereum Mainnet.
  7. 7.
    Visit http://etherscan.io/ and https://blockscout.com/xdai/mainnet to write down the latest blocks produced by the Ethereum Mainnet and the xDai chain.
  8. 8.
    Create the file group_vars/xdai-bridge.yml with the following content:
    1
    ---
    2
    ## General settings
    3
    ORACLE_BRIDGE_MODE: "ERC_TO_NATIVE"
    4
    ORACLE_LOG_LEVEL: info
    5
    6
    ## Home contract
    7
    COMMON_HOME_RPC_URL: "https://xdai.poanetwork.dev"
    8
    COMMON_HOME_BRIDGE_ADDRESS: "0x7301CFA0e1756B71869E93d4e4Dca5c7d0eb0AA6"
    9
    ORACLE_HOME_RPC_POLLING_INTERVAL: 5000
    10
    11
    ## Foreign contract
    12
    COMMON_FOREIGN_RPC_URL: "https://mainnet.infura.io/v3/<YOUR-INFURA-PROJECT-ID> https://mainnet.blockscout.com/"
    13
    COMMON_FOREIGN_BRIDGE_ADDRESS: "0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016"
    14
    ORACLE_FOREIGN_RPC_POLLING_INTERVAL: 15000
    15
    16
    ORACLE_TX_REDUNDANCY: true
    17
    18
    ## Home Gasprice
    19
    COMMON_HOME_GAS_PRICE_FALLBACK: 0 # in wei
    20
    COMMON_HOME_GAS_PRICE_FACTOR: 1
    21
    ORACLE_HOME_GAS_PRICE_UPDATE_INTERVAL: 600000
    22
    23
    ## Foreign Gasprice
    24
    COMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL: gas-price-oracle
    25
    COMMON_FOREIGN_GAS_PRICE_SPEED_TYPE: fast
    26
    COMMON_FOREIGN_GAS_PRICE_FALLBACK: 100000000000 # in wei
    27
    COMMON_FOREIGN_GAS_PRICE_FACTOR: 1
    28
    ORACLE_FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000
    29
    30
    ORACLE_HOME_START_BLOCK: <latest block from the xDai chain>
    31
    ORACLE_FOREIGN_START_BLOCK: <latest block from the Ethereum Mainnet>
    Copied!
    Note: fill COMMON_FOREIGN_RPC_URL, ORACLE_HOME_START_BLOCK and ORACLE_FOREIGN_START_BLOCK with the information from the steps 6 and 7.
  9. 9.
    Run the ansible playbook.
    1
    $ ansible-playbook -e 'ansible_python_interpreter=/usr/bin/python3' -i hosts.yml site.yml
    Copied!
    If the private key file to access the host system by SSH differs from id_rsa, use another command:
    1
    $ ansible-playbook -e 'ansible_python_interpreter=/usr/bin/python3' --private-key=~/.ssh/<priv-key-file> -i hosts.yml site.yml
    Copied!
  10. 10.
    When deployment is finished, login to the host system and stop the xDai bridge oracle.
    1
    $ sudo systemctl stop poabridge
    Copied!
  11. 11.
    Since the RabbitMQ DB can be initialized on this stage, it is necessary to remove it:
    1
    $ sudo rm -rf /home/poadocker/bridge_data/rabbitmq
    Copied!

Phase 2. Re-configure the host environment for OpenEthereum and AMB

The steps below should be executed on the system where the xDai bridge oracle was deployed. It is assumed that the xDai oracle is stopped (sudo systemctl stop poabridge).
  1. 1.
    Add the private key and address of the AMB oracle to /root/.key. Use your favorite editor sudo nano /root/.key or sudo vim /root/.key
    1
    ## Validator-specific options $
    2
    ORACLE_VALIDATOR_ADDRESS=0x...
    3
    ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=cafecafe...cafecafe
    4
    5
    AMB_ORACLE_ADDRESS=0x...
    6
    AMB_ORACLE_ADDRESS_PRIVATE_KEY=deadbeef...deadbeef
    Copied!
  2. 2.
    Change directory to /etc/init.d
    1
    $ cd /etc/init.d
    Copied!
  3. 3.
    Replace the bridge startup script to use the new key for the AMB oracle:
    1
    $ sudo curl https://github.com/poanetwork/tokenbridge/releases/download/2.6.0-rc3/xdai-amb-combined-poabridge \
    2
    -L -o poabridge
    Copied!
  4. 4.
    Update the system configuration to use the new startup script:
    1
    $ sudo systemctl daemon-reload
    Copied!
  5. 5.
    Change directory to /home/poadocker/bridge/oracle
    1
    $ cd /home/poadocker/bridge/oracle
    Copied!
  6. 6.
    Visit http://etherscan.io/ and https://blockscout.com/xdai/mainnet to write down the latest blocks produced by the Ethereum Mainnet and the xDai chain.
  7. 7.
    Modify the oracle configuration file to add parameters for AMB oracle workers. The following line must be added to the end of the file (sudo nano .env or sudo vim .env):
    1
    COMMON_HOME_RPC_URL=http://parity:8545/ https://xdai.poanetwork.dev
    2
    3
    ORACLE_TX_REDUNDANCY=true
    4
    ORACLE_ALLOW_HTTP_FOR_RPC=yes
    5
    6
    AMB_HOME_ADDRESS=0x75Df5AF045d91108662D8080fD1FEFAd6aA0bb59
    7
    AMB_FOREIGN_ADDRESS=0x4C36d2919e407f0Cc2Ee3c993ccF8ac26d9CE64e
    8
    9
    AMB_QUEUE_URL=amqp://rabbit-amb
    10
    AMB_REDIS_URL=redis://redis-amb
    11
    12
    AMB_HOME_START_BLOCK=<latest block from the xDai chain>
    13
    AMB_FOREIGN_START_BLOCK=<latest block from the Ethereum Mainnet>
    Copied!
    Note 1: the file may already have ORACLE_ALLOW_HTTP_FOR_RPC set to 'no' and ORACLE_TX_REDUNDANCY set to 'True'. Remove these old lines.
    Note 2: fill AMB_HOME_START_BLOCK and AMB_FOREIGN_START_BLOCK with the information from step 5.
  8. 8.
    Replace the first docker compose configuration file (docker-compose.yml) with a new one to optimize the number of the xDai bridge oracle workers:
    1
    $ curl https://github.com/poanetwork/tokenbridge/releases/download/2.6.0-rc3/xdai-oracle-wo-senderhome-docker-compose.yml \
    2
    -L -o docker-compose.yml
    Copied!
  9. 9.
    Replace the second docker compose configuration file (docker-compose-erc-native.yml) with a new one so that the service OpenEthereum and AMB workers are added:
    1
    $ curl https://github.com/poanetwork/tokenbridge/releases/download/2.6.0-rc3/xdai-parity-amb-combined-docker-compose-erc-native.yml \
    2
    -L -o docker-compose-erc-native.yml
    Copied!

Phase 3. Synchronize the local OpenEthereum instance

This step assumes that the current working directory is /home/poadocker/bridge/oracle.
Run OE to synchronize the chain (it will take few minutes depending on the internet channel bandwidth). As soon as you see new blocks appearing every 5 seconds, the service can be stopped (by Ctrl+C):
1
$ sudo docker pull openethereum/openethereum:v3.0.1
2
$ sudo docker tag openethereum/openethereum:v3.0.1 openethereum/openethereum:latest
3
$ sudo -u "poadocker" docker-compose -f docker-compose-erc-native.yml up parity
Copied!

Phase 4. Run the oracles

1
$ sudo systemctl start poabridge
Copied!
Check the OpenEthereum service was run:
1
$ sudo docker logs parity
Copied!
Make sure bridge workers are able to access OpenEthereum’s RPC service:
1
$ sudo docker exec -ti oracle_bridge_affirmation_1 curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_chainId","id":1}' http://parity:8545/
2
$ sudo docker exec -ti oracle_bridge_request_1 curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_chainId","id":1}' http://parity:8545/
3
$ sudo docker exec -ti oracle_bridge_senderhome_1 curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_chainId","id":1}' http://parity:8545/
4
$ sudo docker exec -ti oracle_bridge_transfer_1 curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_chainId","id":1}' http://parity:8545/
5
$ sudo docker exec -ti oracle_bridge_amb_affirmation_1 curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_chainId","id":1}' http://parity:8545/
6
$ sudo docker exec -ti oracle_bridge_amb_request_1 curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_chainId","id":1}' http://parity:8545/
7
$ sudo docker exec -ti oracle_bridge_amb_senderhome_1 curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_chainId","id":1}' http://parity:8545/
Copied!