Skip to documentation
SLOP

tiny.reticulum.node

Reference tiny.reticulum node

Defined in tiny.reticulum.

A state machine for one node of a mesh network holds everything the node remembers and turns one input at a time into a list of things for the program around it to do.

API (73)

Actions

Public operations.

Types and contracts

Public types and contracts.

Namespaces

Public namespaces.

Values and defaults

Public values and defaults.

No direct callersNo direct callstiny.reticulumnode
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/reticulum/src/node/access.zig:7

zig
/// The shared key and code length that authenticate every frame on one carrier, for a caller that/// runs a closed network and hands one of these to `registerCarrier`. The node appends the code to/// each frame it sends on that carrier and checks and strips it from each frame it receives. The/// key is 64 bytes and the code runs from 1 to 64 bytes.pub const Access = struct {    key: ifac.Key,    size: ifac.Size,};

Source: lib/reticulum/src/node/access.zig:17

zig
/// What the node remembers about one carrier, so a caller reads one of these to see what the node/// believes about a carrier it registered: that it is registered, whether the node may send on it,/// whether it searches for paths it lacks, and its access code, if it has one. The node holds one/// of these for every carrier index its limits allow, in storage the caller supplied. A carrier/// with no access code carries its frames as they are.pub const Registration = struct {    registered: u1 = 0,    outgoing: u1 = 0,    /// Whether the node asks this carrier for a path it lacks, which Reticulum@1.5.0    /// RNS/Interfaces/Interface.py:55,121 leaves off, so a caller turns this on for the carrier it    /// wants the node to search when it has no path to a destination. Registering the carrier again    /// returns the setting to off.    discover_paths: u1 = 0,    access: ?Access = null,};

Source: lib/reticulum/src/node/effect.zig:15

zig
pub const Code = enum(u8) {    unregistered_interface,    frame_too_large,    ifac_unexpected_flag,    ifac_missing_flag,    ifac_invalid_code,    ifac_truncated,    malformed_packet,    duplicate_packet,    packet_filtered,    no_path,    path_request_malformed,    path_request_duplicate,    path_request_batched,    invalid_announce,    own_announce,    announce_key_changed,    announce_table_full,    discovery_table_full,    announce_relay_too_large,    unknown_destination,    destination_type_mismatch,    decryption_failed,    proof_rejected,    proof_relay_wrong_interface,    links_unsupported,    links_full,    link_request_invalid,    link_request_duplicate,    unknown_link,    link_state_mismatch,    link_wrong_interface,    link_close_invalid,    link_entries_full,    link_relay_early,    link_relay_no_direction,    unsupported_context,    storage_failed,};

Source: lib/reticulum/src/node/effect.zig:129

zig
pub const Effect = union(enum) {    carrier_send: struct {        interface: carrier.Index,        frame: []const u8,    },    application_delivery: struct {        destination: [16]u8,        packet_hash: [32]u8,        plaintext: []const u8,        ratchet_id: ?[10]u8,        proof_requested: bool,        interface: carrier.Index,    },    announce_received: AnnounceReceived,    path_request: PathRequest,    receipt_update: struct {        packet_hash: packet.Hash,        status: packet.receipt.Status,        rtt: ?timer.Seconds,    },    persist: struct {        kind: PersistKind,        key: [16]u8,        bytes: []const u8,        token: event.PersistToken,    },    schedule_timer: struct {        id: timer.TimerId,        at: timer.Seconds,    },    diagnostic: struct {        code: Code,        packet_hash: ?[32]u8,    },    link_requested: LinkRequested,    link_established: LinkEstablished,    link_delivery: LinkDelivery,    link_closed: LinkClosed,};

Source: lib/reticulum/src/node/effect.zig:223

