diff --git a/CHANGES.rst b/CHANGES.rst index 9a042d1756fa71f50a5d533247f1ae3f903ed529..fdc44ab109eb209cdc624346893db39c8b6073fa 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -186,6 +186,13 @@ Node no prevalidator filter is found later on for a different protocol. (MR :gl:`!9261`) +- Added version ``1`` to RPCs ``GET ../blocks/``, and ``GET + ../blocks//operations``. It can be used by calling the RPC with the + parameter ``?version=1`` (default version is still ``0``). Version ``1`` + allows the RPC to output ``attestation``, ``preattestation``, + ``double_attestation_evidence`` and ``double_preattestation_evidence`` kinds + in the JSON result. (MR :gl:`!9008`) + Client ------ - Adding client commands to generate, open and verify a time-lock. diff --git a/src/lib_mockup/local_services.ml b/src/lib_mockup/local_services.ml index 85da3719d45db770b6e11506d7d2a929405578be..10cbfc2c0e263bdee4cef9ccd0a5e9062998953f 100644 --- a/src/lib_mockup/local_services.ml +++ b/src/lib_mockup/local_services.ml @@ -952,10 +952,10 @@ module Make (E : MENV) = struct @@ Directory.register Directory.empty E.Block_services.S.Operations.operations - (fun (((), chain), _block) _query () -> + (fun (((), chain), _block) query () -> with_chain ~caller_name:"operations" chain (fun () -> (* FIXME: Better answer here *) - Tezos_rpc.Answer.return [[]; []; []; []])) + Tezos_rpc.Answer.return (query#version, [[]; []; []; []]))) let monitor_operations () = let open Lwt_syntax in diff --git a/src/lib_shell/block_directory.ml b/src/lib_shell/block_directory.ml index ce187a2e8c6a682d872d4a1dcb2d2e65a3c5b47b..47be17da83ce7205e3762ce4416d1e7ec807e543 100644 --- a/src/lib_shell/block_directory.ml +++ b/src/lib_shell/block_directory.ml @@ -343,40 +343,43 @@ let build_raw_rpc_directory (module Proto : Block_services.PROTO) let with_metadata = with_metadata ~force_metadata:q#force_metadata ~metadata:q#metadata in - match with_metadata with - | Some `Always -> ( - let chain_id = Store.Chain.chain_id chain_store in - let ops = Store.Block.operations block in - let* metadata = Store.Block.get_block_metadata chain_store block in - let ops_metadata = metadata.operations_metadata in - let* ops_metadata = - (* Iter through the operations metadata to check if some are - considered as too large. *) - if - List.exists - (fun v -> - List.exists - (fun v -> v = Block_validation.Too_large_metadata) - v) - ops_metadata - then - (* The metadatas are stored but contains some too large - metadata, we need te recompute them *) - force_operation_metadata chain_id chain_store block - else return ops_metadata - in - List.map2_e - ~when_different_lengths:() - (List.map2 - ~when_different_lengths:() - (convert_with_metadata chain_id)) - ops - ops_metadata - |> function - | Ok v -> return v - | Error () -> fail_with_exn Not_found) - | Some `Never -> operations_without_metadata chain_store block - | None -> operations chain_store block) ; + let* operations = + match with_metadata with + | Some `Always -> ( + let chain_id = Store.Chain.chain_id chain_store in + let ops = Store.Block.operations block in + let* metadata = Store.Block.get_block_metadata chain_store block in + let ops_metadata = metadata.operations_metadata in + let* ops_metadata = + (* Iter through the operations metadata to check if some are + considered as too large. *) + if + List.exists + (fun v -> + List.exists + (fun v -> v = Block_validation.Too_large_metadata) + v) + ops_metadata + then + (* The metadatas are stored but contains some too large + metadata, we need te recompute them *) + force_operation_metadata chain_id chain_store block + else return ops_metadata + in + List.map2_e + ~when_different_lengths:() + (List.map2 + ~when_different_lengths:() + (convert_with_metadata chain_id)) + ops + ops_metadata + |> function + | Ok v -> return v + | Error () -> fail_with_exn Not_found) + | Some `Never -> operations_without_metadata chain_store block + | None -> operations chain_store block + in + return (q#version, operations)) ; register1 S.Operations.operations_in_pass (fun (chain_store, block) i q () -> let chain_id = Store.Chain.chain_id chain_store in Lwt.catch @@ -384,56 +387,63 @@ let build_raw_rpc_directory (module Proto : Block_services.PROTO) let with_metadata = with_metadata ~force_metadata:q#force_metadata ~metadata:q#metadata in - match with_metadata with - | Some `Always -> ( - let*! o = Store.Block.get_block_metadata_opt chain_store block in - let ops = fst @@ Store.Block.operations_path block i in - match o with - | None -> - return (List.map (convert_without_metadata chain_id) ops) - | Some metadata -> ( - let opss_metadata = - Store.Block.operations_metadata metadata - in - let ops_metadata = - List.nth opss_metadata i - |> WithExceptions.Option.to_exn ~none:Not_found - in - let* ops_metadata = - (* Iter through the operations metadata of the - requested pass to check if some are considered as - too large. *) - if - List.exists - (fun v -> v = Block_validation.Too_large_metadata) - ops_metadata - then - let* opss_metadata = - force_operation_metadata chain_id chain_store block - in - let ops_metadata = - List.nth_opt opss_metadata i - |> WithExceptions.Option.to_exn ~none:Not_found - in - return ops_metadata - else return ops_metadata - in - List.map2 - ~when_different_lengths:() - (convert_with_metadata chain_id) - ops - ops_metadata - |> function - | Ok x -> return x - | _ -> fail_with_exn Not_found)) - | Some `Never -> - let* ops = operations_without_metadata chain_store block in - return - (List.nth ops i |> WithExceptions.Option.to_exn ~none:Not_found) - | None -> - let* ops = operations chain_store block in - return - (List.nth ops i |> WithExceptions.Option.to_exn ~none:Not_found)) + let* operations = + match with_metadata with + | Some `Always -> ( + let*! o = + Store.Block.get_block_metadata_opt chain_store block + in + let ops = fst @@ Store.Block.operations_path block i in + match o with + | None -> + return (List.map (convert_without_metadata chain_id) ops) + | Some metadata -> ( + let opss_metadata = + Store.Block.operations_metadata metadata + in + let ops_metadata = + List.nth opss_metadata i + |> WithExceptions.Option.to_exn ~none:Not_found + in + let* ops_metadata = + (* Iter through the operations metadata of the + requested pass to check if some are considered as + too large. *) + if + List.exists + (fun v -> v = Block_validation.Too_large_metadata) + ops_metadata + then + let* opss_metadata = + force_operation_metadata chain_id chain_store block + in + let ops_metadata = + List.nth_opt opss_metadata i + |> WithExceptions.Option.to_exn ~none:Not_found + in + return ops_metadata + else return ops_metadata + in + List.map2 + ~when_different_lengths:() + (convert_with_metadata chain_id) + ops + ops_metadata + |> function + | Ok x -> return x + | _ -> fail_with_exn Not_found)) + | Some `Never -> + let* ops = operations_without_metadata chain_store block in + return + (List.nth ops i + |> WithExceptions.Option.to_exn ~none:Not_found) + | None -> + let* ops = operations chain_store block in + return + (List.nth ops i + |> WithExceptions.Option.to_exn ~none:Not_found) + in + return (q#version, operations)) (fun _ -> fail_with_exn Not_found)) ; register2 S.Operations.operation (fun (chain_store, block) i j q () -> let chain_id = Store.Chain.chain_id chain_store in @@ -446,57 +456,64 @@ let build_raw_rpc_directory (module Proto : Block_services.PROTO) let with_metadata = with_metadata ~force_metadata:q#force_metadata ~metadata:q#metadata in - match with_metadata with - | Some `Always -> ( - let*! o = Store.Block.get_block_metadata_opt chain_store block in - match o with - | None -> return (convert_without_metadata chain_id op) - | Some metadata -> ( - let opss_metadata = - Store.Block.operations_metadata metadata - in - let ops_metadata = - List.nth opss_metadata i - |> WithExceptions.Option.to_exn ~none:Not_found - in - let op_metadata = - List.nth ops_metadata j - |> WithExceptions.Option.to_exn ~none:Not_found - in - match op_metadata with - | Block_validation.Too_large_metadata -> - let* opss_metadata = - force_operation_metadata chain_id chain_store block - in - let ops_metadata = - List.nth_opt opss_metadata i - |> WithExceptions.Option.to_exn ~none:Not_found - in - let op_metadata = - List.nth ops_metadata j - |> WithExceptions.Option.to_exn ~none:Not_found - in - return ((convert_with_metadata chain_id) op op_metadata) - | Metadata _ -> - return (convert_with_metadata chain_id op op_metadata))) - | Some `Never -> - let* opss = operations_without_metadata chain_store block in - let ops = - List.nth opss i |> WithExceptions.Option.to_exn ~none:Not_found - in - let op = - List.nth ops j |> WithExceptions.Option.to_exn ~none:Not_found - in - return op - | None -> - let* opss = operations chain_store block in - let ops = - List.nth opss i |> WithExceptions.Option.to_exn ~none:Not_found - in - let op = - List.nth ops j |> WithExceptions.Option.to_exn ~none:Not_found - in - return op) + let* operation = + match with_metadata with + | Some `Always -> ( + let*! o = + Store.Block.get_block_metadata_opt chain_store block + in + match o with + | None -> return (convert_without_metadata chain_id op) + | Some metadata -> ( + let opss_metadata = + Store.Block.operations_metadata metadata + in + let ops_metadata = + List.nth opss_metadata i + |> WithExceptions.Option.to_exn ~none:Not_found + in + let op_metadata = + List.nth ops_metadata j + |> WithExceptions.Option.to_exn ~none:Not_found + in + match op_metadata with + | Block_validation.Too_large_metadata -> + let* opss_metadata = + force_operation_metadata chain_id chain_store block + in + let ops_metadata = + List.nth_opt opss_metadata i + |> WithExceptions.Option.to_exn ~none:Not_found + in + let op_metadata = + List.nth ops_metadata j + |> WithExceptions.Option.to_exn ~none:Not_found + in + return ((convert_with_metadata chain_id) op op_metadata) + | Metadata _ -> + return (convert_with_metadata chain_id op op_metadata))) + | Some `Never -> + let* opss = operations_without_metadata chain_store block in + let ops = + List.nth opss i + |> WithExceptions.Option.to_exn ~none:Not_found + in + let op = + List.nth ops j |> WithExceptions.Option.to_exn ~none:Not_found + in + return op + | None -> + let* opss = operations chain_store block in + let ops = + List.nth opss i + |> WithExceptions.Option.to_exn ~none:Not_found + in + let op = + List.nth ops j |> WithExceptions.Option.to_exn ~none:Not_found + in + return op + in + return (q#version, operation)) (fun _ -> fail_with_exn Not_found)) ; (* operation_hashes *) register0 S.Operation_hashes.operation_hashes (fun (_, block) () () -> @@ -632,13 +649,14 @@ let build_raw_rpc_directory (module Proto : Block_services.PROTO) | None -> operations chain_store block in return - { - Block_services.hash; - chain_id; - header = {shell; protocol_data}; - metadata; - operations; - }) ; + ( q#version, + { + Block_services.hash; + chain_id; + header = {shell; protocol_data}; + metadata; + operations; + } )) ; (* helpers *) register0 S.Helpers.Preapply.block (fun (chain_store, block) q p -> let timestamp = diff --git a/src/lib_shell_services/block_services.ml b/src/lib_shell_services/block_services.ml index fa1840a6a9a3384c07c64742fd5725466791c2f9..dd591042fc346a07c7390c95f6ed7533be91842f 100644 --- a/src/lib_shell_services/block_services.ml +++ b/src/lib_shell_services/block_services.ml @@ -561,7 +561,17 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct receipt : operation_receipt; } - let operation_data_encoding = + let operation_data_encoding ~use_legacy_attestation_name = + let operation_data_encoding = + if use_legacy_attestation_name then + Proto.operation_data_encoding_with_legacy_attestation_name + else Proto.operation_data_encoding + in + let operation_data_and_receipt_encoding = + if use_legacy_attestation_name then + Proto.operation_data_and_receipt_encoding_with_legacy_attestation_name + else Proto.operation_data_and_receipt_encoding + in let open Data_encoding in union ~tag_size:`Uint8 @@ -570,7 +580,7 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct ~title:"Operation with too large metadata" (Tag 0) (merge_objs - Proto.operation_data_encoding_with_legacy_attestation_name + operation_data_encoding (obj1 (req "metadata" (constant "too large")))) (function | operation_data, Too_large -> Some (operation_data, ()) | _ -> None) @@ -578,13 +588,13 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct case ~title:"Operation without metadata" (Tag 1) - Proto.operation_data_encoding_with_legacy_attestation_name + operation_data_encoding (function operation_data, Empty -> Some operation_data | _ -> None) (fun operation_data -> (operation_data, Empty)); case ~title:"Operation with metadata" (Tag 2) - Proto.operation_data_and_receipt_encoding_with_legacy_attestation_name + operation_data_and_receipt_encoding (function | operation_data, Receipt receipt -> Some (operation_data, receipt) | _ -> None) @@ -592,8 +602,11 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct | operation_data, receipt -> (operation_data, Receipt receipt)); ] - let operation_encoding = - def "operation" + let operation_encoding ~use_legacy_attestation_name = + def + (if use_legacy_attestation_name then + "operation_with_legacy_attestation_name" + else "operation") @@ let open Data_encoding in conv @@ -608,7 +621,13 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct (req "hash" Operation_hash.encoding)) (merge_objs (dynamic_size Operation.shell_header_encoding) - (dynamic_size operation_data_encoding))) + (dynamic_size + (operation_data_encoding ~use_legacy_attestation_name)))) + + let operation_encoding_with_legacy_attestation_name = + operation_encoding ~use_legacy_attestation_name:true + + let operation_encoding = operation_encoding ~use_legacy_attestation_name:false type block_info = { chain_id : Chain_id.t; @@ -618,7 +637,50 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct operations : operation list list; } - let block_info_encoding = + 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 + operation_encoding_with_legacy_attestation_name + else operation_encoding + in conv (fun {chain_id; hash; header; metadata; operations} -> ((), chain_id, hash, header, metadata, operations)) @@ -632,6 +694,12 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct (opt "metadata" (dynamic_size block_metadata_encoding)) (req "operations" (list (dynamic_size (list operation_encoding))))) + 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) + module S = struct let path : prefix Tezos_rpc.Path.context = Tezos_rpc.Path.open_root @@ -718,14 +786,25 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct Tezos_rpc.Path.(path / "protocol_data" / "raw") end + let default_operation_version = Version_0 + + let operations_supported_versions = [Version_0; Version_1] + let force_operation_metadata_query = let open Tezos_rpc.Query in - query (fun force_metadata metadata -> + query (fun version force_metadata metadata -> object + method version = version + method force_metadata = force_metadata method metadata = metadata end) + |+ field + "version" + (version_arg operations_supported_versions) + default_operation_version + (fun t -> t#version) |+ flag "force_metadata" ~descr: @@ -748,10 +827,19 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct let path = Tezos_rpc.Path.(path / "operations") let operations = + 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))) + in Tezos_rpc.Service.get_service ~description:"All the operations included in the block." ~query:force_operation_metadata_query - ~output:(list (dynamic_size (list operation_encoding))) + ~output path let list_arg = @@ -777,20 +865,32 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct Tezos_rpc.Arg.make ~name ~descr ~construct ~destruct () let operations_in_pass = + let output = + encoding_versioning + ~encoding_name:"operations_in_pass" + ~old_encoding:(list operation_encoding_with_legacy_attestation_name) + ~new_encoding:(list operation_encoding) + in Tezos_rpc.Service.get_service ~description: "All the operations included in `n-th` validation pass of the \ block." ~query:force_operation_metadata_query - ~output:(list operation_encoding) + ~output Tezos_rpc.Path.(path /: list_arg) let operation = + let output = + encoding_versioning + ~encoding_name:"operation" + ~old_encoding:operation_encoding_with_legacy_attestation_name + ~new_encoding:operation_encoding + in Tezos_rpc.Service.get_service ~description: "The `m-th` operation in the `n-th` validation pass of the block." ~query:force_operation_metadata_query - ~output:operation_encoding + ~output Tezos_rpc.Path.(path /: list_arg /: offset_arg) end @@ -1693,49 +1793,68 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct end module Operations = struct - module S = S.Operations - - let operations ctxt ?(force_metadata = false) ?metadata = - let f = make_call0 S.operations ctxt in + let operations ctxt ?(version = S.default_operation_version) + ?(force_metadata = false) ?metadata = + let open Lwt_result_syntax in + let f = make_call0 S.Operations.operations ctxt in fun ?(chain = `Main) ?(block = `Head 0) () -> - f - chain - block - (object - method force_metadata = force_metadata + let* (Version_0 | Version_1 | Version_2), operations = + f + chain + block + (object + method version = version - method metadata = metadata - end) - () + method force_metadata = force_metadata + + method metadata = metadata + end) + () + in + return operations - let operations_in_pass ctxt ?(force_metadata = false) ?metadata = - let f = make_call1 S.operations_in_pass ctxt in + let operations_in_pass ctxt ?(version = S.default_operation_version) + ?(force_metadata = false) ?metadata = + let open Lwt_result_syntax in + let f = make_call1 S.Operations.operations_in_pass ctxt in fun ?(chain = `Main) ?(block = `Head 0) n -> - f - chain - block - n - (object - method force_metadata = force_metadata + let* (Version_0 | Version_1 | Version_2), operations = + f + chain + block + n + (object + method version = version - method metadata = metadata - end) - () + method force_metadata = force_metadata + + method metadata = metadata + end) + () + in + return operations - let operation ctxt ?(force_metadata = false) ?metadata = - let f = make_call2 S.operation ctxt in + let operation ctxt ?(version = S.default_operation_version) + ?(force_metadata = false) ?metadata = + let open Lwt_result_syntax in + let f = make_call2 S.Operations.operation ctxt in fun ?(chain = `Main) ?(block = `Head 0) n m -> - f - chain - block - n - m - (object - method force_metadata = force_metadata + let* (Version_0 | Version_1 | Version_2), operation = + f + chain + block + n + m + (object + method version = version - method metadata = metadata - end) - () + method force_metadata = force_metadata + + method metadata = metadata + end) + () + in + return operation end module Operation_hashes = struct @@ -1857,18 +1976,25 @@ module Make (Proto : PROTO) (Next_proto : PROTO) = struct fun ?(chain = `Main) ?(block = `Head 0) s -> f chain block s () () end - let info ctxt ?(force_metadata = false) ?metadata = + let info ctxt ?(version = S.default_operation_version) + ?(force_metadata = false) ?metadata = + let open Lwt_result_syntax in let f = make_call0 S.info ctxt in fun ?(chain = `Main) ?(block = `Head 0) () -> - f - chain - block - (object - method force_metadata = force_metadata + let* (Version_0 | Version_1 | Version_2), infos = + f + chain + block + (object + method version = version - method metadata = metadata - end) - () + method force_metadata = force_metadata + + method metadata = metadata + end) + () + in + return infos module Mempool = struct type t = S.Mempool.t = { diff --git a/src/lib_shell_services/block_services.mli b/src/lib_shell_services/block_services.mli index b85b2f754e59ab00b38556b60725e9a8ce53b2b8..f79febd8139b2816bf9845af91552ac1b8db9da3 100644 --- a/src/lib_shell_services/block_services.mli +++ b/src/lib_shell_services/block_services.mli @@ -186,12 +186,13 @@ module Make (Proto : PROTO) (Next_proto : PROTO) : sig operations : operation list list; } - val block_info_encoding : block_info Data_encoding.t + val block_info_encoding : (version * block_info) Data_encoding.t open Tezos_rpc.Context val info : #simple -> + ?version:version -> ?force_metadata:bool -> ?metadata:[`Always | `Never] -> ?chain:chain -> @@ -259,6 +260,7 @@ module Make (Proto : PROTO) (Next_proto : PROTO) : sig module Operations : sig val operations : #simple -> + ?version:version -> ?force_metadata:bool -> ?metadata:[`Always | `Never] -> ?chain:chain -> @@ -268,6 +270,7 @@ module Make (Proto : PROTO) (Next_proto : PROTO) : sig val operations_in_pass : #simple -> + ?version:version -> ?force_metadata:bool -> ?metadata:[`Always | `Never] -> ?chain:chain -> @@ -277,6 +280,7 @@ module Make (Proto : PROTO) (Next_proto : PROTO) : sig val operation : #simple -> + ?version:version -> ?force_metadata:bool -> ?metadata:[`Always | `Never] -> ?chain:chain -> @@ -494,9 +498,11 @@ module Make (Proto : PROTO) (Next_proto : PROTO) : sig ( [`GET], prefix, prefix, - < force_metadata : bool ; metadata : [`Always | `Never] option >, + < version : version + ; force_metadata : bool + ; metadata : [`Always | `Never] option >, unit, - block_info ) + version * block_info ) Tezos_rpc.Service.t val header : @@ -551,27 +557,33 @@ module Make (Proto : PROTO) (Next_proto : PROTO) : sig ( [`GET], prefix, prefix, - < force_metadata : bool ; metadata : [`Always | `Never] option >, + < version : version + ; force_metadata : bool + ; metadata : [`Always | `Never] option >, unit, - operation list list ) + version * operation list list ) Tezos_rpc.Service.t val operations_in_pass : ( [`GET], prefix, prefix * int, - < force_metadata : bool ; metadata : [`Always | `Never] option >, + < version : version + ; force_metadata : bool + ; metadata : [`Always | `Never] option >, unit, - operation list ) + version * operation list ) Tezos_rpc.Service.t val operation : ( [`GET], prefix, (prefix * int) * int, - < force_metadata : bool ; metadata : [`Always | `Never] option >, + < version : version + ; force_metadata : bool + ; metadata : [`Always | `Never] option >, unit, - operation ) + version * operation ) Tezos_rpc.Service.t end diff --git a/src/proto_016_PtMumbai/lib_delegate/test/mockup_simulator/faked_services.ml b/src/proto_016_PtMumbai/lib_delegate/test/mockup_simulator/faked_services.ml index 9a6603cbee91e3fa2a813d3138aeba01348e0a02..cab89d4c8c06699394a0ed2ffdb57a89deb701fa 100644 --- a/src/proto_016_PtMumbai/lib_delegate/test/mockup_simulator/faked_services.ml +++ b/src/proto_016_PtMumbai/lib_delegate/test/mockup_simulator/faked_services.ml @@ -188,7 +188,10 @@ module Make (Hooks : Mocked_services_hooks) = struct @@ Directory.register Directory.empty Mockup.M.Block_services.S.Operations.operations - (fun (((), _chain), block) _ () -> Hooks.operations block) + (fun (((), _chain), block) q () -> + let open Lwt_result_syntax in + let* ops = Hooks.operations block in + return (q#version, ops)) let hash = Directory.prefix diff --git a/src/proto_017_PtNairob/lib_delegate/test/mockup_simulator/faked_services.ml b/src/proto_017_PtNairob/lib_delegate/test/mockup_simulator/faked_services.ml index e64e5a88da9ee5ec4e999c3353aa1440997852c1..533c0d99036e80fc157e656c867b732e9cc40bc9 100644 --- a/src/proto_017_PtNairob/lib_delegate/test/mockup_simulator/faked_services.ml +++ b/src/proto_017_PtNairob/lib_delegate/test/mockup_simulator/faked_services.ml @@ -188,7 +188,10 @@ module Make (Hooks : Mocked_services_hooks) = struct @@ Directory.register Directory.empty Mockup.M.Block_services.S.Operations.operations - (fun (((), _chain), block) _ () -> Hooks.operations block) + (fun (((), _chain), block) q () -> + let open Lwt_result_syntax in + let* ops = Hooks.operations block in + return (q#version, ops)) let hash = Directory.prefix diff --git a/src/proto_018_Proxford/lib_delegate/test/mockup_simulator/faked_services.ml b/src/proto_018_Proxford/lib_delegate/test/mockup_simulator/faked_services.ml index e64e5a88da9ee5ec4e999c3353aa1440997852c1..533c0d99036e80fc157e656c867b732e9cc40bc9 100644 --- a/src/proto_018_Proxford/lib_delegate/test/mockup_simulator/faked_services.ml +++ b/src/proto_018_Proxford/lib_delegate/test/mockup_simulator/faked_services.ml @@ -188,7 +188,10 @@ module Make (Hooks : Mocked_services_hooks) = struct @@ Directory.register Directory.empty Mockup.M.Block_services.S.Operations.operations - (fun (((), _chain), block) _ () -> Hooks.operations block) + (fun (((), _chain), block) q () -> + let open Lwt_result_syntax in + let* ops = Hooks.operations block in + return (q#version, ops)) let hash = Directory.prefix diff --git a/src/proto_alpha/lib_delegate/test/mockup_simulator/faked_services.ml b/src/proto_alpha/lib_delegate/test/mockup_simulator/faked_services.ml index e64e5a88da9ee5ec4e999c3353aa1440997852c1..533c0d99036e80fc157e656c867b732e9cc40bc9 100644 --- a/src/proto_alpha/lib_delegate/test/mockup_simulator/faked_services.ml +++ b/src/proto_alpha/lib_delegate/test/mockup_simulator/faked_services.ml @@ -188,7 +188,10 @@ module Make (Hooks : Mocked_services_hooks) = struct @@ Directory.register Directory.empty Mockup.M.Block_services.S.Operations.operations - (fun (((), _chain), block) _ () -> Hooks.operations block) + (fun (((), _chain), block) q () -> + let open Lwt_result_syntax in + let* ops = Hooks.operations block in + return (q#version, ops)) let hash = Directory.prefix diff --git a/tezt/lib_tezos/RPC.ml b/tezt/lib_tezos/RPC.ml index b5705c8e13cb3edabf55dbfb7a1b4970ba387a9c..d1594a3b5147b94fad0916944f43cdf1394f4c9f 100644 --- a/tezt/lib_tezos/RPC.ml +++ b/tezt/lib_tezos/RPC.ml @@ -277,8 +277,9 @@ let post_chain_block_helpers_scripts_run_operation ?(chain = "main") let get_chain_chain_id ?(chain = "main") () = make GET ["chains"; chain; "chain_id"] JSON.as_string -let get_chain_block ?(chain = "main") ?(block = "head") () = - make GET ["chains"; chain; "blocks"; block] Fun.id +let get_chain_block ?(chain = "main") ?(block = "head") ?version () = + let query_string = Query_arg.opt "version" Fun.id version in + make ~query_string GET ["chains"; chain; "blocks"; block] Fun.id type block_metadata = { protocol : string; @@ -418,11 +419,16 @@ let get_chain_block_header_protocol_data ?(chain = "main") ?(block = "head") ["chains"; chain; "blocks"; block; "header"; "protocol_data"] Fun.id -let get_chain_block_operations ?(chain = "main") ?(block = "head") () = - make GET ["chains"; chain; "blocks"; block; "operations"] Fun.id +let get_chain_block_operations ?(chain = "main") ?(block = "head") ?version + ?(force_metadata = false) () = + let query_string = + Query_arg.opt "version" Fun.id version + @ if force_metadata then [("force_metadata", "")] else [] + in + make ~query_string GET ["chains"; chain; "blocks"; block; "operations"] Fun.id let get_chain_block_operations_validation_pass ?(chain = "main") - ?(block = "head") ?(force_metadata = false) ?operation_offset + ?(block = "head") ?version ?(force_metadata = false) ?operation_offset ~validation_pass () = let path = [ @@ -435,7 +441,10 @@ let get_chain_block_operations_validation_pass ?(chain = "main") ] @ match operation_offset with None -> [] | Some m -> [string_of_int m] in - let query_string = if force_metadata then [("force_metadata", "")] else [] in + let query_string = + Query_arg.opt "version" Fun.id version + @ if force_metadata then [("force_metadata", "")] else [] + in make ~query_string GET path Fun.id let get_chain_mempool_pending_operations ?(chain = "main") ?version ?validated diff --git a/tezt/lib_tezos/RPC.mli b/tezt/lib_tezos/RPC.mli index ddf79557fa97392a0c4fb0809dff9ea4217482ed..23bf1204a3fe2d8fabf7fd6b08d8dd22e07ad25f 100644 --- a/tezt/lib_tezos/RPC.mli +++ b/tezt/lib_tezos/RPC.mli @@ -283,7 +283,8 @@ val get_chain_chain_id : ?chain:string -> unit -> string t [chain] defaults to ["main"]. [block] defaults to ["head"]. *) -val get_chain_block : ?chain:string -> ?block:string -> unit -> JSON.t t +val get_chain_block : + ?chain:string -> ?block:string -> ?version:string -> unit -> JSON.t t type block_metadata = { protocol : string; @@ -423,7 +424,12 @@ val get_chain_block_header_protocol_data : [block] defaults to ["head"]. *) val get_chain_block_operations : - ?chain:string -> ?block:string -> unit -> JSON.t t + ?chain:string -> + ?block:string -> + ?version:string -> + ?force_metadata:bool -> + unit -> + JSON.t t (** RPC: [GET /chains//blocks//operations/] if [operation_offset] is unset @@ -438,6 +444,7 @@ val get_chain_block_operations : val get_chain_block_operations_validation_pass : ?chain:string -> ?block:string -> + ?version:string -> ?force_metadata:bool -> ?operation_offset:int -> validation_pass:int -> diff --git a/tezt/tests/rpc_versioning_attestation.ml b/tezt/tests/rpc_versioning_attestation.ml index 5e6a0256f7843f42aec78378930978ef12b6c131..0a44befa11dd39decd2ae63a08406512ab18e718 100644 --- a/tezt/tests/rpc_versioning_attestation.ml +++ b/tezt/tests/rpc_versioning_attestation.ml @@ -988,9 +988,154 @@ module Preapply = struct test_preapply_double_preconsensus_evidence protocols end +module Block = struct + let call_and_check_operation ~validation_pass get_name client = + Log.info "Check kind for operation rpc" ; + check_rpc_versions + ~check:(fun ~use_legacy_name:_ -> check_kind) + ~get_name + ~rpc:(fun ~version () -> + RPC.get_chain_block_operations_validation_pass + ~version + ~operation_offset:0 + ~validation_pass + ()) + ~data:() + client + + let call_and_check_operations_validation_pass ~validation_pass get_name client + = + Log.info "Check kind for operations_validation_pass rpc" ; + let check ~use_legacy_name:_ json = check_kind JSON.(json |=> 0) in + check_rpc_versions + ~check + ~get_name + ~rpc:(fun ~version () -> + RPC.get_chain_block_operations_validation_pass + ~version + ~validation_pass + ()) + ~data:() + client + + let call_and_check_operations ~validation_pass get_name client = + Log.info "Check kind for operations rpc" ; + let check ~use_legacy_name:_ json = + check_kind JSON.(json |=> validation_pass |=> 0) + in + check_rpc_versions + ~check + ~get_name + ~rpc:(fun ~version () -> RPC.get_chain_block_operations ~version ()) + ~data:() + client + + let call_and_check_block ~validation_pass get_name client = + Log.info "Check kind for block rpc" ; + let check ~use_legacy_name:_ json = + check_kind JSON.(json |-> "operations" |=> validation_pass |=> 0) + in + check_rpc_versions + ~check + ~get_name + ~rpc:(fun ~version () -> RPC.get_chain_block ~version ()) + ~data:() + client + + let test_block_consensus kind protocol = + let* node, client = Client.init_with_protocol ~protocol `Client () in + let* () = Client.bake_for_and_wait ~node client in + + let* level, slots, block_payload_hash = + get_consensus_info Constant.bootstrap1.public_key_hash client + in + let signer = Constant.bootstrap1 in + let* consensus1 = + create_consensus_op + ~level + ~block_payload_hash + ~slot:(List.hd slots) + ~kind + ~signer + ~use_legacy_name:false + client + in + let* signature = Operation.sign consensus1 client in + let* (`OpHash _) = + Operation.inject ~request:`Inject ~signature consensus1 client + in + let* () = Client.bake_for_and_wait ~node client in + + let get_name = Operation.Consensus.kind_to_string kind in + let validation_pass = 0 (* Consensus operations *) in + let* () = call_and_check_operation ~validation_pass get_name client in + let* () = + call_and_check_operations_validation_pass ~validation_pass get_name client + in + let* () = call_and_check_operations ~validation_pass get_name client in + call_and_check_block ~validation_pass get_name client + + let test_block_operation_consensus = + register_test + ~title:"Block consensus operations" + ~additionnal_tags:["block"; "operations"; "consensus"] + @@ fun protocol -> test_block_consensus Operation.Attestation protocol + + let test_block_double_consensus_evidence double_evidence_kind protocol = + let* node, client = Client.init_with_protocol ~protocol `Client () in + let* () = Client.bake_for_and_wait ~node client in + + let* op = + create_double_consensus_evidence + ~double_evidence_kind + ~use_legacy_name:false + client + in + let* (`OpHash _) = Operation.inject ~request:`Inject op client in + let* () = Client.bake_for_and_wait ~node client in + + let get_name = Operation.Anonymous.kind_to_string double_evidence_kind in + let validation_pass = 2 (* Anonymous operations *) in + let* () = call_and_check_block ~validation_pass get_name client in + let* () = call_and_check_operation ~validation_pass get_name client in + let* () = + call_and_check_operations_validation_pass ~validation_pass get_name client + in + let* () = call_and_check_operations ~validation_pass get_name client in + call_and_check_block ~validation_pass get_name client + + let test_block_operation_double_consensus_evidence = + register_test + ~title:"Block double consensus evidence operations" + ~additionnal_tags: + ["block"; "operations"; "consensus"; "double"; "evidence"] + @@ fun protocol -> + test_block_double_consensus_evidence + Operation.Anonymous.Double_attestation_evidence + protocol + + let test_block_operation_double_preconsensus_evidence = + register_test + ~title:"Block double preconsensus evidence operations" + ~additionnal_tags: + ["block"; "operations"; "consensus"; "pre"; "double"; "evidence"] + @@ fun protocol -> + test_block_double_consensus_evidence + Operation.Anonymous.Double_preattestation_evidence + protocol + + let register ~protocols = + test_block_operation_consensus protocols + (* There is no test for preconsensus since crafting a block with + preconsensus operations in it may be complicated to do. *) ; + test_block_operation_double_consensus_evidence protocols ; + test_block_operation_double_preconsensus_evidence protocols +end + let register ~protocols = Forge.register ~protocols ; Parse.register ~protocols ; Mempool.register ~protocols ; Run_Simulate.register ~protocols ; - Preapply.register ~protocols + Preapply.register ~protocols ; + Block.register ~protocols