mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 15:11:02 +00:00
Impl WeightTrader for tuple (#3601)
* Impl WeightTrader for tuple. * fmt * Renaming. * add tracing for buy_weight * Add comment clarifying the default behavior of a WeightTrader tuple Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use super::{mock::*, *};
|
||||
use frame_support::{assert_err, weights::constants::WEIGHT_PER_SECOND};
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_executor::{traits::*, Config, XcmExecutor};
|
||||
|
||||
@@ -383,3 +384,52 @@ fn prepaid_result_of_query_should_get_free_execution() {
|
||||
let r = XcmExecutor::<TestConfig>::execute_xcm(origin.clone(), message.clone(), weight_limit);
|
||||
assert_eq!(r, Outcome::Incomplete(10, XcmError::Barrier));
|
||||
}
|
||||
|
||||
fn fungible_multi_asset(location: MultiLocation, amount: u128) -> MultiAsset {
|
||||
(AssetId::from(location), Fungibility::Fungible(amount)).into()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn weight_trader_tuple_should_work() {
|
||||
pub const PARA_1: MultiLocation = X1(Parachain(1));
|
||||
pub const PARA_2: MultiLocation = X1(Parachain(2));
|
||||
|
||||
parameter_types! {
|
||||
pub static HereWeightPrice: (AssetId, u128) = (Here.into(), WEIGHT_PER_SECOND.into());
|
||||
pub static PARA1WeightPrice: (AssetId, u128) = (PARA_1.into(), WEIGHT_PER_SECOND.into());
|
||||
}
|
||||
|
||||
type Traders = (
|
||||
// trader one
|
||||
FixedRateOfFungible<HereWeightPrice, ()>,
|
||||
// trader two
|
||||
FixedRateOfFungible<PARA1WeightPrice, ()>,
|
||||
);
|
||||
|
||||
let mut traders = Traders::new();
|
||||
// trader one buys weight
|
||||
assert_eq!(
|
||||
traders.buy_weight(5, fungible_multi_asset(Here, 10).into()),
|
||||
Ok(fungible_multi_asset(Here, 5).into()),
|
||||
);
|
||||
// trader one refunds
|
||||
assert_eq!(traders.refund_weight(2), Some(fungible_multi_asset(Here, 2)));
|
||||
|
||||
let mut traders = Traders::new();
|
||||
// trader one failed; trader two buys weight
|
||||
assert_eq!(
|
||||
traders.buy_weight(5, fungible_multi_asset(PARA_1, 10).into()),
|
||||
Ok(fungible_multi_asset(PARA_1, 5).into()),
|
||||
);
|
||||
// trader two refunds
|
||||
assert_eq!(traders.refund_weight(2), Some(fungible_multi_asset(PARA_1, 2)));
|
||||
|
||||
let mut traders = Traders::new();
|
||||
// all traders fails
|
||||
assert_err!(
|
||||
traders.buy_weight(5, fungible_multi_asset(PARA_2, 10).into()),
|
||||
XcmError::TooExpensive,
|
||||
);
|
||||
// and no refund
|
||||
assert_eq!(traders.refund_weight(2), None);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@ pub trait UniversalWeigher {
|
||||
}
|
||||
|
||||
/// Charge for weight in order to execute XCM.
|
||||
///
|
||||
/// A `WeightTrader` may also be put into a tuple, in which case the default behavior of
|
||||
/// `buy_weight` and `refund_weight` would be to attempt to call each tuple element's own
|
||||
/// implementation of these two functions, in the order of which they appear in the tuple,
|
||||
/// returning early when a successful result is returned.
|
||||
pub trait WeightTrader: Sized {
|
||||
/// Create a new trader instance.
|
||||
fn new() -> Self;
|
||||
@@ -76,11 +81,31 @@ pub trait WeightTrader: Sized {
|
||||
}
|
||||
}
|
||||
|
||||
impl WeightTrader for () {
|
||||
#[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, _: Assets) -> Result<Assets, Error> {
|
||||
Err(Error::Unimplemented)
|
||||
|
||||
fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, Error> {
|
||||
let mut last_error = None;
|
||||
for_tuples!( #(
|
||||
match Tuple.buy_weight(weight, payment.clone()) {
|
||||
Ok(assets) => return Ok(assets),
|
||||
Err(e) => { last_error = Some(e) }
|
||||
}
|
||||
)* );
|
||||
let last_error = last_error.unwrap_or(Error::TooExpensive);
|
||||
log::trace!(target: "xcm::buy_weight", "last_error: {:?}", last_error);
|
||||
Err(last_error)
|
||||
}
|
||||
|
||||
fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
|
||||
for_tuples!( #(
|
||||
if let Some(asset) = Tuple.refund_weight(weight) {
|
||||
return Some(asset);
|
||||
}
|
||||
)* );
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user