Commit Graph
97 Commits
Author SHA1 Message Date
Lorenz Leutgeb d285eccb23 fetch: Include the founder namespace always
Read the initial identity document from the blob addressed by the
repository ID and include its founder in the set of namespaces to
be fetched.

This lets clones resolve the identity COB root even if the founder
is not a delegate anymore.
2026-09-07 18:54:53 +02:00
Lorenz Leutgeb 90f448241e node/test/e2e: Clone without founder namespace
Add a test that demonstrates erroneous behavior in case the founder of a
repository is not a delegate anymore.

The change in commit 388d985578 changed
the semantics of loading the identity COB so that the founder is now
crucial.
2026-09-07 18:54:43 +02:00
Lorenz Leutgeb a6f938026f CHANGELOG: Fix level of headings and whitespace 2026-09-04 16:14:08 +02:00
Lorenz Leutgeb 50129a7179 radicle/canonical: Remove dangling reference
An oversight in commit `218ba30d73adbab0c2c51c6`.
2026-09-04 13:58:53 +02:00
Lorenz Leutgeb 0c2e8c1511 radicle/config: Remove public_seeds
This function is unused.
2026-09-02 17:14:04 +02:00
Lorenz Leutgeb 5790e319d0 radicle/config: Do not populate preferred_seeds
Adding the "public seeds" of the network to the `preferred_seeds`
configuration on all nodes causes all nodes to connect to the preferred
seeds and to have them attempt to keep the connection open at all times.

Assuming some growth in the network, and no growth in the number of
"public seeds", this means that the number of inbound connections to the
public seeds grows as well. Once the public seeds are at capacity,
the network as a whole is in some sense bottlenecked by the capacity of
the public seeds: As the network grows further, more and more outbound
connections to the public seeds will fail.

To avoid such issues, do not populate `preferred_seeds`.
2026-09-02 17:14:04 +02:00
Lorenz Leutgeb c14346d93a radicle/canonical: Remove MatchedRule
This `struct` is unused.
2026-09-01 19:41:02 +02:00
Lorenz Leutgeb fd4e4903d7 radicle, cli: Move Git versions
Move `struct Version` from `radicle` to `radicle-cli`, where it is used.
2026-08-30 23:53:25 +02:00
Lorenz Leutgeb 05a192daff fetch: Do not pretend to be Git
There is no good reason to fake being Git.
2026-08-30 23:53:25 +02:00
Lorenz Leutgeb 2747c52beb remote-helper: Compute HEAD for user namespaces
If a user pushes to the reference of the same name as the default branch
according to the identity document, expose this as `HEAD`, too.
2026-08-30 17:37:09 +02:00
Lorenz Leutgeb fba60164f0 radicle/identity/doc: LazyLock for PayloadId
The functions `PayloadId::{project,canonical_refs}` have two
weaknesses:
 1. They always execute the checks in `from_str` for the same
    `str` over and over again.
 2. They do not return a reference, thus, callers that only
    need a reference make a copy that they then discard.

For improved performance, switch to `LazyLocks`. Keep the less efficient
functions, but deprecate them.
2026-08-30 17:37:09 +02:00
Lorenz Leutgeb 138404df6f radicle: Rely less on ….project payload
Many codepaths error if the `xyz.radicle.project` payload is not present
in the identity document. Change these to fall back gracefully.

Loading of payloads is unified in `GetPayload`.

An important detail is that `PayloadError::NotFound` is removed, and
`Option` is used instead.
2026-08-30 17:37:09 +02:00
Lorenz Leutgeb de43682f16 rust: 1.97.1 → 1.98.0
The changes to `**/args.rs` are due to better linting: Clippy found that
we may use `as_chunks`. Note that this function was stabilized in 1.88.0.
2026-08-30 14:28:36 +02:00
Lorenz Leutgeb 7f5de25223 Release 1.10.2
Update `CHANGELOG.md` for the release of version 1.10.2.
2026-08-26 21:18:50 +02:00
Lorenz Leutgeb 3054779bfa windows: Set process creation flags
When executing programs on Windows, we suppress creating a new window,
and, if the process should continue to run in the background, we
explicitly create a new process group and detach.
2026-08-25 22:58:56 +02:00
Lorenz Leutgeb 9c06c4086a cli/patch: Spawn git for diffs directly
Spawning `rad diff` works, but prints a deprecation notice, because
`rad diff` itself is deprecated. `rad patch diff` however is not
deprecated and should just take a shortcut.
2026-08-25 20:39:29 +02:00
Lorenz Leutgeb 3da781f9e1 remote-helper: Accept option "pushcert if-asked"
This fixes issue 135835b572.
2026-08-23 23:09:38 +02:00
Lorenz Leutgeb 17ff650ec1 cli/node: Label Process ID
Resolve issue bb28940307 by clarifying
that the number printed is a process identifier.
2026-08-23 22:48:34 +02:00
Lorenz Leutgeb 96d74ea9ba radicle/cob/identity: Tighten initial revision
Make `Identity::new` private, to have more control over the initial
revision of the COB. Also assert that the author of the revision is the
solve delegate of the initial revision, i.e., the "founder".
2026-08-23 20:51:13 +02:00
Lorenz Leutgeb 675b82f344 radicle: Remove ReadRepository::identity_root_of
This function is unused.
2026-08-23 20:51:13 +02:00
Lorenz Leutgeb 388d985578 radicle/storage: Secure canonical_identity_head
Do not iterate over all user namespaces to find the ID of the identity
COB, but load from the founder's namespace specifically.

