Bruno Galvao
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
Invitee
Publish Note

Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

Your note will be visible on your profile and discoverable by anyone.
Your note is now live.
This note is visible on your profile and discoverable online.
Everyone on the web can find and read all notes of this public team.
See published notes
Unpublish note
Please check the box to agree to the Community Guidelines.
View profile
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Emoji Reply
Enable
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
5
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
# Setting up a local testnet using Zombienet Zombienet is an excellenet CLI tool to spawn a local test network. With Zombienet we can spawn a local relay chain with several validators as well as parachains with multiple collators. To see the full list of features Zombienet offers, take a look at the README: - https://github.com/paritytech/zombienet ## Objectives Setup a local Rococo testnet with the following: - Four validators - Two parachains - One collator per parachain - Create an HRMP channel between both parachains ## Getting the binaries You can use Zombienet with binaries, docker, kubernetes, and [more](https://github.com/paritytech/zombienet#requirements-by-provider). In this tutorial we will setup Zombienet to use binaries. In your root directory let's create a `bin` folder to hold your binaries: ``` mkdir bin ``` The first binary we will need is Polkadot. This binary will be used to spin up our relay chain. > If you're running Linux you can skip this section and download your Polkadot binary from here: > - https://github.com/paritytech/polkadot/releases First let's clone down Polkadot: ``` git clone https://github.com/paritytech/polkadot ``` `cd` into the repo, checkout the latest release of Polkadot and compile: ``` git checkout release-v0.9.32 cargo build -release ``` We now have a Polkadot binary! Copy the Polkadot binary into your `bin` folder: > Tip: It is good practice to append the version of polkadot to your binary name. This is a nice way of organizing in your `bin` folder multiple versions on your binary. ``` cp ./target/release/polkadot ../bin/polkadot-v0.9.32 ``` `cd` back to your root directory The next binary we will need is the [substrate-parachain-template](https://github.com/substrate-developer-hub/substrate-parachain-template) binary. We need this binary to spin up our parachains! Let's clone down [substrate-parachain-template](https://github.com/substrate-developer-hub/substrate-parachain-template): ``` git clone https://github.com/substrate-developer-hub/substrate-parachain-template ``` `cd` into the repo, checkout the latest Polkadot release, and compile: ``` git checkout polkadot-v0.9.32 cargo build -release ``` We now have a parachain collator binary. Copy the parachain binary into your `bin` folder: ``` cp ./target/release/parachain-template-node ../bin/parachain-template-node-v0.9.32 ``` Nice! We have all the binaries needed. ## Setting up Zombienet In this next section we will setup Zombienet and learn how to configure our testnet. We will need to download the Zombienet executable. You can find linux and macOS executables of the Zombienet CLI here: - https://github.com/paritytech/zombienet/releases Download the Zombienet CLI according to your operating system. > Tip: If you want the executable to be available system-wide then you can follow these steps (otherwise just download the executable to your working directory): > > ``` > wget https://github.com/paritytech/zombienet/releases/download/v1.3.18/zombienet-macos > chmod +x zombienet-macos > cp zombienet-macos /usr/local/bin > ``` Let's make sure Zombienet CLI is installed correctly: ``` ./zombienet-macos --help ``` You should see some similar output: ``` Usage: zombienet [options] [command] Options: -c, --spawn-concurrency <concurrency> Number of concurrent spawning process to launch, default is 1 -p, --provider <provider> Override provider to use (choices: "podman", "kubernetes", "native") -m, --monitor Start as monitor, do not auto cleanup network -h, --help display help for command Commands: spawn <networkConfig> [creds] Spawn the network defined in the config test <testFile> [runningNetworkSpec] Run tests on the network defined setup <binaries...> Setup is meant for downloading and making dev environment of Zombienet ready version Prints zombienet version help [command] display help for command ``` ### Setting up our config Zombienet works with a config. The config is where you specify your test network's configuration. The config is also where we specify our binaries. Create a config file: ``` touch config.toml ``` So we want to specify in our config that we want a Rococo relay chain with four validators and two parachains each with one collator: ``` [relaychain] default_command = "./bin/polkadot-v0.9.32" default_args = [ "-lparachain=debug" ] chain = "rococo-local" # relaychain nodes are by default validators [[relaychain.nodes]] name = "alice" [[relaychain.nodes]] name = "bob" [[relaychain.nodes]] name = "charlie" [[relaychain.nodes]] name = "dave" [[parachains]] id = 1000 cumulus_based = true [parachains.collator] name = "parachain-A-1000-collator-01" command = "./bin/parachain-template-node-v0.9.32" [[parachains]] id = 1001 cumulus_based = true [parachains.collator] name = "parachain-B-1001-collator-01" command = "../bin/parachain-template-node-v0.9.32" ``` Save the file and run the Zombienet CLI using this config: ``` ./zombienet-macos -p native spawn config.toml ``` You should see some nicely formatted output stating that the nodes are up and ready. You can now interact with your nodes on [polkadotJS apps](https://polkadot.js.org/apps/)! ### Opening HRMP Channels Background on HRMP (XCMP-Lite) > 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. - https://wiki.polkadot.network/docs/learn-xcm#hrmp-xcmp-lite This post will show how to open HRMP channels between two parachains: Parachain A and Parachain B. **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 way. A channel can be opened only after the recipient confirms it and only on a session change. ## Initiate an open channel request from Parachain A to Parachain B We will have Parachain A initiate a request to open an HRMP channel with Parachain B. This is done on the relay chain. Open the relay chain's polkadotJS apps and create the following extrinsic: ```js hrmp.hrmpInitOpenChannel( recipient: 2000 // the other parachain you want to open the channel with proposedMaxCapacity: 1000 // specifies how many messages can be in the channel at once proposed_max_message_size: 102400 // specifies the maximum size of the messages ) ``` ![](https://i.stack.imgur.com/AnPOl.png) We will not submit this transaction. Instead, after setting the desired parameters, **copy the encoded call data**. We will need this later to craft our XCM message. > Here is a past example of an encoded call data in Rococo: [`0x1700b80b0000e803000000900100`](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-rpc.polkadot.io#/extrinsics/decode/0x1700b80b0000e803000000900100) Note that `proposedMaxCapacity` and `proposed_max_message_size` numbers are subject to the relay chain's configuration limits. The relay chain's configuration can be found in `configuration.activeConfig()`: ![](https://i.stack.imgur.com/oNE6o.png) > The image above is an example of Rococo's active configuration at the time of writing this article. The next step is done on parachain A. Connect to Parachain A on polkadotJS apps. Create a polkadotXcm extrinsic to notify the relay chain that we want to open a channel with parachain B (using the encoded call data from the previous step): ```js polkadotXcm.send( dest: V1 parents: 1 interior: Here message: V2 XcmV2Instruction: WithdrawAsset id: Concrete parents: 0 interior: Here fun: Fungible Fungible: 1_000_000_000_000 XcmV2Instruction: BuyExecution id: Concrete parents: 0 interior: Here fun: Fungible Fungible: 1_000_000_000_000 weightLimit: Unlimited XcmV2Instruction: Transact originType: Native requireWeightAtMost: 4_000_000_000 encoded: 0x1700b80b0000e803000000900100 // our hrmpInitOpenChannel encoded call data ) ``` > Note: you should compose your message taking into account the active XCM configuration, this is just an example. ## Accept Parachain A's open channel request on Parachain B So far Parachain A has done its part: it has requested to open an HRMP channel to Parachain B. Now this request has to be accepted by Parachain B. On the relay chain, create the following extrinsic: ```js hrmp.hrmpAcceptOpenChannel( sender: 2000 ) ``` There is no need to submit the transaction. Instead copy the encoded call data. > Here is an example of an encoded call data in Rococo: [`0x1701d0070000`](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frococo-rpc.polkadot.io#/extrinsics/decode/0x1701d0070000) Now on Parachain B we use `polkadotXcm.send` extrinsic to craft an XCM message (using the encoded call data from the previous step). ```js polkadotXcm.send( dest: V1 parents: 1 interior: Here message: V2 XcmV2Instruction: WithdrawAsset id: Concrete parents: 0 interior: Here fun: Fungible Fungible: 1_000_000_000_000 XcmV2Instruction: BuyExecution id: Concrete parents: 0 interior: Here fun: Fungible Fungible: 1_000_000_000_000 weightLimit: Unlimited XcmV2Instruction: Transact originType: Native requireWeightAtMost: 4_000_000_000 encoded: 0x1701d0070000 // our hrmpAcceptOpenChannel encoded call data ) ``` > Note: you should compose your message taking into account the active XCM configuration, this is just an example. And that's it &mdash; the channel has been accepted and it will remain open, such that communication from Parachain A to Parachain B can now flow. For making this a bidirectional channel you'll need to open another channel, from Parachain B to Parachain A. You can do this by repeating the steps above (inversely). More info here: - https://docs.substrate.io/reference/how-to-guides/parachains/add-hrmp-channels ## Zombienet HRMP Configuration Zombienet also has an HRMP configuration to quickly open HRMP channels. For testing purposes this can be useful. Simply add the following to your config: ``` [[hrmpChannels]] sender = 1000 recipient = 1001 maxCapacity = 1000 maxMessageSize = 102400 [[hrmpChannels]] sender = 1001 recipient = 1000 maxCapacity = 1000 maxMessageSize = 102400 ``` Restart Zombienet and you now have a bidirectional HRMP channel open between the two parachains!

Import from clipboard

Paste your markdown or webpage here...

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template has been removed or transferred.
Upgrade
All
  • All
  • Team
No template.

Create a template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

Slide Example

API Docs

Edit in VSCode

Install browser extension

Contacts

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Get Full History Access

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

Note content is identical to the latest version.
Compare
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully