{"id":13702530,"url":"https://github.com/hoprnet/hoprnet","last_synced_at":"2026-03-03T19:05:03.311Z","repository":{"id":36953694,"uuid":"286462146","full_name":"hoprnet/hoprnet","owner":"hoprnet","description":"HOPR is an open incentivized mixnet which enables privacy-preserving point-to-point data exchange. HOPR is similar to Tor but actually private, decentralized and economically sustainable.","archived":false,"fork":false,"pushed_at":"2025-04-28T02:52:34.000Z","size":516626,"stargazers_count":227,"open_issues_count":132,"forks_count":95,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-28T03:30:31.437Z","etag":null,"topics":["blockchain","ethereum","privacy"],"latest_commit_sha":null,"homepage":"https://hoprnet.org","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoprnet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-08-10T11:57:55.000Z","updated_at":"2025-04-25T14:23:32.000Z","dependencies_parsed_at":"2023-09-24T16:15:33.136Z","dependency_job_id":"d610f040-61a7-44b4-b43d-31fd8d678bdd","html_url":"https://github.com/hoprnet/hoprnet","commit_stats":{"total_commits":15369,"total_committers":62,"mean_commits":"247.88709677419354","dds":0.6625024399765762,"last_synced_commit":"07935a245d0b6f51ca8c94c5075ffa31205a896f"},"previous_names":[],"tags_count":898,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoprnet%2Fhoprnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoprnet%2Fhoprnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoprnet%2Fhoprnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoprnet%2Fhoprnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoprnet","download_url":"https://codeload.github.com/hoprnet/hoprnet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252439583,"owners_count":21748038,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","ethereum","privacy"],"created_at":"2024-08-02T21:00:37.298Z","updated_at":"2026-03-03T19:05:03.300Z","avatar_url":"https://github.com/hoprnet.png","language":"Rust","funding_links":[],"categories":["Privacy Coins","Official Resources"],"sub_categories":["Node.js"],"readme":"\u003c!-- INTRODUCTION --\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://hoprnet.org\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\n    \u003cimg align=\"middle\" width=\"100\" src=\"https://github.com/hoprnet/hopr-assets/blob/master/v1/logo/hopr_logo_padded.png?raw=true\" alt=\"HOPR Logo\"\u003e\n  \u003c/a\u003e\n\n  \u003c!-- Title Placeholder --\u003e\n  \u003ch3 align=\"center\"\u003eHOPR\u003c/h3\u003e\n  \u003cp align=\"center\"\u003e\n    \u003ccode\u003eA project by the HOPR Association\u003c/code\u003e\n  \u003c/p\u003e\n  \u003cp align=\"center\"\u003e\n    HOPR is a privacy-preserving messaging protocol which enables the creation of a secure communication network via relay nodes powered by economic incentives using digital tokens.\n  \u003c/p\u003e\n\u003c/p\u003e\n\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [About](#about)\n- [Install](#install)\n  - [Install via Docker](#install-via-docker)\n  - [Install via Nix package manager](#install-via-nix-package-manager)\n  - [Install via linux package manager](#install-via-linux-package-manager)\n- [Usage](#usage)\n  - [Environment variables](#environment-variables)\n  - [Example execution](#example-execution)\n  - [Using Docker Compose with extended HOPR node monitoring](#using-docker-compose-with-extended-hopr-node-monitoring)\n  - [REST API](#rest-api)\n- [Testnet accessibility](#testnet-accessibility)\n- [Migrating between releases](#migrating-between-releases)\n- [Develop](#develop)\n  - [Nix environment setup](#nix-environment-setup)\n    - [Nix flake outputs](#nix-flake-outputs)\n    - [Code Formatting](#code-formatting)\n    - [Code Linting](#code-linting)\n    - [Generate the Python SDK](#generate-the-python-sdk)\n  - [Building a Docker image](#building-a-docker-image)\n- [Local cluster](#local-cluster)\n- [Test](#test)\n  - [Github Actions CI](#github-actions-ci)\n  - [End-to-End Testing](#end-to-end-testing)\n    - [Running Tests Locally](#running-tests-locally)\n      - [Test execution](#test-execution)\n- [Profiling \\\u0026 Instrumentation](#profiling--instrumentation)\n  - [`tokio` executor instrumentation](#tokio-executor-instrumentation)\n  - [OpenTelemetry export](#opentelemetry-export)\n  - [Profiling Criterion benchmarks via `flamegraph`](#profiling-criterion-benchmarks-via-flamegraph)\n    - [Prerequisites](#prerequisites)\n    - [Profiling the benchmarking binaries](#profiling-the-benchmarking-binaries)\n  - [HOPR packet capture](#hopr-packet-capture)\n- [Contact](#contact)\n- [License](#license)\n\n## About\n\nThe HOPR project produces multiple artifacts that allow running, maintaining and modifying the HOPR node.\nThe most relevant components for production use cases are:\n\n1. [hopr-lib](https://hoprnet.github.io/hoprnet/hopr_lib/index.html)\n   - A fully self-contained referential implementation of the HOPR protocol over a libp2p based connection mechanism that can be incorporated into other projects as a transport layer.\n2. [hoprd](https://hoprnet.github.io/hoprnet/hoprd/index.html)\n   - Daemon application providing a higher level interface for creating a HOPR protocol compliant node that can use a dedicated REST API.\n3. [hoprd-api-schema](https://hoprnet.github.io/hoprnet/hoprd_api_schema/index.html)\n   - Utility to generate the OpenAPI spec for the `hoprd` served REST API.\n4. [hoprd-cfg](https://hoprnet.github.io/hoprnet/hoprd_cfg/index.html)\n   - Utility for configuration management of the `hoprd`\n\nUnless stated otherwise, the following sections only apply to `hoprd`.\n\n## Install\n\nFor production purposes always run the latest stable release.\n\nMultiple options for installation exist, the preferred choice for any production system should be to use the container image (e.g. using `docker`).\n\nAll releases and associated changelogs are located in the [official releases](https://github.com/hoprnet/hoprnet/releases) section of the [`hoprnet`](https://github.com/hoprnet/hoprnet) repository.\n\n### Install via Docker\n\nThe following instructions show how any `$RELEASE` may be installed, to select the release, override the `$RELEASE` variable, e.g.:\n\n- `export RELEASE=latest` to track the latest changes on the repository's `master` branch\n- `export RELEASE=kaunas` to track the latest changes on the repository's `release/kaunas` branch (3.0.X)\n- `export RELEASE=\u003cversion\u003e` to get a specific `\u003cversion\u003e`\n\nContainer image has the format\n`europe-west3-docker.pkg.dev/hoprassociation/docker-images/$PROJECT:$RELEASE`.\nwhere:\n\n- `$PROJECT` can be: `hoprd`\n\nPull the container image with `docker`:\n\n```bash\ndocker pull europe-west3-docker.pkg.dev/hoprassociation/docker-images/hoprd:kaunas\n```\n\nIt is recommended to setup an alias `hoprd` for the docker command invocation.\n\n### Install via [Nix package manager][1]\n\nWARNING: This setup should only be used for development or advanced usage without any further support.\n\nClone and initialize the [`hoprnet`](https://github.com/hoprnet/hoprnet) repository:\n\n```bash\ngit clone https://github.com/hoprnet/hoprnet\ncd hoprnet\n```\n\nBuild and install the `hoprd` binary, e.g. on a UNIX platform:\n\n```bash\nnix build\nsudo cp result/bin/* /usr/local/bin/\n```\n\nTo build and access man pages for `hoprd`:\n\n```bash\n# Build man page for hoprd\nnix build .#hoprd-man\nman ./result/share/man/man1/hoprd.1.gz\n\n# Or install them system-wide\nsudo cp -r result/share/man/man1/* /usr/local/share/man/man1/\n```\n\n### Install via linux package manager\n\nLinux packages are available at every github release, download the latest package from https://github.com/hoprnet/hoprnet/releases/latest\nTo install on specific distribution, see [detailed information](./deploy/nfpm/README.md)\n\n## Usage\n\n`hoprd` provides various command-line switches to configure its behaviour. For reference these are documented here as well:\n\n```bash\n$ hoprd --help\nHOPR node executable\n\nUsage: hoprd [OPTIONS]\n\nOptions:\n      --identity \u003cIDENTITY\u003e\n          The path to the identity file [env: HOPRD_IDENTITY=]\n      --data \u003cDATA\u003e\n          Specifies the directory to hold all the data [env: HOPRD_DATA=]\n      --host \u003cHOST\u003e\n          Host to listen on for P2P connections [env: HOPRD_HOST=]\n      --announce...\n          Announce the node on chain with a public address [env: HOPRD_ANNOUNCE=]\n      --api...\n          Expose the API on localhost:3001 [env: HOPRD_API=]\n      --apiHost \u003cHOST\u003e\n          Set host IP to which the API server will bind [env: HOPRD_API_HOST=]\n      --apiPort \u003cPORT\u003e\n          Set port to which the API server will bind [env: HOPRD_API_PORT=]\n      --apiToken \u003cTOKEN\u003e\n          A REST API token and for user authentication [env: HOPRD_API_TOKEN=]\n      --password \u003cPASSWORD\u003e\n          A password to encrypt your keys [env: HOPRD_PASSWORD=]\n      --blokliUrl \u003cURL\u003e\n          URL for Blokli provider to be used for the node to connect to blockchain [env: HOPRD_BLOKLI_URL=]\n      --init...\n          initialize a database if it doesn't already exist [env: HOPRD_INIT=]\n      --forceInit...\n          initialize a database, even if it already exists [env: HOPRD_FORCE_INIT=]\n      --probeRecheckThreshold \u003cSECONDS\u003e\n          Timeframe in seconds after which it is reasonable to recheck the nearest neighbor [env: HOPRD_PROBE_RECHECK_THRESHOLD=]\n      --configurationFilePath \u003cCONFIG_FILE_PATH\u003e\n          Path to a file containing the entire HOPRd configuration [env: HOPRD_CONFIGURATION_FILE_PATH=]\n      --safeAddress \u003cHOPRD_SAFE_ADDR\u003e\n          Address of Safe that safeguards tokens [env: HOPRD_SAFE_ADDRESS=]\n      --moduleAddress \u003cHOPRD_MODULE_ADDR\u003e\n          Address of the node management module [env: HOPRD_MODULE_ADDRESS=]\n  -h, --help\n          Print help\n  -V, --version\n          Print version\n```\n\n### Environment variables\n\nOn top of the default configuration options generated for the command line, the following environment variables can be used in order to tweak the node functionality:\n\n- `ENV_WORKER_THREADS` - the number of environment worker threads for the tokio executor\n- `HOPRD_LOG_FORMAT` - override for the default stdout log formatter (follows tracing formatting options)\n- `HOPRD_USE_OPENTELEMETRY` - enable the OpenTelemetry output for this node\n- `HOPRD_OTEL_SIGNALS` - comma-separated OTLP signals to export when OpenTelemetry is enabled (`traces`, `logs`, `metrics`), defaults to `traces`\n- `OTEL_SERVICE_NAME` - the name of this node for the OpenTelemetry service\n- `HOPR_INTERNAL_CHAIN_DISCOVERY_CHANNEL_CAPACITY` - the maximum capacity of the channel for chain generated discovery signals for the p2p transport\n- `HOPR_INTERNAL_ACKED_TICKET_CHANNEL_CAPACITY` - the maximum capacity of the acknowledged ticket processing queue\n- `HOPR_INTERNAL_LIBP2P_MAX_CONCURRENTLY_DIALED_PEER_COUNT` - the maximum number of concurrently dialed peers in libp2p\n- `HOPR_INTERNAL_LIBP2P_MAX_NEGOTIATING_INBOUND_STREAM_COUNT` - the maximum number of negotiating inbound streams\n- `HOPR_INTERNAL_LIBP2P_SWARM_IDLE_TIMEOUT` - timeout for all idle libp2p swarm connections in seconds\n- `HOPR_INTERNAL_DB_PEERS_PERSISTENCE_AFTER_RESTART_IN_SECONDS` - cutoff duration from now to not retain the peers with older records in the peers database (e.g. after a restart)\n- `HOPR_INTERNAL_MANUAL_PING_CHANNEL_CAPACITY` - the maximum capacity of awaiting manual ping queue\n- `HOPR_INTERNAL_MIXER_CAPACITY` - capacity of the mixer buffer\n- `HOPR_INTERNAL_MIXER_MINIMUM_DELAY_IN_MS` - the minimum mixer delay in milliseconds\n- `HOPR_INTERNAL_MIXER_DELAY_RANGE_IN_MS` - the maximum range of the mixer delay from the minimum value in milliseconds\n- `HOPR_INTERNAL_PROTOCOL_BIDIRECTIONAL_CHANNEL_CAPACITY` - the maximum capacity of HOPR messages processed by the node\n- `HOPR_INTERNAL_SESSION_CTL_CHANNEL_CAPACITY` - the maximum capacity of the session control channel\n- `HOPR_INTERNAL_SESSION_INCOMING_CAPACITY` - the maximum capacity of the queue storing unprocessed incoming and outgoing messages inside a session\n- `HOPR_INTERNAL_SESSION_BALANCER_LEVEL_CAPACITY` - the maximum capacity of the session balancer\n- `HOPR_INTERNAL_RAW_SOCKET_LIKE_CHANNEL_CAPACITY` - the maximum capacity of the raw socket-like bidirectional API interface\n- `HOPR_INTERNAL_IN_PACKET_PIPELINE_CONCURRENCY` - the maximum number of incoming packets to process concurrently (default: 8 × CPU cores, 0 = no limit)\n- `HOPR_INTERNAL_OUT_PACKET_PIPELINE_CONCURRENCY` - the maximum number of outgoing packets to process concurrently (default: 8 × CPU cores, 0 = no limit)\n- `HOPR_CPU_TASK_QUEUE_LIMIT` - maximum number of CPU-bound tasks (queued + running) in the Rayon thread pool. If not set, the queue is unbounded. Set this to prevent unbounded queue growth under sustained load (e.g., `1000`). When the limit is reached, new tasks are rejected and packet decode operations may fail with \"local CPU queue full\" errors.\n- `HOPR_BALANCER_PID_P_GAIN` - proportional (P) gain for the PID controller in outgoing SURB balancer (default: `0.6`)\n- `HOPR_BALANCER_PID_I_GAIN` - integral (I) gain for the PID controller in outgoing SURB balancer (default: `0.7`)\n- `HOPR_BALANCER_PID_D_GAIN` - derivative (D) gain for the PID controller in outgoing SURB balancer (default: `0.2`)\n- `HOPR_CAPTURE_PACKETS` - allow capturing customized HOPR packet format to a PCAP file or to a `udpdump` host. Note that `hoprd` must be built with the `capture` feature.\n- `HOPR_CAPTURE_PATH_TRIGGER` - path used as trigger to start capturing customized HOPR packets. When there exists a file in that path, it will start capturing data.\n- `HOPR_TRANSPORT_MAX_CONCURRENT_PACKETS` - maximum number of concurrently processed incoming packets from all peers (default: 10)\n- `HOPR_TRANSPORT_STREAM_OPEN_TIMEOUT_MS` - maximum time (in milliseconds) to wait until a stream connection is established to a peer (default: `2000 ms`)\n- `HOPR_PACKET_PLANNER_CONCURRENCY` - maximum number of concurrently planned outgoing packets (default: `10`)\n- `HOPR_SESSION_FRAME_SIZE` - The maximum chunk of data that can be written to the Session's input buffer (default: 1500)\n- `HOPR_SESSION_FRAME_TIMEOUT_MS` - The maximum time (in milliseconds) for an incomplete frame to stay in the Session's output buffer (default: 800 ms)\n- `HOPR_PROTOCOL_SURB_RB_SIZE` - size of the SURB ring buffer (default: 10 000)\n- `HOPR_PROTOCOL_SURB_RB_DISTRESS` - threshold since number of SURBs in the ring buffer triggers a distress packet signal (default: 1000)\n- `HOPRD_SESSION_PORT_RANGE` - allows restricting the port range (syntax: `start:end` inclusive) of Session listener automatic port selection (when port 0 is specified)\n- `HOPRD_SESSION_ENTRY_UDP_RX_PARALLELISM` - sets the number of UDP listening sockets for UDP sessions on Entry node (defaults to number of CPU cores)\n- `HOPRD_SESSION_EXIT_UDP_RX_PARALLELISM` - sets the number of UDP listening sockets for UDP sessions on Exit node (defaults to number of CPU cores)\n- `HOPRD_NAT` - indicates whether the host is behind a NAT and sets transport-specific settings accordingly (default: `false`)\n- `HOPRD_NUM_CPU_THREADS` - sets the number of threads for CPU-bound tasks (default: number of CPU cores / 2)\n- `HOPRD_NUM_IO_THREADS` - sets the number of threads for IO-bound tasks (default: number of CPU cores / 2)\n- `HOPRD_THREAD_STACK_SIZE` - sets the thread stack size (default: 10 MB)\n- `HOPR_METRICS_UNACK_PER_PEER` - enable per-peer unacknowledged ticket cache metrics (disabled by default to reduce Prometheus cardinality). Set to `1` or `true` for debugging specific peer acknowledgement issues. **Warning**: Do not enable in production with many peers.\n\n### Example execution\n\nRunning the node without any command-line argument might not work depending on the installation method used. Some command line arguments are required.\n\nSome basic reasonable setup uses a custom identity and enables the REST API of the `hoprd`:\n\n```bash\nhoprd --identity /app/hoprd-db/.hopr-identity --password switzerland --init --announce --host \"0.0.0.0:9091\" --apiToken \u003cMY_TOKEN\u003e --blokliUrl \"http://blokli-provider.here\"\n```\n\nHere is a short breakdown of each argument.\n\n```bash\nhoprd\n  # store your node identity information in the persisted database folder\n  --identity /app/hoprd-db/.hopr-identity\n  # set the encryption password for your identity\n  --password switzerland\n  # initialize the database and identity if not present\n  --init\n  # announce the node to other nodes in the network and act as relay if publicly reachable\n  --announce\n  # set IP and port of the P2P API to the container's external IP so it can be reached on your host\n  --host \"0.0.0.0:9091\"\n  # specify password for accessing REST API\n  --apiToken \u003cMY_TOKEN\u003e\n  # blokli provider supplying the HOPR updates\n  --blokliUrl \"http://blokli-provider.here\"\n```\n\n### Using Docker Compose with extended HOPR node monitoring\n\nPlease follow the documentation for [`docker compose` based deployment](./deploy/compose/README.md).\n\n### REST API\n\n`hoprd` running a REST API exposes an endpoint at `http://\u003caddress\u003e/api-docs/openapi.json` with full OpenApi specification of the used REST API, including the current version of the API.\n\n## Testnet accessibility\n\nTo participate in a public network the node must be eligible. See [Network Registry](https://github.com/hoprnet/hoprnet/blob/master/NETWORK_REGISTRY.md) for details.\n\nNode eligibility is not required in a local development cluster (see [Develop section below](#develop)).\n\n## Migrating between releases\n\nThere is **NO** backward compatibility between releases.\n\nWe attempt to provide instructions on how to migrate your tokens between releases.\n\n1. Set your automatic channel strategy to `passive`.\n2. Redeem all unredeemed tickets.\n3. Close all open payment channels.\n4. Once all payment channels have closed, withdraw your funds to an external\n   wallet.\n5. Run `info` and take note of the **network name**.\n6. Once funds are confirmed to exist in a different wallet, backup `.hopr-identity` folder.\n7. Launch new `HOPRd` instance using latest release, observe the account address.\n8. Only transfer funds to new `HOPRd` instance if `HOPRd` operates on the **same network** as last release, you can compare the two networks using `info`.\n\n## Develop\n\nEither setup `nix` and `flake` to use the nix environment, or [install Rust toolchain](https://www.rust-lang.org/tools/install) from the `rust-toolchain.toml`, as well as `foundry-rs` binaries (`forge`, `anvil`).\n\n### Nix environment setup\n\nInstall `nix` from the official website at [https://nix.dev/install-nix.html](https://nix.dev/install-nix.html).\n\nCreate a nix configuration file at `~/.config/nix/nix.conf` with the following content:\n\n```nix\nexperimental-features = nix-command flakes\n```\n\nInstall the `nix-direnv` package to introduce the `direnv`:\n\n```bash\nnix-env -i nix-direnv\n```\n\nAppend the following line to the shell rc file (depending on the shell used it can be `~\\.zshrc`, `~\\.bashrc`, `~\\.cshrc`, etc.). Modify the `\u003cshell\u003e` variable inside the below command with the currently used (`zsh`, `bash`, `csh`, etc.):\n\n```bash\neval \"$(direnv hook \u003cshell\u003e)\"\n```\n\nFrom within the [`hoprnet`](https://github.com/hoprnet/hoprnet) repository's directory, execute the following command.\n\n```bash\ndirenv allow .\n```\n\n#### Nix flake outputs\n\nWe provide a couple of packages, apps and shells to make building and\ndevelopment easier. You may get the full list like so:\n\n```bash\nnix flake show\n```\n\n#### Code Formatting\n\nAll nix, rust, solidity and python code can be automatically formatted:\n\n```bash\nnix fmt\n```\n\nThese formatters are also automatically run as a Git pre-commit check.\n\n#### Code Linting\n\nAll linters can be executed via a Nix flake helper app:\n\n```bash\nnix run .#lint\n```\n\nThis will in particular run `clippy` for the entire Rust codebase.\n\n#### Generate the Python SDK\n\nA Python SDK is not distributed but can be generated to connect to the HOPRd API using the [generate-python-sdk.sh](/scripts/generate-python-sdk.sh) script.\n\nPrerequisites:\n\n- swagger-codegen3\n- build the repository to get the `hoprd-api-schema` generated\n\nThe generated SDK will be available in the `/tmp/hoprd-sdk-python/` directory. Modify the script to generate SDKs for different programming languages supported by swagger-codegen3.\n\nFor usage examples of the generated SDK, refer to the generated README.md file in the SDK directory.\n\n### Building a Docker image\n\nDocker images can be built using the respective nix flake outputs.\nThe available images can be listed with:\n\n```bash\njust list-docker-images\n```\n\nThe following command builds the `hoprd` image for the host platform:\n\n```bash\nnix build .#hoprd-docker\n```\n\nIf needed images for other platforms can be built by specifying the target\nplatform. For example, to build the `hoprd` image for the `x86_64-linux`\nplatform, while being on a Darwin host system, use the following command:\n\n```bash\nnix build .#packages.x86_64-linux.hoprd-docker\n```\n\nNOTE: Building for different platforms requires nix distributed builds to be\nset up properly.\nSee [Nix documentation](https://nix.dev/manual/nix/2.28/advanced-topics/distributed-builds.html)\nfor more information.\n\n## Local cluster\n\nThe best way to test with multiple HOPR nodes is by using a [local cluster of interconnected nodes](https://github.com/hoprnet/hoprnet/blob/master/SETUP_LOCAL_CLUSTER.md).\n\n## Test\n\nRun all tests: `cargo test`.\n\nRun only unit tests: `cargo test --lib`\n\n### Github Actions CI\n\nWe run a fair amount of automation using Github Actions. To ease development\nof these workflows one can use [act][2] to run workflows locally in a\nDocker environment.\n\nE.g. running the build workflow:\n\n```bash\nact -j build\n```\n\nFor more information please refer to [act][2]'s documentation.\n\n### End-to-End Testing\n\nWhen using the `nix` environment, the test environment preparation and activation is automatic.\n\nTests are using the `pytest` infrastructure.\n\n#### Running Tests Locally\n\n##### Test execution\n\nWith the environment activated, execute the tests locally:\n\n```bash\njust run-smoke-test integration\n```\n\n## Profiling \u0026 Instrumentation\n\nMultiple layers of profiling and instrumentation can be used to debug the `hoprd`:\n\n### `tokio` executor instrumentation\n\nRequires a special build:\n\n1. Set `RUSTFLAGS=\"--cfg tokio_unstable\"` before building\n2. Enable the `prof` feature on the `hoprd` package: `cargo build --feature prof`\n\nOnce an instrumented tokio is built into hoprd, the application can be instrumented by `tokio_console` as described in the [official crate documentation](https://docs.rs/tokio-console/latest/tokio_console/#instrumenting-the-application).\n\n### OpenTelemetry export\n\n`hoprd` can stream OpenTelemetry to a compatible endpoint. This behavior is turned off by default. To enable it, configure these environment variables:\n\n- `HOPRD_USE_OPENTELEMETRY` - `true` to enable the OpenTelemetry streaming, `false` to disable it\n- `HOPRD_OTEL_SIGNALS` - comma-separated signal list from `traces`, `logs`, `metrics` (default: `traces`)\n- `OTEL_SERVICE_NAME` - identifier used as `service.name` for this instance (for example `my_hoprd_instance`)\n- `OTEL_EXPORTER_OTLP_ENDPOINT` - base URL of an OTLP endpoint. Transport is inferred from URL scheme (`grpc://...`, `http://...`, or `https://...`)\n\nExamples:\n\n- Traces only (backward-compatible default): `HOPRD_OTEL_SIGNALS=traces`\n- Metrics only: `HOPRD_OTEL_SIGNALS=metrics`\n- Full export: `HOPRD_OTEL_SIGNALS=traces,logs,metrics`\n- With metrics enabled, OTEL exports keep Prometheus family naming (`\u003cmetric\u003e`, `\u003cmetric\u003e_count`, `\u003cmetric\u003e_sum`, `\u003cmetric\u003e_bucket`) and labels (`le` for histogram buckets, `quantile` for summaries).\n\n### Profiling Criterion benchmarks via `flamegraph`\n\n#### Prerequisites\n\n- `perf` installed on the host system\n- flamegraph (install via e.g. `cargo install flamegraph`)\n\n#### Profiling the benchmarking binaries\n\n1. Perform a build of your chosen benchmark with `--no-rosegment` linker flag:\n\n   ```\n   RUSTFLAGS=\"-Clink-arg=-fuse-ld=lld -Clink-arg=-Wl,--no-rosegment\" cargo bench --no-run -p hopr-crypto-packet\n   ```\n\n   Use `mold` instead of `lld` if needed.\n\n2. Find the built benchmarking binary and check if it contains debug symbols:\n\n   ```\n   readelf -S target/release/deps/packet_benches-ce70d68371e6d19a | grep debug\n   ```\n\n   The output of the above command should contain AT LEAST: `.debug_line`, `.debug_info` and `.debug_loc`\n\n3. Run `flamegraph` on the benchmarking binary of a selected benchmark with a fixed profile time (e.g.: 30 seconds):\n   ```\n   flamegraph -- ./target/release/deps/packet_benches-ce70d68371e6d19a --bench --exact packet_sending_no_precomputation/0_hop_0_surbs --profile-time 30\n   ```\n4. The `flamegraph.svg` will be generated in the project root directory and can be opened in a browser.\n\n### HOPR packet capture\n\nUsing the environment variable `HOPR_CAPTURE_PACKETS` allows capturing customized HOPR packet format to a PCAP file or to a `udpdump` host. Also define the environment variable `HOPR_CAPTURE_PATH_TRIGGER` with a path that will be periodically inspected, and once a file exists on that path, it will start capturing packets.\nHowever, for that to work the `hoprd` binary has to be built with the feature `capture`.\nFor ease of use we provide different nix flake outputs that build the `hoprd`\nwith the `capture` feature enabled:\n\n- `nix build .#hoprd-x86_64-linux-profile`\n- `nix build .#hoprd-aarch64-linux-profile`\n- `nix build .#hoprd-x86_64-darwin-profile`\n- `nix build .#hoprd-aarch64-darwin-profile`\n\n## Contact\n\n- [X](https://x.com/hoprnet)\n- [Telegram](https://t.me/hoprnet)\n- [Medium](https://medium.com/hoprnet)\n- [Reddit](https://www.reddit.com/r/HOPR/)\n- [Email](mailto:contact@hoprnet.org)\n- [Discord](https://discord.gg/5FWSfq7)\n- [Youtube](https://www.youtube.com/channel/UC2DzUtC90LXdW7TfT3igasA)\n\n## License\n\n[GPL v3](https://github.com/hoprnet/hoprnet/blob/master/LICENSE) © HOPR Association\n\n[1]: https://nixos.org/learn.html\n[2]: https://github.com/nektos/act\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoprnet%2Fhoprnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoprnet%2Fhoprnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoprnet%2Fhoprnet/lists"}