Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
node: Use git oid for project id
Alexis Sellier committed 3 years ago
commit 6353d6115b505f90e26336f6caba3e0d47513fda
parent 84119b02656657fd7db9d8d042d00c02d7ca8215
5 files changed +42 -38
modified node/src/identity.rs
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::crypto::{self, Verified};
-
use crate::hash;
+
use crate::git;
use crate::serde_ext;
use crate::storage::Remotes;

@@ -17,14 +17,14 @@ pub use doc::{Delegate, Doc};

#[derive(Error, Debug)]
pub enum IdError {
-
    #[error("invalid digest: {0}")]
-
    InvalidDigest(#[from] hash::DecodeError),
+
    #[error("invalid git object id: {0}")]
+
    InvalidOid(#[from] git2::Error),
    #[error(transparent)]
    Multibase(#[from] multibase::Error),
}

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-
pub struct Id(hash::Digest);
+
pub struct Id(git::Oid);

impl fmt::Display for Id {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -40,12 +40,12 @@ impl fmt::Debug for Id {

impl Id {
    pub fn to_human(&self) -> String {
-
        multibase::encode(multibase::Base::Base58Btc, &self.0.as_ref())
+
        multibase::encode(multibase::Base::Base58Btc, self.0.as_bytes())
    }

    pub fn from_human(s: &str) -> Result<Self, IdError> {
        let (_, bytes) = multibase::decode(s)?;
-
        let array: hash::Digest = bytes.as_slice().try_into()?;
+
        let array: git::Oid = bytes.as_slice().try_into()?;

        Ok(Self(array))
    }
@@ -68,14 +68,20 @@ impl TryFrom<OsString> for Id {
    }
}

-
impl From<hash::Digest> for Id {
-
    fn from(digest: hash::Digest) -> Self {
-
        Self(digest)
+
impl From<git::Oid> for Id {
+
    fn from(oid: git::Oid) -> Self {
+
        Self(oid)
+
    }
+
}
+

+
impl From<git2::Oid> for Id {
+
    fn from(oid: git2::Oid) -> Self {
+
        Self(oid.into())
    }
}

impl Deref for Id {
-
    type Target = hash::Digest;
+
    type Target = git::Oid;

    fn deref(&self) -> &Self::Target {
        &self.0
modified node/src/identity/doc.rs
@@ -12,7 +12,6 @@ use thiserror::Error;
use crate::crypto;
use crate::crypto::{Signature, Unverified, Verified};
use crate::git;
-
use crate::hash;
use crate::identity::{Did, Id};
use crate::storage::git::trailers;
use crate::storage::{BranchName, ReadRepository, RemoteId};
@@ -79,22 +78,17 @@ pub struct Doc<V> {
}

impl Doc<Verified> {
-
    pub fn write<W: io::Write>(&self, mut writer: W) -> Result<Id, Error> {
+
    pub fn encode(&self) -> Result<(Id, Vec<u8>), Error> {
        let mut buf = Vec::new();
-
        let mut ser =
+
        let mut serializer =
            serde_json::Serializer::with_formatter(&mut buf, olpc_cjson::CanonicalFormatter::new());

-
        self.serialize(&mut ser)?;
+
        self.serialize(&mut serializer)?;

-
        let digest = hash::Digest::new(&buf);
-
        let id = Id::from(digest);
+
        let oid = git2::Oid::hash_object(git2::ObjectType::Blob, &buf)?;
+
        let id = Id::from(oid);

-
        // TODO: Currently, we serialize the document in canonical JSON. This isn't strictly
-
        // necessary, as we could use CJSON just to get the hash, but then write a prettified
-
        // version to disk to make it easier for users to edit.
-
        writer.write_all(&buf)?;
-

-
        Ok(id)
+
        Ok((id, buf))
    }
}

@@ -367,9 +361,7 @@ mod test {

    #[quickcheck]
    fn prop_encode_decode(doc: Doc<Verified>) {
-
        let mut bytes = Vec::new();
-

-
        doc.write(&mut bytes).unwrap();
+
        let (_, bytes) = doc.encode().unwrap();
        assert_eq!(Doc::from_json(&bytes).unwrap().verified().unwrap(), doc);
    }
}
modified node/src/rad.rs
@@ -47,17 +47,15 @@ pub fn init<'r, G: Signer, S: storage::WriteStorage<'r>>(
        name: String::from("anonymous"),
        id: identity::Did::from(*pk),
    };
-
    let doc = identity::Doc::initial(
+
    let (id, doc) = identity::Doc::initial(
        name.to_owned(),
        description.to_owned(),
        default_branch.clone(),
        delegate,
    )
-
    .verified()?;
+
    .verified()?
+
    .encode()?;

-
    let filename = *identity::doc::PATH;
-
    let mut doc_bytes = Vec::new();
-
    let id = doc.write(&mut doc_bytes)?;
    let project = storage.repository(&id)?;

    {
@@ -70,11 +68,14 @@ pub fn init<'r, G: Signer, S: storage::WriteStorage<'r>>(
        //      git fetch rad
        //      git checkout -b radicle/id remotes/rad/radicle/id
        //
+
        let filename = *identity::doc::PATH;
        let repo = project.raw();
        let tree = {
-
            let id_blob = repo.blob(&doc_bytes)?;
+
            let doc_blob = repo.blob(&doc)?;
            let mut builder = repo.treebuilder(None)?;
-
            builder.insert(filename, id_blob, 0o100_644)?;
+
            builder.insert(filename, doc_blob, 0o100_644)?;
+

+
            assert_eq!(git::Oid::from(doc_blob), *id);

            let tree_id = builder.write()?;
            repo.find_tree(tree_id)
modified node/src/test/arbitrary.rs
@@ -52,6 +52,10 @@ impl<const N: usize> ByteArray<N> {
    pub fn into_inner(self) -> [u8; N] {
        self.0
    }
+

+
    pub fn as_slice(&self) -> &[u8] {
+
        self.0.as_slice()
+
    }
}

impl<const N: usize> Arbitrary for ByteArray<N> {
@@ -174,9 +178,8 @@ impl Arbitrary for MockStorage {

impl Arbitrary for Project {
    fn arbitrary(g: &mut quickcheck::Gen) -> Self {
-
        let mut buf = Vec::new();
        let doc = Doc::<Verified>::arbitrary(g);
-
        let id = doc.write(&mut buf).unwrap();
+
        let (id, _) = doc.encode().unwrap();
        let remotes = storage::Remotes::arbitrary(g);
        let path = PathBuf::arbitrary(g);

@@ -311,8 +314,10 @@ impl Arbitrary for MockSigner {

impl Arbitrary for Id {
    fn arbitrary(g: &mut quickcheck::Gen) -> Self {
-
        let digest = hash::Digest::arbitrary(g);
-
        Id::from(digest)
+
        let bytes = ByteArray::<20>::arbitrary(g);
+
        let oid = git::Oid::try_from(bytes.as_slice()).unwrap();
+

+
        Id::from(oid)
    }
}

modified node/src/wire.rs
@@ -375,9 +375,9 @@ impl Decode for git::Url {

impl Decode for Id {
    fn decode<R: io::Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
-
        let digest: Digest = Decode::decode(reader)?;
+
        let oid: git::Oid = Decode::decode(reader)?;

-
        Ok(Self::from(digest))
+
        Ok(Self::from(oid))
    }
}