diff --git a/src/lib_client_base/client_confirmations.ml b/src/lib_client_base/client_confirmations.ml index 561e4bd9b04cdcf2e34c845cee6542bf3da6177d..ef9d1f1397dcfd5b71ce403b13ae454321a6a570 100644 --- a/src/lib_client_base/client_confirmations.ml +++ b/src/lib_client_base/client_confirmations.ml @@ -308,3 +308,60 @@ let wait_for_bootstrapped ?(retry = fun f x -> f x) display := true ; let*! () = ctxt#answer "Node is bootstrapped." in return_unit + +let really_wait_for_bootstrapped ?(retry = fun f x -> f x) + (ctxt : #Client_context.full) = + let open Lwt_result_syntax in + let rec process (ctxt : #Client_context.full) = + let display = ref false in + Lwt.dont_wait + (fun () -> + let*! () = ctxt#sleep 0.3 in + if not !display then ( + let*! () = ctxt#answer "Waiting for the node to be bootstrapped..." in + display := true ; + Lwt.return_unit) + else Lwt.return_unit) + (fun exc -> + let (_ : unit Lwt.t) = + let*! () = + ctxt#error "Uncaught exception: %s\n%!" (Printexc.to_string exc) + in + ctxt#error "Progress not monitored anymore\n%!" + in + ()) ; + let* stream, _stop = Monitor_services.bootstrapped ctxt in + let*! () = + Lwt_stream.iter_s + (fun (hash, time) -> + if !display then + ctxt#message + "Current head: %a (timestamp: %a, validation: %a)" + Block_hash.pp_short + hash + Time.System.pp_hum + (Time.System.of_protocol_exn time) + Time.System.pp_hum + (ctxt#now ()) + else Lwt.return_unit) + stream + in + (* If the connection is lost with the node, the stream doesn't emit an + error, it just closes. We cannot distinguish whether it is closed because + the node is bootstrapped or unreachable. Therefore we call an additional RPC + to make sure we are bootstrapped. *) + let* is_bootstrapped, _ = + let s = + Tezos_rpc.Service.prefix + Chain_services.path + Chain_services.S.is_bootstrapped + in + Tezos_rpc.Context.make_call s ctxt ((), ctxt#chain) () () + in + if not is_bootstrapped then process ctxt + else ( + display := true ; + let*! () = ctxt#answer "Node is bootstrapped." in + return_unit) + in + retry process ctxt diff --git a/src/lib_client_base/client_confirmations.mli b/src/lib_client_base/client_confirmations.mli index 159c98fb2a80e30a074193e14c910d15ee0ad93e..435fede7ca24007e2c119f77495ae68a29c6d2ad 100644 --- a/src/lib_client_base/client_confirmations.mli +++ b/src/lib_client_base/client_confirmations.mli @@ -48,12 +48,9 @@ val lookup_operation_in_previous_blocks : Operation_list_hash.elt -> (Block_hash.t * int * int) option tzresult Lwt.t -(** returns when the node consider itself as bootstrapped. - - Function [retry] specifies how to behave in order to connect to - the node. The default is the identity which correspond to simply - calling the RPC. As an example, the baker tries 5 times with - delays in between attempts when the connection fails. *) +(** We do not recommend using this function, if the connection is lost with + the node, it considers that it is bootstrapped. Use + {!really_wait_for_bootstrapped} instead. *) val wait_for_bootstrapped : ?retry: (((#Client_context.full as 'a) -> @@ -66,3 +63,17 @@ val wait_for_bootstrapped : Lwt.t) -> 'a -> unit tzresult Lwt.t + +(** Returns when the node consider itself as bootstrapped. + + Function [retry] specifies how to behave in order to connect to + the node. The default is the identity which correspond to simply + calling the RPC. As an example, the baker tries 5 times with + delays in between attempts when the connection fails. *) +val really_wait_for_bootstrapped : + ?retry: + (((#Client_context.full as 'a) -> unit tzresult Lwt.t) -> + 'a -> + unit tzresult Lwt.t) -> + 'a -> + unit tzresult Lwt.t diff --git a/src/proto_022_PsRiotum/lib_delegate/client_daemon.ml b/src/proto_022_PsRiotum/lib_delegate/client_daemon.ml index ce41bc0768e2e2a75b57dada076c060b52679719..8e92f731bf87f573e5ff7d74a8025cebc31dc99e 100644 --- a/src/proto_022_PsRiotum/lib_delegate/client_daemon.ml +++ b/src/proto_022_PsRiotum/lib_delegate/client_daemon.ml @@ -35,7 +35,7 @@ let rec retry_on_disconnection (cctxt : #Protocol_client_context.full) f = in (* Wait forever when the node stops responding... *) let* () = - Client_confirmations.wait_for_bootstrapped + Client_confirmations.really_wait_for_bootstrapped ~retry: (Baking_scheduling.retry cctxt ~max_delay:10. ~delay:1. ~factor:1.5) cctxt @@ -153,8 +153,13 @@ module Baker = struct delegates in let* () = - Client_confirmations.wait_for_bootstrapped - ~retry:(Baking_scheduling.retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + Client_confirmations.really_wait_for_bootstrapped + ~retry: + (Baking_scheduling.retry + cctxt + ~delay:1. + ~factor:1.5 + ?tries:(if keep_alive then None else Some 5)) cctxt in let* () = await_protocol_start cctxt ~chain in @@ -196,8 +201,13 @@ module Accuser = struct valid_blocks_stream in let* () = - Client_confirmations.wait_for_bootstrapped - ~retry:(Baking_scheduling.retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + Client_confirmations.really_wait_for_bootstrapped + ~retry: + (Baking_scheduling.retry + cctxt + ~delay:1. + ~factor:1.5 + ?tries:(if keep_alive then None else Some 5)) cctxt in let* () = await_protocol_start cctxt ~chain in @@ -240,8 +250,13 @@ module VDF = struct Baking_vdf.start_vdf_worker cctxt ~canceler constants chain in let* () = - Client_confirmations.wait_for_bootstrapped - ~retry:(Baking_scheduling.retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + Client_confirmations.really_wait_for_bootstrapped + ~retry: + (Baking_scheduling.retry + cctxt + ~delay:1. + ~factor:1.5 + ?tries:(if keep_alive then None else Some 5)) cctxt in let* () = await_protocol_start cctxt ~chain in diff --git a/src/proto_023_PtSeouLo/lib_delegate/client_daemon.ml b/src/proto_023_PtSeouLo/lib_delegate/client_daemon.ml index b663b248a4162f659343da8145dc648d44b99332..ddabccf80b2db7aab5c363798d65a1feda2a3ce7 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/client_daemon.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/client_daemon.ml @@ -35,7 +35,7 @@ let rec retry_on_disconnection (cctxt : #Protocol_client_context.full) f = in (* Wait forever when the node stops responding... *) let* () = - Client_confirmations.wait_for_bootstrapped + Client_confirmations.really_wait_for_bootstrapped ~retry: (Baking_scheduling.retry cctxt ~max_delay:10. ~delay:1. ~factor:1.5) cctxt @@ -153,8 +153,13 @@ module Baker = struct delegates in let* () = - Client_confirmations.wait_for_bootstrapped - ~retry:(Baking_scheduling.retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + Client_confirmations.really_wait_for_bootstrapped + ~retry: + (Baking_scheduling.retry + cctxt + ~delay:1. + ~factor:1.5 + ?tries:(if keep_alive then None else Some 5)) cctxt in let* () = await_protocol_start cctxt ~chain in @@ -196,8 +201,13 @@ module Accuser = struct valid_blocks_stream in let* () = - Client_confirmations.wait_for_bootstrapped - ~retry:(Baking_scheduling.retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + Client_confirmations.really_wait_for_bootstrapped + ~retry: + (Baking_scheduling.retry + cctxt + ~delay:1. + ~factor:1.5 + ?tries:(if keep_alive then None else Some 5)) cctxt in let* () = await_protocol_start cctxt ~chain in @@ -240,8 +250,13 @@ module VDF = struct Baking_vdf.start_vdf_worker cctxt ~canceler constants chain in let* () = - Client_confirmations.wait_for_bootstrapped - ~retry:(Baking_scheduling.retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + Client_confirmations.really_wait_for_bootstrapped + ~retry: + (Baking_scheduling.retry + cctxt + ~delay:1. + ~factor:1.5 + ?tries:(if keep_alive then None else Some 5)) cctxt in let* () = await_protocol_start cctxt ~chain in diff --git a/src/proto_alpha/lib_delegate/client_daemon.ml b/src/proto_alpha/lib_delegate/client_daemon.ml index b663b248a4162f659343da8145dc648d44b99332..ddabccf80b2db7aab5c363798d65a1feda2a3ce7 100644 --- a/src/proto_alpha/lib_delegate/client_daemon.ml +++ b/src/proto_alpha/lib_delegate/client_daemon.ml @@ -35,7 +35,7 @@ let rec retry_on_disconnection (cctxt : #Protocol_client_context.full) f = in (* Wait forever when the node stops responding... *) let* () = - Client_confirmations.wait_for_bootstrapped + Client_confirmations.really_wait_for_bootstrapped ~retry: (Baking_scheduling.retry cctxt ~max_delay:10. ~delay:1. ~factor:1.5) cctxt @@ -153,8 +153,13 @@ module Baker = struct delegates in let* () = - Client_confirmations.wait_for_bootstrapped - ~retry:(Baking_scheduling.retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + Client_confirmations.really_wait_for_bootstrapped + ~retry: + (Baking_scheduling.retry + cctxt + ~delay:1. + ~factor:1.5 + ?tries:(if keep_alive then None else Some 5)) cctxt in let* () = await_protocol_start cctxt ~chain in @@ -196,8 +201,13 @@ module Accuser = struct valid_blocks_stream in let* () = - Client_confirmations.wait_for_bootstrapped - ~retry:(Baking_scheduling.retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + Client_confirmations.really_wait_for_bootstrapped + ~retry: + (Baking_scheduling.retry + cctxt + ~delay:1. + ~factor:1.5 + ?tries:(if keep_alive then None else Some 5)) cctxt in let* () = await_protocol_start cctxt ~chain in @@ -240,8 +250,13 @@ module VDF = struct Baking_vdf.start_vdf_worker cctxt ~canceler constants chain in let* () = - Client_confirmations.wait_for_bootstrapped - ~retry:(Baking_scheduling.retry cctxt ~delay:1. ~factor:1.5 ~tries:5) + Client_confirmations.really_wait_for_bootstrapped + ~retry: + (Baking_scheduling.retry + cctxt + ~delay:1. + ~factor:1.5 + ?tries:(if keep_alive then None else Some 5)) cctxt in let* () = await_protocol_start cctxt ~chain in