zig
pub const Effects = struct {    phase: alloc_phase.capacity.Phase,    capacity: Capacity,    storage: Storage,    entries: []Effect,    frames: []carrier.Frame,    len: usize = 0,    frames_used: usize = 0,    pub const storage_alignment: usize = 8;    pub const Storage = []align(storage_alignment) u8;    pub const Limits: type = EffectsLimits;    pub const Capacity: type = EffectsCapacity;    pub const Exhaustion = error{Full};    pub const InitError = Capacity.DeriveError || error{StorageLengthMismatch};    pub const work_limits: alloc_phase.capacity.WorkLimits = .{        .transition_steps_max = 2,        .cleanup_steps_per_call_max = 0,        .cleanup_calls_at_capacity_max = 0,    };    pub const claim: alloc_phase.capacity.Declaration = .{        .source = .{            .id = "reticulum.effects",            .kind = .phase_static,            .limit_source = .caller,            .storage = .{                .covered = &.{                    .{                        .id = "caller_effect_entries",                        .lifetime = .transferred,                        .detail = "caller storage for bounded effect values",                    },                    .{                        .id = "caller_effect_frames",                        .lifetime = .transferred,                        .detail = "caller storage for bounded inline effect frame copies",                    },                },                .excluded = &.{                    "event input slices",                    "carrier devices, application callbacks, and persistence state",                },            },            .capacity = .{                .inputs = &.{                    alloc_phase.capacity.bindInput(EffectsLimits, "effects_max", "effects_max"),                    alloc_phase.capacity.bindInput(EffectsLimits, "frames_max", "frames_max"),                },                .type_selectors = &.{                    alloc_phase.capacity.bindType(Effect, "effect"),                    alloc_phase.capacity.bindType(carrier.Frame, "frame"),                },                .nodes = &.{                    .{ .input = 0 },                    .{ .scale = .{                        .node = 0,                        .coefficient = .{ .size_of_concrete_type = 0 },                    } },                    .{ .input = 1 },                    .{ .scale = .{                        .node = 2,                        .coefficient = .{ .size_of_concrete_type = 1 },                    } },                    .{ .add = .{ .left = 1, .right = 3 } },                },                .assertions = &.{.{                    .scope = .closure_total,                    .measure = .retained,                    .relation = .exact,                    .expression = 4,                }},            },            .overload = .{                .kind = .reject_before_mutation,                .detail = "full effect or frame admission preserves every retained effect",            },            .risks = .{                .transitive = .{                    .status = .excluded,                    .detail = "effect copying calls no allocating owner",                },                .foreign = .{                    .status = .excluded,                    .detail = "the effect sink crosses no foreign boundary",                },            },            .work = .{ .equation = "push copies at most one frame and one effect" },            .obligations = &.{                .{ .key = "reticulum_effects_capacity", .role = .capacity_model },                .{ .key = "reticulum_effects_overload", .role = .overload },                .{ .key = "reticulum_effects_work", .role = .work_bound },            },        },        .bindings = .{            .owner = @This(),            .seal = .{                .family = alloc_phase.capacity.selector(@This().activate),                .premise = .{ .class = .checked_semantic_fact, .authority = .checker },            },            .teardown = .{                .family = alloc_phase.capacity.selector(@This().deinit),                .premise = .{ .class = .checked_semantic_fact, .authority = .checker },            },        },    };    pub fn init(storage: Storage, limits: Limits) InitError!Effects {        const capacity = try Capacity.derive(limits);        if (storage.len != capacity.storage_bytes) return error.StorageLengthMismatch;        const entries = std.mem.bytesAsSlice(Effect, storage[0..capacity.effect_bytes]);        const frame_storage: []align(@alignOf(carrier.Frame)) u8 = @alignCast(            storage[capacity.effect_bytes..],        );        const frames = std.mem.bytesAsSlice(carrier.Frame, frame_storage);        for (frames) |*frame| frame.* = .{};        return .{            .phase = .initialization,            .capacity = capacity,            .storage = storage,            .entries = entries,            .frames = frames,        };    }    pub fn activate(self: *Effects) void {        std.debug.assert(self.phase == .initialization);        std.debug.assert(self.len == 0);        std.debug.assert(self.frames_used == 0);        self.phase = .steady;    }    pub fn push(self: *Effects, value: Effect) Exhaustion!void {        std.debug.assert(self.phase == .steady);        if (self.len == self.capacity.effects_max) return error.Full;        const retained: Effect = switch (value) {            .carrier_send => |send| .{ .carrier_send = .{                .interface = send.interface,                .frame = try self.retain(send.frame),            } },            .application_delivery => |delivery| .{ .application_delivery = .{                .destination = delivery.destination,                .packet_hash = delivery.packet_hash,                .plaintext = try self.retain(delivery.plaintext),                .ratchet_id = delivery.ratchet_id,                .proof_requested = delivery.proof_requested,                .interface = delivery.interface,            } },            .announce_received => |announce| .{ .announce_received = .{                .destination_hash = announce.destination_hash,                .identity_hash = announce.identity_hash,                .public_key = announce.public_key,                .app_data = try self.retain(announce.app_data),                .hops = announce.hops,                .rotating_key_present = announce.rotating_key_present,                .path_response = announce.path_response,            } },            .link_delivery => |delivery| .{ .link_delivery = .{                .link_id = delivery.link_id,                .packet_hash = delivery.packet_hash,                .plaintext = try self.retain(delivery.plaintext),                .proof_requested = delivery.proof_requested,            } },            .persist => |persist| .{ .persist = .{                .kind = persist.kind,                .key = persist.key,                .bytes = try self.retain(persist.bytes),                .token = persist.token,            } },            .receipt_update,            .schedule_timer,            .diagnostic,            .path_request,            .link_requested,            .link_established,            .link_closed,            => value,        };        self.entries[self.len] = retained;        self.len += 1;    }    pub fn items(self: *const Effects) []const Effect {        std.debug.assert(self.phase == .steady);        return self.entries[0..self.len];    }    pub fn reset(self: *Effects) void {        std.debug.assert(self.phase == .steady);        self.len = 0;        self.frames_used = 0;    }    pub fn deinit(self: *Effects) Storage {        std.debug.assert(self.phase == .steady);        self.phase = .teardown;        const storage = self.storage;        self.* = undefined;        return storage;    }    fn retain(self: *Effects, bytes: []const u8) Exhaustion![]const u8 {        if (self.frames_used == self.capacity.frames_max) return error.Full;        const frame = carrier.Frame.init(bytes) catch return error.Full;        self.frames[self.frames_used] = frame;        const retained = self.frames[self.frames_used].slice();        self.frames_used += 1;        return retained;    }};

Source: lib/reticulum/src/node/effect.zig:58

zig
/// Records why a link closed: a deadline passed, the initiator closed it, or the responder closed/// it. Reticulum@1.5.0 RNS/Link.py:116-118 names the same three teardown reasons `TIMEOUT`,/// `INITIATOR_CLOSED`, and `DESTINATION_CLOSED`.pub const LinkCloseReason = enum(u8) {    timeout = 1,    initiator_closed = 2,    destination_closed = 3,};

Source: lib/reticulum/src/node/effect.zig:9

zig
pub const PersistKind = enum(u8) {    known_identity,    known_ratchet,    ratchet_ring,};

Source: lib/reticulum/src/node/error.zig:1

zig
pub const Error = error{    EffectsFull,    TimerFull,    NoOutgoingCarrier,    UnknownDestination,    InvalidDestination,    InvalidHops,    PacketTooLarge,    EncryptionFailed,    AppDataTooLong,    MissingEntropy,    TimestampOutOfRange,    ProofUnavailable,    LinksFull,    DuplicateLink,    UnknownLink,    LinkNotEstablished,};

Source: lib/reticulum/src/node/event.zig:43

