Skip to main content

prns_runtime/runtime/node/
recipe.rs

1use crate::engine::RatchetPolicy;
2use crate::identity::in_memory::InMemoryNodeIdentity;
3use crate::identity::{IdentitySigner, Zeroizing, IDENTITY_SECRET_KEY_LEN};
4use crate::routing::announce::{
5    derive_destination_hash, derive_plain_destination_hash, expand_name, ExpandNameError,
6};
7use crate::routing::links::resources::ResourceStrategy;
8use crate::routing::{LinkRequestPolicy, ProofStrategy};
9use crate::units::ByteLimit;
10use crate::wire::DestinationHash;
11
12use super::super::PrnsEvent;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum ServeMyRequestEndpoints {
16    No,
17    Yes,
18}
19
20pub enum PreConfiguredDestination<'a> {
21    Plain {
22        app_name: &'a str,
23        aspects: &'a [&'a str],
24    },
25    Single {
26        app_name: &'a str,
27        aspects: &'a [&'a str],
28        identity: Zeroizing<[u8; IDENTITY_SECRET_KEY_LEN]>,
29        announce_app_data: &'a [u8],
30        proof: ProofStrategy,
31        link_requests: LinkRequestPolicy,
32        ratchet: RatchetPolicy,
33        /// Whether links to this destination accept inbound resources, and how large. The runtime counterpart is the handle's `set_resource_strategy`; most destinations want `ResourceStrategy::AcceptNone` until they expect a transfer.
34        resource_strategy: ResourceStrategy,
35        maximum_request_bytes: ByteLimit,
36        request_endpoints: ServeMyRequestEndpoints,
37    },
38}
39
40impl PreConfiguredDestination<'_> {
41    /// The address this destination answers as, derived from its name (and key, for a `Single`), so an announcing app can name itself before the node starts. `Err` only when the name is malformed (a dotted component, or past the length bound), the same validation `PrnsNode::new` runs as it stands the destination up.
42    pub fn destination_hash(&self) -> Result<DestinationHash, ExpandNameError> {
43        match self {
44            PreConfiguredDestination::Plain { app_name, aspects } => Ok(
45                derive_plain_destination_hash(&expand_name(app_name, aspects)?),
46            ),
47            PreConfiguredDestination::Single {
48                app_name,
49                aspects,
50                identity,
51                ..
52            } => {
53                let signer = InMemoryNodeIdentity::from_secret_key_bytes(identity);
54                Ok(derive_destination_hash(
55                    &signer.identity_hash(),
56                    &expand_name(app_name, aspects)?,
57                ))
58            }
59        }
60    }
61}
62
63/// The explicit "I wire interfaces myself" answer to the recipe's `interfaces` field: attach everything after construction through the node handle (or, on a board, at slot activation).
64#[derive(Debug, Clone, Copy, PartialEq, Eq)]
65pub struct ManuallyAttached;
66
67/// The explicit "this node forgets everything at exit" answer to the recipe's `persistence` field.
68#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69pub struct NoPersistence;
70
71pub struct PrnsNodeRecipe<
72    Destinations,
73    AppState,
74    RequestEndpoints,
75    OnEvent,
76    Interfaces,
77    Storage,
78    Persistence = NoPersistence,
79> where
80    OnEvent: FnMut(PrnsEvent<'_>, &AppState),
81{
82    /// The transport role takes a whole identity, never a bare address: a transport node signs (tunnel synthesis), and RNS 1.4.2 keeps a dedicated persisted transport identity.
83    pub transport_identity: Option<Zeroizing<[u8; IDENTITY_SECRET_KEY_LEN]>>,
84    pub pre_configured_destinations: Destinations,
85    pub app_state: AppState,
86    /// The storage layout the engine's columns run on: `GrowableHeap` on a std
87    /// host, `Esp32S3` for the PSRAM-backed reference target, or a board-owned
88    /// fixed layout for an SRAM-constrained application. A type-level choice
89    /// carried as a value so the recipe owns it and `PrnsNode::new` no longer
90    /// assumes one.
91    pub storage: Storage,
92    pub request_endpoints: RequestEndpoints,
93    pub interfaces: Interfaces,
94    pub persistence: Persistence,
95    pub on_event: OnEvent,
96}