diff options
Diffstat (limited to 'adenosine-pds')
| -rw-r--r-- | adenosine-pds/src/crypto.rs | 7 | ||||
| -rw-r--r-- | adenosine-pds/src/db.rs | 30 | ||||
| -rw-r--r-- | adenosine-pds/src/did.rs | 23 | ||||
| -rw-r--r-- | adenosine-pds/src/lib.rs | 42 | ||||
| -rw-r--r-- | adenosine-pds/src/repo.rs | 208 | 
5 files changed, 158 insertions, 152 deletions
| diff --git a/adenosine-pds/src/crypto.rs b/adenosine-pds/src/crypto.rs index 07119b1..d1a864e 100644 --- a/adenosine-pds/src/crypto.rs +++ b/adenosine-pds/src/crypto.rs @@ -1,4 +1,5 @@  use crate::P256KeyMaterial; +use adenosine_cli::identifiers::Did;  use anyhow::{anyhow, ensure, Result};  use p256::ecdsa::signature::{Signer, Verifier};  use std::str::FromStr; @@ -62,7 +63,7 @@ impl KeyPair {      }      /// This is currently just an un-validated token; we don't actually verify these. -    pub fn ucan(&self, did: &str) -> Result<String> { +    pub fn ucan(&self, did: &Did) -> Result<String> {          let key_material = self.ucan_keymaterial();          let rt = tokio::runtime::Builder::new_current_thread()              .enable_all() @@ -81,10 +82,10 @@ impl KeyPair {      }  } -async fn build_ucan(key_material: P256KeyMaterial, did: &str) -> Result<String> { +async fn build_ucan(key_material: P256KeyMaterial, did: &Did) -> Result<String> {      let token_string = UcanBuilder::default()          .issued_by(&key_material) -        .for_audience(did) +        .for_audience(&did.to_string())          .with_nonce()          .with_lifetime(60 * 60 * 24 * 90)          .build()? diff --git a/adenosine-pds/src/db.rs b/adenosine-pds/src/db.rs index 0fae769..5f185c8 100644 --- a/adenosine-pds/src/db.rs +++ b/adenosine-pds/src/db.rs @@ -1,5 +1,5 @@  /// ATP database (as distinct from blockstore) -use crate::{AtpSession, KeyPair}; +use crate::{AtpSession, Did, KeyPair};  use anyhow::{anyhow, Result};  use lazy_static::lazy_static;  use log::debug; @@ -74,7 +74,7 @@ impl AtpDatabase {      pub fn create_account(          &mut self, -        did: &str, +        did: &Did,          username: &str,          password: &str,          email: &str, @@ -89,8 +89,8 @@ impl AtpDatabase {              username,              password_bcrypt,              email, -            did, -            recovery_pubkey +            did.to_string(), +            recovery_pubkey,          ))?;          Ok(())      } @@ -105,18 +105,19 @@ impl AtpDatabase {          let mut stmt = self              .conn              .prepare_cached("SELECT did, password_bcrypt FROM account WHERE username = ?1")?; -        let (did, password_bcrypt): (String, String) = +        let (did_col, password_bcrypt): (String, String) =              stmt.query_row(params!(username), |row| Ok((row.get(0)?, row.get(1)?)))?;          if !bcrypt::verify(password, &password_bcrypt)? {              return Err(anyhow!("password did not match"));          } +        let did = Did::from_str(&did_col)?;          let jwt = keypair.ucan(&did)?;          let mut stmt = self              .conn              .prepare_cached("INSERT INTO session (did, jwt) VALUES (?1, ?2)")?; -        stmt.execute(params!(did, jwt))?; +        stmt.execute(params!(did.to_string(), jwt))?;          Ok(AtpSession { -            did, +            did: did.to_string(),              name: username.to_string(),              accessJwt: jwt.to_string(),              refreshJwt: jwt, @@ -124,12 +125,13 @@ impl AtpDatabase {      }      /// Returns the DID that a token is valid for, or None if session not found -    pub fn check_auth_token(&mut self, jwt: &str) -> Result<Option<String>> { +    pub fn check_auth_token(&mut self, jwt: &str) -> Result<Option<Did>> {          let mut stmt = self              .conn              .prepare_cached("SELECT did FROM session WHERE jwt = $1")?; -        let did_maybe = stmt.query_row(params!(jwt), |row| row.get(0)).optional()?; -        Ok(did_maybe) +        let did_maybe: Option<String> = +            stmt.query_row(params!(jwt), |row| row.get(0)).optional()?; +        Ok(did_maybe.map(|v| Did::from_str(&v).expect("valid DID in database")))      }      pub fn delete_session(&mut self, jwt: &str) -> Result<bool> { @@ -140,18 +142,18 @@ impl AtpDatabase {          Ok(count >= 1)      } -    pub fn put_did_doc(&mut self, did: &str, did_doc: &Value) -> Result<()> { +    pub fn put_did_doc(&mut self, did: &Did, did_doc: &Value) -> Result<()> {          let mut stmt = self              .conn              .prepare_cached("INSERT INTO did_doc (did, doc_json) VALUES (?1, ?2)")?; -        stmt.execute(params!(did, did_doc.to_string()))?; +        stmt.execute(params!(did.to_string(), did_doc.to_string()))?;          Ok(())      } -    pub fn get_did_doc(&mut self, did: &str) -> Result<Value> { +    pub fn get_did_doc(&mut self, did: &Did) -> Result<Value> {          let mut stmt = self              .conn              .prepare_cached("SELECT doc_json FROM did_doc WHERE did = $1")?; -        let doc_json: String = stmt.query_row(params!(did), |row| row.get(0))?; +        let doc_json: String = stmt.query_row(params!(did.to_string()), |row| row.get(0))?;          Ok(Value::from_str(&doc_json)?)      }  } diff --git a/adenosine-pds/src/did.rs b/adenosine-pds/src/did.rs index cfec27c..84cf4c2 100644 --- a/adenosine-pds/src/did.rs +++ b/adenosine-pds/src/did.rs @@ -1,14 +1,15 @@ -use crate::{KeyPair, PubKey};  /// DID and 'did:plc' stuff  ///  /// This is currently a partial/skeleton implementation, which only generates local/testing did:plc  /// DIDs (and DID documents) using a single 'create' genesis block. Key rotation, etc, is not  /// supported. +use crate::{Did, KeyPair, PubKey};  use anyhow::Result;  use libipld::cbor::DagCborCodec;  use libipld::multihash::Code;  use libipld::{Block, Cid, DagCbor, DefaultParams};  use serde_json::json; +use std::str::FromStr;  #[allow(non_snake_case)]  #[derive(Debug, DagCbor, PartialEq, Eq, Clone)] @@ -72,7 +73,7 @@ impl CreateOp {          unsigned.into_signed(sig)      } -    pub fn did_plc(&self) -> String { +    pub fn did_plc(&self) -> Did {          // dump DAG-CBOR          let block = Block::<DefaultParams>::encode(DagCborCodec, Code::Sha2_256, self)              .expect("encode DAG-CBOR"); @@ -86,7 +87,7 @@ impl CreateOp {              .encode(&digest_bytes)              .to_ascii_lowercase();          // truncate -        format!("did:plc:{}", &digest_b32[0..24]) +        Did::from_str(&format!("did:plc:{}", &digest_b32[0..24])).unwrap()      }      pub fn did_doc(&self) -> serde_json::Value { @@ -99,19 +100,19 @@ impl CreateOp {                  "https://www.w3.org/ns/did/v1",                  "https://w3id.org/security/suites/ecdsa-2019/v1"              ], -            "id": did, +            "id": did.to_string(),              "alsoKnownAs": [ user_url ],              "verificationMethod": [                  {                  "id": format!("{}#signingKey)", did),                  "type": key_type, -                "controller": did, +                "controller": did.to_string(),                  "publicKeyMultibase": self.signingKey                  },                  {                  "id": format!("{}#recoveryKey)", did),                  "type": key_type, -                "controller": did, +                "controller": did.to_string(),                  "publicKeyMultibase": self.recoveryKey                  }              ], @@ -295,7 +296,10 @@ fn test_did_plc_examples() {                  .to_string(),      };      op.verify_self().unwrap(); -    assert_eq!(&op.did_plc(), "did:plc:7iza6de2dwap2sbkpav7c6c6"); +    assert_eq!( +        &op.did_plc().to_string(), +        "did:plc:7iza6de2dwap2sbkpav7c6c6" +    );      // interacting with PDS / PLC server      let op = CreateOp { @@ -310,7 +314,10 @@ fn test_did_plc_examples() {                  .to_string(),      };      op.verify_self().unwrap(); -    assert_eq!(&op.did_plc(), "did:plc:bmrcg7zrxoiw2kiml3tkw2xv"); +    assert_eq!( +        &op.did_plc().to_string(), +        "did:plc:bmrcg7zrxoiw2kiml3tkw2xv" +    );  }  #[test] diff --git a/adenosine-pds/src/lib.rs b/adenosine-pds/src/lib.rs index ac3868a..d0ef02a 100644 --- a/adenosine-pds/src/lib.rs +++ b/adenosine-pds/src/lib.rs @@ -207,8 +207,8 @@ fn xrpc_get_handler(          }          "com.atproto.repoGetRecord" => {              let did = Did::from_str(&xrpc_required_param(request, "user")?)?; -            let collection = xrpc_required_param(request, "collection")?; -            let rkey = xrpc_required_param(request, "rkey")?; +            let collection = Nsid::from_str(&xrpc_required_param(request, "collection")?)?; +            let rkey = Tid::from_str(&xrpc_required_param(request, "rkey")?)?;              let mut srv = srv.lock().expect("service mutex");              let key = format!("/{}/{}", collection, rkey);              match srv.repo.get_atp_record(&did, &collection, &rkey) { @@ -325,11 +325,11 @@ fn xrpc_post_handler(              // insert empty MST repository              let root_cid = { -                let empty_map_cid: String = srv.repo.mst_from_map(&Default::default())?; +                let empty_map_cid = srv.repo.mst_from_map(&Default::default())?;                  let meta_cid = srv.repo.write_metadata(&did)?; -                srv.repo.write_root(&meta_cid, None, &empty_map_cid)? +                srv.repo.write_root(meta_cid, None, empty_map_cid)?              }; -            let _commit_cid = srv.repo.write_commit(&did, &root_cid, "XXX-dummy-sig")?; +            let _commit_cid = srv.repo.write_commit(&did, root_cid, "XXX-dummy-sig")?;              let keypair = srv.pds_keypair.clone();              let sess = srv @@ -400,11 +400,11 @@ fn xrpc_post_handler(              }              let new_mst_cid = srv.repo.update_mst(&last_commit.mst_cid, &mutations)?;              let new_root_cid = srv.repo.write_root( -                &last_commit.meta_cid, -                Some(&last_commit.commit_cid), -                &new_mst_cid, +                last_commit.meta_cid, +                Some(last_commit.commit_cid), +                new_mst_cid,              )?; -            srv.repo.write_commit(&did, &new_root_cid, "dummy-sig")?; +            srv.repo.write_commit(&did, new_root_cid, "dummy-sig")?;              // TODO: next handle updates to database              Ok(json!({}))          } @@ -430,12 +430,12 @@ fn xrpc_post_handler(                  .context("updating MST in repo")?;              debug!("writing new root");              let new_root_cid = srv.repo.write_root( -                &last_commit.meta_cid, -                Some(&last_commit.commit_cid), -                &new_mst_cid, +                last_commit.meta_cid, +                Some(last_commit.commit_cid), +                new_mst_cid,              )?;              debug!("writing new commit"); -            srv.repo.write_commit(&did, &new_root_cid, "dummy-sig")?; +            srv.repo.write_commit(&did, new_root_cid, "dummy-sig")?;              // TODO: next handle updates to database              Ok(json!({}))          } @@ -459,11 +459,11 @@ fn xrpc_post_handler(                  .update_mst(&last_commit.mst_cid, &mutations)                  .context("updating MST in repo")?;              let new_root_cid = srv.repo.write_root( -                &last_commit.meta_cid, -                Some(&last_commit.commit_cid), -                &new_mst_cid, +                last_commit.meta_cid, +                Some(last_commit.commit_cid), +                new_mst_cid,              )?; -            srv.repo.write_commit(&did, &new_root_cid, "dummy-sig")?; +            srv.repo.write_commit(&did, new_root_cid, "dummy-sig")?;              // TODO: next handle updates to database              Ok(json!({}))          } @@ -478,11 +478,11 @@ fn xrpc_post_handler(              let mutations: Vec<Mutation> = vec![Mutation::Delete(collection, tid)];              let new_mst_cid = srv.repo.update_mst(&last_commit.mst_cid, &mutations)?;              let new_root_cid = srv.repo.write_root( -                &last_commit.meta_cid, -                Some(&last_commit.commit_cid), -                &new_mst_cid, +                last_commit.meta_cid, +                Some(last_commit.commit_cid), +                new_mst_cid,              )?; -            srv.repo.write_commit(&did, &new_root_cid, "dummy-sig")?; +            srv.repo.write_commit(&did, new_root_cid, "dummy-sig")?;              // TODO: next handle updates to database              Ok(json!({}))          } diff --git a/adenosine-pds/src/repo.rs b/adenosine-pds/src/repo.rs index 289125c..ad9aade 100644 --- a/adenosine-pds/src/repo.rs +++ b/adenosine-pds/src/repo.rs @@ -1,6 +1,6 @@  use crate::load_car_to_blockstore;  use crate::mst::{collect_mst_keys, generate_mst, CommitNode, MetadataNode, RootNode}; -use adenosine_cli::identifiers::{Nsid, Tid}; +use adenosine_cli::identifiers::{Did, Nsid, Tid};  use anyhow::{anyhow, ensure, Context, Result};  use ipfs_sqlite_block_store::BlockStore;  use libipld::cbor::DagCborCodec; @@ -16,11 +16,11 @@ use std::str::FromStr;  pub struct RepoCommit {      pub sig: Box<[u8]>, -    pub commit_cid: String, -    pub did: String, -    pub prev: Option<String>, -    pub meta_cid: String, -    pub mst_cid: String, +    pub commit_cid: Cid, +    pub did: Did, +    pub prev: Option<Cid>, +    pub meta_cid: Cid, +    pub mst_cid: Cid,  }  pub struct RepoStore { @@ -52,59 +52,51 @@ impl RepoStore {          })      } -    pub fn get_ipld(&mut self, cid: &str) -> Result<Ipld> { -        let ipld_cid = Cid::from_str(cid)?; -        if let Some(b) = self.db.get_block(&ipld_cid)? { -            let block: Block<DefaultParams> = Block::new(ipld_cid, b)?; +    pub fn get_ipld(&mut self, cid: &Cid) -> Result<Ipld> { +        if let Some(b) = self.db.get_block(cid)? { +            let block: Block<DefaultParams> = Block::new(cid.clone(), b)?;              block.ipld()          } else {              Err(anyhow!("missing IPLD CID: {}", cid))          }      } -    pub fn get_blob(&mut self, cid: &str) -> Result<Option<Vec<u8>>> { -        let cid = Cid::from_str(cid)?; -        Ok(self.db.get_block(&cid)?) +    pub fn get_blob(&mut self, cid: &Cid) -> Result<Option<Vec<u8>>> { +        Ok(self.db.get_block(cid)?)      }      /// Returns CID that was inserted -    pub fn put_ipld<S: libipld::codec::Encode<DagCborCodec>>( -        &mut self, -        record: &S, -    ) -> Result<String> { +    pub fn put_ipld<S: libipld::codec::Encode<DagCborCodec>>(&mut self, record: &S) -> Result<Cid> {          let block = Block::<DefaultParams>::encode(DagCborCodec, Code::Sha2_256, record)?;          let cid = *block.cid();          self.db              .put_block(block, None)              .context("writing IPLD DAG-CBOR record to blockstore")?; -        Ok(cid.to_string()) +        Ok(cid)      }      /// Returns CID that was inserted -    pub fn put_blob(&mut self, data: &[u8]) -> Result<String> { +    pub fn put_blob(&mut self, data: &[u8]) -> Result<Cid> {          let block = Block::<DefaultParams>::encode(libipld::raw::RawCodec, Code::Sha2_256, data)?;          let cid = *block.cid();          self.db              .put_block(block, None)              .context("writing non-record blob to blockstore")?; -        Ok(cid.to_string()) +        Ok(cid)      }      /// Quick alias lookup -    pub fn lookup_commit(&mut self, did: &str) -> Result<Option<String>> { -        Ok(self -            .db -            .resolve(Cow::from(did.as_bytes()))? -            .map(|cid| cid.to_string())) +    pub fn lookup_commit(&mut self, did: &Did) -> Result<Option<Cid>> { +        Ok(self.db.resolve(Cow::from(did.as_bytes()))?)      } -    pub fn get_commit(&mut self, commit_cid: &str) -> Result<RepoCommit> { +    pub fn get_commit(&mut self, commit_cid: &Cid) -> Result<RepoCommit> {          // read records by CID: commit, root, meta          let commit_node: CommitNode = DagCborCodec              .decode(                  &self                      .db -                    .get_block(&Cid::from_str(commit_cid)?)? +                    .get_block(commit_cid)?                      .ok_or(anyhow!("expected commit block in store"))?,              )              .context("parsing commit IPLD node from blockstore")?; @@ -136,24 +128,24 @@ impl RepoStore {          );          Ok(RepoCommit {              sig: commit_node.sig, -            commit_cid: commit_cid.to_string(), -            meta_cid: root_node.meta.to_string(), -            did: metadata_node.did, -            prev: root_node.prev.map(|cid| cid.to_string()), -            mst_cid: root_node.data.to_string(), +            commit_cid: commit_cid.clone(), +            meta_cid: root_node.meta, +            did: Did::from_str(&metadata_node.did)?, +            prev: root_node.prev, +            mst_cid: root_node.data,          })      } -    pub fn get_mst_record_by_key(&mut self, mst_cid: &str, key: &str) -> Result<Option<Ipld>> { +    pub fn get_mst_record_by_key(&mut self, mst_cid: &Cid, key: &str) -> Result<Option<Ipld>> {          let map = self.mst_to_map(mst_cid)?;          if let Some(cid) = map.get(key) { -            self.get_ipld(&cid.to_string()).map(|v| Some(v)) +            self.get_ipld(&cid).map(|v| Some(v))          } else {              Ok(None)          }      } -    pub fn collections(&mut self, did: &str) -> Result<Vec<String>> { +    pub fn collections(&mut self, did: &Did) -> Result<Vec<String>> {          let commit = if let Some(c) = self.lookup_commit(did)? {              self.get_commit(&c)?          } else { @@ -171,9 +163,9 @@ impl RepoStore {      pub fn get_atp_record(          &mut self, -        did: &str, -        collection: &str, -        tid: &str, +        did: &Did, +        collection: &Nsid, +        tid: &Tid,      ) -> Result<Option<Ipld>> {          let commit = if let Some(c) = self.lookup_commit(did)? {              self.get_commit(&c)? @@ -184,7 +176,7 @@ impl RepoStore {          self.get_mst_record_by_key(&commit.mst_cid, &record_key)      } -    pub fn write_metadata(&mut self, did: &str) -> Result<String> { +    pub fn write_metadata(&mut self, did: &Did) -> Result<Cid> {          self.put_ipld(&MetadataNode {              datastore: "mst".to_string(),              did: did.to_string(), @@ -192,61 +184,47 @@ impl RepoStore {          })      } -    pub fn write_root( -        &mut self, -        meta_cid: &str, -        prev: Option<&str>, -        mst_cid: &str, -    ) -> Result<String> { +    pub fn write_root(&mut self, meta_cid: Cid, prev: Option<Cid>, mst_cid: Cid) -> Result<Cid> {          self.put_ipld(&RootNode {              auth_token: None, -            // TODO: not unwrap here -            prev: prev.map(|s| Cid::from_str(s).unwrap()), -            // TODO: not 'metadata'? -            meta: Cid::from_str(meta_cid)?, -            data: Cid::from_str(mst_cid)?, +            prev, +            meta: meta_cid, +            data: mst_cid,          })      } -    pub fn write_commit(&mut self, did: &str, root_cid: &str, sig: &str) -> Result<String> { +    pub fn write_commit(&mut self, did: &Did, root_cid: Cid, sig: &str) -> Result<Cid> {          let commit_cid = self.put_ipld(&CommitNode { -            root: Cid::from_str(root_cid)?, +            root: root_cid,              sig: sig.as_bytes().to_vec().into_boxed_slice(),          })?; -        self.db -            .alias(did.as_bytes().to_vec(), Some(&Cid::from_str(&commit_cid)?))?; +        self.db.alias(did.as_bytes().to_vec(), Some(&commit_cid))?;          Ok(commit_cid)      } -    pub fn mst_from_map(&mut self, map: &BTreeMap<String, String>) -> Result<String> { -        // TODO: not unwrap in iter -        let cid_map: BTreeMap<String, Cid> = BTreeMap::from_iter( -            map.iter() -                .map(|(k, v)| (k.to_string(), Cid::from_str(v).unwrap())), -        ); -        let mst_cid = generate_mst(&mut self.db, &cid_map)?; -        Ok(mst_cid.to_string()) +    pub fn mst_from_map(&mut self, map: &BTreeMap<String, Cid>) -> Result<Cid> { +        let mst_cid = generate_mst(&mut self.db, map)?; +        Ok(mst_cid)      } -    fn mst_to_cid_map(&mut self, mst_cid: &str) -> Result<BTreeMap<String, Cid>> { +    pub fn mst_to_map(&mut self, mst_cid: &Cid) -> Result<BTreeMap<String, Cid>> {          let mut cid_map: BTreeMap<String, Cid> = Default::default(); -        let mst_cid = Cid::from_str(mst_cid)?; -        collect_mst_keys(&mut self.db, &mst_cid, &mut cid_map) +        collect_mst_keys(&mut self.db, mst_cid, &mut cid_map)              .context("reading repo MST from blockstore")?;          Ok(cid_map)      } -    pub fn update_mst(&mut self, mst_cid: &str, mutations: &[Mutation]) -> Result<String> { -        let mut cid_map = self.mst_to_cid_map(mst_cid)?; +    pub fn update_mst(&mut self, mst_cid: &Cid, mutations: &[Mutation]) -> Result<Cid> { +        let mut cid_map = self.mst_to_map(mst_cid)?;          for m in mutations.iter() {              match m {                  Mutation::Create(collection, tid, val) => {                      let cid = self.put_ipld(val)?; -                    cid_map.insert(format!("/{}/{}", collection, tid), Cid::from_str(&cid)?); +                    cid_map.insert(format!("/{}/{}", collection, tid), cid);                  }                  Mutation::Update(collection, tid, val) => {                      let cid = self.put_ipld(val)?; -                    cid_map.insert(format!("/{}/{}", collection, tid), Cid::from_str(&cid)?); +                    cid_map.insert(format!("/{}/{}", collection, tid), cid);                  }                  Mutation::Delete(collection, tid) => {                      cid_map.remove(&format!("/{}/{}", collection, tid)); @@ -254,21 +232,13 @@ impl RepoStore {              }          }          let mst_cid = generate_mst(&mut self.db, &cid_map)?; -        Ok(mst_cid.to_string()) -    } - -    /// Returns all the keys for a directory, as a sorted vec of strings -    pub fn mst_to_map(&mut self, mst_cid: &str) -> Result<BTreeMap<String, String>> { -        let cid_map = self.mst_to_cid_map(mst_cid)?; -        let ret_map: BTreeMap<String, String> = -            BTreeMap::from_iter(cid_map.into_iter().map(|(k, v)| (k, v.to_string()))); -        Ok(ret_map) +        Ok(mst_cid)      }      /// returns the root commit from CAR file -    pub fn load_car(&mut self, car_path: &PathBuf, alias: &str) -> Result<String> { +    pub fn load_car(&mut self, car_path: &PathBuf, alias: &str) -> Result<Cid> {          let cid = load_car_to_blockstore(&mut self.db, car_path, alias)?; -        Ok(cid.to_string()) +        Ok(cid)      }      /// Exports in CAR format to a Writer @@ -276,8 +246,8 @@ impl RepoStore {      /// The "from" commit CID feature is not implemented.      pub fn write_car<W: std::io::Write>(          &mut self, -        _did: &str, -        _from_commit_cid: Option<&str>, +        _did: &Did, +        _from_commit_cid: Option<&Cid>,          _out: &mut W,      ) -> Result<()> {          unimplemented!() @@ -289,76 +259,102 @@ fn test_repo_mst() {      use libipld::ipld;      let mut repo = RepoStore::open_ephemeral().unwrap(); -    let did = "did:plc:dummy"; +    let did = Did::from_str("did:plc:dummy").unwrap();      // basic blob and IPLD record put/get      let blob = b"beware the swamp thing"; -    let blob_cid: String = repo.put_blob(blob).unwrap(); +    let blob_cid = repo.put_blob(blob).unwrap();      let record = ipld!({"some-thing": 123}); -    let record_cid: String = repo.put_ipld(&record).unwrap(); +    let record_cid = repo.put_ipld(&record).unwrap();      repo.get_blob(&blob_cid).unwrap().unwrap();      repo.get_ipld(&record_cid).unwrap();      // basic MST get/put -    let mut map: BTreeMap<String, String> = Default::default(); -    let empty_map_cid: String = repo.mst_from_map(&map).unwrap(); +    let mut map: BTreeMap<String, Cid> = Default::default(); +    let empty_map_cid = repo.mst_from_map(&map).unwrap();      assert_eq!(map, repo.mst_to_map(&empty_map_cid).unwrap());      assert!(repo -        .get_mst_record_by_key(&empty_map_cid, "/records/1") +        .get_mst_record_by_key(&empty_map_cid, "/test.records/44444444444444")          .unwrap()          .is_none());      map.insert("/blobs/1".to_string(), blob_cid.clone());      map.insert("/blobs/2".to_string(), blob_cid.clone()); -    map.insert("/records/1".to_string(), record_cid.clone()); -    map.insert("/records/2".to_string(), record_cid.clone()); -    let simple_map_cid: String = repo.mst_from_map(&map).unwrap(); +    map.insert( +        "/test.records/44444444444444".to_string(), +        record_cid.clone(), +    ); +    map.insert( +        "/test.records/22222222222222".to_string(), +        record_cid.clone(), +    ); +    let simple_map_cid = repo.mst_from_map(&map).unwrap();      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 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, simple_root_cid, "dummy-sig")          .unwrap();      assert_eq!(          Some(record.clone()), -        repo.get_mst_record_by_key(&simple_map_cid, "/records/1") +        repo.get_mst_record_by_key(&simple_map_cid, "/test.records/44444444444444")              .unwrap()      );      assert_eq!(          Some(record.clone()), -        repo.get_atp_record(did, "records", "1").unwrap() +        repo.get_atp_record( +            &did, +            &Nsid::from_str("test.records").unwrap(), +            &Tid::from_str("44444444444444").unwrap() +        ) +        .unwrap()      );      assert!(repo -        .get_mst_record_by_key(&simple_map_cid, "/records/3") +        .get_mst_record_by_key(&simple_map_cid, "/test.records/33333333333333") +        .unwrap() +        .is_none()); +    assert!(repo +        .get_atp_record( +            &did, +            &Nsid::from_str("test.records").unwrap(), +            &Tid::from_str("33333333333333").unwrap() +        )          .unwrap()          .is_none()); -    assert!(repo.get_atp_record(did, "records", "3").unwrap().is_none());      assert_eq!(          Some(simple_commit_cid.clone()), -        repo.lookup_commit(did).unwrap() +        repo.lookup_commit(&did).unwrap()      ); -    map.insert("/records/3".to_string(), record_cid.clone()); -    let simple3_map_cid: String = repo.mst_from_map(&map).unwrap(); +    map.insert( +        "/test.records/33333333333333".to_string(), +        record_cid.clone(), +    ); +    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) +        .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, simple3_root_cid, "dummy-sig3")          .unwrap();      assert_eq!(map, repo.mst_to_map(&simple3_map_cid).unwrap());      assert_eq!(          Some(record.clone()), -        repo.get_mst_record_by_key(&simple3_map_cid, "/records/3") +        repo.get_mst_record_by_key(&simple3_map_cid, "/test.records/33333333333333")              .unwrap()      );      assert_eq!(          Some(record.clone()), -        repo.get_atp_record(did, "records", "3").unwrap() +        repo.get_atp_record( +            &did, +            &Nsid::from_str("test.records").unwrap(), +            &Tid::from_str("33333333333333").unwrap() +        ) +        .unwrap()      );      let commit = repo.get_commit(&simple3_commit_cid).unwrap();      assert_eq!(commit.sig.to_vec(), b"dummy-sig3".to_vec()); @@ -367,6 +363,6 @@ fn test_repo_mst() {      assert_eq!(commit.mst_cid, simple3_map_cid);      assert_eq!(          Some(simple3_commit_cid.clone()), -        repo.lookup_commit(did).unwrap() +        repo.lookup_commit(&did).unwrap()      );  } | 
