Torrust Tracker Package Architecture

June 24, 2026 · View on GitHub

packages/
├── axum-health-check-api-server
├── axum-http-server
├── axum-rest-api-server
├── axum-server
├── configuration
├── e2e-tools
├── events
├── http-protocol
├── http-core
├── persistence-benchmark
├── primitives
├── rest-api-application
├── rest-api-client
├── rest-api-core
├── rest-api-protocol
├── rest-api-runtime-adapter
├── swarm-coordination-registry
├── test-helpers
├── torrent-repository-benchmarking
├── tracker-client
├── tracker-core
├── udp-protocol
├── udp-core
└── udp-server
console/
└── tracker-client      # Client for interacting with trackers
contrib/
└── dev-tools           # Developer tooling (git hooks, container scripts, etc.)

REST API Contract-First Architecture

The REST API uses a contract-first layered architecture with four distinct layers and enforced dependency direction. See ADR 20260623200526 for the full architectural decision and alternatives considered.

flowchart TB
    Transport["axum-rest-api-server<br><em>transport</em>"]
    Client["rest-api-client<br><em>client</em>"]
    Application["rest-api-application<br><em>ports / use cases</em>"]
    Adapter["rest-api-runtime-adapter<br><em>port impls</em>"]
    Internals["tracker-core / http-core / udp-core / udp-server<br><em>tracker internals</em>"]
    Protocol["rest-api-protocol<br><em>wire contract</em>"]

    Transport -->|calls| Application
    Adapter -->|implements| Application
    Adapter -->|wraps| Internals
    Transport -.->|serializes| Protocol
    Client -.->|deserializes| Protocol
    Application -->|defines| Protocol

Layer responsibilities

LayerPackageResponsibility
Protocolrest-api-protocolVersioned contract DTOs, error schemas, auth semantics. No Axum, no tracker internals.
Applicationrest-api-applicationPort traits, use-case services, domain-error mapping. Depends only on protocol.
Runtime adapterrest-api-runtime-adapterTracker-specific port implementations, domain→DTO conversions. Only layer that depends on tracker internals.
Transportaxum-rest-api-serverHTTP routing, extraction, serialization. Thin — no business logic.

Dependency rules

EdgeAllowed?
axum-rest-api-server → rest-api-application
axum-rest-api-server → rest-api-protocol
rest-api-client → rest-api-protocol
rest-api-application → rest-api-protocol
rest-api-runtime-adapter → rest-api-application + tracker-core
axum-rest-api-server → tracker-core (direct)❌ (target)

Long-term vision

The protocol contract package (rest-api-protocol) is positioned for potential extraction into a standalone, tracker-agnostic REST API standard. This would allow different tracker implementations to adopt the same protocol surface and interoperate with existing clients. Extraction is deferred until the API stabilizes.

Package Conventions

PrefixResponsibilityDependencies
axum-*HTTP server components using AxumAxum framework
*-serverServer implementationsCorresponding *-core
*-coreDomain logic & business rulesProtocol implementations
*-protocolBitTorrent protocol implementationsBitTorrent protocol
rest-api-*REST API layers (contract-first)See REST API architecture
udp-*UDP Protocol-specific implementationsTracker core
http-*HTTP Protocol-specific implementationsTracker core

Key Architectural Principles:

  1. Separation of Concerns: Servers contain only network I/O logic.
  2. Protocol Compliance: *-protocol packages strictly implement BEP specifications.
  3. Extensibility: Core logic is framework-agnostic for easy protocol additions.

Layer Boundary Enforcement

Dependencies between layers are enforced programmatically via cargo deny check bans — configured in deny.toml at the workspace root.

Motivation

The layered architecture (servers → core → protocol → domain) prevents coupling between concerns. Without automated enforcement, a misplaced dependency (e.g., a core crate importing a server crate) compiles and passes CI silently. cargo deny prohibits these edges at the lockfile level, catching violations in pre-commit hooks and CI before merge.

Forbidden edges

EdgeDescriptionCurrent violations
core -> serverCore must not depend on delivery-layer packagesrest-api-core -> udp-server
tracker-core -> coreTracker core must not depend on its protocol-specific wrappersNone
tracker-core -> protocolTracker core must not depend on protocol parsing cratesNone
tracker-core -> serverTracker core must not depend on server cratesNone
protocol -> coreProtocol crates must not depend on core logicNone
protocol -> tracker-coreProtocol crates must not depend on tracker coreNone
protocol -> serverProtocol crates must not depend on server cratesNone
domain -> serverDomain/shared packages must not depend on server cratesNone
rest-api-server -> tracker-coreREST API transport must not directly depend on tracker coreIn progress — being replaced by application + adapter layers

REST API contract-first forbidden edges

These edges apply to the REST API layers defined in the REST API architecture section and are additional to the general forbidden edges above.

