Persistent store with Git semantics: lazy reads, delayed writes, content-addressing
at perf 93 lines 2.7 kB view raw
1(** MST Proof commands. *) 2 3open Irmin 4 5let produce ~output ~key data = 6 let backend = Backend.Memory.create_sha256 () in 7 (* Parse input: lines of "key=value" *) 8 let tree = 9 List.fold_left 10 (fun tree line -> 11 match String.index_opt line '=' with 12 | None -> tree 13 | Some i -> 14 let k = String.sub line 0 i in 15 let v = String.sub line (i + 1) (String.length line - i - 1) in 16 Tree.Mst.add tree [ k ] v) 17 (Tree.Mst.empty ()) data 18 in 19 let root = Tree.Mst.hash tree ~backend in 20 21 let path = [ key ] in 22 let proof, result = 23 Proof.Mst.produce backend root (fun t -> 24 let v = Proof.Mst.Tree.find t path in 25 (t, v)) 26 in 27 28 let hash_str h = String.sub (Hash.to_hex h) 0 16 in 29 let before_hash = 30 match Proof.before proof with 31 | `Node h -> hash_str h 32 | `Contents h -> hash_str h 33 in 34 let after_hash = 35 match Proof.after proof with 36 | `Node h -> hash_str h 37 | `Contents h -> hash_str h 38 in 39 40 (match output with 41 | `Human -> 42 Fmt.pr "Root: %s@." (hash_str root); 43 Fmt.pr "Key: %s@." key; 44 Fmt.pr "Value: %s@." (Option.value ~default:"<not found>" result); 45 Fmt.pr "Before: %s@." before_hash; 46 Fmt.pr "After: %s@." after_hash 47 | `Json -> 48 Fmt.pr {|{"root":%S,"key":%S,"value":%s,"before":%S,"after":%S}@.|} 49 (Hash.to_hex root) key 50 (match result with Some v -> Fmt.str "%S" v | None -> "null") 51 before_hash after_hash); 52 0 53 54let verify ~output ~key data = 55 let backend = Backend.Memory.create_sha256 () in 56 let tree = 57 List.fold_left 58 (fun tree line -> 59 match String.index_opt line '=' with 60 | None -> tree 61 | Some i -> 62 let k = String.sub line 0 i in 63 let v = String.sub line (i + 1) (String.length line - i - 1) in 64 Tree.Mst.add tree [ k ] v) 65 (Tree.Mst.empty ()) data 66 in 67 let root = Tree.Mst.hash tree ~backend in 68 69 let path = [ key ] in 70 let proof, _ = 71 Proof.Mst.produce backend root (fun t -> 72 let v = Proof.Mst.Tree.find t path in 73 (t, v)) 74 in 75 76 match 77 Proof.Mst.verify proof (fun t -> 78 let v = Proof.Mst.Tree.find t path in 79 (t, v)) 80 with 81 | Ok (_, v) -> 82 (match output with 83 | `Human -> 84 Common.success "Verified: %s" (Option.value ~default:"<none>" v) 85 | `Json -> 86 Fmt.pr {|{"verified":true,"value":%s}@.|} 87 (match v with Some x -> Fmt.str "%S" x | None -> "null")); 88 0 89 | Error (`Proof_mismatch msg) -> 90 (match output with 91 | `Human -> Common.error "Invalid: %s" msg 92 | `Json -> Fmt.pr {|{"verified":false,"error":%S}@.|} msg); 93 1