Introduce XCM Weight Traits (#3802)

* introduce xcm weight traits

* patch some low hanging fruit

* add weightinfobound

* use checked math rather than saturating

* Update xcm/xcm-builder/src/weight.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Revert "Update xcm/xcm-builder/src/weight.rs"

This reverts commit 6331b874f3dccf7f01a051ca6d4ee4d14a23a82d.

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
Shawn Tabrizi
2021-09-07 19:42:05 -04:00
committed by GitHub
parent 268055eb3e
commit 3d18ad34a9
8 changed files with 189 additions and 18 deletions
+2
View File
@@ -16,6 +16,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
log = { version = "0.4.0", default-features = false }
# Polkadot dependencies
polkadot-parachain = { path = "../../parachain", default-features = false }
@@ -29,6 +30,7 @@ polkadot-runtime-parachains = { path = "../../runtime/parachains" }
default = ["std"]
runtime-benchmarks = []
std = [
"log/std",
"parity-scale-codec/std",
"xcm/std",
"xcm-executor/std",
@@ -142,6 +142,7 @@ impl<
}
fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result {
log::trace!("xcm::currency_adapter deposit_asset {:?} {:?}", what, who);
// Check we handle this asset.
let amount: u128 =
Matcher::matches_fungible(&what).ok_or(Error::AssetNotFound)?.saturated_into();
+62 -10
View File
@@ -35,29 +35,81 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo, M: Get<u32>> WeightBounds<C>
let mut instructions_left = M::get();
Self::weight_with_limit(message, &mut instructions_left)
}
fn instr_weight(message: &Instruction<C>) -> Result<Weight, ()> {
Self::instr_weight_with_limit(message, &mut u32::max_value())
fn instr_weight(instruction: &Instruction<C>) -> Result<Weight, ()> {
Self::instr_weight_with_limit(instruction, &mut u32::max_value())
}
}
impl<T: Get<Weight>, C: Decode + GetDispatchInfo, M> FixedWeightBounds<T, C, M> {
fn weight_with_limit(message: &Xcm<C>, instrs_limit: &mut u32) -> Result<Weight, ()> {
let mut r = 0;
let mut r: Weight = 0;
*instrs_limit = instrs_limit.checked_sub(message.0.len() as u32).ok_or(())?;
for m in message.0.iter() {
r += Self::instr_weight_with_limit(m, instrs_limit)?;
r = r.checked_add(Self::instr_weight_with_limit(m, instrs_limit)?).ok_or(())?;
}
Ok(r)
}
fn instr_weight_with_limit(
message: &Instruction<C>,
instruction: &Instruction<C>,
instrs_limit: &mut u32,
) -> Result<Weight, ()> {
Ok(T::get().saturating_add(match message {
Transact { require_weight_at_most, .. } => *require_weight_at_most,
SetErrorHandler(xcm) | SetAppendix(xcm) => Self::weight_with_limit(xcm, instrs_limit)?,
_ => 0,
}))
T::get()
.checked_add(match instruction {
Transact { require_weight_at_most, .. } => *require_weight_at_most,
SetErrorHandler(xcm) | SetAppendix(xcm) =>
Self::weight_with_limit(xcm, instrs_limit)?,
_ => 0,
})
.ok_or(())
}
}
struct WeightInfoBounds<W, C, M>(PhantomData<(W, C, M)>);
impl<W, C, M> WeightBounds<C> for WeightInfoBounds<W, C, M>
where
W: XcmWeightInfo<C>,
C: Decode + GetDispatchInfo,
M: Get<u32>,
Instruction<C>: xcm::GetWeight<W>,
{
fn weight(message: &mut Xcm<C>) -> Result<Weight, ()> {
let mut instructions_left = M::get();
Self::weight_with_limit(message, &mut instructions_left)
}
fn instr_weight(instruction: &Instruction<C>) -> Result<Weight, ()> {
Self::instr_weight_with_limit(instruction, &mut u32::max_value())
}
}
impl<W, C, M> WeightInfoBounds<W, C, M>
where
W: XcmWeightInfo<C>,
C: Decode + GetDispatchInfo,
M: Get<u32>,
Instruction<C>: xcm::GetWeight<W>,
{
fn weight_with_limit(message: &Xcm<C>, instrs_limit: &mut u32) -> Result<Weight, ()> {
let mut r: Weight = 0;
*instrs_limit = instrs_limit.checked_sub(message.0.len() as u32).ok_or(())?;
for m in message.0.iter() {
r = r.checked_add(Self::instr_weight_with_limit(m, instrs_limit)?).ok_or(())?;
}
Ok(r)
}
fn instr_weight_with_limit(
instruction: &Instruction<C>,
instrs_limit: &mut u32,
) -> Result<Weight, ()> {
use xcm::GetWeight;
instruction
.weight()
.checked_add(match instruction {
Transact { require_weight_at_most, .. } => *require_weight_at_most,
SetErrorHandler(xcm) | SetAppendix(xcm) =>
Self::weight_with_limit(xcm, instrs_limit)?,
_ => 0,
})
.ok_or(())
}
}