EdgeDescriptionCurrent violations
axum-rest-api-server -> torrust-tracker-coreTransport must not depend directly on tracker coreIn progress
axum-rest-api-server -> torrust-tracker-http-coreTransport must not depend on http-coreIn progress
axum-rest-api-server -> torrust-tracker-udp-coreTransport must not depend on udp-coreIn progress
axum-rest-api-server -> torrust-tracker-udp-serverTransport must not depend on udp-serverIn progress
rest-api-protocol -> torrust-tracker-coreProtocol must not depend on tracker coreNone
rest-api-protocol -> torrust-tracker-udp-coreProtocol must not depend on udp-coreNone
rest-api-protocol -> torrust-tracker-http-coreProtocol must not depend on http-coreNone
rest-api-application -> torrust-tracker-coreApplication must not depend on tracker coreNone
rest-api-application -> torrust-tracker-udp-coreApplication must not depend on udp-coreNone

How it works

cargo deny uses a bans with wrappers mechanism. For each server-layer or protocol crate that should be restricted, deny.toml lists:

  • The banned crate (the server/protocol package).
  • A wrappers list — the set of packages that are legitimately allowed to depend on that crate directly. Any direct dependency outside this list, and any transitive dependency from a non-server package, is rejected.

For example, torrust-tracker-udp-server can only be depended on by:

  • torrust-tracker (root binary)
  • torrust-tracker-axum-rest-api-server
  • torrust-tracker-axum-health-check-api-server
  • torrust-tracker-rest-api-core (known violation — see below)

A core package like torrust-tracker-http-core adding udp-server as a dependency would be immediately rejected by cargo deny check bans.

Known exceptions

  • torrust-tracker-rest-api-core depends on torrust-tracker-udp-server — a known violation tracked separately. Until it is fixed, the wrapper list for udp-server includes rest-api-core.

Maintenance

When adding a new dependency to a workspace package, run:

cargo deny check bans

If it fails, either:

  1. The new dependency is on a restricted crate — check whether your package belongs in that crate's wrappers list.
  2. The dependency is legitimate — add your package to the appropriate wrapper entry in deny.toml.

Adding a package to a wrapper list should be a deliberate architectural decision, reviewed with the same care as any layer-crossing dependency. See deny.toml for the complete configuration.

Design Decisions

Package Catalog

PackageDescriptionKey Responsibilities
axum-*
axum-serverBase Axum HTTP server infrastructureHTTP server lifecycle management
axum-http-serverBitTorrent HTTP tracker (BEP 3/23)Handle announce/scrape requests
axum-rest-api-serverManagement REST API (transport)HTTP routing, request extraction, response serialization, middleware
axum-health-check-api-serverHealth monitoring endpointSystem health reporting
REST APIContract-first layersSee REST API architecture
rest-api-protocolREST API protocol contractVersioned DTOs, error schemas, auth semantics
rest-api-applicationREST API applicationPort traits, use-case services, domain-error mapping
rest-api-runtime-adapterREST API runtime adapterTracker-specific port implementations, domain→DTO conversions
rest-api-coreREST API core (deprecated)Legacy integration container — to be replaced by application + adapter layers
Core Components
http-coreHTTP-specific implementationRequest validation, Response formatting
udp-coreUDP-specific implementationConnectionless request handling
tracker-coreCentral tracker logicPeer management
Protocols
http-protocolHTTP tracker protocol (BEP 3/23)Announce/scrape request parsing
udp-protocolUDP tracker protocol (BEP 15)UDP message framing/parsing
Domain
swarm-coordination-registryPeer swarm registryTorrent/peer coordination
configurationRuntime configurationConfig file parsing, Environment variables
primitivesDomain-specific typesPeerId, Peer, SwarmMetadata
eventsAsync event busInter-package communication
Utilities
test-helpersTesting utilitiesMock servers, Test data generation
Client Tools
tracker-client (packages/)Tracker client libraryGeneric tracker client library
rest-api-clientAPI client libraryREST API integration
Benchmarking
torrent-repository-benchmarkingTorrent storage benchmarksCriterion benchmarks
persistence-benchmarkPersistence layer benchmarksSQLite/MySQL/PostgreSQL benchmarks

Extracted Packages

Packages that have been extracted to their own standalone repositories.

PackageStandalone RepositoryCrate NameDescription
clocktorrust/torrust-clocktorrust-clockDeterministic clock abstraction
located-errortorrust/torrust-located-errortorrust-located-errorDiagnostic errors with source locations
metricstorrust/torrust-metricstorrust-metricsPrometheus-compatible metrics: counters, gauges, labels, samples
net-primitivestorrust/torrust-net-primitivestorrust-net-primitivesGeneric networking primitive types (ServiceBinding, Protocol)
server-libtorrust/torrust-server-libtorrust-server-libShared server library utilities

Protocol Implementation Details

HTTP Tracker (BEP 3/23)

  • http-protocol implements:
    • URL parameter parsing
    • Response bencoding
    • Error code mapping
    • Compact peer formatting

UDP Tracker (BEP 15)

  • udp-protocol handles:
    • Connection ID management
    • Message framing (32-bit big-endian)
    • Transaction ID tracking
    • Error response codes

Architectural Philosophy

  1. Testability: Core packages have minimal dependencies for easy unit testing
  2. Observability: Health checks and metrics built into server packages
  3. Modularity: Protocol implementations decoupled from transport layers
  4. Extensibility: New protocols can be added without modifying core logic

Torrust Tracker Architecture Diagram

Diagram shows clean separation between network I/O (servers), protocol handling, and core tracker logic