From dd55e8348d486685dc17a56cee0659f431e6bac7 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Tue, 16 May 2023 13:44:51 +0200 Subject: [PATCH 1/6] proto_alpha/plugin: run/simulate_operation can take operations with attestation or endorsements kinds in the JSON formatted operation --- src/proto_alpha/lib_plugin/RPC.ml | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index 292ddfaa939a..e2973a4dbc70 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -409,6 +409,23 @@ module Scripts = struct ~query:RPC_query.empty RPC_path.(path / "normalize_type") + let operations_encodings = + union + [ + case + ~title:"operations_encoding" + (Tag 0) + Operation.encoding + Option.some + Fun.id; + case + ~title:"operations_encoding_with_legacy_attestation_name" + Json_only + Operation.encoding_with_legacy_attestation_name + Option.some + Fun.id; + ] + let run_operation = RPC_service.post_service ~description: @@ -419,7 +436,7 @@ module Scripts = struct ~query:RPC_query.empty ~input: (obj2 - (req "operation" Operation.encoding_with_legacy_attestation_name) + (req "operation" operations_encodings) (req "chain_id" Chain_id.encoding)) ~output: Apply_results @@ -454,7 +471,7 @@ module Scripts = struct ~input: (obj4 (opt "blocks_before_activation" int32) - (req "operation" Operation.encoding_with_legacy_attestation_name) + (req "operation" operations_encodings) (req "chain_id" Chain_id.encoding) (dft "latency" int16 default_operation_inclusion_latency)) ~output: -- GitLab From 55e7a7e35481c78a41d42cf22fc5b1c34e6abe05 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Tue, 16 May 2023 16:10:37 +0200 Subject: [PATCH 2/6] tezt/tests: add run/simulate_operation rpc tests for consensus operations using both the `attestation` and `endorsement` naming --- tezt/tests/rpc_versioning_attestation.ml | 87 +++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/tezt/tests/rpc_versioning_attestation.ml b/tezt/tests/rpc_versioning_attestation.ml index b7b60dcf1455..0b1da216528e 100644 --- a/tezt/tests/rpc_versioning_attestation.ml +++ b/tezt/tests/rpc_versioning_attestation.ml @@ -26,7 +26,8 @@ (* Testing ------- Component: RPCs - Invocation: dune exec tezt/tests/main.exe -- --file rpc_versioning.ml + Invocation: dune exec tezt/tests/main.exe -- --file + rpc_versioning_attestation.ml Subject: rpc versioning *) @@ -512,7 +513,89 @@ module Mempool = struct test_pending_double_preconsensus_evidence protocols end +module Run_Simulate = struct + type rpc = Run | Simulate + + let get_rpc rpc op = + match rpc with + | Run -> RPC.post_chain_block_helpers_scripts_run_operation (Data op) + | Simulate -> + RPC.post_chain_block_helpers_scripts_simulate_operation + ~data:(Data op) + () + + let get_rpc_name = function + | Run -> "run_operations" + | Simulate -> "simulate_operations" + + let test_rpc_operation_unsupported rpc kind protocol = + let* _node, client = Client.init_with_protocol ~protocol `Client () in + let signer = Constant.bootstrap1 in + + let call_rpc_operation_and_check_error op = + let* op_json = Operation.make_run_operation_input op client in + let msg = + rex + "Command failed: The run_operation RPC does not support consensus \ + operations." + (* both run_operation and simulate_operation returns the same error *) + in + let*? p = RPC.Client.spawn client @@ get_rpc rpc op_json in + Process.check_error ~msg p + in + + let call_and_check_error ~use_legacy_name = + Log.info + "Create a %s operation, call %s and check that the call fail" + (Operation.Consensus.kind_to_string kind use_legacy_name) + (get_rpc_name rpc) ; + + let* consensus_op = + create_consensus_op ~use_legacy_name ~signer ~kind client + in + call_rpc_operation_and_check_error consensus_op + in + + let* () = call_and_check_error ~use_legacy_name:true in + call_and_check_error ~use_legacy_name:false + + let test_run_operation_consensus = + register_test + ~title:"Run operation with consensus operations" + ~additionnal_tags:["run"; "operations"; "consensus"] + @@ fun protocol -> + test_rpc_operation_unsupported Run Operation.Attestation protocol + + let test_run_operation_preconsensus = + register_test + ~title:"Run operation with preconsensus operations" + ~additionnal_tags:["run"; "operations"; "pre"; "consensus"] + @@ fun protocol -> + test_rpc_operation_unsupported Run Operation.Preattestation protocol + + let test_simulate_operation_consensus = + register_test + ~title:"Simulate operation with consensus operations" + ~additionnal_tags:["simulate"; "operations"; "consensus"] + @@ fun protocol -> + test_rpc_operation_unsupported Simulate Operation.Attestation protocol + + let test_simulate_operation_preconsensus = + register_test + ~title:"Simulate operation with preconsensus operations" + ~additionnal_tags:["simulate"; "operations"; "pre"; "consensus"] + @@ fun protocol -> + test_rpc_operation_unsupported Simulate Operation.Preattestation protocol + + let register ~protocols = + test_run_operation_consensus protocols ; + test_run_operation_preconsensus protocols ; + test_simulate_operation_consensus protocols ; + test_simulate_operation_preconsensus protocols +end + let register ~protocols = Forge.register ~protocols ; Parse.register ~protocols ; - Mempool.register ~protocols + Mempool.register ~protocols ; + Run_Simulate.register ~protocols -- GitLab From fde595ab7a8600e704fc89724b37dd5d1eee34d8 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Wed, 31 May 2023 10:46:53 +0200 Subject: [PATCH 3/6] tezt/lib_tezos: export and fix operation hash function from helper --- tezt/lib_tezos/operation_core.ml | 17 ++++++++--------- tezt/lib_tezos/operation_core.mli | 3 +++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/tezt/lib_tezos/operation_core.ml b/tezt/lib_tezos/operation_core.ml index 4bd48201f0c4..46becfb67ffc 100644 --- a/tezt/lib_tezos/operation_core.ml +++ b/tezt/lib_tezos/operation_core.ml @@ -114,16 +114,15 @@ let sign ?protocol ({kind; signer; _} as t) client = module Tezos_operation = Tezos_base.TzPervasives.Operation -let to_raw_operation t client : Tezos_operation.t Lwt.t = - let open Tezos_base.TzPervasives in - let branch = Block_hash.of_b58check_exn t.branch in - let* raw = hex t client in - return Tezos_operation.{shell = {branch}; proto = Hex.to_bytes_exn raw} - let hash t client : [`OpHash of string] Lwt.t = - let* op = to_raw_operation t client in - let hash = Tezos_operation.hash op in - return (`OpHash (Tezos_crypto.Hashed.Operation_hash.to_string hash)) + let* signature = sign t client in + let* (`Hex hex) = hex ~signature t client in + let bytes = Hex.to_bytes (`Hex hex) in + let op = + Data_encoding.Binary.of_bytes_exn Tezos_base.Operation.encoding bytes + in + let hash = Tezos_base.Operation.hash op in + return (`OpHash (Tezos_crypto.Hashed.Operation_hash.to_b58check hash)) let inject ?(request = `Inject) ?(force = false) ?protocol ?signature ?error t client : [`OpHash of string] Lwt.t = diff --git a/tezt/lib_tezos/operation_core.mli b/tezt/lib_tezos/operation_core.mli index f9ba93be0ec3..cc95ef5efd25 100644 --- a/tezt/lib_tezos/operation_core.mli +++ b/tezt/lib_tezos/operation_core.mli @@ -108,6 +108,9 @@ val hex : val sign : ?protocol:Protocol.t -> t -> Client.t -> Tezos_crypto.Signature.t Lwt.t +(** [hash t client] returns the hash of the operation *) +val hash : t -> Client.t -> [`OpHash of string] Lwt.t + (** [inject ?(request=`Inject) ?(force=false) ?(signature=None) ?(error=None) t] injects an operation into the node. The node is extracted from the [Client]. If a node cannot be extracted, the -- GitLab From 77115a04dd82db3dadf7315f7b8e4e8d3c60de14 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Wed, 31 May 2023 10:47:54 +0200 Subject: [PATCH 4/6] tezt/tests: factorize double_consensus_evidence helper in rpc_versioning_attestation.ml --- tezt/tests/rpc_versioning_attestation.ml | 64 ++++++++++++++++++++---- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/tezt/tests/rpc_versioning_attestation.ml b/tezt/tests/rpc_versioning_attestation.ml index 0b1da216528e..d7bdde071395 100644 --- a/tezt/tests/rpc_versioning_attestation.ml +++ b/tezt/tests/rpc_versioning_attestation.ml @@ -39,6 +39,23 @@ let register_test ~title ?(additionnal_tags = []) f = ~tags:(["rpc"; "versioning"] @ additionnal_tags) f +let get_consensus_info delegate client = + let* level = Client.level client in + let* slots = + RPC.Client.call client + @@ RPC.get_chain_block_helper_validators ~delegate ~level () + in + let slots = + List.map + JSON.as_int + JSON.(List.hd JSON.(slots |> as_list) |-> "slots" |> as_list) + in + let* block_header = RPC.Client.call client @@ RPC.get_chain_block_header () in + let block_payload_hash = + JSON.(block_header |-> "payload_hash" |> as_string) + in + return (level, slots, block_payload_hash) + let mk_consensus ?(slot = 1) ?(level = 1) ?(round = 0) ?(block_payload_hash = "vh1g87ZG6scSYxKhspAUzprQVuLAyoa5qMBKcUfjgnQGnFb3dJcG") kind @@ -58,12 +75,15 @@ 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 create_consensus_op ~use_legacy_name ~signer ~kind client = +let create_consensus_op ?slot ?level ?round ?block_payload_hash ~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 = + mk_consensus ?slot ?level ?round ?block_payload_hash 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 ; @@ -96,11 +116,33 @@ let create_double_consensus_evidence ~use_legacy_name ~double_evidence_kind in Log.info "Create an %s operation" consensus_name ; + let* level, slots, block_payload_hash = + get_consensus_info Constant.bootstrap1.public_key_hash client + in let signer = Constant.bootstrap1 in - let consensus1 = mk_consensus consensus_kind use_legacy_name in + let consensus1 = + mk_consensus + ~level + ~block_payload_hash + ~slot:(List.nth slots 1) + 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* (`OpHash oph1) = Operation.hash op1 client in + let consensus2 = + mk_consensus + ~level + ~block_payload_hash + ~slot:(List.nth slots 2) + consensus_kind + use_legacy_name + in let* op2 = Operation.Consensus.operation ~signer consensus2 client in + let* (`OpHash oph2) = Operation.hash op2 client in + let op1, op2 = + if String.compare oph1 oph2 < 1 then (op1, op2) else (op2, op1) + in let* double_consensus_evidence = mk_double_consensus_evidence double_evidence_kind @@ -156,7 +198,8 @@ module Forge = struct @@ 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* node, client = Client.init_with_protocol ~protocol `Client () in + let* () = Client.bake_for_and_wait ~node client in let* legacy_double_consensus_evidence_op = create_double_consensus_evidence @@ -196,7 +239,8 @@ module Forge = struct protocol let test_invalid_double_consensus_evidence double_evidence_kind protocol = - let* _node, client = Client.init_with_protocol ~protocol `Client () in + let* node, client = Client.init_with_protocol ~protocol `Client () in + let* () = Client.bake_for_and_wait ~node client in let create_double_consensus_evidence ~use_legacy_name = let consensus_kind = @@ -355,7 +399,8 @@ module Parse = struct @@ 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* node, client = Client.init_with_protocol ~protocol `Client () in + let* () = Client.bake_for_and_wait ~node client in let create_raw_double_consensus_evidence () = let* double_consensus_evidence_op = @@ -449,7 +494,8 @@ module Mempool = struct let test_pending_operations_double_consensus_evidence double_evidence_kind protocol = - let* _node, client = Client.init_with_protocol ~protocol `Client () in + let* node, client = Client.init_with_protocol ~protocol `Client () in + let* () = Client.bake_for_and_wait ~node client in let* consensus_op = create_double_consensus_evidence @@ -470,7 +516,7 @@ module Mempool = struct in return (check_kind - JSON.(mempool_json |-> "refused" |> as_list |> List.hd) + JSON.(mempool_json |-> "applied" |> as_list |> List.hd) (Operation.Anonymous.kind_to_string double_evidence_kind use_legacy_name)) -- GitLab From d8bf2901490741202616a4650060a52fa04253e1 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Wed, 31 May 2023 10:09:09 +0200 Subject: [PATCH 5/6] tezt/tests: add run/simulate_operation rpc tests for double consensus operations using both the `attestation` and `endorsement` naming --- tezt/tests/rpc_versioning_attestation.ml | 71 +++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/tezt/tests/rpc_versioning_attestation.ml b/tezt/tests/rpc_versioning_attestation.ml index d7bdde071395..bee1811802b1 100644 --- a/tezt/tests/rpc_versioning_attestation.ml +++ b/tezt/tests/rpc_versioning_attestation.ml @@ -633,11 +633,80 @@ module Run_Simulate = struct @@ fun protocol -> test_rpc_operation_unsupported Simulate Operation.Preattestation protocol + let test_rpc_double_consensus_evidence rpc double_evidence_kind protocol = + let* node, client = Client.init_with_protocol ~protocol `Client () in + let* () = Client.bake_for_and_wait ~node client in + + let call_and_check_error ~use_legacy_name = + Log.info + "Create a %s operation and call %s " + (Operation.Anonymous.kind_to_string + double_evidence_kind + use_legacy_name) + (get_rpc_name rpc) ; + + let* consensus_op = + create_double_consensus_evidence + ~use_legacy_name + ~double_evidence_kind + client + in + let* op_json = Operation.make_run_operation_input consensus_op client in + let* _ = RPC.Client.call client @@ get_rpc rpc op_json in + unit + in + let* () = call_and_check_error ~use_legacy_name:true in + call_and_check_error ~use_legacy_name:false + + let test_run_operation_double_consensus_evidence = + register_test + ~title:"Run operation with double consensus evidence operations" + ~additionnal_tags:["run"; "operations"; "consensus"; "double"] + @@ fun protocol -> + test_rpc_double_consensus_evidence + Run + Operation.Anonymous.Double_attestation_evidence + protocol + + let test_run_operation_double_preconsensus_evidence = + register_test + ~title:"Run operation with double preconsensus evidence operations" + ~additionnal_tags:["run"; "operations"; "consensus"; "pre"; "double"] + @@ fun protocol -> + test_rpc_double_consensus_evidence + Run + Operation.Anonymous.Double_preattestation_evidence + protocol + + let test_simulate_operation_double_consensus_evidence = + register_test + ~title:"Simulate operation with double consensus evidence operations" + ~additionnal_tags:["simulate"; "operations"; "consensus"; "double"] + @@ fun protocol -> + test_rpc_double_consensus_evidence + Simulate + Operation.Anonymous.Double_attestation_evidence + protocol + + let test_simulate_operation_double_preconsensus_evidence = + register_test + ~title:"Simulate operation with double preconsensus evidence operations" + ~additionnal_tags:["simulate"; "operations"; "consensus"; "pre"; "double"] + @@ fun protocol -> + test_rpc_double_consensus_evidence + Simulate + Operation.Anonymous.Double_preattestation_evidence + protocol + let register ~protocols = test_run_operation_consensus protocols ; test_run_operation_preconsensus protocols ; test_simulate_operation_consensus protocols ; - test_simulate_operation_preconsensus protocols + test_simulate_operation_preconsensus protocols ; + test_run_operation_double_consensus_evidence protocols ; + test_run_operation_double_preconsensus_evidence protocols ; + test_simulate_operation_double_consensus_evidence protocols ; + test_simulate_operation_double_preconsensus_evidence protocols end let register ~protocols = -- GitLab From f384e8d97ac196242afce89a6efffcf828e217e8 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Wed, 24 May 2023 09:16:01 +0200 Subject: [PATCH 6/6] changes: add entry for newly accepted kinds in run_operations and simulate_operations rpcs --- CHANGES.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 670a43f9270f..bae3efc707d1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -94,6 +94,13 @@ Node ``preattestation``, ``double_attestation_evidence`` and ``double_preattestation_evidence`` kinds in the JSON result. (MR :gl:`!8960`) +- RPCs ``/helpers/scripts/run_operation`` and + ``/helpers/scripts/simulate_operation`` can now take JSON formatted operations + with ``double_attestation_evidence`` and ``double_preattestation_evidence`` + kinds. Even though consensus operations are not supported by the RPCs, + ``attestation`` and ``preattestation`` are accepted in the input JSON. (MR + :gl:`!8768`) + Client ------ - Adding client commands to generate, open and verify a time-lock. -- GitLab