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>
* Move storage impl into `storage::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>
To ensure that signatures are unique for verifying an identity a
HashMap is used in place of a Vec of tuples.
This prevents any double counting for quorum checks.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
The `validate` method of `Project` was unused, which is problematic if
the attributes are supposed to be validated based on some
constraints. The issue is that `Project` provided public construction
of its fields with enforcing validation.
This change makes `Project`'s attributes private and introduces a
smart constructor `new` which is fallible if any of the constraints
are not met. The error type was changed to be a vector of errors since
all of these errors can be collected for better error reporting.
Deserialization also provided a way of constructing a `Project`
without ensuring any of the constraints were checked. To prevent this
a hand-rolled `Deserialize` is provided that goes through
`Project::new`.
To access the fields of `Project`, accessor functions are added and
all call sites are updated to use them.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
In RIP-2, we specify that identity document root commits must include
the signature of all founding delegates.
This commit adds the required signatures during document creation
and verifies them on load.
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
The new hierarchy should be much more correct, and cleaner:
* `identity` (`Identity`)
* `identity::did` (`Did`)
* `identity::doc` (`Doc`, `Payload`)
* `identity::doc::id` (`Id`)
* `identity::project` (`Project`)
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
We are working on other mechanisms to help identify keys, and this
is just redundant.
Also update some of the CLI examples to create a canonical example
for documentation.
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This will allow us to run commands other than `rad`
and to have tests that switch between different users.
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
Added the `parse_refname` function for parsing a reference into its
`TypeName` and `ObjectId`, if possible.
This replaces the `cob_suffix` function in `radicle`.
This change also fixes the `FromStr` instance of `ObjectId` to use
`from_str` instead of `TryFrom` for bytes.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
* Use the existing conventions for passing a signer to functions.
* Allow replacing git refs when updating cobs.
* Fix the parsing of a cob id.
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
To wire up radicle-cob, it is necessary to implement the traits for
the following types:
* `Repository`: `change::Storage`, `object::Storage`, and `Store`
* `project::Identity`: `identity::Identity`
For `Repository`, the `change::Storage` implementation is trivial, as
it uses the underlying `git2::Repository` implementation. Then
`object::Storage` simply defines the required references names and
does lookups or updates.
The aforementioned reference naming scheme is:
refs/namespaces/<ns>/refs/cobs/<typename>/<object_id>
For `project::Identity`, the `identity::Identity` implementation is
straight-forward.
To finalise the work, a simplified API is exposed as `radicle::cob`
where the `create`, `update`, `get`, and `list` functions are
redefined in terms of `radicle` specific types.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
To support ssh-agent, add a signing method that can fail.
Also cleanup usage so that we always accept signer references.
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
We move the identity branch out of `heads/` and to the old location:
refs/rad/id
We move the signed refs branch to:
refs/rad/sigrefs
Keeping both "special" branches under the same hierarchy makes things a
bit easier to work with, and tells the user that they should be updated
with special tooling.
We also revert to `rad/` because we no longer have the issue of having
`rad/rad/id` when doing a checkout of the remote branch in a working
copy.
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
The crypto types are useful to use in other components that are
separate from the radicle crate, e.g. the incoming radicle-cobs
crate.
Separate out the types into a radicle-crypto crate. This crate defines
the usual PublicKey, SecretKey, and Signature types. It also provides
the ssh functionality, under the `ssh` feature. It is also necessary
to provide the `From` impl for `Component` here, which again is
guarded by the `git-ref-format` feature.
The `Arbitrary` implementation are moved. The arbitrary decision of
redefining `ByteArray` in both radicle-crypto and radicle was made.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
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.
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>
Since the `HEAD` reference is trusted (we set it locally), use that
when possible, instead of re-computing it.
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
We set the `HEAD` and eg. `refs/heads/master` refs when updating
repositories, which allows users to easily clone with git.
For now, `HEAD` is chosen based on a unanimity quorum of delegates.
This can be made more sophisticated in the future.
We've also had to ignore some refs during verification, since these
have cropped in for eg. due to the staging copy clone and the
changes included here.
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
The `git-ref-format`[0] and `radicle-git-ext`[1] crates are now
published to crates.io.
Switch the dependency to rely on them. This also required to update
the `git2` dependency to `0.15.0` as well as using the
`vendored-libgit2` feature -- avoiding the openssl dependency too.
[0]: https://crates.io/crates/git-ref-format
[1]: https://crates.io/crates/radicle-git-ext
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
The previous iteration of the storage layout for projects organised
peer's subtrees by the `refs/remotes` category. This layout leads to
problems when linking a working copy to the storage project. The fetch
refspec would look something like:
fetch = +refs/remotes/abc/heads/*:refs/remotes/rad/*
This works perfectly fine when running:
git fetch rad
but will fail when one tries to specify:
git fetch rad main
Instead, the command would need to be:
git fetch remotes/abc/heads/main
This patch proposes to move the use of `refs/namespaces` for each
peer. The layout looks similar in that each peer has a subtree, but
instead it is under `refs/namespaces/<peer>/refs/...`.
The previous refspec would look more familiar in its new form:
fetch = +refs/heads/*:refs/remotes/rad/*
With this in place running:
git --namespace=abc rad main
Will work as expected and place the reference under
`refs/remotes/rad/main`. Similary, `git --namespace=abc push` will
work as expected.
Another benefit of this approach is that the use of namespacing means
that a tag is pushed it will be placed under the respective namespace
rather than in the global `refs/tags` category.
The actual implementation needed to work around the fact that
`git2`/`libgit2` does not have any options for fetching or pushing
using namespaces. The working copy code uses processes to shell out to
`git` for namespacing needs.
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>