If the namespace of the founder is gone, attempt to recover by
walking back from `rad/id`.
2026-08-23 20:51:13 +02:00
Lorenz Leutgeb 26708e81a8 node/test: Demonstrate injection of Identity COB
This test shows how Bob is able to change visibility of Alice's repository from
private to public, even though Bob is not a delegate.
2026-08-23 20:49:09 +02:00
Lorenz Leutgeb 392542e923 build/build: Fix filename of Git archive
`build/upload` expects a filename that uses the *version*, i.e., a
semver triple, not the *revision*, i.e. a Git commit object identifier.
2026-08-23 19:33:37 +02:00
Lorenz Leutgeb d66f7e598b cli, crypto: Comment keys in SSH Agent
To avoid confusion how the key ended up in SSH Agent, add a comment that
adds some explanation.

See also
<https://radicle.zulipchat.com/#narrow/channel/392584-Feedback/topic/ssh-key.20with.20comment.20in.20agent/with/618208959>.
2026-08-23 19:28:32 +02:00
Lorenz Leutgeb 31f3d08d63 radicle/cob/thread: Use timeline: IndexSet
Plenty conservative `debug_assert!`s, cause panics as soon as two
actions that should be added to the timeline appear within the same
operation. But there is no code in place to prevent this.

It also does not seem to be problematic to visit the same operation
multiple times (once per contained action).

A set that retains iteration order does the job.

Analysis of this bug was done over Zulip, see
<https://radicle.zulipchat.com/#narrow/channel/369873-Support/topic/radicle-node.201.2E10.20segfaults/with/616991470>.

`Update::Reviewed::review` is boxed due to:

    error: large size difference between variants
       --> crates/radicle-cli/src/terminal/patch/timeline.rs:158:1
        |
    158 | /  enum Update<'a> {
    159 | |      /// A revision of the patch was reviewed.
    160 | |      Reviewed { review: Review },
        | |      --------------------------- the largest variant contains at least 352 bytes
    161 | |      /// A revision of the patch was merged.
    162 | |/     Merged {
    163 | ||         author: Author<'a>,
    164 | ||         /// If the merge is none, this means that it was a fast-forward merge.
    165 | ||         merge: Option<Merge>,
    166 | ||     },
        | ||_____- the second-largest variant contains at least 120 bytes
    167 | |  }
        | |__^ the entire enum is at least 352 bytes
2026-08-23 19:15:09 +02:00
Lorenz Leutgeb d7edbfb217 radicle/cob/thread: Make timeline private
There is no reason to have `pub(crate)` here.
2026-08-23 19:15:09 +02:00
Lorenz Leutgeb 5ddd5c64ea radicle/cob/thread: Make comments private
There is no strong reason to have `pub(crate)` here.
2026-08-23 19:15:09 +02:00
Lorenz Leutgeb 16de8f1950 README: Add references to downstream packages 2026-08-14 15:31:36 +02:00
Lorenz Leutgeb d7d9df27a5 debian: Remove
According to Lars Wirzenius, this is not required anymore, as it was
made redundant by `rad:z2nDKoCF4hg6xVrv7v93LmWHDJKUr`.

