From eef87dfdb28c5775e3bd6d27769e89dbef19f2c0 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Thu, 6 Jul 2023 10:42:55 +0200 Subject: [PATCH 1/6] lib_shell_services: use splitted encoding for block/operation RPC --- src/lib_shell_services/block_services.ml | 101 ++++++++++++----------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/src/lib_shell_services/block_services.ml b/src/lib_shell_services/block_services.ml index dd591042fc34..8e00eeeccb02 100644 --- a/src/lib_shell_services/block_services.ml +++ b/src/lib_shell_services/block_services.ml @@ -67,6 +67,36 @@ let version_arg supported = ~construct:string_of_version () +(* This function creates an encoding that use the [latest_encoding] in binary + and that can use [latest_encoding] and any [old_encodings] in JSON. The + version value is only used to decide which encoding to use in JSON. *) +let encoding_versioning ~encoding_name ~latest_encoding ~old_encodings = + let make_case ~version ~encoding = + case + ~title: + (Format.sprintf + "%s_encoding_v%s" + encoding_name + (string_of_version version)) + Json_only + encoding + (function v, value when v == version -> Some value | _v, _value -> None) + (fun value -> (version, value)) + in + let latest_version, latest_encoding = latest_encoding in + splitted + ~binary: + (conv + (fun (_, value) -> value) + (fun value -> (latest_version, value)) + latest_encoding) + ~json: + (union + (make_case ~version:latest_version ~encoding:latest_encoding + :: List.map + (fun (version, encoding) -> make_case ~version ~encoding) + old_encodings)) + (* TODO: V2.Tree32 has been chosen arbitrarily ; maybe it's not the best option *) module Merkle_proof_encoding = Tezos_context_merkle_proof_encoding.Merkle_proof_encoding.V2.Tree32 @@ -637,44 +667,6 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct operations : operation list list; } - let encoding_versioning ~encoding_name ~old_encoding ~new_encoding = - union - [ - case - ~title:(Format.sprintf "%s_encoding" encoding_name) - (Tag 1) - new_encoding - (function - | Version_1, operations -> Some operations - | ( ( Version_0 - | Version_2 - (* The same [version] type is used for versioning all the - RPC. Even though this version is not supported for this - RPC we need to handle it. We rely on the supported - version list to fail at parsing for this version *) ), - _ ) -> - None) - (fun operations -> (Version_1, operations)); - case - ~title: - (Format.sprintf - "%s_encoding_with_legacy_attestation_name" - encoding_name) - (Tag 0) - old_encoding - (function - | Version_0, operations -> Some operations - | ( ( Version_1 - | Version_2 - (* The same [version] type is used for versioning all the - RPC. Even though this version is not supported for this - RPC we need to handle it. We rely on the supported - version list to fail at parsing for this version *) ), - _ ) -> - None) - (fun operations -> (Version_0, operations)); - ] - let block_info_encoding ~use_legacy_attestation_name = let operation_encoding = if use_legacy_attestation_name then @@ -697,8 +689,10 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct let block_info_encoding = encoding_versioning ~encoding_name:"block_info" - ~old_encoding:(block_info_encoding ~use_legacy_attestation_name:true) - ~new_encoding:(block_info_encoding ~use_legacy_attestation_name:false) + ~latest_encoding: + (Version_1, block_info_encoding ~use_legacy_attestation_name:false) + ~old_encodings: + [(Version_0, block_info_encoding ~use_legacy_attestation_name:true)] module S = struct let path : prefix Tezos_rpc.Path.context = Tezos_rpc.Path.open_root @@ -830,11 +824,16 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct let output = encoding_versioning ~encoding_name:"operations" - ~old_encoding: - (list - (dynamic_size - (list operation_encoding_with_legacy_attestation_name))) - ~new_encoding:(list (dynamic_size (list operation_encoding))) + ~latest_encoding: + (Version_1, list (dynamic_size (list operation_encoding))) + ~old_encodings: + [ + ( Version_0, + list + (dynamic_size + (list operation_encoding_with_legacy_attestation_name)) + ); + ] in Tezos_rpc.Service.get_service ~description:"All the operations included in the block." @@ -868,8 +867,11 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct let output = encoding_versioning ~encoding_name:"operations_in_pass" - ~old_encoding:(list operation_encoding_with_legacy_attestation_name) - ~new_encoding:(list operation_encoding) + ~latest_encoding:(Version_1, list operation_encoding) + ~old_encodings: + [ + (Version_0, list operation_encoding_with_legacy_attestation_name); + ] in Tezos_rpc.Service.get_service ~description: @@ -883,8 +885,9 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct let output = encoding_versioning ~encoding_name:"operation" - ~old_encoding:operation_encoding_with_legacy_attestation_name - ~new_encoding:operation_encoding + ~latest_encoding:(Version_1, operation_encoding) + ~old_encodings: + [(Version_0, operation_encoding_with_legacy_attestation_name)] in Tezos_rpc.Service.get_service ~description: -- GitLab From 75573ed46ad8ef2ac0e73930c3edc469ca2fb473 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Thu, 6 Jul 2023 10:43:24 +0200 Subject: [PATCH 2/6] lib_shell_services: use splitted for pending_operations RPC --- src/lib_shell_services/block_services.ml | 32 ++++-------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/src/lib_shell_services/block_services.ml b/src/lib_shell_services/block_services.ml index 8e00eeeccb02..8c664438e578 100644 --- a/src/lib_shell_services/block_services.ml +++ b/src/lib_shell_services/block_services.ml @@ -1473,33 +1473,11 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct |> seal let pending_operations_encoding = - union - [ - case - ~title:"pending_operations_encoding" - (Tag 2) - version_2_encoding - (function - | Version_2, pending_operations -> Some pending_operations - | (Version_0 | Version_1), _ -> None) - (fun pending_operations -> (Version_2, pending_operations)); - case - ~title:"pending_operations_encoding_with_legacy_attestation_name" - (Tag 1) - version_1_encoding - (function - | Version_1, pending_operations -> Some pending_operations - | (Version_0 | Version_2), _ -> None) - (fun pending_operations -> (Version_1, pending_operations)); - case - ~title:"old_encoding_pending_operations" - Json_only - version_0_encoding - (function - | Version_0, pending_operations -> Some pending_operations - | (Version_1 | Version_2), _ -> None) - (fun pending_operations -> (Version_0, pending_operations)); - ] + encoding_versioning + ~encoding_name:"pending_operations" + ~latest_encoding:(Version_2, version_2_encoding) + ~old_encodings: + [(Version_0, version_0_encoding); (Version_1, version_1_encoding)] let pending_operations path = Tezos_rpc.Service.get_service -- GitLab From 372fb96a0a75a5616a668b36ba6f1cfb177093a4 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Thu, 6 Jul 2023 10:44:29 +0200 Subject: [PATCH 3/6] lib_shell_services: use splitted for monitor_operations RPC --- src/lib_shell_services/block_services.ml | 36 +++++++----------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/src/lib_shell_services/block_services.ml b/src/lib_shell_services/block_services.ml index 8c664438e578..b531a77dc97b 100644 --- a/src/lib_shell_services/block_services.ml +++ b/src/lib_shell_services/block_services.ml @@ -1616,32 +1616,16 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct (obj1 (dft "error" Tezos_rpc.Error.opt_encoding None)) let processed_operation_encoding = - union - [ - case - ~title:"monitor_operations_encoding" - (Tag 1) - (list (monitor_operations_encoding ~use_legacy_name:false)) - (function - | Version_1, monitor_operations -> Some monitor_operations - | ( ( Version_0 - | Version_2 - (* The same [version] type is used for versioning all the - RPC. Even though this version is not supported for this - RPC we need to handle it. We rely on the supported - version list to fail at parsing for this version *) ), - _ ) -> - None) - (fun monitor_operations -> (Version_1, monitor_operations)); - case - ~title:"monitor_operations_encoding_with_legacy_attestation_name" - (Tag 0) - (list (monitor_operations_encoding ~use_legacy_name:true)) - (function - | Version_0, monitor_operations -> Some monitor_operations - | (Version_1 | Version_2), _ -> None) - (fun monitor_operations -> (Version_0, monitor_operations)); - ] + encoding_versioning + ~encoding_name:"monitor_operations" + ~latest_encoding: + ( Version_1, + list (monitor_operations_encoding ~use_legacy_name:false) ) + ~old_encodings: + [ + ( Version_0, + list (monitor_operations_encoding ~use_legacy_name:true) ); + ] let monitor_operations path = Tezos_rpc.Service.get_service -- GitLab From fd81835eae5fdf1fa9f2046bd595dcbd30376e82 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Thu, 6 Jul 2023 10:46:48 +0200 Subject: [PATCH 4/6] lib_shell_services: use splitted for preapply/operations RPC --- src/lib_shell_services/block_services.ml | 40 ++++++++++-------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/lib_shell_services/block_services.ml b/src/lib_shell_services/block_services.ml index b531a77dc97b..96194237eab6 100644 --- a/src/lib_shell_services/block_services.ml +++ b/src/lib_shell_services/block_services.ml @@ -1070,30 +1070,22 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct |> seal let preapplied_operations_encoding = - union - [ - case - ~title:"preapplied_operations_encoding" - (Tag 1) - (list - (dynamic_size Next_proto.operation_data_and_receipt_encoding)) - (function - | Version_1, preapply_operations -> Some preapply_operations - | (Version_0 | Version_2), _ -> None) - (fun preapply_operations -> (Version_1, preapply_operations)); - case - ~title: - "preapplied_operations_encoding_with_legacy_attestation_name" - (Tag 0) - (list - (dynamic_size - Next_proto - .operation_data_and_receipt_encoding_with_legacy_attestation_name)) - (function - | Version_0, preapply_operations -> Some preapply_operations - | (Version_1 | Version_2), _ -> None) - (fun preapply_operations -> (Version_0, preapply_operations)); - ] + encoding_versioning + ~encoding_name:"preapplied_operations" + ~latest_encoding: + ( Version_1, + list + (dynamic_size Next_proto.operation_data_and_receipt_encoding) + ) + ~old_encodings: + [ + ( Version_0, + list + (dynamic_size + Next_proto + .operation_data_and_receipt_encoding_with_legacy_attestation_name) + ); + ] let operations = Tezos_rpc.Service.post_service -- GitLab From adfc6f036053e167c441dc116a0cde03d5c532ca Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Thu, 6 Jul 2023 10:50:45 +0200 Subject: [PATCH 5/6] proto_alpha/lib_plugin: use splitted for run_operations RPC --- src/proto_alpha/lib_plugin/RPC.ml | 60 +++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index 745a3ad0e78e..af0270528ada 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -49,6 +49,37 @@ let version_arg = ~construct:string_of_version () +(* This function creates an encoding that use the [latest_encoding] in binary + and that can use [latest_encoding] and any [old_encodings] in JSON. The + version value is only used to decide which encoding to use in JSON. *) +let encoding_versioning ~encoding_name ~latest_encoding ~old_encodings = + let open Data_encoding in + let make_case ~version ~encoding = + case + ~title: + (Format.sprintf + "%s_encoding_v%s" + encoding_name + (string_of_version version)) + Json_only + encoding + (function v, value when v == version -> Some value | _v, _value -> None) + (fun value -> (version, value)) + in + let latest_version, latest_encoding = latest_encoding in + splitted + ~binary: + (conv + (fun (_, value) -> value) + (fun value -> (latest_version, value)) + latest_encoding) + ~json: + (union + (make_case ~version:latest_version ~encoding:latest_encoding + :: List.map + (fun (version, encoding) -> make_case ~version ~encoding) + old_encodings)) + (** The assumed number of blocks between operation-creation time and the actual time when the operation is included in a block. *) let default_operation_inclusion_latency = 3 @@ -456,24 +487,17 @@ module Scripts = struct ] let run_operation_output_encoding = - union - [ - case - ~title:"new_encoding_run_operation_output" - (Tag 1) - Apply_results.operation_data_and_metadata_encoding - (function - | Version_1, operation -> Some operation | Version_0, _ -> None) - (fun operation -> (Version_1, operation)); - case - ~title:"old_encoding_run_operation_output" - (Tag 0) - Apply_results - .operation_data_and_metadata_encoding_with_legacy_attestation_name - (function - | Version_0, operation -> Some operation | Version_1, _ -> None) - (fun operation -> (Version_0, operation)); - ] + encoding_versioning + ~encoding_name:"run_operation_output" + ~latest_encoding: + (Version_1, Apply_results.operation_data_and_metadata_encoding) + ~old_encodings: + [ + ( Version_0, + Apply_results + .operation_data_and_metadata_encoding_with_legacy_attestation_name + ); + ] let run_operation = RPC_service.post_service -- GitLab From 3f5573d08018b8e1a228fc39e5edb7ab8b250fb1 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Thu, 6 Jul 2023 10:51:54 +0200 Subject: [PATCH 6/6] proto_alpha/lib_plugin: use splitted for parse/operations RPC --- src/proto_alpha/lib_plugin/RPC.ml | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index af0270528ada..c8be834da748 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -2990,26 +2990,16 @@ module Parse = struct |> seal let parse_operations_encoding = - union - [ - case - ~title:"new_encoding_parse_operations" - (Tag 1) - (list (dynamic_size Operation.encoding)) - (function - | Version_1, parse_operations -> Some parse_operations - | Version_0, _ -> None) - (fun parse_operations -> (Version_1, parse_operations)); - case - ~title:"old_encoding_parse_operations" - Json_only - (list - (dynamic_size Operation.encoding_with_legacy_attestation_name)) - (function - | Version_0, parse_operations -> Some parse_operations - | Version_1, _ -> None) - (fun parse_operations -> (Version_0, parse_operations)); - ] + encoding_versioning + ~encoding_name:"parse_operations" + ~latest_encoding:(Version_1, list (dynamic_size Operation.encoding)) + ~old_encodings: + [ + ( Version_0, + list + (dynamic_size Operation.encoding_with_legacy_attestation_name) + ); + ] let operations = RPC_service.post_service -- GitLab