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.