···5858let ( => ) = S.( => )
5959let repo_schema = S.fix (fun _self -> mst_node [ "*" => S.opaque ])
60606161-module type Config = sig
6262- val heap : (Atp.Cid.t, string) Irmin.Heap.t
6363- val now : unit -> float
6464-end
6565-6666-module Make (C : Config) = struct
6767- module Backend = struct
6161+let v ~heap ~now:clock =
6262+ let module Backend = struct
6863 type t = {
6964 mutable head : Atp.Cid.t option;
7065 values : (string, string) Hashtbl.t;
···9893 }
9994 in
10095 let ( let* ) = Result.bind in
101101- let* json = Json.encode Statement_lexicon.main_jsont record in
9696+ let* json =
9797+ Json.encode Statement_lexicon.main_json record
9898+ |> Result.map_error Json.Error.to_string
9999+ in
102100 let* dagcbor_value = Atp.Dagcbor.of_json json in
103101 Ok (Atp.Dagcbor.encode_string dagcbor_value)
104102···135133 (* Add record to MST via Atp.Mst *)
136134 let bs = Atp.Blockstore.memory () in
137135 let mst =
138138- match S.head C.heap ~branch:"main" with
136136+ match S.head heap ~branch:"main" with
139137 | Some tree_root ->
140138 (* Copy blocks from heap to local blockstore *)
141139 let rec copy_block cid =
142142- match Irmin.Heap.find C.heap cid with
140140+ match Irmin.Heap.find heap cid with
143141 | Some data -> (
144142 bs#put cid data;
145143 (* Try to decode as MST node and copy subtrees *)
···160158 in
161159 (* Write the record blob *)
162160 let record_cid = Atp.Cid.v `Dag_cbor dagcbor in
163163- Irmin.Heap.put C.heap record_cid dagcbor;
161161+ Irmin.Heap.put heap record_cid dagcbor;
164162 bs#put record_cid dagcbor;
165163 (* Add to MST *)
166164 let mst = Atp.Mst.add rk record_cid mst ~store:bs in
167165 let tree_root = Atp.Mst.to_cid mst ~store:bs in
168166 (* Copy MST blocks back to heap *)
169167 Atp.Mst.to_blocks mst ~store:(bs :> Atp.Blockstore.readable)
170170- |> Seq.iter (fun (cid, data) -> Irmin.Heap.put C.heap cid data);
168168+ |> Seq.iter (fun (cid, data) -> Irmin.Heap.put heap cid data);
171169 (* Update branch ref *)
172172- S.set_head C.heap ~branch:"main" tree_root;
170170+ S.set_head heap ~branch:"main" tree_root;
173171 t.head <- Some tree_root;
174172 Hashtbl.add t.values key value;
175173 let leaf_hash = sha256 ("\x00" ^ value) in
176174 (* Produce inclusion proof *)
177175 let proof, _value =
178178- S.produce C.heap repo_schema tree_root (fun c ->
176176+ S.produce heap repo_schema tree_root (fun c ->
179177 match S.step_any c rk with
180178 | Some (S.Step (sc, leaf)) ->
181179 (S.Step (sc, leaf), S.get_block leaf)
···225223 ("collection", `String collection);
226224 ("size", `Int (Int64.of_int (Hashtbl.length t.values)));
227225 ])
228228- end
229229-230230- module Impl = struct
226226+ end in
227227+ let module Impl = struct
231228 type nonrec t = {
232229 backend : Backend.t;
233230 now : unit -> (string, string) result;
···244241 Error "consistency proofs not supported for MST backend"
245242246243 let export t = Backend.export t.backend
247247- end
248248-249249- let v () : Scitt.vds =
250250- let now () =
251251- match Ptime.of_float_s (C.now ()) with
252252- | Some p -> Ok (Ptime.to_rfc3339 p)
253253- | None -> Error "clock returned invalid time"
254254- in
255255- let state =
256256- Impl.
257257- { backend = Backend.{ head = None; values = Hashtbl.create 64 }; now }
258258- in
259259- Scitt.Vds.v (module Impl) state
260260-end
244244+ end in
245245+ let now () =
246246+ match Ptime.of_float_s (clock ()) with
247247+ | Some p -> Ok (Ptime.to_rfc3339 p)
248248+ | None -> Error "clock returned invalid time"
249249+ in
250250+ let state =
251251+ Impl.{ backend = Backend.{ head = None; values = Hashtbl.create 64 }; now }
252252+ in
253253+ Scitt.Vds.v (module Impl) state
+6-19
lib/atp/scitt_atp.mli
···55 updates the branch ref.
6677 {[
88- let module Heap_b = Irmin.Heap.Make (...) in
98 let heap = Heap_b.v (Atp.Blockstore.memory ()) in
1010- let module V = Scitt_atp.Make (struct
1111- let heap = heap
1212- let now () = Unix.gettimeofday ()
1313- end) in
1414- let vds = V.v ()
99+ let vds = Scitt_atp.v ~heap ~now:Unix.gettimeofday
1510 ]} *)
16111717-(** Configuration for the MST backend. *)
1818-module type Config = sig
1919- val heap : (Atp.Cid.t, string) Irmin.Heap.t
2020- (** The heap. *)
2121-2222- val now : unit -> float
2323- (** Clock for record timestamps. *)
2424-end
2525-2626-module Make (C : Config) : sig
2727- val v : unit -> Scitt.vds
2828- (** [v ()] creates a new ATProto-backed verifiable data structure. *)
2929-end
1212+val v :
1313+ heap:(Atp.Cid.t, string) Irmin.Heap.t -> now:(unit -> float) -> Scitt.vds
1414+(** [v ~heap ~now] creates a new ATProto-backed verifiable data structure.
1515+ [heap] stores the MST blocks and record blobs keyed by CID; [now] yields
1616+ the time used for the per-record [createdAt] timestamp. *)
+1-6
test/atp/test_scitt_atp.ml
···6767let vds_mst () =
6868 let clock = mock_clock () in
6969 let heap = Atp_heap.v (Atp.Blockstore.memory ()) in
7070- let module C = struct
7171- let heap = heap
7272- let now () = Eio.Time.now clock
7373- end in
7474- let module V = Scitt_atp.Make (C) in
7575- V.v ()
7070+ Scitt_atp.v ~heap ~now:(fun () -> Eio.Time.now clock)
76717772(* -- Helpers -- *)
7873
-1
test/test_scitt.ml
···1111(* -- Helpers -- *)
12121313let sha256 s = Digestif.SHA256.(digest_string s |> to_raw_string)
1414-let sha256_hex s = Digestif.SHA256.(digest_string s |> to_hex)
15141615let append_ok vds ~key ~value =
1716 match Scitt.vds_append vds ~key ~value with