Skip to content

Latest commit

 

History

History
241 lines (177 loc) · 13.3 KB

README.md

File metadata and controls

241 lines (177 loc) · 13.3 KB

Table of Contents

Introduction

Versioning

Set Up

Deployment

Destroy

Local Messaging

Remote Messaging

Vertical Message Passing

Horizontal Message Passing

CLI

Samples

Introduction

The goal of this repository is to describe and provide samples of all possible XCM interactions between Parachains, Relay Chains, and also an optional Bridged counterpart context. The samples are written in TypeScript and connect to a locally deployed infra thanks to Polkadot JS API.

The necessary infra to run and test the samples can be easily deployed with a single command. This repository depends on:

Versioning

Note that the three projects are in continous development. For that reason, it is very important to pay attention on using compatible versions between them. In addition, since XCM versioning and configuration differs for each runtime, it becomes an extra factor to take into account when running or building new samples.

To make sure you are able to successfully run the samples locally, checkout to one of the available releases in this repository. The release name format defines what are the compatible versions you should checkout for the rest of respositories and what runtimes were used.

Release format:

release-<polkadot/cumulus_version>-<source_para_runtime>_<source_relay_runtime>-<target_relay_runtime>_<target_para_runtime>-<bridges_common_version>

For instance, release-0.9.10-rococo_rococo-wococo_rococo-0.9 is telling us that the release was tested against the following versions

  • Polkadot: release-v0.9.10
  • Cumulus: polkadot-v0.9.10
  • Relay Chain Runtimes: rococo-local and wococo-local
  • Parachains Runtimes: rococo-local and rococo-local
  • Bridges Common: v0.9

There might be cases where a certain runtime is not yet supported by Bridges Common, or we just do not want to implement it. Therefore, Bridges Common and a target runtimes are not necessary. For those cases, release-0.9.10-rococo_rococo woulde be telling us that the release was tested against the following versions

  • Polkadot: release-v0.9.10
  • Cumulus: polkadot-v0.9.10
  • Relay Chain Runtime: rococo-local
  • Parachains Runtime: rococo-local

Set Up

Unless you want to run the samples against unimplemented runtimes, the default values should be valid and the only variables you should update in ./config.sh are:

  • POLKADOT_REPO_PATH, PARACHAIN_REPO_PATH and BRIDGES_REPO_PATH point to the directories where the three previously mentioned repositories were cloned. Remember also to checkout the corresponding versions.

To change the Relay Chain runtimes:

  • RUNTIME_RELAY_SOURCE=<source_relay_runtime>
  • RUNTIME_RELAY_TARGET=<target_relay_runtime>

To change the Parachains runtimes:

  • RUNTIME_PARA_SOURCE=<source_para_runtime>
  • RUNTIME_PARA_TARGET=<target_para_runtime>

Deployment

$ ./start.sh

Destroy

$ ./stop.sh

Local Messaging

Relay Chains have a few different mechanisms that are responsible for message passing. They can be generally divided on two categories: Horizontal and Vertical. Horizontal Message Passing (HMP) refers to mechanisms that are responsible for exchanging messages between parachains. Vertical Message Passing (VMP) is used for communication between the relay chain and parachains.

Remote Messaging

All previous mechanisms can also be encapsuladed in a bridge message and executed "remotely" in a target context.

general view

  1. A bridge message payload is formed by:
      const payload = {
        call          
        origin        
        spec_version  
        weight       
      }
    • call: The encoded call data of the XCM to be executed in the Target Relay Chain
    • origin: Defines the Call origin to be used during the dispatch in the Target Relay Chain. There are three types:
      • SourceAccount: represents an account without a private key on the target-chain. This account (Companion Account) will be generated/derived using the account ID of the sender on the source-chain.
      • TargetAccount: represents an account with a private key on the target-chain. The sender on the source-chain needs to prove ownership of this account by using their target-chain private key to sign a proof.
      • SourceRoot: represents the source-chain's Root account on the target-chain. This origin can only be dispatched on the target chain if the "send message" request was made by the Root origin of the source chain - otherwise the message will fail to be dispatched
    • spec_version: The expected Target Relay Chain runtime version. Message will not be dipatched if it does not match.
    • weight: Weight of the call, declared by the message sender. If it is less than actual static weight, the call is not dispatched.
  2. A bridgeMessages.sendMessage(laneId, payload, deliveryAndDispatchFee) extrinsic is signed and sent by an origin in the source context. The bridge message pallet name varies based on the runtime implementation and the name of the Target Relay Chain it is aiming to send the message. For example, for Rococo runtime the pallet name to bridge to Wococo is bridgeWococoMessages. Althought the bridge pallets might have different naming, all of them are instances of pallet_bridge_messages.
  3. If the Message is accepted, it is stored on-chain in the OutboundMessages storage.
  4. The Bridge Message Relayer queries the Messages Outbound Lane from the Source Relay Chain and pass the message over to the Messages Inbound Lane of the Target Relay Chain
  5. Finally, the XCM message is picked up from the Inbound Lane and dispatched by the corresponding pallet_bridge_dispatch in the Target context.

Vertical Message Passing

DMP

Local

Downward Message Passing (DMP) is a mechanism for delivering messages to parachains from the relay chain.

Remote

