mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 11:41: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/>.
|
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use super::{mock::*, *};
|
use super::{mock::*, *};
|
||||||
|
use frame_support::{assert_err, weights::constants::WEIGHT_PER_SECOND};
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_executor::{traits::*, Config, XcmExecutor};
|
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);
|
let r = XcmExecutor::<TestConfig>::execute_xcm(origin.clone(), message.clone(), weight_limit);
|
||||||
assert_eq!(r, Outcome::Incomplete(10, XcmError::Barrier));
|
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.
|
/// 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 {
|
pub trait WeightTrader: Sized {
|
||||||
/// Create a new trader instance.
|
/// Create a new trader instance.
|
||||||
fn new() -> Self;
|
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 {
|
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