bifrost-relayer.rs

What is bifrost-relayer.rs?

We recently introduced a Rust implementation of the CCCP-Relayer for the Bifrost Network. The new relayer has been reengineered to enhance overall performance and robustness across multiple blockchains. It retains the same functions as the Python version, processing cross-chain transactions and facilitating data transfers (e.g., feeding price information) from one blockchain to another.

The following section will guide you through the setup process about the Rust implementation of the Bifrost network's relayer.

Install Requirements

To initiate the bifrost-relayer, certain dependencies must be manually installed. Both the executable binary file and the configuration YAML file are essential for all environments and operators.

First, install the latest bifrost-relayer release binary. You can check the latest releases by going to our GitHub repository under the releases page.

wget "https://github.com/bifrost-platform/bifrost-relayer.rs/releases/latest/download/bifrost-relayer"

In order to execute the binary, the permission of the file has to be updated.

chmod +x bifrost-relayer

Then, install the configuration YAML file. This file serves as an example for a quick start. Given the minor differences between Testnet and Mainnet environments, it's crucial to use the appropriate file for the corresponding network.

# First create a directory to save your configuration file
mkdir configs && cd configs

# For mainnet only
wget "https://github.com/bifrost-platform/bifrost-relayer.rs/releases/latest/download/config.mainnet.yaml"

# For testnet only
wget "https://github.com/bifrost-platform/bifrost-relayer.rs/releases/latest/download/config.testnet.yaml"

Configuration Setup

Next, the configuration YAML file contains certain parameters that the operator has to set. For instance, variables such as your relayer private key and each EVM provider's RPC endpoints depends to the operator itself, thus these values should be manually set.

You should prepare RPC endpoints for the following blockchain networks. There are two options for this: 1) operating your own blockchains nodes, or 2) utilizing services that offers RPC endpoints. You can find node providers on the links below. It’s crucial that each node must be archive-mode enabled.

Configuration Templates

config.mainnet.yaml
system:
  private_key: "<YOUR_RELAYER_PRIVATE_KEY>"
  debug_mode: false

evm_providers:
  - name: "bifrost"
    id: 3068
    provider: "<YOUR_BIFROST_RPC_ENDPOINT>"
    call_interval: 3000
    block_confirmations: 5
    is_native: true
    is_relay_target: true
    socket_address: "0xd551F33Ca8eCb0Be83d8799D9C68a368BA36Dd52"
    vault_address: "0xD85EB87caB9041ad00764b95796702b1104F42D7"
    authority_address: "0x0000000000000000000000000000000000000400"
    relayer_manager_address: "0x0000000000000000000000000000000000002000"
  - name: "ethereum"
    id: 1
    provider: "<YOUR_ETHEREUM_RPC_ENDPOINT>"
    call_interval: 12000
    block_confirmations: 1
    is_relay_target: false
    eip1559: true
    socket_address: "0x4A31FfeAc276CC5e508cAC0568d932d398C4DD84"
    vault_address: "0x2F95C102Cc26875406BC689Fb01aE382B82AA535"
    authority_address: "0xAdcaa90cabDc730855064d5b0f5242c16A9B7E10"
    chainlink_usdc_usd_address: "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6"
    chainlink_usdt_usd_address: "0x3E7d1eAB13ad0104d2750B8863b489D65364e32D"
    chainlink_dai_usd_address: "0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9"
  - name: "bsc"
    id: 56
    provider: "<YOUR_BSC_RPC_ENDPOINT>"
    call_interval: 3000
    block_confirmations: 5
    is_relay_target: false
    is_initially_escalated: true
    socket_address: "0xb5Fa48E8B9b89760a9f9176388D1B64A8D4968dF"
    vault_address: "0x78ae4c0FD4f02CA79A2d8738d3369A4Bc5D4E323"
    authority_address: "0xF0500d77d5446665314722b963ab1F71872063E9"
  - name: "polygon"
    id: 137
    provider: "<YOUR_POLYGON_RPC_ENDPOINT>"
    call_interval: 2000
    block_confirmations: 7
    is_relay_target: false
    eip1559: true
    min_priority_fee: 30000000000
    socket_address: "0x050606CC2Bcd9504991Be2c309D6c6c832Bb5bd0"
    vault_address: "0x5fA7fe5F94f2D15585a3134C1C5d3019c8c1645d"
    authority_address: "0x7F48909fBd1E38f1e05B5E326A44175fc2462B13"
  - name: "base"
    id: 8453
    provider: "<YOUR_BASE_RPC_ENDPOINT>"
    call_interval: 2000
    block_confirmations: 7
    is_relay_target: false
    eip1559: true
    socket_address: "0xAe172D8c5E428D4b7C70f9E593b207F9daC9BF3e"
    vault_address: "0x4F7aB59b5AC112970F5dD66D8a7ac505c8E5e08B"
    authority_address: "0x4C7a44F3FB37A53F33D3fe3cCdE97A444F105239"

