mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-01 04:31:02 +00:00
XCM revamp (#2836)
* Remove unused relaying XCM * Aggregate HRMP (XCMP/HMP) messages. Payloads for spambot. * Revert lock * Fix * Broken example * Introduce fee payment mechanics into XCM. * Weight limitations on XCM execution * Mock environment for tests and the first test * Tests for XCM and a few refactors. * Remove code that's not ready * Fix for an XCM and an additional test * Query response system * XCMP message dispatch system reimagining - Moved most of the logic into xcm-handler pallet - Altered the outgoing XCMP API from push to pull - Changed underlying outgoing queue data structures to avoid multi-page read/writes - Introduced queuing for incoming messages - Introduced signal messages as a flow-control sub-stream - Introduced flow-control with basic threshold back-pressure - Introduced overall weight limitation on messages executed - Additonal alterations to XCM APIs for the new system * Some build fixes * Remove the Encode bounds sprayed around * More faff * Fix bounds amek use latest scale codec. * remove println * fixes * Fix XcmExecutor Tests * Fix XCM bounds using derivative crate * Refactor names of XcmGeneric &c into Xcm * Repot the xcm-executor into xcm-builder * Docs * Docs * Fixes * Update xcm/src/lib.rs Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * Fixes * Docs * Update runtime/parachains/src/ump.rs Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * Docs * Fixes * Fixes * Fixes * Docs * Fixes * Fixes * Introduce transfer_asset specialisation. * Fixes * Fixes Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
@@ -14,70 +14,68 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use sp_std::marker::PhantomData;
|
||||
use sp_std::{marker::PhantomData, borrow::Borrow};
|
||||
use sp_io::hashing::blake2_256;
|
||||
use sp_runtime::traits::AccountIdConversion;
|
||||
use frame_support::traits::Get;
|
||||
use parity_scale_codec::Encode;
|
||||
use xcm::v0::{MultiLocation, NetworkId, Junction};
|
||||
use xcm_executor::traits::LocationConversion;
|
||||
use xcm_executor::traits::{InvertLocation, Convert};
|
||||
|
||||
pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
||||
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
AccountId: From<[u8; 32]> + Into<[u8; 32]>,
|
||||
> LocationConversion<AccountId> for Account32Hash<Network, AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
Some(("multiloc", location).using_encoded(blake2_256).into())
|
||||
AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone,
|
||||
> Convert<MultiLocation, AccountId> for Account32Hash<Network, AccountId> {
|
||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||
Ok(("multiloc", location.borrow()).using_encoded(blake2_256).into())
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
Err(who)
|
||||
fn reverse_ref(_: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ParentIsDefault<AccountId>(PhantomData<AccountId>);
|
||||
|
||||
impl<
|
||||
AccountId: Default + Eq,
|
||||
> LocationConversion<AccountId> for ParentIsDefault<AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
if let MultiLocation::X1(Junction::Parent) = location {
|
||||
Some(AccountId::default())
|
||||
AccountId: Default + Eq + Clone,
|
||||
> Convert<MultiLocation, AccountId> for ParentIsDefault<AccountId> {
|
||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||
if let &MultiLocation::X1(Junction::Parent) = location.borrow() {
|
||||
Ok(AccountId::default())
|
||||
} else {
|
||||
None
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
if who == AccountId::default() {
|
||||
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
||||
if who.borrow() == &AccountId::default() {
|
||||
Ok(Junction::Parent.into())
|
||||
} else {
|
||||
Err(who)
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChildParachainConvertsVia<ParaId, AccountId>(PhantomData<(ParaId, AccountId)>);
|
||||
|
||||
impl<
|
||||
ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>,
|
||||
AccountId,
|
||||
> LocationConversion<AccountId> for ChildParachainConvertsVia<ParaId, AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
if let MultiLocation::X1(Junction::Parachain { id }) = location {
|
||||
Some(ParaId::from(*id).into_account())
|
||||
AccountId: Clone,
|
||||
> Convert<MultiLocation, AccountId> for ChildParachainConvertsVia<ParaId, AccountId> {
|
||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||
if let &MultiLocation::X1(Junction::Parachain { id }) = location.borrow() {
|
||||
Ok(ParaId::from(id).into_account())
|
||||
} else {
|
||||
None
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
if let Some(id) = ParaId::try_from_account(&who) {
|
||||
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
||||
if let Some(id) = ParaId::try_from_account(who.borrow()) {
|
||||
Ok(Junction::Parachain { id: id.into() }.into())
|
||||
} else {
|
||||
Err(who)
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,65 +84,79 @@ pub struct SiblingParachainConvertsVia<ParaId, AccountId>(PhantomData<(ParaId, A
|
||||
|
||||
impl<
|
||||
ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>,
|
||||
AccountId,
|
||||
> LocationConversion<AccountId> for SiblingParachainConvertsVia<ParaId, AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
if let MultiLocation::X2(Junction::Parent, Junction::Parachain { id }) = location {
|
||||
Some(ParaId::from(*id).into_account())
|
||||
AccountId: Clone,
|
||||
> Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia<ParaId, AccountId> {
|
||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||
if let &MultiLocation::X2(Junction::Parent, Junction::Parachain { id }) = location.borrow() {
|
||||
Ok(ParaId::from(id).into_account())
|
||||
} else {
|
||||
None
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
if let Some(id) = ParaId::try_from_account(&who) {
|
||||
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
||||
if let Some(id) = ParaId::try_from_account(who.borrow()) {
|
||||
Ok([Junction::Parent, Junction::Parachain { id: id.into() }].into())
|
||||
} else {
|
||||
Err(who)
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AccountId32Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
||||
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
AccountId: From<[u8; 32]> + Into<[u8; 32]>,
|
||||
> LocationConversion<AccountId> for AccountId32Aliases<Network, AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
if let MultiLocation::X1(Junction::AccountId32 { id, network }) = location {
|
||||
if matches!(network, NetworkId::Any) || network == &Network::get() {
|
||||
return Some((*id).into())
|
||||
}
|
||||
}
|
||||
None
|
||||
AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone,
|
||||
> Convert<MultiLocation, AccountId> for AccountId32Aliases<Network, AccountId> {
|
||||
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
|
||||
let id = match location {
|
||||
MultiLocation::X1(Junction::AccountId32 { id, network: NetworkId::Any }) => id,
|
||||
MultiLocation::X1(Junction::AccountId32 { id, network }) if &network == &Network::get() => id,
|
||||
l => return Err(l),
|
||||
};
|
||||
Ok(id.into())
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
fn reverse(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
Ok(Junction::AccountId32 { id: who.into(), network: Network::get() }.into())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AccountKey20Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
||||
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
AccountId: From<[u8; 20]> + Into<[u8; 20]>
|
||||
> LocationConversion<AccountId> for AccountKey20Aliases<Network, AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
if let MultiLocation::X1(Junction::AccountKey20 { key, network }) = location {
|
||||
if matches!(network, NetworkId::Any) || network == &Network::get() {
|
||||
return Some((*key).into());
|
||||
}
|
||||
}
|
||||
None
|
||||
AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone,
|
||||
> Convert<MultiLocation, AccountId> for AccountKey20Aliases<Network, AccountId> {
|
||||
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
|
||||
let key = match location {
|
||||
MultiLocation::X1(Junction::AccountKey20 { key, network: NetworkId::Any }) => key,
|
||||
MultiLocation::X1(Junction::AccountKey20 { key, network }) if &network == &Network::get() => key,
|
||||
l => return Err(l),
|
||||
};
|
||||
Ok(key.into())
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
Ok(Junction::AccountKey20 {
|
||||
key: who.into(),
|
||||
network: Network::get(),
|
||||
}
|
||||
.into())
|
||||
fn reverse(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
let j = Junction::AccountKey20 { key: who.into(), network: Network::get() };
|
||||
Ok(j.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Simple location inverter; give it this location's ancestry and it'll figure out the inverted location.
|
||||
pub struct LocationInverter<Ancestry>(PhantomData<Ancestry>);
|
||||
impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry> {
|
||||
fn invert_location(location: &MultiLocation) -> MultiLocation {
|
||||
let mut ancestry = Ancestry::get();
|
||||
let mut result = location.clone();
|
||||
for (i, j) in location.iter_rev()
|
||||
.map(|j| match j {
|
||||
Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild),
|
||||
_ => Junction::Parent,
|
||||
})
|
||||
.enumerate()
|
||||
{
|
||||
*result.at_mut(i).expect("location and result begin equal; same size; qed") = j;
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user