Commit Graph

34 Commits

Author SHA1 Message Date
cloudhead d4ec2176bb
Update Rust toolchain to 1.74 2023-11-17 16:58:24 +01:00
Fintan Halpenny ac849f1fd5
radicle: add ReadRepository::contains
It can be useful to be able to check if a repository contains a given
commit. Add a `contains` method to the `ReadRepository` trait to
handle this.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-11-17 16:09:42 +01:00
Fintan Halpenny 61b06553b4
radicle: use git::raw::Error for reference_oid
The minimal error for the `ReadRepository::reference_oid` method is
`git::raw::Error`.

Change the error type from `git::ext::Error` to `git::raw::Error`.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-11-09 17:47:07 +01:00
Fintan Halpenny 75b52e28b2
radicle: separate repository validation
Make the validation logic customisable by extracting it out into a
separate trait that can be defined by other crates.

The Repository validation logic stays the same.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-11-06 12:06:13 +01:00
Fintan Halpenny b503aa6be4
radicle: validations
Instead of returning the unsigned references, the validation of a
repository's remotes returns the set of validation errors. The caller
is then expected to handle these validation errors appropriately, for
example, by logging them and re-raising an error.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-11-06 12:06:13 +01:00
cloudhead 1d167581f2
cob: Introduce `xyz.radicle.id` COB
Introduces a new COB type to store repository identity documents.

The reason for this change is to:

1. Simplify the code, as the identity document logic resembled a COB,
   yet it had custom logic. This allows existing COB code to be used for
   identities.
2. Make identity document update logic more flexible, since COB actions
   can be added in the future.
3. Re-purpose existing tools around COBs to work on identities, eg. `rad
   cob`.
4. Unify the concept of an identity change proposal, with regular identity
   changes. This means we can remove the `id.proposal` COB in favor of
   using the `id` COB itself.

Notes
-----

* Each repository has one Identity COB.
* The `Proposal` COB has been repurposed into the `Identity` COB.
* Identity documents are stored as *embeds* inside the Identity COB
  actions.
* The action that contains new document versions is called `revision`,
  just like the Patches COB.
* The namespaced `rad/id` ref is a symbolic reference to that Identity
  COB.
* The canonical `rad/id` ref is a direct reference to the commit in the
  Identity COB that contains the latest *accepted* revision of the
  document.
* All commands for managing identities have been folded into `rad id`.
  Hence `rad delegate` and `rad edit` are removed.
* The concept of "rebasing" an identity document is gone.
* The `rad id` output has been updated to match the style of other
  commands.
* When a revision has enough signatures, it is automatically adopted as
  the current identity, there is no longer the need for a "commit"
  action.
* When an identity revision is proposed, and the current identity has a
  threshold of `1`, that identity is automatically accepted due to the
  above point.
* The idea of "verifying a peer's identity branch" no longer applies, as
  COBs cannot be verified one history at a time.
* Since the root commit of the Identity COB does not have a "Resource"
  to point to (it would have to point to itself, which is impossible),
  we've made the resource id optional for COBs.
2023-10-12 17:32:33 +02:00
cloudhead c99d9a6aed
radicle: Make mock transport thread-safe
The mock transport was not thread-safe when multiple threads used the
same node ids. This is fixed by including the thread id as part of the
storage key.
2023-10-11 14:53:59 +02:00
cloudhead 457b82f723
cob: Evaluate COB state eagerly
Instead of returning histories from `radicle-cob`, we return an
evaluated object which we build during initial graph traversal.

We do this so that branches can be correctly pruned when operations are
invalid at the application level. This way, new operations are not
building on top of invalid ones contained in the history.

To achieve this, we introduce a new `Evaluate` trait that is implemented
by all COBs, and we make change graph evaluation fallible.

Doing this means that we get `apply` errors returned for free when an
invalid transaction is applied, and no longer need to check for action
validity in multiple places.

We also implement a new `Dag::prune` method to avoid having to copy
graph nodes during traversal.
2023-09-11 23:25:28 +02:00
cloudhead 65fa3cbb1b
radicle: Make `DraftStore` generic over the repo
This will allow using it inside of COBs.
2023-09-10 20:44:38 +02:00
cloudhead 6695074479
cob: Don't require full `Entry` for update
Instead of taking the full entry type, we only need the id.
2023-09-10 20:44:38 +02:00
cloudhead 205c15caa6
cob: Simplify `Entry` and `Change` types
Instead of having two types, we simply have one, called `Entry`, which
we rename from `Change`.

