* add additional information upon stress testing data submission failure
* split stress testing result submission into batches of maximum size
* enable 'float_roundtrip' serde_json feature to ensure consistent float serialisation
* Squashing the mix stress testing branch (#6575)
reduced chain watcher per block log severity
update network monitors contract semver to 1.0.0
fix build issues
fix mixnet client dropping initial packet on egress reconnection
adjusted logs for network monitor agent
changed default testing interval to 2h
refresh NM contract information
explicit return type for batch submission
for mixnet listener task to get scheduled before beginning connectivity test
make sure to always use canonical ip for network monitor noise keys
feat: NMv3: make agents decide egress port (#6746)
add config v12->v13 config migration for nym nodes
fix formatting in wallet types
simplified client config creation
remove other swagger redirect
removed swagger redirect on /swagger/ route
log version info on startup
add workflows, contract address, and dockerfile
bugfix: use correct endpoints when setting up orchestrator (#6733)
clippy
adjust DEFAULT_MIN_STRESS_TESTED_NODES ratio
expose route with new performance metrics
fixes and additional docs
use stress testing scores
stub for usage of stress testing scores
stub traits
added new fields to nym-api config controlling usage of stress test data
guard against duplicate packets
prevent usage of chain_authorisation_check_max_attempts with value of 0
make sure duplicate results cant be inserted into the db
submit test results from orchestrator on an interval
docs and fixes
nym-api side of handling result submission
stubs for submitting results
NM orchestrator verifying nym-api result submission permissions
NM orchestrator to update announced key on startup
allow NM orchestrator to announce its identity key to the contract
stubs within nym-api for accepting NMv3 results
added additional metrics
docs
bugfixes + making sure to only assign mixnode testruns
fixed node refresher to only retrieve mixnodes and add additional metrics
topology metrics
defined basic prometheus metrics
authorised endpoint for returning prometheus data
create initial stub for prometheus metrics
post rebasing fixes
adjusted routes
missing implementation for storage getters
a lot of new stubs and db accessors
stubs for results endpoints
update utoipa tags for agent rountes
shared auth between metrics and results
moved stale results eviction into the interval.tick branch
refactor and comments
create background process to evict stale data
include sphinx packet delay as part of the stats
fix mock construction
add median to the calculated latency distribution
remove unused imports
cleanup
performing testrun and submitting the results
assigning testruns to requesting agents
basic stub for http server for the NMv3 orchestrator
chore: rename existing 'NetworkMonitorAgent' to 'NodeStressTester'
make sure to use canonical ips within the noise config
fixed contract tests
cargo fmt
additional comments and unit tests
contract and nym-node support of NM agents being run on the same host
basic unit tests
refactoring
make agents retrieve mix port assignment from the orchestrator
provide sensible defaults to CLI arguments
stub the initial structure for the agent
chore: remove redundant import
missed tick behaviour
removed redundant mutex
removed redundant try_get_client
reuse existing constant for default nymnode port
add node refresher for periodic scraping of bonded nym-node details
- NodeRefresher periodically queries the mixnet contract for all bonded
nodes and probes each node's HTTP API for host information, sphinx keys,
noise keys, and key rotation IDs
- Extract NymNodeApiClientRetriever into nym-node-requests with port
probing, identity verification, and host information signature checking
- Add clone_query_client on NyxdClient so the refresher can hold its own
query client without locking the signing client
- Batch upsert for nym_node rows (single transaction instead of per-row)
- Reuse the new helpers in nym-api's node_describe_cache
ensure assignment of testrun begins an IMMEDIATE tx
construction of the orchestrator struct
initial set of cli args
make sure to not assign testable nodes too often
very initial database structure and cli
fixed construction of RoutableNetworkMonitors
remove redundant constructor for NoiseNode
forbid 0-nonsense config values
add type safety for test route construction
moved lioness and arrayref to workspace deps
fixed dockerfile build
always use canonical addresses in RoutableNetworkMonitors
fixed old contract formatting issues
removed redundant into() call
network monitor agent fixes
additional logs
config unit tests
more docs
standalone stress testing invocation
further refactoring and changes
refactor testing loop and return valid test result upon completion
initial sending/receiving test loop
generating reusable sphinx headers
additional structure for receiving ingress packets
initial scaffolding for NMv3 agent
added validation of x25519 noise key
removed unstable call to 'is_multiple_of'
remove calls to from_octets as they're unavailable in pre 1.91
additional docs/comments
propagating noise information about NM for mixnet routing
pass full socket address of the agent into the contract storage
feat: store noise keys alongside ip addresses within the contract
removed redundant comment
ensure NM packets can only go to NM
PR review comments
added additional docs
allow NM to replay packets + fix replay prometheus metrics
propagate information about nm agent to connection handler
updated nym-node config migration
feat: introduced nym-node websocket subscription for keeping updated list of NM agents
allow admin to also revoke monitor agents
remove agents upon orchestrator removal
fixed schema generation and regenerated the contract schema
removed rustc restriction on contracts-common
added client methods for interacting with the contract
added unit tests for contract methods
implemented logic of the network monitors contract
create initial structure for network monitors contract
start mix stress testing topic branch
* make nym-node default to the new blockstream rpc/ws node cluster
* reduced mixnet-client log severity
* set network monitors contract address for mainnet
* start node families topic branch
* start node families topic branch
* initialise node families contract
* define contract storage
* registering new family in storage
* accepting family invitation
* add_pending_invitation
* revoke_pending_invitation
* remove_family_member
* reject_pending_invitation
* disband_family
* added unit tests for the storage methods
* added restriction on uniquness of family names
* update rustc version for node families contract common
* clippy
* basic queries by id
* query_families_paged
* change family membership storage and expose query for all members of a family
* queries for pending invitations
* queries for past invitations
* queries for past data per node
* queries for past family members
* query_past_members_for_node_paged
* queries for family by name and by owner
* fixup family name normalisation
* fixed incorrect lower bound for queries for past data
* implement contract and storage initialisation
* stubbing tx messages that are to be exposed by the contract
* handler for updating config
* removed partial fee return
* wip: create family
* move mixnet contract interaction traits to shared location
* store original family name alongside the normalised variant
* prevent family creation if owner has a node in another family
* try_disband_family
* try_invite_to_family + shared helpers
* try_revoke_family_invitation
* accept_family_invitation
* stub method for node unbonding
* try_reject_family_invitation
* unit tests for family name normalisation
* try_leave_family
* try_kick_from_family
* fix outdated comments and add paid fee event attribute
* feat: NMv3: leave family upon node unbonding
* NF contract handling of unbonding
* lints
* init node families contract when creating performance contract tester
* clippy
* avoid self-dep in the contract dev deps
* introduced client traits for interacting with the node families contract
* add node families contract to cache refresher
* added query for all node family members (globally) and started scaffolding nym-api caches
* docs and cache -> api conversion
* calculating average node age based on individual timestamps
* wire up node families cache
* http stubs
* filled in the implementation
* route tests + extracting shared code
* review fixes
* feat: expose family information for all dvpn gateway endpoints within NS API
* expose family information for explorer v3 route
* clippy
* review comments and optimise db family update
* feat: Node Families: expose stake information inside DVpnGateway
* chore: update lock files after rebase
* chore: sort workspace members
* explicitly require providing node families contract address for mixnet contract migration
* fix missing node families contract address env export
* dont swallow cache overwrite failures in fixture
* pin network-defaults rustc version due to contracts dep
* further version pinning
* chore: update mixnet contract schema
* squashing localnet-v2 commits (again)
cargo fmt
fixes to localnet purge
provide path in the error message
output args
log failed exec
print based on tty
check-prerequisites cmd
checked iptables update
basic kernel features check
enable ipv6 rules
add forwarding rules
squashing localnet-v2 commits
additional changes
propagate custom-dns flag to all run containers
remove is_mock from EcashManager
another localnet squash
unused import
chore: remove redundant testnet manager
missing impl
additional linux fixes
command to rebuild container image
wait for at least 2 blocks
additional node startup fixes
added --custom-dns flag to nym node setup
add gateway probe + wait for DKG magic file
fixed localnet down on linux
container ls
re-enable state resync
additional feature locking
macos adjustments
working nyxd startup on linux
wip linux box
wip
separating network inspect betweewn macos and linux
initial linux feature locking
moved all container commands into a single location
finally working initial node performance
squashing orchestrator commits
cleanup
fixed condition for naive rearrangement
added cache of cosmwasm contracts for speed up on subsequent runs
'down' command
refreshing described cache after nodes are bonded
nym nodes setup + wip on nym api refresh
nodes setup WIP
first pass cleanup
placeholder for nym-node setup
bypassing the dkg
further progress on nym-api setup
wip: api setup
up/down/purge placeholders
persisting contract setup data
fix contract upload by forcing amd64 container platform
wip: contracts setup4
wip: contracts setup3
wip: contracts setup2
wip: contracts setup
include network setup
init and spawn nyxd
build nyxd image in dedicated orchestrator
build nyxd image
squashed cherry-picked lp changes
Bits and bobs to make everything work
Title
MacOS setup instructions
Docker/Container localnet
* clippy
* fixes on non-unix targets
---------
Co-authored-by: durch <durch@users.noreply.github.com>
* feat: introduce /v3/unstable/nym-nodes/semi-skimmed to aggregate LP information
nym-nodes will require this information to establish shared PSQ
* reorganised imports
* merging georgio/lp-psqv2-integration
* use authenicator on the responder's side
* nym-lp crate compiling
* moved the e2e test to nym-lp
* move key generation to peer
* moved principal generation
* update KKTResponder
* encapsulation key parsing
* Adding concrete types within KKT exchange
* initiator side of the full handshake
* responder side of the handshake and full e2e test
* fixed unit-tests within nym-kkt
* LpSession cleanup
* helpers for Transport
* revamp of the transport traits and initial work on client-side transport
* compiling nym-crypto
* 'working' client-entry dvpn reg
* Fix key conversion
* Slightly reduce use of rand08
* reverted back to libcrux repo refs
* intial telescoping reg
* removing dead code
* wip
* moved data encryption into the state machine
* restoring nym-lp tests
* update lp api model
* Add receiver index derivation
* Add receiver index derivation
* use derived receiver index
* feat: add kem key generation to nodes
* generate fresh x25519, mlkem768 and mceliece keys on config migration
* add lp peer config
* nym-node startup cleanup
* removed dependency on pre-rand09 from nym-lp
* re-expose LP information on the http API
* fixed tests compilation
* add peer config happy path tests
* formatting
* add more tests and fix bug
* better docs
* clippy and formatting issues
* return error on mceliece within NestedSession
* wasm fixes
* removed legacy nym-vpn-lib-wasm
* fixing wasm for real this time
* additional fixes
* add payload to kkt
* make clippy happy
* moved LP to nym-node crate
* cargo fmt
* integrate lpconfig payload
* fix response size trait impl
* Migrate receiver index
* Change receiver index to u32 and regorganize crates
* clippy
* hopefully final wasm fixes
* simple conversion method from semver to ciphersuite
* updated nym-node config template
* chore: remove duplicated code
---------
Co-authored-by: Georgio Nicolas <me@georgio.xyz>
* use x25519 noise key for ktt instead of deriving one from ed25519
* removed client's IpAddr from RegistrationClient constructor
* Adjusted the gateway probe to inject correct lp data
* remove redundant argument from nym-lp-client
* consistent naming for HashFunction variants
* use workspace dep import for nym-kkt-ciphersuite
* struct renaming
* announce KEM key hashes and use generated value within LpStateMachine
* added digest of remote KEM key into LpSession
* changed constructor to LpSession to take explicit key materials for local and remote
this makes it easier to change keys required by each party without having to change all the interfaces everywhere again
* extended the changes to LpStateMachine constructor
* modify the interface to LpRegistrationHandler and LpListener
* gateway probe fixes
* temp nym-lp-client fixes
* review nits
* remove network test
* introduced v2/nym-nodes/described endpoint for returning nodes description alongside LP data
* missed V1 -> V2 description replacements
* removed deprecated call within mix-fetch
* use old v1 call in network stats
* - standardise versions for all nym-sdk workspace dependencies
- prepend sqlx-pool-guard with 'nym-'
* Test remove nym-api from deps
* Add oneliner to client_pool doc comments
* Add note to commented out docs.rs link in sdk
* remove nym-api from script
* add publishing file
* bring non-binary / contract / tools into workspace version
* added more info to publishing.md
* make deps workspace version
* remove uploaded sphinx-types crate from script
* remove erroueously included ignore-defaults
* add zeroise to feature
* chore: Release
* add topology to batch
* more cargo versioning
* more cargo versioning - wasm utils
* more cargo versioning - wasm utils
* Add publish=false to manifest for cargo workspaces / crates.io
publishing exclusion
* remove script now switched to manifest based exclusion
* rename import based on rename of contracts-common dep
* Making workspace versions for publication + removing unnecessary crates
from publication
* Remove OOD info from publishing sdk guide
* rename contract imports + remove package
* temp commit: continuing with removal of path from cargo manifest and
replacing with workspace version import for publication
* continuing with cargo.toml updates
* dryrun only erroring on known version problem crates
* remove old published-crates file
* Minor comment change
* remove default features warning
* Additional info on workspace dep comment re publish list
* Add missing description to cargo.toml
* Fix missing feature flags
* Add missing descriptions
* Fix remaining path import
* Add workspace repo / homepage / documentation links to cargo.toml files
* remove workspace version from excluded crate
* Remove todo descriptions
* Minor comment change
* add homepage etc
* move from bls git import to nym_bls_fork crate
* Modify rest of imports from path to workspace import, excluding binaries
* add directory/homepage info
* fix cargo fmt
* add notes to gitignore
* better solution to contracts/ experiment
* wasm -> nym_wasm crate renaming
* fix fatfinger
* add metadata to ecash cargo.toml
* stub publishing guide
* fix misrevolved netlink- version
* Fixes and block publication of rebase re: LP
* first pass @ workflows
* Add KKT cryptographic primitives
Post-quantum Key Encapsulation Mechanism (KEM) Key Transfer protocol.
Enables efficient distribution of post-quantum KEM public keys.
Squashed from georgio/noise-psq branch.
* Implement LP registration protocol with KKT/PSQ integration
Initial implementation of the Lewes Protocol (LP) for gateway registration:
- Add nym-lp crate with Noise protocol handshake
- Add LP listener to gateway for handling registrations
- Add LP client for registration flow
- Integrate KKT for post-quantum KEM key exchange
- Integrate PSQ for post-quantum PSK derivation
- Add Ed25519 authentication throughout
- Add docker/localnet support for testing
Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
* Add LP telescoping with nested sessions and subsession support
Extends LP protocol with telescoping architecture for nested sessions:
- Add nested session support with KKpsk0 rekeying
- Add subsession support with collision detection
- Implement unified packet format with outer header
- Refactor gateway handlers for single-packet forwarding
- Add TTL-based state cleanup for stale sessions
- Add outer AEAD encryption layer
- Refactor registration client for packet-per-connection model
* Add gateway-probe localnet mode with WireGuard tunnel support
Adds localnet testing mode to gateway-probe for LP development:
- Add TestMode enum for different probe configurations
- Add --gateway-ip flag for direct gateway testing
- Implement two-hop WireGuard tunnel for localnet
- Add mock ecash support for testing without real credentials
- Add netstack Go bindings for userspace networking
- Restructure probe with mode and common modules
- Update README with localnet mode documentation
* Increase KCP fragment limit from u8 to u16
- Change frg field from u8 to u16 in packet header (25 bytes total)
- Update encode/decode to use get_u16_le/put_u16_le
- Update Segment struct frg field to u16
- Remove truncating cast in session.rs
- Max message size now ~91MB (65,535 fragments × MTU)
- Internal protocol only, no interop concerns
Nym uses KCP for reliability and multiplexing, not standard real-time
use cases. The u8 limit (255 fragments, ~355KB) was insufficient.
Addresses: nym-yih9
* Zeroize Ed25519 key material in to_x25519 conversion
Wrap hash and x25519_bytes in zeroize::Zeroizing to ensure private
key material is cleared from memory after use.
Closes: nym-k55g
* Return Result from KCP session input() for error detection
Change KcpSession::input() to return Result<(), KcpError> so callers
can detect invalid packets instead of silently ignoring them.
- Add ConvMismatch error variant for conversation ID mismatches
- Update driver to propagate errors from session.input()
- Update all test and example callers
Closes: nym-n0kk
* Fix Zeroizing deref in ed25519 to_x25519 conversion
The from_bytes() function expects &[u8], need to deref the Zeroizing
wrapper to get the inner array.
* Add semaphore-based connection limiting for LP packet forwarding
Limits concurrent outbound connections when forwarding LP packets to
prevent file descriptor exhaustion under high load.
Key changes:
- Add max_concurrent_forwards config (default 1000)
- Add forward_semaphore to LpHandlerState
- Acquire semaphore permit before connecting in handle_forward_packet
- Return "Gateway at forward capacity" error when at limit
This provides load signaling so clients can choose another gateway
when the current one is overloaded.
Design note: Connection pooling was considered but provides minimal
benefit since telescope setup is one-time and targets are distributed
across many different gateways. See AIDEV-NOTE in LpHandlerState for
full analysis.
Closes: nym-xi3m
* Return error on session unavailable in handle_subsession_packet
Replace .session().ok() with proper error handling to fail fast when
session is Closed or Processing after state machine processing.
Previously, the code silently continued with outer_key = None, which
could cause protocol errors downstream.
Closes: nym-8de0
* Use explicit bincode Options helper in nested_session
Add bincode_options() helper that returns DefaultOptions with explicit
big_endian and varint_encoding configuration. This future-proofs against
bincode 1.x/2.x default changes and makes serialization format explicit.
Updated all 4 bincode usages in nested_session.rs to use the helper.
* Deduplicate outer_key lookup pattern in nested_session.rs
Extract common state_machine.session().ok().and_then(...) pattern into
two helper methods:
- get_send_key() for encryption (outer_aead_key_for_sending)
- get_recv_key() for decryption (outer_aead_key)
Updated 6 call sites to use the helpers, reducing verbosity.
* Add LpConfig struct and AIDEV-NOTE documentation for KKT+PSQ
- Create config.rs with LpConfig struct (kem_algorithm, psk_ttl, enable_kkt)
- Export LpConfig from lib.rs
- Add AIDEV-NOTE to psk.rs explaining:
- Why PSQ is embedded in Noise (single round-trip, PSK binding)
- KEM migration path (X25519 → MlKem768 → XWing)
- Add AIDEV-NOTE to state_machine.rs explaining protocol flow:
- KKTExchange → Handshaking → Transport state transitions
- PSK derivation formula (ECDH || PSQ || salt)
* Add forward_timeout to LP client config
Add forward_timeout (30s default) to LpConfig and wrap send_forward_packet's
connect_send_receive call with tokio::time::timeout, matching the pattern
used by register() with registration_timeout.
This prevents indefinite hangs when forwarding packets through entry gateway.
* Add negotiated_version field to LpSession
Add AtomicU8 field to store the protocol version from handshake packet
headers. Includes getter and setter methods for future version negotiation
and compatibility checks.
- negotiated_version() returns current version (defaults to 1)
- set_negotiated_version() allows setting during handshake
- Subsessions inherit version 1 (can be enhanced to inherit parent's)
* Change MessageType from u16 to u32
Breaking wire protocol change: MessageType field increased from 2 bytes
to 4 bytes in LP packets. This future-proofs the message type space and
aligns with other u32 fields.
Changes:
- message.rs: #[repr(u32)], from_u32(), to_u32()
- error.rs: InvalidMessageType(u32)
- codec.rs: All serialization/deserialization updated to 4-byte msg_type
- Cleartext parsing: inner_bytes[4..8], content at [8..]
- AEAD parsing: decrypted[4..8], content at [8..]
- Serialization: 4 bytes for message type
* Various smaller fixes
* Refactor LP to stream-oriented TCP processing
Gateway (handler.rs):
- Add bound_receiver_idx field for session-affine connections
- Convert handle() from single-packet to loop with EOF detection
- Add validate_or_set_binding() for receiver_idx validation
- Set binding in handle_client_hello after collision check
- Centralize emit_lifecycle_metrics in main loop only
- Add is_connection_closed() helper for graceful EOF
Client (client.rs):
- Add stream field for persistent TCP connection
- Add ensure_connected(), send_packet(), receive_packet(), close() methods
- Modify perform_handshake_inner() to use persistent stream
- Modify register_with_credential() to use persistent stream
- Modify send_forward_packet() to use persistent stream
- Keep connect_send_receive() for reference (marked dead_code)
This reduces handshake overhead from ~5 TCP connections to 1.
Drive-by: Fix log::info! -> info! in wireguard peer_controller.rs
* Add persistent exit stream for entry→exit forwarding
Entry gateway now maintains a persistent TCP connection to the exit
gateway per client session, reusing it for all forward requests from
that client. This reduces TCP handshake overhead significantly.
Key changes:
- Add exit_stream: Option<(TcpStream, SocketAddr)> to LpConnectionHandler
- Modify handle_forward_packet() to open on first forward, reuse after
- Clear exit_stream on connection errors (auto-reconnect on next forward)
- Semaphore only acquired for connection opens, not reuse (sequential access)
* Fix code review issues for stream-oriented LP
- Add 30s timeout to exit stream I/O operations (nym-df31)
Prevents handler from hanging on unresponsive exit gateway
- Return error on forward target address mismatch (nym-zegu)
Previously warned and proceeded, which could mask bugs
- Close client stream on handshake error paths (nym-scvm)
Prevents state machine inconsistency on timeout or failure
* Add LP registration idempotency and retry logic
Make LP registration resilient to network failures that could waste
credentials. When registration succeeds on the gateway but the response
is lost (e.g., network drop), clients can retry with the same WG key
and get the cached result instead of spending another credential.
Gateway-side:
- Add check_existing_registration() helper that looks up WG peer and
returns cached GatewayData if already registered
- Add idempotency check in process_registration() dVPN branch
- Only return cached response if bandwidth > 0 (ensures registration
was actually completed, not just peer created)
- Track idempotent registrations with lp_registration_dvpn_idempotent metric
Client-side:
- Add register_with_retry() to LpRegistrationClient that acquires
credential once and retries handshake+registration on failure
- Add handshake_and_register_with_retry() to NestedLpSession for
exit gateway registration via forwarding
- Add exponential backoff with jitter between retry attempts
- Verify outer session validity before nested session retry
Both retry methods clear state machine before retry to ensure fresh
handshake, and reuse the same credential across all attempts.
* Add no-mix-acks feature flag to nym-sphinx-framing
When enabled, mix nodes skip ack extraction and forwarding entirely.
The full payload (including ack portion) is returned as the message.
Closes: nym-3wrr
* Create nym-lp-speedtest crate scaffold
- Created tools/nym-lp-speedtest/ with Cargo.toml
- Added main.rs with CLI argument parsing
- Created stub modules: client.rs, speedtest.rs, topology.rs
- Added to workspace members
- Verified compilation with cargo check
* Implement topology fetching for nym-lp-speedtest
- Add topology.rs with NymTopology integration
- Fetch mix nodes and gateways from nym-api
- Build GatewayInfo with LP addresses (port 41264)
- Provide random_route_to_gateway() for Sphinx routing
- Add required Cargo.toml dependencies
* Implement LP+Sphinx+KCP client with SURB support
- Add send_data() and send_data_with_surbs() methods for mixnet data
- Integrate KCP reliable delivery with Sphinx packet construction
- Add x25519 encryption keypair for SURB reply mechanism
- Wire up main.rs to test LP handshake and data path
- Add NymRouteProvider support in topology for SURB construction
- Refactor send_data() to delegate to send_data_with_surbs(0) (DRY)
The client can now:
- Perform LP handshake with gateways
- Send data through the mixnet wrapped in KCP + Sphinx packets
- Attach SURBs for bidirectional communication
- Return encryption keys for decrypting replies
* Rename nym-lp-speedtest to nym-lp-client and fix KCP bug
- Rename crate from nym-lp-speedtest to nym-lp-client
- Fix KCP bug: add driver.update() call before fetch_outgoing()
Without update(), KCP never moves segments from snd_queue to snd_buf
- Update CLI name, about string, and user agent to match new name
* Add LP mixnet mode registration with nym address return
- Extend RegistrationMode::Mixnet to include client_ed25519_pubkey
and client_x25519_pubkey for nym address construction
- Add LpGatewayData struct containing gateway_identity and
gateway_sphinx_key for SURB reply routing
- Add lp_gateway_data field to LpRegistrationResponse for mixnet mode
- Implement success_mixnet() constructor for mixnet registrations
- Update gateway registration to insert clients into ActiveClientsStore
for SURB reply delivery, matching the websocket flow
* Implement LP data handler on UDP:51264
- Add LpDataHandler for UDP data plane (port 51264)
- Decrypt LP layer and forward Sphinx packets to mixnet
- Add outbound_mix_sender to LpHandlerState
- Integrate data handler spawn into LpListener::run()
- Add metrics for data packets received/forwarded/errors
Implements nym-yzzm
* Fix replay protection vulnerability in LP data handler
Use state machine process_input() instead of manual decryption to ensure
proper replay protection:
- Counter check against receiving window
- Counter marking after successful decryption
Also handle subsession actions gracefully (SendPacket ignored on UDP,
clients should use TCP control plane for rekeying).
Security fix for nym-yzzm implementation.
* feat(ipr): add KcpSessionManager for LP client KCP handling
- Add fetch_incoming() and recv() methods to KcpDriver for retrieving
reassembled messages
- Create KcpSessionManager in ip-packet-router that manages KCP sessions
keyed by conv_id (first 4 bytes of KCP packet header)
- Store ReplySurbs per session for sending anonymous replies
- Implement session timeout (5 min) and max sessions limit (10000)
- Add comprehensive tests for session lifecycle and KCP roundtrip
* feat(ipr): integrate KcpSessionManager into MixnetListener
- Add KcpSessionManager field to MixnetListener struct
- Add is_kcp_message() helper to detect KCP-wrapped payloads
- Add on_kcp_message() to process LP client KCP messages
- Refactor on_reconstructed_message() to route KCP vs regular IPR
- Add KCP tick timer (100ms) for session updates and cleanup
- Initialize KcpSessionManager in IpPacketRouter::run_service_provider()
KCP messages are detected by checking byte 4 for valid KCP commands
(81-84), which doesn't conflict with IPR protocol version bytes (6-8)
at position 0.
Closes: nym-96zl
* fix(ipr): prevent KCP detection false positives on IPR messages
Add secondary check in is_kcp_message() to exclude messages that match
IPR protocol header pattern (version 6-8 at byte 0, ServiceProviderType
0-2 at byte 1). This prevents false positives where IPR messages with
byte 4 in range 81-84 would be incorrectly routed to KCP processing.
Added 4 unit tests to validate the detection logic.
Closes: nym-6f3x
* fix(ipr): wrap KCP client responses in KCP before SURB reply
- Modify on_kcp_message to handle responses directly instead of returning them
- Add handle_kcp_response method that wraps response in KCP and sends via mixnet
- Ensures KCP clients receive KCP-wrapped responses for proper reassembly
Closes: nym-7oh2
* fix(ipr): send KCP protocol packets in tick instead of just logging
- Add get_sender_tag() and fetch_outgoing_for_conv() to KcpSessionManager
- Change handle_kcp_tick() to actually send ACKs/retransmissions via mixnet
- Reduce KCP tick interval from 100ms to 10ms for better responsiveness
This fixes the KCP reliability protocol which was broken because
protocol packets (ACKs, retransmissions) were generated but never sent.
* feat(lp-client): wrap payload in IpPacketRequest before KCP
- Add nym-ip-packet-requests and bytes dependencies
- Wrap payload in IpPacketRequest::new_data_request() before sending to KCP
- Add LP_DATA_PORT constant (51264) and lp_data_address field to GatewayInfo
This ensures IPR can properly parse incoming messages as DataRequest.
LP framing (wrapping Sphinx in LP before sending) is a separate task.
* feat(lp-client): add LP session management and UDP data plane support
- Add wrap_data() and session_id() to LpRegistrationClient for LP packet
creation after handshake
- Add init_lp_session() and close_lp_session() to SpeedtestClient for
managing LP sessions
- Extract prepare_sphinx_fragments() helper to reduce code duplication
between send_data_with_surbs() and send_data_via_lp()
- Add send_data_via_lp() for sending Sphinx packets through LP's UDP
data plane (port 51264)
The LP session is kept alive after TCP handshake closes, allowing
subsequent wrap_data() calls for UDP transmission without re-handshaking.
* random formatting
* replaced all instances of bincode::serialize and bincode::deserialize with explicit lp_bincode_serialiser() within the LP
* additional formatting
* removed source of possible panic from nym-kkt
invalid KEM mapping will now return an Err rather than panicking
* integration test for LP entry registration
This includes creation of mocks of various gateway-related components, such as the PeerController
* changed ClientHelloData serialisation
the old variant using bincode did not produce constant-length output in some cases
* Fixed generation of receiver index
removes the possible clash with the boostrap id
* Integration test for nested LP registration
- move `LpTransport` trait definition to shared `nym-lp-transport` crate
- make transport layer within `LpConnectionHandler` generic with respect to the forwarding target. it must, however, use the same type as the incoming client connection
- extracted explicit `LpConnectionHandler::establish_exit_stream` to more easily modify it in the future to fully protect the channel and disallow using untrusted egress points
- fix additional log-string interpolation nits
* resolved clippy issues pointed out by clippy 1.91
* added LP discovery into self-described endpoint:
- removed changes to the node bonding within the contract
- introduced '/api/v1/lewes-protocol' route within nym-node http api
- added 'lewes_protocol' field to 'NymNodeData' inside of NymNodeDescription
- refactored LpConfig to allow separate bind and announce addresses and used more strict typing
* chore: allow unwrap/expect within kkt benchmarking code
* chore: downgraded sha2 dep for cosmwasm compatibility
* clippy
* marking simd calls as unsafe
* fixed calls to '_mm_testz_si128'
* additional clippy fixes
---------
Co-authored-by: Georgio Nicolas <me@georgio.xyz>
Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
* remove [most of] legacy data from nym-api endpoints
* chore: removed contamination with legacy nodes data
* added /v1/nym-nodes/stake-saturation/{node_id}
* added /v1/legacy/mixnodes and /v1/legacy/gateways
* removed scraping of legacy mixnodes in NS api
* remove export of removed types
* huge warnings on attempting to use removed commands in the wallet
* fixed reference to removed type in tests
* feat: unify HTTP client creation and enable domain fronting
Enhanced the base nym_http_api_client to reduce fragmentation and enable domain fronting:
- Added SerializationFormat enum for explicit JSON/bincode choice (no auto-detection)
- Added from_network() method to create clients from NymNetworkDetails with domain fronting
- Added with_bincode() builder method for explicit serialization configuration
- Set Accept header based on serialization preference
- Added deprecation paths for NymApiClient wrapper and nym_api::Client re-export
- Enabled domain fronting support via network defaults feature
This is part of a broader effort to consolidate HTTP client implementations across the codebase,
reducing ~500 lines of wrapper code and providing automatic domain fronting for censorship resistance.
* feat: migrate NymApiClient usage to unified HTTP client
- Wire up domain fronting configuration in NymNetworkDetails
- Implement NymApiClientExt trait for base nym_http_api_client::Client
- Migrate direct NymApiClient usage in multiple components:
- nym-network-monitor
- verloc measurements
- connection tester
- coconut/ecash client
- validator rewarder
- Add Copy derive to ApiUrlConst to enable iteration
- Update error handling and Display implementations
This enables automatic domain fronting for all Nym API calls via the configured CDN front hosts.
* fix: resolve all compilation errors after NymApiClient migration
- Add missing nym-http-api-client dependencies to multiple crates
- Add NymApiClientExt trait imports where needed
- Fix type mismatches from NymApiClient to unified Client
- Add error conversions for NymAPIError in various error enums
- Implement missing trait methods (get_current_rewarded_set, get_all_basic_nodes_with_metadata, get_all_described_nodes)
- Fix type conversions for RewardedSetResponse in network monitor
- Update all API client instantiation to use new unified HTTP client
* feat: complete migration to unified HTTP client and fix all compilation errors
- Added missing NymApiClientExt trait methods (get_all_expanded_nodes, change_base_urls)
- Fixed all compilation errors across the workspace
- Updated nym-node to use unified client instead of deprecated NymApiClient
- Fixed type conversions for RewardedSetResponse → EpochRewardedSet
- Added nym-http-api-client dependency where needed
- Updated all examples and documentation to use new client API
* fix: provide all API URLs for automatic failover in endpoint rotation
Previously, when rotating API endpoints, only a single URL was provided to the
HTTP client, defeating the purpose of having multiple URLs for resilience.
Changes:
- NymApiTopologyProvider now provides all URLs in rotated order when switching endpoints
- NymApisClient similarly provides all URLs starting from the working endpoint
- Added clarifying comments for broadcast/exhaustive query methods where single URLs are intentionally used
- This enables the HTTP client's built-in failover mechanism while maintaining endpoint rotation behavior
The fix ensures that if the primary endpoint fails, the client can automatically
failover to alternative endpoints without manual intervention, improving overall
network resilience.
* Update common/client-core/src/client/base_client/mod.rs
Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
* Remove error generics, address PR comments
* Explicit warning on missing fronting configuration
* Assorted CI fixes
* Registry proc-macro
* Rename macro
* Syn workspace version
* Where do we need to put inventory
* Ergonomics and call sites, incept the builder
* fix: Address critical issues in client configuration registry implementation
- Fixed HeaderMapInit parsing bug that would cause compilation errors
- Added comprehensive documentation with usage examples and DSL reference
- Improved error handling with better error messages for invalid headers
- Added test coverage for both macro and registry functionality
- Added debug inspection capabilities for registered configurations
- Fixed module name conflicts in tests by using separate modules
All tests now passing:
- 7 macro tests validating DSL parsing and code generation
- 4 registry tests verifying configuration collection and application
* Use default value for the ports until api is deployed
* Feature/improved http error (#6025)
* use display impl for urls
* feat: attempt to add more details to reqwest errors
* temporarily restored GenericRequestFailure variant
* another restoration
* cleanup
* Some debug tooling, and default timeout fix
* Fix user-agent override
* Fix various wasm things
---------
Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
Co-authored-by: Bogdan-Ștefan Neacşu <bogdan@nymtech.net>
* node-status-api: fix missing monikers because of deserialisation issues from unstructured data
* node-status-api: bump version after bug fix monikers
---------
Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
delay to gruyere
chore: delay to Feta
added threshold information to the response
nym api test clippy
bugfixes and endpoint improvements
expose results on api endpoints
wip: making nym api monitor network signers
added fallback legacy queries to get basic support idea
refactored the code to expose bool-only methods for status
ecash-signer-check lib for obtaining basic ecash signer information
* wip: changes to surb logic + stronger db typing
* surb invalidation logic
* chore: remove unused deps
* resolving todos
* a lot of additional bugfixes
* 1.88 clippy
* wasm fixes
* wasm clippy
* wallet clippy
* wait for epoch end when setting up new network
* split ReplyController into Sender and Receiver for easier reasoning
* additional reply surbs improvements
includes, but is not limited to: unconditionally reseting sender tag on restart, limiting number of surb re-requests, resetting stale surbs on load
* fixed calculation of number of removed surbs
* add additional calculated field to key rotation info
* DBG: 'request_reply_surbs_for_queue_clearing' temp logs
* fixes for silly mistakes
* conditionally reduce log severity
* renamed nym-api config fields
* decouple rewarder startup from network monitor
* additional sections in nym-api config
* removed vesting queries in circulating supply calculator
* added memoized field for last submitted performance measurement
* wip: performance contract refresher
* cleaned up various contract caches
* modified cache refresher to allow passing update fn
* implement performance cache refreshing
* updated lefthook.yml to run cargo fmt
* impl NodePerformanceProvider trait
* dynamically using specific performance provider
* pre warm up performance contract cache and forbid the mode if its empty
* clippy
* introduce fallback setting for performance contract if value for given epoch is not available
* move some functions around
* wip
* wip: wrap node's sphinx key with a manager
* wip: choosing correct key for packet processing
* further propagation of key rotation information
* attaching key rotation information to reply surbs
* added basic key rotation information to mixnet contract
* wip: introducing cached queries for key rotation info from nym api
* unified nym-api contract cache refreshing
* finish packet decoding
* multi api client + retrieving rotation id
* rotating sphinx key files
* logic for migrating config file
* wip: putting new sphinx keys to self described endpoints
* processing loop of KeyRotationController
* fixed sphinx key loading
* rotating bloomfilters
* wired up KeyRotationController
* flushing bloomfilters to disk and loading
* most of nym-node changes
* post rebase fixes
* fixes due to backwards compatible hostkeys
* split http state.rs file
* dont use deprecated fields
* fixed backwards compatible deserialisation of host information
* split up node describe cache
* added a dedicated CacheRefresher listener to perform full refresh outside the set interval
* controlling announced sphinx keys within nym-api
* retrieving rotation id when pulling topology
* split nym-nodes http handlers
* v2 nym-api endpoints to retrieve nodes with additional metadata information
* bug fixes...
* additional bugfixes and guards against stuck epoch
* testnet manager: set first nym-api as the rewarder
* fixed host information deserialisation
* fixed panic during first key rotation
* post rebase fixes
* clippy
* more guards against stuck epochs
* added helper method to reset node's sphinx key
* instantiate mixnet contract with custom key rotation validity
* additional bugfixes and debugging nym-api deadlock
* passing shutdown to nym apis client
* remove dead test
* post rebasing fixes
* missing MixnetQueryClient variants
* remove usage of deprecated methods in sdk example
* fix: incorrect method signature
* post rebasing fixes
* attempt to retrieve key rotation id before doing any config migration work
* ignore tests relying on networking behaviour
* allow networking failures in certain tests
* change ticketbook data request to allow for pagination
* implemented api endpoints on nym-api side
* auxiliary nym-api queries for number of issued ticketbooks
* ensure that challenged issuers support new queries
* addeed persistent identity to the rewarder
* clippy
* stupid chrono feature workaround
* clippy
* debugging issuance verification
* remove redundant closure
* added a minimum issuance threshold
* new NymNodeTopologyProvider to also keep track of ips of all nodes
* added nym-api endpoint for nodes existence by ip
* change behaviour of updating allowed nodes alongside the topology
* clippy
* license fix
* fix default filtering limit
* nym-api endpoint to return latest block information
* attached chain health to health query
* fixed serde casing
* one of the most nastiest work arounds in test code
* wip
* changed minor/patch weights and introduced full release chain history for more accurate calculations
* clippy
* updated contract schema
* added nym-api endpoint for current rewarded set nodes
* added nym-api endpoint for internal config score data
* guard mixnet contract against decreasing semver
* fixed config score calculation if there are skipped versions
* fixed pagination for querying for validators
* wip: decoupling block signing from ticketbook issuance
* added ecash contract query for latest deposit
* parking the branch: wrappers for merkle tree for issued ticketbooks
* make nym-api store merkle trees of issued ticketbooks
* nym-api route for returning all deposits alongside merkle root
* return index alongside deposit id
* persisting merkle index alongside issued ticketbook details
* wip
* responses for issued deposit challenges
* nym-api cleanup
* verification of issued partial ticketbooks
* cleanup of rewarder code
* make the rest of codebase compile
* updated config file
* improved logging
* fixed division by zero if there were no ticketbooks issued in a day
* using correct budget when rewarding operators
* fixed routes for issued data
* fixed ecash test fixture
* fixed incorrect deserialisation of expiration_date param
* additional bugfixes for ticketbook issuance
* more fixes and updated tests
* fixed formatting after rebasing
* updated schema
* fixed edge case unit test
* added config-score related parameters to the mixnet contract
* weaved in described_cache into NodeStatusCacheRefresher
* adding config score annotation
* using new updated performance for updating rewarded set
* using new values for rewarding
* clippy
* updated contract schema
* wallet fixes
* fixed wasm build