peer

package
v0.1.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package peer implements the local P2P node (plan C15, goal.md §15): announcing cached sample artifacts to the central tracker, serving them to other peers over HTTP, and fetching artifacts with the fallback order local CAS → tracker peers → server → MISS. Announce payloads carry ONLY the rotating-free persistent peer id, the listen port, capability tags, and content-addressed sample ids — never paths, project names, or any other machine-identifying detail (§2.2).

Index

Constants

This section is empty.

Variables

View Source
var ErrMiss = errors.New("peer: sample artifact not found in any source")

ErrMiss is returned by Fetch when the artifact exists in no reachable source: local CAS, announced peers, and the server all came up empty.

Functions

This section is empty.

Types

type AnnounceResult

type AnnounceResult struct {
	Done       bool
	Addr       string `json:"addr"`
	Registered bool   `json:"registered"`
	Reason     string `json:"reason"`
}

AnnounceResult is what the tracker made of the last announce. Registered false means the tracker could not dial this peer back, so it will not be handed to other peers — normal behind NAT, and harmless: evidence, uploads, and fetching all still work, this peer just cannot serve.

type Node

type Node struct {
	CAS       *cas.Store
	DB        *localdb.DB
	Ident     *identity.Identity
	HTTP      *http.Client
	ServerURL string
	Port      int

	// BindAddr is the interface ListenAndServe binds to. Empty means every
	// interface, which is what a real peer needs: the tracker dials it back
	// and other peers fetch from it, so a loopback-only peer cannot serve.
	//
	// Tests set it to 127.0.0.1. A test binary that binds every interface
	// makes Windows Defender Firewall prompt on every single run — the
	// binary is recompiled to a fresh temp path each time, so the allow
	// decision can never be remembered — and it briefly exposes the port to
	// the local network for a test that only ever talks to loopback.
	BindAddr string
	// contains filtered or unexported fields
}

Node is one peer: a CAS full of verified sample artifacts, the local DB tracking which samples have artifacts, and the identity that names this peer on the tracker.

func (*Node) Announce

func (n *Node) Announce(ctx context.Context) error

Announce registers this peer with the tracker: peer id, listen port, blob capability, and the content-addressed ids of samples whose artifacts are locally cached. Sample ids are SHA-256 digests, so the payload can never carry paths or project names.

func (*Node) Fetch

func (n *Node) Fetch(ctx context.Context, sampleID string) ([]byte, string, error)

Fetch returns the artifact bytes for sampleID and where they came from: "local" (CAS hit), "peer" (another node), or "server" (Main Seeder fallback), in that fixed order (§15.1). Every remote payload is re-verified against the content id before it is trusted, cached, or returned; peers or servers sending wrong bytes are skipped. Peer and server errors never abort the chain — the next source is tried — so a fully offline node still serves local hits (§3.9).

func (*Node) Handler

func (n *Node) Handler() http.Handler

Handler returns the peer HTTP surface (plan P9.1):

GET /peer/v1/ping          → 200 "csx-peer" (liveness / protocol probe)
GET /peer/v1/samples/{id}  → artifact bytes from the CAS, 404 if absent

It serves ONLY content-addressed artifacts already public on the network; it never exposes local paths, the DB, or anything else.

func (*Node) LastAnnounce

func (n *Node) LastAnnounce() AnnounceResult

LastAnnounce reports the tracker's verdict on the most recent announce. Done is false until the first announce completes.

func (*Node) ListenAndServe

func (n *Node) ListenAndServe(ctx context.Context) error

ListenAndServe serves the peer handler on n.Port until ctx is canceled, then shuts down gracefully. A canceled ctx returns nil; listener errors (port in use, …) are returned as-is.

func (*Node) SeedHot

func (n *Node) SeedHot(ctx context.Context, hotIDs []string, budgetMB int) (int, error)

SeedHot warms the cache with network-HOT samples (§15.3): each id not yet cached is fetched while total CAS usage stays under budgetMB. It stops at the budget and NEVER evicts — eviction belongs to the cache policy, not the seeder. Individual fetch misses/errors skip to the next id. Returns how many samples were newly seeded.

func (*Node) StartAnnouncing

func (n *Node) StartAnnouncing(ctx context.Context)

StartAnnouncing launches the background announce loop: one immediate announce, then one every 10 minutes until ctx is canceled. Announce failures (server down, §3.9) are tolerated silently — the next tick retries; local serving and fetching are unaffected.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL