use crate::Assets;
use sp_std::result::Result;
use xcm::latest::{prelude::*, Weight};
pub trait WeightBounds<RuntimeCall> {
fn weight(message: &mut Xcm<RuntimeCall>) -> Result<Weight, ()>;
fn instr_weight(instruction: &Instruction<RuntimeCall>) -> Result<Weight, ()>;
}
pub trait UniversalWeigher {
fn weigh(dest: impl Into<MultiLocation>, message: Xcm<()>) -> Result<Weight, ()>;
}
pub trait WeightTrader: Sized {
fn new() -> Self;
fn buy_weight(
&mut self,
weight: Weight,
payment: Assets,
context: &XcmContext,
) -> Result<Assets, XcmError>;
fn refund_weight(&mut self, _weight: Weight, _context: &XcmContext) -> Option<MultiAsset> {
None
}
}
#[impl_trait_for_tuples::impl_for_tuples(30)]
impl WeightTrader for Tuple {
fn new() -> Self {
for_tuples!( ( #( Tuple::new() ),* ) )
}
fn buy_weight(
&mut self,
weight: Weight,
payment: Assets,
context: &XcmContext,
) -> Result<Assets, XcmError> {
let mut too_expensive_error_found = false;
let mut last_error = None;
for_tuples!( #(
match Tuple.buy_weight(weight, payment.clone(), context) {
Ok(assets) => return Ok(assets),
Err(e) => {
if let XcmError::TooExpensive = e {
too_expensive_error_found = true;
}
last_error = Some(e)
}
}
)* );
log::trace!(target: "xcm::buy_weight", "last_error: {:?}, too_expensive_error_found: {}", last_error, too_expensive_error_found);
Err(if too_expensive_error_found {
XcmError::TooExpensive
} else {
last_error.unwrap_or(XcmError::TooExpensive)
})
}
fn refund_weight(&mut self, weight: Weight, context: &XcmContext) -> Option<MultiAsset> {
for_tuples!( #(
if let Some(asset) = Tuple.refund_weight(weight, context) {
return Some(asset);
}
)* );
None
}
}