diff --git a/src/bin_dal_node/constants.ml b/src/bin_dal_node/constants.ml index 8158207892ed52a1320e7bead56fdb56c3a8cdba..f64a9f2549517a65c59f85ade796f079aad81707 100644 --- a/src/bin_dal_node/constants.ml +++ b/src/bin_dal_node/constants.ml @@ -89,3 +89,6 @@ let crawler_retries_on_disconnection = 5 disconnection error is encountered while retrieving data from L1 outside the {!Layer1.iter_heads} callback. *) let crawler_re_processing_delay = 5. + +(* Sleep delay between refreshing the ips associated to bootstrap dns names *) +let bootstrap_dns_refresh_delay = 300. diff --git a/src/bin_dal_node/constants.mli b/src/bin_dal_node/constants.mli index 3bbb214ca6320cc3d990833ddde1115f8750fee2..78e12e6de6963c0e81f8ea19f3c07c11e93b6e1e 100644 --- a/src/bin_dal_node/constants.mli +++ b/src/bin_dal_node/constants.mli @@ -78,3 +78,6 @@ val crawler_retries_on_disconnection : int disconnection error is encountered while retrieving data from L1 outside the {!Layer1.iter_heads} callback. *) val crawler_re_processing_delay : float + +(* Sleep delay between refreshing the ips associated to bootstrap dns names *) +val bootstrap_dns_refresh_delay : float diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index 3539ca79c30a9e01cfebb7fb131624a8228b4ca0..da20989ddf2c4480c498b97eb5f207c5aa6a2ad1 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -1081,13 +1081,44 @@ let run ~data_dir ~configuration_override = return configuration in let*! () = Event.(emit configuration_loaded) () in - let cctxt = Rpc_context.make endpoint in let* dal_config = fetch_dal_config cctxt in + let bootstrap_names = points @ dal_config.bootstrap_peers in + let*! () = + if bootstrap_names = [] then Event.(emit config_error_no_bootstrap) () + else Lwt.return_unit + in (* Resolve: - [points] from DAL node config file and CLI. - [dal_config.bootstrap_peers] from the L1 network config. *) - let* points = resolve (points @ dal_config.bootstrap_peers) in + (* Update the list of bootstrap every 5 minutes *) + let* get_bootstrap_points = + let* current_points = resolve bootstrap_names in + let bootstrap_points = ref current_points in + let rec loop () = + catch_es + (fun () -> + let* current_points = resolve bootstrap_names in + let*! () = + if current_points = [] then + Event.(emit resolved_bootstrap_no_points) () + else + Event.( + emit resolved_bootstrap_points (List.length current_points)) + in + bootstrap_points := current_points ; + let*! () = Lwt_unix.sleep Constants.bootstrap_dns_refresh_delay in + loop ()) + ~catch_only:(function Lwt.Canceled -> true | _ -> false) + in + let dns_job = loop () in + let (_ : Lwt_exit.clean_up_callback_id) = + Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _exit_status -> + let () = Lwt.cancel dns_job in + Lwt.return_unit) + in + return (fun () -> !bootstrap_points) + in (* Create and start a GS worker *) let gs_worker = let rng = @@ -1130,7 +1161,7 @@ let run ~data_dir ~configuration_override = let gs_worker = Gossipsub.Worker.( make - ~bootstrap_points:points + ~bootstrap_points:get_bootstrap_points ~events_logging:Logging.event rng limits @@ -1139,6 +1170,7 @@ let run ~data_dir ~configuration_override = Gossipsub.Worker.start [] gs_worker ; gs_worker in + let points = get_bootstrap_points () in (* Create a transport (P2P) layer instance. *) let* transport_layer = let open Transport_layer_parameters in diff --git a/src/bin_dal_node/event.ml b/src/bin_dal_node/event.ml index 65dd16dce32faadcb255ffe703e698198a3c0b84..fdced3482ff9e7953a8cfc76daf855cb41f03cf5 100644 --- a/src/bin_dal_node/event.ml +++ b/src/bin_dal_node/event.ml @@ -99,6 +99,31 @@ let retry_fetching_node_config_notice = let retry_fetching_node_config_warning = retry_fetching_node_config Internal_event.Warning "warning" +let config_error_no_bootstrap = + declare_0 + ~section + ~name:"config_error_no_bootstrap" + ~msg: + "no bootstrap peers found in the configuration file or network settings" + ~level:Error + () + +let resolved_bootstrap_no_points = + declare_0 + ~section + ~name:"resolved_bootstrap_no_points" + ~msg:"no bootstrap points could be resolved" + ~level:Error + () + +let resolved_bootstrap_points = + declare_1 + ~section + ~name:"resolved_bootstrap_points" + ~msg:"resolved {number} bootstrap points" + ~level:Notice + ("number", Data_encoding.int31) + let fetched_config_success = declare_1 ~section diff --git a/src/lib_gossipsub/gossipsub_intf.ml b/src/lib_gossipsub/gossipsub_intf.ml index fbccf417e27b12c6d14ed15704dec3b864fa7190..7459a5bf3c3cccc35e7900caac268ed86e57b797 100644 --- a/src/lib_gossipsub/gossipsub_intf.ml +++ b/src/lib_gossipsub/gossipsub_intf.ml @@ -1175,12 +1175,12 @@ module type WORKER = sig (** [make ~events_logging ~bootstrap_points rng limits parameters] initializes a new Gossipsub automaton with the given arguments. Then, it initializes and returns a worker for it. The [events_logging] function can be used to - define a handler for logging the worker's events. The list of - [bootstrap_points] represents the list of initially known peers' addresses - to which we may want to reconnect in the worker. *) + define a handler for logging the worker's events. [bootstrap_points] + allows to resolve a list of known peers' addresses to which we may want + to reconnect in the worker. *) val make : ?events_logging:(event -> unit Monad.t) -> - ?bootstrap_points:Point.t list -> + ?bootstrap_points:(unit -> Point.t list) -> Random.State.t -> (GS.Topic.t, GS.Peer.t, GS.Message_id.t, GS.span) limits -> (GS.Peer.t, GS.Message_id.t) parameters -> diff --git a/src/lib_gossipsub/gossipsub_worker.ml b/src/lib_gossipsub/gossipsub_worker.ml index be9a3aec24fe4bf5beee649a210db637646ed236..c659644c4d91b7cf27235a91602a8026cf0a3c82 100644 --- a/src/lib_gossipsub/gossipsub_worker.ml +++ b/src/lib_gossipsub/gossipsub_worker.ml @@ -272,7 +272,7 @@ module Make (C : Gossipsub_intf.WORKER_CONFIGURATION) : type worker_state = { stats : Introspection.stats; gossip_state : GS.state; - bootstrap_points : Point.Set.t; + bootstrap_points : unit -> Point.t list; trusted_peers : Peer.Set.t; connected_bootstrap_peers : Peer.Set.t; events_stream : event Stream.t; @@ -655,9 +655,12 @@ module Make (C : Gossipsub_intf.WORKER_CONFIGURATION) : |> emit_p2p_output state ~mk_output:(fun trusted_peer -> Connect {peer = trusted_peer; origin = Trusted}) ; let p2p_output_stream = state.p2p_output_stream in + let bootstrap_points = + state.bootstrap_points () |> Point.Set.of_list + in Point.Set.iter (fun point -> Stream.push (Connect_point {point}) p2p_output_stream) - state.bootstrap_points) ; + bootstrap_points) ; state let update_gossip_state state (gossip_state, output) = @@ -876,12 +879,12 @@ module Make (C : Gossipsub_intf.WORKER_CONFIGURATION) : event_loop_promise let make ?(events_logging = fun _event -> Monad.return ()) - ?(bootstrap_points = []) rng limits parameters = + ?(bootstrap_points = fun () -> []) rng limits parameters = { status = Starting; state = { - bootstrap_points = Point.Set.of_list bootstrap_points; + bootstrap_points; stats = Introspection.empty_stats (); gossip_state = GS.make rng limits parameters; trusted_peers = Peer.Set.empty;