mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 07:41:08 +00:00
XCM: Fix issue with RequestUnlock (#7278)
* XCM: Fix issue with RequestUnlock * Leave API changes for v4 * Fix clippy errors * Fix tests --------- Co-authored-by: parity-processbot <>
This commit is contained in:
committed by
GitHub
parent
9450970927
commit
aac5b1e364
@@ -136,6 +136,8 @@ fn remote_unlock_roundtrip_should_work() {
|
||||
set_send_price((Parent, 10u128));
|
||||
|
||||
// We have been told by Parachain #1 that Account #3 has locked funds which we can unlock.
|
||||
// Previously, we must have sent a LockAsset instruction to Parachain #1.
|
||||
// This caused Parachain #1 to send us the NoteUnlockable instruction.
|
||||
let message =
|
||||
Xcm(vec![NoteUnlockable { asset: (Parent, 100u128).into(), owner: (3u64,).into() }]);
|
||||
let hash = fake_message_hash(&message);
|
||||
@@ -169,8 +171,10 @@ fn remote_unlock_roundtrip_should_work() {
|
||||
assert_eq!(r, Outcome::Complete(Weight::from_parts(40, 40)));
|
||||
assert_eq!(asset_list((3u64,)), vec![(Parent, 990u128).into()]);
|
||||
|
||||
let expected_msg =
|
||||
Xcm::<()>(vec![UnlockAsset { target: (3u64,).into(), asset: (Parent, 100u128).into() }]);
|
||||
let expected_msg = Xcm::<()>(vec![UnlockAsset {
|
||||
target: (Parent, Parachain(42), 3u64).into(),
|
||||
asset: (Parent, 100u128).into(),
|
||||
}]);
|
||||
let expected_hash = fake_message_hash(&expected_msg);
|
||||
assert_eq!(sent_xcm(), vec![((Parent, Parachain(1)).into(), expected_msg, expected_hash)]);
|
||||
assert_eq!(
|
||||
|
||||
@@ -876,9 +876,11 @@ impl<Config: config::Config> XcmExecutor<Config> {
|
||||
RequestUnlock { asset, locker } => {
|
||||
let origin = *self.origin_ref().ok_or(XcmError::BadOrigin)?;
|
||||
let remote_asset = Self::try_reanchor(asset.clone(), &locker)?.0;
|
||||
let remote_target = Self::try_reanchor_multilocation(origin, &locker)?.0;
|
||||
let reduce_ticket =
|
||||
Config::AssetLocker::prepare_reduce_unlockable(locker, asset, origin)?;
|
||||
let msg = Xcm::<()>(vec![UnlockAsset { asset: remote_asset, target: origin }]);
|
||||
let msg =
|
||||
Xcm::<()>(vec![UnlockAsset { asset: remote_asset, target: remote_target }]);
|
||||
let (ticket, price) = validate_send::<Config::XcmSender>(locker, msg)?;
|
||||
self.take_fee(price, FeeReason::RequestUnlock)?;
|
||||
reduce_ticket.enact()?;
|
||||
@@ -990,6 +992,17 @@ impl<Config: config::Config> XcmExecutor<Config> {
|
||||
Ok((asset, reanchor_context))
|
||||
}
|
||||
|
||||
fn try_reanchor_multilocation(
|
||||
location: MultiLocation,
|
||||
destination: &MultiLocation,
|
||||
) -> Result<(MultiLocation, InteriorMultiLocation), XcmError> {
|
||||
let reanchor_context = Config::UniversalLocation::get();
|
||||
let location = location
|
||||
.reanchored(&destination, reanchor_context)
|
||||
.map_err(|_| XcmError::ReanchorFailed)?;
|
||||
Ok((location, reanchor_context))
|
||||
}
|
||||
|
||||
/// NOTE: Any assets which were unable to be reanchored are introduced into `failed_bin`.
|
||||
fn reanchored(
|
||||
mut assets: Assets,
|
||||
|
||||
@@ -272,7 +272,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remote_locking() {
|
||||
fn remote_locking_and_unlocking() {
|
||||
MockNet::reset();
|
||||
|
||||
let locked_amount = 100;
|
||||
@@ -280,7 +280,7 @@ mod tests {
|
||||
ParaB::execute_with(|| {
|
||||
let message = Xcm(vec![LockAsset {
|
||||
asset: (Here, locked_amount).into(),
|
||||
unlocker: (Parachain(1),).into(),
|
||||
unlocker: Parachain(1).into(),
|
||||
}]);
|
||||
assert_ok!(ParachainPalletXcm::send_xcm(Here, Parent, message.clone()));
|
||||
});
|
||||
@@ -306,6 +306,28 @@ mod tests {
|
||||
}])]
|
||||
);
|
||||
});
|
||||
|
||||
ParaB::execute_with(|| {
|
||||
// Request unlocking part of the funds on the relay chain
|
||||
let message = Xcm(vec![RequestUnlock {
|
||||
asset: (Parent, locked_amount - 50).into(),
|
||||
locker: Parent.into(),
|
||||
}]);
|
||||
assert_ok!(ParachainPalletXcm::send_xcm(Here, (Parent, Parachain(1)), message));
|
||||
});
|
||||
|
||||
Relay::execute_with(|| {
|
||||
use pallet_balances::{BalanceLock, Reasons};
|
||||
// Lock is reduced
|
||||
assert_eq!(
|
||||
relay_chain::Balances::locks(&child_account_id(2)),
|
||||
vec![BalanceLock {
|
||||
id: *b"py/xcmlk",
|
||||
amount: locked_amount - 50,
|
||||
reasons: Reasons::All
|
||||
}]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Scenario:
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
//! Parachain runtime mock.
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use core::marker::PhantomData;
|
||||
use frame_support::{
|
||||
construct_runtime, parameter_types,
|
||||
traits::{EnsureOrigin, EnsureOriginWithArg, Everything, EverythingBut, Nothing},
|
||||
traits::{ContainsPair, EnsureOrigin, EnsureOriginWithArg, Everything, EverythingBut, Nothing},
|
||||
weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight},
|
||||
};
|
||||
|
||||
@@ -27,7 +28,7 @@ use frame_system::EnsureRoot;
|
||||
use sp_core::{ConstU32, H256};
|
||||
use sp_runtime::{
|
||||
testing::Header,
|
||||
traits::{Hash, IdentityLookup},
|
||||
traits::{Get, Hash, IdentityLookup},
|
||||
AccountId32,
|
||||
};
|
||||
use sp_std::prelude::*;
|
||||
@@ -238,7 +239,7 @@ impl Config for XcmConfig {
|
||||
type Trader = FixedRateOfFungible<KsmPerSecondPerByte, ()>;
|
||||
type ResponseHandler = ();
|
||||
type AssetTrap = ();
|
||||
type AssetLocker = ();
|
||||
type AssetLocker = PolkadotXcm;
|
||||
type AssetExchanger = ();
|
||||
type AssetClaims = ();
|
||||
type SubscriptionService = ();
|
||||
@@ -325,7 +326,7 @@ pub mod mock_msg_queue {
|
||||
Ok(xcm) => {
|
||||
let location = (Parent, Parachain(sender.into()));
|
||||
match T::XcmExecutor::execute_xcm(location, xcm, message_hash, max_weight) {
|
||||
Outcome::Error(e) => (Err(e.clone()), Event::Fail(Some(hash), e)),
|
||||
Outcome::Error(e) => (Err(e), Event::Fail(Some(hash), e)),
|
||||
Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))),
|
||||
// As far as the caller is concerned, this was dispatched without error, so
|
||||
// we just report the weight used.
|
||||
@@ -349,7 +350,7 @@ pub mod mock_msg_queue {
|
||||
let _ = XcmpMessageFormat::decode(&mut data_ref)
|
||||
.expect("Simulator encodes with versioned xcm format; qed");
|
||||
|
||||
let mut remaining_fragments = &data_ref[..];
|
||||
let mut remaining_fragments = data_ref;
|
||||
while !remaining_fragments.is_empty() {
|
||||
if let Ok(xcm) =
|
||||
VersionedXcm::<T::RuntimeCall>::decode(&mut remaining_fragments)
|
||||
@@ -403,6 +404,22 @@ parameter_types! {
|
||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
||||
}
|
||||
|
||||
pub struct TrustedLockerCase<T>(PhantomData<T>);
|
||||
impl<T: Get<(MultiLocation, MultiAssetFilter)>> ContainsPair<MultiLocation, MultiAsset>
|
||||
for TrustedLockerCase<T>
|
||||
{
|
||||
fn contains(origin: &MultiLocation, asset: &MultiAsset) -> bool {
|
||||
let (o, a) = T::get();
|
||||
a.matches(asset) && &o == origin
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub RelayTokenForRelay: (MultiLocation, MultiAssetFilter) = (Parent.into(), Wild(AllOf { id: Concrete(Parent.into()), fun: WildFungible }));
|
||||
}
|
||||
|
||||
pub type TrustedLockers = TrustedLockerCase<RelayTokenForRelay>;
|
||||
|
||||
impl pallet_xcm::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||
@@ -420,7 +437,7 @@ impl pallet_xcm::Config for Runtime {
|
||||
type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
|
||||
type Currency = Balances;
|
||||
type CurrencyMatcher = ();
|
||||
type TrustedLockers = ();
|
||||
type TrustedLockers = TrustedLockers;
|
||||
type SovereignAccountOf = LocationToAccountId;
|
||||
type MaxLockers = ConstU32<8>;
|
||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||
|
||||
Reference in New Issue
Block a user