handler_configs:
  - handler_type: BridgeRelay
    watch_list: [3068, 1, 56, 137, 8453]
  - handler_type: Roundup
    watch_list: [3068]

###  The items below are optional. ###

bootstrap_config:
  is_enabled: true
  round_offset: 3

sentry_config:
  environment: "<YOUR_SENTRY_ENVIRONMENT>"
  is_enabled: false
  dsn: "<YOUR_SENTRY_DSN>"

prometheus_config:
  is_enabled: false
  is_external: false
  port: 8000
config.testnet.yaml
system:
  private_key: "<YOUR_RELAYER_PRIVATE_KEY>"
  debug_mode: false

evm_providers:
  - name: "bifrost-testnet"
    id: 49088
    provider: "<YOUR_BIFROST_TESTNET_RPC_ENDPOINT>"
    call_interval: 3000
    block_confirmations: 5
    is_native: true
    is_relay_target: true
    socket_address: "0x0218371b18340aBD460961bdF3Bd5F01858dAB53"
    vault_address: "0x90381bB369D4F8069fdA9246b23637a78c5d1c83"
    authority_address: "0x0000000000000000000000000000000000000400"
    relayer_manager_address: "0x0000000000000000000000000000000000002000"
  - name: "sepolia"
    id: 11155111
    provider: "<YOUR_SEPOLIA_RPC_ENDPOINT>"
    call_interval: 12000
    block_confirmations: 1
    is_relay_target: false
    eip1559: true
    socket_address: "0xdAcc4aeea580F782bB991eA862e1a57827Ea9D68"
    vault_address: "0x9070e3a291B96D156f361A850410d656880540D2"
    authority_address: "0xC96971f6F5A1D20EFcD465B1163812a955b414A3"
  - name: "bsc-testnet"
    id: 97
    provider: "<YOUR_BSC_TESTNET_RPC_ENDPOINT>"
    call_interval: 3000
    block_confirmations: 5
    is_relay_target: false
    is_initially_escalated: true
    socket_address: "0x8039c3AD8ED55509fD3f6Daa78867923fDe6E61c"
    vault_address: "0x27C66cb5caa07C9B332939c357c789C606f5054C"
    authority_address: "0xCf9f6428A309b6652a1dfaA4d8aB8B61C9c7E8CF"
    chainlink_usdc_usd_address: "0x90c069C4538adAc136E051052E14c1cD799C41B7"
    chainlink_usdt_usd_address: "0xEca2605f0BCF2BA5966372C99837b1F182d3D620"
    chainlink_dai_usd_address: "0xE4eE17114774713d2De0eC0f035d4F7665fc025D"
  - name: "mumbai"
    id: 80001
    provider: "<YOUR_MUMBAI_RPC_ENDPOINT>"
    call_interval: 2000
    block_confirmations: 7
    is_relay_target: false
    eip1559: true
    socket_address: "0xA25357F3C313Bd13885678f935178211f0dF6722"
    vault_address: "0xB2ba0020560cF6c164DC48D1E29559AbA8472208"
    authority_address: "0x2FD5232fDFa6e1c127e7821CC48108Ca79281a38"
    chainlink_usdc_usd_address: "0x572dDec9087154dC5dfBB1546Bb62713147e0Ab0"
    chainlink_usdt_usd_address: "0x92C09849638959196E976289418e5973CC96d645"
    chainlink_dai_usd_address: "0x0FCAa9c899EC5A91eBc3D5Dd869De833b06fB046"
  - name: "base-sepolia"
    id: 84532
    provider: "<YOUR_BASE_SEPOLIA_RPC_ENDPOINT>"
    call_interval: 2000
    block_confirmations: 7
    is_relay_target: false
    eip1559: true
    socket_address: "0xdAcc4aeea580F782bB991eA862e1a57827Ea9D68"
    vault_address: "0x9070e3a291B96D156f361A850410d656880540D2"
    authority_address: "0x15EDC0c65004548fa787Bc01e533366674946C5F"
  - name: "arbitrum-sepolia"
    id: 421614
    provider: "<YOUR_ARBITRUM_SEPOLIA_RPC_ENDPOINT>"
    call_interval: 2000
    block_confirmations: 5
    get_logs_batch_size: 8
    is_relay_target: false
    eip1559: true
    socket_address: "0xd1E060FD930B75DA9A709c91E6Ad03B330Fb2950"
    vault_address: "0x6EeE91b7c69e3576C13cE7a9C7C0E305dF6996F9"
    authority_address: "0x4dA97eCD85d4EE00E26C5f3aF21e6Da7bc3F71e2"

