// Copyright 2020 Parity Technologies (UK) Ltd. // This file is part of Polkadot. // Polkadot is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Polkadot is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . use sp_std::marker::PhantomData; use frame_support::traits::{Get, OriginTrait}; use xcm::v0::{MultiLocation, OriginKind, NetworkId, Junction}; use xcm_executor::traits::{LocationConversion, ConvertOrigin}; use polkadot_parachain::primitives::IsSystem; /// Sovereign accounts use the system's `Signed` origin with an account ID derived from the /// `LocationConverter`. pub struct SovereignSignedViaLocation( PhantomData<(LocationConverter, Origin)> ); impl< LocationConverter: LocationConversion, Origin: OriginTrait, > ConvertOrigin for SovereignSignedViaLocation { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { if let OriginKind::SovereignAccount = kind { let location = LocationConverter::from_location(&origin).ok_or(origin)?; Ok(Origin::signed(location).into()) } else { Err(origin) } } } pub struct ParentAsSuperuser(PhantomData); impl< Origin: OriginTrait, > ConvertOrigin for ParentAsSuperuser { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Superuser, MultiLocation::X1(Junction::Parent)) => Ok(Origin::root()), (_, origin) => Err(origin), } } } pub struct ChildSystemParachainAsSuperuser(PhantomData<(ParaId, Origin)>); impl< ParaId: IsSystem + From, Origin: OriginTrait, > ConvertOrigin for ChildSystemParachainAsSuperuser { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Superuser, MultiLocation::X1(Junction::Parachain { id })) if ParaId::from(id).is_system() => Ok(Origin::root()), (_, origin) => Err(origin), } } } pub struct SiblingSystemParachainAsSuperuser(PhantomData<(ParaId, Origin)>); impl< ParaId: IsSystem + From, Origin: OriginTrait > ConvertOrigin for SiblingSystemParachainAsSuperuser { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Superuser, MultiLocation::X2(Junction::Parent, Junction::Parachain { id })) if ParaId::from(id).is_system() => Ok(Origin::root()), (_, origin) => Err(origin), } } } pub struct ChildParachainAsNative( PhantomData<(ParachainOrigin, Origin)> ); impl< ParachainOrigin: From, Origin: From, > ConvertOrigin for ChildParachainAsNative { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Native, MultiLocation::X1(Junction::Parachain { id })) => Ok(Origin::from(ParachainOrigin::from(id))), (_, origin) => Err(origin), } } } pub struct SiblingParachainAsNative( PhantomData<(ParachainOrigin, Origin)> ); impl< ParachainOrigin: From, Origin: From, > ConvertOrigin for SiblingParachainAsNative { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Native, MultiLocation::X2(Junction::Parent, Junction::Parachain { id })) => Ok(Origin::from(ParachainOrigin::from(id))), (_, origin) => Err(origin), } } } // Our Relay-chain has a native origin given by the `Get`ter. pub struct RelayChainAsNative( PhantomData<(RelayOrigin, Origin)> ); impl< RelayOrigin: Get, Origin, > ConvertOrigin for RelayChainAsNative { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Native, MultiLocation::X1(Junction::Parent)) => Ok(RelayOrigin::get()), (_, origin) => Err(origin), } } } pub struct SignedAccountId32AsNative( PhantomData<(Network, Origin)> ); impl< Network: Get, Origin: OriginTrait, > ConvertOrigin for SignedAccountId32AsNative where Origin::AccountId: From<[u8; 32]>, { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Native, MultiLocation::X1(Junction::AccountId32 { id, network })) if matches!(network, NetworkId::Any) || network == Network::get() => Ok(Origin::signed(id.into())), (_, origin) => Err(origin), } } } pub struct SignedAccountKey20AsNative( PhantomData<(Network, Origin)> ); impl< Network: Get, Origin: OriginTrait > ConvertOrigin for SignedAccountKey20AsNative where Origin::AccountId: From<[u8; 20]>, { fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result { match (kind, origin) { (OriginKind::Native, MultiLocation::X1(Junction::AccountKey20 { key, network })) if matches!(network, NetworkId::Any) || network == Network::get() => { Ok(Origin::signed(key.into())) } (_, origin) => Err(origin), } } }