Commit Graph

67 Commits

Author SHA1 Message Date
Alexis Sellier c9162121b0
cob: Parametrize `cob::Store` with repository type
The additional flexibility in choosing a backend for the COB store will
allow things like "draft" COBs that are stored in a different location,
without changing much of the logic.
2023-07-14 16:57:55 +02:00
Alexis Sellier 45ccbde226
Update `radicle-surf` and `git-ref-format` 2023-07-14 16:57:55 +02:00
Alexis Sellier b60569d3cb
cob: Test deterministic traversal order
We test to make sure that in the event of concurrent operations,
traversal order is deterministic.

This required some changes to the testing infrastructure. We're also
able to simplify the `Actor` type that now has redundant functionality.
2023-05-30 16:31:01 +02:00
Alexis Sellier 0e14dacb99
cob: Simplify graph evaluation
Simplify graph traversal and evaluation by building in some of the
functionality into `radicle-dag`, namely the pruning fold.

We avoid building vectors of graph nodes this way, and simply iterate
over the graph in one go.
2023-05-30 16:31:01 +02:00
Alexis Sellier ac60069a33
cob: Remove `description` from `Patch`
Since patches always have a "root" revision, use that revision's description
as the patch description.
2023-05-26 10:31:00 +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
Alexis Sellier 87ae8cfb62
cob: Fix some clippy warnings 2023-05-12 12:47:41 +02:00
Alexis Sellier d249937a61
Update dependencies
* radicle-surf
* radicle-git-ext
* amplify
2023-05-10 15:56:21 +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 649d59f143
cob: Include head in initial patch entry in DAG
This change ensures that we include as a parent to the initial commit
of a patch COB, the head of the branch we are proposing as a patch.

This was already happening for patch updates, but we forgot to also
include it for the initial patch revision.

This ensures that the code is always fetched alongside the patch.
2023-05-02 09:18:17 +02:00
Alexis Sellier 3e9c3d2679
cob: Don't overwrite nodes during traversal
By not checking if the node exists, if a node is traversed twice,
the second instance of it gets overwritten, and all the edges get
lost.
2023-04-27 14:44:47 +02:00
Alexis Sellier d74535a5a5
Update license for `radicle-cob`
Now that we've obtained permission from the original author, we're
able to update the license to MIT/Apache.
2023-04-23 15:20:35 +02:00
Alexis Sellier eecea67ffd
cob: Deduplicate change parents 2023-04-14 13:54:27 +02:00
Alexis Sellier 97f076e3cf
Include dependencies for certain COB actions
We ensure that for example, the given commits are fetched before the
revision or merge actions in a patch.
2023-04-14 13:22:10 +02: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 8205f8ad4e
Update `fastrand` dependency to 1.9.0 2023-04-14 13:15:52 +02:00
Alexis Sellier b6fa4a4b2a
cli: Some improvements to `rad merge` 2023-04-03 16:06:24 +02:00
Slack Coder 0b7f169c8b
cli: Support revision id in `rad merge`
Revision IDs are globally unique.  Users will be able to use the
Revision ID in place of its patch ID.

Make `rad merge` refuse to merge an older revision unless the `--force`
option is given.
2023-03-31 17:24:55 +02:00
Alexis Sellier aacacf872f
cob: Use `EntryId` as the operation identifier
By introducing a small limitation: only allowing entries in the change
graph to be addressable, instead of individual operations; we
drastically simplify the CRDT implementation.

There are four advantages:

1. Op ids are just regular SHA-1s
2. There's no need for relative IDs, ops never refer to other ops within the
   same commit
3. There's no need for a nonce, since commits can't collide, and neither can op IDs
4. `OpId` can just be an alias of `EntryId`

The disadvantage of course, is that we have to be mindful of how we
create op transactions, since each transaction creates an addressable
unit. For example, we must not include multiple patch revisions in the
same transaction.
2023-03-09 17:08:56 +01:00
Alexis Sellier 5f59493c70
cob: Don't require a local fork to exist
Before this change, the identity document would be loaded for the
COB signer. This meant that a fork would be needed for that signer.

