Skip to main content

pop_chains/registry/
pop.rs

1// SPDX-License-Identifier: GPL-3.0
2
3use super::{traits::Requires, *};
4use crate::{
5	Error, accounts,
6	traits::{Args, Binary},
7};
8use pop_common::{
9	polkadot_sdk::sort_by_latest_semantic_version,
10	sourcing::{ArchiveFileSpec, GitHub::ReleaseArchive, Source, traits::Source as SourceT},
11	target,
12};
13use serde_json::{Map, Value, json};
14use sp_core::crypto::Ss58Codec;
15use std::collections::HashMap;
16
17/// Pop Network makes it easy for smart contract developers to use the power of Polkadot.
18#[derive(Clone)]
19pub struct Pop(Chain);
20impl Pop {
21	/// A new instance of Pop.
22	///
23	/// # Arguments
24	/// * `id` - The chain identifier.
25	/// * `chain` - The identifier of the chain, as used by the chain specification.
26	pub fn new(id: Id, chain: impl Into<String>) -> Self {
27		Self(Chain::new("pop", id, chain))
28	}
29}
30
31impl SourceT for Pop {
32	type Error = Error;
33	/// Defines the source of a binary.
34	fn source(&self) -> Result<Source, Error> {
35		// Source from GitHub release asset
36		let binary = self.binary();
37		Ok(Source::GitHub(ReleaseArchive {
38			owner: "r0gue-io".into(),
39			repository: "pop-node".into(),
40			tag: None,
41			tag_pattern: Some("node-{version}".into()),
42			prerelease: false,
43			version_comparator: sort_by_latest_semantic_version,
44			fallback: "v0.3.0".into(),
45			archive: format!("{binary}-{}.tar.gz", target()?),
46			contents: vec![ArchiveFileSpec::new(binary.into(), None, true)],
47			latest: None,
48		}))
49	}
50}
51
52impl Binary for Pop {
53	fn binary(&self) -> &'static str {
54		"pop-node"
55	}
56}
57
58impl Requires for Pop {
59	/// Defines the requirements of a chain, namely which other chains it depends on and any
60	/// corresponding overrides to genesis state.
61	fn requires(&self) -> Option<HashMap<ChainTypeId, Override>> {
62		let id = self.id();
63		let amount: u128 = 1_200_000_000_000_000_000;
64
65		Some(HashMap::from([(
66			ChainTypeId::of::<AssetHub>(),
67			Box::new(move |genesis_overrides: &mut Map<String, Value>| {
68				let sovereign_account = accounts::sibl(id).to_ss58check();
69				let endowment = json!([sovereign_account, amount]);
70				// Add sovereign account endowment
71				genesis_overrides
72					.entry("balances")
73					.and_modify(|balances| {
74						let balances =
75							balances.as_object_mut().expect("expected balances as object");
76						match balances.get_mut("balances") {
77							None => {
78								balances.insert("balances".to_string(), json!([endowment]));
79							},
80							Some(balances) => {
81								let balances =
82									balances.as_array_mut().expect("expected balances as array");
83								balances.push(endowment.clone());
84							},
85						}
86					})
87					.or_insert(json!({"balances": [endowment]}));
88			}) as Override,
89		)]))
90	}
91}
92
93impl Args for Pop {
94	fn args(&self) -> Option<Vec<&str>> {
95		Some(vec![
96			"-lpop-api::extension=debug",
97			"-lruntime::contracts=trace",
98			"-lruntime::revive=trace",
99			"-lruntime::revive::strace=trace",
100			"-lxcm=trace",
101			"--enable-offchain-indexing=true",
102		])
103	}
104}
105
106impl GenesisOverrides for Pop {}
107
108impl_chain!(Pop);
109
110#[cfg(test)]
111mod tests {
112	use super::*;
113	use pop_common::SortedSlice;
114	use std::ptr::fn_addr_eq;
115
116	#[test]
117	fn source_works() {
118		let pop = Pop::new(3395, "pop");
119		assert!(matches!(
120			pop.source().unwrap(),
121			Source::GitHub(ReleaseArchive { owner, repository, tag, tag_pattern, prerelease, version_comparator, fallback, archive, contents, latest })
122				if owner == "r0gue-io" &&
123					repository == "pop-node" &&
124					tag.is_none() &&
125					tag_pattern == Some("node-{version}".into()) &&
126					!prerelease &&
127					fn_addr_eq(version_comparator, sort_by_latest_semantic_version as for<'a> fn(&'a mut [String]) -> SortedSlice<'a, String>) &&
128					fallback == "v0.3.0" &&
129					archive == format!("pop-node-{}.tar.gz", target().unwrap()) &&
130					contents == vec![ArchiveFileSpec::new("pop-node".into(), None, true)] &&
131					latest.is_none()
132		));
133	}
134
135	#[test]
136	fn binary_works() {
137		let pop = Pop::new(3395, "pop");
138		assert_eq!(pop.binary(), "pop-node");
139	}
140
141	#[test]
142	fn requires_asset_hub() {
143		let pop = Pop::new(3395, "pop");
144		let mut requires = pop.requires().unwrap();
145		let r#override = requires.get_mut(&ChainTypeId::of::<AssetHub>()).unwrap();
146		let expected = json!({
147			"balances": {
148				"balances": [["5Eg2fnsomjubNiqxnqSSeVwcmQYQzsHdyr79YhcJDKRYfPCL", 1200000000000000000u64]]
149		}});
150		// Empty
151		let mut overrides = Map::new();
152		r#override(&mut overrides);
153		assert_eq!(Value::Object(overrides), expected);
154		// Inserts
155		let mut overrides = Map::new();
156		overrides.insert("balances".to_string(), json!({}));
157		r#override(&mut overrides);
158		assert_eq!(Value::Object(overrides), expected);
159		// Updates
160		let mut overrides = Map::new();
161		overrides.insert("balances".to_string(), json!({ "balances": []}));
162		r#override(&mut overrides);
163		assert_eq!(Value::Object(overrides), expected);
164	}
165
166	#[test]
167	fn args_works() {
168		let pop = Pop::new(3395, "pop");
169		assert_eq!(
170			pop.args().unwrap(),
171			vec![
172				"-lpop-api::extension=debug",
173				"-lruntime::contracts=trace",
174				"-lruntime::revive=trace",
175				"-lruntime::revive::strace=trace",
176				"-lxcm=trace",
177				"--enable-offchain-indexing=true",
178			]
179		);
180	}
181}