1use super::{Binary, Relay, chain_specs::chain_spec_generator};
4use crate::{Error, registry, registry::System, traits::Binary as BinaryT};
5use pop_common::sourcing::{filters::prefix, traits::*};
6use std::path::Path;
7
8pub(super) async fn system(
19 id: u32,
20 command: &str,
21 version: Option<&str>,
22 runtime_version: Option<&str>,
23 relay_chain_version: &str,
24 chain: Option<&str>,
25 cache: &Path,
26) -> Result<Option<super::Chain>, Error> {
27 let para = &System;
28 let name = para.binary().to_string();
29 if command != name {
30 return Ok(None);
31 }
32 let source = para
34 .source()?
35 .resolve(&name, version.or(Some(relay_chain_version)), cache, |f| prefix(f, &name))
36 .await
37 .into();
38 let binary = Binary::Source { name, source, cache: cache.to_path_buf() };
39 let chain_spec_generator = match chain {
40 Some(chain) => chain_spec_generator(chain, runtime_version, cache).await?,
41 None => None,
42 };
43 Ok(Some(super::Chain { id, binary, chain: chain.map(|c| c.to_string()), chain_spec_generator }))
44}
45
46pub(super) async fn from(
55 relay: &Relay,
56 id: u32,
57 command: &str,
58 version: Option<&str>,
59 chain: Option<&str>,
60 cache: &Path,
61) -> Result<Option<super::Chain>, Error> {
62 if let Some(para) = registry::chains(relay).iter().find(|p| p.binary() == command) {
63 let name = para.binary().to_string();
64 let source =
65 para.source()?.resolve(&name, version, cache, |f| prefix(f, &name)).await.into();
66 let binary = Binary::Source { name, source, cache: cache.to_path_buf() };
67 return Ok(Some(super::Chain {
68 id,
69 binary,
70 chain: chain.map(|c| c.to_string()),
71 chain_spec_generator: None,
72 }));
73 }
74 Ok(None)
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use crate::up::tests::{FALLBACK, RELAY_BINARY_VERSION, SYSTEM_PARA_BINARY_VERSION};
81 use pop_common::{
82 polkadot_sdk::{sort_by_latest_semantic_version, sort_by_latest_stable_version},
83 sourcing::{ArchiveFileSpec, GitHub::ReleaseArchive, Source},
84 target,
85 };
86 use std::path::PathBuf;
87 use tempfile::tempdir;
88
89 #[tokio::test]
90 async fn system_matches_command() -> anyhow::Result<()> {
91 assert!(
92 system(
93 1000,
94 "polkadot",
95 None,
96 None,
97 RELAY_BINARY_VERSION,
98 Some("asset-hub-paseo-local"),
99 tempdir()?.path()
100 )
101 .await?
102 .is_none()
103 );
104 Ok(())
105 }
106
107 #[tokio::test]
108 async fn system_using_relay_version() -> anyhow::Result<()> {
109 let expected = &System;
110 let para_id = 1000;
111
112 let temp_dir = tempdir()?;
113 let parachain = system(
114 para_id,
115 expected.binary(),
116 None,
117 None,
118 RELAY_BINARY_VERSION,
119 None,
120 temp_dir.path(),
121 )
122 .await?
123 .unwrap();
124 assert_eq!(para_id, parachain.id);
125 assert!(matches!(parachain.binary, Binary::Source { name, source, cache }
126 if name == expected.binary() && source == Source::GitHub(ReleaseArchive {
127 owner: "r0gue-io".to_string(),
128 repository: "polkadot".to_string(),
129 tag: Some(format!("polkadot-{RELAY_BINARY_VERSION}")),
130 tag_pattern: Some("polkadot-{version}".into()),
131 prerelease: false,
132 version_comparator: sort_by_latest_stable_version,
133 fallback: FALLBACK.into(),
134 archive: format!("{name}-{}.tar.gz", target()?),
135 contents: vec![ArchiveFileSpec::new(expected.binary().into(), None, true)],
136 latest: parachain.binary.latest().map(|l| l.to_string()),
137 }).into() && cache == temp_dir.path()
138 ));
139 Ok(())
140 }
141
142 #[tokio::test]
143 async fn system_works() -> anyhow::Result<()> {
144 let expected = &System;
145 let para_id = 1000;
146
147 let temp_dir = tempdir()?;
148 let parachain = system(
149 para_id,
150 expected.binary(),
151 Some(SYSTEM_PARA_BINARY_VERSION),
152 None,
153 RELAY_BINARY_VERSION,
154 None,
155 temp_dir.path(),
156 )
157 .await?
158 .unwrap();
159 assert_eq!(para_id, parachain.id);
160 assert!(matches!(parachain.binary, Binary::Source { name, source, cache }
161 if name == expected.binary() && source == Source::GitHub(ReleaseArchive {
162 owner: "r0gue-io".to_string(),
163 repository: "polkadot".to_string(),
164 tag: Some(format!("polkadot-{SYSTEM_PARA_BINARY_VERSION}")),
165 tag_pattern: Some("polkadot-{version}".into()),
166 prerelease: false,
167 version_comparator: sort_by_latest_stable_version,
168 fallback: FALLBACK.into(),
169 archive: format!("{name}-{}.tar.gz", target()?),
170 contents: vec![ArchiveFileSpec::new(expected.binary().into(), None, true)],
171 latest: parachain.binary.latest().map(|l| l.to_string()),
172 }).into() && cache == temp_dir.path()
173 ));
174 Ok(())
175 }
176
177 #[tokio::test]
178 async fn system_with_chain_spec_generator_works() -> anyhow::Result<()> {
179 let expected = System;
180 let runtime_version = "v1.3.3";
181 let para_id = 1000;
182
183 let temp_dir = tempdir()?;
184 let parachain = system(
185 para_id,
186 expected.binary(),
187 None,
188 Some(runtime_version),
189 RELAY_BINARY_VERSION,
190 Some("asset-hub-paseo-local"),
191 temp_dir.path(),
192 )
193 .await?
194 .unwrap();
195 assert_eq!(parachain.id, para_id);
196 assert_eq!(parachain.chain.unwrap(), "asset-hub-paseo-local");
197 let chain_spec_generator = parachain.chain_spec_generator.unwrap();
198 assert!(matches!(chain_spec_generator, Binary::Source { name, source, cache }
199 if name == "paseo-chain-spec-generator" && source == Source::GitHub(ReleaseArchive {
200 owner: "r0gue-io".to_string(),
201 repository: "paseo-runtimes".to_string(),
202 tag: Some(runtime_version.to_string()),
203 tag_pattern: None,
204 prerelease: false,
205 version_comparator: sort_by_latest_semantic_version,
206 fallback: "v1.4.1".into(),
207 archive: format!("chain-spec-generator-{}.tar.gz", target()?),
208 contents: [ArchiveFileSpec::new("chain-spec-generator".into(), Some("paseo-chain-spec-generator".into()), true)].to_vec(),
209 latest: chain_spec_generator.latest().map(|l| l.to_string()),
210 }).into() && cache == temp_dir.path()
211 ));
212 Ok(())
213 }
214
215 #[tokio::test]
216 async fn pop_works() -> anyhow::Result<()> {
217 let version = "v0.3.0";
218 let expected = "pop-node";
219 let para_id = 2000;
220
221 let temp_dir = tempdir()?;
222 let parachain =
223 from(&Relay::Paseo, para_id, expected, Some(version), None, temp_dir.path())
224 .await?
225 .unwrap();
226 assert_eq!(para_id, parachain.id);
227 assert!(matches!(parachain.binary, Binary::Source { name, source, cache }
228 if name == expected && source == Source::GitHub(ReleaseArchive {
229 owner: "r0gue-io".to_string(),
230 repository: "pop-node".to_string(),
231 tag: Some(format!("node-{version}")),
232 tag_pattern: Some("node-{version}".into()),
233 prerelease: false,
234 version_comparator: sort_by_latest_semantic_version,
235 fallback: "v0.3.0".into(),
236 archive: format!("{name}-{}.tar.gz", target()?),
237 contents: vec![ArchiveFileSpec::new(expected.into(), None, true)],
238 latest: parachain.binary.latest().map(|l| l.to_string()),
239 }).into() && cache == temp_dir.path()
240 ));
241 Ok(())
242 }
243
244 #[tokio::test]
245 async fn from_handles_unsupported_command() -> anyhow::Result<()> {
246 assert!(
247 from(&Relay::Paseo, 2000, "none", None, None, &PathBuf::default())
248 .await?
249 .is_none()
250 );
251 Ok(())
252 }
253}