From a89ef23dd549e7c8f4723556b7f414ddb2aac187 Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Mon, 26 May 2025 11:32:42 +0200 Subject: [PATCH 1/7] API: add a result type for hash outputs --- server/lib/directory.ml | 8 +++++--- server/lib/rollup_node_client.ml | 20 ++++++++++++++++---- server/lib/rollup_node_client.mli | 8 +++++++- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/server/lib/directory.ml b/server/lib/directory.ml index 38675c2..48edeb0 100644 --- a/server/lib/directory.ml +++ b/server/lib/directory.ml @@ -180,11 +180,13 @@ module External_message = struct end module Notarize_hash = struct - let service : (string, unit, _, Security.scheme) post_service0 = + let service : + (string, Rollup_node_client.result_rpc, _, Security.scheme) post_service0 + = post_service ~section ~name:"Notarize a hash" ~descr:"Notarize a hash with pandora" ~input:Encoding.hex_string - ~input_example:Encoding.hash_example ~output:Encoding.unit - ~output_example:() + ~input_example:Encoding.hash_example ~output:Encoding.result_rpc_encoding + ~output_example:Encoding.result_rpc_example Path.(root // "notarize" // "hash") let handler state _params _ hash = Rollup_node_client.notarize_hash state hash diff --git a/server/lib/rollup_node_client.ml b/server/lib/rollup_node_client.ml index af5cbee..5ed9b58 100644 --- a/server/lib/rollup_node_client.ml +++ b/server/lib/rollup_node_client.ml @@ -26,6 +26,8 @@ type hash_ts = { type hashes_ts = hash_ts list +type result_rpc = { result : string } + module Encoding = struct open Json_encoding @@ -70,6 +72,12 @@ module Encoding = struct let hashes_ts = conv Fun.id Fun.id (list hash_ts) let unit = conv Fun.id Fun.id unit + + let result_rpc_encoding = + conv (fun { result } -> result) (fun result -> { result }) + @@ obj1 (req "result" string) + + let result_rpc_example = { result = "Success" } end module Arg = struct @@ -237,13 +245,17 @@ let make_external_message state hash = let notarize_hash state hash = let external_message = make_external_message state hash in - let+? ids = inject_messages state.config [external_message] in + let* ids = inject_messages state.config [external_message] in match ids with - | [_id] -> + | Ok [_id] -> (* TODO: Return the id when the feature to track the id is implemented. See https://gitlab.com/functori/dev/pandora/-/issues/38. *) - () - | _ -> assert false + Lwt.return_ok { result = "The notarization succeeded" } + | Ok [] -> Lwt.return_ok { result = "Internal API error, no id was returned" } + | Ok _ -> Lwt.return_ok { result = "Internal API error, too many ids" } + | Error error -> + Lwt.return_ok + { result = Format.sprintf "The notarization failed because of %s" error } let notarization_status config ?block hash = let (Base58 hash_b58) = Document_hash.(to_base58 (V hash)) in diff --git a/server/lib/rollup_node_client.mli b/server/lib/rollup_node_client.mli index 28495a3..9ddebbd 100644 --- a/server/lib/rollup_node_client.mli +++ b/server/lib/rollup_node_client.mli @@ -27,6 +27,8 @@ type hash_ts = { (** List of hash and associated timestamp *) type hashes_ts = hash_ts list +type result_rpc = { result : string } + module Encoding : sig val timestamp : Ptime.t Json_encoding.encoding @@ -43,6 +45,10 @@ module Encoding : sig val hashes_ts : hashes_ts Json_encoding.encoding val unit : unit Json_encoding.encoding + + val result_rpc_encoding : result_rpc Json_encoding.encoding + + val result_rpc_example : result_rpc end module Arg : sig @@ -86,7 +92,7 @@ val get_balance : val make_external_message : State.t -> string -> string (** Notarizes a hash on pandora and returns the id to follow the status *) -val notarize_hash : State.t -> string -> (unit, string) Lwt_result.t +val notarize_hash : State.t -> string -> (result_rpc, string) Lwt_result.t (** Returns the notarization status for a given hash. *) val notarization_status : -- GitLab From 932f404a93cb5238cc99b6330f64833a79f7666c Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Mon, 26 May 2025 14:42:53 +0200 Subject: [PATCH 2/7] API: user-friendly hash error Implem. is quite hack-ish but UX-wise, better than what we had. --- server/lib/directory.ml | 2 +- server/lib/rollup_node_client.ml | 42 +++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/server/lib/directory.ml b/server/lib/directory.ml index 48edeb0..cdfb526 100644 --- a/server/lib/directory.ml +++ b/server/lib/directory.ml @@ -184,7 +184,7 @@ module Notarize_hash = struct (string, Rollup_node_client.result_rpc, _, Security.scheme) post_service0 = post_service ~section ~name:"Notarize a hash" - ~descr:"Notarize a hash with pandora" ~input:Encoding.hex_string + ~descr:"Notarize a hash with pandora" ~input:Json_encoding.string ~input_example:Encoding.hash_example ~output:Encoding.result_rpc_encoding ~output_example:Encoding.result_rpc_example Path.(root // "notarize" // "hash") diff --git a/server/lib/rollup_node_client.ml b/server/lib/rollup_node_client.ml index 5ed9b58..0ec0fb0 100644 --- a/server/lib/rollup_node_client.ml +++ b/server/lib/rollup_node_client.ml @@ -244,18 +244,36 @@ let make_external_message state hash = ] let notarize_hash state hash = - let external_message = make_external_message state hash in - let* ids = inject_messages state.config [external_message] in - match ids with - | Ok [_id] -> - (* TODO: Return the id when the feature to track the id is implemented. See - https://gitlab.com/functori/dev/pandora/-/issues/38. *) - Lwt.return_ok { result = "The notarization succeeded" } - | Ok [] -> Lwt.return_ok { result = "Internal API error, no id was returned" } - | Ok _ -> Lwt.return_ok { result = "Internal API error, too many ids" } - | Error error -> - Lwt.return_ok - { result = Format.sprintf "The notarization failed because of %s" error } + if String.length hash != 64 then + Lwt.return_ok { result = "Invalid hash, it must be a 32 bytes hash" } + else + let result = + try + let hash = Hex.of_string hash in + let hash = Hex.to_string hash in + Ok hash + with _ -> + Error (Format.sprintf "Invalid hash, must be an hexadecimal value") + in + match result with + | Error msg -> Lwt.return_ok { result = msg } + | Ok hash -> ( + let external_message = make_external_message state hash in + let* ids = inject_messages state.config [external_message] in + match ids with + | Ok [_id] -> + (* TODO: Return the id when the feature to track the id is implemented. + See https://gitlab.com/functori/dev/pandora/-/issues/38. *) + Lwt.return_ok { result = "The notarization succeeded" } + | Ok [] -> + Lwt.return_ok { result = "Internal API error, no id was returned" } + | Ok _ -> Lwt.return_ok { result = "Internal API error, too many ids" } + | Error error -> + Lwt.return_ok + { + result = + Format.sprintf "The notarization failed because of %s" error; + }) let notarization_status config ?block hash = let (Base58 hash_b58) = Document_hash.(to_base58 (V hash)) in -- GitLab From 7b3e1d52dd89a39379e65f3e2ce69ecf3549bb3b Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Mon, 26 May 2025 15:02:52 +0200 Subject: [PATCH 3/7] API: better result output --- server/lib/rollup_node_client.ml | 89 ++++++++++++++++++++----------- server/lib/rollup_node_client.mli | 9 +++- 2 files changed, 65 insertions(+), 33 deletions(-) diff --git a/server/lib/rollup_node_client.ml b/server/lib/rollup_node_client.ml index 0ec0fb0..1aa4ed1 100644 --- a/server/lib/rollup_node_client.ml +++ b/server/lib/rollup_node_client.ml @@ -26,7 +26,27 @@ type hash_ts = { type hashes_ts = hash_ts list -type result_rpc = { result : string } +type result_rpc_kind = + | Success + | Err + +let result_rpc_kind_to_string = function + | Success -> "success" + | Err -> "error" + +let result_rpc_kind_of_string = function + | "success" -> Success + | "error" -> Err + | _ -> failwith "Not a [result_rpc_kind]" + +type result_rpc = { + result : result_rpc_kind; + reason : string option; +} + +let result_rpc_return_success = { result = Success; reason = None } + +let result_rpc_return_error reason = { result = Err; reason = Some reason } module Encoding = struct open Json_encoding @@ -73,11 +93,16 @@ module Encoding = struct let unit = conv Fun.id Fun.id unit + let result_rpc_kind = + conv result_rpc_kind_to_string result_rpc_kind_of_string string + let result_rpc_encoding = - conv (fun { result } -> result) (fun result -> { result }) - @@ obj1 (req "result" string) + conv + (fun { result; reason } -> (result, reason)) + (fun (result, reason) -> { result; reason }) + (obj2 (req "result" result_rpc_kind) (opt "reason" string)) - let result_rpc_example = { result = "Success" } + let result_rpc_example = { result = Success; reason = None } end module Arg = struct @@ -243,37 +268,37 @@ let make_external_message state hash = signature; ] +let is_valid_hex s = + let is_hex_char = function + | '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' -> true + | _ -> false in + String.length s mod 2 = 0 && String.for_all is_hex_char s + let notarize_hash state hash = if String.length hash != 64 then - Lwt.return_ok { result = "Invalid hash, it must be a 32 bytes hash" } + Lwt.return_ok + @@ result_rpc_return_error "Invalid hash, it must be a 32 bytes hash" + else if not (is_valid_hex hash) then + Lwt.return_ok + @@ result_rpc_return_error "Invalid hash, must be a valid hexadecimal value" else - let result = - try - let hash = Hex.of_string hash in - let hash = Hex.to_string hash in - Ok hash - with _ -> - Error (Format.sprintf "Invalid hash, must be an hexadecimal value") - in - match result with - | Error msg -> Lwt.return_ok { result = msg } - | Ok hash -> ( - let external_message = make_external_message state hash in - let* ids = inject_messages state.config [external_message] in - match ids with - | Ok [_id] -> - (* TODO: Return the id when the feature to track the id is implemented. - See https://gitlab.com/functori/dev/pandora/-/issues/38. *) - Lwt.return_ok { result = "The notarization succeeded" } - | Ok [] -> - Lwt.return_ok { result = "Internal API error, no id was returned" } - | Ok _ -> Lwt.return_ok { result = "Internal API error, too many ids" } - | Error error -> - Lwt.return_ok - { - result = - Format.sprintf "The notarization failed because of %s" error; - }) + let external_message = make_external_message state hash in + let* ids = inject_messages state.config [external_message] in + match ids with + | Ok [_id] -> + (* TODO: Return the id when the feature to track the id is implemented. + See https://gitlab.com/functori/dev/pandora/-/issues/38. *) + Lwt.return_ok result_rpc_return_success + | Ok [] -> + Lwt.return_ok + @@ result_rpc_return_error "Internal API error, no id was returned" + | Ok _ -> + Lwt.return_ok + @@ result_rpc_return_error "Internal API error, too many ids" + | Error error -> + Lwt.return_ok + @@ result_rpc_return_error + (Format.sprintf "The notarization failed because of %s" error) let notarization_status config ?block hash = let (Base58 hash_b58) = Document_hash.(to_base58 (V hash)) in diff --git a/server/lib/rollup_node_client.mli b/server/lib/rollup_node_client.mli index 9ddebbd..e00eb78 100644 --- a/server/lib/rollup_node_client.mli +++ b/server/lib/rollup_node_client.mli @@ -27,7 +27,14 @@ type hash_ts = { (** List of hash and associated timestamp *) type hashes_ts = hash_ts list -type result_rpc = { result : string } +type result_rpc_kind = + | Success + | Err + +type result_rpc = { + result : result_rpc_kind; + reason : string option; +} module Encoding : sig val timestamp : Ptime.t Json_encoding.encoding -- GitLab From aaf7115ef51be168e9ca97a6d950f7602d73800a Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Mon, 26 May 2025 15:25:18 +0200 Subject: [PATCH 4/7] testing --- server/lib/rollup_node_client.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/lib/rollup_node_client.ml b/server/lib/rollup_node_client.ml index 1aa4ed1..9e7ce16 100644 --- a/server/lib/rollup_node_client.ml +++ b/server/lib/rollup_node_client.ml @@ -276,10 +276,10 @@ let is_valid_hex s = let notarize_hash state hash = if String.length hash != 64 then - Lwt.return_ok + Lwt.return_error @@ result_rpc_return_error "Invalid hash, it must be a 32 bytes hash" else if not (is_valid_hex hash) then - Lwt.return_ok + Lwt.return_error @@ result_rpc_return_error "Invalid hash, must be a valid hexadecimal value" else let external_message = make_external_message state hash in -- GitLab From 518ca29d92aa6b3a11200b27f26b88c28b1084a1 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Mon, 26 May 2025 15:49:31 +0200 Subject: [PATCH 5/7] Revert "API: add a result type for hash outputs" This reverts commit 8170b8d6ea7b5412ffb876ea8d751c12fb5112ad. --- server/lib/directory.ml | 10 ++--- server/lib/rollup_node_client.ml | 71 ++++--------------------------- server/lib/rollup_node_client.mli | 15 +------ 3 files changed, 13 insertions(+), 83 deletions(-) diff --git a/server/lib/directory.ml b/server/lib/directory.ml index cdfb526..38675c2 100644 --- a/server/lib/directory.ml +++ b/server/lib/directory.ml @@ -180,13 +180,11 @@ module External_message = struct end module Notarize_hash = struct - let service : - (string, Rollup_node_client.result_rpc, _, Security.scheme) post_service0 - = + let service : (string, unit, _, Security.scheme) post_service0 = post_service ~section ~name:"Notarize a hash" - ~descr:"Notarize a hash with pandora" ~input:Json_encoding.string - ~input_example:Encoding.hash_example ~output:Encoding.result_rpc_encoding - ~output_example:Encoding.result_rpc_example + ~descr:"Notarize a hash with pandora" ~input:Encoding.hex_string + ~input_example:Encoding.hash_example ~output:Encoding.unit + ~output_example:() Path.(root // "notarize" // "hash") let handler state _params _ hash = Rollup_node_client.notarize_hash state hash diff --git a/server/lib/rollup_node_client.ml b/server/lib/rollup_node_client.ml index 9e7ce16..af5cbee 100644 --- a/server/lib/rollup_node_client.ml +++ b/server/lib/rollup_node_client.ml @@ -26,28 +26,6 @@ type hash_ts = { type hashes_ts = hash_ts list -type result_rpc_kind = - | Success - | Err - -let result_rpc_kind_to_string = function - | Success -> "success" - | Err -> "error" - -let result_rpc_kind_of_string = function - | "success" -> Success - | "error" -> Err - | _ -> failwith "Not a [result_rpc_kind]" - -type result_rpc = { - result : result_rpc_kind; - reason : string option; -} - -let result_rpc_return_success = { result = Success; reason = None } - -let result_rpc_return_error reason = { result = Err; reason = Some reason } - module Encoding = struct open Json_encoding @@ -92,17 +70,6 @@ module Encoding = struct let hashes_ts = conv Fun.id Fun.id (list hash_ts) let unit = conv Fun.id Fun.id unit - - let result_rpc_kind = - conv result_rpc_kind_to_string result_rpc_kind_of_string string - - let result_rpc_encoding = - conv - (fun { result; reason } -> (result, reason)) - (fun (result, reason) -> { result; reason }) - (obj2 (req "result" result_rpc_kind) (opt "reason" string)) - - let result_rpc_example = { result = Success; reason = None } end module Arg = struct @@ -268,37 +235,15 @@ let make_external_message state hash = signature; ] -let is_valid_hex s = - let is_hex_char = function - | '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' -> true - | _ -> false in - String.length s mod 2 = 0 && String.for_all is_hex_char s - let notarize_hash state hash = - if String.length hash != 64 then - Lwt.return_error - @@ result_rpc_return_error "Invalid hash, it must be a 32 bytes hash" - else if not (is_valid_hex hash) then - Lwt.return_error - @@ result_rpc_return_error "Invalid hash, must be a valid hexadecimal value" - else - let external_message = make_external_message state hash in - let* ids = inject_messages state.config [external_message] in - match ids with - | Ok [_id] -> - (* TODO: Return the id when the feature to track the id is implemented. - See https://gitlab.com/functori/dev/pandora/-/issues/38. *) - Lwt.return_ok result_rpc_return_success - | Ok [] -> - Lwt.return_ok - @@ result_rpc_return_error "Internal API error, no id was returned" - | Ok _ -> - Lwt.return_ok - @@ result_rpc_return_error "Internal API error, too many ids" - | Error error -> - Lwt.return_ok - @@ result_rpc_return_error - (Format.sprintf "The notarization failed because of %s" error) + let external_message = make_external_message state hash in + let+? ids = inject_messages state.config [external_message] in + match ids with + | [_id] -> + (* TODO: Return the id when the feature to track the id is implemented. See + https://gitlab.com/functori/dev/pandora/-/issues/38. *) + () + | _ -> assert false let notarization_status config ?block hash = let (Base58 hash_b58) = Document_hash.(to_base58 (V hash)) in diff --git a/server/lib/rollup_node_client.mli b/server/lib/rollup_node_client.mli index e00eb78..28495a3 100644 --- a/server/lib/rollup_node_client.mli +++ b/server/lib/rollup_node_client.mli @@ -27,15 +27,6 @@ type hash_ts = { (** List of hash and associated timestamp *) type hashes_ts = hash_ts list -type result_rpc_kind = - | Success - | Err - -type result_rpc = { - result : result_rpc_kind; - reason : string option; -} - module Encoding : sig val timestamp : Ptime.t Json_encoding.encoding @@ -52,10 +43,6 @@ module Encoding : sig val hashes_ts : hashes_ts Json_encoding.encoding val unit : unit Json_encoding.encoding - - val result_rpc_encoding : result_rpc Json_encoding.encoding - - val result_rpc_example : result_rpc end module Arg : sig @@ -99,7 +86,7 @@ val get_balance : val make_external_message : State.t -> string -> string (** Notarizes a hash on pandora and returns the id to follow the status *) -val notarize_hash : State.t -> string -> (result_rpc, string) Lwt_result.t +val notarize_hash : State.t -> string -> (unit, string) Lwt_result.t (** Returns the notarization status for a given hash. *) val notarization_status : -- GitLab From ea81c33d3d68c0b6cb15a6a34490a900eb2a844c Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Mon, 26 May 2025 16:38:59 +0200 Subject: [PATCH 6/7] better error messages --- server/lib/directory.ml | 89 +++++++++++++++++++++++-------- server/lib/rollup_node_client.ml | 6 ++- server/lib/rollup_node_client.mli | 26 ++++++--- server/lib/server.ml | 2 +- 4 files changed, 91 insertions(+), 32 deletions(-) diff --git a/server/lib/directory.ml b/server/lib/directory.ml index 38675c2..8deeae0 100644 --- a/server/lib/directory.ml +++ b/server/lib/directory.ml @@ -13,7 +13,11 @@ type no_error = | let directory = ref (fun _ -> EzAPIServer.empty) let handle_errors = function - | Error e -> EzAPIServer.return_error 502 ~content:e + | Error (`Internal_error _ as content) -> + EzAPIServer.return_error 502 ~content + | Error (`Bad_gateway_to_rollup_node _ as content) -> + EzAPIServer.return_error 502 ~content + | Error (`Invalid_input _ as content) -> EzAPIServer.return_error 400 ~content | Ok a -> EzAPIServer.return_ok a let register service handler = @@ -38,23 +42,50 @@ let register_no_error_service service handler = let section = Doc.section "pandora" -let errors = +let err_500 = let open Json_encoding in - [ - Err.make ~code:502 ~name:"bad_gateway" - ~encoding: - (obj2 - (req "error" (constant "bad_gateway_to_rollup_node")) - (opt "message" string)) - ~select:(fun s -> Some ((), s)) - ~deselect:(fun ((), s) -> s); - ] + Err.make ~code:500 ~name:"internal_error" + ~encoding: + (obj2 (req "error" (constant "internal_error")) (req "message" string)) + ~select:(function + | Some (`Internal_error e) -> Some ((), e) + | _ -> None) + ~deselect:(fun ((), e) -> Some (`Internal_error e)) + +let err_502 = + let open Json_encoding in + Err.make ~code:502 ~name:"bad_gateway" + ~encoding: + (obj2 + (req "error" (constant "bad_gateway_to_rollup_node")) + (req "message" string)) + ~select:(function + | Some (`Bad_gateway_to_rollup_node e) -> Some ((), e) + | _ -> None) + ~deselect:(fun ((), e) -> Some (`Bad_gateway_to_rollup_node e)) + +let err_400 = + let open Json_encoding in + Err.make ~code:400 ~name:"invalid_input" + ~encoding: + (obj2 (req "error" (constant "invalid_input")) (req "message" string)) + ~select:(function + | Some (`Invalid_input e) -> Some ((), e) + | _ -> None) + ~deselect:(fun ((), e) -> Some (`Invalid_input e)) let no_error_service = service ~errors:([] : no_error option Err.case list) -let service = service ~errors +let service ?(errors = [err_502]) ?section ?name ?descr ?meth ~output ?params + ?security ?access_control ?register ?output_example p = + service ~errors ?section ?name ?descr ?meth ~output ?params ?security + ?access_control ?register ?output_example p -let post_service = post_service ~errors +let post_service ?(errors = [err_502]) ?section ?name ?descr ?meth ~input + ~output ?params ?security ?access_control ?register ?input_example + ?output_example p = + post_service ~errors ?section ?name ?descr ?meth ~input ~output ?params + ?security ?access_control ?register ?input_example ?output_example p module Encoding = struct open Json_encoding @@ -64,6 +95,9 @@ module Encoding = struct def "mutez" ~title:"mutez" ~description:"Amount in mutez" @@ ranged_int53 ~minimum:0L ~maximum:(Int64.shift_left 1L 53) "mutez" + let hash = + def "hash" ~title:"hash" ~description:"Hexadecimal 32 bytes hash" @@ string + let status = let open Rollup_node_client in conv @@ -91,6 +125,17 @@ module Encoding = struct let _msg_id_example = Rollup_node_client.Msg_id "scmsg3VXXYqJGVabKwe14FNcPGVXNDGuKLC9KuayDFBkMzJXdMu9oQB" + + let parse_hex str = + if String.length str != 64 then + Lwt_result.fail + (`Invalid_input "Invalid hash, it must be a 32 bytes hash") + else + let h = `Hex str in + try Lwt_result.return (Hex.to_string h) + with _ -> + Lwt_result.fail + (`Invalid_input "Invalid hash, must be a valid hexadecimal value") end module Arg = struct @@ -181,13 +226,15 @@ end module Notarize_hash = struct let service : (string, unit, _, Security.scheme) post_service0 = - post_service ~section ~name:"Notarize a hash" - ~descr:"Notarize a hash with pandora" ~input:Encoding.hex_string + post_service ~section ~name:"Notarize a hash" ~errors:[err_502; err_400] + ~descr:"Notarize a hash with pandora" ~input:Encoding.hash ~input_example:Encoding.hash_example ~output:Encoding.unit ~output_example:() Path.(root // "notarize" // "hash") - let handler state _params _ hash = Rollup_node_client.notarize_hash state hash + let handler state _params _ hash = + let*? hash = Encoding.parse_hex hash in + Rollup_node_client.notarize_hash state hash let () = register service handler end @@ -199,14 +246,15 @@ module Notarization_status = struct _, Security.scheme ) post_service0 = - post_service ~section ~name:"Notarization status" + post_service ~section ~name:"Notarization status" ~errors:[err_502; err_400] ~descr:"Retrieve the notarization status for a given hash" - ~input:Encoding.hex_string ~input_example:Encoding.hash_example + ~input:Encoding.hash ~input_example:Encoding.hash_example ~output:(Json_encoding.option Encoding.status) ~output_example:(Some Encoding.status_example) ~params:[Param.block] Path.(root // "notarize" // "status") let handler state params _ hash = + let*? hash = Encoding.parse_hex hash in let block = Option.bind (Req.find_param Param.block params) Arg.block_id_of_string in @@ -240,9 +288,8 @@ module Openapi = struct end module All_hashes = struct - let service : - (Rollup_node_client.hashes_ts, string option, Security.scheme) service0 = - service ~section ~name:"All hashes" + let service = + service ~section ~name:"All hashes" ~errors:[err_502; err_500] ~descr:"Retrieve all the hashes registered on Pandora" ~output:Encoding.hashes_ts ~params:[Param.block] Path.(root // "hashes" // "all") diff --git a/server/lib/rollup_node_client.ml b/server/lib/rollup_node_client.ml index af5cbee..6bbabc7 100644 --- a/server/lib/rollup_node_client.ml +++ b/server/lib/rollup_node_client.ml @@ -151,7 +151,9 @@ let map_req_error service res = match EzAPI.Error_codes.error code with | None -> string_of_int code | Some s -> s in - Format.ksprintf Result.error "Rollup node request to %s failed: %s [%s]" + Format.ksprintf + (fun s -> Error (`Bad_gateway_to_rollup_node s)) + "Rollup node request to %s failed: %s [%s]" (Service.path service.EzAPI.s |> Path.to_string) (Option.value msg ~default:"") err @@ -274,7 +276,7 @@ let all_hashes config ?block () = let*? number_of_hashes = get_durable_storage_value config ?block length_key in let cached_length = List.length !hashrecords_cache in match number_of_hashes with - | None -> Lwt.return_error "Invalid number of hashes" + | None -> Lwt.return_error (`Internal_error "Invalid number of hashes") | Some b -> let n = EndianBytes.LittleEndian.get_int64 b 0 |> Int64.to_int in let rec collect i = diff --git a/server/lib/rollup_node_client.mli b/server/lib/rollup_node_client.mli index 28495a3..2d64248 100644 --- a/server/lib/rollup_node_client.mli +++ b/server/lib/rollup_node_client.mli @@ -57,47 +57,57 @@ end (** Retrieve rollup address which the rollup node handles *) val get_rollup_address : - Configuration.t -> (Smart_rollup.t, string) result Lwt.t + Configuration.t -> + (Smart_rollup.t, [> `Bad_gateway_to_rollup_node of string]) Lwt_result.t (** Inject messages to the batcher and return a list of identifiers to be used by {!get_message_status}. *) val inject_messages : - Configuration.t -> string list -> (msg_id list, string) result Lwt.t + Configuration.t -> + string list -> + (msg_id list, [> `Bad_gateway_to_rollup_node of string]) result Lwt.t (** Retrieve the status of the message in the rollup node. *) val get_message_status : - Configuration.t -> msg_id -> (Json_repr.ezjsonm, string) result Lwt.t + Configuration.t -> + msg_id -> + (Json_repr.ezjsonm, [> `Bad_gateway_to_rollup_node of string]) result Lwt.t (** Retrieve a value associated to a given key in the durable storage. *) val get_durable_storage_value : Configuration.t -> ?block:block_id -> string -> - (bytes option, string) result Lwt.t + (bytes option, [> `Bad_gateway_to_rollup_node of string]) result Lwt.t (** Retrieve balance for account on the pandora rollup. *) val get_balance : Configuration.t -> ?block:block_id -> Tz1.t -> - (int64 option, string) Lwt_result.t + (int64 option, [> `Bad_gateway_to_rollup_node of string]) Lwt_result.t (** Create external message with signature for hash. *) val make_external_message : State.t -> string -> string (** Notarizes a hash on pandora and returns the id to follow the status *) -val notarize_hash : State.t -> string -> (unit, string) Lwt_result.t +val notarize_hash : + State.t -> + string -> + (unit, [> `Bad_gateway_to_rollup_node of string]) Lwt_result.t (** Returns the notarization status for a given hash. *) val notarization_status : Configuration.t -> ?block:block_id -> string -> - (status option, string) Lwt_result.t + (status option, [> `Bad_gateway_to_rollup_node of string]) Lwt_result.t (** Returns all the notarized hashes with their respective timestamps. *) val all_hashes : Configuration.t -> ?block:block_id -> unit -> - (hash_ts list, string) Lwt_result.t + ( hashes_ts, + [> `Bad_gateway_to_rollup_node of string | `Internal_error of string] ) + Lwt_result.t diff --git a/server/lib/server.ml b/server/lib/server.ml index 086fc61..60c107e 100644 --- a/server/lib/server.ml +++ b/server/lib/server.ml @@ -11,7 +11,7 @@ let init_state config = let rollup = match rollup with | Ok r -> r - | Error e -> + | Error (`Bad_gateway_to_rollup_node e) -> Format.ksprintf failwith "Could not retrieve rollup address: %s" e in { State.config; rollup } -- GitLab From a8d7b37240f90c7af5653ed47b7508e9676d04ca Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Mon, 26 May 2025 16:49:45 +0200 Subject: [PATCH 7/7] success output in /notarize --- server/lib/directory.ml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/lib/directory.ml b/server/lib/directory.ml index 8deeae0..69f8179 100644 --- a/server/lib/directory.ml +++ b/server/lib/directory.ml @@ -98,6 +98,8 @@ module Encoding = struct let hash = def "hash" ~title:"hash" ~description:"Hexadecimal 32 bytes hash" @@ string + let unit_success = obj1 (req "result" (constant "success")) + let status = let open Rollup_node_client in conv @@ -228,7 +230,7 @@ module Notarize_hash = struct let service : (string, unit, _, Security.scheme) post_service0 = post_service ~section ~name:"Notarize a hash" ~errors:[err_502; err_400] ~descr:"Notarize a hash with pandora" ~input:Encoding.hash - ~input_example:Encoding.hash_example ~output:Encoding.unit + ~input_example:Encoding.hash_example ~output:Encoding.unit_success ~output_example:() Path.(root // "notarize" // "hash") -- GitLab