From 759425491f580f7a3dcd0ae90190a06330eed3da Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Mon, 22 May 2023 15:51:20 +0200 Subject: [PATCH 1/6] proto_alpha/plugin: add versioning to parse operations RPC --- src/proto_alpha/lib_plugin/RPC.ml | 124 ++++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 25 deletions(-) diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index 5e769604fee7..292ddfaa939a 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -34,15 +34,6 @@ open Environment.Error_monad the actual time when the operation is included in a block. *) let default_operation_inclusion_latency = 3 -let parse_operation (op : Operation.raw) = - match - Data_encoding.Binary.of_bytes_opt - Operation.protocol_data_encoding_with_legacy_attestation_name - op.proto - with - | Some protocol_data -> ok {shell = op.shell; protocol_data} - | None -> error Plugin_errors.Cannot_parse_operation - let path = RPC_path.(open_root / "helpers") let elab_conf = @@ -2866,16 +2857,66 @@ module Parse = struct let path = RPC_path.(path / "parse") + type version = Version_0 | Version_1 + + let string_of_version = function Version_0 -> "0" | Version_1 -> "1" + + let version_of_string = function + | "0" -> Ok Version_0 + | "1" -> Ok Version_1 + | _ -> Error "Cannot parse version (supported versions \"0\" and \"1\")" + + let default_parse_operations_version = Version_0 + + let version_arg = + let open RPC_arg in + make + ~name:"version" + ~destruct:version_of_string + ~construct:string_of_version + () + + let operations_query = + let open RPC_query in + query (fun version -> + object + method version = version + end) + |+ field "version" version_arg default_parse_operations_version (fun t -> + t#version) + |> 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)); + ] + let operations = RPC_service.post_service ~description:"Parse operations" - ~query:RPC_query.empty + ~query:operations_query ~input: (obj2 (req "operations" (list (dynamic_size Operation.raw_encoding))) (opt "check_signature" bool)) - ~output: - (list (dynamic_size Operation.encoding_with_legacy_attestation_name)) + ~output:parse_operations_encoding RPC_path.(path / "operations") let block = @@ -2896,26 +2937,59 @@ module Parse = struct | None -> Stdlib.failwith "Cant_parse_protocol_data" | Some protocol_data -> protocol_data + let parse_operation (op : Operation.raw) = + match + Data_encoding.Binary.of_bytes_opt + Operation.protocol_data_encoding_with_legacy_attestation_name + op.proto + with + | Some protocol_data -> ok {shell = op.shell; protocol_data} + | None -> error Plugin_errors.Cannot_parse_operation + let register () = + let open Lwt_result_syntax in Registration.register0 ~chunked:true S.operations - (fun _ctxt () (operations, check) -> - List.map_es - (fun raw -> - parse_operation raw >>?= fun op -> - (match check with - | Some true -> return_unit (* FIXME *) - (* I.check_signature ctxt *) - (* op.protocol_data.signature op.shell op.protocol_data.contents *) - | Some false | None -> return_unit) - >|=? fun () -> op) - operations) ; + (fun _ctxt params (operations, check) -> + let* ops = + List.map_es + (fun raw -> + let*? op = parse_operation raw in + let () = + match check with + | Some true -> () + (* FIXME: https://gitlab.com/tezos/tezos/-/issues/5702 + The signature of the parsed operation should be properly + checked *) + (* I.check_signature ctxt *) + (* op.protocol_data.signature op.shell op.protocol_data.contents *) + | Some false | None -> () + in + return op) + operations + in + let version = params#version in + return (version, ops)) ; Registration.register0_noctxt ~chunked:false S.block (fun () raw_block -> return @@ parse_protocol_data raw_block.protocol_data) - let operations ctxt block ?check operations = - RPC_context.make_call0 S.operations ctxt block () (operations, check) + let operations ctxt block ?(version = S.default_parse_operations_version) + ?check operations = + let open Lwt_result_syntax in + let*! v = + RPC_context.make_call0 + S.operations + ctxt + block + (object + method version = version + end) + (operations, check) + in + match v with + | Error e -> fail e + | Ok ((Version_0 | Version_1), parse_operation) -> return parse_operation let block ctxt block shell protocol_data = RPC_context.make_call0 -- GitLab From f356d16ce8e1ddcb4b0a589b61f58fd19ac29501 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Tue, 23 May 2023 14:26:18 +0200 Subject: [PATCH 2/6] tezt/lib_tezos: add parse operations RPC helper --- tezt/lib_tezos/RPC.ml | 13 +++++++++++++ tezt/lib_tezos/RPC.mli | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/tezt/lib_tezos/RPC.ml b/tezt/lib_tezos/RPC.ml index 2bc5ff586849..3e8d88a4cd13 100644 --- a/tezt/lib_tezos/RPC.ml +++ b/tezt/lib_tezos/RPC.ml @@ -506,6 +506,19 @@ let post_chain_block_helpers_forge_block_header ?(chain = "main") ["chains"; chain; "blocks"; block; "helpers"; "forge_block_header"] Fun.id +let post_chain_block_helpers_parse_operations ?(chain = "main") + ?(block = "head") ?(check_signature = true) ?version ops = + let query_string = Query_arg.opt "version" Fun.id version in + let data : RPC_core.data = + Data (`O [("operations", ops); ("check_signature", `Bool check_signature)]) + in + make + ~query_string + ~data + POST + ["chains"; chain; "blocks"; block; "helpers"; "parse"; "operations"] + Fun.id + let post_chain_block_helpers_scripts_simulate_operation ?(chain = "main") ?(block = "head") ~data () = make diff --git a/tezt/lib_tezos/RPC.mli b/tezt/lib_tezos/RPC.mli index 4d1a02608919..c0fd1fd7b038 100644 --- a/tezt/lib_tezos/RPC.mli +++ b/tezt/lib_tezos/RPC.mli @@ -519,6 +519,20 @@ val post_chain_block_helpers_forge_operations : val post_chain_block_helpers_forge_block_header : ?chain:string -> ?block:string -> data:data -> unit -> JSON.t t +(** RPC: [POST /chains//blocks//helpers/parse/operations] + + [chain] defaults to ["main"]. + [block] defaults to ["head"]. + [check_signature] defaults to [true]. +*) +val post_chain_block_helpers_parse_operations : + ?chain:string -> + ?block:string -> + ?check_signature:bool -> + ?version:string -> + JSON.u -> + JSON.t t + (** RPC: [POST /chains//blocks//helpers/scripts/simulate_operation] [chain] defaults to ["main"]. -- GitLab From c24619cbb700828acef5881e2613a949f13149c7 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Wed, 31 May 2023 09:43:04 +0200 Subject: [PATCH 3/6] tezt/tests: modularize rpc_versioning_attestation.ml --- tezt/tests/rpc_versioning_attestation.ml | 393 ++++++++++++----------- 1 file changed, 200 insertions(+), 193 deletions(-) diff --git a/tezt/tests/rpc_versioning_attestation.ml b/tezt/tests/rpc_versioning_attestation.ml index 79bb68a81c1a..0771ec683c38 100644 --- a/tezt/tests/rpc_versioning_attestation.ml +++ b/tezt/tests/rpc_versioning_attestation.ml @@ -57,226 +57,233 @@ let check_kind json kind = if not (String.equal json_kind kind) then Test.fail ~__LOC__ "Operation should have %s kind, got: %s" kind json_kind -let check_hex_from_ops op1 op2 client = - Log.info - "Ensures that Bytes returned from calling the forge RPC on both operations \ - are identical" ; - let* (`Hex op1_raw) = Operation.hex op1 client in - let* (`Hex op2_raw) = Operation.hex op2 client in - if not (String.equal op1_raw op2_raw) then - Test.fail ~__LOC__ "Bytes are not equal, got: %s and: %s" op1_raw op2_raw - else unit +let create_consensus_op ~use_legacy_name ~signer ~kind client = + let consensus_name = + Operation.Consensus.kind_to_string kind use_legacy_name + in + Log.info "Create an %s operation" consensus_name ; + let consensus = mk_consensus kind use_legacy_name in + let* consensus_op = Operation.Consensus.operation ~signer consensus client in + + Log.info "Ensures that the generated JSON contains the %s kind" consensus_name ; + let consensus_json = + JSON.annotate ~origin:__LOC__ @@ Operation.json consensus_op + in + check_kind consensus_json consensus_name ; + Lwt.return consensus_op -let test_consensus kind protocol = - let* _node, client = Client.init_with_protocol ~protocol `Client () in - let signer = Constant.bootstrap1 in +module Forge = struct + let check_hex_from_ops op1 op2 client = + Log.info + "Ensures that Bytes returned from calling the forge RPC on both \ + operations are identical" ; + let* (`Hex op1_raw) = Operation.hex op1 client in + let* (`Hex op2_raw) = Operation.hex op2 client in + if not (String.equal op1_raw op2_raw) then + Test.fail ~__LOC__ "Bytes are not equal, got: %s and: %s" op1_raw op2_raw + else unit - let create_consensus_op ~use_legacy_name = - let consensus_name = - Operation.Consensus.kind_to_string kind use_legacy_name + let test_consensus kind protocol = + let* _node, client = Client.init_with_protocol ~protocol `Client () in + let signer = Constant.bootstrap1 in + + let* legacy_consensus_op = + create_consensus_op ~use_legacy_name:true ~signer ~kind client in - Log.info "Create an %s operation" consensus_name ; - let consensus = mk_consensus kind use_legacy_name in let* consensus_op = - Operation.Consensus.operation ~signer consensus client + create_consensus_op ~use_legacy_name:false ~signer ~kind client in + check_hex_from_ops legacy_consensus_op consensus_op client - Log.info - "Ensures that the generated JSON contains the %s kind" - consensus_name ; - let consensus_json = - JSON.annotate ~origin:__LOC__ @@ Operation.json consensus_op - in - check_kind consensus_json consensus_name ; - Lwt.return consensus_op - in + let test_forge_consensus = + register_test + ~title:"Forge consensus operations" + ~additionnal_tags:["forge"; "operations"; "consensus"] + @@ fun protocol -> test_consensus Operation.Attestation protocol - let* legacy_consensus_op = create_consensus_op ~use_legacy_name:true in - let* consensus_op = create_consensus_op ~use_legacy_name:false in - check_hex_from_ops legacy_consensus_op consensus_op client + let test_forge_preconsensus = + register_test + ~title:"Forge pre-consensus operations" + ~additionnal_tags:["forge"; "operations"; "consensus"; "pre"] + @@ fun protocol -> test_consensus Operation.Preattestation protocol -let test_forge_consensus = - register_test - ~title:"Forge consensus operations" - ~additionnal_tags:["forge"; "operations"; "consensus"] - @@ fun protocol -> test_consensus Operation.Attestation protocol + let mk_double_consensus_evidence kind use_legacy_name op1 op2 client = + let* op1_sign = Operation.sign op1 client in + let* op2_sign = Operation.sign op2 client in + return + (Operation.Anonymous.double_consensus_evidence + ~kind + ~use_legacy_name + (op1, op1_sign) + (op2, op2_sign)) -let test_forge_preconsensus = - register_test - ~title:"Forge pre-consensus operations" - ~additionnal_tags:["forge"; "operations"; "consensus"; "pre"] - @@ fun protocol -> test_consensus Operation.Preattestation protocol + let test_double_consensus_evidence double_evidence_kind protocol = + let* _node, client = Client.init_with_protocol ~protocol `Client () in -let mk_double_consensus_evidence kind use_legacy_name op1 op2 client = - let* op1_sign = Operation.sign op1 client in - let* op2_sign = Operation.sign op2 client in - return - (Operation.Anonymous.double_consensus_evidence - ~kind - ~use_legacy_name - (op1, op1_sign) - (op2, op2_sign)) + let create_double_consensus_evidence ~use_legacy_name = + let consensus_kind = + match double_evidence_kind with + | Operation.Anonymous.Double_attestation_evidence -> + Operation.Attestation + | Operation.Anonymous.Double_preattestation_evidence -> + Operation.Preattestation + in + let consensus_name = + Operation.Anonymous.kind_to_string double_evidence_kind use_legacy_name + in + Log.info "Create an %s operation" consensus_name ; -let test_double_consensus_evidence double_evidence_kind protocol = - let* _node, client = Client.init_with_protocol ~protocol `Client () in + let signer = Constant.bootstrap1 in + let consensus1 = mk_consensus consensus_kind use_legacy_name in + let* op1 = Operation.Consensus.operation ~signer consensus1 client in + let consensus2 = mk_consensus ~slot:2 consensus_kind use_legacy_name in + let* op2 = Operation.Consensus.operation ~signer consensus2 client in + let* double_consensus_evidence = + mk_double_consensus_evidence + double_evidence_kind + use_legacy_name + op1 + op2 + client + in + let* double_consensus_evidence_op = + Operation.Anonymous.operation double_consensus_evidence client + in - let create_double_consensus_evidence ~use_legacy_name = - let consensus_kind = - match double_evidence_kind with - | Operation.Anonymous.Double_attestation_evidence -> Operation.Attestation - | Operation.Anonymous.Double_preattestation_evidence -> - Operation.Preattestation + Log.info + "Ensures that the generated JSON contains the %s kind" + consensus_name ; + let consensus_json = + JSON.annotate ~origin:__LOC__ + @@ Operation.json double_consensus_evidence_op + in + check_kind consensus_json consensus_name ; + Lwt.return double_consensus_evidence_op in - let consensus_name = - Operation.Anonymous.kind_to_string double_evidence_kind use_legacy_name - in - Log.info "Create an %s operation" consensus_name ; - let signer = Constant.bootstrap1 in - let consensus1 = mk_consensus consensus_kind use_legacy_name in - let* op1 = Operation.Consensus.operation ~signer consensus1 client in - let consensus2 = mk_consensus ~slot:2 consensus_kind use_legacy_name in - let* op2 = Operation.Consensus.operation ~signer consensus2 client in - let* double_consensus_evidence = - mk_double_consensus_evidence - double_evidence_kind - use_legacy_name - op1 - op2 - client + let* legacy_double_consensus_evidence_op = + create_double_consensus_evidence ~use_legacy_name:true in let* double_consensus_evidence_op = - Operation.Anonymous.operation double_consensus_evidence client + create_double_consensus_evidence ~use_legacy_name:false in + check_hex_from_ops + legacy_double_consensus_evidence_op + double_consensus_evidence_op + client - Log.info - "Ensures that the generated JSON contains the %s kind" - consensus_name ; - let consensus_json = - JSON.annotate ~origin:__LOC__ - @@ Operation.json double_consensus_evidence_op - in - check_kind consensus_json consensus_name ; - Lwt.return double_consensus_evidence_op - in + let test_forge_double_consensus_evidence = + register_test + ~title:"Forge double consensus evidence operations" + ~additionnal_tags: + ["forge"; "operations"; "consensus"; "double"; "evidence"] + @@ fun protocol -> + test_double_consensus_evidence + Operation.Anonymous.Double_attestation_evidence + protocol - let* legacy_double_consensus_evidence_op = - create_double_consensus_evidence ~use_legacy_name:true - in - let* double_consensus_evidence_op = - create_double_consensus_evidence ~use_legacy_name:false - in - check_hex_from_ops - legacy_double_consensus_evidence_op - double_consensus_evidence_op - client + let test_forge_double_preconsensus_evidence = + register_test + ~title:"Forge double pre-consensus evidence operations" + ~additionnal_tags: + ["forge"; "operations"; "consensus"; "pre"; "double"; "evidence"] + @@ fun protocol -> + test_double_consensus_evidence + Operation.Anonymous.Double_preattestation_evidence + protocol -let test_forge_double_consensus_evidence = - register_test - ~title:"Forge double consensus evidence operations" - ~additionnal_tags:["forge"; "operations"; "consensus"; "double"; "evidence"] - @@ fun protocol -> - test_double_consensus_evidence - Operation.Anonymous.Double_attestation_evidence - protocol + let test_invalid_double_consensus_evidence double_evidence_kind protocol = + let* _node, client = Client.init_with_protocol ~protocol `Client () in -let test_forge_double_preconsensus_evidence = - register_test - ~title:"Forge double pre-consensus evidence operations" - ~additionnal_tags: - ["forge"; "operations"; "consensus"; "pre"; "double"; "evidence"] - @@ fun protocol -> - test_double_consensus_evidence - Operation.Anonymous.Double_preattestation_evidence - protocol + let create_double_consensus_evidence ~use_legacy_name = + let consensus_kind = + match double_evidence_kind with + | Operation.Anonymous.Double_attestation_evidence -> + Operation.Attestation + | Operation.Anonymous.Double_preattestation_evidence -> + Operation.Preattestation + in + let consensus_name = + Operation.Anonymous.kind_to_string double_evidence_kind use_legacy_name + in + Log.info "Create an %s operation" consensus_name ; -let test_invalid_double_consensus_evidence double_evidence_kind protocol = - let* _node, client = Client.init_with_protocol ~protocol `Client () in + let signer = Constant.bootstrap1 in + let consensus1 = mk_consensus consensus_kind use_legacy_name in + let* op1 = Operation.Consensus.operation ~signer consensus1 client in + let consensus2 = + mk_consensus ~slot:2 consensus_kind (not use_legacy_name) + in + let* op2 = Operation.Consensus.operation ~signer consensus2 client in + let* double_consensus_evidence = + mk_double_consensus_evidence + double_evidence_kind + use_legacy_name + op1 + op2 + client + in + let* double_consensus_evidence_op = + Operation.Anonymous.operation double_consensus_evidence client + in - let create_double_consensus_evidence ~use_legacy_name = - let consensus_kind = - match double_evidence_kind with - | Operation.Anonymous.Double_attestation_evidence -> Operation.Attestation - | Operation.Anonymous.Double_preattestation_evidence -> - Operation.Preattestation - in - let consensus_name = - Operation.Anonymous.kind_to_string double_evidence_kind use_legacy_name - in - Log.info "Create an %s operation" consensus_name ; + Log.info + "Ensures that the generated JSON contains the %s kind" + consensus_name ; + let consensus_json = Operation.json double_consensus_evidence_op in + let annotated_json = JSON.annotate ~origin:__LOC__ @@ consensus_json in + check_kind annotated_json consensus_name ; - let signer = Constant.bootstrap1 in - let consensus1 = mk_consensus consensus_kind use_legacy_name in - let* op1 = Operation.Consensus.operation ~signer consensus1 client in - let consensus2 = - mk_consensus ~slot:2 consensus_kind (not use_legacy_name) - in - let* op2 = Operation.Consensus.operation ~signer consensus2 client in - let* double_consensus_evidence = - mk_double_consensus_evidence - double_evidence_kind - use_legacy_name - op1 - op2 - client + Log.info + "Ensures that the generated JSON cannot be parsed by the forge RPC" ; + let*? t = + RPC.Client.spawn client + @@ RPC.post_chain_block_helpers_forge_operations + ~data:(Data consensus_json) + () + in + let msg = rex "Failed to parse the request body: No case matched:" in + Process.check_error ~msg t in - let* double_consensus_evidence_op = - Operation.Anonymous.operation double_consensus_evidence client - in - - Log.info - "Ensures that the generated JSON contains the %s kind" - consensus_name ; - let consensus_json = Operation.json double_consensus_evidence_op in - let annotated_json = JSON.annotate ~origin:__LOC__ @@ consensus_json in - check_kind annotated_json consensus_name ; - Log.info "Ensures that the generated JSON cannot be parsed by the forge RPC" ; - let*? t = - RPC.Client.spawn client - @@ RPC.post_chain_block_helpers_forge_operations - ~data:(Data consensus_json) - () - in - let msg = rex "Failed to parse the request body: No case matched:" in - Process.check_error ~msg t - in + let* () = create_double_consensus_evidence ~use_legacy_name:true in + create_double_consensus_evidence ~use_legacy_name:false - let* () = create_double_consensus_evidence ~use_legacy_name:true in - create_double_consensus_evidence ~use_legacy_name:false + let test_forge_invalid_double_consensus_evidence = + register_test + ~title:"Forge invalid double consensus evidence operations" + ~additionnal_tags: + ["forge"; "operations"; "consensus"; "double"; "evidence"; "invalid"] + @@ fun protocol -> + test_invalid_double_consensus_evidence + Operation.Anonymous.Double_attestation_evidence + protocol -let test_forge_invalid_double_consensus_evidence = - register_test - ~title:"Forge invalid double consensus evidence operations" - ~additionnal_tags: - ["forge"; "operations"; "consensus"; "double"; "evidence"; "invalid"] - @@ fun protocol -> - test_invalid_double_consensus_evidence - Operation.Anonymous.Double_attestation_evidence - protocol + let test_forge_invalid_double_preconsensus_evidence = + register_test + ~title:"Forge invalid double pre-consensus evidence operations" + ~additionnal_tags: + [ + "forge"; + "operations"; + "consensus"; + "pre"; + "double"; + "evidence"; + "invalid"; + ] + @@ fun protocol -> + test_invalid_double_consensus_evidence + Operation.Anonymous.Double_preattestation_evidence + protocol -let test_forge_invalid_double_preconsensus_evidence = - register_test - ~title:"Forge invalid double pre-consensus evidence operations" - ~additionnal_tags: - [ - "forge"; - "operations"; - "consensus"; - "pre"; - "double"; - "evidence"; - "invalid"; - ] - @@ fun protocol -> - test_invalid_double_consensus_evidence - Operation.Anonymous.Double_preattestation_evidence - protocol + let register ~protocols = + test_forge_consensus protocols ; + test_forge_preconsensus protocols ; + test_forge_double_consensus_evidence protocols ; + test_forge_double_preconsensus_evidence protocols ; + test_forge_invalid_double_consensus_evidence protocols ; + test_forge_invalid_double_preconsensus_evidence protocols +end -let register ~protocols = - test_forge_consensus protocols ; - test_forge_preconsensus protocols ; - test_forge_double_consensus_evidence protocols ; - test_forge_double_preconsensus_evidence protocols ; - test_forge_invalid_double_consensus_evidence protocols ; - test_forge_invalid_double_preconsensus_evidence protocols +let register ~protocols = Forge.register ~protocols -- GitLab From 3713100e8858a6e9c521395a62e13c73f1f13c62 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Tue, 23 May 2023 14:28:09 +0200 Subject: [PATCH 4/6] tezt/tests: add parse_operations rpc tests for consensus operations using both the `attestation` and `endorsement` naming --- tezt/tests/rpc_versioning_attestation.ml | 74 +++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/tezt/tests/rpc_versioning_attestation.ml b/tezt/tests/rpc_versioning_attestation.ml index 0771ec683c38..fc9039be7c86 100644 --- a/tezt/tests/rpc_versioning_attestation.ml +++ b/tezt/tests/rpc_versioning_attestation.ml @@ -286,4 +286,76 @@ module Forge = struct test_forge_invalid_double_preconsensus_evidence protocols end -let register ~protocols = Forge.register ~protocols +module Parse = struct + let parse_operations_rpc ~version raw = + RPC.post_chain_block_helpers_parse_operations + ~version + (`A [JSON.unannotate raw]) + + let check_parsed_kind kind json = + check_kind JSON.(json |> as_list |> List.hd) kind + + let create_raw_op ~protocol op client = + Log.info "Sign and forge the operation" ; + let* signature = Operation.sign op client in + let* (`Hex h1) = Operation.hex ~signature op client in + Log.info + "Use octez-codec to retrieve the raw representation of the operation \ + from its hexadecimal representation" ; + Codec.decode + ~name:(Protocol.encoding_prefix protocol ^ "." ^ "operation.raw") + h1 + + let check_version ~use_legacy_name name raw client = + let* t = + RPC.Client.call client + @@ parse_operations_rpc + ~version:(if use_legacy_name then "0" else "1") + raw + in + return (check_parsed_kind name t) + + let check_unknown_version raw client = + let version = "2" in + let*? p = RPC.Client.spawn client @@ parse_operations_rpc ~version raw in + let msg = rex (sf "Failed to parse argument 'version'") in + Process.check_error ~msg p + + let test_parse kind protocol = + let* _node, client = Client.init_with_protocol ~protocol `Client () in + let signer = Constant.bootstrap1 in + + let* consensus_op = + create_consensus_op ~use_legacy_name:false ~signer ~kind client + in + let* raw = create_raw_op ~protocol consensus_op client in + + let check_version ~use_legacy_name = + let name = Operation.Consensus.kind_to_string kind use_legacy_name in + check_version ~use_legacy_name name raw client + in + + let* () = check_version ~use_legacy_name:true in + let* () = check_version ~use_legacy_name:false in + check_unknown_version raw client + + let test_parse_consensus = + register_test + ~title:"Parse raw consensus operations" + ~additionnal_tags:["parse"; "raw"; "operations"; "consensus"] + @@ fun protocol -> test_parse Operation.Attestation protocol + + let test_parse_preconsensus = + register_test + ~title:"Parse raw pre-consensus operations" + ~additionnal_tags:["parse"; "raw"; "operations"; "consensus"; "pre"] + @@ fun protocol -> test_parse Operation.Preattestation protocol + + let register ~protocols = + test_parse_consensus protocols ; + test_parse_preconsensus protocols +end + +let register ~protocols = + Forge.register ~protocols ; + Parse.register ~protocols -- GitLab From 2f69c209bfe03c628362ba1e0454eae09dc463aa Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Tue, 23 May 2023 14:29:02 +0200 Subject: [PATCH 5/6] tezt/tests: add parse_operations rpc tests for double consensus operations using both the `attestation` and `endorsement` naming --- tezt/tests/rpc_versioning_attestation.ml | 157 +++++++++++++++-------- 1 file changed, 103 insertions(+), 54 deletions(-) diff --git a/tezt/tests/rpc_versioning_attestation.ml b/tezt/tests/rpc_versioning_attestation.ml index fc9039be7c86..5bfafdf0384a 100644 --- a/tezt/tests/rpc_versioning_attestation.ml +++ b/tezt/tests/rpc_versioning_attestation.ml @@ -72,6 +72,53 @@ let create_consensus_op ~use_legacy_name ~signer ~kind client = check_kind consensus_json consensus_name ; Lwt.return consensus_op +let mk_double_consensus_evidence kind use_legacy_name op1 op2 client = + let* op1_sign = Operation.sign op1 client in + let* op2_sign = Operation.sign op2 client in + return + (Operation.Anonymous.double_consensus_evidence + ~kind + ~use_legacy_name + (op1, op1_sign) + (op2, op2_sign)) + +let create_double_consensus_evidence ~use_legacy_name ~double_evidence_kind + client = + let consensus_kind = + match double_evidence_kind with + | Operation.Anonymous.Double_attestation_evidence -> Operation.Attestation + | Operation.Anonymous.Double_preattestation_evidence -> + Operation.Preattestation + in + let consensus_name = + Operation.Anonymous.kind_to_string double_evidence_kind use_legacy_name + in + Log.info "Create an %s operation" consensus_name ; + + let signer = Constant.bootstrap1 in + let consensus1 = mk_consensus consensus_kind use_legacy_name in + let* op1 = Operation.Consensus.operation ~signer consensus1 client in + let consensus2 = mk_consensus ~slot:2 consensus_kind use_legacy_name in + let* op2 = Operation.Consensus.operation ~signer consensus2 client in + let* double_consensus_evidence = + mk_double_consensus_evidence + double_evidence_kind + use_legacy_name + op1 + op2 + client + in + let* double_consensus_evidence_op = + Operation.Anonymous.operation double_consensus_evidence client + in + + Log.info "Ensures that the generated JSON contains the %s kind" consensus_name ; + let consensus_json = + JSON.annotate ~origin:__LOC__ @@ Operation.json double_consensus_evidence_op + in + check_kind consensus_json consensus_name ; + Lwt.return double_consensus_evidence_op + module Forge = struct let check_hex_from_ops op1 op2 client = Log.info @@ -107,65 +154,20 @@ module Forge = struct ~additionnal_tags:["forge"; "operations"; "consensus"; "pre"] @@ fun protocol -> test_consensus Operation.Preattestation protocol - let mk_double_consensus_evidence kind use_legacy_name op1 op2 client = - let* op1_sign = Operation.sign op1 client in - let* op2_sign = Operation.sign op2 client in - return - (Operation.Anonymous.double_consensus_evidence - ~kind - ~use_legacy_name - (op1, op1_sign) - (op2, op2_sign)) - let test_double_consensus_evidence double_evidence_kind protocol = let* _node, client = Client.init_with_protocol ~protocol `Client () in - let create_double_consensus_evidence ~use_legacy_name = - let consensus_kind = - match double_evidence_kind with - | Operation.Anonymous.Double_attestation_evidence -> - Operation.Attestation - | Operation.Anonymous.Double_preattestation_evidence -> - Operation.Preattestation - in - let consensus_name = - Operation.Anonymous.kind_to_string double_evidence_kind use_legacy_name - in - Log.info "Create an %s operation" consensus_name ; - - let signer = Constant.bootstrap1 in - let consensus1 = mk_consensus consensus_kind use_legacy_name in - let* op1 = Operation.Consensus.operation ~signer consensus1 client in - let consensus2 = mk_consensus ~slot:2 consensus_kind use_legacy_name in - let* op2 = Operation.Consensus.operation ~signer consensus2 client in - let* double_consensus_evidence = - mk_double_consensus_evidence - double_evidence_kind - use_legacy_name - op1 - op2 - client - in - let* double_consensus_evidence_op = - Operation.Anonymous.operation double_consensus_evidence client - in - - Log.info - "Ensures that the generated JSON contains the %s kind" - consensus_name ; - let consensus_json = - JSON.annotate ~origin:__LOC__ - @@ Operation.json double_consensus_evidence_op - in - check_kind consensus_json consensus_name ; - Lwt.return double_consensus_evidence_op - in - let* legacy_double_consensus_evidence_op = - create_double_consensus_evidence ~use_legacy_name:true + create_double_consensus_evidence + ~use_legacy_name:true + ~double_evidence_kind + client in let* double_consensus_evidence_op = - create_double_consensus_evidence ~use_legacy_name:false + create_double_consensus_evidence + ~use_legacy_name:false + ~double_evidence_kind + client in check_hex_from_ops legacy_double_consensus_evidence_op @@ -351,9 +353,56 @@ module Parse = struct ~additionnal_tags:["parse"; "raw"; "operations"; "consensus"; "pre"] @@ fun protocol -> test_parse Operation.Preattestation protocol + let test_parse_double_evidence double_evidence_kind protocol = + let* _node, client = Client.init_with_protocol ~protocol `Client () in + + let create_raw_double_consensus_evidence () = + let* double_consensus_evidence_op = + create_double_consensus_evidence + ~use_legacy_name:false + ~double_evidence_kind + client + in + create_raw_op ~protocol double_consensus_evidence_op client + in + let* raw = create_raw_double_consensus_evidence () in + + let check_version ~use_legacy_name = + let name = + Operation.Anonymous.kind_to_string double_evidence_kind use_legacy_name + in + check_version ~use_legacy_name name raw client + in + + let* () = check_version ~use_legacy_name:true in + let* () = check_version ~use_legacy_name:false in + check_unknown_version raw client + + let test_parse_double_consensus_evidence = + register_test + ~title:"Parse raw double consensus evidence operations" + ~additionnal_tags: + ["parse"; "raw"; "operations"; "double"; "consensus"; "evidence"] + @@ fun protocol -> + test_parse_double_evidence + Operation.Anonymous.Double_attestation_evidence + protocol + + let test_parse_double_preconsensus_evidence = + register_test + ~title:"Parse raw double pre-consensus evidence operations" + ~additionnal_tags: + ["parse"; "raw"; "operations"; "double"; "consensus"; "pre"; "evidence"] + @@ fun protocol -> + test_parse_double_evidence + Operation.Anonymous.Double_preattestation_evidence + protocol + let register ~protocols = test_parse_consensus protocols ; - test_parse_preconsensus protocols + test_parse_preconsensus protocols ; + test_parse_double_consensus_evidence protocols ; + test_parse_double_preconsensus_evidence protocols end let register ~protocols = -- GitLab From 414beb28998365bd133b0f9512945c8360709830 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Wed, 24 May 2023 09:26:05 +0200 Subject: [PATCH 6/6] changes: add entry for new version parameter of parse/operations RPC --- CHANGES.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index dadc66fefe44..0a7d9926eb05 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -82,6 +82,12 @@ Node - Fixed a bug where the node could freeze when an old block was requested during a store merge. (MR :gl:`!8952`)` +- Added version ``1`` to RPC ``POST ../helpers/parse/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:`!8840`) + Client ------ - Adding client commands to generate, open and verify a time-lock. -- GitLab