There was no real benefit to having two almost identical types, but lots
of added complexity. This patch simplifies the crate by removing one of
the types.
2023-08-24 12:57:30 +02:00
cloudhead 534503d002
cob: Add support for media embeds in COBs
This change allows for files (blobs) to be embedded into COB entries.
This allows for things like image attachments in issue comments for example.

For now, we only enable this in the `issue` COB.

The way it works is that relevant COB actions carry metadata about which
files are attached to them; and we store those files as blobs inside the
COB entry's *tree* object, under an `embeds/` folder.

The `Embed<T>` type is used for the above, and either carries actual
content, or carries a content-id. Retrieving the actual content is as
simple as asking the repository for a blob with that content-id.

As a possible future extension, MIME types could be stored alongside the
files in a "metadata" file. This could help clients display the content
appropriately.
2023-08-22 14:29:23 +02:00
cloudhead d13f47b2a4
Update toolchain to Rust 1.71 2023-08-09 18:49:13 +02:00
Alexis Sellier 3bd5589b1a
cob: Stabilize formats
> I'm going to be making a set of breaking changes to COBs in order to
stabilize the data formats. This is hopefully a one-time change that
bundles various breaking changes.

All COBs have been reworked: issue, patch, id.

The changes included are:

* Revise the assign and tag actions to take a single list of
  assignees/tags to set, instead of an "add" and a "remove" list. This
  makes API usage simpler when editing issues, and simplifies the apply
  function
* Rename "tags" to "labels", and the tag action to label. This is
  because tag is confusing in the context of git, as it could mean a git
  tag. Using label removes that confusion.
* Use DIDs instead of PublicKeys for assignees -- this is more
  future-proof
* Modify the manifest file format in the COB tree. Mainly, remove the
  `history_type` key which is redundant, and use camelCase for keys
* Flatten the `Thread` actions into the parent action type
* Ensure that operations on redacted objects do not fail, since
  redactions could have happened concurrently
* Use a consistent naming scheme for actions, using `.` as separator
* Consolidate comment types and remove `CodeComment`, by adding an
  optional `location` field to `Comment`
* Add many placeholder actions that are not yet implemented

To preserve backwards compatibility, a `legacy` module is created with
the old `apply` function. When loading the manifest, we check whether it
is a legacy COB or a "stable" COB, and in the legacy case, use the
legacy code to materialize the state and then convert the object into
the stable type. Eventually, we'll delete the legacy code.
2023-08-07 11:05:14 +02:00
Alexis Sellier f639192dc6
cob: Remove CRDTs from COB state
It turns out that the CRDT formed by the union of Git DAGs
is enough to guarantee everything we need for COBs.

This changes the following things:
* COB operations no longer need to be commutative
* COB histories are traversed in the same deterministic order on all
  replicas
* It's now possible to implement RSMs on top of COBs, eg. scripting
* Lamport clocks have been removed
* `radicle-crdt` is no longer a dependency of `radicle`
* COBs are no longer instances of `Semilattice`
* The `Ops` type was removed in favor of having `Op` contain multiple
  actions
2023-07-25 15:29:27 +02:00
Alexis Sellier 4634913b66
radicle: Split out `SignRepository` trait
This new trait is used when only signing refs is needed, and not general
write access to a repository.

We also implement `ReadRepository` and `SignRepository` for
`DraftStore`.
2023-07-14 16:58:23 +02:00
Alexis Sellier ff7e9ded17
radicle: Introduce `cob::DraftStore`
This storage backend for COBs stores changes in a `draft/cobs/*` namespace,
which allows for some of the features needed for code review. For
example, users can draft comments and later decide to publish
them.
2023-07-14 16:57:55 +02:00
Alexis Sellier 94cd7658b1
cli: Merge patches on `git push`
Allows patches to have their state updated to `Merged` with a `git push`
to the default branch.

Currently, due to the limitations of the COB store, this requires a
linear search through all patches. This will eventually become a problem
when projects have thousands of patches, so we should look into
long-term solutions.
2023-05-16 21:11:57 +02:00
Vincenzo Palazzo b29321dbf7
cob: Fix recursion bug in TryFrom of Reference
This commit addresses the issue of recursion in the TryFrom
call of Reference by resolving the parent in a lazy way.

Due to constraints posed by the need to access `git2::Repository`
or `git2::Commit` to resolve the parent, this commit decides to
pull out the parent resolution logic from the `cob::object::Commit`
module and move it inside the `cob::store::Store` implementation by adding
a new method `parents_of`.

