When piping the output in for eg. `head -n 1`, the `head` utility
might close down the pipe at some point, yielding a broken pipe error.
We catch that and simply return if that's the case.
Adds the new `migrate` sub-command to migrate the COB database.
Checks for version when opening the COBs database and suggests the
command on out of date version.
Also adds the 2nd migration to the COBs cache, which updates the patch
JSON schema.
We were rejecting patches that were once valid, due to a rule that was
added some time ago. Move that rule one level up, in the write path,
instead of in the read path.
We ensure that a `rad/root` ref is included in the signed refs file
under `rad/sigrefs` for all remotes. This prevents a certain kind of
"grafting" attack where signed refs can be copied between repositories,
by having the peer sign over the identity root together with the data refs.
When verifying signed refs, we ensure that the ref is present and points
to an identity branch root that matches the repository identity containing
the signed refs.
Alternatives: lots of alternatives were considered, but this one doesn't
introduce any changes to the signing. The `rad/id/root` name was
considered but is invalid due to `rad/id`.
To facilitate edit actions, take URIs instead of the actual blobs. This
means API callers don't have to load all the blobs just for them to be
re-hashed when an edit action is submitted.
There are some peculiarities when dealing with the `Identity` COB since
the embed is the identity document itself. We handle that special case.
Though refs of private repositories are not announced publicly, they can
sometimes be relayed to nodes that are not in the allow list.
We fix this by always checking the visibility of a repository before
sending a refs announcement of it to a peer.
Discovered-by: Adrian Duke <adrian.duke@gmail.com>
Due to the way review editing was implemented, we were losing comments
on previous review edits.
Here, we add a new `review.edit` action that is specifically for
editing, and make the existing `review` action fail silently (for
backwards compatibility) in case it is used when there is already a
review.
We also simplify the review data structure by only keeping track of one
review per author per revision, instead of all edits. Later, if needed,
it will be possible to keep track of all review edits.
When pushing to the default branch and updating the canonical head,
check to see if any merged patches are reverted due to this change.
If so, make sure the COB cache reflects this.
When two `review` actions were posted by the same author, for the same
revision, an error was returned, cancelling evaluation for that author.
This caused certain patches to for eg. lose their merge status.
To remedy this, we *allow* multiple `review` actions per revision, but
simply take the last one as the "current" review. Since this makes the
`review.edit` action redundant, we remove that action completely. This
is safe, as none of the tools created review edits.
This change simply logs an error if there is a problem loading a COB
from storage, instead of bailing on the cache update process.
We also ensure that objects that can't be loaded from storage are
removed from the cache.
In case of a bug or failed cache update, there may be objects in the
cache that are no longer in storage.
When doing a full re-cache, remove all existing entries from the repo
first.
This adds an option to `rad init` to initialize a working copy with
an existing radicle repository in storage:
rad init --existing <rid>
This sets up the remote(s) and configures the repo for you.
In the current design it's possible for one peer to fill the fetch queue
so that fetches from other peers are delayed.
To improve fairness, we move to a queue per peer. We then try to dequeue
from all peers in a random order for good measure.
To avoid buffering large amounts of data in the process, we set the
worker channel size to `64`. Keep in mind that this is one
`ChannelEvent`, not one byte. `ChannelEvent::Data` can already contain
an arbitrary amount of data via its `Vec<u8>`, but in practice the
maximum is 8192, due to the use of `io::copy`.
We also remove an unused function, and move the flushing to the
`ChannelFlushWriter`.
Gives the same options to `rad seed` as `rad sync --fetch`.
Allows seeding and syncing from specific seeds in one command:
rad seed <rid> --from <nid>
Useful for seeding private repos on public nodes.
If two peers are persistent for each other and experience
disconnections, it's possible that an outbound connection is turned into
an inbound one. But if we don't set that correctly, we'll eventually run
into a crash where an already connected peer re-connects, since the
disconnection logic checks for the link direction.
The fetch queue could sometimes not drain due to skipped fetches not
signaling that to the dequeue loop.
We now return a `bool` from `try_fetch` and keep trying to dequeue
fetches until one of them actually is initiated.
Additionally, we try to dequeue fetches at a regular interval
(`IDLE_INTERVAL`) to ensure that the queue is drained.
There are cases where the service state doesn't match the state
of the underlying wire protocol. We remedy this by transitioning peers
to a "connected" state when a message is received, if they are in a
"connecting" state.
The long term solution to this will likely be to merge the service and
protocol layer so that there are no inconsistencies.
The other case happens when a persistent peer is in "disconnected" state
and attempts an inbound connection to us.
1. Adds a user-agent string to the node announcement. This lets us keep
track of what software version everyone is running. Especially useful
to see what percentage of the network has upgraded to a new release.
For old nodes, this defaults to the string `/radicle/`.
The user agent format is roughly based on BIP 0014.
2. Advertize protocol version in node announcement.
By advertizing the protocol version, nodes can decide to only connect to
peers with a compatible version. The default and current version is `1`.
We bundle these two changes as they both modify the node announcement
and node database.
3. Swap the order of the fields in announcements to make the message
extensible.
This prevents potential memory leaks. We also ensure that sends fail
instead of blocking, in case the channels are full.
Additionally, we add some metrics to report on channel size.
Previously, our advertized inventory was not always correct: when we
stopped seeding a repository, it was still advertised as part of our
inventory until node restart, because the `Storage` type doesn't have
access to seeding policies.
In this change, we remove the concept of inventory from `Storage` and
make the authoritative place for it the routing table in our database.
To make this work, we have to add our node to the database on profile
creation, to not violate the foreign key constraint on the routing
table. Hence, the tests are changed to include our alias which is now
always available.