See also
<https://radicle.zulipchat.com/#narrow/channel/369277-heartwood/topic/Removal.20of.20.60debian.60.20directory/with/616115121>
2026-08-14 15:21:12 +02:00
Lorenz Leutgeb 71f39fb195 Release 1.10.1 2026-08-12 16:55:28 +02:00
Lorenz Leutgeb d18293c6ad cli/test: Do not accidentally test rad debug
The tests `rad-warn-ipv6.md` and `rad-warn-old-nodes.md` are meant to
primarily test the output of warnings. They test the output twice, via
`rad debug` and via `rad node status`.

Testing the output via one command should be sufficient.
2026-08-12 16:14:34 +02:00
Lorenz Leutgeb 4e3c274468 crypto, node: Randomly generate ephemeral keys 2026-08-12 15:28:40 +02:00
Lorenz LeutgebandKonstantinos Maninakis 4fff390c32 crypto: Use VerifyingKey::verify_strict
Refer to
<https://docs.rs/ed25519-dalek/2.2.0/ed25519_dalek/struct.VerifyingKey.html#method.verify_strict>.

Co-authored-by: Konstantinos Maninakis <maninak@protonmail.com>
2026-08-12 15:28:40 +02:00
Lorenz Leutgeb 6ba619f9a6 build/config: Link -dead_strip_dylibs on macOS 2026-08-06 17:31:04 +02:00
Lorenz Leutgeb 4641c342c6 Release 1.10.0 2026-08-05 15:32:21 +02:00
Lorenz Leutgeb a2eb756887 cli/id: Introduce rad id cache
Similar to `rad [issue|patch] cache`, this will re-compute cached state
about the identity document. The identity COB does not cache to SQLite,
but there is `refs/rad/id`, which can become stale.
2026-08-04 19:42:13 +02:00
Lorenz Leutgeb 71a91042d9 cargo/workspace: Bump crate versions
In topological order:

 - radicle-git-metadata     0.2.0 →  0.2.1
 - radicle-git-ref-format   0.1.0 →  0.2.0
 - radicle-oid              0.2.1 →  0.2.2
 - radicle-crypto          0.18.0 → 0.19.0
 - radicle-surf            0.28.0 → 0.29.0
 - radicle-cob             0.21.0 → 0.21.1
 - radicle-core             0.4.0 →  0.4.1
 - radicle                 0.25.0 → 0.25.1
 - radicle-signals         0.12.0 → 0.12.1
 - radicle-fetch           0.21.0 → 0.21.1
 - radicle-term            0.19.0 → 0.19.1
 - radicle-protocol         0.9.0 →  0.9.1
 - radicle-cli-test        0.14.0 → 0.14.1
 - radicle-node            0.21.0 → 0.21.1
 - radicle-cli             0.22.0 → 0.23.0
 - radicle-schemars         0.9.0 →  0.9.1
 - radicle-remote-helper   0.18.0 → 0.18.1
2026-07-24 21:37:41 +02:00
Lorenz Leutgeb ac607c8cad git-ref-format: Integrate with workspace
Instead of depending on `git-ref-format-core`, the
`radicle-git-ref-format` crate succeeds it.
2026-07-24 16:31:30 +02:00
Lorenz Leutgeb 8731d01bca git-ref-format: Copy over from radicle-git
This is the result of

    cp -r \
      ../radicle-git/radicle-git-ext/git-ref-format/core/src/{{cbor,check,deriv,lit,name,refspec,serde}.rs,{name,refspec}} \
      crates/radicle-git-ref-format/src/

with the radicle-git workspace at commit
8c5df5ecbd3f2507d323608b52e1fbf7b177d864.
2026-07-24 16:27:02 +02:00
Lorenz Leutgeb e880810e48 surf: Move test files into place
In the radicle-git workspace, crates brought their own testing crates
along with them, usually in a subdirectory named "t". In the heartwood
workspace we use tests within the same crate.

This commit only moves files, so that it is easier to follow changes to
them in the upcoming commit.
2026-07-24 16:09:56 +02:00
Lorenz Leutgeb 64a028353b scripts/just/check-ellipses: Replace less
Replacing all "..." with "…" is too aggressive.
2026-07-23 22:16:01 +02:00
Lorenz Leutgeb e9b999e2dd protocol: Calm typos
The `typos` spell-checker complains about "[T]ype" and "[I]nitiator".

