reticulum-js
    Preparing search index...

    Class PropagationNode

    Server-side propagation logic. Owns the MessageStore and implements the /get request-response exchange and the ingestion of submitted blobs.

    Index
    _lastDedupPrune: number

    Epoch seconds of the last dedup-cache prune (0 = due immediately).

    getDeliveryDestination: (destinationHash: Uint8Array) => Destination | null
    getLocalIdentityHash: () => Uint8Array
    identityAllowed: (identity: Identity) => boolean
    inboundSyncs: Map<any, any>

    hex(resource hash) → in-flight inbound peer-sync transfers.

    ingestFilter:
        | (
            (
                candidate: {
                    destinationHash: Uint8Array;
                    size: number;
                    stampValue: number;
                    transientId: Uint8Array;
                },
            ) => boolean
            | Promise<boolean>
        )
        | null

    Application hook deciding which non-local blobs to store (see PropagationNodeOptions.ingestFilter). null stores everything (the Python reference's behavior).

    locallyDelivered: Map<any, any>

    hex(transientId) delivered to a local identity → epoch seconds.

    locallyProcessed: Map<string, number>

    hex(transientId) already processed (dedup) → epoch seconds. TTL-pruned (see tickMaintenance) so the set cannot grow without bound on long-running nodes.

    maxInboundSyncs: number

    Cap on concurrent inbound peer-sync transfers (Python MAX_INBOUND_SYNCS, lxmd default 3). Offers arriving while this many sync transfers are in flight are refused with ERROR_THROTTLED; the throttled peer postpones its next sync by stampThrottleSecs.

    name: string | null
    nodeState: boolean
    onLocalDelivery: (
        message: LXMessage,
        transientId: Uint8Array,
    ) => void | Promise<void>
    onStored: (storedIds: Uint8Array<ArrayBufferLike>[]) => void
    peeringCost: number
    perSyncLimitKb: number
    perTransferLimitKb: number
    sequentialValidation: boolean

    Whether only one stamp batch may validate at a time — offers arriving during a validation are refused with ERROR_THROTTLED (Python propagation_sequential_validation, lxmd default on). Static peers listed in staticPeerHashes bypass the gates.

    stampCost: number
    stampCostFlexibility: number
    stampThrottleSecs: number

    Throttle window (seconds) applied to peers whose transferred batches contained invalid stamps, and the postponement the ERROR_THROTTLED reply asks of the peer (Python PN_STAMP_THROTTLE).

    staticPeerHashes: Set<string>

    Peered node destination hashes (hex) that bypass the sequential validation and inbound-sync gates (Python static_peers + static_peers_bypass_sequential).

    throttledPeers: Map<any, any>

    hex(identityHash) → throttle-until epoch seconds (invalid-stamp bans).

    validatingCount: number

    Number of stamp batches currently validating.

    • Drops dedup-cache (locally processed / delivered) entries older than PROCESSED_TID_TTL_SECS (the Python reference's MESSAGE_EXPIRY * 6 cleanup). Called from tickMaintenance and lazily from ingestBlobs, so the caches stay bounded even without a driver.

      Parameters

      • Optionalnow: number = ...

        Epoch seconds; defaults to now.

      Returns number

      count of pruned entries.

    • Marks an inbound peer-sync transfer as in flight (Python propagation_resources_transferring). The owning router calls this when a transfer born of an accepted offer begins, and endInboundSync when it concludes. While maxInboundSyncs transfers are in flight, /offer replies ERROR_THROTTLED.

      Parameters

      • key: string

        hex(resource hash)

      Returns void

    • Builds the lxmf.propagation announce app_data advertising this node's limits and costs (LXMRouter.get_propagation_node_app_data).

      Parameters

      • Optionaltimebase: number = ...

        Unix seconds; defaults to now.

      Returns Uint8Array<ArrayBufferLike>

    • Builds the responseGenerator for registerRequestHandler("/offer", …).

      Returns (
          arg0: string,
          arg1: any,
          arg2: Uint8Array,
          arg3: Identity | null,
          arg4: number,
          arg5: Link,
      ) => Promise<number | boolean | Uint8Array<ArrayBufferLike>[]>

      The §11 response generator.

    • Builds the responseGenerator for registerRequestHandler("/get", …). Adapts the Link handler signature to handleGetRequest.

      Returns (
          path: string,
          data: any,
          requestId: Uint8Array,
          remoteIdentity: Identity | null,
          requestedAt: number,
      ) => Promise<number | Uint8Array<ArrayBufferLike>[]>

    • Handles a /get REQUEST (LXMRouter.message_get_request).

      data is the decoded [want, have] or [want, have, transferLimitKb]:

      • [null, null] → list of available transient_ids for the requester.
      • [wants[], haves[]] → purge haves, return base lxmf_data for wants.
      • [null, haves[]] → purge-ack only (returns []).

      Returns a value to be msgpack-encoded as the response: an array of transient_ids, an array of lxmf_data blobs, or a peer error code.

      Parameters

      • remoteIdentity: Identity | null
      • data: any

      Returns Promise<number | Uint8Array<ArrayBufferLike>[]>

    • Handles a /offer REQUEST from a peering propagation node (LXMRouter.offer_request).

      data is [peering_key, [transient_id, …]]. The peering key is validated against peering_id = receivingIdentityHash ‖ offeringIdentityHash at this node's own peering cost. The node then reports which offered messages it does not yet have:

      • false → it already has every offered message.
      • true → it wants every offered message.
      • [ids] → it wants exactly that subset.

      Parameters

      • remoteIdentity: Identity | null
      • data: any
      • link: null = null

      Returns Promise<number | boolean | Uint8Array<ArrayBufferLike>[]>

      the offer response, or a peer-error code.

    • Ingests a list of propagation blobs received in a submit/sync Resource container (LXMRouter.propagation_resource_concluded → lxmf_propagation).

      Parameters

      • transientList: Uint8Array<ArrayBufferLike>[]
      • Optionaloptions: { origin?: "peer-sync" | "submission" } = {}
        • Optionalorigin?: "peer-sync" | "submission"

          Where the blobs came from: "peer-sync" for offer-born peer-sync transfers (mirrored copies — subject to PropagationNodeOptions.ingestFilter), "submission" for direct submissions to this node (always kept — this node is their origin custodian, and the only copy).

      Returns Promise<
          {
              delivered: number;
              dropped: number;
              rejected: number;
              stored: number;
              storedIds: Uint8Array<ArrayBufferLike>[];
          },
      >

    • Throttles a peer identity for stampThrottleSecs — used when a transferred batch contained invalid stamps (Python throttled_peers).

      Parameters

      • remoteHex: string

        hex(identityHash) of the offender

      Returns void

    • Periodic maintenance — prunes aged entries (when messageTtlSecs is set), re-runs capacity eviction, and TTL-prunes the dedup caches. A runner calls this hourly (the Python reference runs the same cull from its job loop).

      Returns { aged: number; dedupPruned: number }