Skip to main content

pop_chains/registry/
system.rs

1// SPDX-License-Identifier: GPL-3.0
2
3use super::{traits::Requires, *};
4use crate::{
5	Error,
6	traits::{Args, Binary},
7};
8use pop_common::{
9	polkadot_sdk::sort_by_latest_stable_version,
10	sourcing::{ArchiveFileSpec, GitHub::ReleaseArchive, Source, traits::Source as SourceT},
11	target,
12};
13
14/// A chain containing core Polkadot protocol features.
15///
16/// See <https://docs.polkadot.com/polkadot-protocol/architecture/system-chains/overview/> for more details.
17#[derive(Clone)]
18pub(crate) struct System;
19
20impl SourceT for System {
21	type Error = Error;
22	fn source(&self) -> Result<Source, Error> {
23		// Source from GitHub release asset
24		let binary = self.binary();
25		Ok(Source::GitHub(ReleaseArchive {
26			owner: "r0gue-io".into(),
27			repository: "polkadot".into(),
28			tag: None,
29			tag_pattern: Some("polkadot-{version}".into()),
30			prerelease: false,
31			version_comparator: sort_by_latest_stable_version,
32			fallback: "stable2512".into(),
33			archive: format!("{binary}-{}.tar.gz", target()?),
34			contents: vec![ArchiveFileSpec::new(binary.into(), None, true)],
35			latest: None,
36		}))
37	}
38}
39
40impl Binary for System {
41	fn binary(&self) -> &'static str {
42		"polkadot-parachain"
43	}
44}
45
46impl Args for System {
47	fn args(&self) -> Option<Vec<&str>> {
48		Some(vec!["-lxcm=trace"])
49	}
50}
51
52// Macro for reducing boilerplate code.
53macro_rules! impl_system_chain {
54	($name:ident) => {
55		impl_chain!($name);
56		impl Requires for $name {}
57
58		impl SourceT for $name {
59			type Error = Error;
60			fn source(&self) -> Result<Source, Error> {
61				SourceT::source(&System)
62			}
63		}
64
65		impl Binary for $name {
66			fn binary(&self) -> &'static str {
67				"polkadot-parachain"
68			}
69		}
70
71		impl Args for $name {
72			fn args(&self) -> Option<Vec<&str>> {
73				System.args()
74			}
75		}
76
77		impl GenesisOverrides for $name {}
78	};
79}
80
81/// The Asset Hub enables the management of fungible and non-fungible assets across the network.
82///
83/// See <https://docs.polkadot.com/polkadot-protocol/architecture/system-chains/asset-hub/> for more details.
84#[derive(Clone, Debug, PartialEq)]
85pub struct AssetHub(pub(super) Chain);
86impl AssetHub {
87	/// A new instance of the Asset Hub.
88	///
89	/// # Arguments
90	/// * `id` - The chain identifier.
91	/// * `relay` - The relay chain.
92	pub fn new(id: Id, relay: Relay) -> Self {
93		Self(Chain::new("asset-hub", id, format!("asset-hub-{}", relay.chain())))
94	}
95}
96impl_system_chain!(AssetHub);
97
98/// The Bridge Hub facilitates trustless interactions between Polkadot, Kusama, Ethereum, and
99/// other blockchain ecosystems.
100///
101/// See <https://docs.polkadot.com/polkadot-protocol/architecture/system-chains/bridge-hub/> for more details.
102#[derive(Clone)]
103pub struct BridgeHub(Chain);
104impl BridgeHub {
105	/// A new instance of the Bridge Hub.
106	///
107	/// # Arguments
108	/// * `id` - The chain identifier.
109	/// * `relay` - The relay chain.
110	pub fn new(id: Id, relay: Relay) -> Self {
111		Self(Chain::new("bridge-hub", id, format!("bridge-hub-{}", relay.chain())))
112	}
113}
114impl_system_chain!(BridgeHub);
115
116/// The Collectives chain operates as a dedicated chain exclusive to the Polkadot network.
117/// This specialized infrastructure provides a foundation for various on-chain governance groups
118/// essential to Polkadot's ecosystem.
119///
120/// See <https://docs.polkadot.com/polkadot-protocol/architecture/system-chains/collectives/> for more details.
121#[derive(Clone)]
122pub struct Collectives(Chain);
123impl Collectives {
124	/// A new instance of the Collectives chain.
125	///
126	/// # Arguments
127	/// * `id` - The chain identifier.
128	/// * `relay` - The relay chain.
129	pub fn new(id: Id, relay: Relay) -> Self {
130		Self(Chain::new("collectives", id, format!("collectives-{}", relay.chain())))
131	}
132}
133impl_system_chain!(Collectives);
134
135/// The Coretime system chain facilitates the allocation, procurement, sale, and scheduling of
136/// bulk coretime, enabling tasks (such as chains) to utilize the computation and security
137/// provided by Polkadot.
138///
139/// See <https://docs.polkadot.com/polkadot-protocol/architecture/system-chains/coretime/> for more details.
140#[derive(Clone)]
141pub struct Coretime(Chain);
142impl Coretime {
143	/// A new instance of the Coretime chain.
144	///
145	/// # Arguments
146	/// * `id` - The chain identifier.
147	/// * `relay` - The relay chain.
148	pub fn new(id: Id, relay: Relay) -> Self {
149		Self(Chain::new("coretime", id, format!("coretime-{}", relay.chain())))
150	}
151}
152impl_system_chain!(Coretime);
153
154/// The People system chain is a specialized chain within the Polkadot ecosystem dedicated
155/// to secure, decentralized identity management.
156///
157/// See <https://docs.polkadot.com/polkadot-protocol/architecture/system-chains/people/> for more details.
158#[derive(Clone)]
159pub struct People(Chain);
160impl People {
161	/// A new instance of the People chain.
162	///
163	/// # Arguments
164	/// * `id` - The chain identifier.
165	/// * `relay` - The relay chain.
166	pub fn new(id: Id, relay: Relay) -> Self {
167		Self(Chain::new("people", id, format!("people-{}", relay.chain())))
168	}
169}
170impl_system_chain!(People);
171
172/// The PassetHub system chain is a temporary chain within the Polkadot ecosystem dedicated
173/// to deploy smart contracts..
174///
175/// See <https://docs.polkadot.com/polkadot-protocol/smart-contract-basics/networks/#passet-hub> for more details.
176#[derive(Clone)]
177pub struct PassetHub(Chain);
178impl PassetHub {
179	/// A new instance of the PassetHub chain.
180	///
181	/// # Arguments
182	/// * `id` - The chain identifier.
183	/// * `relay` - The relay chain.
184	pub fn new(id: Id, relay: Relay) -> Self {
185		Self(Chain::new("passet-hub", id, format!("passet-hub-{}", relay.chain())))
186	}
187}
188impl_system_chain!(PassetHub);
189
190#[cfg(test)]
191mod tests {
192	use super::*;
193	use pop_common::SortedSlice;
194	use std::ptr::fn_addr_eq;
195
196	#[test]
197	fn source_works() {
198		let system = System;
199		assert!(matches!(
200			system.source().unwrap(),
201			Source::GitHub(ReleaseArchive { owner, repository, tag, tag_pattern, prerelease, version_comparator, fallback, archive, contents, latest })
202				if owner == "r0gue-io" &&
203					repository == "polkadot" &&
204					tag.is_none() &&
205					tag_pattern == Some("polkadot-{version}".into()) &&
206					!prerelease &&
207					fn_addr_eq(version_comparator, sort_by_latest_stable_version as for<'a> fn(&'a mut [String]) -> SortedSlice<'a, String>) &&
208					fallback == "stable2512" &&
209					archive == format!("polkadot-parachain-{}.tar.gz", target().unwrap()) &&
210					contents == vec![ArchiveFileSpec::new("polkadot-parachain".into(), None, true)] &&
211					latest.is_none()
212		));
213	}
214
215	#[test]
216	fn binary_works() {
217		assert_eq!(System.binary(), "polkadot-parachain");
218	}
219
220	#[test]
221	fn args_works() {
222		assert_eq!(System.args().unwrap(), vec!["-lxcm=trace",]);
223	}
224
225	#[test]
226	fn asset_hub_works() {
227		let asset_hub = AssetHub::new(1_000, Relay::Paseo);
228		assert_eq!(asset_hub.args(), System.args());
229		assert_eq!(asset_hub.binary(), "polkadot-parachain");
230		assert_eq!(asset_hub.chain(), "asset-hub-paseo-local");
231		assert!(asset_hub.genesis_overrides().is_none());
232		assert_eq!(asset_hub.name(), "asset-hub");
233		assert_eq!(asset_hub.source().unwrap(), System.source().unwrap());
234	}
235
236	#[test]
237	fn bridge_hub_works() {
238		let bridge_hub = BridgeHub::new(1_002, Relay::Paseo);
239		assert_eq!(bridge_hub.args(), System.args());
240		assert_eq!(bridge_hub.binary(), "polkadot-parachain");
241		assert_eq!(bridge_hub.chain(), "bridge-hub-paseo-local");
242		assert!(bridge_hub.genesis_overrides().is_none());
243		assert_eq!(bridge_hub.name(), "bridge-hub");
244		assert_eq!(bridge_hub.source().unwrap(), System.source().unwrap());
245	}
246
247	#[test]
248	fn collectives_works() {
249		let collectives = Collectives::new(1_001, Relay::Paseo);
250		assert_eq!(collectives.args(), System.args());
251		assert_eq!(collectives.binary(), "polkadot-parachain");
252		assert_eq!(collectives.chain(), "collectives-paseo-local");
253		assert!(collectives.genesis_overrides().is_none());
254		assert_eq!(collectives.name(), "collectives");
255		assert_eq!(collectives.source().unwrap(), System.source().unwrap());
256	}
257
258	#[test]
259	fn coretime_works() {
260		let coretime = Coretime::new(1_001, Relay::Paseo);
261		assert_eq!(coretime.args(), System.args());
262		assert_eq!(coretime.binary(), "polkadot-parachain");
263		assert_eq!(coretime.chain(), "coretime-paseo-local");
264		assert!(coretime.genesis_overrides().is_none());
265		assert_eq!(coretime.name(), "coretime");
266		assert_eq!(coretime.source().unwrap(), System.source().unwrap());
267	}
268
269	#[test]
270	fn people_works() {
271		let people = People::new(1_001, Relay::Paseo);
272		assert_eq!(people.args(), System.args());
273		assert_eq!(people.binary(), "polkadot-parachain");
274		assert_eq!(people.chain(), "people-paseo-local");
275		assert!(people.genesis_overrides().is_none());
276		assert_eq!(people.name(), "people");
277		assert_eq!(people.source().unwrap(), System.source().unwrap());
278	}
279
280	#[test]
281	fn passet_hub_works() {
282		let passethub = PassetHub::new(1_111, Relay::Paseo);
283		assert_eq!(passethub.args(), System.args());
284		assert_eq!(passethub.binary(), "polkadot-parachain");
285		assert_eq!(passethub.chain(), "passet-hub-paseo-local");
286		assert!(passethub.genesis_overrides().is_none());
287		assert_eq!(passethub.name(), "passet-hub");
288		assert_eq!(passethub.source().unwrap(), System.source().unwrap());
289	}
290}