handler_configs:
  - handler_type: BridgeRelay
    watch_list: [49088, 11155111, 97, 80001, 84532, 421614]
  - handler_type: Roundup
    watch_list: [49088]

###  The items below are optional. ###

bootstrap_config:
  is_enabled: true
  round_offset: 3

sentry_config:
  environment: "<YOUR_SENTRY_ENVIRONMENT>"
  is_enabled: false
  dsn: "<YOUR_SENTRY_DSN>"

prometheus_config:
  is_enabled: false
  is_external: false
  port: 8000

Configuration Parameters

The following table presents customizable parameters for the relayer. You can change each parameter according to your environment. However, we highly recommend to use the default values specified in the template except for fields that are not checked in the "Template Provided" column. Furthermore, "Template Provided" merely serves as an example, thus you must change the correct values for certain parameters (e.g., your private key).

Generally, for safety and to prevent unexpected system malfunctions, you should refrain from altering parameters that are included in the YAML file but not explicitly specified. If the network's self-monitoring mechanism detects a malfunction stemming from altered parameters, the offending relayer may be subject to slashing.

Using Systemd

For operators who prefer on using Systemd, you should make a configuration file for the Systemd execution environment. First, create a configuration file in the following directory.

sudo vi /etc/systemd/system/bifrost-relayer.service

An example of the configuration is provided below. The following parameters should be set regarding to your setup environment.

  • <DIRECTORY_WHERE_BIFROST_RELAYER_LOCATES> : The absolute path to the directory where the installed bifrost-relayer binary file locates.

  • <PATH_TO_BIFROST_RELAYER> : The absolute path to the installed bifrost-relayer binary file.

  • <PATH_TO_CONFIG_FILE> : The absolute path to the installed config.testnet.yaml or config.mainnet.yaml. This parameter will be the the value for the CLI option, --chain.

[Unit]
Description=Bifrost Relayer Daemon
After=network.target
StartLimitIntervalSec=5

[Service]
Type=simple
Restart=always
RestartSec=30
SyslogIdentifier=bifrost-relayer
SyslogFacility=local7
WorkingDirectory=<DIRECTORY_WHERE_BIFROST_RELAYER_LOCATES>
ExecStart=<PATH_TO_BIFROST_RELAYER> --chain <mainnet|testnet|<PATH_TO_CONFIG_FILE>>
KillSignal=SIGHUP

[Install]
WantedBy=multi-user.target
Example
[Unit]
Description=Bifrost Relayer Daemon
After=network.target
StartLimitIntervalSec=5

