Skip to main content

choreo_content/
config.rs

1//! Hardcoded Coordination Platform endpoint + identity configuration.
2//!
3//! The Choreographr Coordination Platform is currently a single local
4//! deployment, so these are compile-time constants (per the design decision to
5//! "hardcode the endpoint + identity config" rather than read it from
6//! configuration). The three backends match the reference implementation
7//! (`acuity-dioxus`):
8//!
9//! - the Substrate node (`choreo-runtime`) at `ws://127.0.0.1:9944`
10//! - the event indexer (`acuity-index`, TOML schema `~/acuity-index/acuity.toml`)
11//!   at `ws://127.0.0.1:8172`
12//! - the local IPFS daemon at `http://127.0.0.1:5001`
13//!
14//! `GENESIS_HASH`, `ITEM_ID_NAMESPACE`, and the item bounds are pinned to the
15//! runtime configuration so item-id derivation and validation match the chain.
16
17/// WebSocket endpoint of the Coordination Platform Substrate node.
18pub const CHAIN_WS_URL: &str = "ws://127.0.0.1:9944";
19
20/// WebSocket endpoint of the `acuity-index` JSON-RPC event indexer.
21pub const INDEXER_WS_URL: &str = "ws://127.0.0.1:8172";
22
23/// HTTP base URL of the local IPFS daemon (the `/api/v0/*` raft).
24pub const IPFS_API_URL: &str = "http://127.0.0.1:5001";
25
26/// Chain genesis hash (hex, `0x`-prefixed) from `acuity-index/acuity.toml`.
27/// Used to sanity-check that the connected node is the Coordination Platform.
28pub const GENESIS_HASH: &str = "0xd6be38e4049024b2a41d76e8d6dc3fa38173d85c74c4c2d3966669c082199219";
29
30/// Item-id derivation namespace (`choreo-runtime`'s `ItemIdNamespace`), pinned
31/// to `1000`. Item IDs are computed as
32/// `blake2_256(account ++ nonce ++ namespace)`.
33pub const ITEM_ID_NAMESPACE: u32 = 1000;
34
35/// Upper bound on parent item references (`choreo-runtime`'s `MaxParents`).
36pub const MAX_PARENTS: usize = 32;
37
38/// Upper bound on linked item references (`choreo-runtime`'s `MaxLinks`).
39pub const MAX_LINKS: usize = 128;
40
41/// Upper bound on mentioned accounts (`choreo-runtime`'s `MaxMentions`).
42pub const MAX_MENTIONS: usize = 256;
43
44/// Item lifecycle flag bits, matching `pallet-content`. `publish_item` only
45/// accepts `REVISIONABLE | RETRACTABLE`; reserved bits are rejected.
46pub mod flags {
47    /// New revisions are allowed.
48    pub const REVISIONABLE: u8 = 1 << 0;
49    /// The item can be marked retracted.
50    pub const RETRACTABLE: u8 = 1 << 1;
51    /// Set by `retract_item`.
52    pub const RETRACTED: u8 = 1 << 2;
53}
54
55/// Valid flag mask accepted by `publish_item`.
56pub const VALID_PUBLISH_FLAGS: u8 = flags::REVISIONABLE | flags::RETRACTABLE;
57
58/// Default flags for a freshly published item: revisionable (so it can be
59/// updated) and retractable (so it can be withdrawn), with the retracted bit
60/// clear.
61pub const DEFAULT_ITEM_FLAGS: u8 = flags::REVISIONABLE | flags::RETRACTABLE;
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn default_item_flags_are_within_valid_mask() {
69        assert_eq!(DEFAULT_ITEM_FLAGS & VALID_PUBLISH_FLAGS, DEFAULT_ITEM_FLAGS);
70        // The retracted bit is never set at publish.
71        assert_eq!(DEFAULT_ITEM_FLAGS & flags::RETRACTED, 0);
72    }
73
74    #[test]
75    fn flags_are_distinct_bits() {
76        // The two publish-accepted bits are independent flags, not the same bit.
77        assert_ne!(flags::REVISIONABLE, flags::RETRACTABLE);
78        assert_ne!(flags::REVISIONABLE, flags::RETRACTED);
79        assert_ne!(flags::RETRACTABLE, flags::RETRACTED);
80        // Distinct flags do not overlap.
81        assert_eq!(flags::REVISIONABLE & flags::RETRACTABLE, 0);
82        assert_eq!(flags::REVISIONABLE & flags::RETRACTED, 0);
83        assert_eq!(flags::RETRACTABLE & flags::RETRACTED, 0);
84    }
85
86    #[test]
87    fn genesis_hash_is_hex_512_bits() {
88        assert!(GENESIS_HASH.starts_with("0x"));
89        assert_eq!(GENESIS_HASH.len(), 2 + 64);
90    }
91
92    #[test]
93    fn item_bounds_are_positive() {
94        // Compile-time guard: the runtime rejects zero bounds, so the pinned
95        // constants are asserted in a const block (a runtime `assert!` on a
96        // constant would be dead — clippy flags it).
97        const {
98            assert!(MAX_PARENTS > 0);
99            assert!(MAX_LINKS > 0);
100            assert!(MAX_MENTIONS > 0);
101        }
102        assert_eq!(ITEM_ID_NAMESPACE, 1000);
103    }
104}