diff --git a/src/bin_dal_node/RPC_server.ml b/src/bin_dal_node/RPC_server.ml index 265e11633015cfd5cc419ec6707518b777ede7fe..5854ef2720770e4a3c41475f6d43c549446209f6 100644 --- a/src/bin_dal_node/RPC_server.ml +++ b/src/bin_dal_node/RPC_server.ml @@ -188,7 +188,8 @@ module Slots_handlers = struct | None | Some _ -> return_unit in let* proto_parameters = - Node_context.get_proto_parameters ctxt + Node_context.get_proto_parameters ctxt ~level:`Last_proto + |> Lwt.return |> lwt_map_error (fun e -> `Other e) in let slot_size = proto_parameters.cryptobox_parameters.slot_size in @@ -274,7 +275,8 @@ module Node = struct |> Store.last_processed_level |> Store.Last_processed_level.load let get_protocol_parameters ctxt level () = - Node_context.get_proto_parameters ?level ctxt + let level = match level with None -> `Last_proto | Some l -> `Level l in + Node_context.get_proto_parameters ~level ctxt |> Lwt.return end module Profile_handlers = struct @@ -287,7 +289,8 @@ module Profile_handlers = struct |> lwt_map_error (fun e -> `Other e) in let* proto_parameters = - Node_context.get_proto_parameters ctxt + Node_context.get_proto_parameters ctxt ~level:`Last_proto + |> Lwt.return |> lwt_map_error (fun e -> `Other e) in let number_of_slots = proto_parameters.Types.number_of_slots in @@ -469,7 +472,10 @@ module Profile_handlers = struct level may be in the future and we may not have the plugin for it. *) let* proto_parameters = - Node_context.get_proto_parameters ctxt ~level:published_level + Node_context.get_proto_parameters + ctxt + ~level:(`Level published_level) + |> Lwt.return |> lwt_map_error (fun e -> `Other e) in @@ -494,7 +500,10 @@ module Profile_handlers = struct List.map_es number_of_shards_stored all_slot_indexes in let* published_level_parameters = - Node_context.get_proto_parameters ctxt ~level:published_level + Node_context.get_proto_parameters + ctxt + ~level:(`Level published_level) + |> Lwt.return |> lwt_map_error (fun e -> `Other e) in let* flags = @@ -540,7 +549,8 @@ module Profile_handlers = struct |> Errors.other_lwt_result in let* proto_parameters = - Node_context.get_proto_parameters ctxt + Node_context.get_proto_parameters ctxt ~level:`Last_proto + |> Lwt.return |> lwt_map_error (fun e -> `Other e) in let store = Node_context.get_store ctxt in diff --git a/src/bin_dal_node/accuser.ml b/src/bin_dal_node/accuser.ml index 03d5cd23fb85746b24d74cb52bf0d318aba6ba9d..fdcce62421f0a83cb4eb002e5e1d20b8345a9ccf 100644 --- a/src/bin_dal_node/accuser.ml +++ b/src/bin_dal_node/accuser.ml @@ -74,8 +74,8 @@ let inject_entrapment_evidences (type block_info) rpc_ctxt block = let open Lwt_result_syntax in let attested_level = (Plugin.block_shell_header block).level in - let* proto_parameters = - Node_context.get_proto_parameters node_ctxt ~level:attested_level + let*? proto_parameters = + Node_context.get_proto_parameters node_ctxt ~level:(`Level attested_level) in when_ proto_parameters.incentives_enable (fun () -> let published_level = diff --git a/src/bin_dal_node/amplificator.ml b/src/bin_dal_node/amplificator.ml index 9ec6006351d81b217b5c4920798556977d5c5e63..3d86f6ebb0ff6cb065014e5c89b136af0988e81c 100644 --- a/src/bin_dal_node/amplificator.ml +++ b/src/bin_dal_node/amplificator.ml @@ -475,7 +475,11 @@ let try_amplification commitment slot_metrics slot_id amplificator = let open Lwt_result_syntax in let node_ctxt = amplificator.node_ctxt in let node_store = Node_context.get_store node_ctxt in - let* proto_parameters = Node_context.get_proto_parameters node_ctxt in + let*? proto_parameters = + Node_context.get_proto_parameters + node_ctxt + ~level:(`Level slot_id.Types.Slot_id.slot_level) + in let number_of_shards = proto_parameters.cryptobox_parameters.number_of_shards in diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index f72c0c43040de4793347d9032ed5ad312e71cc69..549acd26e7a72bcd163dcdde385640feb859012c 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -424,7 +424,10 @@ module Handler = struct ~dal_constants ~pred_publication_level_dal_constants: (lazy - (Node_context.get_proto_parameters ctxt ~level:pred_published_level)) + (Lwt.return + @@ Node_context.get_proto_parameters + ctxt + ~level:(`Level pred_published_level))) in let cells_of_level = List.map @@ -710,8 +713,8 @@ module Handler = struct ~proto_level:finalized_shell_header.proto_level ~block_level:level in - let* proto_parameters = - Node_context.get_proto_parameters ctxt ~level + let*? proto_parameters = + Node_context.get_proto_parameters ctxt ~level:(`Level level) in (* At each potential published_level [level], we prefetch the committee for its corresponding attestation_level (that is: @@ -1094,7 +1097,9 @@ let update_and_register_profiles ctxt = let open Lwt_result_syntax in let profile_ctxt = Node_context.get_profile_ctxt ctxt in let gs_worker = Node_context.get_gs_worker ctxt in - let* proto_parameters = Node_context.get_proto_parameters ctxt in + let*? proto_parameters = + Node_context.get_proto_parameters ctxt ~level:`Last_proto + in let profile_ctxt = Profile_manager.register_profile profile_ctxt @@ -1158,7 +1163,9 @@ let clean_up_store_and_catch_up ctxt cctxt ~last_processed_level let* block_info = Plugin.block_info cctxt ~block:(`Level level) ~metadata:`Always in - let* dal_constants = Node_context.get_proto_parameters ctxt ~level in + let*? dal_constants = + Node_context.get_proto_parameters ctxt ~level:(`Level level) + in Handler.store_skip_list_cells ctxt cctxt @@ -1397,14 +1404,15 @@ let run ~data_dir ~configuration_override = wait_for_block_with_plugin cctxt in let head_level = header.Block_header.shell.level in + let* proto_parameters = + Plugin.get_constants `Main (`Level head_level) cctxt + in let proto_plugins = Proto_plugins.singleton ~first_level:head_level ~proto_level:header.shell.proto_level (module Plugin) - in - let* proto_parameters = - Plugin.get_constants `Main (`Level head_level) cctxt + proto_parameters in (* Set proto number of slots hook. *) Value_size_hooks.set_number_of_slots proto_parameters.number_of_slots ; @@ -1457,7 +1465,6 @@ let run ~data_dir ~configuration_override = profile_ctxt cryptobox shards_proofs_precomputation - proto_parameters proto_plugins store gs_worker diff --git a/src/bin_dal_node/node_context.ml b/src/bin_dal_node/node_context.ml index 6d0c2f9194c466a817ccb4a8f977b7719fbbb424..7b58759a81aa6e978d0ce0a5cfe187702e9cc9e4 100644 --- a/src/bin_dal_node/node_context.ml +++ b/src/bin_dal_node/node_context.ml @@ -28,7 +28,6 @@ type t = { config : Configuration_file.t; cryptobox : Cryptobox.t; shards_proofs_precomputation : Cryptobox.shards_proofs_precomputation option; - proto_parameters : Types.proto_parameters; mutable proto_plugins : Proto_plugins.t; mutable ongoing_amplifications : Types.Slot_id.Set.t; mutable slots_under_reconstruction : @@ -46,8 +45,7 @@ type t = { } let init config profile_ctxt cryptobox shards_proofs_precomputation - proto_parameters proto_plugins store gs_worker transport_layer cctxt - ~last_finalized_level = + proto_plugins store gs_worker transport_layer cctxt ~last_finalized_level = let neighbors_cctxts = List.map (fun Configuration_file.{addr; port} -> @@ -61,7 +59,6 @@ let init config profile_ctxt cryptobox shards_proofs_precomputation config; cryptobox; shards_proofs_precomputation; - proto_parameters; proto_plugins; ongoing_amplifications = Types.Slot_id.Set.empty; slots_under_reconstruction = Types.Slot_id.Map.empty; @@ -108,22 +105,27 @@ let may_add_plugin ctxt cctxt ~block_level ~proto_level = ctxt.proto_plugins <- proto_plugins ; return_unit +let get_plugin_and_parameters_for_level ctxt ~level = + Proto_plugins.get_plugin_and_parameters_for_level ctxt.proto_plugins ~level + let get_plugin_for_level ctxt ~level = - Proto_plugins.get_plugin_for_level ctxt.proto_plugins ~level + let open Result_syntax in + let* plugin, _parameters = get_plugin_and_parameters_for_level ctxt ~level in + return plugin let get_all_plugins ctxt = Proto_plugins.to_list ctxt.proto_plugins let set_proto_plugins ctxt proto_plugins = ctxt.proto_plugins <- proto_plugins -let get_proto_parameters ?level ctxt = - let open Lwt_result_syntax in - match level with - | None -> return ctxt.proto_parameters - | Some level -> - (* get the plugin from the plugin cache *) - let*? (module Plugin) = get_plugin_for_level ctxt ~level in - let cctxt = get_tezos_node_cctxt ctxt in - Plugin.get_constants `Main (`Level level) cctxt +let get_proto_parameters ~level ctxt = + let open Result_syntax in + let level = + match level with + | `Last_proto -> ctxt.last_finalized_level + | `Level level -> level + in + let* _plugin, parameters = get_plugin_and_parameters_for_level ctxt ~level in + return parameters let storage_period ctxt proto_parameters = match ctxt.config.history_mode with @@ -194,9 +196,7 @@ let fetch_committee ctxt ~level = match Committee_cache.find cache ~level with | Some committee -> return committee | None -> - let*? (module Plugin) = - Proto_plugins.get_plugin_for_level ctxt.proto_plugins ~level - in + let*? (module Plugin) = get_plugin_for_level ctxt ~level in let+ committee = Plugin.get_committee cctxt ~level in Committee_cache.add cache ~level ~committee ; committee diff --git a/src/bin_dal_node/node_context.mli b/src/bin_dal_node/node_context.mli index 0f6d85d0c896ab3444d3252fc25d4ebdb591e3fa..e3666648a30d97d6d12d604af038dc477b73b8b7 100644 --- a/src/bin_dal_node/node_context.mli +++ b/src/bin_dal_node/node_context.mli @@ -34,7 +34,6 @@ val init : Profile_manager.t -> Cryptobox.t -> Cryptobox.shards_proofs_precomputation option -> - Types.proto_parameters -> Proto_plugins.t -> Store.t -> Gossipsub.Worker.t -> @@ -46,15 +45,23 @@ val init : (** Returns all the registered plugins *) val get_all_plugins : t -> (module Dal_plugin.T) list -(** Returns the plugin to be used for the given (block) level. +(** Returns the plugin to be used for the given (block) level together with the + protocol parameters at that level. + Recall that, for a migration level L: * to retrieve the metadata of the block L, one should use the plugin for the old protocol; * to retrieve context-related information, one should use the plugin for the new protocol. + This function returns the plugin of [metadata.protocols.next_protocol], so it is tailored for the second use case. To get the plugin for the first use-case, just get the plugin for the predecessor of the target level. *) +val get_plugin_and_parameters_for_level : + t -> level:int32 -> ((module Dal_plugin.T) * Types.proto_parameters) tzresult + +(** Returns the plugin to be used for the given (block) level. See + {!get_plugin_and_parameters_for_level}. *) val get_plugin_for_level : t -> level:int32 -> (module Dal_plugin.T) tzresult (** Tries to add a new plugin for the protocol with level [proto_level] to be used @@ -73,6 +80,14 @@ val may_add_plugin : (** Set the protocol plugins to the given value. *) val set_proto_plugins : t -> Proto_plugins.t -> unit +(** [get_proto_parameters ~level ctxt] returns the DAL node's protocol + parameters. When [level] is [`Last_proto], it returns the last known + parameters. If [level] is [`Level level], then the protocol parameters for + that level are returned. The parameters returned are obtained via + {!get_plugin_and_parameters_for_level}. *) +val get_proto_parameters : + level:[`Last_proto | `Level of int32] -> t -> Types.proto_parameters tzresult + (** Reconstruct the given slot id by calling the [reconstruct] function unless a reconstruction for the given slot id is alredy ongoing in which case the ongoing promise is returned instead. *) @@ -99,13 +114,6 @@ val get_config : t -> Configuration_file.t (** [get_cryptobox ctxt] returns the DAL node's cryptobox *) val get_cryptobox : t -> Cryptobox.t -(** [get_proto_parameters ?level ctxt] returns the DAL node's protocol - parameters stored in the context, when [level] is not provided. If [level] - is provided, then the protocol parameters for that level are fetched via the - relevant plugin. *) -val get_proto_parameters : - ?level:int32 -> t -> Types.proto_parameters tzresult Lwt.t - (** Update the node's last finalized level. *) val set_last_finalized_level : t -> int32 -> unit diff --git a/src/bin_dal_node/proto_plugins.ml b/src/bin_dal_node/proto_plugins.ml index 3a00a3c2e7f2b2eabe2e58c75d7e11067ba2213b..7bc0c06a3c85b44566a22dabf06ba2c2a5653257 100644 --- a/src/bin_dal_node/proto_plugins.ml +++ b/src/bin_dal_node/proto_plugins.ml @@ -13,18 +13,24 @@ module Plugins = struct let compare a b = compare b a end) - type proto_plugin = {proto_level : int; plugin : (module Dal_plugin.T)} + type proto_plugin = { + proto_level : int; + plugin : (module Dal_plugin.T); + proto_parameters : Types.proto_parameters; + } type t = proto_plugin LevelMap.t let empty = LevelMap.empty - let add t ~first_level ~proto_level plugin = - LevelMap.add first_level {proto_level; plugin} t + let add t ~first_level ~proto_level plugin proto_parameters = + LevelMap.add first_level {proto_level; plugin; proto_parameters} t let to_list t = LevelMap.bindings t - |> List.map (fun (_block_level, {proto_level = _; plugin}) -> plugin) + |> List.map + (fun (_block_level, {proto_level = _; plugin; proto_parameters = _}) -> + plugin) end let singleton = Plugins.add Plugins.empty @@ -78,11 +84,12 @@ let add_plugin_for_level cctxt plugins (protocols : Chain_services.Blocks.protocols) ~level = let open Lwt_result_syntax in let* plugin = resolve_plugin_by_hash protocols.next_protocol in - let+ header = - Shell_services.Blocks.Header.shell_header cctxt ~block:(`Level level) () - in + let block = `Level level in + let* header = Shell_services.Blocks.Header.shell_header cctxt ~block () in let proto_level = header.proto_level in - Plugins.add plugins ~first_level:level ~proto_level plugin + let (module Plugin) = plugin in + let+ proto_parameters = Plugin.get_constants `Main block cctxt in + Plugins.add plugins ~first_level:level ~proto_level plugin proto_parameters (* This function performs a (kind of) binary search to search for all values that satisfy the given condition [cond] on values. There is bijection between @@ -177,15 +184,20 @@ let initial_plugins cctxt ~first_level ~last_level = let may_add cctxt plugins ~first_level ~proto_level = let open Lwt_result_syntax in + let add first_level = + let* plugin = resolve_plugin_for_level cctxt ~level:first_level in + let (module Plugin) = plugin in + let+ proto_parameters = + Plugin.get_constants `Main (`Level first_level) cctxt + in + Plugins.add plugins ~proto_level ~first_level plugin proto_parameters + in let plugin_opt = Plugins.LevelMap.min_binding_opt plugins in match plugin_opt with - | None -> - let* plugin = resolve_plugin_for_level cctxt ~level:first_level in - Plugins.add plugins ~proto_level ~first_level plugin |> return + | None -> add first_level | Some (_, Plugins.{proto_level = prev_proto_level; _}) when prev_proto_level < proto_level -> - let* plugin = resolve_plugin_for_level cctxt ~level:first_level in - Plugins.add plugins ~proto_level ~first_level plugin |> return + add first_level | _ -> return plugins type error += No_plugin_for_level of {level : int32} @@ -205,7 +217,7 @@ let () = (* Say that [plugins = [(level_1, plugin_1); ... ; (level_n, plugin_n)]]. We have [level_1 > ... > level_n]. We return the plugin [plugin_i] with the smallest [i] such that [level_i <= level]. *) -let get_plugin_for_level plugins ~level = +let get_plugin_and_parameters_for_level plugins ~level = let open Result_syntax in let plugin_opt = Plugins.LevelMap.to_seq plugins @@ -213,6 +225,7 @@ let get_plugin_for_level plugins ~level = in match plugin_opt with | None -> tzfail @@ No_plugin_for_level {level} - | Some (_first_level, Plugins.{plugin; proto_level = _}) -> return plugin + | Some (_first_level, Plugins.{plugin; proto_level = _; proto_parameters}) -> + return (plugin, proto_parameters) include Plugins diff --git a/src/bin_dal_node/proto_plugins.mli b/src/bin_dal_node/proto_plugins.mli index a178674ccbec757dec3ab9f7d20bc250d33a8897..868efbb86c0607110fd1fabdd63b38dd2cdd1df3 100644 --- a/src/bin_dal_node/proto_plugins.mli +++ b/src/bin_dal_node/proto_plugins.mli @@ -16,7 +16,11 @@ type t (** It builds a value of type [t] containing a single plugin, given as parameter. *) val singleton : - first_level:int32 -> proto_level:int -> (module Dal_plugin.T) -> t + first_level:int32 -> + proto_level:int -> + (module Dal_plugin.T) -> + Types.proto_parameters -> + t val to_list : t -> (module Dal_plugin.T) list @@ -25,18 +29,20 @@ type error += | No_plugin_for_proto of {proto_hash : Protocol_hash.t} (** [get_plugin_for_level plugins ~level] searches in [plugins] the plugin for - the given [level] and returns it if found. Otherwise, it returns the error - [No plugin_for_level level]. + the given [level] and returns it if found together with the associated + protocol parameters. Otherwise, it returns the error [No plugin_for_level + level]. Recall that, for a migration level L: * to retrieve the metadata of the block L, one should use the plugin for the old protocol; * to retrieve context-related information, one should use the plugin for the new protocol. - This function returns the plugin of [metadata.protocols.next_protocol], so it is - tailored for the second use case. To get plugin for the first use-case, just - get the plugin for the predecessor of the target level. *) -val get_plugin_for_level : t -> level:int32 -> (module Dal_plugin.T) tzresult + This function returns the plugin of [metadata.protocols.next_protocol], so + it is tailored for the second use case. To get plugin for the first + use-case, just get the plugin for the predecessor of the target level. *) +val get_plugin_and_parameters_for_level : + t -> level:int32 -> ((module Dal_plugin.T) * Types.proto_parameters) tzresult (** [may_add rpc_ctxt plugins ~first_level ~proto_level] may add to [plugins] a new plugin for the protocol with level [proto_level] to be used starting diff --git a/src/bin_dal_node/slot_manager.ml b/src/bin_dal_node/slot_manager.ml index 24b9427d7e7c0fccfad8b1cd537871a1a570ef7a..66acbc47bd5d7fffc6b43b08a0d81d74ae97e379 100644 --- a/src/bin_dal_node/slot_manager.ml +++ b/src/bin_dal_node/slot_manager.ml @@ -401,7 +401,10 @@ let get_slot_shard (store : Store.t) (slot_id : Types.slot_id) shard_index = let get_slot_pages ~reconstruct_if_missing node_context slot_id = let open Lwt_result_syntax in let* proto_parameters = - Node_context.get_proto_parameters node_context + Node_context.get_proto_parameters + node_context + ~level:(`Level slot_id.Types.Slot_id.slot_level) + |> Lwt.return |> lwt_map_error (fun e -> `Other e) in let page_size = proto_parameters.cryptobox_parameters.page_size in