aboutsummaryrefslogtreecommitdiffstats
path: root/adenosine/src/repo.rs
diff options
context:
space:
mode:
authorbryan newbold <bnewbold@robocracy.org>2023-04-10 00:19:13 -0700
committerbryan newbold <bnewbold@robocracy.org>2023-04-10 00:19:13 -0700
commit4c51ee2decdd709be9d38806e002d7f69bcd3ebd (patch)
tree1d49c6a4dd2bee9f65505bd851d7cb1a24343150 /adenosine/src/repo.rs
parentbca44be1b01d2fd2f021cfaed344ff945f9b41b6 (diff)
downloadadenosine-4c51ee2decdd709be9d38806e002d7f69bcd3ebd.tar.gz
adenosine-4c51ee2decdd709be9d38806e002d7f69bcd3ebd.zip
repov2 commit node updates
Diffstat (limited to 'adenosine/src/repo.rs')
-rw-r--r--adenosine/src/repo.rs126
1 files changed, 43 insertions, 83 deletions
diff --git a/adenosine/src/repo.rs b/adenosine/src/repo.rs
index a3a5a12..3fb3a40 100644
--- a/adenosine/src/repo.rs
+++ b/adenosine/src/repo.rs
@@ -3,7 +3,7 @@ use crate::car::{
};
use crate::crypto::KeyPair;
use crate::identifiers::{Did, Nsid, Tid};
-use crate::mst::{collect_mst_keys, generate_mst, CommitNode, MetadataNode, RootNode};
+use crate::mst::{collect_mst_keys, generate_mst, SignedCommitNode, UnsignedCommitNode};
use anyhow::{anyhow, ensure, Context, Result};
use ipfs_sqlite_block_store::BlockStore;
use libipld::cbor::DagCborCodec;
@@ -20,13 +20,12 @@ use std::str::FromStr;
#[derive(Debug, serde::Serialize)]
pub struct RepoCommit {
- pub sig: Box<[u8]>,
- pub commit_cid: Cid,
- pub root_cid: Cid,
pub did: Did,
+ pub version: u8,
pub prev: Option<Cid>,
- pub meta_cid: Cid,
pub mst_cid: Cid,
+ pub sig: Box<[u8]>,
+ pub commit_cid: Cid,
}
impl RepoCommit {
@@ -34,13 +33,12 @@ impl RepoCommit {
/// (aka, CID as a string, not an array of bytes).
pub fn to_pretty_json(&self) -> Value {
json!({
- "sig": data_encoding::HEXUPPER.encode(&self.sig),
- "commit_cid": self.commit_cid.to_string(),
- "root_cid": self.root_cid.to_string(),
"did": self.did.to_string(),
+ "version": self.version.to_string(),
"prev": self.prev.map(|v| v.to_string()),
- "meta_cid": self.meta_cid.to_string(),
"mst_cid": self.mst_cid.to_string(),
+ "sig": data_encoding::HEXUPPER.encode(&self.sig),
+ "commit_cid": self.commit_cid.to_string(),
})
}
}
@@ -115,7 +113,7 @@ impl RepoStore {
pub fn get_commit(&mut self, commit_cid: &Cid) -> Result<RepoCommit> {
// read records by CID: commit, root, meta
- let commit_node: CommitNode = DagCborCodec
+ let commit_node: SignedCommitNode = DagCborCodec
.decode(
&self
.db
@@ -123,40 +121,18 @@ impl RepoStore {
.ok_or(anyhow!("expected commit block in store"))?,
)
.context("parsing commit IPLD node from blockstore")?;
- let root_node: RootNode = DagCborCodec
- .decode(
- &self
- .db
- .get_block(&commit_node.root)?
- .ok_or(anyhow!("expected root block in store"))?,
- )
- .context("parsing root IPLD node from blockstore")?;
- let metadata_node: MetadataNode = DagCborCodec
- .decode(
- &self
- .db
- .get_block(&root_node.meta)?
- .ok_or(anyhow!("expected metadata block in store"))?,
- )
- .context("parsing metadata IPLD node from blockstore")?;
- ensure!(
- metadata_node.datastore == "mst",
- "unexpected repo metadata.datastore: {}",
- metadata_node.datastore
- );
ensure!(
- metadata_node.version == 1,
- "unexpected repo metadata.version: {}",
- metadata_node.version
+ commit_node.version == 2,
+ "unexpected repo version: {}",
+ commit_node.version
);
Ok(RepoCommit {
+ did: Did::from_str(&commit_node.did)?,
+ version: commit_node.version,
+ prev: commit_node.prev,
+ mst_cid: commit_node.data,
sig: commit_node.sig,
commit_cid: *commit_cid,
- root_cid: commit_node.root,
- meta_cid: root_node.meta,
- did: Did::from_str(&metadata_node.did)?,
- prev: root_node.prev,
- mst_cid: root_node.data,
})
}
@@ -200,26 +176,28 @@ impl RepoStore {
self.get_mst_record_by_key(&commit.mst_cid, &record_key)
}
- pub fn write_metadata(&mut self, did: &Did) -> Result<Cid> {
- self.put_ipld(&MetadataNode {
- datastore: "mst".to_string(),
+ pub fn write_commit(
+ &mut self,
+ did: &Did,
+ prev: Option<Cid>,
+ mst_cid: Cid,
+ signing_key: &KeyPair,
+ ) -> Result<Cid> {
+ let unsigned_commit = UnsignedCommitNode {
did: did.to_string(),
- version: 1,
- })
- }
-
- pub fn write_root(&mut self, meta_cid: Cid, prev: Option<Cid>, mst_cid: Cid) -> Result<Cid> {
- self.put_ipld(&RootNode {
- auth_token: None,
+ version: 2,
prev,
- meta: meta_cid,
data: mst_cid,
- })
- }
+ };
+ let block = Block::<DefaultParams>::encode(DagCborCodec, Code::Sha2_256, &unsigned_commit)?;
+ let digest = sha256::digest(block.data());
+ let sig = signing_key.sign_bytes(digest.as_bytes());
- pub fn write_commit(&mut self, did: &Did, root_cid: Cid, sig: &str) -> Result<Cid> {
- let commit_cid = self.put_ipld(&CommitNode {
- root: root_cid,
+ let commit_cid = self.put_ipld(&SignedCommitNode {
+ did: did.to_string(),
+ version: 2,
+ prev,
+ data: mst_cid,
sig: sig.as_bytes().to_vec().into_boxed_slice(),
})?;
self.db.alias(did.as_bytes().to_vec(), Some(&commit_cid))?;
@@ -272,19 +250,11 @@ impl RepoStore {
let new_mst_cid = self
.update_mst(&last_commit.mst_cid, mutations)
.context("updating MST in repo")?;
- let new_root_cid = self.write_root(
- last_commit.meta_cid,
- Some(last_commit.commit_cid),
- new_mst_cid,
- )?;
- // TODO: is this how signatures are supposed to work?
- // TODO: no, CID in bytes and sign that?
- let sig = signing_key.sign_bytes(new_root_cid.to_string().as_bytes());
- self.write_commit(did, new_root_cid, &sig)
+ self.write_commit(did, Some(last_commit.commit_cid), new_mst_cid, &signing_key)
}
/// Reads in a full MST tree starting at a repo commit, then re-builds and re-writes the tree
- /// in to the repo, and verifies that both the MST root CIDs and the repo root CIDs are identical.
+ /// in to the repo, and verifies that both the MST root CIDs are identical.
pub fn verify_repo_mst(&mut self, commit_cid: &Cid) -> Result<()> {
// load existing commit and MST tree
let existing_commit = self.get_commit(commit_cid)?;
@@ -300,16 +270,6 @@ impl RepoStore {
))?;
}
- let new_root_cid =
- self.write_root(existing_commit.meta_cid, existing_commit.prev, new_mst_cid)?;
- if new_root_cid != existing_commit.root_cid {
- Err(anyhow!(
- "repo root CID did not verify: {} != {}",
- existing_commit.root_cid,
- new_root_cid
- ))?;
- }
-
Ok(())
}
@@ -359,6 +319,7 @@ fn test_repo_mst() {
let mut repo = RepoStore::open_ephemeral().unwrap();
let did = Did::from_str("did:plc:dummy").unwrap();
+ let dummy_keypair = KeyPair::new_random();
// basic blob and IPLD record put/get
let blob = b"beware the swamp thing";
@@ -387,10 +348,8 @@ fn test_repo_mst() {
assert_eq!(map, repo.mst_to_map(&simple_map_cid).unwrap());
// create root and commit IPLD nodes
- let meta_cid = repo.write_metadata(&did).unwrap();
- let simple_root_cid = repo.write_root(meta_cid, None, simple_map_cid).unwrap();
let simple_commit_cid = repo
- .write_commit(&did, simple_root_cid, "dummy-sig")
+ .write_commit(&did, None, simple_map_cid, &dummy_keypair)
.unwrap();
assert_eq!(
Some(record.clone()),
@@ -422,11 +381,13 @@ fn test_repo_mst() {
map.insert("test.records/33333333333333".to_string(), record_cid);
let simple3_map_cid = repo.mst_from_map(&map).unwrap();
- let simple3_root_cid = repo
- .write_root(meta_cid, Some(simple_commit_cid), simple3_map_cid)
- .unwrap();
let simple3_commit_cid = repo
- .write_commit(&did, simple3_root_cid, "dummy-sig3")
+ .write_commit(
+ &did,
+ Some(simple_commit_cid),
+ simple3_map_cid,
+ &dummy_keypair,
+ )
.unwrap();
assert_eq!(map, repo.mst_to_map(&simple3_map_cid).unwrap());
assert_eq!(
@@ -444,7 +405,6 @@ fn test_repo_mst() {
.unwrap()
);
let commit = repo.get_commit(&simple3_commit_cid).unwrap();
- assert_eq!(commit.sig.to_vec(), b"dummy-sig3".to_vec());
assert_eq!(commit.did, did);
assert_eq!(commit.prev, Some(simple_commit_cid));
assert_eq!(commit.mst_cid, simple3_map_cid);