Reformulate the comment to work around the issue.
2026-07-23 22:13:56 +02:00
Lorenz Leutgeb 474b7f3693 cargo/workspace: Add "no-std" category
Add the "no-std" category package metadata to all crates that are
`no_std`.
2026-07-22 16:44:59 +02:00
Lorenz Leutgeb a71f3b7295 cargo/workspace: Remove workspace version
No crate actually inherits this version number, remove it.
2026-07-22 16:44:59 +02:00
Lorenz Leutgeb e373f80d08 cargo/workspace: Add repository metadata
Some `/crates/*/Cargo.toml` were missing to inherit repository package
metadata from `/Cargo.toml`.
2026-07-22 16:44:59 +02:00
Lorenz Leutgeb a0551416f9 cargo/workspace: Remove homepage
In `/Cargo.toml` and all `/crates/*/Cargo.toml`, remove homepage package
metadata. This field is inteded to carry the *homepage of the crate*. In
our case, no crate has an actual homepage on its own.
2026-07-22 16:44:58 +02:00
Lorenz Leutgeb 69a4da6ffb cargo/workspace: Reorder package metadata
In all `/crates/*/Cargo.toml`, split package metadata into two or three
blocks:

 1. name, version, and description (in this order)
 2. Further metadata defined per crate.
 3. References to the workspace.

Lines in blocks (2.) and (3.) are sorted lexicographically, and blocks
are separated by empty lines.
2026-07-22 16:44:58 +02:00
Lorenz Leutgeb 024006297d cargo/workspace: Remove package.authors metadata
This field is deprecated, see
<https://doc.rust-lang.org/cargo/reference/manifest.html#the-authors-field>.
2026-07-22 16:44:58 +02:00
Lorenz Leutgeb caf45f1525 cli: Tighten visibility and minimize pub use
In `radicle-cli`, which is a binary crate (!) a few `pub use`s can be
removed. This forces `radicle-remote-helper` to depend on the library
crate `radicle-term` to access some of the types that were re-exported
from `radicle-cli`, making the dependency more obvious, and minimizing
the public symbols on `radicle-cli`.

The dependency on `radicle-cli` cannot be removed from
`radicle-remote-helper` easily, so is kept.
2026-07-22 16:43:34 +02:00
Lorenz Leutgeb c2af4b5982 signals: Fix Windows
Commit `41d776be4120df9f84633f1d54c1a1de27624c4e` accidentally broke
`radicle-signals` by a simple confusion of
`std::sync::mpsc::{,Sync}Sender`.
2026-07-22 16:26:47 +02:00
Lorenz Leutgeb 2ae6301f86 cargo/workspace: Bump crate versions
In topological order:

 - radicle-crypto         0.17.0 → 0.18.0
 - radicle-oid             0.2.0 →  0.2.1
 - radicle-cob            0.20.0 → 0.21.0
 - radicle-core            0.3.0 →  0.4.0
 - radicle                0.24.0 → 0.25.0
 - radicle-signals        0.11.0 → 0.12.0
 - radicle-fetch          0.20.0 → 0.21.0
 - radicle-log             0.1.0 →  0.2.0
 - radicle-term           0.18.0 → 0.19.0
 - radicle-protocol        0.8.0 →  0.9.0
 - radicle-cli-test       0.13.0 → 0.14.0
 - radicle-node           0.20.0 → 0.21.0
 - radicle-cli            0.21.0 → 0.22.0
 - radicle-schemars        0.8.0 →  0.9.0
 - radicle-remote-helper  0.17.0 → 0.18.0
2026-07-22 13:12:19 +02:00
Lorenz Leutgeb 008b1a25e1 flake/nixpkgs: 25.11 → 26.05
Running `cargo semver-checks` errors with

    error: unsupported rustdoc format v57 for file:
    …/heartwood/target/semver-checks/local-radicle-…/target/doc/radicle.json
    (supported formats are v53, v55, v56)

Support for rustdoc format v57 is part of cargo-semver-checks 0.46,
which is not part of NixOS 25.11, which has reached EOL.

Re-point the "nixpkgs-stable" input to NixOS 26.05 to reach a newer
cargo-semver-checks and a NixOS version that is supported.

