Integration Guide: Advanced
In the basic guide from the previous section, we walked through a minimal implementation of a cross-chain app. In this guide, we are going to discuss the following topics to make the BatchTransfer inter-chain dApp more production ready. The goal is to get you on board with the patterns involved in deploying a robust service on top of the Celer IM infrastructure.
Enhance security through executor's "sender groups" config
Dealing with bridge failures (refunds)
Chaining messages
Configuring a retry back-off strategy
Enhance security through executor's "sender groups" config
Under the current IM architecture, any contract can send messages to any other contracts. This means that a malicious party can forge messages that conform to your contract's message data type, send them to your contract, and exhaust your executor's gas fund. Thus, in production, it is important that the executor checks where a message originated from. Sender groups are designed just for that.
If you have experience with cloud services such as AWS, your might recognize that a sender group is pretty much a "security group".
An example sender group looks like this
After defining the security groups, we need to mount it to individual contract configs
Dealing with Bridge Failures
Contract Changes
It is possible that bridging would fail when the user calls batchTransfer
due to high slippage, not enough liquidity, etc. In These cases, the executor automatically prepares a refund and executes it on the source chain. In order for this to work, the BatchTransfer contract on the source chain needs to implement executeMessageWithTransferRefund
.
Note that this function is called with the original _message we encoded and sent out. And the funds are guaranteed to arrive before it is called.
Executor Changes
The executor has an option that needs to be explicitly turned on to enable auto refund for bridge failures.
Chaining Messages
You may want to "chain" or "nest" a message in executeMessageWithTransfer
on the destination chain. Since the executeMessageWithTransfer
interface is payable, this usage is supported.
In the BatchTransfer contract, a "receipt" message is chained inside.
Now we need to configure the executor to add a payable value when calling executeMessageWithTransfer
to cover the fee introduced by chaining the additional message.
But how do we know how much fee is needed? This is the tricky part since we can only estimate the amount of fee our sendMessage
call is incurring. Let's take a look at how the message fee is calculated in the MessageBus contract:
You can query the MessageBus contract on a chain for these parameters. If you use abi.encode
to encode your message, the message length is likely fixed. If you happen to have variable length fields in your message, you should add a safe margin to the add_payable_value_for_execution
to reduce the chance of having message execution reverted.
Last updated