after playing with the Substrate Cumulus Parachain Template and the ping-pallet to get an idea of how to use XCM, I built a local Rococo testnet connected to two parachains.

In my code, at some point, the two parachains exchange XCM messages like in this image:

simple xcm exchange example

  • "step 1" Alice send a signed extrinsic call to parachain A, which triggers a XCM transact call towards parachain B
  • "step 2" parachain B receive the XCM transact call, execute the extrinsic function, and triggers a reply XCM transact call towards parachain A
  • "step 3" parachain A receive the XCM transact call, execute the extrinsic function

My question is: How are the costs of XCM messages designed?

I see that Alice pays for the extrinsic execution in "step 1". But in "step 2" and "step 3" there is no extrinsic costs for the XCM transact call, despite using a weight higher than 0 on the called extrinsic !?

Maybe the XCM transact origin_type has to do something with it but I don't understand it well.

Note: All XCM transact are using origin_type: OriginKind::Native. Also all the code works, my question is only about how the XCM interaction are being paid and how incentivization mechanism around XCM works.


1 Answer 1


Since XCM is configurable, this can depend from chain to chain. However, most(if not all) Dotsama chains adopt the same approach. We rely on parity's implementation of XcmExecutor (here) and various off-the-shelf implementation of various traits from the xcm-builder crate.

XCM Instruction Weight

Each XCM instruction has a certain weight since executing it takes some time. How XCM instructions are weighed is configured via XcmConfig,by setting type Weigher to some type.

E.g polkadot uses FixedWeightBounds(here and here) which will assign fixed weight to each XCM instruction with few exceptions. E.g. Transact's weight will consist of fixed weight + the weight of the call being transacted.

Using this approach, we can calculate the sum of weights for all the XCM instructions in a sequence. E.g. sequence { WithdrawAsset, BuyExecution, Transact } can be weighed as Weigher::weigh(WithdrawAsset) + Weigher::weigh(BuyExecution) + Weigher::weigh(Transact).

Paying For Xcm Execution

Let's assume for the sake of this example that we receive a XCM sent by a user with normal privileges (not root or sovereign-account). Like in you case above, Alice sends XCM from one chain to another.

Since Alice isn't a privileged user, she has to pay for executing transaction on Parachain-A, as you already noted. She also has to pay for XCM execution on the Parachain-B.

How much she has to pay and what currencies are supported for payment is once again configured by each chain. The setting type related to this is type Trader(here). In case of Polkadot, it just supports native DOT as payment asset (here and here). Same as with any other transaction on Polkadot, execution fee is correlated with weight - the more heavy the XCM is, the more you have to pay.

It's worth noting that many parachains allow XCM execution payment to be done in non-native asset. E.g. Astar has a configurable pallet that allows us to configure non-native asset as payment assets (here). Other parachains also use basically the same approach.

If you don't intend to pay for execution, chains will simply block your XCM and discard it. This is configured via type Barrier (here and here). Most relevant Barrier for Alice in this example is probably AllowTopLevelPaidExecutionFrom (here). It requires that the first message in XCM sequence is one that will put some assets into the holding register. This command should be followed-up by BuyExecution command which ensures you can pay for the follow-up XCM instructions you want to execute on the destination chain.

For the sake of example, let's assume the first XCM instruction is WithdrawAsset. Executing this in Parachain-B will attempt to withdraw some funds from Alice-derived account there. Which account is used, yet again depends on chain configuration. In case you're sending XCM from e.g. Astar to Polkadot, no new account would be derived and your public key would just be used on Polkadot. This would mean that Alice has to have some DOT in her account on Polkadot.

After this, BuyExecution is executed and some DOTs are spent to pay for XCM execution on Polkadot.

Hope this helps you :)

EDIT: regarding OriginKind, maybe this topic can be of help to you. It was quite confusing to me as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.