From 84a0214e0f104718e545fcf0eebf80910b54d6fa Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 22 Jan 2025 10:21:37 +0100 Subject: [PATCH 1/5] DAL/Plugin: add is_delegate function --- src/lib_dal_node/dal_plugin.ml | 5 +++++ src/lib_dal_node/dal_plugin.mli | 5 +++++ .../lib_dal/dal_plugin_registration.ml | 3 +++ .../lib_dal/dal_plugin_registration.ml | 11 +++++++++++ src/proto_alpha/lib_dal/dal_plugin_registration.ml | 11 +++++++++++ 5 files changed, 35 insertions(+) diff --git a/src/lib_dal_node/dal_plugin.ml b/src/lib_dal_node/dal_plugin.ml index 50abdc0a4e25..0a1ed7a0bf25 100644 --- a/src/lib_dal_node/dal_plugin.ml +++ b/src/lib_dal_node/dal_plugin.ml @@ -176,6 +176,11 @@ module type T = sig proof:Cryptobox.shard_proof -> unit tzresult Lwt.t + val is_delegate : + Tezos_rpc.Context.generic -> + pkh:Signature.Public_key_hash.t -> + bool tzresult Lwt.t + (* Section of helpers for Skip lists *) module Skip_list : sig diff --git a/src/lib_dal_node/dal_plugin.mli b/src/lib_dal_node/dal_plugin.mli index ab66a17f5e99..1e5fcb255e8c 100644 --- a/src/lib_dal_node/dal_plugin.mli +++ b/src/lib_dal_node/dal_plugin.mli @@ -139,6 +139,11 @@ module type T = sig proof:Cryptobox.shard_proof -> unit tzresult Lwt.t + val is_delegate : + Tezos_rpc.Context.generic -> + pkh:Signature.Public_key_hash.t -> + bool tzresult Lwt.t + (* Section of helpers for Skip lists *) module Skip_list : sig diff --git a/src/proto_020_PsParisC/lib_dal/dal_plugin_registration.ml b/src/proto_020_PsParisC/lib_dal/dal_plugin_registration.ml index bb9902374da0..03fbc81402ee 100644 --- a/src/proto_020_PsParisC/lib_dal/dal_plugin_registration.ml +++ b/src/proto_020_PsParisC/lib_dal/dal_plugin_registration.ml @@ -204,6 +204,9 @@ module Plugin = struct let is_attested attestation slot_index = match Bitset.mem attestation slot_index with Ok b -> b | Error _ -> false + let is_delegate _ctxt ~pkh:_ = + failwith "Plugin.ParisC.is_delegate is not available" + (* Section of helpers for Skip lists *) module Skip_list = struct diff --git a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml index bb6943c11d37..00fe7bcfed34 100644 --- a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml +++ b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml @@ -204,6 +204,17 @@ module Plugin = struct let is_attested attestation slot_index = match Bitset.mem attestation slot_index with Ok b -> b | Error _ -> false + let is_delegate ctxt ~pkh = + let open Lwt_result_syntax in + let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in + (* We just want to know whether is a delegate. We call + 'context/delegates//deactivated' just because it should be cheaper + than calling 'context/delegates//' (called [Delegate.info]). *) + let*! res = + Plugin.Alpha_services.Delegate.deactivated cpctxt (`Main, `Head 0) pkh + in + return @@ match res with Ok _deactivated -> true | Error _ -> false + (* Section of helpers for Skip lists *) module Skip_list = struct diff --git a/src/proto_alpha/lib_dal/dal_plugin_registration.ml b/src/proto_alpha/lib_dal/dal_plugin_registration.ml index 52c418c72fcc..f132674c363a 100644 --- a/src/proto_alpha/lib_dal/dal_plugin_registration.ml +++ b/src/proto_alpha/lib_dal/dal_plugin_registration.ml @@ -245,6 +245,17 @@ module Plugin = struct | Ok b -> b | Error _ -> false + let is_delegate ctxt ~pkh = + let open Lwt_result_syntax in + let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in + (* We just want to know whether is a delegate. We call + 'context/delegates//deactivated' just because it should be cheaper + than calling 'context/delegates//' (called [Delegate.info]). *) + let*! res = + Plugin.Alpha_services.Delegate.deactivated cpctxt (`Main, `Head 0) pkh + in + return @@ match res with Ok _deactivated -> true | Error _ -> false + (* Section of helpers for Skip lists *) module Skip_list = struct -- GitLab From 48a2619a9821a2a646bba5faa1d2259b661568c6 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Sat, 25 Jan 2025 07:15:44 +0100 Subject: [PATCH 2/5] DAL/Node: add function to warn when a pkh is not a delegate --- src/bin_dal_node/node_context.ml | 27 +++++++++++++++++++++++++++ src/bin_dal_node/node_context.mli | 7 +++++++ 2 files changed, 34 insertions(+) diff --git a/src/bin_dal_node/node_context.ml b/src/bin_dal_node/node_context.ml index 037b6dfa776f..8d1d5ba52222 100644 --- a/src/bin_dal_node/node_context.ml +++ b/src/bin_dal_node/node_context.ml @@ -202,6 +202,33 @@ let version {config; _} = let network_name = config.Configuration_file.network_name in Types.Version.make ~network_version:(Gossipsub.version ~network_name) +let warn_if_attesters_not_delegates ctxt ?level operator_profiles = + let open Lwt_result_syntax in + let pkh_set = Operator_profile.attesters operator_profiles in + if Signature.Public_key_hash.Set.is_empty pkh_set then return_unit + else + let* level_opt = + match level with + | Some _ -> return level + | None -> + let store = get_store ctxt in + let lpl_store = Store.last_processed_level store in + Store.Last_processed_level.load lpl_store + in + Option.iter_es + (fun level -> + let cctxt = get_tezos_node_cctxt ctxt in + let*? (module Plugin) = get_plugin_for_level ctxt ~level in + Signature.Public_key_hash.Set.iter_es + (fun pkh -> + let* is_delegate = Plugin.is_delegate cctxt ~pkh in + if not is_delegate then + let*! () = Event.(emit registered_pkh_not_a_delegate pkh) in + return_unit + else return_unit) + pkh_set) + level_opt + module P2P = struct let connect {transport_layer; _} ?timeout point = Gossipsub.Transport_layer.connect transport_layer ?timeout point diff --git a/src/bin_dal_node/node_context.mli b/src/bin_dal_node/node_context.mli index 628bb67694ce..34b83a9955c4 100644 --- a/src/bin_dal_node/node_context.mli +++ b/src/bin_dal_node/node_context.mli @@ -168,6 +168,13 @@ val fetch_committee : (** [version ctxt] returns the current version of the node *) val version : t -> Types.Version.t +(** Emit a warning for each public key hash in the given operator profile (if + any) that is not that of a L1-registered delegate. The optional [level] + argument is used to specify for which level to obtain the plugin; if not + given the last process level is used (if found in the store). *) +val warn_if_attesters_not_delegates : + t -> ?level:int32 -> Operator_profile.t -> unit tzresult Lwt.t + (** Module for P2P-related accessors. *) module P2P : sig (** [connect t ?timeout point] initiates a connection to the point -- GitLab From 9c28bc1b4da414438d1cb5e4fd91e10b4002ab28 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 22 Jan 2025 10:22:08 +0100 Subject: [PATCH 3/5] DAL/Node: warn if trying to register a pkh which is not a delegate --- src/bin_dal_node/RPC_server.ml | 4 ++++ src/bin_dal_node/daemon.ml | 9 +++++++++ src/bin_dal_node/event.ml | 10 ++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/bin_dal_node/RPC_server.ml b/src/bin_dal_node/RPC_server.ml index 523334ddd018..ed5ba21bce82 100644 --- a/src/bin_dal_node/RPC_server.ml +++ b/src/bin_dal_node/RPC_server.ml @@ -270,6 +270,10 @@ module Profile_handlers = struct let open Lwt_result_syntax in let gs_worker = Node_context.get_gs_worker ctxt in call_handler1 (fun () -> + let* () = + Node_context.warn_if_attesters_not_delegates ctxt operator_profiles + |> lwt_map_error (fun e -> `Other e) + in let proto_parameters = Node_context.get_proto_parameters ctxt in match Profile_manager.add_and_register_operator_profile diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index 9d21b270c8de..9d79b1274169 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -1374,6 +1374,15 @@ let run ~data_dir ~configuration_override = transport_layer cctxt in + let* () = + match Profile_manager.get_profiles profile_ctxt with + | Operator profile -> + Node_context.warn_if_attesters_not_delegates + ctxt + ~level:head_level + profile + | _ -> return_unit + in Gossipsub.Worker.Validate_message_hook.set (Handler.gossipsub_app_messages_validation ctxt diff --git a/src/bin_dal_node/event.ml b/src/bin_dal_node/event.ml index 3f25a693b768..5b427ba74991 100644 --- a/src/bin_dal_node/event.ml +++ b/src/bin_dal_node/event.ml @@ -800,3 +800,13 @@ let trap_delegate_attestation_not_found = ("shard_index", Data_encoding.int31) ("published_level", Data_encoding.int32) ("attested_level", Data_encoding.int32) + +let registered_pkh_not_a_delegate = + declare_1 + ~section + ~name:"register_pkh_not_a_delegate" + ~msg: + "The public key hash {pkh} registered by PATCH /profiles is not a \ + delegate." + ~level:Warning + ("pkh", Signature.Public_key_hash.encoding) -- GitLab From 862f9436694e959279b7d9db321759956e64cc9e Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Sat, 25 Jan 2025 07:26:47 +0100 Subject: [PATCH 4/5] DAL/Node: add reference to #7706 --- src/bin_dal_node/node_context.ml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bin_dal_node/node_context.ml b/src/bin_dal_node/node_context.ml index 8d1d5ba52222..3447e0f97d9d 100644 --- a/src/bin_dal_node/node_context.ml +++ b/src/bin_dal_node/node_context.ml @@ -202,6 +202,8 @@ let version {config; _} = let network_name = config.Configuration_file.network_name in Types.Version.make ~network_version:(Gossipsub.version ~network_name) +(* TODO: https://gitlab.com/tezos/tezos/-/issues/7706 + This level argument would not be needed if we had the head level in the context. *) let warn_if_attesters_not_delegates ctxt ?level operator_profiles = let open Lwt_result_syntax in let pkh_set = Operator_profile.attesters operator_profiles in -- GitLab From 758762d30be88fa08e6359bfaff22919dc2dc38d Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Tue, 28 Jan 2025 07:04:52 +0100 Subject: [PATCH 5/5] CHANGES: add corresponding entry --- CHANGES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 757e3f1615f1..8d202a0ad8bd 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -236,6 +236,9 @@ DAL node - **Breaking change** The baker daemon ``--dal-node-timeout-percentage`` argument has been removed. (MR :gl:`!15554`) +- A warning is emitted when registering a public key hash (as an attester + profile) that does not correspond to that of a delegate. (MR :gl:`!16336`) + Protocol ~~~~~~~~ -- GitLab