After this change, it's no longer necessary, since the identity doc
head is computed from available remotes.

While making those changes, it was also apparent that some of the
identity-related functions had bad names and error types, this
was fixed as well.
2023-03-01 15:40:30 +01:00
Alexis Sellier 06a92d52d9
cob: Use hashes for operation ids
It's fairly easy for a user to (by mistake or intentionally) create two
operations with the same OpId. This patch makes it much less likely,
and ensures that if the OpId is equal, it's because the operations
are identical.
2023-02-27 17:11:48 +01:00
Alexis Sellier e584bd6c1c
crypto: Use `ssh-key` crate for signatures 2023-02-17 11:53:46 +01:00
Alexis Sellier 8cbc3c2403
node: Move to NoiseXK
Move from NoiseNN with a custom authentication protocol, to NoiseXK.
Uses ECDH on the ed25519 curve via the `ec25519` library.
2023-02-15 22:05:04 +01:00
Fintan Halpenny 99c1e2ac52
radicle-cob: simplify trailers module
The macro in the trailers module existed since there were multiple
trailers before the refactoring, so it minimised boilerplate code.

After the refactoring of the code there was only one trailer
left. Remove the macro generation code and replace it with just the
necessary code for the ResourceCommitTrailer.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-13 13:30:08 +01:00
xphoniex bdc0ab9881
Update `radicle-git` and `radicle-surf`
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
2023-02-10 22:14:50 +01:00
Fintan Halpenny 3f48c2c516
Rust 1.67
Rust 1.67 was announced[0]. Update the necessary files for running
1.67 and fix the clippy suggestions for string interpolation.

[0]: https://blog.rust-lang.org/2023/01/26/Rust-1.67.0.html

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-04 19:30:29 +01:00
Alexis Sellier a50329eb43
cob: Remove redundant indentation
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2023-01-06 13:00:01 +01:00
Alexis Sellier 329af88ca6
cob: Quiet warnings in release mode
We were getting warnings in release mode, since the
debug code is not being run, and some vars are mutable
instead of immutable.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2023-01-06 13:00:01 +01:00
Alexis Sellier b7d0479b5c
cob: Add some more information about `resource`
Signed-off-by: Alexis Sellier <self@cloudhead.io>
2023-01-03 14:28:18 +01:00
Alexis Sellier 2f42bc942c
cob: Make it easy to build histories
Signed-off-by: Alexis Sellier <self@cloudhead.io>
2023-01-03 14:23:47 +01:00
Alexis Sellier 5ee1f42b6a
cob: Have clock value for empty COB state
By using `0` as the clock value for an empty state (without operations),
we simplify transaction code. Previously, there was no clock value for
empty states, which meant that we had to sometimes use an `Option`.
2023-01-01 18:29:47 +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 86e56d2053
cob: Move graph sorting to `evaluate` function
This avoids passing the sorted items as an iterator.

Signed-off-by: Alexis Sellier <self@cloudhead.io>
2022-12-28 19:24:22 +01:00
Alexis Sellier 70260236b2
cob: Simplify graph builder
Since we use `Oid` as the primary graph index, there's no need to keep
a separate index.

Signed-off-by: Alexis Sellier <self@cloudhead.io>
2022-12-28 18:01:24 +01:00
Alexis Sellier 57fcb117fc
cob: Remove redundant history indices
Signed-off-by: Alexis Sellier <self@cloudhead.io>
2022-12-28 17:53:00 +01:00
Alexis Sellier 2f07b76fcb
Switch to our own DAG representation for COBs
We're using petgraph to encode an operation based CRDT (each graph node
is an operation) as a DAG, and one of the important things to ensure
is that the final state is not influenced by the order of concurrent
operations. In this case a concurrent operation would mean two potential
graph traversal orders, as there's no direct edge between the two
concurrent ops. This is essential a "partial order" of operations.

