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.Configure and deploy the xDai bridge oracle.
- 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.Synchronize the local OpenEthereum instance.
- 4.Run the oracles.
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
The oracle deployment procedure uses ansible playbooks, so two system are required. One hosts the oracle and a second deploys the oracle.
- 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.System for deploying the oracle (will run ansible playbooks). Installation assumptions:
- Python 2 (v2.6-v2.7)/Python3 (v3.5+)
- Git
- 3.Copy the private key to access the oracle host to
~/.ssh/
directory. - 4.Clone this repository and go to the deployment folder.$ git clone https://github.com/poanetwork/tokenbridge.git$ cd tokenbridge/deployment
- 5.Create the file
hosts.yml
fromhosts.yml.example
$ cp hosts.yml.example hosts.ymlhosts.yml
should have the following structure:---xdai-bridge:children:oracle:hosts:<ip.to.host>:ansible_user: <username to ssh into the host node. Typically ubuntu or root>ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY: "cafecafe...cafecafe"syslog_server_port: "<destination to forward logs, e.g. papertrail>"Note: the private key specified here is for the xDai bridge not for the AMB bridge. - 6.Prepare the Infura project ID used by the oracle as the main JSON RPC endpoint to get updates from the Ethereum Mainnet.
- 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.Create the file
group_vars/xdai-bridge.yml
with the following content:---## General settingsORACLE_BRIDGE_MODE: "ERC_TO_NATIVE"ORACLE_LOG_LEVEL: info## Home contractCOMMON_HOME_RPC_URL: "https://xdai.poanetwork.dev"COMMON_HOME_BRIDGE_ADDRESS: "0x7301CFA0e1756B71869E93d4e4Dca5c7d0eb0AA6"ORACLE_HOME_RPC_POLLING_INTERVAL: 5000## Foreign contractCOMMON_FOREIGN_RPC_URL: "https://mainnet.infura.io/v3/<YOUR-INFURA-PROJECT-ID> https://mainnet.blockscout.com/"COMMON_FOREIGN_BRIDGE_ADDRESS: "0x4aa42145Aa6Ebf72e164C9bBC74fbD3788045016"ORACLE_FOREIGN_RPC_POLLING_INTERVAL: 15000ORACLE_TX_REDUNDANCY: true## Home GaspriceCOMMON_HOME_GAS_PRICE_FALLBACK: 0 # in weiCOMMON_HOME_GAS_PRICE_FACTOR: 1ORACLE_HOME_GAS_PRICE_UPDATE_INTERVAL: 600000## Foreign GaspriceCOMMON_FOREIGN_GAS_PRICE_SUPPLIER_URL: gas-price-oracleCOMMON_FOREIGN_GAS_PRICE_SPEED_TYPE: fastCOMMON_FOREIGN_GAS_PRICE_FALLBACK: 100000000000 # in weiCOMMON_FOREIGN_GAS_PRICE_FACTOR: 1ORACLE_FOREIGN_GAS_PRICE_UPDATE_INTERVAL: 600000ORACLE_HOME_START_BLOCK: <latest block from the xDai chain>ORACLE_FOREIGN_START_BLOCK: <latest block from the Ethereum Mainnet>Note: fillCOMMON_FOREIGN_RPC_URL
,ORACLE_HOME_START_BLOCK
andORACLE_FOREIGN_START_BLOCK
with the information from the steps 6 and 7. - 9.Run the ansible playbook.$ ansible-playbook -e 'ansible_python_interpreter=/usr/bin/python3' -i hosts.yml site.ymlIf the private key file to access the host system by SSH differs from
id_rsa
, use another command:$ ansible-playbook -e 'ansible_python_interpreter=/usr/bin/python3' --private-key=~/.ssh/<priv-key-file> -i hosts.yml site.yml - 10.When deployment is finished, login to the host system and stop the xDai bridge oracle.$ sudo systemctl stop poabridge
- 11.Since the RabbitMQ DB can be initialized on this stage, it is necessary to remove it:$ sudo rm -rf /home/poadocker/bridge_data/rabbitmq
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.Add the private key and address of the AMB oracle to
/root/.key
. Use your favorite editorsudo nano /root/.key
orsudo vim /root/.key
## Validator-specific options $ORACLE_VALIDATOR_ADDRESS=0x...ORACLE_VALIDATOR_ADDRESS_PRIVATE_KEY=cafecafe...cafecafeAMB_ORACLE_ADDRESS=0x...AMB_ORACLE_ADDRESS_PRIVATE_KEY=deadbeef...deadbeef - 2.Change directory to
/etc/init.d
$ cd /etc/init.d - 3.Replace the bridge startup script to use the new key for the AMB oracle:$ sudo curl https://github.com/poanetwork/tokenbridge/releases/download/2.6.0-rc3/xdai-amb-combined-poabridge \-L -o poabridge
- 4.Update the system configuration to use the new startup script:$ sudo systemctl daemon-reload
- 5.Change directory to
/home/poadocker/bridge/oracle
$ cd /home/poadocker/bridge/oracle - 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.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
orsudo vim .env
):COMMON_HOME_RPC_URL=http://parity:8545/ https://xdai.poanetwork.devORACLE_TX_REDUNDANCY=trueORACLE_ALLOW_HTTP_FOR_RPC=yesAMB_HOME_ADDRESS=0x75Df5AF045d91108662D8080fD1FEFAd6aA0bb59AMB_FOREIGN_ADDRESS=0x4C36d2919e407f0Cc2Ee3c993ccF8ac26d9CE64eAMB_QUEUE_URL=amqp://rabbit-ambAMB_REDIS_URL=redis://redis-ambAMB_HOME_START_BLOCK=<latest block from the xDai chain>AMB_FOREIGN_START_BLOCK=<latest block from the Ethereum Mainnet>Note 1: the file may already haveORACLE_ALLOW_HTTP_FOR_RPC
set to 'no' andORACLE_TX_REDUNDANCY
set to 'True'. Remove these old lines.Note 2: fillAMB_HOME_START_BLOCK
andAMB_FOREIGN_START_BLOCK
with the information from step 5. - 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:$ curl https://github.com/poanetwork/tokenbridge/releases/download/2.6.0-rc3/xdai-oracle-wo-senderhome-docker-compose.yml \-L -o docker-compose.yml - 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:$ curl https://github.com/poanetwork/tokenbridge/releases/download/2.6.0-rc3/xdai-parity-amb-combined-docker-compose-erc-native.yml \-L -o docker-compose-erc-native.yml
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
):$ sudo docker pull openethereum/openethereum:v3.0.1
$ sudo docker tag openethereum/openethereum:v3.0.1 openethereum/openethereum:latest
$ sudo -u "poadocker" docker-compose -f docker-compose-erc-native.yml up parity
$ sudo systemctl start poabridge
Check the OpenEthereum service was run:
$ sudo docker logs parity
Make sure bridge workers are able to access OpenEthereum’s RPC service:
$ 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/
$ 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/
$ 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/
$ 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/
$ 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/
$ 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/
$ 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/