What's the meaning of weightLimit: Unlimited
in BuyExecution
?
When should I use a certain amount? Because I found that people always use Unlimited
.
First, you will have to provide some funds into the holding register using an instruction like WithdrawAsset
or ClaimAsset
, so buying execution assumes that you have something in the holding register to buy with.
At the beginning of execution, the executor will weigh the entire message, given what it knows about the weight of each Instruction
in the array (some instructions, like Transact
, need to be told a max weight).
Now that it knows the weight, it can check if it should_execute
. The key here is how it constructs the BuyExecution
instruction:
match i {
BuyExecution { weight_limit: Limited(ref mut weight), .. } if *weight >= max_weight => {
*weight = max_weight;
Ok(())
},
BuyExecution { ref mut weight_limit, .. } if weight_limit == &Unlimited => {
*weight_limit = Limited(max_weight);
Ok(())
},
_ => Err(()),
}
If the weight is Unlimited
, it will just try to use whatever funds are in the holding register to buy enough weight to execute the instructions. By putting in Limited(weight)
, you are basically saying "I'm only willing to buy this much weight, and if the message comes out to be heavier, then don't execute it."
Of course, even with Unlimited
, it can still fail. Depending on the weight to fee rate, you may not have provided enough funds in the holding register, in which case you'll get a TooExpensive
error.
If you use a certain amount like WeightLimit::Limited(5000000000)
, it means the upper limit of weight you are willing to pay for XCM, if the actual need over than this amount, the XCM will not be executed.
Let's take a look at the code:
weigher
(config in XcmCExecutorConfig
) https://github.com/paritytech/polkadot/blob/release-v0.9.26/xcm/xcm-executor/src/lib.rs#L84let xcm_weight = match Config::Weigher::weight(&mut message)
BuyExecution
instruction will be modified. https://github.com/paritytech/polkadot/blob/release-v0.9.26/xcm/xcm-builder/src/barriers.rs#L80 match i {
BuyExecution { weight_limit: Limited(ref mut weight), .. } if *weight >= max_weight => {
*weight = max_weight;
Ok(())
},
BuyExecution { ref mut weight_limit, .. } if weight_limit == &Unlimited => {
*weight_limit = Limited(max_weight);
Ok(())
},
_ => Err(()),
}
As you can see, if you use Unlimited
or a certain weight lager than the required weight, it will be replaced by the weight caculated in the first step.
But if you use a certain weight smaller than the required weight, it will be error and blocked by the barrier.