Skip to main content

zebrad/components/zcashd_compat/
manifest.rs

1//! Embedded zcashd compatibility release manifest.
2//!
3//! [`zebrad/zcashd-compat-manifest.json`](../../../zcashd-compat-manifest.json) is the
4//! single source of truth for the zcashd compat pin: `make/zcashd-compat.mk` and
5//! `scripts/install-zebra.sh` read it with `jq`, and zebrad embeds it at compile
6//! time and parses it here.
7
8use std::sync::LazyLock;
9
10use serde::Deserialize;
11
12/// Embedded manifest schema version.
13pub const EMBEDDED_MANIFEST_SCHEMA_VERSION: u32 = 1;
14
15/// Embedded zcashd compatibility release manifest.
16#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
17#[serde(deny_unknown_fields)]
18pub struct ZcashdReleaseManifest {
19    /// Manifest schema version.
20    pub schema_version: u32,
21    /// Release tag from which artifacts were published.
22    pub release_tag: String,
23    /// Release artifacts by target triple.
24    pub artifacts: Vec<ZcashdReleaseArtifact>,
25}
26
27/// One released zcashd compatibility artifact.
28#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
29#[serde(deny_unknown_fields)]
30pub struct ZcashdReleaseArtifact {
31    /// Rust-style target triple.
32    pub target_triple: String,
33    /// Fully-qualified runtime archive URL.
34    pub runtime_archive_url: String,
35    /// SHA256 hex digest of the runtime archive.
36    pub runtime_archive_sha256: String,
37    /// Runtime archive member path that points to the `zcashd` executable.
38    pub runtime_archive_member_binary_path: String,
39}
40
41/// Embedded manifest used by managed zcashd downloads.
42pub static EMBEDDED_ZCASHD_RELEASE_MANIFEST: LazyLock<ZcashdReleaseManifest> =
43    LazyLock::new(|| {
44        let manifest: ZcashdReleaseManifest =
45            serde_json::from_str(include_str!("../../../zcashd-compat-manifest.json"))
46                .expect("committed zcashd-compat-manifest.json is validated by unit tests and CI");
47
48        assert_eq!(
49            manifest.schema_version, EMBEDDED_MANIFEST_SCHEMA_VERSION,
50            "unsupported zcashd-compat-manifest.json schema version"
51        );
52
53        manifest
54    });
55
56impl ZcashdReleaseManifest {
57    /// Returns the configured artifact for `target_triple`, if any.
58    pub fn artifact_for_target(&self, target_triple: &str) -> Option<&ZcashdReleaseArtifact> {
59        self.artifacts
60            .iter()
61            .find(|artifact| artifact.target_triple == target_triple)
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use std::collections::HashSet;
68
69    use super::EMBEDDED_ZCASHD_RELEASE_MANIFEST;
70
71    #[test]
72    fn embedded_manifest_targets_are_unique() {
73        let mut targets = HashSet::new();
74        for artifact in &EMBEDDED_ZCASHD_RELEASE_MANIFEST.artifacts {
75            assert!(
76                targets.insert(artifact.target_triple.as_str()),
77                "duplicate manifest target found: {}",
78                artifact.target_triple
79            );
80        }
81    }
82
83    #[test]
84    fn embedded_manifest_entries_are_well_formed() {
85        for artifact in &EMBEDDED_ZCASHD_RELEASE_MANIFEST.artifacts {
86            assert!(
87                artifact.runtime_archive_url.starts_with("https://"),
88                "managed zcashd artifact URL must be https: {}",
89                artifact.runtime_archive_url
90            );
91            assert_eq!(
92                artifact.runtime_archive_sha256.len(),
93                64,
94                "artifact SHA256 must be 64 hex chars for target {}",
95                artifact.target_triple
96            );
97            assert!(
98                artifact
99                    .runtime_archive_sha256
100                    .chars()
101                    .all(|c| c.is_ascii_hexdigit()),
102                "artifact SHA256 contains non-hex characters for target {}",
103                artifact.target_triple
104            );
105        }
106    }
107}