dmp remote

  1. XCM encoded call and messages payload are generated
  2. Bridge Message is signed and sent with the XCM encoded call as part of its payload
  3. Message is accepted and stored in OtboundMessages
  4. The Bridge Message Relayer query the message from the Source Relay Chain Outbound Lane and pass it over the Target Relay Chain
  5. The XCM enconded call is dispatched in the Target Relay Chain

UMP

Upward Message Passing (UMP) is a mechanism responsible for delivering messages in the opposite direction: from a parachain up to the relay chain.

Horizontal Message Passing

CLI

A Comand Line Interface is available to run the samples. The command has the following format:

  yarn dev <MESSAGING> <TARGET> [OPTIONS] <XCM> [OPTIONS]
  • MESSAGING: mechanism for message passing

    • dmp: Downward Message Passing
    • ump: Upward Message Passing
    • hmp: Horizontal Message Passing
  • TARGET: context the message is going to be executed

    • local: the message is executed in the Source Chain
    • remote: the message is passed through the bridge to the Target Chain and executed there.
      • -l: bridge message lane | 0x00000000 (Default)
      • -f: fee | 10000000000000 (Default)
      • -o: origin | SourceAccount (Default)
  • XCM: XCM instruction type. All instructions but teleport-asset will fallback to the send() dispatchable from the xcmPallet

    • teleport-asset: call to the teleportAsset() dispatachable call from the xcmPallet
      • -p: parachain ID destiantion | 2000 (Default)
      • -s: extrinsic signer account (uri or private key) | //Alice (Default)
      • -b: beneficiary account
      • -a: amount to teleport
      • -w: destination weight
    • transact: Transact
      • -p: parachain ID destiantion | 2000 (Default)
      • -s: extrinsic signer account (uri or private key) | //Alice (Default)
      • -t: origin type
        • SovereignAccount
        • Native
        • Superuser
        • Xcm
      • -c: encoded call to be executed in the parachain target
      • -w: required weight at most

Samples

DMP

Teleport Asset

Local

yarn dev dmp local teleport-asset -s //Alice -p 2000 -b //Bob -a 1000000000000000 -w 100000000000

dmp local teleport

  1. Alice signs and sends a xcmPallet.teleportAssets(destination, beneficiary, assets, destWeight) extrinsic
  2. A WithdrawAsset XCM is executed Asset amount is withdrawn from Alice and deposited in the Check Account
  3. A InitiateTeleport XCM with two effects (BuyExecution and DepositAsset) is stored in the Relay Chain storage
  4. The XCM is read from the Relay Chain storage by the Parachain Full Node
  5. InitiateTeleport is executed, Asset amount is minted and deposited in Bob's account.

Remote

  • SourceAccount: The Xcm is executed by the Companion Account in the target Relay Chain. Therefore, the Companion Account should have some balance (1K at least for the following sample). //Alice Companion Account in Wococo is: 5GfixJndjo7RuMeaVGJFXiDBQogCHyhxKgGaBkjs6hj15smD

    yarn dev dmp remote -f 10000000000000 -l 0x00000000 teleport-asset -s //Alice -p 2000 -b //Bob -a 1000000000000000 -w 100000000000
    
  • TargetAccount: The Xcm is executed by an owned account in the target Relay Chain

    yarn dev dmp remote -o TargetAccount -t //Alice -f 10000000000000 -l 0x00000000 teleport-asset -s //Alice -p 2000 -b //Bob -a 1000000000000000 -w 100000000000
    

Transact

Local

Only Root Account (sudo) is able to send a Transact XCM to a Parachain. The Call will be dispatched by the Sovereign Account in the Parachain Thus, the source Sovereign Account, 5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM should have some balance (1K at least for the following sample)

The encoded Call that Transact instruction will dispatch is 0x1e00008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480f0080c6a47e8d03 and corresponds to balance.transfer() of 1k to //Bob

yarn dev dmp local transact -s //Alice -p 2000 -t SovereignAccount -w 1000000000 -c 0x1e00008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480f0080c6a47e8d03

dmp local transact

  1. The encoded call balance.transfer(dest, value) to be executed by the Transact XCM is generated.
  2. The Transact XCM is formed with originType = SovereignAccount
      const xcm = { Transact: { originType, requireWeightAtMost, encodedCall } }
  3. Alice signs and send the extrinsic sudo.sudo(api.tx.xcmPallet.send(destination, xcm))
  4. The Transact XCM is stored in the Relay Chain
  5. The XCM is read from the Relay Chain storage by the Parachain Full Node
  6. The encoded call in the Transact XCM is executed in the Parachain by its Sovereign Account, transfering the balance value to Bob

NOTE: Sending a Transact with a encoded bridgeWococoMessages.sendMessage() dispatch is not possible as the bridge pallet is only implemented in the Parachain. Therefore, DMP messages are not possible. Only a UMP or HMP would work. The alternative would be to try to send a Transact with destination Here instead of the Parachain.

Remote

  • SourceAccount: This case is not possible because a Transact XCM can only be executed by Root.

  • TargetAccount: The Root Account private key of the target key should be know to be able to use this option. The Sovereign Account 5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM of the target Parachain should have some balance.

    yarn dev dmp remote -o TargetAccount -t //Alice -f 10000000000000 -l 0x00000000 transact -s //Alice -p 2000 -t SovereignAccount -w 1000000000 -c 0x1e00008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480f0080c6a47e8d03