Update the flake.
2026-07-22 13:12:19 +02:00
Lorenz Leutgeb ee8b7919fc crypto: Add conditions for PublicKey::to_bytes 2026-07-22 13:12:14 +02:00
Lorenz Leutgeb 0a2981d78d term: Fix features for zeroize
In `df6524e7e21027c4eb128dd2eaab0a6d70a6d76d`, default features for
`zeroize` were disabled for the workspace in `/Cargo.toml`, accidentally
affecting `radicle-term`, since `radicle-term` depends on
`impl Zeroize for String` which is available on feature "alloc" only.
2026-07-22 12:51:07 +02:00
Lorenz Leutgeb a87e0bd1c8 build/Dockerfile: Install Zig via apk 2026-07-21 14:23:23 +02:00
Lorenz Leutgeb 8d50b75826 build/Dockerfile/zig: 0.13.0 → 0.16.0 2026-07-21 14:23:23 +02:00
Lorenz Leutgeb 4751432b3c build/Dockerfile: Specify Registry docker.io
Make explicit that Docker Hub is used.
2026-07-21 14:23:23 +02:00
Lorenz Leutgeb 828bfd02fa build/Dockerfile: Re-use $ALPINE_VERSION
Use the same version of Alpine Linux for building and packaging.
2026-07-21 14:23:00 +02:00
Lorenz Leutgeb 394ade5576 build/Dockerfile/alpine: 3.24 → 3.24 2026-07-21 13:48:12 +02:00
Lorenz Leutgeb 0f8e1cc597 build/Dockerfile: Omit default RUST_VERSION
The Rust version used for development is tracked in
`/rust-toolchain.toml`, and the value specified there is used to set
`RUST_VERSION` in the `build/build` script. Thus, when using
`build/build`, the default value is unimportant.

However, ensuring that the default value remains consistent with
`/rust-toolchain.toml` is a maintenance burden.

Remove the default value. This increases friction of building without
`build/build`, but makes maintenance easier.
2026-07-21 13:47:40 +02:00
Lorenz Leutgeb e0dc14de2b protocol/handle: Responder in Command::Block
Other variants of `Command` use `Responder` respond with data.
`Command::Block` does not.

Change `Command::Block` to be in line with other variants.
2026-07-21 13:25:25 +02:00
Lorenz Leutgeb 3658ece34f node/test: Clean up
Adjusting visibility and conditional compilation for the modules in
`radicle_node::test` allows some dead code elimination.
2026-07-21 12:32:42 +02:00
Lorenz Leutgeb 8efbf06f78 node: Clean up uses
The re-exports from other crates got quite confusing.

Remove all `pub use` from `radicle-node`, and rewrite all `use`s
accordingly.