[Service]
Type=simple
Restart=always
RestartSec=30
SyslogIdentifier=bifrost-relayer
SyslogFacility=local7
WorkingDirectory=/home/ubuntu/example
ExecStart=/home/ubuntu/example/bifrost-relayer --chain testnet
KillSignal=SIGHUP

[Install]
WantedBy=multi-user.target

Run the Relayer Service

Now, the service can be started by executing the following commands. First, enable the service that will let it start automatically at every next system restart.

sudo systemctl enable bifrost-relayer

Then, start the Systemd service, executing instructions in the service’s configuration file, use the start command as mentioned below.

sudo systemctl start bifrost-relayer

And lastly, verify the service has successfully executed.

systemctl status bifrost-relayer

Check Logs

To check your running bifrost-relayer service logs, execute the command below.

journalctl -f -u bifrost-relayer

Once the service has successfully started, the initial logs will show up similar as below.

2023-08-04T14:41:38 INFO  sc_sysinfo     ]💻 Operating system: macos
2023-08-04T14:41:38 INFO  sc_sysinfo     ]💻 CPU architecture: aarch64
2023-08-04T14:41:38 INFO  bifrost-relayer]-[main               ] Bifrost Relayer
2023-08-04T14:41:38 INFO  bifrost-relayer]-[main               ] ✌️  version 1.0.2-1053ac84663
2023-08-04T14:41:38 INFO  bifrost-relayer]-[main               ] ❤️  by bifrost-platform, 2023-2023
2023-08-04T14:41:38 INFO  bifrost-relayer]-[main               ]   Chain specification: testnet
2023-08-04T14:41:38 INFO  bifrost-relayer]-[main               ] 👤 Relayer: 0xf708d58820fa20405993e186a8b38fb777f3143a
2023-08-04T14:41:38 INFO  bifrost-relayer]-[main               ] 🔨 Relay Targets (Legacy): bifrost, bsc
2023-08-04T14:41:38 INFO  bifrost-relayer]-[main               ] 🔨 Relay Targets (EIP1559): ethereum, polygon
2023-08-04T14:41:38 INFO  bifrost        ]-[block-manager      ] 💤 Idle, best: #8495214
2023-08-04T14:41:38 INFO  ethereum       ]-[block-manager      ] 💤 Idle, best: #9459619
2023-08-04T14:41:38 INFO  polygon        ]-[block-manager      ] 💤 Idle, best: #38621155
2023-08-04T14:41:38 INFO  bsc            ]-[block-manager      ] 💤 Idle, best: #32143709

If the bootstrap configuration is enabled, it will then start to bootstrap historical events as below.

2023-07-14T16:00:35 INFO  bifrost        ]-[roundup-handler    ] ⚙️  [Bootstrap mode] Bootstrapping RoundUp events.
2023-07-14T16:00:35 INFO  bsc            ]-[bridge-handler     ] ⚙️  [Bootstrap mode] Bootstrapping Socket events.
2023-07-14T16:00:35 INFO  bifrost        ]-[bridge-handler     ] ⚙️  [Bootstrap mode] Bootstrapping Socket events.
2023-07-14T16:00:35 INFO  mumbai         ]-[bridge-handler     ] ⚙️  [Bootstrap mode] Bootstrapping Socket events.
2023-07-14T16:00:35 INFO  goerli         ]-[bridge-handler     ] ⚙️  [Bootstrap mode] Bootstrapping Socket events.
2023-07-14T16:00:37 INFO  bifrost        ]-[bridge-handler     ] ⚙️  [Bootstrap mode] Bootstrapping Socket events.
2023-07-14T16:00:37 INFO  bifrost-relayer]-[bridge-handler     ] ⚙️  [Bootstrap mode] Bootstrap process successfully ended.

After the initial launch and the bootstrap process ends, the system will wait until each chain has reached the block confirmations specified in your configuration YAML file. It will then import every new block on every interval as below.

