forked from
gazagnaire.org/irmin
Persistent store with Git semantics: lazy reads, delayed writes, content-addressing
1(** Demonstrate MST proof generation and verification. *)
2
3open Irmin
4
5let () =
6 (* Create in-memory backend *)
7 let backend = Backend.Memory.create_sha256 () in
8
9 (* Build a tree with ATProto-style keys (flat namespace) *)
10 let tree = Tree.Mst.empty () in
11 let tree = Tree.Mst.add tree [ "post/3k2yihx" ] "Hello World" in
12 let tree =
13 Tree.Mst.add tree [ "profile/self" ] "{\"displayName\":\"Alice\"}"
14 in
15 let tree =
16 Tree.Mst.add tree [ "like/3k2yihy" ] "{\"subject\":\"at://...\"}"
17 in
18 let root = Tree.Mst.hash tree ~backend in
19
20 Printf.printf "MST Root: %s\n" (String.sub (Hash.to_hex root) 0 16);
21 Printf.printf "\n";
22
23 (* Produce a proof for reading a post *)
24 let path = [ "post/3k2yihx" ] in
25 let proof, result =
26 Proof.Mst.produce backend root (fun t ->
27 let v = Proof.Mst.Tree.find t path in
28 (t, v))
29 in
30
31 Printf.printf "Proof for: %s\n" (List.hd path);
32 Printf.printf "Value: %s\n" (Option.value ~default:"<not found>" result);
33 Printf.printf "\n";
34
35 (* Show proof hashes *)
36 let hash_str h = String.sub (Hash.to_hex h) 0 16 in
37 let before_hash =
38 match Proof.before proof with
39 | `Node h -> hash_str h
40 | `Contents h -> hash_str h
41 in
42 let after_hash =
43 match Proof.after proof with
44 | `Node h -> hash_str h
45 | `Contents h -> hash_str h
46 in
47 Printf.printf "Before: %s (read-only, no change)\n" before_hash;
48 Printf.printf "After: %s\n" after_hash;
49 Printf.printf "\n";
50
51 (* Verify without backend - proof contains all needed data *)
52 Printf.printf "Verifying proof (no backend access)...\n";
53 match
54 Proof.Mst.verify proof (fun t ->
55 let v = Proof.Mst.Tree.find t path in
56 (t, v))
57 with
58 | Ok (_, v) ->
59 Printf.printf "✓ Verified: %s\n" (Option.value ~default:"<none>" v)
60 | Error (`Proof_mismatch msg) -> Printf.printf "✗ Invalid: %s\n" msg