The result is a slight increase in the number of `use` lines, but with
improved clarity on which type is actually imported.
2026-07-21 12:31:48 +02:00
Lorenz Leutgeb 9eeecacf28 node: Remove re-export …::node::PROTOCOL_VERSION
It appears that `radicle_node::PROTOCOL_VERSION` (which is a re-export
of `radicle::node::PROTOCOL_VERSION` is the only symbol exported from
`radicle-node` that is used in `radicle-cli` (except tests).

Since `radicle-cli` depends on `radicle` anyway, it is questionable how
much sense that re-export and use from a binary crate (!) makes.

Remove the re-export.
2026-07-21 12:28:10 +02:00
Lorenz LeutgebandFintan Halpenny df6524e7e2 crypto: Rewrite
Reasons for the rewrite:
 - Migrate away from `ec25519` as our implementation of Ed25519,
   because that crate is unmaintained.
   Instead of `ec25519` we use `ed25519-dalek` which is the most popular
   implementation of Ed25519 in Rust.
 - Migrate away from `amplify`, because we make very little use of its
   features. Here, we only use `amplify::Bytes32`, which is just a thin
   wrapper of `[u8; 32]`.
   Instead of `amplify::Bytes32` we use `type PublicKeyBytes = [u8; 32]`.

The realization that `ExtendedSignature` is not really tied to SSH, but
is merely a representation of a key together with a signature, allows to
relax the bounds on traits in `radicle-cob`.

Separating out uses of "public key" (a rather simple model of a key,
just 32 bytes) and "verifying key" (an actual point on the Edwards
curve, ready to verify signatures, using more memory than just 32 bytes)
allows a more sensible definition of `crypto::Signer`, which propagates
to `radicle-cob`, `radicle`, `radicle-cli`, `radicle-node` and
simplifies trait bounds.

In `radicle-node`, make the fact clearer that actually the secret key
itself is required (for our implementation of Diffie-Hellman) not
"just" signing. This results in removal of the generic argument
(usually called `G`) of multiple types.

Concretizing the types in `radicle-node` this way, i.e. by (morally)
setting `G = radicle_crypto::SigningKey`, leads to removal of
`MemorySigner` and `MockSigner`, as they really just wrap a signing
key.

Re-exporting `ed25519::Signature` (via re-export in `ed25519-dalek`)
is hopefully more future-proof than using our own type for signatures.
However, the fact that `ed25519::Signature` is not serializable and
does not implement `std::hash::Hash` means that we have to resort to
ad-hoc solutions in `radicle`:
 1. The Identity COB requires serialization of signatures. These are
    generally questionable, since the security of the Identity COB
    should rely on the security of Signed References. In the medium
    term we might even want to consider ignoring signatures in actions.
 2. When reading Signed References, detection of Replay Attacks uses
    a `HashMap` keyed by signatures. This detection only exists for
    backwards compatibility.
These two use cases are exotic enough to warrant ad-hoc implementations.
By not wrapping `ed25519::Signature`, we encourage writing more widely
compatible code in the future.

Co-authored-by: Fintan Halpenny <fintan.halpenny@gmail.com>
2026-07-21 09:19:01 +02:00
Lorenz Leutgeb 0fd0104e87 radicle, cli/auth: Let binary crate generate seed
In preparation of a rewrite of `radicle-crypto`, move the
responsibility for generating a cryptographically secure
seed from `radicle` (transitively via dependency on
`radicle-crypto` and `ec25519`) to the dependent of `radicle`.

Applications should decide how to obtain randomness, not `radicle` via
some far-removed dependency.

Within the workspace, the only dependent using `Profile::seed` is
`radicle-cli`, in particular for the `rad auth` subcommand. To obtain
random bytes, `radicle-cli` depends on `getrandom` and uses
`getrandom::fill`.
2026-07-17 16:52:33 +01:00
Lorenz Leutgeb 027de89cdb node/worker/garbage: Clean up
Clippy reports dead code on all variants except `Hours` on `Expiry`,
since the type is defined in a binary crate.

Allow dead code here, just in case we want to use the other variants in
the future. They are not a maintenance burden, as the implementation is
simple and does not see much change.

Slightly refactor:
 - `impl std::fmt::Display for Expiry` to look cleaner.
 - `fn collect` to borrow `RepoId`, since it only needs
   a borrow, and a a borrow of `Expiry` to spare a copy
   at the only call site.
 - The constant for the default value of `Expiry` to be
   associated with the type `Expiry`.

Remove a remark about the default value of `Expiry` from `FetchConfig`,
as the default value is not a concern there, but rather wherever
`Expiry` is initialized.
2026-07-17 11:30:26 +02:00
Lorenz Leutgeb 41d776be41 treewide: Use channels from std, not Crossbeam
For most use-cases, i.e., except some in `radicle-node`, the channels
in `std::sync::mpsc` suffice, allowing us to get rid of the dependency
`crossbeam-channel`.

Crossbeam is sometimes mentioned to offer higher performance compared
to `std::sync::mpsc`.
For usage in `radicle-signals` (and the counterparts in `radicle-node`
and `radicle-term`) performance is irrelevant, as these channels are
used to send a singular message (to the effect of shutting down the
node or stopping the spinner). These could potentially use
`std::sync::oneshot` in the future, which is nightly-only as of
2026-06-17, see <https://github.com/rust-lang/rust/issues/143674>.
Usage in `radicle-protocol` and `radicle`, is a heavier duty.
The channels pass commands to the service (arriving e.g. via the
control socket in `radicle-node`), events from the service to other
listeners (e.g. the control socket), and fetch results from workers to
the service. For user interaction, performance is irrelevant, since
the messages are in the tens or hundreds per second. Even for delivering
events and programmatic usage of commands, thousands to hundreds of
thousands of messages per second are plenty.

Note that these channel implementations are benchmarked in the millions
of operations per second, see e.g.:
 - <https://github.com/crossbeam-rs/crossbeam/tree/b23b7e8eca2efdad9bdc1ceb1aee1207a852c03b/crossbeam-channel/benchmarks#results>
 - <https://github.com/fereidani/rust-channel-benchmarks/blob/b4c979a94482e5012734657c2ee153b528bc56d6/README.md>

Also, `crossbeam-channel` was merged into `std` in 2022-11, and we do
not believe that performance of the implementations has siginifcantly
drifted since then, see <https://github.com/rust-lang/rust/pull/93563>.

One minor downside is that the channels in the standard library do not
expose the number of pending messages.
2026-07-17 10:58:58 +02:00
Lorenz Leutgeb f31fbf40ce rust: 1.95 → 1.97.1
The update to `flake.lock` is a simple

    nix flake update rust-overlay

to be able to reach 1.97.1.

The changes to `**/*.rs` files are improvements suggested by Clippy.
2026-07-17 10:29:56 +02:00
Lorenz Leutgeb 6d846d754d radicle: Mark AddressType as non_exhaustive 2026-07-17 10:17:40 +02:00
Lorenz Leutgeb cff80006a2 protocol: Remove duplicate enum AddressType
We already have `radicle::node::address::AddressType` for the same
purpose.
2026-07-17 10:17:40 +02:00
Lorenz Leutgeb e4775edf41 radicle: Remove dependency amplify
The `amplify` crate is only used in a handful places to derive `impl`s
that are not very complex.

Provide the required `impl`s directly, and remove the dependency.
2026-07-17 10:06:48 +02:00
Lorenz Leutgeb 564c167de1 git2: 0.20 → 0.21
Update `git2` due to
 - https://rustsec.org/advisories/RUSTSEC-2026-0008.html
 - https://rustsec.org/advisories/RUSTSEC-2026-0183.html
 - https://rustsec.org/advisories/RUSTSEC-2026-0184.html
2026-07-16 14:37:32 +02:00
Lorenz Leutgeb 27e2a9428a node: Refactor Tests
The tests in `crates/radicle-node/src/tests/.rs` repeat code quite a
bit, for example, construction of IP addresses. Also, `Peer` is
unnecessarily complex (too many struct members, state indicated via a
boolean, type parameter that is always instantiated for the same type).

Clean up `Peer` by removing multiple struct members, remove the
unnecessary type parameter, and provide convenience functions that make
statement of the actual tests a little less repetitive and more concise.

For test networks, five standard nodes (Amy, Bob, Cid, Dan, Eve) are all
easy to construct. Tests are refactored to make use of these nodes in
lexicgraphic oreder. The order of initialization may differ.
Modification of configuration is done by passing `FnMut`.

In the future, using the builder pattern could be explored.
2026-07-13 14:23:13 +02:00
Lorenz Leutgeb a079825afc node/reactor: Simplify Transport
1. Properly drain readiness
 2. Remove `WriteAtomic`
 3. Introduce `BufWrite`
 4. Remove flushing
2026-07-09 21:57:14 +02:00
Lorenz Leutgeb 4e22e929d8 node/reactor/session: Protocol::{state → machine}
Even though for the existing implementations all state machines are
somehow named "state", it is less confusing to call the struct member
"machine".
2026-07-09 21:57:14 +02:00
Lorenz Leutgeb 7d5248a89b node/reactor: Remove unnecessary functions/types
The functions
 - `Session::run_handshake`
 - `Session::stream`
 - `Session::disconnect`
are unused.

The associated type `Session::Inner` is unused.

The function `Session::display` is of limited use with little benefit.

`Transport::link_direction` is only used in implementations of
`Debug` and `Display`, but is not helpful otherwise.
2026-07-09 21:57:14 +02:00
Lorenz Leutgeb b5e6d82769 radicle/identity: Tidy up
Small improvements:
 - Remove confusing comments in test
 - Rename `has_active_sibling_accept`
     to   `has_accepted_active_sibling`
 - Small refactoring to avoid `… } else { None }`
2026-07-09 16:26:25 +02:00
Lorenz Leutgeb ebf0f417f7 radicle/cob/identity: Deprecate Identity::id
In the heartwood workspace, there is just a single use of this function.
Also, the repository ID can be computed on demand, saving memory.
2026-07-03 15:22:13 +01:00
Lorenz Leutgeb 88bf2a9648 term: Remove typing indication for passwords
`inquire::PasswordDisplayMode::Masked` causes inquire to
render characters of the password text input marked as
different characters (asterisks).

Users reported that they would prefer password text input to not be
rendered at all, i.e., have no indication of input. This is inquire's
default, so remove the lines that set the display mode.
2026-06-12 14:21:21 +02:00
Lorenz Leutgeb cf108311dc node: Heap Profiling with DHAT 2026-05-27 12:07:52 +01:00
Lorenz Leutgeb ff8660d872 radicle: Warn less aggressively on IPv6 addresses
Parsing of IPv6 addresses not enclosed in square brackets causes a
warning to be logged.

This is too strict, since the user can not influence IPv6 addresses
received over the network, but only those in their configuration.

Remove the warning from parsing, and instead carry a boolean to warn the
user later.
2026-05-21 14:52:35 +01:00
Lorenz Leutgeb 7ed9d50ab6 crypto: Update ssh-agent-lib from 0.5.2 to 0.6
This should fix issues handling SSH certificates.

See
<https://radicle.zulipchat.com/#narrow/channel/369873-Support/topic/1.2E9.2E0.3A.20rad.20auth.20fails.20with.20SSH.20certificate.20in.20agent/with/596358640>.
2026-05-21 13:10:35 +02:00
Lorenz Leutgeb 09b1f1f77c node: Fix handling absence of systemd credential
In case `radicle_systemd::credential::path` returns `Ok(None)`, a
misleading warning is logged.

Handle this case separately and do not emit a warning.
2026-05-20 09:36:22 +02:00
Lorenz Leutgeb 9158df5067 flake: Add NixOS tests to checks 2026-05-13 17:23:54 +01:00
Lorenz Leutgeb 767b80e7fe flake: Sort Inputs Lexicographically 2026-05-13 17:23:54 +01:00
Lorenz Leutgeb c5043617b9 flake: Fix nixpkgs inputs 2026-05-13 17:23:49 +01:00
Lorenz Leutgeb 420af3b710 workspace/rust: 1.90 → 1.95
The update to `flake.lock` is a simple

    nix flake update rust-overlay

to be able to reach 1.95.
2026-05-11 12:09:04 +01:00
Lorenz Leutgeb 9ea040ccd0 rust/msrv: 1.85.0 → 1.88.0
`cargo check` fails because `human-panic` and `sysinfo` require at least
1.88.0.

    +++ command cargo check --release --locked --all-targets
    error: rustc 1.85.0 is not supported by the following packages:
      human-panic@2.0.6 requires rustc 1.88
      sysinfo@0.37.2 requires rustc 1.88

Bump MSRV to fix this.

1.88.0 introduced [let chains], which in turn has `clippy` warn about
nested if statements. All of these sites are fixed in this change.

1.87.0 introduced [`is_multiple_of`], which is a more readable version
of `x % y == 0`.

[let chains]: https://blog.rust-lang.org/2025/06/26/Rust-1.88.0/#let-chains
[`is_multiple_of`]: https://doc.rust-lang.org/std/primitive.usize.html#method.is_multiple_of
2026-05-11 11:23:18 +01:00
Lorenz Leutgeb 0a0e70b1d1 node/systemd: Fix reading credentials
In `cb57e6560fe7767e79b87473a11261fbb82ce84c` the loading of systemd
credentials was refactored. The idea was to only change the accepted IDs
slightly after switching from radicle.xyz to radicle.dev. Unfortunately,
this was done in a sloppy way. The two cases for passphrase and secret
actually differ in ways that was overlooked.

Rectify these mistakes and restore the old behavior:
 1. The logic to read the passphrase from the file that contains the
    credential is moved out of `load_credential` since it only applies
    to the passphrase, not the secret.
 2. The warnings printed are now generic, and will not mention the
    passphrase in case reading the path for the secret fails.
2026-05-07 22:53:57 +02:00
Lorenz Leutgeb 9177146794 radicle/web: Fix schema of Config::description
The JSON Schema for the field `radicle::web::Config::description` is specified
to be a URI, which is wrong.

Remove the additional attribute.
2026-05-07 15:23:31 +01:00
Lorenz Leutgeb ee9a9de36d radicle/web: Relax deserialization of Config
Allow omission of `pinned` and its members.
2026-05-07 15:23:31 +01:00
Lorenz Leutgeb aa177b0400 treewide: radicle.{xyz → dev,network}
We have moved to radicle.dev, so adjust the domain name in various
places.

Not changed:
 - COB type names
 - systemd secret identifiers
2026-04-27 18:34:30 +02:00
Lorenz Leutgeb cb57e6560f node: Rename systemd Credentials
Because we changed our main domain from radicle.xyz to radicle.dev, we
should also change our systemd credential identifiers.

Handling is move into a new function, which also checks the old names
for backwards compatibility.
2026-04-27 18:21:26 +02:00
Lorenz Leutgeb 06ff36ebc4 cli: Update warning for new bootstrap node names 2026-04-27 18:20:25 +02:00
Lorenz Leutgeb 22287fd94a radicle: Change names of bootstrap nodes 2026-04-27 18:19:47 +02:00
Lorenz Leutgeb 3bc8abdc29 radicle/node/config: Use IndexSet
With `connect: std::collections::HashSet`, we suffer unpredictable reordering
of values in our test cases.

Use `connect: indexmap::IndexSet` instead, which preserves insertion
order for iteration.
2026-04-27 17:36:20 +02:00