2023-08-04T14:41:54 INFO  polygon        ]-[block-manager      ]  Imported #38621155
2023-08-04T14:41:56 INFO  bifrost        ]-[block-manager      ]  Imported #8495214
2023-08-04T14:41:56 INFO  polygon        ]-[block-manager      ]  Imported #38621156
2023-08-04T14:41:57 INFO  bsc            ]-[block-manager      ]  Imported #32143709
2023-08-04T14:41:58 INFO  polygon        ]-[block-manager      ]  Imported #38621157
2023-08-04T14:41:59 INFO  bifrost        ]-[block-manager      ]  Imported #8495215
2023-08-04T14:42:00 INFO  bsc            ]-[block-manager      ]  Imported #32143710
2023-08-04T14:42:00 INFO  polygon        ]-[block-manager      ]  Imported #38621158
2023-08-04T14:42:02 INFO  ethereum       ]-[block-manager      ]  Imported #9459619
2023-08-04T14:42:02 INFO  bifrost        ]-[block-manager      ]  Imported #8495216
2023-08-04T14:42:02 INFO  polygon        ]-[block-manager      ]  Imported #38621159
2023-08-04T14:42:03 INFO  bsc            ]-[block-manager      ]  Imported #32143711

If your relayer has met every system logs mentioned above, this means that it has successfully been launched and has started to operate in a healthy state.

Upgrade Service

As the bifrost-relayer is under continuous development, there will be instances when it becomes necessary to upgrade your relayer service. When such upgrades become available, relayer operators will be notified either through our community channels or via direct communication. Please note that some upgrades may be optional rather than mandatory.

First, remove or backup the previous bifrost-relayer binary file.

rm <PATH_TO_BIFROST_RELAYER_BINARY>

Then, install the latest version of bifrost-relayer into the same directory and update permissions. (In case of directory changes, the Systemd configuration file should be modified as well)

chmod +x bifrost-relayer

At last, restart the Systemd service.

sudo systemctl restart bifrost-relayer

Using Docker

For operators who prefer on using Docker, it must be pre-installed in your operating system. Once installed, you can proceed to the following steps.

To run the relayer as a Docker container, use the command as mentioned below.

  • <DIRECTORY_WHERE_CONFIG_FILE_LOCATES> : The absolute path of the directory where the installed config.testnet.yaml or config.mainnet.yaml locates.

  • <YOUR_CONFIG_FILE_NAME> : The file name of the installed configuration YAML file.

  • <YOUR_CONTAINER_NAME> : Please set an explicit name for your relayer container.

docker run -d \
  --restart always \
  --network host \
  --mount type=bind,source=<DIRECTORY_WHERE_CONFIG_FILE_LOCATES>,target=/relayer/configs \
  --name <YOUR_CONTAINER_NAME> \
  thebifrost/bifrost-relayer.rs:latest --chain /relayer/configs/<YOUR_CONFIG_FILE_NAME>
Example
docker run -d \
  --restart always \
  --network host \
  --mount type=bind,source=/home/ubuntu/example,target=/relayer/configs \
  --name bifrost-relayer \
  thebifrost/bifrost-relayer.rs:latest --chain /relayer/configs/config.mainnet.yaml

Check Logs

To check your running bifrost-relayer container logs, execute the command below.

docker logs -f <YOUR_CONTAINER_NAME>

Upgrade Docker Image

As the bifrost-relayer is under continuous development, there will be instances when it becomes necessary to upgrade your relayer service. When such upgrades become available, relayer operators will be notified either through our community channels or via direct communication. Please note that some upgrades may be optional rather than mandatory.

First stop and remove your running relayer container.

docker stop "YOUR_CONTAINER_NAME"
docker rm "YOUR_CONTAINER_NAME"

Then, pull the latest bifrost-relayer Docker image.

docker pull thebifrost/bifrost-relayer.rs:latest

At last execute the following command below to start a new container.

