···242242 async fn test_cursor_single_leaf() {
243243 let storage = Arc::new(MemoryBlockStore::new());
244244 let tree = Mst::new(storage);
245245- let tree = tree.add("key1", test_cid(1)).await.unwrap();
245245+ let tree = tree.add("com.example.test/key1", test_cid(1)).await.unwrap();
246246247247 let mut cursor = MstCursor::new(tree);
248248···251251252252 // Advance to first leaf
253253 cursor.advance().await.unwrap();
254254- assert_eq!(cursor.key(), Some("key1"));
254254+ assert_eq!(cursor.key(), Some("com.example.test/key1"));
255255256256 // Advance past last leaf
257257 cursor.advance().await.unwrap();
···262262 async fn test_cursor_multiple_leaves() {
263263 let storage = Arc::new(MemoryBlockStore::new());
264264 let tree = Mst::new(storage);
265265- let tree = tree.add("a", test_cid(1)).await.unwrap();
266266- let tree = tree.add("b", test_cid(2)).await.unwrap();
267267- let tree = tree.add("c", test_cid(3)).await.unwrap();
265265+ let tree = tree.add("com.example.test/a", test_cid(1)).await.unwrap();
266266+ let tree = tree.add("com.example.test/b", test_cid(2)).await.unwrap();
267267+ let tree = tree.add("com.example.test/c", test_cid(3)).await.unwrap();
268268269269 let mut cursor = MstCursor::new(tree);
270270···280280 cursor.advance().await.unwrap();
281281 }
282282283283- assert_eq!(keys, vec!["a", "b", "c"]);
283283+ assert_eq!(keys, vec!["com.example.test/a", "com.example.test/b", "com.example.test/c"]);
284284 }
285285286286 #[tokio::test]
···289289 let tree = Mst::new(storage);
290290291291 // Add enough keys to create subtrees
292292- let tree = tree.add("a", test_cid(1)).await.unwrap();
293293- let tree = tree.add("b", test_cid(2)).await.unwrap();
294294- let tree = tree.add("c", test_cid(3)).await.unwrap();
292292+ let tree = tree.add("com.example.test/a", test_cid(1)).await.unwrap();
293293+ let tree = tree.add("com.example.test/b", test_cid(2)).await.unwrap();
294294+ let tree = tree.add("com.example.test/c", test_cid(3)).await.unwrap();
295295296296 let mut cursor = MstCursor::new(tree);
297297
+26-26
crates/jacquard-repo/src/mst/diff.rs
···548548549549 let storage2 = Arc::new(MemoryBlockStore::new());
550550 let tree2 = Mst::new(storage2);
551551- let tree2 = tree2.add("a", test_cid(1)).await.unwrap();
552552- let tree2 = tree2.add("b", test_cid(2)).await.unwrap();
551551+ let tree2 = tree2.add("com.example.test/a", test_cid(1)).await.unwrap();
552552+ let tree2 = tree2.add("com.example.test/b", test_cid(2)).await.unwrap();
553553554554 let diff = tree1.diff(&tree2).await.unwrap();
555555···562562 assert!(
563563 diff.creates
564564 .iter()
565565- .any(|(k, c)| k == "a" && *c == test_cid(1))
565565+ .any(|(k, c)| k == "com.example.test/a" && *c == test_cid(1))
566566 );
567567 assert!(
568568 diff.creates
569569 .iter()
570570- .any(|(k, c)| k == "b" && *c == test_cid(2))
570570+ .any(|(k, c)| k == "com.example.test/b" && *c == test_cid(2))
571571 );
572572 }
573573···575575 async fn test_diff_deletes() {
576576 let storage1 = Arc::new(MemoryBlockStore::new());
577577 let tree1 = Mst::new(storage1);
578578- let tree1 = tree1.add("a", test_cid(1)).await.unwrap();
579579- let tree1 = tree1.add("b", test_cid(2)).await.unwrap();
578578+ let tree1 = tree1.add("com.example.test/a", test_cid(1)).await.unwrap();
579579+ let tree1 = tree1.add("com.example.test/b", test_cid(2)).await.unwrap();
580580581581 let storage2 = Arc::new(MemoryBlockStore::new());
582582 let tree2 = Mst::new(storage2);
···592592 assert!(
593593 diff.deletes
594594 .iter()
595595- .any(|(k, c)| k == "a" && *c == test_cid(1))
595595+ .any(|(k, c)| k == "com.example.test/a" && *c == test_cid(1))
596596 );
597597 assert!(
598598 diff.deletes
599599 .iter()
600600- .any(|(k, c)| k == "b" && *c == test_cid(2))
600600+ .any(|(k, c)| k == "com.example.test/b" && *c == test_cid(2))
601601 );
602602 }
603603···605605 async fn test_diff_updates() {
606606 let storage1 = Arc::new(MemoryBlockStore::new());
607607 let tree1 = Mst::new(storage1);
608608- let tree1 = tree1.add("a", test_cid(1)).await.unwrap();
609609- let tree1 = tree1.add("b", test_cid(2)).await.unwrap();
608608+ let tree1 = tree1.add("com.example.test/a", test_cid(1)).await.unwrap();
609609+ let tree1 = tree1.add("com.example.test/b", test_cid(2)).await.unwrap();
610610611611 let storage2 = Arc::new(MemoryBlockStore::new());
612612 let tree2 = Mst::new(storage2);
613613- let tree2 = tree2.add("a", test_cid(10)).await.unwrap(); // Changed CID
614614- let tree2 = tree2.add("b", test_cid(2)).await.unwrap(); // Same CID
613613+ let tree2 = tree2.add("com.example.test/a", test_cid(10)).await.unwrap(); // Changed CID
614614+ let tree2 = tree2.add("com.example.test/b", test_cid(2)).await.unwrap(); // Same CID
615615616616 let diff = tree1.diff(&tree2).await.unwrap();
617617···621621 assert_eq!(diff.op_count(), 1);
622622623623 // Check update content
624624- assert_eq!(diff.updates[0].0, "a");
624624+ assert_eq!(diff.updates[0].0, "com.example.test/a");
625625 assert_eq!(diff.updates[0].1, test_cid(10)); // new CID
626626 assert_eq!(diff.updates[0].2, test_cid(1)); // old CID
627627 }
···630630 async fn test_diff_mixed_operations() {
631631 let storage1 = Arc::new(MemoryBlockStore::new());
632632 let tree1 = Mst::new(storage1);
633633- let tree1 = tree1.add("a", test_cid(1)).await.unwrap();
634634- let tree1 = tree1.add("b", test_cid(2)).await.unwrap();
635635- let tree1 = tree1.add("c", test_cid(3)).await.unwrap();
633633+ let tree1 = tree1.add("com.example.test/a", test_cid(1)).await.unwrap();
634634+ let tree1 = tree1.add("com.example.test/b", test_cid(2)).await.unwrap();
635635+ let tree1 = tree1.add("com.example.test/c", test_cid(3)).await.unwrap();
636636637637 let storage2 = Arc::new(MemoryBlockStore::new());
638638 let tree2 = Mst::new(storage2);
639639- let tree2 = tree2.add("a", test_cid(10)).await.unwrap(); // Updated
640640- let tree2 = tree2.add("b", test_cid(2)).await.unwrap(); // Unchanged
639639+ let tree2 = tree2.add("com.example.test/a", test_cid(10)).await.unwrap(); // Updated
640640+ let tree2 = tree2.add("com.example.test/b", test_cid(2)).await.unwrap(); // Unchanged
641641 // "c" deleted
642642- let tree2 = tree2.add("d", test_cid(4)).await.unwrap(); // Created
642642+ let tree2 = tree2.add("com.example.test/d", test_cid(4)).await.unwrap(); // Created
643643644644 let diff = tree1.diff(&tree2).await.unwrap();
645645···653653 async fn test_diff_to_empty() {
654654 let storage = Arc::new(MemoryBlockStore::new());
655655 let tree = Mst::new(storage);
656656- let tree = tree.add("a", test_cid(1)).await.unwrap();
657657- let tree = tree.add("b", test_cid(2)).await.unwrap();
658658- let tree = tree.add("c", test_cid(3)).await.unwrap();
656656+ let tree = tree.add("com.example.test/a", test_cid(1)).await.unwrap();
657657+ let tree = tree.add("com.example.test/b", test_cid(2)).await.unwrap();
658658+ let tree = tree.add("com.example.test/c", test_cid(3)).await.unwrap();
659659660660 let diff = tree.diff_to_empty().await.unwrap();
661661···688688 // diff(A, B) should be inverse of diff(B, A)
689689 let storage1 = Arc::new(MemoryBlockStore::new());
690690 let tree1 = Mst::new(storage1);
691691- let tree1 = tree1.add("a", test_cid(1)).await.unwrap();
692692- let tree1 = tree1.add("b", test_cid(2)).await.unwrap();
691691+ let tree1 = tree1.add("com.example.test/a", test_cid(1)).await.unwrap();
692692+ let tree1 = tree1.add("com.example.test/b", test_cid(2)).await.unwrap();
693693694694 let storage2 = Arc::new(MemoryBlockStore::new());
695695 let tree2 = Mst::new(storage2);
696696- let tree2 = tree2.add("b", test_cid(2)).await.unwrap();
697697- let tree2 = tree2.add("c", test_cid(3)).await.unwrap();
696696+ let tree2 = tree2.add("com.example.test/b", test_cid(2)).await.unwrap();
697697+ let tree2 = tree2.add("com.example.test/c", test_cid(3)).await.unwrap();
698698699699 let diff1 = tree1.diff(&tree2).await.unwrap();
700700 let diff2 = tree2.diff(&tree1).await.unwrap();
+222-89
crates/jacquard-repo/src/mst/tree.rs
···33use super::node::NodeEntry;
44use super::util;
55use crate::error::{RepoError, Result};
66+use crate::mst::util::validate_key;
67use crate::storage::BlockStore;
78use cid::Cid as IpldCid;
89use core::fmt;
···412413 ) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<IpldCid>>> + Send + 'a>>
413414 {
414415 Box::pin(async move {
415415- util::validate_key(key)?;
416416+ validate_key(key)?;
416417417418 let entries = self.get_entries().await?;
418419 let index = Self::find_gt_or_equal_leaf_index_in(&entries, key);
···448449 cid: IpldCid,
449450 ) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Mst<S>>> + Send + 'a>> {
450451 Box::pin(async move {
451451- util::validate_key(key)?;
452452+ validate_key(key)?;
452453453454 let key_layer = util::layer_for_key(key);
454455 let node_layer = self.get_layer().await?;
···571572 key: &'a str,
572573 ) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Mst<S>>> + Send + 'a>> {
573574 Box::pin(async move {
574574- util::validate_key(key)?;
575575+ validate_key(key)?;
575576576577 let altered = self.delete_recurse(key).await?;
577578 altered.trim_top().await
···645646646647 /// Update an existing key (returns new tree)
647648 pub async fn update(&self, key: &str, cid: IpldCid) -> Result<Mst<S>> {
648648- util::validate_key(key)?;
649649+ validate_key(key)?;
649650650651 // Check key exists
651652 if self.get(key).await?.is_none() {
···10851086 ) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Vec<IpldCid>>> + Send + 'a>>
10861087 {
10871088 Box::pin(async move {
10881088- util::validate_key(key)?;
10891089+ validate_key(key)?;
1089109010901091 let mut cids = vec![self.get_pointer().await?];
10911092 let entries = self.get_entries().await?;
···13081309 let storage = Arc::new(MemoryBlockStore::new());
13091310 let mst = Mst::new(storage);
1310131113111311- let result = mst.get("test/key").await.unwrap();
13121312+ let result = mst.get("com.example.test/key").await.unwrap();
13121313 assert!(result.is_none());
13131314 }
13141315···1319132013201321 let entries = vec![
13211322 NodeEntry::Leaf {
13221322- key: SmolStr::new("a"),
13231323+ key: SmolStr::new("com.example.test/a"),
13231324 value: test_cid(1),
13241325 },
13251326 NodeEntry::Leaf {
13261326- key: SmolStr::new("b"),
13271327+ key: SmolStr::new("com.example.test/b"),
13271328 value: test_cid(2),
13281329 },
13291330 NodeEntry::Leaf {
13301330- key: SmolStr::new("c"),
13311331+ key: SmolStr::new("com.example.test/c"),
13311332 value: test_cid(3),
13321333 },
13331334 ];
1334133513351336 let mst = Mst::create(storage, entries, Some(0)).await.unwrap();
1336133713371337- assert_eq!(mst.get("a").await.unwrap(), Some(test_cid(1)));
13381338- assert_eq!(mst.get("b").await.unwrap(), Some(test_cid(2)));
13391339- assert_eq!(mst.get("c").await.unwrap(), Some(test_cid(3)));
13401340- assert_eq!(mst.get("d").await.unwrap(), None);
13381338+ assert_eq!(
13391339+ mst.get("com.example.test/a").await.unwrap(),
13401340+ Some(test_cid(1))
13411341+ );
13421342+ assert_eq!(
13431343+ mst.get("com.example.test/b").await.unwrap(),
13441344+ Some(test_cid(2))
13451345+ );
13461346+ assert_eq!(
13471347+ mst.get("com.example.test/c").await.unwrap(),
13481348+ Some(test_cid(3))
13491349+ );
13501350+ assert_eq!(mst.get("com.example.test/d").await.unwrap(), None);
13511351+ }
13521352+13531353+ #[tokio::test]
13541354+ async fn test_allowed_keys() -> Result<()> {
13551355+ let cid1str = "bafyreie5cvv4h45feadgeuwhbcutmh6t2ceseocckahdoe6uat64zmz454";
13561356+ let cid1 = IpldCid::try_from(cid1str).unwrap();
13571357+13581358+ let storage = Arc::new(MemoryBlockStore::new());
13591359+ let mst = Mst::new(storage);
13601360+ // Rejects empty key
13611361+ let result = mst.add(&"".to_string(), cid1).await;
13621362+ assert!(result.is_err());
13631363+13641364+ // Rejects a key with no collection
13651365+ let result = mst.add(&"asdf".to_string(), cid1).await;
13661366+ assert!(result.is_err());
13671367+13681368+ // Rejects a key with a nested collection
13691369+ let result = mst.add(&"nested/collection/asdf".to_string(), cid1).await;
13701370+ assert!(result.is_err());
13711371+13721372+ // Rejects on empty coll or rkey
13731373+ let result = mst.add(&"coll/".to_string(), cid1).await;
13741374+ assert!(result.is_err());
13751375+ let result = mst.add(&"/rkey".to_string(), cid1).await;
13761376+ assert!(result.is_err());
13771377+13781378+ // Rejects non-ascii chars
13791379+ let result = mst.add(&"coll/jalapeñoA".to_string(), cid1).await;
13801380+ assert!(result.is_err());
13811381+ let result = mst.add(&"coll/coöperative".to_string(), cid1).await;
13821382+ assert!(result.is_err());
13831383+ let result = mst.add(&"coll/abc💩".to_string(), cid1).await;
13841384+ assert!(result.is_err());
13851385+13861386+ // Rejects ascii that we don't support
13871387+ let invalid_chars = vec!["$", "%", "(", ")", "+", "="];
13881388+ for ch in invalid_chars {
13891389+ let key = format!("coll/key{}", ch);
13901390+ let result = mst.add(&key, cid1).await;
13911391+ assert!(result.is_err(), "Key '{}' should be invalid", key);
13921392+ }
13931393+13941394+ // Rejects keys over 256 chars
13951395+ let long_key: String = "a".repeat(253);
13961396+ let key = format!("coll/{}", long_key);
13971397+ let result = mst.add(&key, cid1).await;
13981398+ assert!(result.is_err());
13991399+14001400+ // Allows long key under 256 chars
14011401+ let long_key: String = "a".repeat(250);
14021402+ let key = format!("coll/{}", long_key);
14031403+ let result = mst.add(&key, cid1).await;
14041404+ assert!(result.is_ok());
14051405+14061406+ // Allows URL-safe chars
14071407+ let valid_keys = vec![
14081408+ "coll/key0",
14091409+ "coll/key_",
14101410+ "coll/key:",
14111411+ "coll/key.",
14121412+ "coll/key-",
14131413+ ];
14141414+ for key in valid_keys {
14151415+ let result = mst.add(&key.to_string(), cid1).await;
14161416+ assert!(result.is_ok(), "Key '{}' should be valid", key);
14171417+ }
14181418+14191419+ Ok(())
13411420 }
1342142113431422 #[tokio::test]
···13451424 let storage = Arc::new(MemoryBlockStore::new());
13461425 let mst = Mst::new(storage);
1347142613481348- let updated = mst.add("test/key", test_cid(1)).await.unwrap();
14271427+ let updated = mst.add("com.example.test/key", test_cid(1)).await.unwrap();
1349142813501350- assert_eq!(updated.get("test/key").await.unwrap(), Some(test_cid(1)));
14291429+ assert_eq!(
14301430+ updated.get("com.example.test/key").await.unwrap(),
14311431+ Some(test_cid(1))
14321432+ );
13511433 }
1352143413531435 #[tokio::test]
···13551437 let storage = Arc::new(MemoryBlockStore::new());
13561438 let mst = Mst::new(storage);
1357143913581358- let mst = mst.add("a", test_cid(1)).await.unwrap();
13591359- let mst = mst.add("b", test_cid(2)).await.unwrap();
13601360- let mst = mst.add("c", test_cid(3)).await.unwrap();
14401440+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
14411441+ let mst = mst.add("com.example.test/b", test_cid(2)).await.unwrap();
14421442+ let mst = mst.add("com.example.test/c", test_cid(3)).await.unwrap();
1361144313621362- assert_eq!(mst.get("a").await.unwrap(), Some(test_cid(1)));
13631363- assert_eq!(mst.get("b").await.unwrap(), Some(test_cid(2)));
13641364- assert_eq!(mst.get("c").await.unwrap(), Some(test_cid(3)));
14441444+ assert_eq!(
14451445+ mst.get("com.example.test/a").await.unwrap(),
14461446+ Some(test_cid(1))
14471447+ );
14481448+ assert_eq!(
14491449+ mst.get("com.example.test/b").await.unwrap(),
14501450+ Some(test_cid(2))
14511451+ );
14521452+ assert_eq!(
14531453+ mst.get("com.example.test/c").await.unwrap(),
14541454+ Some(test_cid(3))
14551455+ );
13651456 }
1366145713671458 #[tokio::test]
···13691460 let storage = Arc::new(MemoryBlockStore::new());
13701461 let mst = Mst::new(storage);
1371146213721372- let mst = mst.add("test", test_cid(1)).await.unwrap();
13731373- let mst = mst.add("test", test_cid(2)).await.unwrap();
14631463+ let mst = mst.add("com.example.test/key1", test_cid(1)).await.unwrap();
14641464+ let mst = mst.add("com.example.test/key1", test_cid(2)).await.unwrap();
1374146513751375- assert_eq!(mst.get("test").await.unwrap(), Some(test_cid(2)));
14661466+ assert_eq!(
14671467+ mst.get("com.example.test/key1").await.unwrap(),
14681468+ Some(test_cid(2))
14691469+ );
13761470 }
1377147113781472 #[tokio::test]
···13801474 let storage = Arc::new(MemoryBlockStore::new());
13811475 let mst = Mst::new(storage);
1382147613831383- let mst = mst.add("test", test_cid(1)).await.unwrap();
13841384- let mst = mst.delete("test").await.unwrap();
14771477+ let mst = mst.add("com.example.test/key1", test_cid(1)).await.unwrap();
14781478+ let mst = mst.delete("com.example.test/key1").await.unwrap();
1385147913861386- assert_eq!(mst.get("test").await.unwrap(), None);
14801480+ assert_eq!(mst.get("com.example.test/key1").await.unwrap(), None);
13871481 assert_eq!(mst.get_entries().await.unwrap().len(), 0);
13881482 }
13891483···13921486 let storage = Arc::new(MemoryBlockStore::new());
13931487 let mst = Mst::new(storage);
1394148813951395- let mst = mst.add("a", test_cid(1)).await.unwrap();
13961396- let mst = mst.add("b", test_cid(2)).await.unwrap();
13971397- let mst = mst.add("c", test_cid(3)).await.unwrap();
14891489+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
14901490+ let mst = mst.add("com.example.test/b", test_cid(2)).await.unwrap();
14911491+ let mst = mst.add("com.example.test/c", test_cid(3)).await.unwrap();
1398149213991399- let mst = mst.delete("b").await.unwrap();
14931493+ let mst = mst.delete("com.example.test/b").await.unwrap();
1400149414011401- assert_eq!(mst.get("a").await.unwrap(), Some(test_cid(1)));
14021402- assert_eq!(mst.get("b").await.unwrap(), None);
14031403- assert_eq!(mst.get("c").await.unwrap(), Some(test_cid(3)));
14951495+ assert_eq!(
14961496+ mst.get("com.example.test/a").await.unwrap(),
14971497+ Some(test_cid(1))
14981498+ );
14991499+ assert_eq!(mst.get("com.example.test/b").await.unwrap(), None);
15001500+ assert_eq!(
15011501+ mst.get("com.example.test/c").await.unwrap(),
15021502+ Some(test_cid(3))
15031503+ );
14041504 }
1405150514061506 #[tokio::test]
···14081508 let storage = Arc::new(MemoryBlockStore::new());
14091509 let mst = Mst::new(storage);
1410151014111411- let mst = mst.add("a", test_cid(1)).await.unwrap();
15111511+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
1412151214131413- let result = mst.delete("b").await;
15131513+ let result = mst.delete("com.example.test/b").await;
14141514 assert!(result.is_err());
14151515 }
14161516···14191519 let storage = Arc::new(MemoryBlockStore::new());
14201520 let mst = Mst::new(storage.clone());
1421152114221422- let mst = mst.add("a", test_cid(1)).await.unwrap();
14231423- let mst = mst.add("b", test_cid(2)).await.unwrap();
14241424- let mst = mst.add("c", test_cid(3)).await.unwrap();
15221522+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
15231523+ let mst = mst.add("com.example.test/b", test_cid(2)).await.unwrap();
15241524+ let mst = mst.add("com.example.test/c", test_cid(3)).await.unwrap();
1425152514261526 // Persist to storage
14271527 let cid = mst.persist().await.unwrap();
···14301530 let reloaded = Mst::load(storage, cid, Some(0));
1431153114321532 // Verify all keys are present
14331433- assert_eq!(reloaded.get("a").await.unwrap(), Some(test_cid(1)));
14341434- assert_eq!(reloaded.get("b").await.unwrap(), Some(test_cid(2)));
14351435- assert_eq!(reloaded.get("c").await.unwrap(), Some(test_cid(3)));
15331533+ assert_eq!(
15341534+ reloaded.get("com.example.test/a").await.unwrap(),
15351535+ Some(test_cid(1))
15361536+ );
15371537+ assert_eq!(
15381538+ reloaded.get("com.example.test/b").await.unwrap(),
15391539+ Some(test_cid(2))
15401540+ );
15411541+ assert_eq!(
15421542+ reloaded.get("com.example.test/c").await.unwrap(),
15431543+ Some(test_cid(3))
15441544+ );
14361545 }
1437154614381547 #[tokio::test]
···14401549 // Same keys inserted in same order should produce same CID
14411550 let storage1 = Arc::new(MemoryBlockStore::new());
14421551 let mst1 = Mst::new(storage1);
14431443- let mst1 = mst1.add("a", test_cid(1)).await.unwrap();
14441444- let mst1 = mst1.add("b", test_cid(2)).await.unwrap();
14451445- let mst1 = mst1.add("c", test_cid(3)).await.unwrap();
15521552+ let mst1 = mst1.add("com.example.test/a", test_cid(1)).await.unwrap();
15531553+ let mst1 = mst1.add("com.example.test/b", test_cid(2)).await.unwrap();
15541554+ let mst1 = mst1.add("com.example.test/c", test_cid(3)).await.unwrap();
14461555 let cid1 = mst1.get_pointer().await.unwrap();
1447155614481557 let storage2 = Arc::new(MemoryBlockStore::new());
14491558 let mst2 = Mst::new(storage2);
14501450- let mst2 = mst2.add("a", test_cid(1)).await.unwrap();
14511451- let mst2 = mst2.add("b", test_cid(2)).await.unwrap();
14521452- let mst2 = mst2.add("c", test_cid(3)).await.unwrap();
15591559+ let mst2 = mst2.add("com.example.test/a", test_cid(1)).await.unwrap();
15601560+ let mst2 = mst2.add("com.example.test/b", test_cid(2)).await.unwrap();
15611561+ let mst2 = mst2.add("com.example.test/c", test_cid(3)).await.unwrap();
14531562 let cid2 = mst2.get_pointer().await.unwrap();
1454156314551564 assert_eq!(cid1, cid2);
···14601569 // Different insertion orders should produce same CID
14611570 let storage1 = Arc::new(MemoryBlockStore::new());
14621571 let mst1 = Mst::new(storage1);
14631463- let mst1 = mst1.add("a", test_cid(1)).await.unwrap();
14641464- let mst1 = mst1.add("b", test_cid(2)).await.unwrap();
14651465- let mst1 = mst1.add("c", test_cid(3)).await.unwrap();
15721572+ let mst1 = mst1.add("com.example.test/a", test_cid(1)).await.unwrap();
15731573+ let mst1 = mst1.add("com.example.test/b", test_cid(2)).await.unwrap();
15741574+ let mst1 = mst1.add("com.example.test/c", test_cid(3)).await.unwrap();
14661575 let cid1 = mst1.get_pointer().await.unwrap();
1467157614681577 let storage2 = Arc::new(MemoryBlockStore::new());
14691578 let mst2 = Mst::new(storage2);
14701470- let mst2 = mst2.add("c", test_cid(3)).await.unwrap();
14711471- let mst2 = mst2.add("a", test_cid(1)).await.unwrap();
14721472- let mst2 = mst2.add("b", test_cid(2)).await.unwrap();
15791579+ let mst2 = mst2.add("com.example.test/c", test_cid(3)).await.unwrap();
15801580+ let mst2 = mst2.add("com.example.test/a", test_cid(1)).await.unwrap();
15811581+ let mst2 = mst2.add("com.example.test/b", test_cid(2)).await.unwrap();
14731582 let cid2 = mst2.get_pointer().await.unwrap();
1474158314751584 assert_eq!(cid1, cid2);
···1482159114831592 let ops = vec![
14841593 VerifiedWriteOp::Create {
14851485- key: SmolStr::new("a"),
15941594+ key: SmolStr::new("com.example.test/a"),
14861595 cid: test_cid(1),
14871596 },
14881597 VerifiedWriteOp::Create {
14891489- key: SmolStr::new("b"),
15981598+ key: SmolStr::new("com.example.test/b"),
14901599 cid: test_cid(2),
14911600 },
14921601 VerifiedWriteOp::Create {
14931493- key: SmolStr::new("c"),
16021602+ key: SmolStr::new("com.example.test/c"),
14941603 cid: test_cid(3),
14951604 },
14961605 ];
1497160614981607 let mst = mst.batch(&ops).await.unwrap();
1499160815001500- assert_eq!(mst.get("a").await.unwrap(), Some(test_cid(1)));
15011501- assert_eq!(mst.get("b").await.unwrap(), Some(test_cid(2)));
15021502- assert_eq!(mst.get("c").await.unwrap(), Some(test_cid(3)));
16091609+ assert_eq!(
16101610+ mst.get("com.example.test/a").await.unwrap(),
16111611+ Some(test_cid(1))
16121612+ );
16131613+ assert_eq!(
16141614+ mst.get("com.example.test/b").await.unwrap(),
16151615+ Some(test_cid(2))
16161616+ );
16171617+ assert_eq!(
16181618+ mst.get("com.example.test/c").await.unwrap(),
16191619+ Some(test_cid(3))
16201620+ );
15031621 }
1504162215051623 #[tokio::test]
···15081626 let mst = Mst::new(storage);
1509162715101628 // Start with some keys
15111511- let mst = mst.add("a", test_cid(1)).await.unwrap();
15121512- let mst = mst.add("b", test_cid(2)).await.unwrap();
15131513- let mst = mst.add("c", test_cid(3)).await.unwrap();
16291629+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
16301630+ let mst = mst.add("com.example.test/b", test_cid(2)).await.unwrap();
16311631+ let mst = mst.add("com.example.test/c", test_cid(3)).await.unwrap();
1514163215151633 let ops = vec![
15161634 VerifiedWriteOp::Create {
15171517- key: SmolStr::new("d"),
16351635+ key: SmolStr::new("com.example.test/d"),
15181636 cid: test_cid(4),
15191637 },
15201638 VerifiedWriteOp::Update {
15211521- key: SmolStr::new("a"),
16391639+ key: SmolStr::new("com.example.test/a"),
15221640 cid: test_cid(10),
15231641 prev: test_cid(1),
15241642 },
15251643 VerifiedWriteOp::Delete {
15261526- key: SmolStr::new("b"),
16441644+ key: SmolStr::new("com.example.test/b"),
15271645 prev: test_cid(2),
15281646 },
15291647 ];
1530164815311649 let mst = mst.batch(&ops).await.unwrap();
1532165015331533- assert_eq!(mst.get("a").await.unwrap(), Some(test_cid(10))); // Updated
15341534- assert_eq!(mst.get("b").await.unwrap(), None); // Deleted
15351535- assert_eq!(mst.get("c").await.unwrap(), Some(test_cid(3))); // Unchanged
15361536- assert_eq!(mst.get("d").await.unwrap(), Some(test_cid(4))); // Created
16511651+ assert_eq!(
16521652+ mst.get("com.example.test/a").await.unwrap(),
16531653+ Some(test_cid(10))
16541654+ ); // Updated
16551655+ assert_eq!(mst.get("com.example.test/b").await.unwrap(), None); // Deleted
16561656+ assert_eq!(
16571657+ mst.get("com.example.test/c").await.unwrap(),
16581658+ Some(test_cid(3))
16591659+ ); // Unchanged
16601660+ assert_eq!(
16611661+ mst.get("com.example.test/d").await.unwrap(),
16621662+ Some(test_cid(4))
16631663+ ); // Created
15371664 }
1538166515391666 #[tokio::test]
15401667 async fn test_batch_with_prev_validation() {
15411668 let storage = Arc::new(MemoryBlockStore::new());
15421669 let mst = Mst::new(storage);
15431543- let mst = mst.add("a", test_cid(1)).await.unwrap();
16701670+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
1544167115451672 // Update with correct prev - should succeed
15461673 let ops = vec![VerifiedWriteOp::Update {
15471547- key: SmolStr::new("a"),
16741674+ key: SmolStr::new("com.example.test/a"),
15481675 cid: test_cid(2),
15491676 prev: test_cid(1),
15501677 }];
15511678 let mst = mst.batch(&ops).await.unwrap();
15521552- assert_eq!(mst.get("a").await.unwrap(), Some(test_cid(2)));
16791679+ assert_eq!(
16801680+ mst.get("com.example.test/a").await.unwrap(),
16811681+ Some(test_cid(2))
16821682+ );
1553168315541684 // Update with wrong prev - should fail
15551685 let ops = vec![VerifiedWriteOp::Update {
15561556- key: SmolStr::new("a"),
16861686+ key: SmolStr::new("com.example.test/a"),
15571687 cid: test_cid(3),
15581688 prev: test_cid(99), // Wrong CID
15591689 }];
···1561169115621692 // Delete with correct prev - should succeed
15631693 let ops = vec![VerifiedWriteOp::Delete {
15641564- key: SmolStr::new("a"),
16941694+ key: SmolStr::new("com.example.test/a"),
15651695 prev: test_cid(2),
15661696 }];
15671697 let mst = mst.batch(&ops).await.unwrap();
15681568- assert_eq!(mst.get("a").await.unwrap(), None);
16981698+ assert_eq!(mst.get("com.example.test/a").await.unwrap(), None);
15691699 }
1570170015711701 #[tokio::test]
15721702 async fn test_batch_create_duplicate_error() {
15731703 let storage = Arc::new(MemoryBlockStore::new());
15741704 let mst = Mst::new(storage);
15751575- let mst = mst.add("a", test_cid(1)).await.unwrap();
17051705+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
1576170615771707 let ops = vec![VerifiedWriteOp::Create {
15781578- key: SmolStr::new("a"),
17081708+ key: SmolStr::new("com.example.test/a"),
15791709 cid: test_cid(2),
15801710 }];
15811711···15891719 let mst = Mst::new(storage);
1590172015911721 let ops = vec![VerifiedWriteOp::Update {
15921592- key: SmolStr::new("a"),
17221722+ key: SmolStr::new("com.example.test/a"),
15931723 cid: test_cid(1),
15941724 prev: test_cid(99), // Doesn't matter since key doesn't exist
15951725 }];
···16041734 let mst = Mst::new(storage);
1605173516061736 let ops = vec![VerifiedWriteOp::Delete {
16071607- key: SmolStr::new("a"),
17371737+ key: SmolStr::new("com.example.test/a"),
16081738 prev: test_cid(99), // Doesn't matter since key doesn't exist
16091739 }];
16101740···16161746 async fn test_batch_empty() {
16171747 let storage = Arc::new(MemoryBlockStore::new());
16181748 let mst = Mst::new(storage);
16191619- let mst = mst.add("a", test_cid(1)).await.unwrap();
17491749+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
1620175016211751 let ops = vec![];
16221752 let mst = mst.batch(&ops).await.unwrap();
1623175316241754 // Should be unchanged
16251625- assert_eq!(mst.get("a").await.unwrap(), Some(test_cid(1)));
17551755+ assert_eq!(
17561756+ mst.get("com.example.test/a").await.unwrap(),
17571757+ Some(test_cid(1))
17581758+ );
16261759 }
1627176016281761 #[tokio::test]
···16311764 let storage = Arc::new(MemoryBlockStore::new());
16321765 let mst = Mst::new(storage);
1633176616341634- let mst = mst.add("a", test_cid(1)).await.unwrap();
16351635- let mst = mst.add("b", test_cid(2)).await.unwrap();
16361636- let mst = mst.add("c", test_cid(3)).await.unwrap();
17671767+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
17681768+ let mst = mst.add("com.example.test/b", test_cid(2)).await.unwrap();
17691769+ let mst = mst.add("com.example.test/c", test_cid(3)).await.unwrap();
1637177016381771 // Get proof path for key "b"
16391639- let cids = mst.cids_for_path("b").await.unwrap();
17721772+ let cids = mst.cids_for_path("com.example.test/b").await.unwrap();
1640177316411774 // Should contain: root CID, record CID
16421775 assert_eq!(cids.len(), 2);
···16501783 let storage = Arc::new(MemoryBlockStore::new());
16511784 let mst = Mst::new(storage);
1652178516531653- let mst = mst.add("a", test_cid(1)).await.unwrap();
16541654- let mst = mst.add("c", test_cid(3)).await.unwrap();
17861786+ let mst = mst.add("com.example.test/a", test_cid(1)).await.unwrap();
17871787+ let mst = mst.add("com.example.test/c", test_cid(3)).await.unwrap();
1655178816561789 // Get proof path for nonexistent key "b"
16571657- let cids = mst.cids_for_path("b").await.unwrap();
17901790+ let cids = mst.cids_for_path("com.example.test/b").await.unwrap();
1658179116591792 // Should contain root CID first, and NOT contain the record CID (proves absence)
16601793 assert!(cids.len() >= 1, "Should have at least the root CID");