Commit Graph

2797 Commits

Author SHA1 Message Date
Fintan Halpenny d596b14e48 build: Pin Zig to 0.13.0
Control the version of Zig that is being downloaded rather than getting
it via the Alpine Package Keeper.

Version 0.13.0 is chosen so that it can correctly recognise MacOS TBD
v4 which is required due to the introduction of the IOKit in the
bundled `macos-sdk-11.3`.
2026-02-19 21:02:22 +01:00
Fintan Halpenny 4c759a2674 build: Update macos-sdk to include IOKit, libconv, and libcharset
The `build/macos-sdk.tar.xz` is a slimmed down bundle of the required
SDKs to build Radicle on MacOS.
IOKit, libconv, and libcharset were retrieved from
`phracker/MacOSX-SDKs`, see <https://github.com/phracker/MacOSX-SDKs>.
2026-02-19 21:02:22 +01:00
Fintan Halpenny 57a44daeb2 build: Update cargo-zigbuild to 0.22.1 2026-02-19 21:02:22 +01:00
Fintan Halpenny 89478b16fe cargo/git2: Update to 0.20.4
Update to `git2` to 0.20.4` and `radicle-surf` to 0.27.0.

This fixes a low severity vulnerability[^0].

[^0]: https://github.com/advisories/GHSA-j39j-6gw9-jw6h
2026-02-19 20:57:18 +01:00
Fintan Halpenny 423cf604e1 nix: update to 25.11
Obtain the latest tooling for the project by updating the nixpkgs
release to 25.11.
2026-02-18 09:50:16 +00:00
Lorenz Leutgeb 30701cc6fb node/runtime: Make `Runtime::run` more readable
A small refactoring that reorders arms of a match and makes them shorter
by precise imports.
2026-02-18 09:36:49 +00:00
Lorenz Leutgeb 057edf55b8 node/reactor: Introduce `LAG_TIMEOUT`
Since the service performs further I/O (e.g. uses SQLite), it can keep
the reactor runtime thread busy for long periods. Emit a warning if that
is the case.

100 ms is quite relaxed, this is to only catch severe cases and avoid
spamming the log.
2026-02-18 09:36:49 +00:00
Lorenz Leutgeb ae06111e07 node/reactor: Rewrite `Runtime::run`
More commentary and slight refactoring in `Runtime::run` to improve
readability.
2026-02-18 09:36:49 +00:00
Lorenz Leutgeb 4d7b942b75
remote-helper: Rename `to_branch_name`
Since `to_branch_name` consumes `self`, it should better be called
`into_branch_name`.

See also
<https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention>.
2026-02-18 00:07:49 +01:00
Lorenz Leutgeb 6d2a99e1ae
remote-helper: Remove Unused Error Variants
Previous minimization of visibility modifiers enables automated
removal of these unused variants.
2026-02-18 00:07:49 +01:00
Lorenz Leutgeb a69420b9b7
remote-helper: Rework Visibility Modifiers
Since this is a binary crate, `pub` is not necessary. By removing `pub`
at the boundary of the crate (`src/main.rs`) and working our way in we
obtain tighter boundaries. This enables dead-code elimination and more
liberal lints (see following two commits).
2026-02-18 00:07:49 +01:00
Adrian Duke d36ed7c8af remote-helper/protocol: Introduce Line and Command
A new module to model the domain of protocol lines and commands
being exchanged is introduced.

This is to increase readability and to pave the way for a
future sans I/O version of the binary crate.

Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.xyz>
2026-02-18 00:07:35 +01:00
Adrian Duke 27493c2229 remote-helper/service: Introduce `NodeSession`
Prefactor to add a trait capturing behaviour of the node.
2026-02-18 00:04:14 +01:00
Adrian Duke 56253b529e remote-helper/service: Introduce `GitService`
Prefactor to introduce `trait GitService` around the behaviour of
`fetch_pack` and `send_pack`.
2026-02-18 00:03:00 +01:00
Adrian Duke bd30e80b9a remote-helper/list: Remove printing to stdio
Prefactor to aid testing.
2026-02-18 00:00:14 +01:00
Lorenz Leutgeb 119445ce6c
cli-test: Move `let mut args` closer to its uses
In case a `cd` command is to be processed, no replacement of
environment variables in arguments is performed. This means that the
definition of `let mut args` and the replacement itself can be moved
closer to where `args` is then actually used, which is easier to
reason about.
2026-02-17 20:19:26 +01:00
Lorenz Leutgeb 56ece480ee
cli-test: Remove special handling for `rad`
The special handling for `rad` was introduced in commit
`e63f33489055962845c70976bd9a40d0d84c6b1c` without further comment.

Since we control the `$PATH` for spawning `rad`, and it is clear
that `rad` must be on the path, we do not need any special handing.

See also:
 - https://doc.rust-lang.org/std/process/struct.Command.html#method.new
 - https://github.com/rust-lang/rust/issues/15149
 - https://github.com/rust-lang/rust/issues/37519
2026-02-17 20:16:29 +01:00
Lorenz Leutgeb 3cd1af1dd5
cli-test: Configure `escargot` properly
Configuration calls to `escargot` were removed in commit `4894657b`.
An unintentional consequence are spurious failures to invoke freshly
compiled binaries in CLI tests.

Bring back the explicit configuration to remedy.
2026-02-17 18:59:59 +01:00
Lorenz Leutgeb 5aca9bf16a
cli-test: Refactor Path Handling
In the previous refactoring in commit `4894657b`, the order of entries
in `$PATH` was changed unintentionally. Revisit the order and use
nicer APIs to handle paths.
2026-02-17 18:59:59 +01:00
Adrian Duke d88ef3fa66 e2e: Introduce 3 tests for block command
1. It disconnects an active connection.
2. A blocked peer can not connect to us.
3. A blocked peer can not be fetched from.
2026-02-17 16:12:04 +01:00
Fintan Halpenny a4806f2718 node/test: check remote events for `Event::PeerDisconnected`
The node being connected to may be blocking the connecting node.
In this case the service will emit an event that says the connecting
node is disconnected.

Check the events for this event as well as `Event::PeerConnected`.
2026-02-17 16:12:04 +01:00
Adrian Duke 1fa14ef529 protocol/service: Use block list for connections
The service learns to consult the policies database to check if a
`NodeId` is blocked.

When a node is blocked the service will prevent any inbound or
outbound connection.

In the case of an inbound connection, a disconnect must be submitted
to the reactor.

In the case of an outbound connection, nodes are filtered out from any
connection lists, and prevented from submitting a connect to the
reactor.
2026-02-17 16:12:04 +01:00
Adrian Duke 94e0a5128d node: Add block command to control socket
Introduces the ability to explicitly block a peer via the node control
socket. Previously, the node only exposed follow and unfollow commands.
While the underlying policy database schema supported a Block variant,
there was no mechanism to trigger this state via the client handle.

The new block command:

 1. Updates the node's follow policy to Block.
 2. Immediately disconnects the peer if a session is active.
2026-02-17 16:12:04 +01:00
Fintan Halpenny 4286590fd9 fetch: move `Component::from` outside of loop
The previous code would convert the `remote` into a `Component` on
each iteration of the loop.

The conversion now happens outside of the loop and can be reused.
2026-02-17 15:47:31 +01:00
Lorenz Leutgeb 0e9d7607e4 hooks: Enable typos, fix reported errors 2026-02-17 11:35:28 +00:00
Lorenz Leutgeb 5fa68ed814
node: Use `gix_packetline`
`gix-packetline` already is in the dependency closure of `radicle-node`.
Use the well-tested and -used reader instead of ours.
2026-02-16 21:42:59 +01:00
Adrian Duke c96aea0699 node/e2e: Fix test_non_fastforward_identity_doc
This test was flakey.
2026-02-16 21:39:11 +01:00
Adrian Duke 832598ceb7 cli: Warn user about implicit seeding policy
To prepare for future changes, warn users if their config file currently
does not explicitly specify a default seeding policy.

Because there are now potentially multiple warnings generated that all
relate to the configuration file, group these together and adjust the
wording to be more uniform.
2026-02-16 21:39:11 +01:00
Adrian Duke cee3659ed5 radicle: Introduce `radicle::node::config::Scope`
The `SeedingPolicy` type now requires a `Scope`, however existing
configurations allow it to not be specified.

Introduce a `radicle::node::config::Scope` type that allows for an
optional `policy::Scope`. The default value resolves to
`policy::Scope::All`. This preserves backwards compatibility for
existing configurations.
2026-02-16 21:39:11 +01:00
Adrian Duke 306d0afbfe protocol: Note on peering and fetches
As part of the work to change the default scope, one of the tests
surfaced an issue where the topology was Alice <--> Bob <--> Eve,
however because of the previous 'all' scope Alice could receive Eve
references via Bob, but since the scope was changed to 'follow' Alice
would need to have a direct connection to Eve. TODO left here for future
consideration.
2026-02-16 21:39:11 +01:00
Adrian Duke 0684d1ccdf cli: Changed the default scope from all to followed for clone and seed
The previous implementation used 'all' as the default for scope, this
could lead to surprising behaviour where a user would fetch all
references for cloned and seeded repositories. Instead have a progressive,
safe by default value - where it fetches only 'followed' references. Later
a user can decide to set the scope to 'all'. NOTE: the default policy
scope was not changed from 'all' and is intended to be changed at a
later date.
2026-02-16 21:39:11 +01:00
Adrian Duke dd13eed1d0 cli: Do not print scope in block table
Previous implementation used the default scope when a scope wasn't
present. Scope is not present when the policy is block, because block
doesn't have a scope. Instead use an empty string when printing the
block policy.
2026-02-16 21:39:11 +01:00
Adrian Duke b5e8776efd fetch: Improve `refs/rad/id` resolution
The previous resolution would favour one `Oid` over another, due to
the call to `Option::or`.

This was found to result in scenarios where an identity document being
advertised was older than the identity document that the fetching node
already has, and would not fetch namespaces by newly added delegates.

The resolution logic is updated to handle all cases for these `Oid`s,
and when they are both present, uses a commit graph check to see which
one is the latest.

An e2e test is added to check ensure behaviour works correctly.
2026-02-16 21:39:11 +01:00
Fintan Halpenny 84320919e2 node/tests/e2e: use assert_eq! in test
The use of `assert_eq!` will highlight the differences in the two
values when it fails.
2026-02-16 17:13:39 +00:00
Fintan Halpenny 7862e108b6 Update gix-* crates
Fixes [CVE-2026-0810].

The `gix` crates require updating due to the security vulnerability above.
They require updating together in lock-step so both `radicle-fetch`
and `radicle-oid` are affected.

`radicle-oid` handles the non-exhaustive nature of `ObjectId`.

`radicle-fetch` updates to the new API types, however, this comes with
some updates to the `ls_refs` protocol.

A regression is documented in [gitoxide issue 2429].
The regression highlighted that it is the duty of the caller to also
filter the outcome of ls-refs, and `ref-prefix` is simply an
optimisation.

The ls-refs code is refactored to better represent and handle this operation.

[CVE-2026-0810]: https://www.cve.org/CVERecord?id=CVE-2026-0810
[gitoxide issue 2429]: https://github.com/GitoxideLabs/gitoxide/issues/2429
2026-02-16 17:13:39 +00:00
Fintan Halpenny 391571178e fetch: introduce domain type RefPrefix
Better represent the domain by introducing the `RefPrefix` type.
It captures the different `ref-prefix` values that can be used in the
`ls-refs` step of the protocol.

These are turned into their equivalent `ref-prefix` values using
`RefPrefix::into_bstring`.

This better connects the `ProtocolStage::ls_refs` method with the
`ls_refs::run` through the use of the `RefPrefix` type, rather than
any set of `BString` values.
2026-02-16 17:11:32 +00:00
Fintan Halpenny 8070f98a5b fetch/transport/ls_refs: Post-filter of references
The Git protocol specification states about `ls-refs`[^1]:

>    ref-prefix <prefix>
> When specified, only references having a prefix matching one of
> the provided prefixes are displayed. Multiple instances may be
> given, in which case references matching any prefix will be
> shown. Note that this is purely for optimization; a server MAY
> show refs not matching the prefix if it chooses, and clients
> should filter the result themselves.

The `ref-prefix` arguments should not be relied on and post-filtering
after the ls-refs invocation should also be performed.

[^1]: https://git-scm.com/docs/protocol-v2#_ls_refs
2026-02-16 17:10:40 +00:00
Fintan Halpenny 980ed56186 protocol/service: rename `Responder::new` to `Responder::oneshot`
The `Responder` is a oneshot channel where it sends one result and the
other side receives that result.

This surfaced that the `AnnounceRefs` command was returning one result
at a time. At the moment, this is only used for a single namespace,
the local user's.
2026-02-16 13:33:00 +01:00
Fintan Halpenny 0d628a45e2 protocol: refactor to use Responder
Refactors every command that uses a `Sender` to use a `Responder`
instead. There is an exception for `QueryState` since its usage
differs slightly to the other cases.

To make the usage more ergonomic, constructors for the variants that
require a `Responder` are added.
2026-02-16 13:33:00 +01:00
Fintan Halpenny b1eedd3b64 protocol/service: introduce Responder type
Introduce a `Responder` type that wraps a
`crossbeam_channel::Sender<Result<T>>`.

It provides a standard constructor and three sending methods: one for
a `Result`, one for an `Ok` value, and one for an `Err` value.
2026-02-16 13:25:58 +01:00
Fintan Halpenny 61a9b2140f protocol/service: introduce Result synonym
Create a type synonym for `Result<T, Error>`, to simplify result types
being returned by commands in a later change.
2026-02-16 13:25:58 +01:00
Fintan Halpenny 2c1972151d protocol: opaque command error
Refactor `CommandError` to be an opaque, boxed error.
Rename it to `Error`, so that it is imported via `command::Error`.
2026-02-16 13:25:58 +01:00
Fintan Halpenny 38713a8e62 protocol/service: drop `chan` qualifier
Small refactor to drop the `chan` qualifier and use `Sender` directly.
2026-02-16 13:25:58 +01:00
Fintan Halpenny 912a5ca42b protocol/service: create command module
Create a `command` module to house the command related types.
2026-02-16 13:25:58 +01:00
Lorenz Leutgeb fa94638abb radicle/storage/init: Remove placeholder files
These files contain stub texts (see added reference) and only clutter
storage.
2026-02-16 11:16:30 +00:00
Lorenz Leutgeb 7425ae4b49 ssh: Treat "connection refused" on Windows
Slightly relax the conditions under which an error is considered to
indicate that the SSH agent is not running, to accommodate differences
in the API of named pipes on Windows vs. Unix domain sockets.
2026-02-16 09:47:08 +00:00
Lorenz Leutgeb 5099c25df7 node/debug: Use derived serializers
The construction of the debug object is unwieldy, and error prone
(for example, renamed struct members have to be manually renamed
in the serialization code, see "refs" vs. "refsAt").

Use derived serializers where possible to make this easier to maintain.
2026-02-16 09:43:38 +00:00
Lorenz Leutgeb a1fa38018e protocol: Depend on `cypheraddr` not `cyphernet`
`radicle-protocol` depends on `cyphernet`, but only uses the module
`cyphernet::addr`, which is a re-export of `cypheraddr`, which is
unnecessary (as `cypheraddr` alone would do), and invites accidentally
pulling in more dependencies via `cyphernet`.

To prevent accidentally depending on further types from `cyphernet`,
change this to more conservativeley depend on `cypheraddr`.
2026-02-16 09:43:38 +00:00
Lorenz Leutgeb d530f1265e node/test: Remove unused file `environment.rs` 2026-02-16 09:38:37 +00:00
Lorenz Leutgeb 730d696d74 node/test: Bind to loopback interface 2026-02-16 09:38:37 +00:00