docker run -d \
  --restart always \
  --network host \
  --mount type=bind,source=<DIRECTORY_WHERE_CONFIG_FILE_LOCATES>,target=/relayer/configs \
  --name <YOUR_CONTAINER_NAME> \
  thebifrost/bifrost-relayer.rs:latest --chain /relayer/configs/<YOUR_CONFIG_FILE_NAME>

Parameter Descriptions

NameDescriptionExample / Available ValuesRequiredTemplate ProvidedDefault

system

System related parameters of the relayer.

-

-

system.private_key

The private key of the relayer.

"0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133"

-

system.debug_mode

The flag that represents if the debug mode is enabled. If enabled, debug-level logs and sentry alerts will be enabled.

true / false

false

evm_providers

The parameters related to EVM chain providers.

-

-

evm_providers.name

The name of the chain.

"bifrost"

-

evm_providers.provider

The RPC endpoint of the node. If the node is running, or is expected to be operated on the same server with the relayer, then set this value to the provided example.

"http://127.0.0.1:9933"

-

evm_providers.call_interval

The block synchronization interval in milliseconds. At every new interval, the system will synchronize every new block mined on the target chain.

1500

-

evm_providers.block_confirmations

The number of block confirmations required to synchronize a new block.

5

-

evm_providers.is_relay_target

The flag which represents whether the system will participate in external-chain CCCP actions. If this value is set to true, the system will try to execute transactions on the target chain, so sufficient balances are required. This value must be set to true if it is the Bifrost Network.

true / false

-

evm_providers.eip1559

The flag which represents whether the system will execute EIP-1559 transactions. If set to false, transactions will be executed by legacy types.

true / false

false

evm_providers.min_gas_price

The minimum gas price (in WEI) that the system will setup when executing legacy transactions. If the value is null, it will be dynamically set. This field only has effect when the eip1559 parameter is disabled.

30000000000

0

evm_providers.min_priority_fee

The minimum priority fee (in WEI) that the system will setup when executing EIP-1559 transactions. If the value is null, it will be dynamically set. This field only has effect when the eip1559 parameter is enabled.

30000000000

0

evm_providers.escalate_interval

The interval (in seconds) that will be used on gas price escalation to replace a transaction that is stuck in the mempool. This option will only have effect for legacy transactions.

12

12

evm_providers.escalate_percentage

The percentage that will be used on gas price escalation to replace a transaction that is stuck in the mempool. This option will only have effect for legacy transactions.

15.0

15.0

evm_providers.is_initially_escalated

The flag whether if the gas price will be initially escalated. The escalate_percentage will be used on escalation. This option will only have effect for legacy transactions.

true / false

false

evm_providers.get_logs_batch_size

The batch size (=block range) used when requesting eth_getLogs(). If increased the RPC request ration will be reduced, however event processing will be delayed regarded to the configured value. Default size is set to 1, which means it will be requested on every new block.

5

1

sentry_config

Sentry related parameters. If this section does not exist in your configuration file, Sentry will be disabled.

-

None

sentry_config.is_enabled

The flag which represents whether Sentry is enabled.

-

-

sentry_config.environment

The identifier for the Sentry client. This value will be used to distinguish triggered alarms.

"mainnet"

""

sentry_config.dsn

The Sentry DSN. If the value has been set, error and warning alerts will be notified. If the value is empty, Sentry will be disabled.

-

-

prometheus_config

Prometheus related parameters. It this section does not exist in your configuration file, Prometheus will be disabled.

-

None

prometheus_config.is_enabled

The flag which represents whether Prometheus metric collection is enabled.

true / false

-

prometheus_config.is_external

The flag which represents whether the Prometheus server is exposed on all interfaces.

true / false

false

prometheus_config.port

The Prometheus exporter TCP port.

8000

8000

bootstrap_config

Bootstrap related parameters. Bootstrap is a process that will be executed whenever the relayer (re-)starts. It will collect historical CCCP events and let the relayer re-handle the event to prevent missed actions.

-

None

bootstrap_config.is_enabled

The flag which represents whether bootstrap is enabled

true / false

-

bootstrap_config.round_offset

The amount of rounds to search for missed events.

3

3

Last updated