1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* Copyright (c) 2019-2020 Nomadic Labs, <contact@nomadic-labs.com> *)(* *)(* 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. *)(* *)(*****************************************************************************)openFilename.Infixlethome=trySys.getenv"HOME"withNot_found->"/root"letdata_dir_env_name="TEZOS_NODE_DIR"letdefault_data_dir=home//".tezos-node"letdefault_rpc_port=8732letdefault_metrics_port=9932letdefault_p2p_port=9732letdefault_discovery_port=10732typechain_name=Distributed_db_version.Name.ttypeblockchain_network={alias:stringoption;genesis:Genesis.t;genesis_parameters:Genesis.Parameters.toption;chain_name:chain_name;old_chain_name:chain_nameoption;incompatible_chain_name:chain_nameoption;sandboxed_chain_name:chain_name;user_activated_upgrades:User_activated.upgrades;user_activated_protocol_overrides:User_activated.protocol_overrides;default_bootstrap_peers:stringlist;}letmake_blockchain_network~alias~chain_name?old_chain_name?incompatible_chain_name~sandboxed_chain_name?(user_activated_upgrades=[])?(user_activated_protocol_overrides=[])?(default_bootstrap_peers=[])?genesis_parametersgenesis=letof_string=Distributed_db_version.Name.of_stringin{alias=Somealias;genesis;genesis_parameters;chain_name=of_stringchain_name;old_chain_name=Option.mapof_stringold_chain_name;incompatible_chain_name=Option.mapof_stringincompatible_chain_name;sandboxed_chain_name=of_stringsandboxed_chain_name;user_activated_upgrades=List.map(fun(l,h)->(l,Protocol_hash.of_b58check_exnh))user_activated_upgrades;user_activated_protocol_overrides=List.map(fun(a,b)->(Protocol_hash.of_b58check_exna,Protocol_hash.of_b58check_exnb))user_activated_protocol_overrides;default_bootstrap_peers;}(* The script in scripts/user_activated_upgrade.sh patches the following lines
when it needs to set the user activated upgrade levels for Mainnet. *)(* BEGIN_PATCHING_ZONE_FOR_MAINNET_USER_ACTIVATED_UPGRADES *)letmainnet_user_activated_upgrades=[(28082l,"PsYLVpVvgbLhAhoqAkMFUo6gudkJ9weNXhUYCiLDzcUpFpkk8Wt");(204761l,"PsddFKi32cMJ2qPjf43Qv5GDWLDPZb3T3bF6fLKiF5HtvHNU7aP");](* END_PATCHING_ZONE_FOR_MAINNET_USER_ACTIVATED_UPGRADES *)(* it patches the following lines when it needs to set the user activated
upgrade levels for a sandbox. *)(* BEGIN_PATCHING_ZONE_FOR_SANDBOX_USER_ACTIVATED_UPGRADES *)letsandbox_user_activated_upgrades=[](* END_PATCHING_ZONE_FOR_SANDBOX_USER_ACTIVATED_UPGRADES *)letblockchain_network_mainnet=make_blockchain_network~alias:"mainnet"{time=Time.Protocol.of_notation_exn"2018-06-30T16:07:32Z";block=Block_hash.of_b58check_exn"BLockGenesisGenesisGenesisGenesisGenesisf79b5d1CoW2";protocol=Protocol_hash.of_b58check_exn"Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P";}~chain_name:"TEZOS_MAINNET"~old_chain_name:"TEZOS_BETANET_2018-06-30T16:07:32Z"~incompatible_chain_name:"INCOMPATIBLE"~sandboxed_chain_name:"SANDBOXED_TEZOS_MAINNET"~user_activated_upgrades:mainnet_user_activated_upgrades~user_activated_protocol_overrides:[("PsBABY5HQTSkA4297zNHfsZNKtxULfL18y95qb3m53QJiXGmrbU","PsBabyM1eUXZseaJdmXFApDSBqj8YBfwELoxZHHW77EMcAbbwAS");("PtEdoTezd3RHSC31mpxxo1npxFjoWWcFgQtxapi51Z8TLu6v6Uq","PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA");("PtHangzHogokSuiMHemCuowEavgYTP8J5qQ9fQS793MHYFpCY3r","PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx");("PtMumbaiiFFEGbew1rRjzSPyzRbA51Tm3RVZL5suHPxSZYDhCEc","PtMumbai2TmsJHNGRkD8v8YDbtao7BLUC3wjASn1inAKLFCjaH1");]~default_bootstrap_peers:["boot.tzboot.net";"boot.tzbeta.net";"boot.mainnet.oxheadhosted.com"]letblockchain_network_ghostnet=make_blockchain_network~alias:"ghostnet"{time=Time.Protocol.of_notation_exn"2022-01-25T15:00:00Z";block=Block_hash.of_b58check_exn"BLockGenesisGenesisGenesisGenesisGenesis1db77eJNeJ9";protocol=Protocol_hash.of_b58check_exn"Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P";}~genesis_parameters:{context_key="sandbox_parameter";values=`O[("genesis_pubkey",`String"edpkuYLienS3Xdt5c1vfRX1ibMxQuvfM67ByhJ9nmRYYKGAAoTq1UC");];}~chain_name:"TEZOS_ITHACANET_2022-01-25T15:00:00Z"~sandboxed_chain_name:"SANDBOXED_TEZOS"~user_activated_upgrades:[(8191l,"Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A");(765952l,"PtJakart2xVj7pYXJBXrqHgd82rdkLey5ZeeGwDgPp9rhQUbSqY");(1191936l,"PtKathmankSpLLDALzWw7CGD2j2MtyveTwboEYokqUCP4a1LxMg");(1654784l,"PtLimaPtLMwfNinJi9rCfDPWea8dFgTZ1MeJ9f1m2SRic6ayiwW");]~default_bootstrap_peers:["ghostnet.teztnets.xyz";"ghostnet.smartpy.io";"ghostnet.boot.ecadinfra.com";"ghostnet.kaml.fr";"ghostnet.stakenow.de:9733";"ghostnet.visualtez.com";]letblockchain_network_mumbainet=make_blockchain_network~alias:"mumbainet"{time=Time.Protocol.of_notation_exn"2023-03-09T15:00:00Z";block=Block_hash.of_b58check_exn"BLytf7aG27Ca4xZ8cG4otofaUQfUA9TdULvHC3L9fToPHBcPKDV";protocol=Protocol_hash.of_b58check_exn"Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P";}~genesis_parameters:{context_key="sandbox_parameter";values=`O[("genesis_pubkey",`String"edpkuYLienS3Xdt5c1vfRX1ibMxQuvfM67ByhJ9nmRYYKGAAoTq1UC");];}~chain_name:"TEZOS_MUMBAINET_2023-03-09T15:00:00Z"~sandboxed_chain_name:"SANDBOXED_TEZOS"~default_bootstrap_peers:["mumbainet.teztnets.xyz";"mumbainet.boot.ecadinfra.com"]letblockchain_network_sandbox=make_blockchain_network~alias:"sandbox"{time=Time.Protocol.of_notation_exn"2018-06-30T16:07:32Z";block=Block_hash.of_b58check_exn"BLockGenesisGenesisGenesisGenesisGenesisf79b5d1CoW2";protocol=Protocol_hash.of_b58check_exn"ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im";}~genesis_parameters:(* Genesis public key corresponds to the following private key:
unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6 *){context_key="sandbox_parameter";values=`O[("genesis_pubkey",`String"edpkuSLWfVU1Vq7Jg9FucPyKmma6otcMHac9zG4oU1KMHSTBpJuGQ2");];}~chain_name:"TEZOS"~sandboxed_chain_name:"SANDBOXED_TEZOS"~user_activated_upgrades:sandbox_user_activated_upgradesletblockchain_network_encoding:blockchain_networkData_encoding.t=letopenData_encodinginconv(fun{alias=_;genesis;genesis_parameters;chain_name;old_chain_name;incompatible_chain_name;sandboxed_chain_name;user_activated_upgrades;user_activated_protocol_overrides;default_bootstrap_peers;}->(genesis,genesis_parameters,chain_name,old_chain_name,incompatible_chain_name,sandboxed_chain_name,user_activated_upgrades,user_activated_protocol_overrides,default_bootstrap_peers))(fun(genesis,genesis_parameters,chain_name,old_chain_name,incompatible_chain_name,sandboxed_chain_name,user_activated_upgrades,user_activated_protocol_overrides,default_bootstrap_peers)->{alias=None;genesis;genesis_parameters;chain_name;old_chain_name;incompatible_chain_name;sandboxed_chain_name;user_activated_upgrades;user_activated_protocol_overrides;default_bootstrap_peers;})(letchain=Distributed_db_version.Name.encodinginobj9(req"genesis"Genesis.encoding)(opt"genesis_parameters"Genesis.Parameters.encoding)(req"chain_name"chain)(opt"old_chain_name"chain)(opt"incompatible_chain_name"chain)(req"sandboxed_chain_name"chain)(dft"user_activated_upgrades"User_activated.upgrades_encoding[])(dft"user_activated_protocol_overrides"User_activated.protocol_overrides_encoding[])(dft"default_bootstrap_peers"~description:"List of hosts to use if p2p.bootstrap_peers is unspecified."(liststring)[]))letbuiltin_blockchain_networks_with_tags=[(1,blockchain_network_sandbox);(4,blockchain_network_mainnet);(19,blockchain_network_ghostnet);(22,blockchain_network_mumbainet);]|>List.map(fun(tag,network)->matchnetwork.aliaswith|None->assertfalse(* all built-in networks must have aliases *)|Somealias->(tag,alias,network))letbuiltin_blockchain_networks=List.map(fun(_,name,network)->(name,network))builtin_blockchain_networks_with_tagsletsugared_blockchain_network_encoding:blockchain_networkData_encoding.t=letopenData_encodinginletbuiltin_encoding(tag,network_alias,network)=case(Tagtag)~title:network_alias(constantnetwork_alias)(funcandidate->matchcandidate.aliaswith|None->None|Somecandidate_alias->ifString.equalcandidate_aliasnetwork_aliasthenSome()elseNone)(fun()->network)in(* It is important that built-in networks are listed before the Custom case,
so that they have priority. Indeed, if possible we want to store the alias
in the configuration file, not the full network description. Not just because
it is prettier, but also in case user-activated upgrades are added to the built-in
network: by writing the alias we ensure that new upgrades are used without having
to update the configuration file manually. *)union~tag_size:`Uint8(List.mapbuiltin_encodingbuiltin_blockchain_networks_with_tags@[case(Tag0)~title:"Custom"blockchain_network_encoding(funx->Somex)(funx->x);])typet={data_dir:string;disable_config_validation:bool;p2p:p2p;rpc:rpc;log:Lwt_log_sink_unix.cfg;internal_events:Internal_event_config.toption;shell:Shell_limits.limits;blockchain_network:blockchain_network;metrics_addr:stringlist;dal:Tezos_crypto_dal.Cryptobox.Config.t;}andp2p={expected_pow:float;bootstrap_peers:stringlistoption;listen_addr:stringoption;advertised_net_port:intoption;discovery_addr:stringoption;private_mode:bool;limits:Tezos_p2p_services.P2p_limits.t;disable_mempool:bool;enable_testchain:bool;reconnection_config:Tezos_p2p_services.Point_reconnection_config.t;disable_peer_discovery:bool;}andrpc={listen_addrs:stringlist;cors_origins:stringlist;cors_headers:stringlist;tls:tlsoption;acl:RPC_server.Acl.policy;media_type:Media_type.Command_line.t;}andtls={cert:string;key:string}letdefault_p2p={expected_pow=26.;bootstrap_peers=None;listen_addr=Some("[::]:"^string_of_intdefault_p2p_port);advertised_net_port=None;discovery_addr=None;private_mode=false;limits=Tezos_p2p_services.P2p_limits.default;disable_mempool=false;enable_testchain=false;reconnection_config=Tezos_p2p_services.Point_reconnection_config.default;disable_peer_discovery=false;}letdefault_rpc={listen_addrs=[];cors_origins=[];cors_headers=[];tls=None;acl=RPC_server.Acl.empty_policy;media_type=Media_type.Command_line.Any;}letdefault_disable_config_validation=falseletlwt_log_sink_default_cfg={Lwt_log_sink_unix.default_cfgwithtemplate="$(date).$(milliseconds): $(message)";}letdefault_config={data_dir=default_data_dir;p2p=default_p2p;rpc=default_rpc;log=lwt_log_sink_default_cfg;internal_events=None;shell=Shell_limits.default_limits;blockchain_network=blockchain_network_mainnet;disable_config_validation=default_disable_config_validation;metrics_addr=[];dal=Tezos_crypto_dal.Cryptobox.Config.default;}letp2p=letopenData_encodinginconv(fun{expected_pow;bootstrap_peers;listen_addr;advertised_net_port;discovery_addr;private_mode;limits;disable_mempool;enable_testchain;reconnection_config;disable_peer_discovery;}->((expected_pow,bootstrap_peers,listen_addr,advertised_net_port,discovery_addr),(private_mode,limits,disable_mempool,enable_testchain,reconnection_config,disable_peer_discovery)))(fun((expected_pow,bootstrap_peers,listen_addr,advertised_net_port,discovery_addr),(private_mode,limits,disable_mempool,enable_testchain,reconnection_config,disable_peer_discovery))->{expected_pow;bootstrap_peers;listen_addr;advertised_net_port;discovery_addr;private_mode;limits;disable_mempool;enable_testchain;reconnection_config;disable_peer_discovery;})(merge_objs(obj5(dft"expected-proof-of-work"~description:"Floating point number between 0 and 256 that represents a \
difficulty, 24 signifies for example that at least 24 leading \
zeroes are expected in the hash."floatdefault_p2p.expected_pow)(opt"bootstrap-peers"~description:"List of hosts. Tezos can connect to both IPv6 and IPv4 hosts. \
If the port is not specified, default port 9732 will be \
assumed."(liststring))(opt"listen-addr"~description:"Host to listen to. If the port is not specified, the default \
port 9732 will be assumed."string)(opt"advertised-net-port"~description:"Alternative port advertised to other peers to connect to. If \
the port is not specified, the port from listen-addr will be \
assumed."uint16)(dft"discovery-addr"~description:"Host for local peer discovery. If the port is not specified, \
the default port 10732 will be assumed."(optionstring)default_p2p.discovery_addr))(obj6(dft"private-mode"~description:"Specify if the node is in private mode or not. A node in \
private mode rejects incoming connections from untrusted peers \
and only opens outgoing connections to peers listed in \
'bootstrap-peers' or provided with '--peer' option. Moreover, \
these peers will keep the identity and the address of the \
private node secret."booldefault_p2p.private_mode)(dft"limits"~description:"Network limits"Tezos_p2p_services.P2p_limits.encodingTezos_p2p_services.P2p_limits.default)(dft"disable_mempool"~description:"If set to [true], the node will not participate in the \
propagation of pending operations (mempool). Default value is \
[false]. It can be used to decrease the memory and computation \
footprints of the node."booldefault_p2p.disable_mempool)(dft"enable_testchain"~description:"DEPRECATED. If set to [true], the node will spawn a testchain \
during the protocol's testing voting period. Default value is \
[false]. It is disabled to decrease the node storage usage and \
computation by dropping the validation of the test network \
blocks."booldefault_p2p.enable_testchain)(letopenTezos_p2p_services.Point_reconnection_configindft"greylisting_config"~description:"The reconnection policy regulates the frequency with which the \
node tries to reconnect to an old known peer."encodingdefault)(dft"disable_peer_discovery"~description:"This field should be used for testing purpose only. If set to \
[true], the node will not participate to the peer discovery \
mechanism. The node will not be able to find new peers to \
connect with."booldefault_p2p.disable_peer_discovery)))letrpc:rpcData_encoding.t=letopenData_encodinginconv(fun{cors_origins;cors_headers;listen_addrs;tls;acl;media_type}->letcert,key=matchtlswith|None->(None,None)|Some{cert;key}->(Somecert,Somekey)in(Somelisten_addrs,None,cors_origins,cors_headers,cert,key,acl,media_type))(fun(listen_addrs,legacy_listen_addr,cors_origins,cors_headers,cert,key,acl,media_type)->lettls=match(cert,key)with|None,_|_,None->None|Somecert,Somekey->Some{cert;key}inletlisten_addrs=match(listen_addrs,legacy_listen_addr)with|Someaddrs,None->addrs|None,Someaddr->[addr]|None,None->default_rpc.listen_addrs|Some_,Some_->Stdlib.failwith"Config file: Use only \"listen-addrs\" and not (legacy) \
\"listen-addr\"."in{listen_addrs;cors_origins;cors_headers;tls;acl;media_type})(obj8(opt"listen-addrs"~description:"Hosts to listen to. If the port is not specified, the default \
port 8732 will be assumed."(liststring))(opt"listen-addr"~description:"Legacy value: Host to listen to"string)(dft"cors-origin"~description:"Cross Origin Resource Sharing parameters, see \
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing."(liststring)default_rpc.cors_origins)(dft"cors-headers"~description:"Cross Origin Resource Sharing parameters, see \
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing."(liststring)default_rpc.cors_headers)(opt"crt"~description:"Certificate file (necessary when TLS is used)."string)(opt"key"~description:"Key file (necessary when TLS is used)."string)(dft"acl"~description:"A list of RPC ACLs for specific listening addresses."RPC_server.Acl.policy_encodingdefault_rpc.acl)(dft"media-type"~description:"The media types supported by the server."Media_type.Command_line.encodingdefault_rpc.media_type))letencoding=letopenData_encodinginconv(fun{data_dir;disable_config_validation;rpc;p2p;log;internal_events;shell;blockchain_network;metrics_addr;dal;}->(data_dir,disable_config_validation,rpc,p2p,log,internal_events,shell,blockchain_network,metrics_addr,dal))(fun(data_dir,disable_config_validation,rpc,p2p,log,internal_events,shell,blockchain_network,metrics_addr,dal)->{disable_config_validation;data_dir;rpc;p2p;log;internal_events;shell;blockchain_network;metrics_addr;dal;})(obj10(dft"data-dir"~description:"Location of the data dir on disk."stringdefault_data_dir)(dft"disable-config-validation"~description:"Disable the node configuration validation."booldefault_disable_config_validation)(dft"rpc"~description:"Configuration of rpc parameters"rpcdefault_rpc)(dft"p2p"~description:"Configuration of network parameters"p2pdefault_p2p)(dft"log"~description:"Configuration of the Lwt-log sink (part of the logging framework)"Lwt_log_sink_unix.cfg_encodinglwt_log_sink_default_cfg)(opt"internal-events"~description:"Configuration of the structured logging framework"Internal_event_config.encoding)(dft"shell"~description:"Configuration of network parameters"Shell_limits.limits_encodingShell_limits.default_limits)(dft"network"~description:"Configuration of which network/blockchain to connect to"sugared_blockchain_network_encodingblockchain_network_mainnet)(dft"metrics_addr"~description:"Configuration of the Prometheus metrics endpoint"(liststring)default_config.metrics_addr)(dft"dal"~description:"USE FOR TESTING PURPOSE ONLY. Configuration for the \
data-availibility layer"Tezos_crypto_dal.Cryptobox.Config.encodingTezos_crypto_dal.Cryptobox.Config.default))(* Abstract version of [Json_encoding.Cannot_destruct]: first argument is the
string representation of the path, second argument is the error message
of the actual exception which was raised (as [Cannot_destruct] takes an [exn]
as second argument). *)typeerror+=Invalid_contentofstringoption*stringlet()=register_error_kind`Permanent~id:"config_file.invalid_content"~title:"Invalid config file"~description:"Invalid content in node config file"~pp:(funppf(path,exn)->matchpathwith|Somepath->Format.fprintfppf"@[<hov>Invalid configuration file:@ at %s:@ %s@]"pathexn|None->Format.fprintfppf"@[<hov>Invalid configuration file:@ %s@]"exn)Data_encoding.(obj2(req"path"(optionstring))(req"error"string))(functionInvalid_content(p,e)->Some(p,e)|_->None)(fun(p,e)->Invalid_content(p,e))moduleEvent=structincludeInternal_event.Simpleletsection=["node";"main"]letlevel=Internal_event.Warningletcannot_convert_to_ipv4=Internal_event.Simple.declare_1~section~level~name:"cannot_convert_to_ipv4"~msg:"failed to convert {addr} to an ipv4 address"~pp1:(funppf->Format.fprintfppf"%S")("addr",Data_encoding.string)letall_rpc_allowed=declare_1~level:Error~section~name:"all_rpc_allowed"~msg:"FULL access to RPC enabled; this is very risky."~pp1:Format.(pp_print_list~pp_sep:(funfmt()->pp_print_stringfmt", ")P2p_point.Id.pp_addr_port_id)("addresses",Data_encoding.(listP2p_point.Id.addr_port_id_encoding))endletstring_of_json_encoding_errorexn=Format.asprintf"%a"(Json_encoding.print_error?print_unknown:None)exnletreadfp=letopenLwt_result_syntaxinifSys.file_existsfpthenlet*json=Lwt_utils_unix.Json.read_filefpintryreturn(Data_encoding.Json.destructencodingjson)with|Json_encoding.Cannot_destruct(path,exn)->letpath=Json_query.json_pointer_of_pathpathinletexn=string_of_json_encoding_errorexnintzfail(Invalid_content(Somepath,exn))|(Json_encoding.Unexpected_|Json_encoding.No_case_matched_|Json_encoding.Bad_array_size_|Json_encoding.Missing_field_|Json_encoding.Unexpected_field_|Json_encoding.Bad_schema_)asexn->letexn=string_of_json_encoding_errorexnintzfail(Invalid_content(None,exn))elsereturndefault_configletwritefpcfg=letopenLwt_result_syntaxinlet*()=Data_version.ensure_data_dir~mode:Existscfg.blockchain_network.genesis(Filename.dirnamefp)inLwt_utils_unix.Json.write_filefp(Data_encoding.Json.constructencodingcfg)letto_stringcfg=Data_encoding.Json.to_string(Data_encoding.Json.constructencodingcfg)letupdate?(disable_config_validation=false)?data_dir?min_connections?expected_connections?max_connections?max_download_speed?max_upload_speed?binary_chunks_size?peer_table_size?expected_pow?bootstrap_peers?listen_addr?advertised_net_port?discovery_addr?(rpc_listen_addrs=[])?(allow_all_rpc=[])?(media_type=Media_type.Command_line.Any)?(metrics_addr=[])?operation_metadata_size_limit?(private_mode=default_p2p.private_mode)?(disable_p2p_maintenance=Option.is_nonedefault_p2p.limits.maintenance_idle_time)?(disable_p2p_swap=Option.is_nonedefault_p2p.limits.swap_linger)?(disable_mempool=default_p2p.disable_mempool)?(disable_mempool_precheck=Shell_limits.default_limits.prevalidator_limits.disable_precheck)?(enable_testchain=default_p2p.enable_testchain)?(cors_origins=[])?(cors_headers=[])?rpc_tls?log_output?synchronisation_threshold?history_mode?network?latencycfg=letopenLwt_result_syntaxinletdisable_config_validation=cfg.disable_config_validation||disable_config_validationinletdata_dir=Option.value~default:cfg.data_dirdata_dirinlet*!()=ifList.compare_length_withallow_all_rpc1>=0thenEvent.(emitall_rpc_allowedallow_all_rpc)elseLwt.return_unitinlet*()=Data_version.ensure_data_dir~mode:Existscfg.blockchain_network.genesisdata_dirinletpeer_table_size=Option.map(funi->(i,i/4*3))peer_table_sizeinletunopt_list~default=function[]->default|l->linletlimits:Tezos_p2p_services.P2p_limits.t={cfg.p2p.limitswithmin_connections=Option.value~default:cfg.p2p.limits.min_connectionsmin_connections;expected_connections=Option.value~default:cfg.p2p.limits.expected_connectionsexpected_connections;max_connections=Option.value~default:cfg.p2p.limits.max_connectionsmax_connections;max_download_speed=Option.eithermax_download_speedcfg.p2p.limits.max_download_speed;max_upload_speed=Option.eithermax_upload_speedcfg.p2p.limits.max_upload_speed;max_known_points=Option.eitherpeer_table_sizecfg.p2p.limits.max_known_points;max_known_peer_ids=Option.eitherpeer_table_sizecfg.p2p.limits.max_known_peer_ids;binary_chunks_size=Option.map(funx->xlsl10)binary_chunks_size;maintenance_idle_time=(ifdisable_p2p_maintenancethenNoneelsecfg.p2p.limits.maintenance_idle_time);swap_linger=(ifdisable_p2p_swapthenNoneelsecfg.p2p.limits.swap_linger);}inletacl=(* Take addresses listed in allow_all_rpc and add each of them with allow_all
ACL to the policy. *)List.fold_rightRPC_server.Acl.put_policy(List.map(funaddr->(addr,RPC_server.Acl.allow_all))allow_all_rpc)cfg.rpc.aclinletp2p:p2p={expected_pow=Option.value~default:cfg.p2p.expected_powexpected_pow;bootstrap_peers=Option.value~default:cfg.p2p.bootstrap_peersbootstrap_peers;listen_addr=Option.eitherlisten_addrcfg.p2p.listen_addr;advertised_net_port=Option.eitheradvertised_net_portcfg.p2p.advertised_net_port;discovery_addr=Option.eitherdiscovery_addrcfg.p2p.discovery_addr;private_mode=cfg.p2p.private_mode||private_mode;limits;disable_mempool=cfg.p2p.disable_mempool||disable_mempool;enable_testchain=cfg.p2p.enable_testchain||enable_testchain;reconnection_config=cfg.p2p.reconnection_config;disable_peer_discovery=cfg.p2p.disable_peer_discovery;}andrpc:rpc={listen_addrs=unopt_list~default:cfg.rpc.listen_addrsrpc_listen_addrs;cors_origins=unopt_list~default:cfg.rpc.cors_originscors_origins;cors_headers=unopt_list~default:cfg.rpc.cors_headerscors_headers;tls=Option.eitherrpc_tlscfg.rpc.tls;acl;media_type;}andmetrics_addr=unopt_list~default:cfg.metrics_addrmetrics_addrandlog:Lwt_log_sink_unix.cfg={cfg.logwithoutput=Option.value~default:cfg.log.outputlog_output}andshell=Shell_limits.{peer_validator_limits=cfg.shell.peer_validator_limits;block_validator_limits={cfg.shell.block_validator_limitswithoperation_metadata_size_limit=Option.value~default:cfg.shell.block_validator_limits.operation_metadata_size_limitoperation_metadata_size_limit;};prevalidator_limits={cfg.shell.prevalidator_limitswithdisable_precheck=cfg.shell.prevalidator_limits.disable_precheck||disable_mempool_precheck;};chain_validator_limits=(letsynchronisation:synchronisation_limits={latency=Option.value~default:cfg.shell.chain_validator_limits.synchronisation.latencylatency;threshold=Option.value~default:cfg.shell.chain_validator_limits.synchronisation.thresholdsynchronisation_threshold;}in{synchronisation});history_mode=Option.eitherhistory_modecfg.shell.history_mode;}in(* If --network is specified it overrides the "network" entry of the
configuration file, which itself defaults to mainnet. *)letblockchain_network=Option.value~default:cfg.blockchain_networknetworkinreturn{cfgwithdisable_config_validation;data_dir;p2p;rpc;log;shell;blockchain_network;metrics_addr;}typeError_monad.error+=Failed_to_parse_addressof(string*string)let()=(* Parsing of an address failed with an explanation *)Error_monad.register_error_kind`Permanent~id:"config_file.parsing_address_failed"~title:"Parsing of an address failed"~description:"Parsing an address failed with an explanation."~pp:(funppf(addr,explanation)->Format.fprintfppf"Failed to parse address '%s': %s@."addrexplanation)Data_encoding.(obj2(req"addr"string)(req"explanation"string))(functionFailed_to_parse_addresss->Somes|_->None)(funs->Failed_to_parse_addresss)letto_ipv4ipv6_l=letopenLwt_syntaxinletconvert_or_warn(ipv6,port)=letipv4=Ipaddr.v4_of_v6ipv6inmatchipv4with|None->let*()=Event.(emitcannot_convert_to_ipv4)(Ipaddr.V6.to_stringipv6)inreturn_none|Someipv4->return_some(ipv4,port)inList.filter_map_sconvert_or_warnipv6_l(* Parse an address.
- [peer] is a string representing the peer.
- if [no_peer_id_expected] is true, then parsing a representation
containing a peer id will result in an error.
- [default_addr] is the used if no hostname or IP is given or if
the hostname "_" is used.
- [default_port] is the used if port is given. *)letresolve_addr~default_addr?(no_peer_id_expected=true)?default_port?(passive=false)peer:(P2p_point.Id.t*P2p_peer.Id.toption)listtzresultLwt.t=letopenLwt_result_syntaxinmatchP2p_point.Id.parse_addr_port_idpeerwith|(Error(P2p_point.Id.Bad_id_format_)|Ok{peer_id=Some_;_})whenno_peer_id_expected->tzfail(Failed_to_parse_address(peer,"no peer identity should be specified here"))|Errorerr->tzfail(Failed_to_parse_address(peer,P2p_point.Id.string_of_parsing_errorerr))|Ok{addr;port;peer_id}->letservice_port=match(port,default_port)with|Someport,_->port|None,Somedefault_port->default_port|None,None->default_p2p_portinletservice=string_of_intservice_portinletnode=ifaddr=""||addr="_"thendefault_addrelseaddrinlet*!l=Lwt_utils_unix.getaddrinfo~passive~node~serviceinreturn(List.map(funpoint->(point,peer_id))l)letresolve_addrs?default_port?passive?no_peer_id_expected~default_addraddrs=List.concat_map_es(resolve_addr~default_addr?default_port?passive?no_peer_id_expected)addrsletresolve_discovery_addrsdiscovery_addr=letopenLwt_result_syntaxinlet*addrs=resolve_addr~default_addr:Ipaddr.V4.(to_stringbroadcast)~default_port:default_discovery_port~passive:truediscovery_addrinlet*!addrs=to_ipv4(List.mapfstaddrs)inreturnaddrsletresolve_listening_addrslisten_addr=letopenLwt_result_syntaxinlet+addrs=resolve_addr~default_addr:"::"~default_port:default_p2p_port~passive:truelisten_addrinList.mapfstaddrsletresolve_rpc_listening_addrslisten_addr=letopenLwt_result_syntaxinlet+addrs=resolve_addr~default_addr:"localhost"~default_port:default_rpc_port~passive:truelisten_addrinList.mapfstaddrsletresolve_metrics_addrs?(default_metrics_port=default_metrics_port)metrics_addr=letopenLwt_result_syntaxinlet+addrs=resolve_addr~default_addr:"localhost"~default_port:default_metrics_port~passive:truemetrics_addrinList.mapfstaddrsletresolve_bootstrap_addrspeers=resolve_addrs~no_peer_id_expected:false~default_addr:"::"~default_port:default_p2p_portpeersletbootstrap_peersconfig=Option.value~default:config.blockchain_network.default_bootstrap_peersconfig.p2p.bootstrap_peers