From 77ef85b04deca5ec3dabbbef507903578be7db19 Mon Sep 17 00:00:00 2001
From: Branislav Kontur <bkontur@gmail.com>
Date: Mon, 3 Jul 2023 15:03:47 +0200
Subject: [PATCH] [xcm] BridgeBlobDispatcher - prepend bridge instance
 discriminator. (#7438)

---
 .../src/tests/bridging/local_para_para.rs     |  2 +-
 .../src/tests/bridging/local_relay_relay.rs   |  2 +-
 .../tests/bridging/paid_remote_relay_relay.rs |  2 +-
 .../src/tests/bridging/remote_para_para.rs    |  5 +++--
 .../bridging/remote_para_para_via_relay.rs    |  5 +++--
 .../src/tests/bridging/remote_relay_relay.rs  |  2 +-
 .../xcm/xcm-builder/src/universal_exports.rs  | 21 +++++++++++++++----
 7 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs
index 77248e72ed1..406843a0fe8 100644
--- a/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs
+++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_para_para.rs
@@ -25,7 +25,7 @@ parameter_types! {
 	pub RemoteUniversalLocation: Junctions = X2(GlobalConsensus(Remote::get()), Parachain(1));
 }
 type TheBridge =
-	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteUniversalLocation>>;
+	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteUniversalLocation, ()>>;
 type Router =
 	TestTopic<UnpaidLocalExporter<HaulBlobExporter<TheBridge, Remote, Price>, UniversalLocation>>;
 
diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs
index ff2b714718e..02c454bb212 100644
--- a/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs
+++ b/polkadot/xcm/xcm-builder/src/tests/bridging/local_relay_relay.rs
@@ -25,7 +25,7 @@ parameter_types! {
 	pub RemoteUniversalLocation: Junctions = X1(GlobalConsensus(Remote::get()));
 }
 type TheBridge =
-	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteUniversalLocation>>;
+	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteUniversalLocation, ()>>;
 type Router =
 	TestTopic<UnpaidLocalExporter<HaulBlobExporter<TheBridge, Remote, Price>, UniversalLocation>>;
 
diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs
index 5472a3bd541..2f9bfcc2d80 100644
--- a/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs
+++ b/polkadot/xcm/xcm-builder/src/tests/bridging/paid_remote_relay_relay.rs
@@ -33,7 +33,7 @@ parameter_types! {
 	//     x (10 + 10) weight each).
 }
 type TheBridge =
-	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteUniversalLocation>>;
+	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteUniversalLocation, ()>>;
 type RelayExporter = HaulBlobExporter<TheBridge, Remote, Price>;
 type LocalInnerRouter = ExecutingRouter<UniversalLocation, RelayUniversalLocation, RelayExporter>;
 type LocalBridgeRouter = SovereignPaidRemoteExporter<
diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs
index b760e6829e9..124a909bc07 100644
--- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs
+++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para.rs
@@ -27,8 +27,9 @@ parameter_types! {
 	pub BridgeTable: Vec<(NetworkId, MultiLocation, Option<MultiAsset>)>
 		= vec![(Remote::get(), (Parent, Parachain(1)).into(), None)];
 }
-type TheBridge =
-	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteParaBridgeUniversalLocation>>;
+type TheBridge = TestBridge<
+	BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteParaBridgeUniversalLocation, ()>,
+>;
 type RelayExporter = HaulBlobExporter<TheBridge, Remote, ()>;
 type LocalInnerRouter =
 	UnpaidExecutingRouter<UniversalLocation, ParaBridgeUniversalLocation, RelayExporter>;
diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs
index 9dc94e27e9a..2ff1f9fb976 100644
--- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs
+++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_para_para_via_relay.rs
@@ -27,8 +27,9 @@ parameter_types! {
 	pub BridgeTable: Vec<(NetworkId, MultiLocation, Option<MultiAsset>)>
 		= vec![(Remote::get(), Parachain(1).into(), None)];
 }
-type TheBridge =
-	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteParaBridgeUniversalLocation>>;
+type TheBridge = TestBridge<
+	BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteParaBridgeUniversalLocation, ()>,
+>;
 type RelayExporter = HaulBlobExporter<TheBridge, Remote, ()>;
 type LocalInnerRouter =
 	UnpaidExecutingRouter<UniversalLocation, ParaBridgeUniversalLocation, RelayExporter>;
diff --git a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs
index 2b34c93c075..cdd6b89b7b1 100644
--- a/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs
+++ b/polkadot/xcm/xcm-builder/src/tests/bridging/remote_relay_relay.rs
@@ -28,7 +28,7 @@ parameter_types! {
 		= vec![(Remote::get(), MultiLocation::parent(), None)];
 }
 type TheBridge =
-	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteUniversalLocation>>;
+	TestBridge<BridgeBlobDispatcher<TestRemoteIncomingRouter, RemoteUniversalLocation, ()>>;
 type RelayExporter = HaulBlobExporter<TheBridge, Remote, ()>;
 type LocalInnerRouter =
 	UnpaidExecutingRouter<UniversalLocation, RelayUniversalLocation, RelayExporter>;
diff --git a/polkadot/xcm/xcm-builder/src/universal_exports.rs b/polkadot/xcm/xcm-builder/src/universal_exports.rs
index 38795042d00..9a65ec7dfe4 100644
--- a/polkadot/xcm/xcm-builder/src/universal_exports.rs
+++ b/polkadot/xcm/xcm-builder/src/universal_exports.rs
@@ -332,9 +332,14 @@ pub enum DispatchBlobError {
 	WrongGlobal,
 }
 
-pub struct BridgeBlobDispatcher<Router, OurPlace>(PhantomData<(Router, OurPlace)>);
-impl<Router: SendXcm, OurPlace: Get<InteriorMultiLocation>> DispatchBlob
-	for BridgeBlobDispatcher<Router, OurPlace>
+pub struct BridgeBlobDispatcher<Router, OurPlace, OurPlaceBridgeInstance>(
+	PhantomData<(Router, OurPlace, OurPlaceBridgeInstance)>,
+);
+impl<
+		Router: SendXcm,
+		OurPlace: Get<InteriorMultiLocation>,
+		OurPlaceBridgeInstance: Get<Option<InteriorMultiLocation>>,
+	> DispatchBlob for BridgeBlobDispatcher<Router, OurPlace, OurPlaceBridgeInstance>
 {
 	fn dispatch_blob(blob: Vec<u8>) -> Result<(), DispatchBlobError> {
 		let our_universal = OurPlace::get();
@@ -352,8 +357,16 @@ impl<Router: SendXcm, OurPlace: Get<InteriorMultiLocation>> DispatchBlob
 			.map_err(|()| DispatchBlobError::NonUniversalDestination)?;
 		ensure!(intended_global == our_global, DispatchBlobError::WrongGlobal);
 		let dest = universal_dest.relative_to(&our_universal);
-		let message: Xcm<()> =
+		let mut message: Xcm<()> =
 			message.try_into().map_err(|_| DispatchBlobError::UnsupportedXcmVersion)?;
+
+		// Prepend our bridge instance discriminator.
+		// Can be used for fine-grained control of origin on destination in case of multiple bridge instances,
+		// e.g. restrict `type UniversalAliases` and `UniversalOrigin` instruction to trust just particular bridge instance for `NetworkId`.
+		if let Some(bridge_instance) = OurPlaceBridgeInstance::get() {
+			message.0.insert(0, DescendOrigin(bridge_instance));
+		}
+
 		let _ = send_xcm::<Router>(dest, message).map_err(|_| DispatchBlobError::RoutingError)?;
 		Ok(())
 	}
-- 
GitLab