2016-09-08 21:13:10 +04:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Copyright (c) 2014 - 2016. *)
|
|
|
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
open Store_sigs
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
type t = Raw_store.t
|
|
|
|
type global_store = t
|
|
|
|
|
|
|
|
(**************************************************************************
|
|
|
|
* Net store under "net/"
|
|
|
|
**************************************************************************)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Net = struct
|
|
|
|
|
|
|
|
type store = global_store * Net_id.t
|
|
|
|
let get s id = (s, id)
|
|
|
|
|
|
|
|
module Indexed_store =
|
|
|
|
Store_helpers.Make_indexed_substore
|
|
|
|
(Store_helpers.Make_substore(Raw_store)(struct let name = ["net"] end))
|
|
|
|
(Net_id)
|
|
|
|
|
|
|
|
let destroy = Indexed_store.remove_all
|
|
|
|
let list t =
|
|
|
|
Indexed_store.fold_indexes t ~init:[]
|
|
|
|
~f:(fun h acc -> Lwt.return (h :: acc))
|
|
|
|
|
2017-03-31 15:04:05 +04:00
|
|
|
module Genesis_hash =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["genesis" ; "hash"] end)
|
|
|
|
(Store_helpers.Make_value(Block_hash))
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Genesis_time =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["genesis" ; "time"] end)
|
|
|
|
(Store_helpers.Make_value(Time))
|
|
|
|
|
|
|
|
module Genesis_protocol =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["genesis" ; "protocol"] end)
|
|
|
|
(Store_helpers.Make_value(Protocol_hash))
|
|
|
|
|
|
|
|
module Genesis_test_protocol =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["genesis" ; "test_protocol"] end)
|
|
|
|
(Store_helpers.Make_value(Protocol_hash))
|
|
|
|
|
|
|
|
module Expiration =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["expiration"] end)
|
|
|
|
(Store_helpers.Make_value(Time))
|
|
|
|
|
2017-04-10 23:14:17 +04:00
|
|
|
module Allow_forked_network =
|
|
|
|
Indexed_store.Make_set (struct let name = ["allow_forked_network"] end)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
|
|
|
|
(**************************************************************************
|
|
|
|
* Generic store for "tracked" data: discovery_time, invalidity,
|
|
|
|
* incoming peers,... (for operations, block_headers, and protocols).
|
|
|
|
**************************************************************************)
|
|
|
|
|
|
|
|
module type DATA_STORE = sig
|
|
|
|
|
|
|
|
type store
|
2016-09-08 21:13:10 +04:00
|
|
|
type key
|
2017-02-24 20:17:53 +04:00
|
|
|
type key_set
|
2016-09-08 21:13:10 +04:00
|
|
|
type value
|
2016-10-21 16:01:20 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
val encoding: value Data_encoding.t
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
val compare: value -> value -> int
|
|
|
|
val equal: value -> value -> bool
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
val hash: value -> key
|
|
|
|
val hash_raw: MBytes.t -> key
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Discovery_time : MAP_STORE
|
|
|
|
with type t := store
|
|
|
|
and type key := key
|
|
|
|
and type value := Time.t
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Contents : SINGLE_STORE
|
|
|
|
with type t = store * key
|
|
|
|
and type value := value
|
2016-10-21 16:01:20 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module RawContents : SINGLE_STORE
|
|
|
|
with type t = store * key
|
|
|
|
and type value := MBytes.t
|
|
|
|
|
|
|
|
module Validation_time : SINGLE_STORE
|
|
|
|
with type t = store * key
|
|
|
|
and type value := Time.t
|
|
|
|
|
|
|
|
module Errors : MAP_STORE
|
|
|
|
with type t := store
|
|
|
|
and type key := key
|
|
|
|
and type value = error list
|
|
|
|
|
|
|
|
module Pending : BUFFERED_SET_STORE
|
|
|
|
with type t = store
|
|
|
|
and type elt := key
|
|
|
|
and type Set.t = key_set
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Errors_value =
|
|
|
|
Store_helpers.Make_value(struct
|
|
|
|
type t = error list
|
|
|
|
let encoding = (Data_encoding.list (Error_monad.error_encoding ()))
|
|
|
|
end)
|
|
|
|
|
2016-09-08 21:13:10 +04:00
|
|
|
module Raw_value = struct
|
|
|
|
type t = MBytes.t
|
2017-02-24 20:17:53 +04:00
|
|
|
let of_bytes b = ok b
|
2016-09-08 21:13:10 +04:00
|
|
|
let to_bytes b = b
|
|
|
|
end
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Make_data_store
|
|
|
|
(S : STORE) (I : INDEX) (V : VALUE)
|
|
|
|
(Set : Set.S with type elt = I.t) = struct
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
type key = I.t
|
|
|
|
type value = V.t
|
|
|
|
type key_set = Set.t
|
|
|
|
|
|
|
|
let of_bytes = V.of_bytes
|
|
|
|
let to_bytes = V.to_bytes
|
|
|
|
|
|
|
|
module Indexed_store =
|
|
|
|
Store_helpers.Make_indexed_substore
|
|
|
|
(Store_helpers.Make_substore (S) (struct let name = ["data"] end))
|
|
|
|
(I)
|
2017-03-30 19:19:59 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Discovery_time =
|
|
|
|
Indexed_store.Make_map
|
|
|
|
(struct let name = ["discovery_time"] end)
|
|
|
|
(Store_helpers.Make_value(Time))
|
|
|
|
module Contents =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["contents"] end)
|
|
|
|
(V)
|
|
|
|
module RawContents =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["contents"] end)
|
|
|
|
(Raw_value)
|
|
|
|
module Errors =
|
|
|
|
Store_helpers.Make_map
|
|
|
|
(Store_helpers.Make_substore (S) (struct let name = ["invalids"] end))
|
|
|
|
(I)
|
|
|
|
(Errors_value)
|
|
|
|
module Pending =
|
|
|
|
Store_helpers.Make_buffered_set
|
|
|
|
(Store_helpers.Make_substore (S) (struct let name = ["pending"] end))
|
|
|
|
(I)
|
|
|
|
(Set)
|
|
|
|
module Validation_time =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["validation_time"] end)
|
|
|
|
(Store_helpers.Make_value(Time))
|
2017-03-30 19:19:59 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
(**************************************************************************
|
|
|
|
* Operation store under "net/<id>/operations/"
|
|
|
|
**************************************************************************)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Operation = struct
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
type shell_header = {
|
|
|
|
net_id: Net_id.t ;
|
|
|
|
}
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
let shell_header_encoding =
|
|
|
|
let open Data_encoding in
|
|
|
|
conv
|
|
|
|
(fun { net_id } -> net_id)
|
|
|
|
(fun net_id -> { net_id })
|
|
|
|
(obj1 (req "net_id" Net_id.encoding))
|
|
|
|
|
|
|
|
module Encoding = struct
|
|
|
|
type t = {
|
|
|
|
shell: shell_header ;
|
|
|
|
proto: MBytes.t ;
|
|
|
|
}
|
|
|
|
let encoding =
|
|
|
|
let open Data_encoding in
|
|
|
|
conv
|
|
|
|
(fun { shell ; proto } -> (shell, proto))
|
|
|
|
(fun (shell, proto) -> { shell ; proto })
|
|
|
|
(merge_objs
|
|
|
|
shell_header_encoding
|
|
|
|
(obj1 (req "data" Variable.bytes)))
|
|
|
|
end
|
|
|
|
module Value = Store_helpers.Make_value(Encoding)
|
|
|
|
include Encoding
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
let compare o1 o2 =
|
|
|
|
let (>>) x y = if x = 0 then y () else x in
|
|
|
|
Net_id.compare o1.shell.net_id o1.shell.net_id >> fun () ->
|
|
|
|
MBytes.compare o1.proto o2.proto
|
|
|
|
let equal b1 b2 = compare b1 b2 = 0
|
|
|
|
let hash op = Operation_hash.hash_bytes [Value.to_bytes op]
|
|
|
|
let hash_raw bytes = Operation_hash.hash_bytes [bytes]
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
type store = Net.store
|
|
|
|
let get x = x
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
include
|
|
|
|
Make_data_store
|
|
|
|
(Store_helpers.Make_substore
|
|
|
|
(Net.Indexed_store.Store)
|
|
|
|
(struct let name = ["operations"] end))
|
|
|
|
(Operation_hash)
|
|
|
|
(Value)
|
|
|
|
(Operation_hash.Set)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-03-30 19:19:59 +04:00
|
|
|
let register s =
|
|
|
|
Base58.register_resolver Operation_hash.b58check_encoding begin fun str ->
|
|
|
|
let pstr = Operation_hash.prefix_path str in
|
|
|
|
Net.Indexed_store.fold_indexes s ~init:[]
|
|
|
|
~f:begin fun net acc ->
|
|
|
|
Indexed_store.resolve_index (s, net) pstr >>= fun l ->
|
|
|
|
Lwt.return (List.rev_append l acc)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-09-08 21:13:10 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
(**************************************************************************
|
|
|
|
* Block_header store under "net/<id>/blocks/"
|
|
|
|
**************************************************************************)
|
|
|
|
|
|
|
|
module Block_header = struct
|
|
|
|
|
|
|
|
type shell_header = {
|
|
|
|
net_id: Net_id.t ;
|
2017-04-10 15:01:22 +04:00
|
|
|
level: Int32.t ;
|
2017-04-12 20:22:40 +04:00
|
|
|
proto_level: int ; (* uint8 *)
|
2017-02-24 20:17:53 +04:00
|
|
|
predecessor: Block_hash.t ;
|
|
|
|
timestamp: Time.t ;
|
2017-04-10 19:06:11 +04:00
|
|
|
operations_hash: Operation_list_list_hash.t ;
|
2017-02-24 20:17:53 +04:00
|
|
|
fitness: MBytes.t list ;
|
|
|
|
}
|
|
|
|
|
|
|
|
let shell_header_encoding =
|
|
|
|
let open Data_encoding in
|
|
|
|
conv
|
2017-04-12 20:22:40 +04:00
|
|
|
(fun { net_id ; level ; proto_level ; predecessor ;
|
2017-04-10 19:06:11 +04:00
|
|
|
timestamp ; operations_hash ; fitness } ->
|
2017-04-12 20:22:40 +04:00
|
|
|
(net_id, level, proto_level, predecessor,
|
2017-04-10 19:06:11 +04:00
|
|
|
timestamp, operations_hash, fitness))
|
2017-04-12 20:22:40 +04:00
|
|
|
(fun (net_id, level, proto_level, predecessor,
|
2017-04-10 19:06:11 +04:00
|
|
|
timestamp, operations_hash, fitness) ->
|
2017-04-12 20:22:40 +04:00
|
|
|
{ net_id ; level ; proto_level ; predecessor ;
|
2017-04-10 19:06:11 +04:00
|
|
|
timestamp ; operations_hash ; fitness })
|
2017-04-12 20:22:40 +04:00
|
|
|
(obj7
|
2017-02-24 20:17:53 +04:00
|
|
|
(req "net_id" Net_id.encoding)
|
2017-04-10 15:01:22 +04:00
|
|
|
(req "level" int32)
|
2017-04-12 20:22:40 +04:00
|
|
|
(req "proto" uint8)
|
2017-02-24 20:17:53 +04:00
|
|
|
(req "predecessor" Block_hash.encoding)
|
|
|
|
(req "timestamp" Time.encoding)
|
2017-04-10 19:06:11 +04:00
|
|
|
(req "operations_hash" Operation_list_list_hash.encoding)
|
2017-03-30 15:16:21 +04:00
|
|
|
(req "fitness" Fitness.encoding))
|
2017-02-24 20:17:53 +04:00
|
|
|
|
|
|
|
module Encoding = struct
|
|
|
|
type t = {
|
|
|
|
shell: shell_header ;
|
|
|
|
proto: MBytes.t ;
|
|
|
|
}
|
|
|
|
let encoding =
|
|
|
|
let open Data_encoding in
|
|
|
|
conv
|
|
|
|
(fun { shell ; proto } -> (shell, proto))
|
|
|
|
(fun (shell, proto) -> { shell ; proto })
|
|
|
|
(merge_objs
|
|
|
|
shell_header_encoding
|
|
|
|
(obj1 (req "data" Variable.bytes)))
|
|
|
|
end
|
|
|
|
module Value = Store_helpers.Make_value(Encoding)
|
|
|
|
include Encoding
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let compare b1 b2 =
|
|
|
|
let (>>) x y = if x = 0 then y () else x in
|
|
|
|
let rec list compare xs ys =
|
|
|
|
match xs, ys with
|
|
|
|
| [], [] -> 0
|
|
|
|
| _ :: _, [] -> -1
|
|
|
|
| [], _ :: _ -> 1
|
|
|
|
| x :: xs, y :: ys ->
|
|
|
|
compare x y >> fun () -> list compare xs ys in
|
|
|
|
Block_hash.compare b1.shell.predecessor b2.shell.predecessor >> fun () ->
|
|
|
|
compare b1.proto b2.proto >> fun () ->
|
2017-03-30 15:16:21 +04:00
|
|
|
Operation_list_list_hash.compare
|
2017-04-10 19:06:11 +04:00
|
|
|
b1.shell.operations_hash b2.shell.operations_hash >> fun () ->
|
2016-09-08 21:13:10 +04:00
|
|
|
Time.compare b1.shell.timestamp b2.shell.timestamp >> fun () ->
|
|
|
|
list compare b1.shell.fitness b2.shell.fitness
|
|
|
|
|
|
|
|
let equal b1 b2 = compare b1 b2 = 0
|
2017-02-24 20:17:53 +04:00
|
|
|
let hash block = Block_hash.hash_bytes [Value.to_bytes block]
|
|
|
|
let hash_raw bytes = Block_hash.hash_bytes [bytes]
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
type store = Net.store
|
|
|
|
let get x = x
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
include Make_data_store
|
|
|
|
(Store_helpers.Make_substore
|
|
|
|
(Net.Indexed_store.Store)
|
|
|
|
(struct let name = ["blocks"] end))
|
|
|
|
(Block_hash)
|
|
|
|
(Value)
|
|
|
|
(Block_hash.Set)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-03-30 15:16:21 +04:00
|
|
|
module Operation_list_count =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["operation_list_count"] end)
|
|
|
|
(Store_helpers.Make_value(struct
|
|
|
|
type t = int
|
|
|
|
let encoding = Data_encoding.int8
|
|
|
|
end))
|
|
|
|
|
|
|
|
module Operations_index =
|
|
|
|
Store_helpers.Make_indexed_substore
|
|
|
|
(Store_helpers.Make_substore
|
|
|
|
(Indexed_store.Store)
|
|
|
|
(struct let name = ["operations"] end))
|
|
|
|
(Store_helpers.Integer_index)
|
|
|
|
|
|
|
|
module Operation_list =
|
|
|
|
Operations_index.Make_map
|
|
|
|
(struct let name = ["list"] end)
|
|
|
|
(Store_helpers.Make_value(struct
|
|
|
|
type t = Operation_hash.t list
|
|
|
|
let encoding = Data_encoding.list Operation_hash.encoding
|
|
|
|
end))
|
|
|
|
|
|
|
|
module Operation_list_path =
|
|
|
|
Operations_index.Make_map
|
|
|
|
(struct let name = ["path"] end)
|
|
|
|
(Store_helpers.Make_value(struct
|
|
|
|
type t = Operation_list_list_hash.path
|
|
|
|
let encoding = Operation_list_list_hash.path_encoding
|
|
|
|
end))
|
|
|
|
|
2017-03-30 19:19:59 +04:00
|
|
|
let register s =
|
|
|
|
Base58.register_resolver Block_hash.b58check_encoding begin fun str ->
|
|
|
|
let pstr = Block_hash.prefix_path str in
|
|
|
|
Net.Indexed_store.fold_indexes s ~init:[]
|
|
|
|
~f:begin fun net acc ->
|
|
|
|
Indexed_store.resolve_index (s, net) pstr >>= fun l ->
|
|
|
|
Lwt.return (List.rev_append l acc)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-09-08 21:13:10 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
(**************************************************************************
|
|
|
|
* Blockchain data
|
|
|
|
**************************************************************************)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Chain = struct
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
type store = Net.store
|
|
|
|
let get s = s
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Known_heads =
|
|
|
|
Store_helpers.Make_buffered_set
|
|
|
|
(Store_helpers.Make_substore
|
|
|
|
(Net.Indexed_store.Store)
|
|
|
|
(struct let name = ["known_heads"] end))
|
|
|
|
(Block_hash)
|
|
|
|
(Block_hash.Set)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Current_head =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Net.Indexed_store.Store)
|
|
|
|
(struct let name = ["current_head"] end)
|
|
|
|
(Store_helpers.Make_value(Block_hash))
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module Successor_in_chain =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Block_header.Indexed_store.Store)
|
|
|
|
(struct let name = ["successor_in_chain"] end)
|
|
|
|
(Store_helpers.Make_value(Block_hash))
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
module In_chain_insertion_time =
|
|
|
|
Store_helpers.Make_single_store
|
|
|
|
(Block_header.Indexed_store.Store)
|
|
|
|
(struct let name = ["in_chain_insertion_time"] end)
|
|
|
|
(Store_helpers.Make_value(Time))
|
2016-10-21 16:01:20 +04:00
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
(**************************************************************************
|
|
|
|
* Protocol store under "protocols/"
|
|
|
|
**************************************************************************)
|
2016-10-21 16:01:20 +04:00
|
|
|
|
|
|
|
module Protocol = struct
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
include Tezos_compiler.Protocol
|
|
|
|
let hash_raw bytes = Protocol_hash.hash_bytes [bytes]
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
type store = global_store
|
|
|
|
let get x = x
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
include Make_data_store
|
|
|
|
(Store_helpers.Make_substore
|
|
|
|
(Raw_store)
|
|
|
|
(struct let name = ["protocols"] end))
|
|
|
|
(Protocol_hash)
|
|
|
|
(Store_helpers.Make_value(Tezos_compiler.Protocol))
|
|
|
|
(Protocol_hash.Set)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-03-30 19:19:59 +04:00
|
|
|
let register s =
|
|
|
|
Base58.register_resolver Protocol_hash.b58check_encoding begin fun str ->
|
|
|
|
let pstr = Protocol_hash.prefix_path str in
|
|
|
|
Indexed_store.resolve_index s pstr
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2016-09-08 21:13:10 +04:00
|
|
|
end
|
2017-02-24 20:17:53 +04:00
|
|
|
|
2017-03-30 19:19:59 +04:00
|
|
|
let init dir =
|
|
|
|
Raw_store.init dir >>=? fun s ->
|
|
|
|
Block_header.register s ;
|
|
|
|
Operation.register s ;
|
|
|
|
Protocol.register s ;
|
|
|
|
return s
|
|
|
|
|
2017-05-31 20:27:11 +04:00
|
|
|
let close = Raw_store.close
|