diff --git a/src/lib_dac/RPC_services.ml b/src/lib_dac/RPC_services.ml index 10fc16ae42757f63f034ea476c3ddb40bf52da6e..a8d5821dfcedf5ede1e068fe33f754c1a10093aa 100644 --- a/src/lib_dac/RPC_services.ml +++ b/src/lib_dac/RPC_services.ml @@ -33,9 +33,11 @@ let store_preimage_request_encoding = (req "payload" Data_encoding.(bytes' Hex)) (req "pagination_scheme" pagination_scheme_encoding)) -let store_preimage_response_encoding ((module P) : Dac_plugin.t) = +let store_preimage_response_encoding = Data_encoding.( - obj2 (req "root_hash" P.encoding) (req "external_message" (bytes' Hex))) + obj2 + (req "root_hash" Dac_plugin.raw_hash_encoding) + (req "external_message" (bytes' Hex))) let external_message_query = let open Tezos_rpc.Query in @@ -43,49 +45,48 @@ let external_message_query = |+ opt_field "external_message" Tezos_rpc.Arg.string (fun s -> s) |> seal -let post_store_preimage ctx = +let post_store_preimage = Tezos_rpc.Service.post_service ~description:"Split DAC reveal data" ~query:Tezos_rpc.Query.empty ~input:store_preimage_request_encoding - ~output:(store_preimage_response_encoding ctx) + ~output:store_preimage_response_encoding Tezos_rpc.Path.(open_root / "store_preimage") (* DAC/FIXME: https://gitlab.com/tezos/tezos/-/issues/4263 remove this endpoint once end-to-end tests are in place. *) -let get_verify_signature : - ([`GET], unit, unit, string option, unit, bool) Tezos_rpc.Service.service = +let get_verify_signature = Tezos_rpc.Service.get_service ~description:"Verify signature of an external message to inject in L1" ~query:external_message_query ~output:Data_encoding.bool Tezos_rpc.Path.(open_root / "verify_signature") -let get_preimage ((module P) : Dac_plugin.t) = +let get_preimage = Tezos_rpc.Service.get_service ~description:"Retrieves a page by its page hash and returns its contents" ~query:Tezos_rpc.Query.empty ~output:Data_encoding.bytes - Tezos_rpc.Path.(open_root / "preimage" /: P.hash_rpc_arg) + Tezos_rpc.Path.(open_root / "preimage" /: Dac_plugin.raw_hash_rpc_arg) -let put_dac_member_signature dac_plugin = +let put_dac_member_signature = Tezos_rpc.Service.put_service ~description: "Verifies and stores the Dac member signature of a root page hash" ~query:Tezos_rpc.Query.empty - ~input:(Signature_repr.encoding dac_plugin) + ~input:Signature_repr.encoding ~output:Data_encoding.empty Tezos_rpc.Path.(open_root / "dac_member_signature") -let get_certificate ((module P) : Dac_plugin.t) = +let get_certificate = Tezos_rpc.Service.get_service ~description: "Retrieve the Dac certificate associated with the given root page hash" ~query:Tezos_rpc.Query.empty - ~output:(Data_encoding.option (Certificate_repr.encoding (module P))) - Tezos_rpc.Path.(open_root / "certificates" /: P.hash_rpc_arg) + ~output:(Data_encoding.option Certificate_repr.encoding) + Tezos_rpc.Path.(open_root / "certificates" /: Dac_plugin.raw_hash_rpc_arg) -let get_missing_page ((module P) : Dac_plugin.t) = +let get_missing_page = Tezos_rpc.Service.get_service ~description: "Fetch a given page by forwarding the request to a Coordinator's GET \ @@ -94,7 +95,7 @@ let get_missing_page ((module P) : Dac_plugin.t) = Observer mode." ~query:Tezos_rpc.Query.empty ~output:Data_encoding.bytes - Tezos_rpc.Path.(open_root / "missing_page" /: P.hash_rpc_arg) + Tezos_rpc.Path.(open_root / "missing_page" /: Dac_plugin.raw_hash_rpc_arg) (* TODO: https://gitlab.com/tezos/tezos/-/issues/4935 Coordinator's "POST /preimage" endpoint should in addition to root page hash @@ -105,7 +106,7 @@ module Coordinator = struct (** [Coordinator]'s endpoint for serializing dac payload. In addition to returning a root page hash, it also pushes it to the subscribed [Observer]s and [Dac_member]s. *) - let post_preimage ((module P) : Dac_plugin.t) = + let post_preimage = Tezos_rpc.Service.post_service ~description: "Stores the preimage in a sequence of pages. Returns a root page hash \ @@ -113,6 +114,6 @@ module Coordinator = struct of root page hash to subscribed committee members and observers. " ~query:Tezos_rpc.Query.empty ~input:Data_encoding.bytes - ~output:P.encoding + ~output:Dac_plugin.raw_hash_encoding Tezos_rpc.Path.(open_root / "preimage") end diff --git a/src/lib_dac/RPC_services.mli b/src/lib_dac/RPC_services.mli index e933f6a458962df5478ddaa794866c65c9bb3cf7..0c7a8eb445052eead5fe0017b7ffbee62c37b46d 100644 --- a/src/lib_dac/RPC_services.mli +++ b/src/lib_dac/RPC_services.mli @@ -2,13 +2,12 @@ It returns the base58 encoded root page hash and the raw bytes. *) val post_store_preimage : - Dac_plugin.t -> ( [`POST], - 'a, - 'a, + unit, + unit, unit, Bytes.t * Pagination_scheme.t, - Dac_plugin.hash * Bytes.t ) + Dac_plugin.raw_hash * Bytes.t ) Tezos_rpc.Service.service (** GET dac/verify_signature endpoint requests the DAL node to verify @@ -22,10 +21,9 @@ val get_verify_signature : single page, from cctxt. When the request succeeds, the raw page will be returned as a sequence of bytes. *) val get_preimage : - Dac_plugin.t -> ( [`GET], - 'a, - 'a * Dac_plugin.hash, + unit, + unit * Dac_plugin.raw_hash, unit, unit, Bytes.t ) @@ -34,16 +32,14 @@ val get_preimage : (** PUT dac/member_signature endpoint stores the [signature] generated from signing [hex_root_hash] by [dac_member_pkh]. *) val put_dac_member_signature : - Dac_plugin.t -> - ([`PUT], 'a, 'a, unit, Signature_repr.t, unit) Tezos_rpc.Service.service + ([`PUT], unit, unit, unit, Signature_repr.t, unit) Tezos_rpc.Service.service (** GET dac/certificate endpoint returns the DAC certificate for the provided [root_page_hash]. *) val get_certificate : - Dac_plugin.t -> ( [`GET], - 'a, - 'a * Dac_plugin.hash, + unit, + unit * Dac_plugin.raw_hash, unit, unit, Certificate_repr.t option ) @@ -53,10 +49,9 @@ val get_certificate : from a Coordinator node. The missing page is then saved to a page store before returning the page as a response. *) val get_missing_page : - Dac_plugin.t -> ( [`GET], - 'a, - 'a * Dac_plugin.hash, + unit, + unit * Dac_plugin.raw_hash, unit, unit, Bytes.t ) @@ -69,6 +64,11 @@ module Coordinator : sig On the backend side it also pushes root page hash of the preimage to all the subscribed DAC Members and Observers. *) val post_preimage : - Dac_plugin.t -> - ([`POST], 'a, 'a, unit, Bytes.t, Dac_plugin.hash) Tezos_rpc.Service.service + ( [`POST], + unit, + unit, + unit, + Bytes.t, + Dac_plugin.raw_hash ) + Tezos_rpc.Service.service end diff --git a/src/lib_dac/certificate_repr.ml b/src/lib_dac/certificate_repr.ml index 387776be32ee878c8f42c3a19f3fc0f40974d35c..2d5fe4ba9f1490ca573f2b2df48f209452fd7820 100644 --- a/src/lib_dac/certificate_repr.ml +++ b/src/lib_dac/certificate_repr.ml @@ -29,7 +29,7 @@ (* Representation of a Data Availibility Committee Certificate. *) type t = { - root_hash : Dac_plugin.hash; + root_hash : Dac_plugin.raw_hash; aggregate_signature : Tezos_crypto.Aggregate_signature.signature; witnesses : Z.t; (* TODO: https://gitlab.com/tezos/tezos/-/issues/4853 @@ -37,11 +37,11 @@ type t = { *) } -let encoding ((module P) : Dac_plugin.t) = +let encoding = let obj_enc = Data_encoding.( obj3 - (req "root_hash" P.encoding) + (req "root_hash" Dac_plugin.raw_hash_encoding) (req "aggregate_signature" Tezos_crypto.Aggregate_signature.encoding) (req "witnesses" z)) in diff --git a/src/lib_dac/dac_plugin.ml b/src/lib_dac/dac_plugin.ml index cf91c7ceff0667b3a5d188d8d3eeb8f24dd6e43a..f627e1d26bafc3f14ba468887560d61d06f65695 100644 --- a/src/lib_dac/dac_plugin.ml +++ b/src/lib_dac/dac_plugin.ml @@ -2,6 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2023 Trili Tech, *) +(* Copyright (c) 2023 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -25,15 +26,72 @@ type hash = bytes +type raw_hash = bytes + let hash_to_bytes = Fun.id +let raw_hash_to_bytes = Fun.id + let hash_to_hex hash = Hex.of_bytes hash type supported_hashes = Blake2B let raw_compare = Bytes.compare -let non_proto_encoding_unsafe = Data_encoding.bytes' Hex +let raw_hash_encoding = Data_encoding.bytes' Hex + +let hash_to_raw = Fun.id + +let raw_hash_to_hex raw_hash = + let (`Hex hash) = Hex.of_bytes raw_hash in + hash + +let raw_hash_of_hex hex = Hex.to_bytes (`Hex hex) + +let raw_hash_rpc_arg = + let construct = raw_hash_to_hex in + let destruct hash = + match raw_hash_of_hex hash with + | None -> Error "Impossible to parse raw_hash" + | Some reveal_hash -> Ok reveal_hash + in + Tezos_rpc.Arg.make + ~descr:"A reveal hash" + ~name:"reveal_hash" + ~destruct + ~construct + () + +type cannot_convert_raw_hash_to_hash = { + raw_hash : raw_hash; + proto : Protocol_hash.t; +} + +type error += Cannot_convert_raw_hash_to_hash of cannot_convert_raw_hash_to_hash + +let () = + register_error_kind + `Permanent + ~id:"cannot_convert_raw_hash_to_hash" + ~title:"Impossible to retrieve hash from raw_hash" + ~description: + "Impossible to validate the provided raw_hash against the protocol" + ~pp:(fun ppf (raw_hash, proto) -> + Format.fprintf + ppf + "Impossible to validate the provided raw_hash %s against the actual \ + protocol %s and transform it to a valid hash" + (raw_hash_to_hex raw_hash) + (Protocol_hash.to_string proto)) + Data_encoding.( + obj2 + (req "raw_hash" raw_hash_encoding) + (req "proto" Protocol_hash.encoding)) + (function + | Cannot_convert_raw_hash_to_hash {raw_hash; proto} -> + Some (raw_hash, proto) + | _ -> None) + (fun (raw_hash, proto) -> Cannot_convert_raw_hash_to_hash {raw_hash; proto}) module type T = sig val encoding : hash Data_encoding.t @@ -53,13 +111,21 @@ module type T = sig val size : scheme:supported_hashes -> int - val hash_rpc_arg : hash Tezos_rpc.Arg.arg - module Proto : Registered_protocol.T end type t = (module T) +let raw_to_hash ((module Plugin) : t) raw_hash = + let of_bytes_opt = + Data_encoding.Binary.of_bytes_opt Plugin.encoding raw_hash + in + match of_bytes_opt with + | Some hash -> Ok hash + | None -> + Result_syntax.tzfail + @@ Cannot_convert_raw_hash_to_hash {raw_hash; proto = Plugin.Proto.hash} + let table : t Protocol_hash.Table.t = Protocol_hash.Table.create 5 let register (make_plugin : (bytes -> hash) -> t) : unit = diff --git a/src/lib_dac/dac_plugin.mli b/src/lib_dac/dac_plugin.mli index 8b627099daebc355fc1229e1f152f2bb28f742f9..ac304dc9cd5d65a4fae896c3e1105e295dcd0839 100644 --- a/src/lib_dac/dac_plugin.mli +++ b/src/lib_dac/dac_plugin.mli @@ -2,6 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2023 Trili Tech, *) +(* Copyright (c) 2023 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -41,16 +42,45 @@ val hash_to_hex : hash -> Hex.t this function does not require an instance of [Dac_plugin.t]. *) val raw_compare : hash -> hash -> int +(** Protocol independant hash. Useful to avoid needing the Plugin in + the RPC APIs. *) +type raw_hash + (** Protocol independent encoding of Dac_plugin.hash values. Only use in situations where the plugin is not available, and for reporting purposes (e.g. when emitting an event or registering an error). *) -val non_proto_encoding_unsafe : hash Data_encoding.t +val raw_hash_encoding : raw_hash Data_encoding.t + +(** This conversion is safe. *) +val raw_hash_to_bytes : raw_hash -> bytes + +(** Thanks to [hash] and [raw_hash] internal representation, + this conversion is safe. *) +val hash_to_raw : hash -> raw_hash + +(** [raw_hash_to_hex] encodes a [raw_hash] into hex. *) +val raw_hash_to_hex : raw_hash -> string + +(** [raw_hash_of_hex] decodes a hex string representation into [raw_hash]. *) +val raw_hash_of_hex : string -> raw_hash option + +(** [raw_hash] argument definition for RPC. *) +val raw_hash_rpc_arg : raw_hash Tezos_rpc.Arg.arg (** FIXME: https://gitlab.com/tezos/tezos/-/issues/4856 - Fix static supported_hashes type *) + Fix static supported_hashes type. *) type supported_hashes = Blake2B +(** Type used to track exception when impossible to convert + [raw_hash] to [hash]. *) +type cannot_convert_raw_hash_to_hash = { + raw_hash : raw_hash; + proto : Protocol_hash.t; +} + +type error += Cannot_convert_raw_hash_to_hash of cannot_convert_raw_hash_to_hash + module type T = sig (** The encoding of reveal hashes. *) val encoding : hash Data_encoding.t @@ -81,15 +111,15 @@ module type T = sig specified in input. *) val size : scheme:supported_hashes -> int - (** Hash argument definition for RPC *) - val hash_rpc_arg : hash Tezos_rpc.Arg.arg - module Proto : Registered_protocol.T end -(** Dac plugin module type *) +(** Dac plugin module type. *) type t = (module T) +(** Unlike [hash_to_raw] this conversion is unsafe. *) +val raw_to_hash : t -> raw_hash -> hash tzresult + (** [register make_plugin] derives and registers a new [Dac_plugin.T] given an [of_bytes]. Implementers of plugin are responsible for providing the definition of this derivation. Functions that expose diff --git a/src/lib_dac/signature_repr.ml b/src/lib_dac/signature_repr.ml index 3c9d281d1f0858479ed24d04791c1419b7957901..3953632c071f078eab3a51453326285efe0621a0 100644 --- a/src/lib_dac/signature_repr.ml +++ b/src/lib_dac/signature_repr.ml @@ -26,13 +26,13 @@ (** Representation of committee member signature. *) type t = { - root_hash : Dac_plugin.hash; + root_hash : Dac_plugin.raw_hash; signature : Tezos_crypto.Aggregate_signature.t; signer_pkh : Tezos_crypto.Aggregate_signature.public_key_hash; } (** [encoding dac_plugin] returns the [t Data_encoding.t] given a [dac_plugin]. *) -let encoding ((module P) : Dac_plugin.t) = +let encoding = Data_encoding.( conv (fun {root_hash; signature; signer_pkh} -> @@ -40,7 +40,7 @@ let encoding ((module P) : Dac_plugin.t) = (fun (root_hash, signature, signer_pkh) -> {root_hash; signature; signer_pkh}) (obj3 - (req "root_hash" P.encoding) + (req "root_hash" Dac_plugin.raw_hash_encoding) (req "signature" Tezos_crypto.Aggregate_signature.encoding) (req "signer_pkh" diff --git a/src/lib_dac_client/dac_node_client.ml b/src/lib_dac_client/dac_node_client.ml index 477c87d04da9fdb73db9ef81f0784cd59a44b659..7ecc19953eef871f7f4b686e672884fd0409c756 100644 --- a/src/lib_dac_client/dac_node_client.ml +++ b/src/lib_dac_client/dac_node_client.ml @@ -50,13 +50,12 @@ let make_unix_cctxt ~scheme ~host ~port = hash of the protocol that the coordinator was using when the page hash was computed. *) -let get_preimage (plugin : Dac_plugin.t) (cctxt : #cctxt) ~page_hash = - cctxt#call_service (RPC_services.get_preimage plugin) ((), page_hash) () () +let get_preimage (cctxt : #cctxt) ~page_hash = + cctxt#call_service RPC_services.get_preimage ((), page_hash) () () -let post_store_preimage (plugin : Dac_plugin.t) (cctxt : #cctxt) ~payload - ~pagination_scheme = +let post_store_preimage (cctxt : #cctxt) ~payload ~pagination_scheme = cctxt#call_service - (RPC_services.post_store_preimage plugin) + RPC_services.post_store_preimage () () (payload, pagination_scheme) @@ -64,26 +63,13 @@ let post_store_preimage (plugin : Dac_plugin.t) (cctxt : #cctxt) ~payload let get_verify_signature (cctxt : #cctxt) ~external_message = cctxt#call_service RPC_services.get_verify_signature () external_message () -let put_dac_member_signature (plugin : Dac_plugin.t) (cctxt : #cctxt) ~signature - = - cctxt#call_service - (RPC_services.put_dac_member_signature plugin) - () - () - signature +let put_dac_member_signature (cctxt : #cctxt) ~signature = + cctxt#call_service RPC_services.put_dac_member_signature () () signature -let get_certificate (plugin : Dac_plugin.t) (cctxt : #cctxt) ~root_page_hash = - cctxt#call_service - (RPC_services.get_certificate plugin) - ((), root_page_hash) - () - () +let get_certificate (cctxt : #cctxt) ~root_page_hash = + cctxt#call_service RPC_services.get_certificate ((), root_page_hash) () () module Coordinator = struct - let post_preimage (plugin : Dac_plugin.t) (cctxt : #cctxt) ~payload = - cctxt#call_service - (RPC_services.Coordinator.post_preimage plugin) - () - () - payload + let post_preimage (cctxt : #cctxt) ~payload = + cctxt#call_service RPC_services.Coordinator.post_preimage () () payload end diff --git a/src/lib_dac_client/dac_node_client.mli b/src/lib_dac_client/dac_node_client.mli index af40e4c8d2c17f40f7ee94d2d48c5384170810de..ee2665283bfb882d9420c6a74e524812e9466aa4 100644 --- a/src/lib_dac_client/dac_node_client.mli +++ b/src/lib_dac_client/dac_node_client.mli @@ -43,17 +43,16 @@ val make_unix_cctxt : scheme:string -> host:string -> port:int -> cctxt single page, from cctxt. When the request succeeds, the raw page will be returned as a sequence of bytes. *) val get_preimage : - Dac_plugin.t -> #cctxt -> page_hash:Dac_plugin.hash -> bytes tzresult Lwt.t + #cctxt -> page_hash:Dac_plugin.raw_hash -> bytes tzresult Lwt.t (** [post_store_preimage cctxt ~payload ~pagination_scheme] posts a [payload] to dac/store_preimage using a given [pagination_scheme]. It returns the base58 encoded root page hash and the raw bytes. *) val post_store_preimage : - Dac_plugin.t -> #cctxt -> payload:bytes -> pagination_scheme:Pagination_scheme.t -> - (Dac_plugin.hash * bytes) tzresult Lwt.t + (Dac_plugin.raw_hash * bytes) tzresult Lwt.t (** [get_verify_signature cctxt ~external_message] requests the DAL node to verify the signature of the external message [external_message] via @@ -67,14 +66,13 @@ val get_verify_signature : stores the [signature] generated from signing [hex_root_hash] by [dac_member_pkh]. *) val put_dac_member_signature : - Dac_plugin.t -> #cctxt -> signature:Signature_repr.t -> unit tzresult Lwt.t + #cctxt -> signature:Signature_repr.t -> unit tzresult Lwt.t (** [get_certificate cctxt ~root_page_hash] fetches the DAC certificate for the provided [root_page_hash]. *) val get_certificate : - Dac_plugin.t -> #cctxt -> - root_page_hash:Dac_plugin.hash -> + root_page_hash:Dac_plugin.raw_hash -> Certificate_repr.t option tzresult Lwt.t module Coordinator : sig @@ -84,5 +82,5 @@ module Coordinator : sig On the backend side it also pushes root page hash of the preimage to all the subscribed DAC Members and Observers. *) val post_preimage : - Dac_plugin.t -> #cctxt -> payload:bytes -> Dac_plugin.hash tzresult Lwt.t + #cctxt -> payload:bytes -> Dac_plugin.raw_hash tzresult Lwt.t end diff --git a/src/lib_dac_node/RPC_server.ml b/src/lib_dac_node/RPC_server.ml index 37df315ba78a02eacc8f105a535f0f7621da94be..9aa77288cc26608aeebaf852a413d87e21dc2fee 100644 --- a/src/lib_dac_node/RPC_server.ml +++ b/src/lib_dac_node/RPC_server.ml @@ -75,7 +75,9 @@ let handle_post_store_preimage dac_plugin cctxt dac_sk_uris page_store ~page_store data in - let () = Data_streamer.publish hash_streamer root_hash in + let () = + Data_streamer.publish hash_streamer (Dac_plugin.hash_to_raw root_hash) + in let*! () = Event.emit_root_hash_pushed_to_data_streamer dac_plugin root_hash in @@ -90,21 +92,22 @@ let handle_post_store_preimage dac_plugin cctxt dac_sk_uris page_store let* signature, witnesses = Signature_manager.sign_root_hash dac_plugin cctxt dac_sk_uris root_hash in + let raw_root_hash = Dac_plugin.hash_to_raw root_hash in let*! external_message = External_message.Default.make dac_plugin root_hash signature witnesses in match external_message with - | Ok external_message -> return @@ (root_hash, external_message) + | Ok external_message -> return @@ (raw_root_hash, external_message) | Error _ -> tzfail @@ Cannot_construct_external_message let handle_get_verify_signature dac_plugin public_keys_opt encoded_l1_message = let open Lwt_result_syntax in + let ((module Plugin) : Dac_plugin.t) = dac_plugin in let external_message = let open Option_syntax in let* encoded_l1_message in let* as_bytes = Hex.to_bytes @@ `Hex encoded_l1_message in - let ((module P) : Dac_plugin.t) = dac_plugin in - External_message.Default.of_bytes P.encoding as_bytes + External_message.Default.of_bytes Plugin.encoding as_bytes in match external_message with | None -> tzfail @@ Cannot_deserialize_external_message @@ -112,11 +115,13 @@ let handle_get_verify_signature dac_plugin public_keys_opt encoded_l1_message = Signature_manager.verify dac_plugin ~public_keys_opt - root_hash + (Dac_plugin.hash_to_raw root_hash) signature witnesses -let handle_get_preimage dac_plugin page_store hash = +let handle_get_preimage dac_plugin page_store raw_hash = + let open Lwt_result_syntax in + let*? hash = Dac_plugin.raw_to_hash dac_plugin raw_hash in Page_store.Filesystem.load dac_plugin page_store hash (* Handler for subscribing to the streaming of root hashes via @@ -129,24 +134,27 @@ let handle_monitor_root_hashes hash_streamer = let* () = Event.(emit handle_new_subscription_to_hash_streamer ()) in Tezos_rpc.Answer.return_stream {next; shutdown} -let handle_get_certificate ctx root_hash = +let handle_get_certificate dac_plugin ctx raw_root_hash = let open Lwt_result_syntax in + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin raw_root_hash in let node_store = Node_context.get_node_store ctx Store_sigs.Read_only in let+ value_opt = Store.Certificate_store.find node_store root_hash in Option.map (fun Store.{aggregate_signature; witnesses} -> - Certificate_repr.{aggregate_signature; witnesses; root_hash}) + Certificate_repr. + {aggregate_signature; witnesses; root_hash = raw_root_hash}) value_opt -let handle_get_missing_page cctxt page_store dac_plugin root_hash = +let handle_get_missing_page cctxt page_store dac_plugin raw_root_hash = let open Lwt_result_syntax in + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin raw_root_hash in let remote_store = Page_store.Remote.(init {cctxt; page_store}) in let* preimage = (* TODO: https://gitlab.com/tezos/tezos/-/issues/5142 Retrieve missing page from dac committee via "flooding". *) Page_store.Remote.load dac_plugin remote_store root_hash in - let*! () = Event.(emit (fetched_missing_page dac_plugin) root_hash) in + let*! () = Event.(emit fetched_missing_page raw_root_hash) in return preimage let register_post_store_preimage ctx cctxt dac_sk_uris page_store hash_streamer @@ -154,7 +162,7 @@ let register_post_store_preimage ctx cctxt dac_sk_uris page_store hash_streamer directory |> add_service Tezos_rpc.Directory.register0 - (RPC_services.post_store_preimage ctx) + RPC_services.post_store_preimage (fun () input -> handle_post_store_preimage ctx @@ -175,19 +183,19 @@ let register_get_verify_signature dac_plugin public_keys_opt directory = let register_get_preimage dac_plugin page_store = add_service Tezos_rpc.Directory.register1 - (RPC_services.get_preimage dac_plugin) + RPC_services.get_preimage (fun hash () () -> handle_get_preimage dac_plugin page_store hash) -let register_monitor_root_hashes dac_plugin hash_streamer dir = +let register_monitor_root_hashes hash_streamer dir = Tezos_rpc.Directory.gen_register dir - (Monitor_services.S.root_hashes dac_plugin) + Monitor_services.S.root_hashes (fun () () () -> handle_monitor_root_hashes hash_streamer) -let register_put_dac_member_signature ctx dac_plugin cctxt = +let register_put_dac_member_signature ctx cctxt = add_service Tezos_rpc.Directory.register0 - (RPC_services.put_dac_member_signature dac_plugin) + RPC_services.put_dac_member_signature (fun () dac_member_signature -> Signature_manager.Coordinator.handle_put_dac_member_signature ctx @@ -197,15 +205,15 @@ let register_put_dac_member_signature ctx dac_plugin cctxt = let register_get_certificate ctx dac_plugin = add_service Tezos_rpc.Directory.register1 - (RPC_services.get_certificate dac_plugin) - (fun root_hash () () -> handle_get_certificate ctx root_hash) + RPC_services.get_certificate + (fun root_hash () () -> handle_get_certificate dac_plugin ctx root_hash) let register_get_missing_page ctx dac_plugin = match Node_context.mode ctx with | Legacy _ | Observer _ -> add_service Tezos_rpc.Directory.register1 - (RPC_services.get_missing_page dac_plugin) + RPC_services.get_missing_page (fun root_hash () () -> let open Lwt_result_syntax in let page_store = Node_context.get_page_store ctx in @@ -222,18 +230,24 @@ module Coordinator = struct ~page_store payload in - let () = Data_streamer.publish hash_streamer root_hash in + let () = + Data_streamer.publish hash_streamer (Dac_plugin.hash_to_raw root_hash) + in let*! () = Event.emit_root_hash_pushed_to_data_streamer dac_plugin root_hash in - return root_hash + return @@ Dac_plugin.hash_to_raw root_hash - let handle_monitor_certificate ro_store certificate_streamers root_hash - committee_members = + let handle_monitor_certificate dac_plugin ro_store certificate_streamers + raw_root_hash committee_members = let open Lwt_result_syntax in - let stream, stopper = - Certificate_streamers.handle_subscribe certificate_streamers root_hash + let*? stream, stopper = + Certificate_streamers.handle_subscribe + dac_plugin + certificate_streamers + raw_root_hash in + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin raw_root_hash in let*! () = Event.emit_new_subscription_to_certificate_updates root_hash in let shutdown () = Lwt_watcher.shutdown stopper in let next () = Lwt_stream.get stream in @@ -249,43 +263,57 @@ module Coordinator = struct Option.iter (fun Store.{aggregate_signature; witnesses} -> let certificate = - Certificate_repr.{root_hash; aggregate_signature; witnesses} + Certificate_repr. + {root_hash = raw_root_hash; aggregate_signature; witnesses} + in + let _ = + Certificate_streamers.push + dac_plugin + certificate_streamers + raw_root_hash + certificate in - Certificate_streamers.push - certificate_streamers - root_hash - certificate ; if Certificate_repr.all_committee_members_have_signed committee_members certificate then let _ = - Certificate_streamers.close certificate_streamers root_hash + Certificate_streamers.close + dac_plugin + certificate_streamers + raw_root_hash in () else ()) current_certificate_store_value in - Tezos_rpc.Answer.return_stream {next; shutdown} - | Error e -> Tezos_rpc.Answer.fail e + return (next, shutdown) + | Error e -> fail e let register_monitor_certificate dac_plugin ro_store certificate_streamers committee_members dir = Tezos_rpc.Directory.gen_register dir - (Monitor_services.S.certificate dac_plugin) + Monitor_services.S.certificate (fun ((), root_hash) () () -> - handle_monitor_certificate - ro_store - certificate_streamers - root_hash - committee_members) + let open Lwt_result_syntax in + let*! handler = + handle_monitor_certificate + dac_plugin + ro_store + certificate_streamers + root_hash + committee_members + in + match handler with + | Ok (next, shutdown) -> Tezos_rpc.Answer.return_stream {next; shutdown} + | Error e -> Tezos_rpc.Answer.fail e) let register_coordinator_post_preimage dac_plugin hash_streamer page_store = add_service Tezos_rpc.Directory.register0 - (RPC_services.Coordinator.post_preimage dac_plugin) + RPC_services.Coordinator.post_preimage (fun () payload -> handle_post_preimage dac_plugin page_store hash_streamer payload) @@ -313,13 +341,13 @@ module Coordinator = struct |> register_coordinator_post_preimage dac_plugin hash_streamer page_store |> register_get_verify_signature dac_plugin public_keys_opt |> register_get_preimage dac_plugin page_store - |> register_monitor_root_hashes dac_plugin hash_streamer + |> register_monitor_root_hashes hash_streamer |> register_monitor_certificate dac_plugin ro_store certificate_streamers committee_members - |> register_put_dac_member_signature node_ctxt dac_plugin cctxt + |> register_put_dac_member_signature node_ctxt cctxt |> register_get_certificate node_ctxt dac_plugin end @@ -362,8 +390,8 @@ module Legacy = struct hash_streamer |> register_get_verify_signature dac_plugin public_keys_opt |> register_get_preimage dac_plugin page_store - |> register_monitor_root_hashes dac_plugin hash_streamer - |> register_put_dac_member_signature node_ctxt dac_plugin cctxt + |> register_monitor_root_hashes hash_streamer + |> register_put_dac_member_signature node_ctxt cctxt |> register_get_certificate node_ctxt dac_plugin |> register_get_missing_page node_ctxt dac_plugin end diff --git a/src/lib_dac_node/certificate_streamers.ml b/src/lib_dac_node/certificate_streamers.ml index f78d0c8d1caf650b2d8af6b0d5ced6ad9b101f93..9c9c794af1ccbf96c772e9dcd885a44d799c120e 100644 --- a/src/lib_dac_node/certificate_streamers.ml +++ b/src/lib_dac_node/certificate_streamers.ml @@ -46,19 +46,25 @@ let create_if_none certificate_streamers root_hash = !certificate_streamers |> Map.find root_hash |> Option.value_f ~default:(fun _ -> assert false) -let handle_subscribe certificate_streamers root_hash = +let handle_subscribe dac_plugin certificate_streamers raw_root_hash = + let open Result_syntax in + let* root_hash = Dac_plugin.raw_to_hash dac_plugin raw_root_hash in let certificate_streamer_for_root_hash = create_if_none certificate_streamers root_hash in - Data_streamer.handle_subscribe certificate_streamer_for_root_hash + return @@ Data_streamer.handle_subscribe certificate_streamer_for_root_hash -let push certificate_streamers root_hash certificate = +let push dac_plugin certificate_streamers raw_root_hash certificate = + let open Result_syntax in + let* root_hash = Dac_plugin.raw_to_hash dac_plugin raw_root_hash in let certificate_streamer_for_root_hash = create_if_none certificate_streamers root_hash in - Data_streamer.publish certificate_streamer_for_root_hash certificate + return @@ Data_streamer.publish certificate_streamer_for_root_hash certificate -let close certificate_streamers root_hash = +let close dac_plugin certificate_streamers raw_root_hash = + let open Result_syntax in + let* root_hash = Dac_plugin.raw_to_hash dac_plugin raw_root_hash in let certificate_streamer_for_root_hash = Map.find root_hash !certificate_streamers in @@ -66,5 +72,5 @@ let close certificate_streamers root_hash = | Some streamer -> Data_streamer.close streamer ; certificate_streamers := Map.remove root_hash !certificate_streamers ; - true - | None -> false + return true + | None -> return false diff --git a/src/lib_dac_node/certificate_streamers.mli b/src/lib_dac_node/certificate_streamers.mli index 6145cf5f91f1dc7e12df1277df37651636d62318..7073032c258b534cd45fe6093b281bd98c10fce6 100644 --- a/src/lib_dac_node/certificate_streamers.mli +++ b/src/lib_dac_node/certificate_streamers.mli @@ -35,17 +35,25 @@ type t (** [init ()] returns an empty map of certificate streams. *) val init : unit -> t -(** [handle_subscribe t root_hash] creates a new watcher for [root_hash] in +(** [handle_subscribe dac_plugin t root_hash] creates a new watcher for [root_hash] in [t], and returns the corresponding [Lwt_stream] and [Lwt_watcher.stopper]. *) val handle_subscribe : - t -> Dac_plugin.hash -> Certificate_repr.t Lwt_stream.t * Lwt_watcher.stopper + Dac_plugin.t -> + t -> + Dac_plugin.raw_hash -> + (Certificate_repr.t Lwt_stream.t * Lwt_watcher.stopper) tzresult -(** [push t root_hash certificate] streams the updated certificate for +(** [push dac_plugin t root_hash certificate] streams the updated certificate for [root_hash]. *) -val push : t -> Dac_plugin.hash -> Certificate_repr.t -> unit +val push : + Dac_plugin.t -> + t -> + Dac_plugin.raw_hash -> + Certificate_repr.t -> + unit tzresult -(** [close t root_hash] closes the certificate [Data_streamer.t] for +(** [close dac_plugin t root_hash] closes the certificate [Data_streamer.t] for [root_hash]. Returns true if the [Data_streamer.t] associated to [root_hash] was open before the function was invoked, false otherwise. *) -val close : t -> Dac_plugin.hash -> bool +val close : Dac_plugin.t -> t -> Dac_plugin.raw_hash -> bool tzresult diff --git a/src/lib_dac_node/event.ml b/src/lib_dac_node/event.ml index aa6f340e1c041c4951322b4871b397c2757efc37..081d816c84c4cd7b35d14988642903fa69f9c719 100644 --- a/src/lib_dac_node/event.ml +++ b/src/lib_dac_node/event.ml @@ -277,21 +277,23 @@ let emit_protocol_plugin_not_resolved current_protocol next_protocol = ( proto_short_hash_string current_protocol, proto_short_hash_string next_protocol ) -let emit_new_root_hash_received ((module P) : Dac_plugin.t) hash = - emit new_root_hash_received (P.to_hex hash) +let emit_new_root_hash_received ((module Plugin) : Dac_plugin.t) hash = + emit new_root_hash_received (Plugin.to_hex hash) let emit_new_subscription_to_certificate_updates hash = let hex = Hex.show @@ Dac_plugin.hash_to_hex hash in emit new_subscription_to_certificate_updates hex -let emit_root_hash_pushed_to_data_streamer ((module P) : Dac_plugin.t) hash = - emit new_hash_pushed_to_data_streamer (P.to_hex hash) +let emit_root_hash_pushed_to_data_streamer ((module Plugin) : Dac_plugin.t) hash + = + emit new_hash_pushed_to_data_streamer (Plugin.to_hex hash) -let emit_received_root_hash_processed ((module P) : Dac_plugin.t) hash = - emit received_root_hash_processed (P.to_hex hash) +let emit_received_root_hash_processed ((module Plugin) : Dac_plugin.t) hash = + emit received_root_hash_processed (Plugin.to_hex hash) -let emit_processing_root_hash_failed ((module P) : Dac_plugin.t) hash errors = - emit processing_root_hash_failed (P.to_hex hash, errors) +let emit_processing_root_hash_failed ((module Plugin) : Dac_plugin.t) hash + errors = + emit processing_root_hash_failed (Plugin.to_hex hash, errors) let emit_signature_pushed_to_coordinator signature = emit new_signature_pushed_to_coordinator signature @@ -301,10 +303,10 @@ let emit_no_committee_member_address = emit no_committee_member_address let emit_cannot_retrieve_keys_from_address address = emit cannot_retrieve_keys_from_address address -let fetched_missing_page ((module P) : Dac_plugin.t) = +let fetched_missing_page = declare_1 ~section ~name:"missing_page_fetched" ~msg:"Successfully fetched missing page for hash: {hash}" ~level:Notice - ("hash", P.encoding) + ("hash", Dac_plugin.raw_hash_encoding) diff --git a/src/lib_dac_node/external_message.ml b/src/lib_dac_node/external_message.ml index c85fbb3537291fb463f517672a854cc3e1944990..8b1aa7b2c64ad091762b511f69937511ce5165ea 100644 --- a/src/lib_dac_node/external_message.ml +++ b/src/lib_dac_node/external_message.ml @@ -2,6 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2022-2023 Trili Tech *) +(* Copyright (c) 2023 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -86,17 +87,19 @@ struct (fun msg -> msg); ]) - let make ((module P) : Dac_plugin.t) root_hash signature witnesses = + let make ((module Plugin) : Dac_plugin.t) root_hash signature witnesses = let open Lwt_result_syntax in let message = {root_hash; signature; witnesses} in let res = - Data_encoding.Binary.to_bytes (dac_message_encoding P.encoding) message + Data_encoding.Binary.to_bytes + (dac_message_encoding Plugin.encoding) + message in match res with | Ok bytes -> return bytes | Error _ -> tzfail - @@ Could_not_serialize_rollup_external_message (P.to_hex root_hash) + @@ Could_not_serialize_rollup_external_message (Plugin.to_hex root_hash) let of_bytes dac_hash_encoding encoded_message = Data_encoding.Binary.of_bytes_opt diff --git a/src/lib_dac_node/external_message.mli b/src/lib_dac_node/external_message.mli index 1237f2c4a9bb81f0e762ceda302e2ac40959225f..af950b2c91852b634f14f9af63f87b9aabce1bff 100644 --- a/src/lib_dac_node/external_message.mli +++ b/src/lib_dac_node/external_message.mli @@ -2,6 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2022-2023 Trili Tech *) +(* Copyright (c) 2023 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) diff --git a/src/lib_dac_node/handler.ml b/src/lib_dac_node/handler.ml index d0a5077a1cccf0514d51391b5b9c197b92828bc4..05e3869e2bec0485407cabb0893ecec6252141a0 100644 --- a/src/lib_dac_node/handler.ml +++ b/src/lib_dac_node/handler.ml @@ -135,8 +135,8 @@ let new_head ctxt = {li Send the signature back to the [Coordinaotor].} } *) module Committee_member = struct - let push_payload_signature dac_plugin coordinator_cctxt wallet_cctxt - committee_member root_hash = + let push_payload_signature coordinator_cctxt wallet_cctxt committee_member + root_hash = let open Lwt_result_syntax in let signer_pkh = committee_member.Wallet_account.Committee_member.public_key_hash @@ -149,10 +149,12 @@ module Committee_member = struct secret_key_uri bytes_to_sign in - let signature_repr = Signature_repr.{root_hash; signature; signer_pkh} in + let signature_repr = + Signature_repr. + {root_hash = Dac_plugin.hash_to_raw root_hash; signature; signer_pkh} + in let* () = Dac_node_client.put_dac_member_signature - dac_plugin coordinator_cctxt ~signature:signature_repr in @@ -165,6 +167,7 @@ module Committee_member = struct ctxt.Node_context.Committee_member.coordinator_cctxt in let handler dac_plugin remote_store _stopper root_hash = + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin root_hash in let*! () = Event.emit_new_root_hash_received dac_plugin root_hash in let*! payload_result = Pages_encoding.Merkle_tree.V0.Remote.deserialize_payload @@ -181,7 +184,6 @@ module Committee_member = struct ctxt.Node_context.Committee_member.committee_member in push_payload_signature - dac_plugin coordinator_cctxt wallet_cctxt committee_member @@ -200,7 +202,7 @@ module Committee_member = struct let*! () = Event.(emit subscribed_to_root_hashes_stream ()) in make_stream_daemon (handler dac_plugin remote_store) - (Monitor_services.root_hashes coordinator_cctxt dac_plugin) + (Monitor_services.root_hashes coordinator_cctxt) end (** Handlers specific to an [Observer]. An [Observer] is responsible for @@ -215,6 +217,7 @@ module Observer = struct let open Lwt_result_syntax in let coordinator_cctxt = ctxt.Node_context.Observer.coordinator_cctxt in let handler dac_plugin remote_store _stopper root_hash = + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin root_hash in let*! () = Event.emit_new_root_hash_received dac_plugin root_hash in let*! payload_result = Pages_encoding.Merkle_tree.V0.Remote.deserialize_payload @@ -242,7 +245,7 @@ module Observer = struct let*! () = Event.(emit subscribed_to_root_hashes_stream ()) in make_stream_daemon (handler dac_plugin remote_store) - (Monitor_services.root_hashes coordinator_cctxt dac_plugin) + (Monitor_services.root_hashes coordinator_cctxt) end (** Handlers specific to a [Legacy] DAC node. If no @@ -267,8 +270,8 @@ end } *) module Legacy = struct - let push_payload_signature dac_plugin coordinator_cctxt wallet_cctxt - committee_member root_hash = + let push_payload_signature coordinator_cctxt wallet_cctxt committee_member + root_hash = let open Lwt_result_syntax in let secret_key_uri_opt = committee_member.Wallet_account.Legacy.secret_key_uri_opt @@ -284,11 +287,15 @@ module Legacy = struct bytes_to_sign in let signature_repr = - Signature_repr.{root_hash; signature; signer_pkh} + Signature_repr. + { + root_hash = Dac_plugin.hash_to_raw root_hash; + signature; + signer_pkh; + } in let* () = Dac_node_client.put_dac_member_signature - dac_plugin coordinator_cctxt ~signature:signature_repr in @@ -306,6 +313,7 @@ module Legacy = struct let committee_member_opt = ctxt.Node_context.Legacy.committee_member_opt in let open Lwt_result_syntax in let handler dac_plugin remote_store _stopper root_hash = + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin root_hash in let*! () = Event.emit_new_root_hash_received dac_plugin root_hash in let*! payload_result = Pages_encoding.Merkle_tree.V0.Remote.deserialize_payload @@ -325,7 +333,6 @@ module Legacy = struct If there is no [committee_member_address] provided, it means the node is run as an observer then we simply [return ()] *) push_payload_signature - dac_plugin coordinator_cctxt wallet_cctxt committee_member @@ -347,7 +354,7 @@ module Legacy = struct let*! () = Event.(emit subscribed_to_root_hashes_stream ()) in make_stream_daemon (handler dac_plugin remote_store) - (Monitor_services.root_hashes coordinator_cctxt dac_plugin) + (Monitor_services.root_hashes coordinator_cctxt) end let handlers node_ctxt = diff --git a/src/lib_dac_node/monitor_services.ml b/src/lib_dac_node/monitor_services.ml index afdc42970eccd589a56f0866f4dace9d97701211..41a38017d90ba10f711927d89fcae44bb94fc073 100644 --- a/src/lib_dac_node/monitor_services.ml +++ b/src/lib_dac_node/monitor_services.ml @@ -24,16 +24,16 @@ (*****************************************************************************) module S = struct - let root_hashes ((module P) : Dac_plugin.t) = + let root_hashes = Tezos_rpc.Service.get_service ~description: "Monitor a stream of root hashes that are produced by another dac node \ responsible for the serialization of the dac payload (coordinator). " ~query:Tezos_rpc.Query.empty - ~output:P.encoding + ~output:Dac_plugin.raw_hash_encoding Tezos_rpc.Path.(open_root / "monitor" / "root_hashes") - let certificate ((module P) : Dac_plugin.t) = + let certificate = Tezos_rpc.Service.get_service ~description: "Monitor a stream of updates to certificates for a given root hash. \ @@ -43,21 +43,17 @@ module S = struct once delivery, i.e. a certificate update could be streamed multiple \ times." ~query:Tezos_rpc.Query.empty - ~output:(Certificate_repr.encoding (module P)) - Tezos_rpc.Path.(open_root / "monitor" / "certificate" /: P.hash_rpc_arg) + ~output:Certificate_repr.encoding + Tezos_rpc.Path.( + open_root / "monitor" / "certificate" /: Dac_plugin.raw_hash_rpc_arg) end -let root_hashes dac_node_cctxt dac_plugin = - Tezos_rpc.Context.make_streamed_call - (S.root_hashes dac_plugin) - dac_node_cctxt - () - () - () +let root_hashes dac_node_cctxt = + Tezos_rpc.Context.make_streamed_call S.root_hashes dac_node_cctxt () () () -let certificate dac_node_cctxt dac_plugin root_hash = +let certificate dac_node_cctxt root_hash = Tezos_rpc.Context.make_streamed_call - (S.certificate dac_plugin) + S.certificate dac_node_cctxt ((), root_hash) () diff --git a/src/lib_dac_node/monitor_services.mli b/src/lib_dac_node/monitor_services.mli index b5b2bf7caba56537d7543e720733beef0bf48295..63cc638a05fd12ff887ef5b2c461e40c84a52b47 100644 --- a/src/lib_dac_node/monitor_services.mli +++ b/src/lib_dac_node/monitor_services.mli @@ -26,15 +26,19 @@ module S : sig (** Define RPC GET /monitor/root_hashes. *) val root_hashes : - Dac_plugin.t -> - ([`GET], unit, unit, unit, unit, Dac_plugin.hash) Tezos_rpc.Service.service + ( [`GET], + unit, + unit, + unit, + unit, + Dac_plugin.raw_hash ) + Tezos_rpc.Service.service (** Define RPC GET /monitor/certificate/{hex_root_hash}. *) val certificate : - Dac_plugin.t -> ( [`GET], unit, - unit * Dac_plugin.hash, + unit * Dac_plugin.raw_hash, unit, unit, Certificate_repr.t ) @@ -48,15 +52,13 @@ end *) val root_hashes : #Tezos_rpc.Context.streamed -> - Dac_plugin.t -> - (Dac_plugin.hash Lwt_stream.t * Tezos_rpc.Context.stopper) + (Dac_plugin.raw_hash Lwt_stream.t * Tezos_rpc.Context.stopper) Error_monad.tzresult Lwt.t val certificate : #Tezos_rpc.Context.streamed -> - Dac_plugin.t -> - Dac_plugin.hash -> + Dac_plugin.raw_hash -> (Certificate_repr.t Lwt_stream.t * Tezos_rpc.Context.stopper) Error_monad.tzresult Lwt.t diff --git a/src/lib_dac_node/node_context.ml b/src/lib_dac_node/node_context.ml index ca03c4723d7f981578150d0f32e9a23d45b5d6ea..47416656e5b0b23f10adaa8b6f111d5c28dee9ce 100644 --- a/src/lib_dac_node/node_context.ml +++ b/src/lib_dac_node/node_context.ml @@ -32,7 +32,7 @@ type dac_plugin_module = (module Dac_plugin.T) module Coordinator = struct type t = { committee_members : Wallet_account.Coordinator.t list; - hash_streamer : Dac_plugin.hash Data_streamer.t; + hash_streamer : Dac_plugin.raw_hash Data_streamer.t; (* FIXME: https://gitlab.com/tezos/tezos/-/issues/4895 This could be problematic in case coordinator and member/observer use two different plugins that bind different underlying hashes. *) @@ -116,7 +116,7 @@ module Legacy = struct type t = { committee_members : Wallet_account.Legacy.t list; coordinator_cctxt : Dac_node_client.cctxt option; - hash_streamer : Dac_plugin.hash Data_streamer.t; + hash_streamer : Dac_plugin.raw_hash Data_streamer.t; committee_member_opt : Wallet_account.Legacy.t option; } diff --git a/src/lib_dac_node/node_context.mli b/src/lib_dac_node/node_context.mli index d27bb2869a0dab1987405da662ee8636317f3de1..132354bfaebc2944ddd9922608015b8cc91efadd 100644 --- a/src/lib_dac_node/node_context.mli +++ b/src/lib_dac_node/node_context.mli @@ -34,7 +34,7 @@ module Coordinator : sig (** The list of [Wallet.Coordinator] values associated with the Data Availability Committee members managed by the [Coordinator] node. *) - hash_streamer : Dac_plugin.hash Data_streamer.t; + hash_streamer : Dac_plugin.raw_hash Data_streamer.t; (** The [Dac_plugin.hash Data_streamer.t] that the [Coordinator] node use to advertise root hashes to [Committee_member] and [Observer] nodes. *) @@ -95,7 +95,7 @@ module Legacy : sig enables a [Legacy] node to act as if it were an [Observer], using the associated [Dac_node_client.cctxt] value to send requests to a [Coordinator] node. *) - hash_streamer : Dac_plugin.hash Data_streamer.t; + hash_streamer : Dac_plugin.raw_hash Data_streamer.t; (** A [Dac_plugin.hash Data_streamer.t] that the [Legacy] node use to advertise root hashes to other nodes *) committee_member_opt : Wallet_account.Legacy.t option; diff --git a/src/lib_dac_node/page_store.ml b/src/lib_dac_node/page_store.ml index a9e590532ba8cf8e605e6c4f3b20514337429662..a7045287d27687b202244a55dfaaeb8985f660c3 100644 --- a/src/lib_dac_node/page_store.ml +++ b/src/lib_dac_node/page_store.ml @@ -30,8 +30,8 @@ type error += | Cannot_write_page_to_page_storage of {hash : string; content : bytes} | Cannot_read_page_from_page_storage of string | Incorrect_page_hash of { - expected : Dac_plugin.hash; - actual : Dac_plugin.hash; + expected : Dac_plugin.raw_hash; + actual : Dac_plugin.raw_hash; } let () = @@ -102,13 +102,13 @@ let () = ppf "Hash of page content is %a, while %a was expected." Format.pp_print_bytes - (Dac_plugin.hash_to_bytes expected) + (Dac_plugin.raw_hash_to_bytes expected) Format.pp_print_bytes - (Dac_plugin.hash_to_bytes actual)) + (Dac_plugin.raw_hash_to_bytes actual)) Data_encoding.( obj2 - (req "expected" Dac_plugin.non_proto_encoding_unsafe) - (req "acual" Dac_plugin.non_proto_encoding_unsafe)) + (req "expected" Dac_plugin.raw_hash_encoding) + (req "acual" Dac_plugin.raw_hash_encoding)) (function | Incorrect_page_hash {expected; actual} -> Some (expected, actual) | _ -> None) @@ -158,9 +158,9 @@ module Filesystem : S with type configuration = string = struct let path data_dir hash_string_key = Filename.(concat data_dir @@ hash_string_key) - let save ((module P) : Dac_plugin.t) data_dir ~hash ~content = + let save ((module Plugin) : Dac_plugin.t) data_dir ~hash ~content = let open Lwt_result_syntax in - let hash_string = P.to_hex hash in + let hash_string = Plugin.to_hex hash in let path = path data_dir hash_string in let*! result = Lwt_utils_unix.with_atomic_open_out path @@ fun chan -> @@ -172,9 +172,9 @@ module Filesystem : S with type configuration = string = struct tzfail @@ Cannot_write_page_to_page_storage {hash = hash_string; content} - let mem ((module P) : Dac_plugin.t) data_dir hash = + let mem ((module Plugin) : Dac_plugin.t) data_dir hash = let open Lwt_result_syntax in - let hash_string = P.to_hex hash in + let hash_string = Plugin.to_hex hash in let path = path data_dir hash_string in let*! result = Lwt_utils_unix.with_open_in path (fun _fd -> Lwt.return ()) @@ -184,9 +184,9 @@ module Filesystem : S with type configuration = string = struct | Error {unix_code = Unix.ENOENT; _} -> return false | Error _ -> tzfail @@ Cannot_read_page_from_page_storage hash_string - let load ((module P) : Dac_plugin.t) data_dir hash = + let load ((module Plugin) : Dac_plugin.t) data_dir hash = let open Lwt_result_syntax in - let hash_string = P.to_hex hash in + let hash_string = Plugin.to_hex hash in let path = path data_dir hash_string in Lwt.catch (fun () -> @@ -209,7 +209,12 @@ module With_data_integrity_check (P : S) : let scheme = Plugin.scheme_of_hash hash in let content_hash = Plugin.hash_bytes [content] ~scheme in if not @@ Plugin.equal hash content_hash then - tzfail @@ Incorrect_page_hash {expected = hash; actual = content_hash} + tzfail + @@ Incorrect_page_hash + { + expected = Dac_plugin.hash_to_raw hash; + actual = Dac_plugin.hash_to_raw content_hash; + } else P.save plugin page_store ~hash ~content let mem = P.mem @@ -244,7 +249,6 @@ end) let load plugin (remote_ctxt, page_store) hash = let open Lwt_result_syntax in - let (module Plugin : Dac_plugin.T) = plugin in let* page_exists_in_store = mem plugin (remote_ctxt, page_store) hash in if page_exists_in_store then P.load plugin page_store hash else @@ -269,8 +273,10 @@ module Remote : S with type configuration = remote_configuration = struct (struct type remote_context = Dac_node_client.cctxt - let fetch dac_plugin remote_context hash = - Dac_node_client.get_preimage dac_plugin remote_context ~page_hash:hash + let fetch _dac_plugin remote_context hash = + Dac_node_client.get_preimage + remote_context + ~page_hash:(Dac_plugin.hash_to_raw hash) end) (F) diff --git a/src/lib_dac_node/page_store.mli b/src/lib_dac_node/page_store.mli index 3fddf244a00817279814e634ba845ef95917a98f..97ce6e12174e2af680ea63568be63cc286a07312 100644 --- a/src/lib_dac_node/page_store.mli +++ b/src/lib_dac_node/page_store.mli @@ -30,8 +30,8 @@ type error += | Cannot_write_page_to_page_storage of {hash : string; content : bytes} | Cannot_read_page_from_page_storage of string | Incorrect_page_hash of { - expected : Dac_plugin.hash; - actual : Dac_plugin.hash; + expected : Dac_plugin.raw_hash; + actual : Dac_plugin.raw_hash; } (** [S] is the module type defining the backend required for diff --git a/src/lib_dac_node/pages_encoding.ml b/src/lib_dac_node/pages_encoding.ml index 7aef36ff1080f1feab9c7a03825229688faea871..7c090bea980bac744d0b8d4b2d092e89dfdf7885 100644 --- a/src/lib_dac_node/pages_encoding.ml +++ b/src/lib_dac_node/pages_encoding.ml @@ -2,7 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2022-2023 Trili Tech *) -(* Copyright (c) 2022 Marigold *) +(* Copyright (c) 2022-2023 Marigold *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -220,18 +220,19 @@ module Merkle_tree = struct type page_store = S.t - let hash ((module P) : Dac_plugin.t) bytes = - P.hash_bytes [bytes] ~scheme:Blake2B + let hash ((module Plugin) : Dac_plugin.t) bytes = + Plugin.hash_bytes [bytes] ~scheme:Blake2B - let hashes_encoding ((module P) : Dac_plugin.t) = - Data_encoding.list P.encoding + let hashes_encoding ((module Plugin) : Dac_plugin.t) = + Data_encoding.list Plugin.encoding (** The preamble of a serialized page contains 1 byte denoting the version, and 4 bytes encoding the size of the rest of the page. In total, 5 bytes. *) let page_preamble_size = 5 - let hash_bytes_size ((module P) : Dac_plugin.t) = P.size ~scheme:Blake2B + let hash_bytes_size ((module Plugin) : Dac_plugin.t) = + Plugin.size ~scheme:Blake2B (** Payload pages are encoded as follows: the first byte is an integer, which corresponds to either [content_version_tag] (for payload pages) @@ -571,14 +572,14 @@ module Hash_chain = struct module V0 = struct type page = {succ_hash : Dac_plugin.hash; content : string} - let hash ((module P) : Dac_plugin.t) bytes = - P.hash_bytes ~scheme:Blake2B [bytes] + let hash ((module Plugin) : Dac_plugin.t) bytes = + Plugin.hash_bytes ~scheme:Blake2B [bytes] let content_limit = (4 * 1024) - 100 (* We reserve 100 bytes for the continuation hash. *) - let serialize_page ((module P) : Dac_plugin.t) page = - Format.asprintf "%s hash:%s" page.content (P.to_hex page.succ_hash) + let serialize_page ((module Plugin) : Dac_plugin.t) page = + Format.asprintf "%s hash:%s" page.content (Plugin.to_hex page.succ_hash) let link_chunks dac_plugin chunks : (Dac_plugin.hash * bytes) list = let rec link_chunks_rev linked_pages rev_pages = diff --git a/src/lib_dac_node/pages_encoding.mli b/src/lib_dac_node/pages_encoding.mli index 8967b2a01e1e4c4b1b4dc0563aca6e127932b1cd..662d27731ff8372a9e442a41325d99b8bd95eac8 100644 --- a/src/lib_dac_node/pages_encoding.mli +++ b/src/lib_dac_node/pages_encoding.mli @@ -2,6 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2022-2023 Trili Tech *) +(* Copyright (c) 2023 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) diff --git a/src/lib_dac_node/signature_manager.ml b/src/lib_dac_node/signature_manager.ml index 053e3cfce77f6845e9e240e12323200abe025c9c..5fef6f9aa1d2d5224b70738cf6cc774f20ab90c8 100644 --- a/src/lib_dac_node/signature_manager.ml +++ b/src/lib_dac_node/signature_manager.ml @@ -117,10 +117,13 @@ let compute_signatures_with_witnesses rev_indexed_signatures = ([], Z.zero) rev_indexed_signatures -let sign_root_hash ((module P) : Dac_plugin.t) cctxt dac_sk_uris root_hash = +let sign_root_hash ((module Plugin) : Dac_plugin.t) cctxt dac_sk_uris root_hash + = let open Lwt_result_syntax in - let bytes_to_sign = Data_encoding.Binary.to_bytes_opt P.encoding root_hash in - let root_hash = P.to_hex root_hash in + let bytes_to_sign = + Data_encoding.Binary.to_bytes_opt Plugin.encoding root_hash + in + let root_hash = Plugin.to_hex root_hash in match bytes_to_sign with | None -> tzfail @@ Cannot_convert_root_page_hash_to_bytes root_hash | Some bytes_to_sign -> ( @@ -136,15 +139,16 @@ let sign_root_hash ((module P) : Dac_plugin.t) cctxt dac_sk_uris root_hash = | None -> tzfail @@ Cannot_compute_aggregate_signature root_hash | Some signature -> return @@ (signature, witnesses)) -let verify ((module P) : Dac_plugin.t) ~public_keys_opt root_page_hash signature - witnesses = +let verify dac_plugin ~public_keys_opt root_page_hash signature witnesses = let open Lwt_result_syntax in + let ((module Plugin) : Dac_plugin.t) = dac_plugin in + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin root_page_hash in let hash_as_bytes = - Data_encoding.Binary.to_bytes_opt P.encoding root_page_hash + Data_encoding.Binary.to_bytes_opt Plugin.encoding root_hash in + let hex_root_hash = Plugin.to_hex root_hash in match hash_as_bytes with - | None -> - tzfail @@ Cannot_convert_root_page_hash_to_bytes (P.to_hex root_page_hash) + | None -> tzfail @@ Cannot_convert_root_page_hash_to_bytes hex_root_hash | Some bytes -> let* pk_msg_list = public_keys_opt @@ -155,8 +159,7 @@ let verify ((module P) : Dac_plugin.t) ~public_keys_opt root_page_hash signature | None -> if is_witness then tzfail - @@ Public_key_for_witness_not_available - (i, P.to_hex root_page_hash) + @@ Public_key_for_witness_not_available (i, hex_root_hash) else return None | Some public_key -> if is_witness then return @@ Some (public_key, None, bytes) @@ -256,14 +259,16 @@ module Coordinator = struct (function Unknown_root_hash hash -> Some hash | _ -> None) (fun hash -> Unknown_root_hash hash) - let verify_signature ((module P) : Dac_plugin.t) pk signature root_hash = + let verify_signature ((module Plugin) : Dac_plugin.t) pk signature root_hash = let root_hash_bytes = Dac_plugin.hash_to_bytes root_hash in fail_unless (Aggregate_signature.check pk signature root_hash_bytes) - (Signature_verification_failed (pk, signature, P.to_hex root_hash)) + (Signature_verification_failed (pk, signature, Plugin.to_hex root_hash)) - let add_dac_member_signature ((module Plugin) : Dac_plugin.t) signature_store + let add_dac_member_signature dac_plugin signature_store Signature_repr.{root_hash; signer_pkh; signature} = + let open Lwt_result_syntax in + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin root_hash in Store.Signature_store.add signature_store ~primary_key:root_hash @@ -283,8 +288,7 @@ module Coordinator = struct Option.map (fun signature -> (index, signature)) signature_opt) dac_members_pk - let update_aggregate_sig_store ((module P) : Dac_plugin.t) node_store - dac_members_pk_opt root_hash = + let update_aggregate_sig_store node_store dac_members_pk_opt root_hash = let open Lwt_result_syntax in let* rev_indexed_signature = rev_find_indexed_signatures node_store dac_members_pk_opt root_hash @@ -308,8 +312,7 @@ module Coordinator = struct in return @@ (aggregate_signature, witnesses) - let check_dac_member_has_signed ((module P) : Dac_plugin.t) signature_store - root_hash dac_member_pkh = + let check_dac_member_has_signed signature_store root_hash dac_member_pkh = let open Lwt_result_syntax in let* dac_member_has_signed = Store.Signature_store.mem @@ -325,9 +328,10 @@ module Coordinator = struct (fun pkh -> Aggregate_signature.Public_key_hash.equal signer_pkh pkh) dac_committee - let check_coordinator_knows_root_hash ((module Plugin) : Dac_plugin.t) - page_store root_hash = + let check_coordinator_knows_root_hash dac_plugin page_store raw_root_hash = let open Lwt_result_syntax in + let ((module Plugin) : Dac_plugin.t) = dac_plugin in + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin raw_root_hash in let*! has_payload = Page_store.Filesystem.mem (module Plugin) page_store root_hash in @@ -342,7 +346,9 @@ module Coordinator = struct let should_update_certificate dac_plugin cctxt ro_node_store committee_members Signature_repr.{signer_pkh; root_hash; signature} = + let ((module Plugin) : Dac_plugin.t) = dac_plugin in let open Lwt_result_syntax in + let*? root_hash = Dac_plugin.raw_to_hash dac_plugin root_hash in let* () = fail_unless (check_is_dac_member committee_members signer_pkh) @@ -357,24 +363,33 @@ module Coordinator = struct pub_key_opt in let* dac_member_has_signed = - check_dac_member_has_signed dac_plugin ro_node_store root_hash signer_pkh + check_dac_member_has_signed ro_node_store root_hash signer_pkh in if dac_member_has_signed then return false else let* () = verify_signature dac_plugin pub_key signature root_hash in return true - let stream_certificate_update committee_members + let stream_certificate_update dac_plugin committee_members (Certificate_repr.{root_hash; _} as certificate) certificate_streamers = - Certificate_streamers.push certificate_streamers root_hash certificate ; + let open Result_syntax in + let* () = + Certificate_streamers.push + dac_plugin + certificate_streamers + root_hash + certificate + in if Certificate_repr.all_committee_members_have_signed committee_members certificate then - let _ = Certificate_streamers.close certificate_streamers root_hash in - () - else () + let _ = + Certificate_streamers.close dac_plugin certificate_streamers root_hash + in + return () + else return () let handle_put_dac_member_signature ctx cctxt committee_member_signature = let open Lwt_result_syntax in @@ -394,7 +409,6 @@ module Coordinator = struct failwith "Operation not supported for operating mode" in let*? dac_plugin = Node_context.get_dac_plugin ctx in - let ((module Plugin) : Dac_plugin.t) = dac_plugin in let page_store = Node_context.get_page_store ctx in let*? committee_members = Node_context.get_committee_members ctx in let rw_node_store = Node_context.get_node_store ctx Store_sigs.Read_write in @@ -417,18 +431,18 @@ module Coordinator = struct rw_node_store committee_member_signature in + let*? root_hash' = Dac_plugin.raw_to_hash dac_plugin root_hash in let* aggregate_signature, witnesses = - update_aggregate_sig_store - dac_plugin - rw_node_store - committee_members - root_hash + update_aggregate_sig_store rw_node_store committee_members root_hash' in - return - @@ Option.iter - (stream_certificate_update - committee_members - Certificate_repr.{root_hash; aggregate_signature; witnesses}) - certificate_streamers_opt + let*? () = + Option.iter_e + (stream_certificate_update + dac_plugin + committee_members + Certificate_repr.{root_hash; aggregate_signature; witnesses}) + certificate_streamers_opt + in + return () else return () end diff --git a/src/lib_dac_node/signature_manager.mli b/src/lib_dac_node/signature_manager.mli index 4f77d23647a61e547a7edddd7e3075de34e08119..5e9288cc2c11715843d06be1108a6228ff5429c6 100644 --- a/src/lib_dac_node/signature_manager.mli +++ b/src/lib_dac_node/signature_manager.mli @@ -47,7 +47,7 @@ val sign_root_hash : val verify : Dac_plugin.t -> public_keys_opt:Tezos_crypto.Aggregate_signature.public_key option trace -> - Dac_plugin.hash -> + Dac_plugin.raw_hash -> Tezos_crypto.Aggregate_signature.signature -> Z.t -> (bool, tztrace) result Lwt.t diff --git a/src/proto_017_PtNairob/lib_dac_plugin/dac_plugin_registration.ml b/src/proto_017_PtNairob/lib_dac_plugin/dac_plugin_registration.ml index dfe9d670233eb0cb45797354e9ade7e06855482f..e7a6f4860ca6987d75e1036a7ff4cb16b38b9170 100644 --- a/src/proto_017_PtNairob/lib_dac_plugin/dac_plugin_registration.ml +++ b/src/proto_017_PtNairob/lib_dac_plugin/dac_plugin_registration.ml @@ -92,20 +92,6 @@ end) : Dac_plugin.T = struct Protocol.Sc_rollup_reveal_hash.size ~scheme:(dac_hash_to_proto_supported_hashes scheme) - let hash_rpc_arg = - let construct = to_hex in - let destruct hash = - match of_hex hash with - | None -> Error "Cannot parse reveal hash" - | Some reveal_hash -> Ok reveal_hash - in - Tezos_rpc.Arg.make - ~descr:"A reveal hash" - ~name:"reveal_hash" - ~destruct - ~construct - () - module Proto = Registerer.Registered end diff --git a/src/proto_017_PtNairob/lib_dac_plugin/test/test_dac_pages_encoding.ml b/src/proto_017_PtNairob/lib_dac_plugin/test/test_dac_pages_encoding.ml index 6370488c1ad763fe7375b653517d2b238b9c80b0..a9483a551538dbf4837de8678c675074601cc3e8 100644 --- a/src/proto_017_PtNairob/lib_dac_plugin/test/test_dac_pages_encoding.ml +++ b/src/proto_017_PtNairob/lib_dac_plugin/test/test_dac_pages_encoding.ml @@ -2,6 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2022-2023 Trili Tech *) +(* Copyright (c) 2023 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -46,11 +47,7 @@ let dac_plugin = Stdlib.Option.get (Dac_plugin.get Protocol.hash) module Hashes_map = Map.Make (struct type t = Dac_plugin.hash - let compare h1 h2 = - let (module Dac_plugin) = dac_plugin in - let s1 = Dac_plugin.to_hex h1 in - let s2 = Dac_plugin.to_hex h2 in - String.compare s1 s2 + let compare h1 h2 = Dac_plugin.raw_compare h1 h2 end) type hashes_map = bytes Hashes_map.t @@ -203,21 +200,21 @@ module Hashes_map_backend = struct let init () = ref Hashes_map.empty - type error += Page_is_missing of Dac_plugin.hash + type error += Page_is_missing of Dac_plugin.raw_hash - let save (_plugin : Dac_plugin.t) t ~hash ~content = + let save (_plugin : Dac_plugin.t) t ~(hash : Dac_plugin.hash) ~content = let open Lwt_result_syntax in let () = t := Hashes_map.add hash content !t in return () - let mem (_plugin : Dac_plugin.t) t hash = + let mem (_plugin : Dac_plugin.t) t (hash : Dac_plugin.hash) = Lwt_result_syntax.return @@ Hashes_map.mem hash !t let load (_plugin : Dac_plugin.t) t hash = let open Lwt_result_syntax in let bytes = Hashes_map.find hash !t in match bytes with - | None -> tzfail @@ Page_is_missing hash + | None -> tzfail @@ Page_is_missing (Dac_plugin.hash_to_raw hash) | Some bytes -> return bytes let number_of_pages t = List.length @@ Hashes_map.bindings !t @@ -444,7 +441,10 @@ module Merkle_tree = struct ~page_store root_hash) (Page_store.Incorrect_page_hash - {expected = root_hash; actual = root_hash_of_corrupt_payload}) + { + expected = Dac_plugin.hash_to_raw root_hash; + actual = Dac_plugin.hash_to_raw root_hash_of_corrupt_payload; + }) in (* Check that pages have not been copied from the remote mock store to the local one. *) diff --git a/src/proto_alpha/lib_dac_plugin/dac_plugin_registration.ml b/src/proto_alpha/lib_dac_plugin/dac_plugin_registration.ml index dfe9d670233eb0cb45797354e9ade7e06855482f..735e96fc78c183917cabded95926538dbccc02e7 100644 --- a/src/proto_alpha/lib_dac_plugin/dac_plugin_registration.ml +++ b/src/proto_alpha/lib_dac_plugin/dac_plugin_registration.ml @@ -3,6 +3,7 @@ (* Open Source License *) (* Copyright (c) 2022 Nomadic Labs, *) (* Copyright (c) 2023 TriliTech, *) +(* Copyright (c) 2023 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -92,20 +93,6 @@ end) : Dac_plugin.T = struct Protocol.Sc_rollup_reveal_hash.size ~scheme:(dac_hash_to_proto_supported_hashes scheme) - let hash_rpc_arg = - let construct = to_hex in - let destruct hash = - match of_hex hash with - | None -> Error "Cannot parse reveal hash" - | Some reveal_hash -> Ok reveal_hash - in - Tezos_rpc.Arg.make - ~descr:"A reveal hash" - ~name:"reveal_hash" - ~destruct - ~construct - () - module Proto = Registerer.Registered end diff --git a/src/proto_alpha/lib_dac_plugin/test/test_dac_pages_encoding.ml b/src/proto_alpha/lib_dac_plugin/test/test_dac_pages_encoding.ml index 555dff35f6e373ef6c14a3dc77300845c257c99e..2a6018905deccb04d4f06bcbf7aa9cd8c1df572a 100644 --- a/src/proto_alpha/lib_dac_plugin/test/test_dac_pages_encoding.ml +++ b/src/proto_alpha/lib_dac_plugin/test/test_dac_pages_encoding.ml @@ -2,6 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2022-2023 Trili Tech *) +(* Copyright (c) 2023 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -46,11 +47,7 @@ let dac_plugin = Stdlib.Option.get (Dac_plugin.get Protocol.hash) module Hashes_map = Map.Make (struct type t = Dac_plugin.hash - let compare h1 h2 = - let (module Dac_plugin) = dac_plugin in - let s1 = Dac_plugin.to_hex h1 in - let s2 = Dac_plugin.to_hex h2 in - String.compare s1 s2 + let compare h1 h2 = Dac_plugin.raw_compare h1 h2 end) type hashes_map = bytes Hashes_map.t @@ -203,21 +200,21 @@ module Hashes_map_backend = struct let init () = ref Hashes_map.empty - type error += Page_is_missing of Dac_plugin.hash + type error += Page_is_missing of Dac_plugin.raw_hash - let save (_plugin : Dac_plugin.t) t ~hash ~content = + let save (_plugin : Dac_plugin.t) t ~(hash : Dac_plugin.hash) ~content = let open Lwt_result_syntax in let () = t := Hashes_map.add hash content !t in return () - let mem (_plugin : Dac_plugin.t) t hash = + let mem (_plugin : Dac_plugin.t) t (hash : Dac_plugin.hash) = Lwt_result_syntax.return @@ Hashes_map.mem hash !t let load (_plugin : Dac_plugin.t) t hash = let open Lwt_result_syntax in let bytes = Hashes_map.find hash !t in match bytes with - | None -> tzfail @@ Page_is_missing hash + | None -> tzfail @@ Page_is_missing (Dac_plugin.hash_to_raw hash) | Some bytes -> return bytes let number_of_pages t = List.length @@ Hashes_map.bindings !t @@ -444,7 +441,10 @@ module Merkle_tree = struct ~page_store root_hash) (Page_store.Incorrect_page_hash - {expected = root_hash; actual = root_hash_of_corrupt_payload}) + { + expected = Dac_plugin.hash_to_raw root_hash; + actual = Dac_plugin.hash_to_raw root_hash_of_corrupt_payload; + }) in (* Check that pages have not been copied from the remote mock store to the local one. *)