123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2023 TriliTech, <contact@trili.tech> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)moduleDac_client=Dac_node_clienttypeerror+=|Failed_to_initialize_dac_plugin|Failed_to_fetch_missing_page_from_observerofDac_plugin.raw_hash|TimeoutofZ.t|Wrong_hashof{found:Dac_plugin.raw_hash;expected:Dac_plugin.raw_hash}let()=register_error_kind~id:"dac_observer_client.failed_to_initialize_dac_plugin"~title:"Failed to initialize DAC plugin"~description:"Failed to initialize DAC plugin in DAC Observer client."~pp:(funppf()->Format.fprintfppf"Failed to initialize DAC plugin in DAC Observer client.")`PermanentData_encoding.unit(functionFailed_to_initialize_dac_plugin->Some()|_->None)(fun_->Failed_to_initialize_dac_plugin);register_error_kind~id:"dac_observer_client_timeout"~title:"Timeout while querying Dac Observer Node"~description:"Timeout while querying Dac Observer Node."~pp:(funppfseconds->Format.fprintfppf"Timeout after %as when querying Dac Observer Node"Z.pp_printseconds)`PermanentData_encoding.(obj1(req"seconds"z))(functionTimeoutseconds->Someseconds|_->None)(funseconds->Timeoutseconds);register_error_kind~id:"dac_observer_client.failed_to_fetch_missing_page_from_observer"~title:"Failed to fetch missing page from DAC Observer."~description:"Failed to fetch missing page from DAC Observer."~pp:(funppfhash->Format.fprintfppf"Failed to fetch missing page from DAC Observer for hash: %a"Dac_plugin.pp_raw_hashhash)`PermanentData_encoding.(obj1(req"hash"Dac_plugin.raw_hash_encoding))(function|Failed_to_fetch_missing_page_from_observerhash->Somehash|_->None)(funhash->Failed_to_fetch_missing_page_from_observerhash);register_error_kind~id:"dac_observer_client.wrong_hash_of_reveal_preimage"~title:"Hash of reveal preimage is incorrect."~description:"Hash of reveal preimage is incorrect."~pp:(funppf(found,expected)->Format.fprintfppf"Reveal preimage hash is '%a' while a value of '%a' is expected"Dac_plugin.pp_raw_hashfoundDac_plugin.pp_raw_hashexpected)`PermanentData_encoding.(obj2(req"found"Dac_plugin.raw_hash_encoding)(req"expected"Dac_plugin.raw_hash_encoding))(function|Wrong_hash{found;expected}->Some(found,expected)|_->None)(fun(found,expected)->Wrong_hash{found;expected})moduleConfiguration=structtypet={observer_endpoint:Uri.t;reveal_data_dir:string;timeout_seconds:Z.toption;}endtypet={reveal_data_dir:string;timeout_seconds:Z.t;observer_cctxt:Dac_client.unix_cctxt;}moduleClient=structletmake_unixendpoint=letrpc_config={Tezos_rpc_http_client_unix.RPC_client_unix.default_configwithendpoint}innewDac_node_client.unix_cctxt~rpc_configletfetch_missing_pageobserver_cctxthash=letopenLwt_result_syntaxinletdac_hash=Dac_plugin.hash_to_rawhashinlet+preimage=(* TODO: https://gitlab.com/tezos/tezos/-/issues/5627
Currently we have only one major DAC API version ([V0]). For this reason,
clients can always default to [Dac_node_client.V0]. This should be
revisited once we add another major version. *)Dac_node_client.V0.Observer.get_missing_pageobserver_cctxtdac_hashinString.of_bytespreimageendlettimeout_default=Z.of_int30letinitConfiguration.{observer_endpoint;reveal_data_dir;timeout_seconds}=letopenLwt_result_syntaxinletobserver_cctxt=Client.make_unixobserver_endpointinlettimeout_seconds=Option.value~default:timeout_defaulttimeout_secondsinreturn{reveal_data_dir;timeout_seconds;observer_cctxt}(** TODO: https://gitlab.com/tezos/tezos/-/issues/5519
Remove duplicate code from reveals.ml
*)letfile_contentsfilename=letopenLwt_result_syntaxinLwt.catch(fun()->let*!contents=Lwt_utils_unix.read_filefilenameinreturn_somecontents)(fun_->return_none)letpathdata_dirhash=lethash=Dac_plugin.hash_to_hexhash|>Hex.showinFilename.(concatdata_dirhash)(** TODO: https://gitlab.com/tezos/tezos/-/issues/5521
Return non fatal error kinds if any.
*)letfetch_preimagedac_client((modulePlugin):Dac_plugin.t)hash=letopenLwt_result_syntaxinlet{reveal_data_dir;timeout_seconds;observer_cctxt}=dac_clientinletfilename=pathreveal_data_dirhashinlet*contents_opt=file_contentsfilenameinlet*contents=matchcontents_optwith|Somepreimage->returnpreimage|None->letrun()=Lwt_unix.with_timeout(Z.to_floattimeout_seconds)(fun()->Client.fetch_missing_pageobserver_cctxthash)inLwt.catchrun(function|Lwt_unix.Timeout->tzfail@@Timeouttimeout_seconds|_->tzfail@@Failed_to_fetch_missing_page_from_observer(Dac_plugin.hash_to_rawhash))inlet*?()=letcontents_hash=Plugin.hash_string~scheme:Dac_plugin.Blake2B[contents]inerror_unless(Dac_plugin.raw_comparecontents_hashhash=0)(Wrong_hash{found=Dac_plugin.hash_to_rawcontents_hash;expected=Dac_plugin.hash_to_rawhash;})inreturncontents