Suggested-by: Fintan Halpenny <fintan.halpenny@gmail.com>
Tested-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
2023-05-09 10:11:36 +02:00
Fintan Halpenny 8508eab8fa
radicle: update radicle-git-ext
This change updates to the latest radicle-git-ext, which required a
few changes within the radicle family of crates.

One set of changes is that the radicle-git-ext crate subsumes
git-commit, git-trailers, and git-ref-format -- so all those imports
go through radicle-git-ext.

The commit code requires that parent `Oid`s point to commits, which
made some tests fail. One of the reasons for these failures is that
the patch tests used fabricated `Oid`s and so the verification would
fail. This is fixed by allowing the test context code to create
`PatchRequest`s that create valid commits.
The other reason for failure was that the identity `Action` passed an
`Oid` that pointed to a blob. This is fixed by removing that code and
making a note of it in documentation.

The final major change was moving the Refspec type into git-ref-format
and removing the AsRefspecs trait. The trait was not required and
could its usage could be replaced by simpler code.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-05-08 10:36:15 +01:00
Alexis Sellier 489370dcbd
cob: Add ability to add more parents to change
This allows change commits to have more than one parent that isn't
part of the DAG.

We can use this to create dependencies towards git objects such as
commits, in the case of patch actions.
2023-04-14 13:22:10 +02:00
Alexis Sellier ef950d515a
node: Fully integrate worker fetch into service 2023-01-25 10:21:57 +01:00
Alexis Sellier 1f06f5340f
Make `Id` to string conversion more explicit
Two types of conversion: `canonical`, which is just the base58 encoding,
and `urn` which is like canonical, but includes `rad:`.
2023-01-24 13:49:03 +01:00
Alexis Sellier 438ae84304
node: Implement E2E node test
There are few unrelated changes in this commit that I wasn't able to
split out, mostly due to laziness, so I'll list them here:

* The node startup logic is moved out of the main function, and into a
  dedicated functionin `client.rs`.
* There is a tentative worker implementation that is untested, and
  handles git replication both ways. It's likely lacking in various ways
  but I wanted to get it in there anyway.
* `Address` was moved from `radicle-node` to `radicle`, because it's
  needed to send `Connect` commands from the node handle.
* The `netservices` dependency was updated.
* Finally, there is a first end-to-end node test, which currently
  doesn't use NoiseXK, but uses the new reactor in `netservices`.

Signed-off-by: Alexis Sellier <self@cloudhead.io>
2023-01-12 20:34:31 +01:00
Alexis Sellier 49cd26c0b3
Tidy up COBs code a little
* Move storage impl into `storage::git::cob`
* Rename `change::Create` to `change::Template`
* Rename `change::Storage::create` to `change::Storage::store`

Some of the renames are to further distinguish COBs from Changes, and
the different types of "create" operations within cobs.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-31 09:58:45 +01:00
Alexis Sellier 2a1154ef87
Re-work git transports
The changes in this commit are all intertwined and it was hard to
split them into smaller commits:

* Use custom transports everywhere

Instead of `file://` and instead of using a child process for fetching
and pushing; we go through our custom transports, which use the `rad://`
and `heartwood://` schemes.

* Introduce a 'mock' remote transport

To test the remote transport without needing to spawn TCP streams,
we add a mock transport that works between storages on the file
system.

* Get rid of node's `git-url`

Instead of git urls, nodes simply use their node-ids to replicate.
2022-10-26 21:40:19 +02:00
Alexis Sellier 3407c6c017
Add `ToString` support for transport URLs
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-10-24 21:57:53 +02:00
Alexis Sellier 66493422c2
Add 'local' and 'remote' URL formats
To distinguish between working-copy-to-storage (local) and
storage-to-storage (remote) replication, we create two new
URL types: a `remote::Url` (`heartwood://`) and a `local::Url`
(`rad://`).

These schemes are to be used for the remote and local transports,
respectively.

The difference between the two schemes is that remote replication
requires a node id.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-10-24 20:19:45 +02:00
Alexis Sellier 657a951df0
Create `url` module shared between crates
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-10-19 14:30:01 +02:00
Alexis Sellier a104f9681c
Warn on `unwrap`, remove last remaining instances
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-10-11 09:31:54 +02:00
Alexis Sellier 48a5c75ae3
Revise git transport to use I/O more directly
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-28 15:41:11 +02:00
Alexis Sellier f85a0426d7
Only support `rad://` in the custom proto
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-28 13:45:03 +02:00
Alexis Sellier 1da38708fc
Flesh out custom git transport
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-28 13:36:57 +02:00
Alexis Sellier b4dcc00fe3
Custom git protocol sketch
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-27 18:14:57 +02:00