diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index 071e355a4f034146db58a16d81b0a143004899a6..34559136108319e443abeb599420c7f2d678e14a 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -176,12 +176,14 @@ module Handler = struct in return @@ Node_context.set_profile_ctxt ctxt pctxt in - Node_context.set_ready - ctxt - plugin - cryptobox - proto_parameters - block_header.Block_header.shell.proto_level ; + let*? () = + Node_context.set_ready + ctxt + plugin + cryptobox + proto_parameters + block_header.Block_header.shell.proto_level + in (* FIXME: https://gitlab.com/tezos/tezos/-/issues/4441 The hook below should be called each time cryptobox parameters diff --git a/src/bin_dal_node/errors.ml b/src/bin_dal_node/errors.ml index 7e711bf2e7b72d21116d0615fbc362930d7fdecc..e805bc8d7a9764d0364f8cd2327c40c328fe8a3a 100644 --- a/src/bin_dal_node/errors.ml +++ b/src/bin_dal_node/errors.ml @@ -25,7 +25,10 @@ (** Extention of the open type [error] with the errors that could be raised by the DAL node. *) -type error += Decoding_failed of Types.kind | Profile_incompatibility +type error += + | Decoding_failed of Types.kind + | Profile_incompatibility + | Invalid_slot_index of {slot_index : int; number_of_slots : int} (* TODO: https://gitlab.com/tezos/tezos/-/issues/4622 @@ -56,7 +59,25 @@ let () = profiles." Data_encoding.empty (function Profile_incompatibility -> Some () | _ -> None) - (fun () -> Profile_incompatibility) + (fun () -> Profile_incompatibility) ; + register_error_kind + `Permanent + ~id:"dal.node.invalid_slot_index" + ~title:"Invalid slot index" + ~description:"Invalid slot index provided for the producer profile" + ~pp:(fun ppf (slot_index, number_of_slots) -> + Format.fprintf + ppf + "The slot index (%d) should be smaller than the number of slots (%d)" + slot_index + number_of_slots) + Data_encoding.(obj2 (req "slot_index" int16) (req "number_of_slots" int16)) + (function + | Invalid_slot_index {slot_index; number_of_slots} -> + Some (slot_index, number_of_slots) + | _ -> None) + (fun (slot_index, number_of_slots) -> + Invalid_slot_index {slot_index; number_of_slots}) (** This part defines and handles more elaborate errors for the DAL node. *) diff --git a/src/bin_dal_node/errors.mli b/src/bin_dal_node/errors.mli index 94f7878d29d793ff9d1c2249635e03ad773d6227..0a20b66833de6c256cef25799285ed0d0072e566 100644 --- a/src/bin_dal_node/errors.mli +++ b/src/bin_dal_node/errors.mli @@ -25,7 +25,10 @@ (** Extention of the open type [error] with the errors that could be raised by the DAL node. *) -type error += Decoding_failed of Types.kind | Profile_incompatibility +type error += + | Decoding_failed of Types.kind + | Profile_incompatibility + | Invalid_slot_index of {slot_index : int; number_of_slots : int} (** The errors below are used to extend tzresult/tztrace monad/errors with Some specific errors on which we'd like to match in the DAL node's code. *) diff --git a/src/bin_dal_node/node_context.ml b/src/bin_dal_node/node_context.ml index 0d3bf882a13c2f4c286e887404a6d0c4c984cea3..f0a272464bf147ae5f6c4cdaad784051eaba808a 100644 --- a/src/bin_dal_node/node_context.ml +++ b/src/bin_dal_node/node_context.ml @@ -79,6 +79,7 @@ let init config store gs_worker transport_layer cctxt metrics_server = } let set_ready ctxt plugin cryptobox proto_parameters plugin_proto = + let open Result_syntax in match ctxt.status with | Starting -> (* FIXME: https://gitlab.com/tezos/tezos/-/issues/5743 @@ -88,6 +89,11 @@ let set_ready ctxt plugin cryptobox proto_parameters plugin_proto = let shards_proofs_precomputation = Cryptobox.precompute_shards_proofs cryptobox in + let* () = + Profile_manager.validate_slot_indexes + ctxt.profile_ctxt + ~number_of_slots:proto_parameters.Dal_plugin.number_of_slots + in ctxt.status <- Ready { @@ -97,7 +103,8 @@ let set_ready ctxt plugin cryptobox proto_parameters plugin_proto = shards_proofs_precomputation; plugin_proto; last_seen_head = None; - } + } ; + return_unit | Ready _ -> raise Status_already_ready let update_plugin_in_ready ctxt plugin proto = diff --git a/src/bin_dal_node/node_context.mli b/src/bin_dal_node/node_context.mli index aa102109cbfabf1dcb3f52d7a5cd67098a93b948..2aa9e351b5c6ac588cf6761ca6414e61490fc140 100644 --- a/src/bin_dal_node/node_context.mli +++ b/src/bin_dal_node/node_context.mli @@ -79,7 +79,7 @@ val set_ready : Cryptobox.t -> Dal_plugin.proto_parameters -> int -> - unit + unit tzresult (** Updates the plugin and the protocol level. *) val update_plugin_in_ready : diff --git a/src/bin_dal_node/profile_manager.ml b/src/bin_dal_node/profile_manager.ml index 8ef5bcb8f9dbba730a6f0a0ff3838a442b4fdd34..388cff6d387216ac27fe13bf0ea78571df99bd9f 100644 --- a/src/bin_dal_node/profile_manager.ml +++ b/src/bin_dal_node/profile_manager.ml @@ -74,6 +74,18 @@ let add_operator_profiles t proto_parameters gs_worker in Some (Operator operator_sets) +let validate_slot_indexes t ~number_of_slots = + let open Result_syntax in + match t with + | Bootstrap -> return_unit + | Operator o -> ( + match + Slot_set.find_first (fun i -> i < 0 || i >= number_of_slots) o.producers + with + | Some slot_index -> + tzfail (Errors.Invalid_slot_index {slot_index; number_of_slots}) + | None -> return_unit) + (* TODO https://gitlab.com/tezos/tezos/-/issues/5934 We need a mechanism to ease the tracking of newly added/removed topics. *) let join_topics_for_producer gs_worker committee producers = diff --git a/src/bin_dal_node/profile_manager.mli b/src/bin_dal_node/profile_manager.mli index b4903c29897f02460c924dc188dc4867917481a2..69ae6dc06b83c1db848ad1e868bee824b8f13615 100644 --- a/src/bin_dal_node/profile_manager.mli +++ b/src/bin_dal_node/profile_manager.mli @@ -45,6 +45,12 @@ val add_operator_profiles : Services.Types.operator_profiles -> t option +(** Checks that each producer profile only refers to slot indexes strictly + smaller than [number_of_slots]. This may not be the case when the profile + context is first built because there is no information about the number of + slots. Returns an [Invalid_slot_index] error if the check fails. *) +val validate_slot_indexes : t -> number_of_slots:int -> unit tzresult + (** [on_new_head t proto_parameters gs_worker committee] performs profile-related actions that depend on the current head, more precisely on the current committee. *) val on_new_head :