I can see that many parachains
have opened HRMP channels on Rococo and are beginning to experiment with XCM:
Source:
I would like to open HRMP channels between parachains on a local Rococo test network.
How do I do this?
I can see that many parachains
have opened HRMP channels on Rococo and are beginning to experiment with XCM:
Source:
I would like to open HRMP channels between parachains on a local Rococo test network.
How do I do this?
Feel free to update/modify this if you see something that can be improved upon
If you are new to XCM, read the following:
Here is the setup for this tutorial:
You will need the following:
You can read up more on how to set up a test network here:
Since this tutorial is for example purposes, both parachains should have the sudo pallet configured. In a production chain this would be substituted with governance.
Here is an excerpt from the Polkadot Wiki:
While XCMP is still being implemented, a stop-gap protocol (see definition below) known as Horizontal Relay-routed Message Passing (HRMP) exists in its place. HRMP has the same interface and functionality as XCMP but is much more demanding on resources since it stores all messages in the Relay Chain storage. When XCMP has been implemented, HRMP is planned to be deprecated and phased out in favor of it.
Source:
HRMP channels are unidirectional
The parachain that wants to open an HRMP channel must make a request to the parachain it wishes to have an open channel with. Once that is done, the other parachain needs to accept this request. This is what we mean by unidirectional flow. For bidirectional communication we need to open another channel in the opposite direction.
A channel can be opened only after the recipient confirms it and only on a session change.
So in recap, for this tutorial, the idea is that we want bidirectional communication between parachain 1001 and parachain 1002 so that they can exchange XCM's.
hrmpInitOpenChannel
call. Do not submit the call, instead copy the encoded call data for later use:proposed_max_capacity
- specifies how many messages can be in the channel at once.proposed_max_message_size
- specifies the maximum size of the messages.These numbers are a subject to the relay chain's configuration limits.
You can find this in the relay chain's active configuration:
The next step will be to create and submit an XCM on parachain 1001 with our encoded call data from above, but before we can do this we need to make sure parachain 1001's sovereign account on the relay chain is funded so it can take care of any XCM transact fees.
Let's add parachain 1001's sovereign account to our address book.
On the relay chain, open the address book and add the following contact:
If you're unsure as to how to calculate the parachain's sovereign account checkout this post:
Note that if the parachain's
paraId
changes, then sovereign account will also change. Therefore, as a rule-of-thumb, avoid hard coding the parachain's sovereign account.
We can now transfer some tokens from Alice to the sovereign account:
And the account is now funded!
We can now create the XCM on parachain 1001:
A few things to note.
- Below you will see we use
sudo
, in the real-world this would be done via governance.- Always check what the XCM configuration is for the relay chain you are working with. The numbers below are for example purposes.
Notice the encoded call that we created in the beginning of this tutorial is now used in the
Transact
.
In the above call, we are executing a few instructions:
WithdrawAsset
- Removes the on-chain asset(s) and accrue them into the XCVM Holding Register. More info here.BuyExecution
- Pays for the execution of the current message using the asset(s) that were deposited in the XCVM Holding Register from our previous WithdrawAsset
instruction. More info here.RefundSurplus
- Increases Refunded Weight Register to the value of Surplus Weight Register. Attempts to accrue fees previously paid via BuyExecution
into the XCVM Holding Register for the amount that Refunded Weight Register is increased.DepositAsset
- Subtracts the asset(s) from the XCVM Holding Register and deposits on-chain equivalent assets under the ownership of the beneficiary. The operands are:
Notice that with DepositAsset
we are specifying an account where the surplus will go. In this example we have used Eve's account. In general, we can use the sovereign account of our sender chain(here is {0, X1(Parachain(1001))}
), so that we can use the surplus tokens to open the next HRMP channel.
Read more on how RefundSurplus
and DepositAsset
work here:
The first part of this call is the destination - where we want to send the XCM to be executed. In our case we are saying parent: 1
- the parent of parachain 1001 is the relay chain and in the context of the parent
we are specifying an interior: Here
meaning that we want the relay chain to execute the XCM. This is all done by using MultiLocation
. If you're not familiar with MultiLocation
then read up here:
Additionally, the actual XCM instructions themselves e.g. WithdrawAsset
, BuyExecution
, etc. also use MultiLocation
. In this case the MultiLocation
is in respect to the system that will be executing the XCM message:
Throughout XCM, messages are authored such that when interpreted from the receiver's point of view they will have the desired meaning/effect. This means that relative paths should always by constructed to be read from the point of view of the receiving system, which may have a completely different meaning in the authoring system.
More info here:
As far as the amount that is needed to withdraw to cover execution, this is something that you will need to calculate ahead of time. More info can be found here:
And a nice StackExchange write up from a community member on weights and paying for execution here:
So in summary, we are going to withdraw some amount from the parachain sovereign account to the XCVM Holding Register. Use the amount in there to "buy" execution time for our XCM Transact
instruction. Execute the Transact
. And whatever amount is left over (determined by RefundSurplus
) is deposited into an account we specify by using the DepositAsset
instruction.
Before submitting this call, let's open the parachain's explorer:
Also, open the relay chain's explorer:
You can now submit the XCM extrinsic and you will see the events.
First you will see the events in the parachain's explorer:
Then you will see the events in the relay chain's explorer:
Success!
But let's double check. Check the chain state on the relay chain to see if there is now an HRMP open channel request from parachain 1001 to parachain 1002:
You can also check here:
And note that some amount has been deducted from the sovereign account:
The surplus has gone to Eve's account:
Their balance went from 1,000,000,000,000,000,000 to 1,000,000,885,011,945,986!
Awesome!
We have succeeded in creating an HRMP open channel request. The next step is for parachain 1002 to accept the request.
On the relay chain create the following call:
Copy the encoded call data for later use in our XCM.
Make sure that parachain 1002's sovereign account is funded.
You will have to repeat the process of adding and funding parachain 1002's sovereign account which was documented above for parachain 1001.
Now, create the XCM on parachain 1002:
Submit.
Wait one epoch for the change to take place.
You now have established a unidirectional HRMP channel between parachain 1001 and parachain 1002!
And finally, we repeat the same process documented throughout this article but instead we do it from parachain 1002 to parachain 1001 and in doing so we will have succefully created a bidirectional HRMP channel.