To be able to test this, we'd want some kind of control over how
neighbors are iterated over I guess, when there's more than one possible
sort order. Say we have a graph like this:

             ┌────────b◄─────┐
             ▼               │
             a               d
             ▲               │
             └────────c◄─────┘

There are two possible topological traverse orders: [a, b, c, d] and [a,
c, b, d]. Having a way to go through these different orders would
be super handy.

One option would be to allow random order traversal. This would allow us
to test all orders by running the test enough times to likely test all
permutations.

Since petgraph doesn't support this, we implement our own simple DAG in
`radicle-dag`, which implements random-order topological orders.

For now, we don't make explicit use of these improvements, we simply
replace the underlying graph with our own.
2022-12-28 13:34:17 +01:00
Alexis Sellier f6177f85fe
cob: Remove redundant type
Signed-off-by: Alexis Sellier <self@cloudhead.io>
2022-12-27 17:30:06 +01:00
Slack Coder 873ce895ae
cob: panic on badly formatted debug env var
Panic to clear to the operator something is wrong.  Panic'ing like this
is ok in debug mode, but must be avoided in production.

Signed-off-by: Slack Coder <slackcoder@server.ky>
2022-12-26 15:38:39 +01:00
Slack Coder edef49d1ef
Improve client example test determinism
Collaborative object IDs are derived from their commit oid.  These
IDs must be reproducible to support testing the client's example.  All but
one of the parameters used to derive the Object ID is the commit's Author
and committer timestamp.

Introduce an environment variable 'RAD_COMMIT_TIME' to set both Author and
Committer timestamp when creating a commit in the cob module.

Use single variable, instead of Git's two (for author and committer), to
keep the changes simple.  The function being modified returns a single
timestamp which is derived from the author's.

Signed-off-by: Slack Coder <slackcoder@server.ky>
2022-12-26 15:37:55 +01:00
Alexis Sellier 335fcbca89
cob: Return correct clock value for multi-ops
We weren't accounting for batches ops in an entry.
This change should account for it by adding N-1
to the clock value of an entry, where N is the number
of entries.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-13 10:16:18 +01:00
Alexis Sellier 98c1566109
Make `Doc` type payload generic 2022-12-09 22:05:38 +01:00
Alexis Sellier b7c1f091fa
Fix issue with colliding doc files
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-09 14:37:36 +01:00
Fintan Halpenny 5f80ee9671
cobs: allow for batched operations
Sometimes it is more efficient to perform multiple operations at once
and store those in the collaborative object graph together.

Change the contents to be a non-empty sequence of byte sequences,
i.e. NonEmpty<Vec<u8>>. These are stored as blobs in a git tree in
order by their index in the non-empty sequence. They are, in turn,
retrieved in order of their original index.

Change the conversion of an `EntryWithClock` to return a non-empty
sequence of `Op`s, which are in turn used to apply many changes in
each `from_history` implementation.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2022-12-07 17:11:40 +01:00
Alexis Sellier f9c81ab382
Replace `quickcheck` with `qcheck`
The latter is a fork of the former, which adds const generics
and a bunch of other quality of life improvements that aren't
in the original crate due to it being unmaintained.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-04 20:40:54 +01:00
Alexis Sellier 81a1ee5cc2
cob: Implement `Store::remove`
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-02 14:21:50 +01:00
Alexis Sellier 6c0c7b2969
cob: Delete redundant functions
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-02 14:21:50 +01:00
Alexis Sellier 64ce15dbe2
crdt: Include timestamp in `Change`
We can then use the real change timestamp for our COBs.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-02 14:19:25 +01:00
Alexis Sellier d061afdab1
cob: Include commit timestamp in `Entry`
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-02 14:19:25 +01:00
Alexis Sellier 3af2c53bb2
cob: Implement COB removal function
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-01 12:05:44 +01:00