zig
pub const ApplicationAnnounce = struct {    destination: [16]u8,    app_data: []const u8,    random: [5]u8,    fresh_rotating_key: ?[32]u8,    now: timer.Seconds,    /// The carrier to answer a path request on, which a caller sets on an announce so    /// Reticulum@1.5.0 RNS/Transport.py:3379-3382 answers on that carrier alone. Left null, the    /// announce goes out on every outgoing carrier.    path_response: ?carrier.Index = null,};

Source: lib/reticulum/src/node/event.zig:111

zig
/// Asks the node to take down one link it holds open, so a caller can close a link once done with/// it. An encrypted LINKCLOSE goes out, the link leaves the pool, and the caller hears that it/// closed. A link that has yet to activate drops at once with no packet sent. The reason is/// `initiator_closed` on an initiator and `destination_closed` on a responder, per Reticulum@1.5.0/// RNS/Link.py:657-672.pub const ApplicationLinkClose = struct {    link_id: [16]u8,    iv: [16]u8,    now: timer.Seconds,};

Source: lib/reticulum/src/node/event.zig:77

zig
/// Asks the node to open a link toward a single destination it holds an identity for, learned from/// an announce, for an encrypted session that outlives a single packet. `encryption_private` and/// `signing_private` hold the X25519 and Ed25519 private keys the initiator uses for this session/// alone, and Reticulum@1.5.0 RNS/Link.py:284-285 draws both at random.pub const ApplicationLinkOpen = struct {    destination: [16]u8,    encryption_private: [32]u8,    signing_private: [32]u8,    now: timer.Seconds,    /// What the node does with data delivered over this link, chosen here for an initiator link    /// because it has no registered destination to read it from. Under `.none` the node proves    /// nothing, under `.all` it proves every delivered packet at once, and under `.app` it reports    /// each delivery with a proof request that a link proof event answers. By contrast, a responder    /// reads this from its destination, per Reticulum@1.5.0 RNS/Link.py:958-968.    proof_strategy: ProofStrategy = .none,};

Source: lib/reticulum/src/node/event.zig:122

zig
/// Asks the node to answer one packet of link data it has handed up with a proof, so a caller under/// the `.app` strategy can answer a delivery that asked to be proved. The application names the/// packet hash from a delivery whose `proof_requested` was set, and the node sends that hash and a/// signature over it as link plaintext. A packet the node has already forgotten returns/// `error.ProofUnavailable`, per Reticulum@1.5.0 RNS/Link.py:378-389.pub const ApplicationLinkProve = struct {    link_id: [16]u8,    packet_hash: [32]u8,    now: timer.Seconds,};

Source: lib/reticulum/src/node/event.zig:98

zig
/// Asks the node to put application plaintext across a link that has activated, so the caller can/// send application bytes over the open link. Plaintext over 431 bytes returns/// `error.PacketTooLarge` before the node changes anything, per Reticulum@1.5.0 RNS/Link.py:73./// With `create_receipt` set, the node tracks the delivery, fails a receipt that stays in the table/// max(rtt * 6, 0.005) seconds after the send when no proof has arrived, per Reticulum@1.5.0/// RNS/Packet.py:419-420 and Reticulum@1.5.0 RNS/Transport.py:1307-1318, and culls the oldest/// receipt and reports it as a `receipt_update` effect with status `culled` and no round trip time/// when a later send that asks for a receipt finds the receipt table full.pub const ApplicationLinkSend = struct {    link_id: [16]u8,    plaintext: []const u8,    iv: [16]u8,    now: timer.Seconds,    create_receipt: bool = true,};

Source: lib/reticulum/src/node/event.zig:66

zig
/// Asks any node that knows a path to the named destination to answer with one, carrying the/// caller's own tag, for a caller that has yet to learn a route to that destination, as/// Reticulum@1.5.0 RNS/Transport.py:3207-3220 requests it. Naming a carrier sends the request on/// that carrier alone, and leaving it null sends it on every outgoing carrier.pub const ApplicationPathRequest = struct {    destination: [16]u8,    tag: [16]u8,    interface: ?carrier.Index,    now: timer.Seconds,};

Source: lib/reticulum/src/node/event.zig:55

zig
pub const ApplicationProve = struct {    destination: [16]u8,    packet_hash: [32]u8,    interface: carrier.Index,    now: timer.Seconds,};

Source: lib/reticulum/src/node/event.zig:32

zig
pub const ApplicationSend = struct {    destination: [16]u8,    now: timer.Seconds,    plaintext: []const u8,    context: wire.Context = .none,    hops: u8 = 0,    ephemeral_private: [32]u8,    iv: [16]u8,    create_receipt: bool = true,};

Source: lib/reticulum/src/node/event.zig:8

zig
pub const CarrierFrame = struct {    interface: carrier.Index,    now: timer.Seconds,    bytes: []const u8,    /// Thirty-two bytes of randomness that the caller renews for every frame it gives the node, so    /// a link's keys on the receiving side come out of them. A step that needs a key or an    /// initialization vector runs HKDF-SHA256 over those bytes, taking the link id as the salt and    /// a label that names the use. A responder gets its X25519 private key from this expansion, and    /// Reticulum@1.5.0 RNS/Link.py:276 draws one at random. An initiator's round trip packet and a    /// responder's LINKCLOSE take their initialization vectors this way, and Reticulum@1.5.0    /// RNS/Cryptography/Token.py:89 draws a random one.    entropy: [32]u8,};

Source: lib/reticulum/src/node/event.zig:133

zig
pub const Event = union(enum) {    carrier_frame: CarrierFrame,    timer_expired: TimerExpired,    application_send: ApplicationSend,    application_announce: ApplicationAnnounce,    application_prove: ApplicationProve,    application_path_request: ApplicationPathRequest,    application_link_open: ApplicationLinkOpen,    application_link_send: ApplicationLinkSend,    application_link_close: ApplicationLinkClose,    application_link_prove: ApplicationLinkProve,    storage_complete: StorageComplete,};

Source: lib/reticulum/src/node/event.zig:128

zig
pub const StorageComplete = struct {    token: PersistToken,    now: timer.Seconds,};

Source: lib/reticulum/src/node/event.zig:22

zig
pub const TimerExpired = struct {    id: timer.TimerId,    now: timer.Seconds,    /// Thirty-two bytes of randomness that the caller renews for every timer it reports, so a timer    /// that closes a link can encrypt. A step driven by a timer derives its keys and initialization    /// vectors the same way, through HKDF-SHA256 with the link id as the salt and a label that    /// names the use.    entropy: [32]u8,};

Source: lib/reticulum/src/node/limits.zig:72

zig
pub const Capacity = struct {    interface_storage_bytes: usize,    identity_storage_bytes: usize,    ratchet_binding_storage_bytes: usize,    scratch_storage_bytes: usize,    destinations: destination.registry.Table.Capacity,    known_identities: identity.known.Identities.Capacity,    known_ratchets: identity.known.Ratchets.Capacity,    receipts: packet.receipt.Table.Capacity,    duplicate_hashes: packet.hashlist.Table.Capacity,    timers: timer.Table.Capacity,    transport: transport.State.Capacity,    effects: effect.Effects.Capacity,    identities_offset: usize,    ratchet_bindings_offset: usize,    destinations_offset: usize,    known_identities_offset: usize,    known_ratchets_offset: usize,    receipts_offset: usize,    duplicate_hashes_offset: usize,    timers_offset: usize,    transport_offset: usize,    effects_offset: usize,    scratch_offset: usize,    storage_bytes: usize,    pub const DeriveError = error{ InvalidLimit, CapacityOverflow };    pub fn derive(limits: Limits) DeriveError!Capacity {        if (limits.interfaces_max == 0) return error.InvalidLimit;        if (limits.interfaces_max > @as(usize, std.math.maxInt(carrier.Index)) + 1) {            return error.InvalidLimit;        }        const subs = try deriveSubcapacities(limits);        const interface_storage_bytes = try alloc_phase.capacity.mul(            usize,            limits.interfaces_max,            @sizeOf(access.Registration),        );        var cursor = try alignForward(interface_storage_bytes, 8);        const identities_offset = try advance(&cursor, try alloc_phase.capacity.mul(            usize,            limits.destinations_max,            @sizeOf(identity.Private),        ));        const ratchet_bindings_offset = try advance(&cursor, try alloc_phase.capacity.mul(            usize,            limits.destinations_max,            @sizeOf(RatchetBinding),        ));        const destinations_offset = try advance(&cursor, subs.destinations.storage_bytes);        const known_identities_offset = try advance(&cursor, subs.known_identities.storage_bytes);        const known_ratchets_offset = try advance(&cursor, subs.known_ratchets.storage_bytes);        const receipts_offset = try advance(&cursor, subs.receipts.storage_bytes);        const duplicate_hashes_offset = try advance(&cursor, subs.duplicate_hashes.storage_bytes);        const timers_offset = try advance(&cursor, subs.timers.storage_bytes);        const transport_offset = try advance(&cursor, subs.transport.storage_bytes);        const effects_offset = try advance(&cursor, subs.effects.storage_bytes);        const scratch_offset = try advance(&cursor, wire.mtu);        return .{            .interface_storage_bytes = interface_storage_bytes,            .identity_storage_bytes = ratchet_bindings_offset - identities_offset,            .ratchet_binding_storage_bytes = destinations_offset - ratchet_bindings_offset,            .scratch_storage_bytes = wire.mtu,            .destinations = subs.destinations,            .known_identities = subs.known_identities,            .known_ratchets = subs.known_ratchets,            .receipts = subs.receipts,            .duplicate_hashes = subs.duplicate_hashes,            .timers = subs.timers,            .transport = subs.transport,            .effects = subs.effects,            .identities_offset = identities_offset,            .ratchet_bindings_offset = ratchet_bindings_offset,            .destinations_offset = destinations_offset,            .known_identities_offset = known_identities_offset,            .known_ratchets_offset = known_ratchets_offset,            .receipts_offset = receipts_offset,            .duplicate_hashes_offset = duplicate_hashes_offset,            .timers_offset = timers_offset,            .transport_offset = transport_offset,            .effects_offset = effects_offset,            .scratch_offset = scratch_offset,            .storage_bytes = cursor,        };    }};

Source: lib/reticulum/src/node/limits.zig:29

zig
pub const Limits = struct {    interfaces_max: usize,    destinations_max: usize,    known_identities_max: usize,    known_ratchets_max: usize,    receipts_max: usize,    duplicate_hashes_max: usize,    timers_max: usize,    effects_max: usize,    effect_frames_max: usize,    paths_max: usize,    announces_max: usize,    reverse_entries_max: usize,    path_request_tags_max: usize,    inflight_requests_max: usize,    discoveries_max: usize,    links_max: usize,    link_entries_max: usize,    /// One set of limits that pairs the reference receipt, hash, and tag maxima above with a single    /// entry in every other table. The tests derive a capacity from it to show that those maxima    /// fit and that raising one past the range of its entry type is refused.    pub const reference = Limits{        .interfaces_max = 1,        .destinations_max = 1,        .known_identities_max = 1,        .known_ratchets_max = 1,        .receipts_max = reference_receipts_max,        .duplicate_hashes_max = reference_duplicate_hashes_max,        .timers_max = 1,        .effects_max = effect.effects_per_event_max,        .effect_frames_max = effect.effect_frames_per_event_max,        .paths_max = 1,        .announces_max = 1,        .reverse_entries_max = 1,        .path_request_tags_max = reference_path_request_tags_max,        .inflight_requests_max = 1,        .discoveries_max = 1,        .links_max = 1,        .link_entries_max = 1,    };};

Source: lib/reticulum/src/node/limits.zig:24

zig
pub const RatchetBinding = struct {    ring: ?*identity.Ring = null,    enforce: bool = false,};

Source: lib/reticulum/src/node/owner.zig:27

zig
pub const Node = struct {    phase: alloc_phase.capacity.Phase,    capacity: Capacity,    storage: Storage,    interfaces: []Interface,    identities: []identity.Private,    ratchet_bindings: []RatchetBinding,    destinations: destination.registry.Table,    known_identities: identity.known.Identities,    known_ratchets: identity.known.Ratchets,    receipts: packet.receipt.Table,    duplicate_hashes: packet.hashlist.Table,    timers: timer.Table,    transport: transport.State,    effects: effect.Effects,    scratch: []u8,    proof_mode: ProofMode = .implicit,    pub const storage_alignment: usize = 8;    pub const Storage = []align(storage_alignment) u8;    pub const Limits: type = limits.Limits;    pub const Capacity: type = limits.Capacity;    pub const InitError = Capacity.DeriveError || error{StorageLengthMismatch};    pub const work_limits: alloc_phase.capacity.WorkLimits = .{        .transition_steps_max = 8,        .cleanup_steps_per_call_max = 0,        .cleanup_calls_at_capacity_max = 0,    };    pub const claim: alloc_phase.capacity.Declaration = .{        .source = .{            .id = "reticulum.node",            .kind = .phase_static,            .limit_source = .caller,            .storage = .{                .covered = &.{                    .{                        .id = "caller_interface_slots",                        .lifetime = .transferred,                        .detail = "caller storage for bounded carrier access registrations",                    },                    .{                        .id = "caller_node_subowners",                        .lifetime = .transferred,                        .detail = "caller storage for local identities and eight strict subowners",                    },                    .{                        .id = "caller_node_work",                        .lifetime = .transferred,                        .detail = "caller storage for rotating-key bindings and one MTU scratch",                    },                },                .excluded = &.{                    "carrier memory and interface devices",                    "bound rotating-key rings and application payload inputs",                    "persistent storage and operating-system state",                },            },            .capacity = .{                .inputs = &.{                    alloc_phase.capacity.bindInput(Limits, "interfaces", "interfaces_max"),                    alloc_phase.capacity.bindInput(Limits, "destinations", "destinations_max"),                    alloc_phase.capacity.bindInput(Limits, "identities", "known_identities_max"),                    alloc_phase.capacity.bindInput(Limits, "ratchets", "known_ratchets_max"),                    alloc_phase.capacity.bindInput(Limits, "receipts", "receipts_max"),                    alloc_phase.capacity.bindInput(Limits, "hashes", "duplicate_hashes_max"),                    alloc_phase.capacity.bindInput(Limits, "timers", "timers_max"),                    alloc_phase.capacity.bindInput(Limits, "effects", "effects_max"),                    alloc_phase.capacity.bindInput(Limits, "frames", "effect_frames_max"),                    alloc_phase.capacity.bindInput(Limits, "paths", "paths_max"),                    alloc_phase.capacity.bindInput(Limits, "announces", "announces_max"),                    alloc_phase.capacity.bindInput(                        Limits,                        "reverse_entries",                        "reverse_entries_max",                    ),                    alloc_phase.capacity.bindInput(                        Limits,                        "path_request_tags",                        "path_request_tags_max",                    ),                    alloc_phase.capacity.bindInput(                        Limits,                        "inflight_requests",                        "inflight_requests_max",                    ),                    alloc_phase.capacity.bindInput(Limits, "discoveries", "discoveries_max"),                    alloc_phase.capacity.bindInput(Limits, "links", "links_max"),                },                .type_selectors = &.{                    alloc_phase.capacity.bindType(identity.Private, "private_identity"),                    alloc_phase.capacity.bindType(RatchetBinding, "ratchet_binding"),                    alloc_phase.capacity.bindType(                        destination.registry.Entry,                        "destination",                    ),                    alloc_phase.capacity.bindType(                        identity.known.IdentityEntry,                        "identity",                    ),                    alloc_phase.capacity.bindType(                        identity.known.RatchetEntry,                        "ratchet",                    ),                    alloc_phase.capacity.bindType(packet.receipt.Receipt, "receipt"),                    alloc_phase.capacity.bindType(packet.Hash, "hash"),                    alloc_phase.capacity.bindType(timer.Timer, "timer"),                    alloc_phase.capacity.bindType(effect.Effect, "effect"),                    alloc_phase.capacity.bindType(carrier.Frame, "frame"),                    alloc_phase.capacity.bindType(Interface, "interface"),                    alloc_phase.capacity.bindType(transport.path.Entry, "path"),                    alloc_phase.capacity.bindType(transport.announces.Entry, "announce"),                    alloc_phase.capacity.bindType(transport.reverse.Entry, "reverse_entry"),                    alloc_phase.capacity.bindType(transport.inflight.Entry, "inflight_request"),                    alloc_phase.capacity.bindType(transport.discoveries.Entry, "discovery"),                },                .nodes = &.{                    .{ .input = 0 },                    .{ .scale = .{                        .node = 0,                        .coefficient = .{ .size_of_concrete_type = 10 },                    } },                    .{ .alignment = .{ .node = 1, .alignment = .{ .literal = 8 } } },                    .{ .input = 1 },                    .{ .scale = .{                        .node = 3,                        .coefficient = .{ .size_of_concrete_type = 0 },                    } },                    .{ .add = .{ .left = 2, .right = 4 } },                    .{ .scale = .{                        .node = 3,                        .coefficient = .{ .size_of_concrete_type = 1 },                    } },                    .{ .add = .{ .left = 5, .right = 6 } },                    .{ .scale = .{                        .node = 3,                        .coefficient = .{ .size_of_concrete_type = 2 },                    } },                    .{ .add = .{ .left = 7, .right = 8 } },                    .{ .input = 2 },                    .{ .scale = .{                        .node = 10,                        .coefficient = .{ .size_of_concrete_type = 3 },                    } },                    .{ .add = .{ .left = 9, .right = 11 } },                    .{ .input = 3 },                    .{ .scale = .{                        .node = 13,                        .coefficient = .{ .size_of_concrete_type = 4 },                    } },                    .{ .add = .{ .left = 12, .right = 14 } },                    .{ .input = 4 },                    .{ .scale = .{                        .node = 16,                        .coefficient = .{ .size_of_concrete_type = 5 },                    } },                    .{ .add = .{ .left = 15, .right = 17 } },                    .{ .input = 5 },                    .{ .scale = .{                        .node = 19,                        .coefficient = .{ .size_of_concrete_type = 6 },                    } },                    .{ .add = .{ .left = 18, .right = 20 } },                    .{ .input = 6 },                    .{ .scale = .{                        .node = 22,                        .coefficient = .{ .size_of_concrete_type = 7 },                    } },                    .{ .add = .{ .left = 21, .right = 23 } },                    .{ .input = 7 },                    .{ .scale = .{                        .node = 25,                        .coefficient = .{ .size_of_concrete_type = 8 },                    } },                    .{ .add = .{ .left = 24, .right = 26 } },                    .{ .input = 8 },                    .{ .scale = .{                        .node = 28,                        .coefficient = .{ .size_of_concrete_type = 9 },                    } },                    .{ .add = .{ .left = 27, .right = 29 } },                    .{ .input = 9 },                    .{ .scale = .{                        .node = 31,                        .coefficient = .{ .size_of_concrete_type = 11 },                    } },                    .{ .add = .{ .left = 30, .right = 32 } },                    .{ .input = 10 },                    .{ .scale = .{                        .node = 34,                        .coefficient = .{ .size_of_concrete_type = 12 },                    } },                    .{ .add = .{ .left = 33, .right = 35 } },                    .{ .input = 11 },                    .{ .scale = .{                        .node = 37,                        .coefficient = .{ .size_of_concrete_type = 13 },                    } },                    .{ .add = .{ .left = 36, .right = 38 } },                    .{ .input = 12 },                    .{ .scale = .{                        .node = 40,                        .coefficient = .{ .size_of_concrete_type = 6 },                    } },                    .{ .add = .{ .left = 39, .right = 41 } },                    .{ .input = 13 },                    .{ .scale = .{                        .node = 43,                        .coefficient = .{ .size_of_concrete_type = 14 },                    } },                    .{ .add = .{ .left = 42, .right = 44 } },                    .{ .input = 14 },                    .{ .scale = .{                        .node = 46,                        .coefficient = .{ .size_of_concrete_type = 15 },                    } },                    .{ .add = .{ .left = 45, .right = 47 } },                    .{ .input = 15 },                    .{ .scale = .{                        .node = 49,                        .coefficient = .{ .literal = @sizeOf(transport.links.Entry) },                    } },                    .{ .add = .{ .left = 48, .right = 50 } },                    .{ .constant = 500 },                    .{ .add = .{ .left = 51, .right = 52 } },                },                .assertions = &.{.{                    .scope = .closure_total,                    .measure = .retained,                    .relation = .exact,                    .expression = 53,                }},            },            .overload = .{                .kind = .reject_before_seal,                .detail = "invalid limits and short caller storage reject before activation",            },            .risks = .{                .transitive = .{                    .status = .witnessed,                    .detail = "all retained subowner storage is carved from the node region",                },                .foreign = .{                    .status = .excluded,                    .detail = "the node owner crosses no foreign boundary",                },            },            .work = .{ .equation = "activation and teardown each visit eight subowners" },            .dependencies = &.{                "reticulum.destinations",                "reticulum.known_identities",                "reticulum.known_ratchets",                "reticulum.receipts",                "reticulum.hashlist",                "reticulum.timers",                "reticulum.effects",                "reticulum.transport",            },            .obligations = &.{                .{ .key = "reticulum_node_capacity", .role = .capacity_model },                .{ .key = "reticulum_node_overload", .role = .overload },                .{ .key = "reticulum_node_transitive", .role = .transitive_risk },                .{ .key = "reticulum_node_work", .role = .work_bound },            },        },        .bindings = .{            .owner = @This(),            .seal = .{                .family = alloc_phase.capacity.selector(@This().activate),                .premise = .{ .class = .checked_semantic_fact, .authority = .checker },            },            .teardown = .{                .family = alloc_phase.capacity.selector(@This().deinit),                .premise = .{ .class = .checked_semantic_fact, .authority = .checker },            },        },    };    pub fn init(storage: Storage, selected: Limits) InitError!Node {        const capacity = try Capacity.derive(selected);        if (storage.len != capacity.storage_bytes) return error.StorageLengthMismatch;        const interfaces = initializeInterfaces(storage, capacity);        const identities = std.mem.bytesAsSlice(identity.Private, region(            storage,            capacity.identities_offset,            capacity.identity_storage_bytes,        ));        for (identities) |*private| private.* = identity.Private.fromBytes(@splat(0));        const ratchet_bindings = std.mem.bytesAsSlice(RatchetBinding, region(            storage,            capacity.ratchet_bindings_offset,            capacity.ratchet_binding_storage_bytes,        ));        @memset(ratchet_bindings, .{});        const subowners = try initSubowners(storage, capacity, selected);        const scratch = storage[capacity.scratch_offset..][0..capacity.scratch_storage_bytes];        @memset(scratch, 0);        return .{            .phase = .initialization,            .capacity = capacity,            .storage = storage,            .interfaces = interfaces,            .identities = identities,            .ratchet_bindings = ratchet_bindings,            .destinations = subowners.destinations,            .known_identities = subowners.known_identities,            .known_ratchets = subowners.known_ratchets,            .receipts = subowners.receipts,            .duplicate_hashes = subowners.duplicate_hashes,            .timers = subowners.timers,            .transport = subowners.transport,            .effects = subowners.effects,            .scratch = scratch,        };    }    pub fn activate(self: *Node) void {        std.debug.assert(self.phase == .initialization);        self.destinations.activate();        self.known_identities.activate();        self.known_ratchets.activate();        self.receipts.activate();        self.duplicate_hashes.activate();        self.timers.activate();        self.transport.activate();        self.effects.activate();        self.phase = .steady;    }    pub fn identityAt(self: *Node, index: usize) ?*identity.Private {        std.debug.assert(self.phase == .steady);        if (index >= self.identities.len) return null;        return &self.identities[index];    }    /// Registers one carrier index, so the node accepts frames that arrive on it and, with    /// `outgoing` set, sends on it as well. An access code given here authenticates every frame in    /// both directions on that carrier. An index at or past the caller's carrier maximum returns    /// `error.Index`. Registering the same index again zeroes what was there, so its path discovery    /// returns to off.    pub fn registerCarrier(        self: *Node,        index: carrier.Index,        outgoing: bool,        access_config: ?Access,    ) error{Index}!void {        std.debug.assert(self.phase == .steady);        std.debug.assert(self.interfaces.len > 0);        std.debug.assert(self.interfaces.len <= @as(usize, std.math.maxInt(carrier.Index)) + 1);        if (access_config) |value| {            std.debug.assert(value.size.byte() >= ifac.min_size_bytes);            std.debug.assert(@as(usize, wire.mtu) + value.size.byte() <= carrier.frame_bytes_max);        }        const slot: usize = index;        if (slot >= self.interfaces.len) return error.Index;        std.crypto.secureZero(u8, std.mem.asBytes(&self.interfaces[slot]));        self.interfaces[slot] = .{            .registered = 1,            .outgoing = @intFromBool(outgoing),            .access = access_config,        };        std.debug.assert(self.interfaces[slot].registered == 1);    }    /// Binds a rotating-key ring to one of the node's own identities, so announces from that    /// identity carry a rotating public key and data addressed to it is decrypted with the ring's    /// keys first. The ring stays the caller's and has to outlive the node, which holds only a    /// pointer to it. With `enforce` set, the node decrypts only with the ring's keys, so a packet    /// that none of them open fails. An identity index at or past the caller's destination maximum    /// returns `error.Index`.    pub fn bindRatchetRing(        self: *Node,        identity_index: usize,        ring: *identity.Ring,        enforce: bool,    ) error{Index}!void {        std.debug.assert(self.phase == .steady);        if (identity_index >= self.ratchet_bindings.len) return error.Index;        self.ratchet_bindings[identity_index] = .{ .ring = ring, .enforce = enforce };    }    /// Chooses whether a proof this node sends carries the proved packet's hash beside the    /// signature or the signature alone. The node starts in implicit mode, with the signature    /// alone.    pub fn setProofMode(self: *Node, mode: ProofMode) void {        std.debug.assert(self.phase == .steady);        self.proof_mode = mode;    }    /// Turns the node into one that carries traffic for others and gives it the 16 bytes that name    /// it to its neighbors, which Reticulum@1.5.0 RNS/Transport.py:1577-1580,1907 sets. An enabled    /// transport node rebroadcasts the announces it accepts and relays the packets that name it as    /// the next hop.    pub fn setTransport(self: *Node, identity_hash: [16]u8, enabled: bool) void {        std.debug.assert(self.phase == .steady);        self.transport.configure(identity_hash, enabled);    }    /// Lets the node ask one carrier for a path it lacks, which Reticulum@1.5.0    /// RNS/Transport.py:3352-3355 searches. An index at or past the carrier maximum, or one the    /// caller has yet to register, returns `error.Index`. Registering that carrier again returns    /// the setting to off, per Reticulum@1.5.0 RNS/Interfaces/Interface.py:55,121.    pub fn setPathDiscovery(self: *Node, index: carrier.Index, enabled: bool) error{Index}!void {        std.debug.assert(self.phase == .steady);        const slot: usize = index;        if (slot >= self.interfaces.len) return error.Index;        if (self.interfaces[slot].registered == 0) return error.Index;        self.interfaces[slot].discover_paths = @intFromBool(enabled);        std.debug.assert(self.interfaces[slot].discover_paths == @intFromBool(enabled));    }    /// Applies one event and returns the effects it produced. The effects point into the node's own    /// storage and stay valid until the next call.    pub fn step(self: *Node, value: event.Event) errors.Error![]const effect.Effect {        return @import("step.zig").run(self, value);    }    pub fn deinit(self: *Node) Storage {        std.debug.assert(self.phase == .steady);        _ = self.effects.deinit();        _ = self.transport.deinit();        _ = self.timers.deinit();        _ = self.duplicate_hashes.deinit();        _ = self.receipts.deinit();        _ = self.known_ratchets.deinit();        _ = self.known_identities.deinit();        _ = self.destinations.deinit();        std.crypto.secureZero(u8, std.mem.sliceAsBytes(self.interfaces));        @memset(self.ratchet_bindings, .{});        for (self.identities) |*private| private.zero();        std.crypto.secureZero(u8, self.scratch);        self.phase = .teardown;        const storage = self.storage;        self.* = undefined;        return storage;    }};

Source: lib/reticulum/src/node/owner.zig:20

zig
pub const ProofMode = enum(u1) {    implicit,    explicit,};
Called byCallsNo direct callstest sourcelib.reticulum.src.node.effecttest: announce effects retain applica...test sourcelib.reticulum.src.node.effecttest: effect frame bytes admit maximu...test sourcelib.reticulum.src.node.effecttest: effect frames admit maximum and...test sourcelib.reticulum.src.node.effecttest: effects admit maximum and rejec...test sourcelib.reticulum.src.node.effecttest: effects retain every slice in t...node.Nodeactivatenode.Effectsactivate
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.reticulum.src.node.effecttest: announce effects retain applica...test sourcelib.reticulum.src.node.effecttest: effect frame bytes admit maximu...test sourcelib.reticulum.src.node.effecttest: effect frames admit maximum and...test sourcelib.reticulum.src.node.effecttest: effects admit maximum and rejec...test sourcelib.reticulum.src.node.effecttest: effects retain every slice in t...node.Nodedeinitnode.Effectsdeinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.reticulum.src.node.effecttest: announce effects retain applica...test sourcelib.reticulum.src.node.effecttest: effect frame bytes admit maximu...test sourcelib.reticulum.src.node.effecttest: effect frames admit maximum and...test sourcelib.reticulum.src.node.effecttest: effects admit maximum and rejec...test sourcelib.reticulum.src.node.effecttest: effects retain every slice in t...private sourcelib.reticulum.src.node.ownerinitSubownersnode.Effectsinit
Static calls · unresolved targets: 2 · external targets: 0.
Called byCallsNo direct callstest sourcelib.reticulum.src.node.effecttest: announce effects retain applica...test sourcelib.reticulum.src.node.effecttest: effect frames admit maximum and...test sourcelib.reticulum.src.node.effecttest: effects admit maximum and rejec...test sourcelib.reticulum.src.node.effecttest: effects retain every slice in t...node.Effectsitems
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.reticulum.src.node.effecttest: announce effects retain applica...test sourcelib.reticulum.src.node.effecttest: effect frame bytes admit maximu...test sourcelib.reticulum.src.node.effecttest: effect frames admit maximum and...test sourcelib.reticulum.src.node.effecttest: effects admit maximum and rejec...test sourcelib.reticulum.src.node.effecttest: effects retain every slice in t...private sourcelib.reticulum.src.node.effect.Effectsretainnode.Effectspush
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/reticulum/src/node/effect.zig:177

zig
/// Gives the most byte slices one event's effects retain, so a caller sizes the effect list's frame/// storage from this bound. One delivery that also proves reaches that number, retaining the/// plaintext and 256 carrier frames.pub const effect_frames_per_event_max: u16 = 257;

Source: lib/reticulum/src/node/effect.zig:173

zig
/// Gives the most effects one event can produce, so a caller sizes its effect storage from this/// bound. An announce reaches that number: it reports the announce, arms one timer, and sends one/// answer over every one of 256 carriers. A link open with no known path reaches it too: it reports/// the request, arms one timer, and sends that request over every one of 256 carriers.pub const effects_per_event_max: u16 = 258;

Source: lib/reticulum/src/node/event.zig:6

zig
pub const PersistToken = u64;
Called byCallstest sourcelib.reticulum.src.node.limitstest: node capacity accepts reference...test sourcelib.reticulum.src.node.limitstest: node capacity rejects zero and ...private sourcelib.reticulum.src.node.limitsadvanceprivate sourcelib.reticulum.src.node.limitsalignForwardprivate sourcelib.reticulum.src.node.limitsderiveSubcapacitiesnode.Capacityderive
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallstest sourcelib.reticulum.src.node.ownertest: node carrier and rotating-key b...test sourcelib.reticulum.src.node.ownertest: node carves and activates every...test sourcelib.reticulum.src.node.ownertest: node keyed carrier registration...test sourcelib.reticulum.src.node.ownertest: node path discovery defaults of...destination.registry.Tableactivateidentity.known.Identitiesactivateidentity.known.Ratchetsactivatenode.Effectsactivatenode.timer.Tableactivate+2 morenode.Nodeactivate
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.reticulum.src.node.ownertest: node carrier and rotating-key b...node.NodebindRatchetRing
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.reticulum.src.node.ownertest: node carrier and rotating-key b...test sourcelib.reticulum.src.node.ownertest: node carves and activates every...test sourcelib.reticulum.src.node.ownertest: node keyed carrier registration...test sourcelib.reticulum.src.node.ownertest: node path discovery defaults of...destination.registry.Tabledeinitidentity.known.Identitiesdeinitidentity.known.Ratchetsdeinitnode.Effectsdeinitnode.timer.Tabledeinit+2 morenode.Nodedeinit
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.reticulum.src.node.ownertest: node carrier and rotating-key b...test sourcelib.reticulum.src.node.ownertest: node carves and activates every...test sourcelib.reticulum.src.node.ownertest: node keyed carrier registration...test sourcelib.reticulum.src.node.ownertest: node path discovery defaults of...private sourcelib.reticulum.src.node.ownerinitSubownersprivate sourcelib.reticulum.src.node.ownerinitializeInterfacesprivate sourcelib.reticulum.src.node.ownerregionnode.Nodeinit
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsNo direct callstest sourcelib.reticulum.src.node.ownertest: node carrier and rotating-key b...test sourcelib.reticulum.src.node.ownertest: node keyed carrier registration...test sourcelib.reticulum.src.node.ownertest: node path discovery defaults of...node.NoderegisterCarrier
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.reticulum.src.node.ownertest: node path discovery defaults of...node.NodesetPathDiscovery
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/reticulum/src/node/root.zig

zig
//! A state machine for one node of a mesh network holds everything the node remembers and turns one//! input at a time into a list of things for the program around it to do. That network is//! Reticulum, in which nodes find each other by broadcasting signed announcements and reach each//! other over any network interface that moves bytes.//!//! Someone writing such a node has to decide what to put on the wire, what to remember about who is//! out there, and when a deadline has passed, and the program around the node keeps the sockets,//! the clock, and the source of randomness. The node has to run on machines whose memory is fixed//! before the program starts, so it takes the size of each store it keeps from the caller and//! refuses work once a store is full. A port of an existing protocol has to be checkable against//! the original, byte for byte.//!//! Code that reads the wall clock and draws its own randomness gives a different answer on every//! run, which leaves nothing to compare against a reference. Sending from inside the protocol logic//! also needs somewhere for the bytes to live. A transition can run out of room part way through,//! and a half-applied transition would leave the node's stores disagreeing with what the caller was//! told.//!//! The subtree follows *Reticulum 1.5.0*, the reference implementation this package is a port of.//! The package README and the generated conformance material pin the upstream commit. What the//! subtree takes from the reference is its order of handling an arriving packet, its state machines//! for routes and for encrypted sessions, and its timeouts, and each declaration names the//! reference file and line range it follows. The package generates reference bytes and clocks from//! that release (a *conformance corpus*) and replays them in differential tests, so each of those//! claims is checkable from this tree.//!//! A transition (a *step*) takes the instant and the 32 bytes of randomness it needs from its own//! input, so replaying the same inputs gives the same results. The node sends nothing, arms no//! timer, and writes no storage itself: it appends a record of each such request (an *effect*) to a//! list, and the caller performs them. Every transition first reserves room (a *reserve*): it//! checks that the list of effects and the storage for its bytes can hold what it is about to//! append before it changes any store, so a transition that runs out of room leaves the node as it//! was. Every store takes its entry maximum (its *limits*) from the caller and is carved out of one//! block of caller storage whose length has to equal the derived byte count exactly. The node keeps//! one packet-sized buffer (its *scratch*) where a transition builds the bytes it is about to hand//! to one network interface.//!//! The file exports the subtree's pieces: `Node` and `Limits`, the `Event` a transition takes and//! the `Effect` records it returns, `timer`, and the modules `inbound` for arriving frames,//! `outbound` for sends, `announce`, `link`, `transport` for carrying traffic on behalf of other//! nodes, and `fixture`, the three-node test world.//!//! - *node*: the state machine that holds one Reticulum node's tables, one packet of scratch space,//!   and its effect list.//! - *event*: the one input a step takes, either a frame that arrived on a carrier, a timer that//!   came due, an application request, or the completion of a caller's storage write.//! - *step entropy*: the 32 bytes the caller draws fresh for each carrier frame and each timer//!   event, which the step expands with HKDF-SHA256 whenever it needs a key or an initialization//!   vector.//! - *table*: an owner over caller-supplied bytes with a fixed entry maximum, which carves the//!   caller's storage once and hands it back at teardown.//! - *packet*: one Reticulum datagram, at most 500 bytes, carrying a flags byte, a hop count, an//!   optional transport id, a destination hash, a context byte, and a payload.//! - *frame*: the bytes handed to one carrier, one packet plus at most a 64-byte signature.//! - *carrier*: one network interface a node sends and receives frames over, named by a byte index.//! - *announce*: a packet carrying a destination's public keys, a name hash, ten random bytes, and//!   a signature, so any node that hears it learns that destination and how far away it sits.//! - *path*: what a node learned from an announce about reaching one destination: the carrier to//!   send on, the neighbor to name as the next hop, and how many hops away it sits.//! - *link*: an encrypted session between two endpoints, named by a 16-byte link id that both ends//!   derive from the request packet.//! - *timer*: a deadline the node holds, naming what comes due and the whole second it comes due//!   at.//! - *transport node*: a node that carries traffic on behalf of other nodes, as well as sending and//!   receiving its own.const effect = @import("effect.zig");const errors = @import("error.zig");const event = @import("event.zig");const limits = @import("limits.zig");const owner = @import("owner.zig");pub const timer = @import("timer.zig");pub const outbound = @import("outbound.zig");pub const announce = @import("announce.zig");pub const inbound = @import("inbound.zig");pub const link = @import("link.zig");pub const transition = @import("step.zig");pub const transport = @import("transport/root.zig");pub const fixture = @import("fixture/root.zig");pub const Seconds = timer.Seconds;pub const TimerId = timer.TimerId;pub const PersistToken = event.PersistToken;pub const Limits = limits.Limits;pub const Capacity = limits.Capacity;pub const Node = owner.Node;pub const Access = owner.Access;pub const Interface = owner.Interface;pub const ProofMode = owner.ProofMode;pub const RatchetBinding = owner.RatchetBinding;pub const StepError = errors.Error;pub const Event = event.Event;pub const CarrierFrame = event.CarrierFrame;pub const TimerExpired = event.TimerExpired;pub const ApplicationSend = event.ApplicationSend;pub const ApplicationAnnounce = event.ApplicationAnnounce;pub const ApplicationProve = event.ApplicationProve;pub const ApplicationPathRequest = event.ApplicationPathRequest;pub const ApplicationLinkOpen = event.ApplicationLinkOpen;pub const ApplicationLinkSend = event.ApplicationLinkSend;pub const ApplicationLinkClose = event.ApplicationLinkClose;pub const ApplicationLinkProve = event.ApplicationLinkProve;pub const StorageComplete = event.StorageComplete;pub const Effect = effect.Effect;pub const Effects = effect.Effects;pub const Code = effect.Code;pub const LinkCloseReason = effect.LinkCloseReason;pub const LinkRole = transport.links.Role;pub const PersistKind = effect.PersistKind;pub const effects_per_event_max = effect.effects_per_event_max;pub const effect_frames_per_event_max = effect.effect_frames_per_event_max;

Source: lib/reticulum/src/root.zig:65

zig
pub const node = @import("node/root.zig");

Complete call list for node.Node.activate

7 direct calls.

Complete call list for node.Node.deinit

7 direct calls.

Audit

Definitions64
Public names64
Members206
Version26.7.0
Revisiondaab053ee433