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.
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.
Serialization and deserialization of symbolic references was implemented
with assumptions on the order of pairs of key and value in JSON objects,
and further, that the enabling the `preserve_order` of `serde_json` would
always guarante that these assumptions hold. See
<https://docs.rs/crate/serde_json/1.0.149/features#preserve_order>.
This is mistaken. The identity document is serialized via `Doc::encode`
which uses `radicle::…::CanonicalFormatter`, which enforces a particular
ordering. From the point of view of the implementation of symbolic
references, this means that the ordering changes, thus violating the
ordering assumption.
The effects are that during deserialization, some symbolic references
might be considered dangling, when they are only missing other symbolic
references that were reordered to occur "later" in the JSON object.
To remedy, introduce `RawSymbolicRefs`, in analogy to `RawRules`. Just
like `RawRules` may be converted to `Rules`, `RawSymbolicRefs` may be
converted to `SymbolicRefs`. This gives the most flexibility for
handling `RawSymbolicRefs`, and one clear point at which validation
happens.
The fact that the implementation cannot depend on ordering anymore means
that all symbolic references have to be validated together, which fits
the pattern of `Raw{,*}` well.
Tests expose the issue.
Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.dev>
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`.
Testing revealed that the implementation violated RIP-0006, which
requires the most specific rule matching the target of `HEAD`
to use an `allow` of `delegates` and the document threshold.
`validate_head_rule` took the first match from `RawRules`, which orders
patterns lexicographically, so a glob could be validated in place of the
rule that actually governs the branch.
The issue here is that the correct order for matching patterns is only
guaranteed on `Rules`, but not on `RawRules`.
To prevent such errors in the future, remove `RawRules::matches`. This
requires some refactoring, and makes synthesis of the default branch
rule slightly less efficient in the worst case, but we are willing to
take that hit for a cleaner implementation.
Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.dev>
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.
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.
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.
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.
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".
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`.
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
Update the rustup action in the pre-plan in `.radicle/ambient.yaml`
to use the same toolchain and components as `rust-toolchain.toml`
specifies. This allows `cargo` commands to work.
This is conditional on the target operating system being FreeBSDs.
HardenedBSD is FreeBSD but with changes. We determine which one it is,
by running 'sysctl --values hardening.version'.
Co-authored-by: Shawn Webb <shawn.webb@hardenedbsd.org>
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.
When `Service::handle_message` handles `Message::Subscribe`, constraints
regarding visibility of repositories are not considered, this leads to
leaking RIDs of private repositories.
Add a corresponding check.
Add a test to verify that reference announcements relayed via subscribe
correctly apply visibility filtering, there by ensuring references of
private repositories are only propagated to nodes on the allow list.
The test regarding deduplication needs a fix: Ensure that all mock
repositories are public and in storage so that they do not
get filtered out in case of unknown visiblity.
Co-authored-by: Lorenz Leutgeb <lorenz.leutgeb@radicle.dev>