Removed unused src/bin_node.

This commit is contained in:
Christian Rinderknecht 2019-05-16 15:21:05 +02:00
parent 378e4a5904
commit 044f4dfa59
20 changed files with 0 additions and 2927 deletions

View File

@ -1,35 +0,0 @@
(executable
(name main)
(public_name tezos-node)
(libraries tezos-base
tezos-stdlib-unix
tezos-shell-services
tezos-rpc-http
tezos-p2p
tezos-shell
tezos-protocol-updater
tezos-embedded-protocol-genesis
tezos-embedded-protocol-demo
tezos-embedded-protocol-alpha
cmdliner
tls)
(flags (:standard -w -9+27-30-32-40@8
-safe-string
-open Tezos_base__TzPervasives
-open Tezos_stdlib_unix
-open Tezos_shell_services
-open Tezos_rpc_http
-open Tezos_p2p
-open Tezos_shell
-open Tezos_protocol_updater
-linkall)))
(install
(section bin)
(files (tezos-sandboxed-node.sh as tezos-sandboxed-node.sh)))
(alias
(name runtest_indent)
(deps (glob_files *.ml{,i}))
(action
(run bash %{libexec:tezos-stdlib:test-ocp-indent.sh} %{deps})))

View File

@ -1,75 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
let () =
if Filename.basename Sys.argv.(0) = Updater.compiler_name then begin
try
Tezos_protocol_compiler.Compiler.main
Tezos_protocol_compiler_native.Native.driver ;
Pervasives.exit 0
with exn ->
Format.eprintf "%a\n%!" Opterrors.report_error exn;
Pervasives.exit 1
end
let term =
let open Cmdliner.Term in
ret (const (`Help (`Pager, None)))
let description = [
`S "DESCRIPTION" ;
`P "Entry point for initializing, configuring and running a Tezos node." ;
`P Node_identity_command.Manpage.command_description ;
`P Node_run_command.Manpage.command_description ;
`P Node_config_command.Manpage.command_description ;
]
let man =
description @
Node_run_command.Manpage.examples
let info =
let version =
Tezos_base.Current_git_info.abbreviated_commit_hash ^
" ("^Tezos_base.Current_git_info.committer_date^")" in
Cmdliner.Term.info
~doc:"The Tezos node"
~man
~version
"tezos-node"
let commands = [
Node_run_command.cmd ;
Node_config_command.cmd ;
Node_identity_command.cmd ;
]
let () =
Random.self_init () ;
match Cmdliner.Term.eval_choice (term, info) commands with
| `Error _ -> exit 1
| `Help -> exit 0
| `Version -> exit 1
| `Ok () -> exit 0

View File

@ -1,164 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
(** Commands *)
let show (args : Node_shared_arg.t) =
if not @@ Sys.file_exists args.config_file then
Format.eprintf
"\n\
Warning: no config file at %s,\n\
\ displaying the default configuration.\n@."
args.config_file ;
Node_shared_arg.read_and_patch_config_file args >>=? fun cfg ->
Node_config_file.check cfg >>= fun () ->
print_endline @@ Node_config_file.to_string cfg ;
return_unit
let reset (args : Node_shared_arg.t) =
if Sys.file_exists args.config_file then
Format.eprintf
"Ignoring previous configuration file: %s.@."
args.config_file ;
Node_shared_arg.read_and_patch_config_file args >>=? fun cfg ->
Node_config_file.check cfg >>= fun () ->
Node_config_file.write args.config_file cfg
let init (args : Node_shared_arg.t) =
if Sys.file_exists args.config_file then
failwith
"Pre-existing config file at %s, use `reset`."
args.config_file
else
Node_shared_arg.read_and_patch_config_file args >>=? fun cfg ->
Node_config_file.check cfg >>= fun () ->
Node_config_file.write args.config_file cfg
let update (args : Node_shared_arg.t) =
if not (Sys.file_exists args.config_file) then
failwith
"Missing configuration file at %s. \
Use `%s config init [options]` to generate a new file"
args.config_file Sys.argv.(0)
else
Node_shared_arg.read_and_patch_config_file args >>=? fun cfg ->
Node_config_file.check cfg >>= fun () ->
Node_config_file.write args.config_file cfg
(** Main *)
module Term = struct
type subcommand = Show | Reset | Init | Update
let process subcommand args =
let res =
match subcommand with
| Show -> show args
| Reset -> reset args
| Init -> init args
| Update -> update args in
match Lwt_main.run res with
| Ok () -> `Ok ()
| Error err -> `Error (false, Format.asprintf "%a" pp_print_error err)
let subcommand_arg =
let parser = function
| "show" -> `Ok Show
| "reset" -> `Ok Reset
| "init" -> `Ok Init
| "update" -> `Ok Update
| s -> `Error ("invalid argument: " ^ s)
and printer ppf = function
| Show -> Format.fprintf ppf "show"
| Reset -> Format.fprintf ppf "reset"
| Init -> Format.fprintf ppf "init"
| Update -> Format.fprintf ppf "update" in
let open Cmdliner.Arg in
let doc =
"Operation to perform. \
Possible values: $(b,show), $(b,reset), $(b,init), $(b,update)." in
value & pos 0 (parser, printer) Show & info [] ~docv:"OPERATION" ~doc
let term =
let open Cmdliner.Term in
ret (const process $ subcommand_arg $ Node_shared_arg.Term.args)
end
module Manpage = struct
let command_description =
"The $(b,config) command is meant to inspect and amend the \
configuration of the Tezos node. \
This command is complementary to manually editing the tezos \
node configuration file. Its arguments are a subset of the $(i,run) \
command ones."
let description = [
`S "DESCRIPTION" ;
`P (command_description ^ " Several operations are possible: ");
`P "$(b,show) reads, parses and displays Tezos current config file. \
Use this command to see exactly what config file will be used by \
Tezos. If additional command-line arguments are provided, \
the displayed configuration will be amended accordingly. \
This is the default operation." ;
`P "$(b,reset) will overwrite the current configuration file with a \
factory default one. \
If additional command-line arguments are provided, \
they will amend the generated file. \
It assumes that a configuration file already exists \
and will abort otherwise." ;
`P "$(b,init) is like reset but assumes that \
no configuration file is present \
and will abort otherwise." ;
`P "$(b,update) is the main option to edit the configuration file of Tezos. \
It will parse command line arguments and add or replace corresponding \
entries in the Tezos configuration file."
]
let schema = Data_encoding.Json.schema (Node_config_file.encoding)
let options = [
`S "OPTIONS" ;
`P "All options available in the config file";
`Pre (Format.asprintf "@[%a@]" Json_schema.pp schema)
]
let man =
description @
Node_shared_arg.Manpage.args @
options @
Node_shared_arg.Manpage.bugs
let info =
Cmdliner.Term.info
~doc:"Manage node configuration"
~man
"config"
end
let cmd =
Term.term, Manpage.info

View File

@ -1,30 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
val cmd : unit Cmdliner.Term.t * Cmdliner.Term.info
module Manpage : sig
val command_description: string
end

View File

@ -1,776 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* Copyright (c) 2019 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. *)
(* *)
(*****************************************************************************)
let (//) = Filename.concat
let home =
try Sys.getenv "HOME"
with Not_found -> "/root"
let default_data_dir = home // ".tezos-node"
let default_rpc_port = 8732
let default_p2p_port = 9732
let default_discovery_port = 10732
type t = {
data_dir : string ;
p2p : p2p ;
rpc : rpc ;
log : Logging_unix.cfg ;
shell : shell ;
}
and p2p = {
expected_pow : float ;
bootstrap_peers : string list ;
listen_addr : string option ;
discovery_addr : string option ;
private_mode : bool ;
limits : P2p.limits ;
disable_mempool : bool ;
}
and rpc = {
listen_addr : string option ;
cors_origins : string list ;
cors_headers : string list ;
tls : tls option ;
}
and tls = {
cert : string ;
key : string ;
}
and shell = {
block_validator_limits : Node.block_validator_limits ;
prevalidator_limits : Node.prevalidator_limits ;
peer_validator_limits : Node.peer_validator_limits ;
chain_validator_limits : Node.chain_validator_limits ;
}
let default_p2p_limits : P2p.limits = {
connection_timeout = 10. ;
authentication_timeout = 5. ;
greylist_timeout = 86400 ; (* one day *)
maintenance_idle_time = 120. ; (* two minutes *)
min_connections = 10 ;
expected_connections = 50 ;
max_connections = 100 ;
backlog = 20 ;
max_incoming_connections = 20 ;
max_download_speed = None ;
max_upload_speed = None ;
read_buffer_size = 1 lsl 14 ;
read_queue_size = None ;
write_queue_size = None ;
incoming_app_message_queue_size = None ;
incoming_message_queue_size = None ;
outgoing_message_queue_size = None ;
known_points_history_size = 500 ;
known_peer_ids_history_size = 500 ;
max_known_points = Some (400, 300) ;
max_known_peer_ids = Some (400, 300) ;
swap_linger = 30. ;
binary_chunks_size = None ;
}
let default_p2p = {
expected_pow = 26. ;
bootstrap_peers = [] ;
listen_addr = Some ("[::]:" ^ string_of_int default_p2p_port) ;
discovery_addr = None ;
private_mode = false ;
limits = default_p2p_limits ;
disable_mempool = false ;
}
let default_rpc = {
listen_addr = None ;
cors_origins = [] ;
cors_headers = [] ;
tls = None ;
}
let default_shell = {
block_validator_limits = Node.default_block_validator_limits ;
prevalidator_limits = Node.default_prevalidator_limits ;
peer_validator_limits = Node.default_peer_validator_limits ;
chain_validator_limits = Node.default_chain_validator_limits ;
}
let default_config = {
data_dir = default_data_dir ;
p2p = default_p2p ;
rpc = default_rpc ;
log = Logging_unix.default_cfg ;
shell = default_shell ;
}
let limit : P2p.limits Data_encoding.t =
let open Data_encoding in
conv
(fun { P2p.connection_timeout ; authentication_timeout ; greylist_timeout ;
maintenance_idle_time ;
min_connections ; expected_connections ; max_connections ;
backlog ; max_incoming_connections ;
max_download_speed ; max_upload_speed ;
read_buffer_size ; read_queue_size ; write_queue_size ;
incoming_app_message_queue_size ;
incoming_message_queue_size ; outgoing_message_queue_size ;
known_points_history_size ; known_peer_ids_history_size ;
max_known_points ; max_known_peer_ids ;
swap_linger ; binary_chunks_size
} ->
(((( connection_timeout, authentication_timeout,
min_connections, expected_connections,
max_connections, backlog, max_incoming_connections,
max_download_speed, max_upload_speed, swap_linger),
( binary_chunks_size, read_buffer_size, read_queue_size, write_queue_size,
incoming_app_message_queue_size,
incoming_message_queue_size, outgoing_message_queue_size,
known_points_history_size, known_peer_ids_history_size,
max_known_points)),
( max_known_peer_ids, greylist_timeout, maintenance_idle_time))))
(fun (((( connection_timeout, authentication_timeout,
min_connections, expected_connections,
max_connections, backlog, max_incoming_connections,
max_download_speed, max_upload_speed, swap_linger),
( binary_chunks_size, read_buffer_size, read_queue_size, write_queue_size,
incoming_app_message_queue_size,
incoming_message_queue_size, outgoing_message_queue_size,
known_points_history_size, known_peer_ids_history_size,
max_known_points)),
( max_known_peer_ids, greylist_timeout, maintenance_idle_time))) ->
{ connection_timeout ; authentication_timeout ; greylist_timeout ;
maintenance_idle_time ;
min_connections ; expected_connections ;
max_connections ; backlog ; max_incoming_connections ;
max_download_speed ; max_upload_speed ;
read_buffer_size ; read_queue_size ; write_queue_size ;
incoming_app_message_queue_size ;
incoming_message_queue_size ; outgoing_message_queue_size ;
known_points_history_size ; known_peer_ids_history_size ;
max_known_points ; max_known_peer_ids ; swap_linger ;
binary_chunks_size
})
(merge_objs
(merge_objs
(obj10
(dft "connection-timeout"
~description: "Delay acceptable when initiating a \
connection to a new peer, in seconds."
float default_p2p_limits.authentication_timeout)
(dft "authentication-timeout"
~description: "Delay granted to a peer to perform authentication, \
in seconds."
float default_p2p_limits.authentication_timeout)
(dft "min-connections"
~description: "Strict minimum number of connections (triggers an \
urgent maintenance)."
uint16
default_p2p_limits.min_connections)
(dft "expected-connections"
~description: "Targeted number of connections to reach when \
bootstrapping / maintaining."
uint16
default_p2p_limits.expected_connections)
(dft "max-connections"
~description: "Maximum number of connections (exceeding peers are \
disconnected)."
uint16
default_p2p_limits.max_connections)
(dft "backlog"
~description: "Number above which pending incoming connections are \
immediately rejected."
uint8
default_p2p_limits.backlog)
(dft "max-incoming-connections"
~description: "Number above which pending incoming connections are \
immediately rejected."
uint8
default_p2p_limits.max_incoming_connections)
(opt "max-download-speed"
~description: "Max download speeds in KiB/s."
int31)
(opt "max-upload-speed"
~description: "Max upload speeds in KiB/s."
int31)
(dft "swap-linger" float default_p2p_limits.swap_linger))
(obj10
(opt "binary-chunks-size" uint8)
(dft "read-buffer-size"
~description: "Size of the buffer passed to read(2)."
int31
default_p2p_limits.read_buffer_size)
(opt "read-queue-size" int31)
(opt "write-queue-size" int31)
(opt "incoming-app-message-queue-size" int31)
(opt "incoming-message-queue-size" int31)
(opt "outgoing-message-queue-size" int31)
(dft "known_points_history_size" uint16
default_p2p_limits.known_points_history_size)
(dft "known_peer_ids_history_size" uint16
default_p2p_limits.known_points_history_size)
(opt "max_known_points" (tup2 uint16 uint16))
))
(obj3
(opt "max_known_peer_ids" (tup2 uint16 uint16))
(dft "greylist-timeout"
~description: "GC delay for the greylists tables, in seconds."
int31 default_p2p_limits.greylist_timeout)
(dft "maintenance-idle-time"
~description: "How long to wait at most, in seconds, \
before running a maintenance loop."
float default_p2p_limits.maintenance_idle_time)
)
)
let p2p =
let open Data_encoding in
conv
(fun { expected_pow ; bootstrap_peers ; listen_addr ; discovery_addr ;
private_mode ; limits ; disable_mempool } ->
( expected_pow, bootstrap_peers, listen_addr, discovery_addr ,
private_mode, limits, disable_mempool ))
(fun ( expected_pow, bootstrap_peers, listen_addr, discovery_addr,
private_mode, limits, disable_mempool ) ->
{ expected_pow ; bootstrap_peers ; listen_addr ; discovery_addr ;
private_mode ; limits ; disable_mempool })
(obj7
(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."
float default_p2p.expected_pow)
(dft "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."
(list string) default_p2p.bootstrap_peers)
(opt "listen-addr"
~description: "Host to listen to. If the port is not \
specified, the default port 8732 will be \
assumed."
string)
(dft "discovery-addr"
~description: "Host for local peer discovery. If the port is not \
specified, the default port 10732 will be \
assumed."
(option string) default_p2p.discovery_addr)
(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."
bool false)
(dft "limits"
~description: "Network limits"
limit default_p2p_limits)
(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."
bool false)
)
let rpc : rpc Data_encoding.t =
let open Data_encoding in
conv
(fun { cors_origins ; cors_headers ; listen_addr ; tls } ->
let cert, key =
match tls with
| None -> None, None
| Some { cert ; key } -> Some cert, Some key in
(listen_addr, cors_origins, cors_headers, cert, key ))
(fun (listen_addr, cors_origins, cors_headers, cert, key ) ->
let tls =
match cert, key with
| None, _ | _, None -> None
| Some cert, Some key -> Some { cert ; key } in
{ listen_addr ; cors_origins ; cors_headers ; tls })
(obj5
(opt "listen-addr"
~description: "Host to listen to. If the port is not specified, \
the default port 8732 will be assumed."
string)
(dft "cors-origin"
~description: "Cross Origin Resource Sharing parameters, see \
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing."
(list string) default_rpc.cors_origins)
(dft "cors-headers"
~description: "Cross Origin Resource Sharing parameters, see \
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing."
(list string) 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)
)
let worker_limits_encoding
default_size
default_level
default_zombie_lifetime
default_zombie_memory =
let open Data_encoding in
conv
(fun { Worker_types.backlog_size ; backlog_level ; zombie_lifetime ; zombie_memory } ->
(backlog_size, backlog_level, zombie_lifetime, zombie_memory))
(fun (backlog_size, backlog_level, zombie_lifetime, zombie_memory) ->
{ backlog_size ; backlog_level ; zombie_lifetime ; zombie_memory })
(obj4
(dft "worker_backlog_size" uint16 default_size)
(dft "worker_backlog_level" Logging_unix.level_encoding default_level)
(dft "worker_zombie_lifetime" float default_zombie_lifetime)
(dft "worker_zombie_memory" float default_zombie_memory))
let timeout_encoding =
Data_encoding.ranged_float 0. 500.
let block_validator_limits_encoding =
let open Data_encoding in
conv
(fun { Node.protocol_timeout ; worker_limits } ->
(protocol_timeout, worker_limits))
(fun (protocol_timeout, worker_limits) ->
{ protocol_timeout ; worker_limits})
(merge_objs
(obj1
(dft "protocol_request_timeout" timeout_encoding
default_shell.block_validator_limits.protocol_timeout))
(worker_limits_encoding
default_shell.block_validator_limits.worker_limits.backlog_size
default_shell.block_validator_limits.worker_limits.backlog_level
default_shell.block_validator_limits.worker_limits.zombie_lifetime
default_shell.block_validator_limits.worker_limits.zombie_memory))
let prevalidator_limits_encoding =
let open Data_encoding in
conv
(fun { Node.operation_timeout ; max_refused_operations ; worker_limits } ->
((operation_timeout, max_refused_operations), worker_limits))
(fun ((operation_timeout, max_refused_operations), worker_limits) ->
{ operation_timeout ; max_refused_operations ; worker_limits})
(merge_objs
(obj2
(dft "operations_request_timeout" timeout_encoding
default_shell.prevalidator_limits.operation_timeout)
(dft "max_refused_operations" uint16
default_shell.prevalidator_limits.max_refused_operations))
(worker_limits_encoding
default_shell.prevalidator_limits.worker_limits.backlog_size
default_shell.prevalidator_limits.worker_limits.backlog_level
default_shell.prevalidator_limits.worker_limits.zombie_lifetime
default_shell.prevalidator_limits.worker_limits.zombie_memory))
let peer_validator_limits_encoding =
let open Data_encoding in
let default_limits = default_shell.peer_validator_limits in
conv
(fun { Node.block_header_timeout ; block_operations_timeout ;
protocol_timeout ; new_head_request_timeout ; worker_limits } ->
((block_header_timeout, block_operations_timeout,
protocol_timeout, new_head_request_timeout), worker_limits))
(fun ((block_header_timeout, block_operations_timeout,
protocol_timeout, new_head_request_timeout), worker_limits) ->
{ block_header_timeout ; block_operations_timeout ;
protocol_timeout ; new_head_request_timeout ; worker_limits })
(merge_objs
(obj4
(dft "block_header_request_timeout" timeout_encoding default_limits.block_header_timeout)
(dft "block_operations_request_timeout" timeout_encoding default_limits.block_operations_timeout)
(dft "protocol_request_timeout" timeout_encoding default_limits.protocol_timeout)
(dft "new_head_request_timeout" timeout_encoding default_limits.new_head_request_timeout))
(worker_limits_encoding
default_limits.worker_limits.backlog_size
default_limits.worker_limits.backlog_level
default_limits.worker_limits.zombie_lifetime
default_limits.worker_limits.zombie_memory))
let chain_validator_limits_encoding =
let open Data_encoding in
conv
(fun { Node.bootstrap_threshold ; worker_limits } ->
(bootstrap_threshold, worker_limits))
(fun (bootstrap_threshold, worker_limits) ->
{ bootstrap_threshold ; worker_limits})
(merge_objs
(obj1
(dft "bootstrap_threshold"
~description:
"Set the number of peers with whom a chain synchronization must \
be completed to bootstrap the node."
uint8
default_shell.chain_validator_limits.bootstrap_threshold))
(worker_limits_encoding
default_shell.chain_validator_limits.worker_limits.backlog_size
default_shell.chain_validator_limits.worker_limits.backlog_level
default_shell.chain_validator_limits.worker_limits.zombie_lifetime
default_shell.chain_validator_limits.worker_limits.zombie_memory))
let shell =
let open Data_encoding in
conv
(fun { peer_validator_limits ; block_validator_limits ;
prevalidator_limits ; chain_validator_limits } ->
(peer_validator_limits, block_validator_limits,
prevalidator_limits, chain_validator_limits))
(fun (peer_validator_limits, block_validator_limits,
prevalidator_limits, chain_validator_limits) ->
{ peer_validator_limits ; block_validator_limits ;
prevalidator_limits ; chain_validator_limits })
(obj4
(dft "peer_validator" peer_validator_limits_encoding default_shell.peer_validator_limits)
(dft "block_validator" block_validator_limits_encoding default_shell.block_validator_limits)
(dft "prevalidator" prevalidator_limits_encoding default_shell.prevalidator_limits)
(dft "chain_validator" chain_validator_limits_encoding default_shell.chain_validator_limits)
)
let encoding =
let open Data_encoding in
conv
(fun { data_dir ; rpc ; p2p ; log ; shell } ->
(data_dir, rpc, p2p, log, shell))
(fun (data_dir, rpc, p2p, log, shell) ->
{ data_dir ; rpc ; p2p ; log ; shell })
(obj5
(dft "data-dir"
~description: "Location of the data dir on disk."
string default_data_dir)
(dft "rpc"
~description: "Configuration of rpc parameters"
rpc default_rpc)
(req "p2p"
~description: "Configuration of network parameters" p2p)
(dft "log"
~description: "Configuration of network parameters"
Logging_unix.cfg_encoding Logging_unix.default_cfg)
(dft "shell"
~description: "Configuration of network parameters"
shell default_shell))
let read fp =
if Sys.file_exists fp then begin
Lwt_utils_unix.Json.read_file fp >>=? fun json ->
try return (Data_encoding.Json.destruct encoding json)
with exn -> fail (Exn exn)
end else
return default_config
let write fp cfg =
Node_data_version.ensure_data_dir (Filename.dirname fp) >>=? fun () ->
Lwt_utils_unix.Json.write_file fp
(Data_encoding.Json.construct encoding cfg)
let to_string cfg =
Data_encoding.Json.to_string
(Data_encoding.Json.construct encoding cfg)
let update
?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
?discovery_addr
?rpc_listen_addr
?(private_mode = false)
?(disable_mempool = false)
?(cors_origins = [])
?(cors_headers = [])
?rpc_tls
?log_output
?bootstrap_threshold
cfg = let data_dir = Option.unopt ~default:cfg.data_dir data_dir in
Node_data_version.ensure_data_dir data_dir >>=? fun () ->
let peer_table_size =
Option.map peer_table_size ~f:(fun i -> i, i / 4 * 3) in
let unopt_list ~default = function
| [] -> default
| l -> l in
let limits : P2p.limits = {
cfg.p2p.limits with
min_connections =
Option.unopt
~default:cfg.p2p.limits.min_connections
min_connections ;
expected_connections =
Option.unopt
~default:cfg.p2p.limits.expected_connections
expected_connections ;
max_connections =
Option.unopt
~default:cfg.p2p.limits.max_connections
max_connections ;
max_download_speed =
Option.first_some
max_download_speed cfg.p2p.limits.max_download_speed ;
max_upload_speed =
Option.first_some
max_upload_speed cfg.p2p.limits.max_upload_speed ;
max_known_points =
Option.first_some
peer_table_size cfg.p2p.limits.max_known_points ;
max_known_peer_ids =
Option.first_some
peer_table_size cfg.p2p.limits.max_known_peer_ids ;
binary_chunks_size =
Option.map ~f:(fun x -> x lsl 10) binary_chunks_size ;
} in
let p2p : p2p = {
expected_pow =
Option.unopt ~default:cfg.p2p.expected_pow expected_pow ;
bootstrap_peers =
Option.unopt ~default:cfg.p2p.bootstrap_peers bootstrap_peers ;
listen_addr =
Option.first_some listen_addr cfg.p2p.listen_addr ;
discovery_addr =
Option.first_some discovery_addr cfg.p2p.discovery_addr ;
private_mode = cfg.p2p.private_mode || private_mode ;
limits ;
disable_mempool = cfg.p2p.disable_mempool || disable_mempool ;
}
and rpc : rpc = {
listen_addr =
Option.first_some rpc_listen_addr cfg.rpc.listen_addr ;
cors_origins =
unopt_list ~default:cfg.rpc.cors_origins cors_origins ;
cors_headers =
unopt_list ~default:cfg.rpc.cors_headers cors_headers ;
tls =
Option.first_some rpc_tls cfg.rpc.tls ;
}
and log : Logging_unix.cfg = {
cfg.log with
output = Option.unopt ~default:cfg.log.output log_output ;
}
and shell : shell = {
peer_validator_limits = cfg.shell.peer_validator_limits ;
block_validator_limits = cfg.shell.block_validator_limits ;
prevalidator_limits = cfg.shell.prevalidator_limits ;
chain_validator_limits =
Option.unopt_map
~default:cfg.shell.chain_validator_limits
~f:(fun bootstrap_threshold ->
{ cfg.shell.chain_validator_limits
with bootstrap_threshold })
bootstrap_threshold
}
in
return { data_dir ; p2p ; rpc ; log ; shell }
let resolve_addr ~default_addr ?default_port ?(passive = false) peer =
let addr, port = P2p_point.Id.parse_addr_port peer in
let node = if addr = "" || addr = "_" then default_addr else addr
and service =
match port, default_port with
| "", None -> invalid_arg ""
| "", Some default_port -> string_of_int default_port
| port, _ -> port in
Lwt_utils_unix.getaddrinfo ~passive ~node ~service
let resolve_addrs ~default_addr ?default_port ?passive peers =
Lwt_list.fold_left_s begin fun a peer ->
resolve_addr ~default_addr ?default_port ?passive peer >>= fun points ->
Lwt.return (List.rev_append points a)
end [] peers
let resolve_discovery_addrs discovery_addr =
resolve_addr
~default_addr:Ipaddr.V4.(to_string broadcast)
~default_port:default_discovery_port
~passive:true
discovery_addr
>>= fun addrs ->
let rec to_ipv4 acc = function
| [] -> Lwt.return (List.rev acc)
| (ip, port) :: xs -> begin match Ipaddr.v4_of_v6 ip with
| Some v -> to_ipv4 ((v, port) :: acc) xs
| None ->
Format.eprintf
"Warning: failed to convert %S to an ipv4 address@."
(Ipaddr.V6.to_string ip) ;
to_ipv4 acc xs
end
in to_ipv4 [] addrs
let resolve_listening_addrs listen_addr =
resolve_addr
~default_addr:"::"
~default_port:default_p2p_port
~passive:true
listen_addr
let resolve_rpc_listening_addrs listen_addr =
resolve_addr
~default_addr:"::"
~default_port:default_rpc_port
~passive:true
listen_addr
let resolve_bootstrap_addrs peers =
resolve_addrs
~default_addr:"::"
~default_port:default_p2p_port
peers
let check_listening_addr config =
match config.p2p.listen_addr with
| None -> Lwt.return_unit
| Some addr ->
Lwt.catch begin fun () ->
resolve_listening_addrs addr >>= function
| [] ->
Format.eprintf "Warning: failed to resolve %S\n@." addr ;
Lwt.return_unit
| _ :: _ ->
Lwt.return_unit
end begin function
| (Invalid_argument msg) ->
Format.eprintf "Warning: failed to parse %S:\ %s\n@." addr msg ;
Lwt.return_unit
| exn -> Lwt.fail exn
end
let check_discovery_addr config =
match config.p2p.discovery_addr with
| None -> Lwt.return_unit
| Some addr ->
Lwt.catch begin fun () ->
resolve_discovery_addrs addr >>= function
| [] ->
Format.eprintf "Warning: failed to resolve %S\n@." addr ;
Lwt.return_unit
| _ :: _ ->
Lwt.return_unit
end begin function
| (Invalid_argument msg) ->
Format.eprintf "Warning: failed to parse %S:\ %s\n@." addr msg ;
Lwt.return_unit
| exn -> Lwt.fail exn
end
let check_rpc_listening_addr config =
match config.rpc.listen_addr with
| None -> Lwt.return_unit
| Some addr ->
Lwt.catch begin fun () ->
resolve_rpc_listening_addrs addr >>= function
| [] ->
Format.eprintf "Warning: failed to resolve %S\n@." addr ;
Lwt.return_unit
| _ :: _ ->
Lwt.return_unit
end begin function
| (Invalid_argument msg) ->
Format.eprintf "Warning: failed to parse %S:\ %s\n@." addr msg ;
Lwt.return_unit
| exn -> Lwt.fail exn
end
let check_bootstrap_peer addr =
Lwt.catch begin fun () ->
resolve_bootstrap_addrs [addr] >>= function
| [] ->
Format.eprintf "Warning: cannot resolve %S\n@." addr ;
Lwt.return_unit
| _ :: _ ->
Lwt.return_unit
end begin function
| (Invalid_argument msg) ->
Format.eprintf "Warning: failed to parse %S:\ %s\n@." addr msg ;
Lwt.return_unit
| exn -> Lwt.fail exn
end
let check_bootstrap_peers config =
Lwt_list.iter_p check_bootstrap_peer config.p2p.bootstrap_peers
let fail fmt =
Format.kasprintf (fun s -> prerr_endline s ; exit 1) fmt
let check_connections config =
if config.p2p.limits.min_connections > config.p2p.limits.expected_connections then
fail "Error: The minumum number of connections is greater than \
the expected number of connections"
config.p2p.limits.min_connections
config.p2p.limits.expected_connections ;
if config.p2p.limits.expected_connections > config.p2p.limits.max_connections then
fail "Error: The expected number of connections is greater than \
the maximum number of connections"
config.p2p.limits.expected_connections
config.p2p.limits.max_connections ;
begin
match config.p2p.limits.max_known_peer_ids with
| None -> ()
| Some (max_known_peer_ids, target_known_peer_ids) ->
if target_known_peer_ids > max_known_peer_ids then
fail "Error: The target number of known peer ids is greater than \
the maximum number of known peer ids."
target_known_peer_ids max_known_peer_ids ;
if config.p2p.limits.max_connections > target_known_peer_ids then
fail "Error: The target number of known peer ids is lower than \
the maximum number of connections."
target_known_peer_ids max_known_peer_ids ;
end ;
begin
match config.p2p.limits.max_known_points with
| None -> ()
| Some (max_known_points, target_known_points) ->
if target_known_points > max_known_points then
fail "Error: The target number of known points is greater than \
the maximum number of known points."
target_known_points max_known_points ;
if config.p2p.limits.max_connections > target_known_points then
fail "Error: The target number of known points is lower than \
the maximum number of connections."
target_known_points max_known_points ;
end
let check config =
check_listening_addr config >>= fun () ->
check_rpc_listening_addr config >>= fun () ->
check_discovery_addr config >>= fun () ->
check_bootstrap_peers config >>= fun () ->
check_connections config ;
Lwt.return_unit

View File

@ -1,104 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* Copyright (c) 2019 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. *)
(* *)
(*****************************************************************************)
type t = {
data_dir : string ;
p2p : p2p ;
rpc : rpc ;
log : Logging_unix.cfg ;
shell : shell ;
}
and p2p = {
expected_pow : float ;
bootstrap_peers : string list ;
listen_addr : string option ;
discovery_addr : string option ;
private_mode : bool ;
limits : P2p.limits ;
disable_mempool : bool ;
}
and rpc = {
listen_addr : string option ;
cors_origins : string list ;
cors_headers : string list ;
tls : tls option ;
}
and tls = {
cert : string ;
key : string ;
}
and shell = {
block_validator_limits : Node.block_validator_limits ;
prevalidator_limits : Node.prevalidator_limits ;
peer_validator_limits : Node.peer_validator_limits ;
chain_validator_limits : Node.chain_validator_limits ;
}
val default_data_dir: string
val default_p2p_port: int
val default_rpc_port: int
val default_p2p: p2p
val default_config: t
val update:
?data_dir:string ->
?min_connections:int ->
?expected_connections:int ->
?max_connections:int ->
?max_download_speed:int ->
?max_upload_speed:int ->
?binary_chunks_size:int->
?peer_table_size:int ->
?expected_pow:float ->
?bootstrap_peers:string list ->
?listen_addr:string ->
?discovery_addr:string ->
?rpc_listen_addr:string ->
?private_mode:bool ->
?disable_mempool:bool ->
?cors_origins:string list ->
?cors_headers:string list ->
?rpc_tls:tls ->
?log_output:Logging_unix.Output.t ->
?bootstrap_threshold:int ->
t -> t tzresult Lwt.t
val to_string: t -> string
val read: string -> t tzresult Lwt.t
val write: string -> t -> unit tzresult Lwt.t
val resolve_listening_addrs: string -> (P2p_addr.t * int) list Lwt.t
val resolve_discovery_addrs: string -> (Ipaddr.V4.t * int) list Lwt.t
val resolve_rpc_listening_addrs: string -> (P2p_addr.t * int) list Lwt.t
val resolve_bootstrap_addrs: string list -> (P2p_addr.t * int) list Lwt.t
val encoding: t Data_encoding.t
val check: t -> unit Lwt.t

View File

@ -1,136 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
type t = string
let data_version = "0.0.1"
let default_identity_file_name = "identity.json"
let version_encoding = Data_encoding.(obj1 (req "version" string))
let version_file_name = "version.json"
let pp ppf version = Format.pp_print_string ppf version
type error += Invalid_data_dir_version of t * t
type error += Invalid_data_dir of string
type error += No_data_dir_version_file of string
type error += Could_not_read_data_dir_version of string
let () =
register_error_kind
`Permanent
~id: "invalidDataDir"
~title: "Invalid data directory"
~description: "The data directory cannot be accessed or created"
~pp:(fun ppf path ->
Format.fprintf ppf
"Invalid data directory '%s'."
path)
Data_encoding.(obj1 (req "datadir_path" string))
(function
| Invalid_data_dir path ->
Some path
| _ -> None)
(fun path -> Invalid_data_dir path) ;
register_error_kind
`Permanent
~id: "invalidDataDirVersion"
~title: "Invalid data directory version"
~description: "The data directory version was not the one that was expected"
~pp:(fun ppf (exp, got) ->
Format.fprintf ppf
"Invalid data directory version '%s' (expected '%s')."
got exp)
Data_encoding.(obj2
(req "expected_version" string)
(req "actual_version" string))
(function
| Invalid_data_dir_version (expected, actual) ->
Some (expected, actual)
| _ -> None)
(fun (expected, actual) -> Invalid_data_dir_version (expected, actual)) ;
register_error_kind
`Permanent
~id: "couldNotReadDataDirVersion"
~title: "Could not read data directory version file"
~description: "Data directory version file was invalid."
Data_encoding.(obj1 (req "version_path" string))
~pp:(fun ppf path ->
Format.fprintf ppf
"Tried to read version file at '%s', \
\ but the file could not be parsed."
path)
(function Could_not_read_data_dir_version path -> Some path | _ -> None)
(fun path -> Could_not_read_data_dir_version path);
register_error_kind
`Permanent
~id: "noDataDirVersionFile"
~title: "Data directory version file does not exist"
~description: "Data directory version file does not exist"
Data_encoding.(obj1 (req "version_path" string))
~pp:(fun ppf path ->
Format.fprintf ppf
"Expected to find data directory version file at '%s', \
\ but the file does not exist."
path)
(function No_data_dir_version_file path -> Some path | _ -> None)
(fun path -> No_data_dir_version_file path)
let version_file data_dir =
(Filename.concat data_dir version_file_name)
let check_data_dir_version data_dir =
let version_file = version_file data_dir in
fail_unless (Sys.file_exists version_file)
(No_data_dir_version_file version_file) >>=? fun () ->
Lwt_utils_unix.Json.read_file version_file
|> trace (Could_not_read_data_dir_version version_file) >>=? fun json ->
begin
try return (Data_encoding.Json.destruct version_encoding json)
with _ -> fail (Could_not_read_data_dir_version version_file)
end >>=? fun version ->
fail_unless
(String.equal data_version version)
(Invalid_data_dir_version (data_version, version)) >>=? fun () ->
return_unit
let ensure_data_dir data_dir =
let write_version () =
Lwt_utils_unix.Json.write_file
(version_file data_dir)
(Data_encoding.Json.construct version_encoding data_version) in
try if Sys.file_exists data_dir then
match Sys.readdir data_dir with
| [||] -> write_version ()
| [| single |] when single = default_identity_file_name -> write_version ()
| _ -> check_data_dir_version data_dir
else begin
Lwt_utils_unix.create_dir ~perm:0o700 data_dir >>= fun () ->
write_version ()
end
with Sys_error _ | Unix.Unix_error _ ->
fail (Invalid_data_dir data_dir)

View File

@ -1,38 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
type t
type error += Invalid_data_dir_version of t * t
type error += Could_not_read_data_dir_version of string
val data_version : t
val default_identity_file_name : string
val pp : Format.formatter -> t -> unit
val version_encoding : t Data_encoding.encoding
val ensure_data_dir : string -> unit tzresult Lwt.t

View File

@ -1,171 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
let (//) = Filename.concat
(** Commands *)
let identity_file data_dir = data_dir // Node_data_version.default_identity_file_name
let show { Node_config_file.data_dir } =
Node_identity_file.read (identity_file data_dir) >>=? fun id ->
Format.printf "Peer_id: %a.@." P2p_peer.Id.pp id.peer_id ;
return_unit
let generate { Node_config_file.data_dir ; p2p } =
let identity_file = identity_file data_dir in
if Sys.file_exists identity_file then
fail (Node_identity_file.Existent_identity_file identity_file)
else
let target = Crypto_box.make_target p2p.expected_pow in
Format.eprintf "Generating a new identity... (level: %.2f) " p2p.expected_pow ;
let id =
P2p_identity.generate_with_animation Format.err_formatter target in
Node_identity_file.write identity_file id >>=? fun () ->
Format.eprintf
"Stored the new identity (%a) into '%s'.@."
P2p_peer.Id.pp id.peer_id identity_file ;
return_unit
let check { Node_config_file.data_dir ; p2p = { expected_pow } } =
Node_identity_file.read
~expected_pow (identity_file data_dir) >>=? fun id ->
Format.printf
"Peer_id: %a. Proof of work is higher than %.2f.@."
P2p_peer.Id.pp id.peer_id expected_pow ;
return_unit
(** Main *)
module Term = struct
type subcommand = Show | Generate | Check
let process subcommand data_dir config_file expected_pow =
let res =
begin
match data_dir, config_file with
| None, None ->
let default_config =
Node_config_file.default_data_dir // "config.json" in
if Sys.file_exists default_config then
Node_config_file.read default_config
else
return Node_config_file.default_config
| None, Some config_file ->
Node_config_file.read config_file
| Some data_dir, None ->
Node_config_file.read (data_dir // "config.json") >>=? fun cfg ->
return { cfg with data_dir }
| Some data_dir, Some config_file ->
Node_config_file.read config_file >>=? fun cfg ->
return { cfg with data_dir }
end >>=? fun cfg ->
Node_config_file.update ?expected_pow cfg >>=? fun cfg ->
match subcommand with
| Show -> show cfg
| Generate -> generate cfg
| Check -> check cfg in
match Lwt_main.run res with
| Ok () -> `Ok ()
| Error err -> `Error (false, Format.asprintf "%a" pp_print_error err)
let subcommand_arg =
let parser = function
| "show" -> `Ok Show
| "generate" -> `Ok Generate
| "check" -> `Ok Check
| s -> `Error ("invalid argument: " ^ s)
and printer fmt = function
| Show -> Format.fprintf fmt "show"
| Generate -> Format.fprintf fmt "generate"
| Check -> Format.fprintf fmt "check" in
let doc =
"Operation to perform. \
Possible values: $(b,show), $(b,generate), $(b,check)." in
let open Cmdliner.Arg in
value & pos 0 (parser, printer) Show & info [] ~docv:"OPERATION" ~doc
let expected_pow =
let open Cmdliner in
let doc =
"Expected amount of proof-of-work for the node identity. \
The optional parameter should be a float between 0 and 256, where
0 disables the proof-of-work mechanism." in
Arg.(value & pos 1 (some float) None & info [] ~docv:"DIFFICULTY" ~doc)
let term =
Cmdliner.Term.(ret (const process
$ subcommand_arg
$ Node_shared_arg.Term.data_dir
$ Node_shared_arg.Term.config_file
$ expected_pow))
end
module Manpage = struct
let command_description =
"The $(b,identity) command is meant to create and manage node \
identities. An $(i,identity) uniquely identifies a peer on the \
network and consists of a cryptographic key pair as well as a \
proof-of-work stamp that certifies \
that enough CPU time has been dedicated to produce the identity, \
to avoid sybil attacks. An identity with enough proof-of-work is \
required to participate in the Tezos network, therefore this command \
is necessary to launch Tezos the first time."
let description = [
`S "DESCRIPTION" ;
`P (command_description ^ " Several options are possible:");
`P "$(b,show) reads, parses and displays the current identity of the node. \
Use this command to see what identity will be used by Tezos. \
This is the default operation." ;
`P "$(b,generate [difficulty]) generates an identity whose \
proof of work stamp difficulty is at least equal to $(i,difficulty). \
The value provided must be a floating point number between 0 and 256. \
It roughly reflects the numbers of expected leading zeroes in the hash \
of the identity data-structure. \
Therefore, a value of 0 means no proof-of-work, and the difficulty \
doubles for each increment of 1 in the difficulty value." ;
`P "$(b,check [difficulty]) checks that an identity is valid and that its \
proof of work stamp difficulty is at least equal to $(i,difficulty)." ;
]
let man =
description @
(* [ `S misc_docs ] @ *)
Node_shared_arg.Manpage.bugs
let info =
Cmdliner.Term.info
~doc: "Manage node identities"
~man
"identity"
end
let cmd =
Term.term, Manpage.info

View File

@ -1,30 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
val cmd: unit Cmdliner.Term.t * Cmdliner.Term.info
module Manpage : sig
val command_description: string
end

View File

@ -1,158 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
type error += No_identity_file of string
type error += Insufficient_proof_of_work of { expected: float }
type error += Identity_mismatch of {
filename: string ;
peer_id: Crypto_box.Public_key_hash.t ;
}
type error += Identity_keys_mismatch of {
filename: string ;
expected_key:Crypto_box.public_key ;
}
let () =
register_error_kind
`Permanent
~id:"main.identity.no_file"
~title:"No identity file"
~description:"The node identity file cannot be found"
~pp:(fun ppf file ->
Format.fprintf ppf
"Cannot read the identity file: `%s`. \
See `%s identity --help` on how to generate an identity."
file Sys.argv.(0))
Data_encoding.(obj1 (req "file" string))
(function No_identity_file file -> Some file | _ -> None)
(fun file -> No_identity_file file)
let () =
register_error_kind
`Permanent
~id:"main.identity.insufficient_proof_of_work"
~title:"Insufficient proof of work"
~description:"The proof of work embeded by the current identity is not sufficient"
~pp:(fun ppf expected ->
Format.fprintf ppf
"The current identity does not embed a sufficient stamp of proof-of-work. \
(expected level: %.2f). \
See `%s identity --help` on how to generate a new identity."
expected Sys.argv.(0))
Data_encoding.(obj1 (req "expected" float))
(function Insufficient_proof_of_work { expected } -> Some expected | _ -> None)
(fun expected -> Insufficient_proof_of_work { expected })
let () =
register_error_kind
`Permanent
~id:"main.identity.identity_mismatch"
~title:"Identity mismatch"
~description:"The identity (public key hash) does not match the keys provided with it"
~pp:(fun ppf (file, public_key_hash) ->
Format.fprintf ppf
"The current identity (public key hash) does not match the keys in %s.
Expected identity %a."
file
Crypto_box.Public_key_hash.pp
public_key_hash)
Data_encoding.(obj2 (req "file" string) (req "public_key_hash" Crypto_box.Public_key_hash.encoding))
(function Identity_mismatch { filename ; peer_id } ->
Some (filename, peer_id) | _ -> None)
(fun (filename,peer_id) -> Identity_mismatch { filename ; peer_id })
let () =
register_error_kind
`Permanent
~id:"main.identity.identity_keys_mismatch"
~title:"Identity keys mismatch"
~description:"The current identity file has non-matching keys (secret key/ public key pair is not valid)"
~pp:(fun ppf (file, public_key) ->
Format.fprintf ppf
"The current identity file %s has non-matching keys (secret key/ public key pair is not valid).
Expected public key %a."
file
Crypto_box.pp_pk
public_key)
Data_encoding.(obj2 (req "file" string) (req "public_key" Crypto_box.public_key_encoding))
(function
| Identity_keys_mismatch { filename ; expected_key } ->
Some (filename, expected_key)
| _ -> None)
(fun (filename, expected_key) ->
Identity_keys_mismatch { filename ; expected_key })
let read ?expected_pow filename =
Lwt_unix.file_exists filename >>= function
| false ->
fail (No_identity_file filename)
| true ->
Lwt_utils_unix.Json.read_file filename >>=? fun json ->
let id = Data_encoding.Json.destruct P2p_identity.encoding json in
let pkh = Crypto_box.hash id.public_key in
(* check public_key hash *)
if not (Crypto_box.Public_key_hash.equal pkh id.peer_id) then
fail (Identity_mismatch { filename ; peer_id = pkh })
(* check public/private keys correspondance *)
else if not Crypto_box.(equal (neuterize id.secret_key) id.public_key) then
fail (Identity_keys_mismatch { filename ; expected_key = id.public_key })
else (* check PoW level *)
match expected_pow with
| None -> return id
| Some expected ->
let target = Crypto_box.make_target expected in
if
not (Crypto_box.check_proof_of_work
id.public_key id.proof_of_work_stamp target)
then
fail (Insufficient_proof_of_work { expected })
else
return id
type error += Existent_identity_file of string
let () =
register_error_kind
`Permanent
~id:"main.identity.existent_file"
~title:"Cannot overwrite identity file"
~description:"Cannot implicitely overwrite the current identity file"
~pp:(fun ppf file ->
Format.fprintf ppf
"Cannot implicitely overwrite the current identity file: '%s'. \
See `%s identity --help` on how to generate a new identity."
file Sys.argv.(0))
Data_encoding.(obj1 (req "file" string))
(function Existent_identity_file file -> Some file | _ -> None)
(fun file -> Existent_identity_file file)
let write file identity =
if Sys.file_exists file then
fail (Existent_identity_file file)
else
Node_data_version.ensure_data_dir (Filename.dirname file) >>=? fun () ->
Lwt_utils_unix.Json.write_file file
(Data_encoding.Json.construct P2p_identity.encoding identity)

View File

@ -1,35 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
type error += No_identity_file of string
type error += Insufficient_proof_of_work of { expected: float }
val read:
?expected_pow:float ->
string -> P2p_identity.t tzresult Lwt.t
type error += Existent_identity_file of string
val write: string -> P2p_identity.t -> unit tzresult Lwt.t

View File

@ -1,26 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
include Tezos_stdlib.Logging.Make(struct let name = "node.main" end)

View File

@ -1,26 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
include Tezos_stdlib.Logging.LOG

View File

@ -1,438 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* Copyright (c) 2019 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. *)
(* *)
(*****************************************************************************)
open Node_logging
let genesis : State.Chain.genesis = {
time =
Time.of_notation_exn "2018-06-30T16:07:32Z" ;
block =
Block_hash.of_b58check_exn
"BLockGenesisGenesisGenesisGenesisGenesisf79b5d1CoW2" ;
protocol =
Protocol_hash.of_b58check_exn
"ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im" ;
}
type error += Non_private_sandbox of P2p_addr.t
type error += RPC_Port_already_in_use of P2p_point.Id.t list
let () =
register_error_kind
`Permanent
~id:"main.run.non_private_sandbox"
~title:"Forbidden public sandbox"
~description:"A sandboxed node should not listen on a public address."
~pp:begin fun ppf addr ->
Format.fprintf ppf
"The node is configured to listen on a public address (%a), \
while only 'private' networks are authorised with `--sandbox`.
See `%s run --help` on how to change the listening address."
Ipaddr.V6.pp addr Sys.argv.(0)
end
Data_encoding.(obj1 (req "addr" P2p_addr.encoding))
(function Non_private_sandbox addr -> Some addr | _ -> None)
(fun addr -> Non_private_sandbox addr);
register_error_kind
`Permanent
~id:"main.run.port_already_in_use"
~title:"Cannot start sode: RPC port already in use"
~description:"An other tezos node is probably running on the same RPC port."
~pp:begin fun ppf addrlist ->
Format.fprintf ppf
"An other tezos node is probably running on one of these addresses (%a). \
Please choose another RPC port."
(Format.pp_print_list P2p_point.Id.pp) addrlist
end
Data_encoding.(obj1 (req "addrlist" (list P2p_point.Id.encoding)))
(function | RPC_Port_already_in_use addrlist -> Some addrlist | _ -> None)
(fun addrlist -> RPC_Port_already_in_use addrlist)
let (//) = Filename.concat
let store_dir data_dir = data_dir // "store"
let context_dir data_dir = data_dir // "context"
let protocol_dir data_dir = data_dir // "protocol"
let lock_file data_dir = data_dir // "lock"
let init_node ?sandbox ?checkpoint (config : Node_config_file.t) =
let patch_context json ctxt =
begin
match json with
| None -> Lwt.return ctxt
| Some json ->
Tezos_storage.Context.set ctxt
["sandbox_parameter"]
(Data_encoding.Binary.to_bytes_exn Data_encoding.json json)
end >>= fun ctxt ->
let module Proto = (val Registered_protocol.get_exn genesis.protocol) in
Proto.init ctxt {
level = 0l ;
proto_level = 0 ;
predecessor = genesis.block ;
timestamp = genesis.time ;
validation_passes = 0 ;
operations_hash = Operation_list_list_hash.empty ;
fitness = [] ;
context = Context_hash.zero ;
} >>= function
| Error _ -> assert false (* FIXME error *)
| Ok { context = ctxt ; _ } ->
Lwt.return ctxt in
begin
match sandbox with
| None -> Lwt.return_none
| Some sandbox_param ->
match sandbox_param with
| None -> Lwt.return_none
| Some file ->
Lwt_utils_unix.Json.read_file file >>= function
| Error err ->
lwt_warn
"Can't parse sandbox parameters: %s" file >>= fun () ->
lwt_debug "%a" pp_print_error err >>= fun () ->
Lwt.return_none
| Ok json ->
Lwt.return_some json
end >>= fun sandbox_param ->
(* TODO "WARN" when pow is below our expectation. *)
begin
match config.p2p.discovery_addr with
| None ->
lwt_log_notice "No local peer discovery." >>= fun () ->
return (None, None)
| Some addr ->
Node_config_file.resolve_discovery_addrs addr >>= function
| [] ->
failwith "Cannot resolve P2P discovery address: %S" addr
| (addr, port) :: _ ->
return (Some addr, Some port)
end >>=? fun (discovery_addr, discovery_port) ->
begin
match config.p2p.listen_addr with
| None ->
lwt_log_notice "Not listening to P2P calls." >>= fun () ->
return (None, None)
| Some addr ->
Node_config_file.resolve_listening_addrs addr >>= function
| [] ->
failwith "Cannot resolve P2P listening address: %S" addr
| (addr, port) :: _ -> return (Some addr, Some port)
end >>=? fun (listening_addr, listening_port) ->
begin
match listening_addr, sandbox with
| Some addr, Some _
when Ipaddr.V6.(compare addr unspecified) = 0 ->
return_none
| Some addr, Some _ when not (Ipaddr.V6.is_private addr) ->
fail (Non_private_sandbox addr)
| None, Some _ -> return_none
| _ ->
(Node_config_file.resolve_bootstrap_addrs
config.p2p.bootstrap_peers) >>= fun trusted_points ->
Node_identity_file.read
(config.data_dir //
Node_data_version.default_identity_file_name) >>=? fun identity ->
lwt_log_notice
"Peer's global id: %a"
P2p_peer.Id.pp identity.peer_id >>= fun () ->
let p2p_config : P2p.config =
{ listening_addr ;
listening_port ;
discovery_addr ;
discovery_port ;
trusted_points ;
peers_file =
(config.data_dir // "peers.json") ;
private_mode = config.p2p.private_mode ;
identity ;
proof_of_work_target =
Crypto_box.make_target config.p2p.expected_pow ;
disable_mempool = config.p2p.disable_mempool ;
trust_discovered_peers = (sandbox_param <> None) ;
}
in
return_some (p2p_config, config.p2p.limits)
end >>=? fun p2p_config ->
let node_config : Node.config = {
genesis ;
patch_context = Some (patch_context sandbox_param) ;
store_root = store_dir config.data_dir ;
context_root = context_dir config.data_dir ;
p2p = p2p_config ;
test_chain_max_tll = Some (48 * 3600) ; (* 2 days *)
checkpoint ;
} in
Node.create
~sandboxed:(sandbox <> None)
node_config
config.shell.peer_validator_limits
config.shell.block_validator_limits
config.shell.prevalidator_limits
config.shell.chain_validator_limits
(* Add default accepted CORS headers *)
let sanitize_cors_headers ~default headers =
List.map String.lowercase_ascii headers |>
String.Set.of_list |>
String.Set.(union (of_list default)) |>
String.Set.elements
let launch_rpc_server
(rpc_config : Node_config_file.rpc) node (addr, port) =
let host = Ipaddr.V6.to_string addr in
let dir = Node.build_rpc_directory node in
let mode =
match rpc_config.tls with
| None -> `TCP (`Port port)
| Some { cert ; key } ->
`TLS (`Crt_file_path cert, `Key_file_path key,
`No_password, `Port port) in
lwt_log_notice
"Starting a RPC server listening on %s:%d%s."
host port
(if rpc_config.tls = None then "" else " (TLS enabled)") >>= fun () ->
let cors_headers =
sanitize_cors_headers
~default:["Content-Type"] rpc_config.cors_headers in
Lwt.catch begin fun () ->
RPC_server.launch ~host mode dir
~media_types:Media_type.all_media_types
~cors:{ allowed_origins = rpc_config.cors_origins ;
allowed_headers = cors_headers } >>= return
end begin function
| Unix.Unix_error(Unix.EADDRINUSE, "bind","") ->
fail (RPC_Port_already_in_use [(addr,port)])
| exn -> Lwt.return (error_exn exn)
end
let init_rpc (rpc_config: Node_config_file.rpc) node =
match rpc_config.listen_addr with
| None ->
lwt_log_notice "Not listening to RPC calls." >>= fun () ->
return_nil
| Some addr ->
Node_config_file.resolve_rpc_listening_addrs addr >>= function
| [] ->
failwith "Cannot resolve listening address: %S" addr
| addrs ->
map_s (launch_rpc_server rpc_config node) addrs
let init_signal () =
let handler name id = try
fatal_error "Received the %s signal, triggering shutdown." name ;
Lwt_exit.exit id
with _ -> () in
ignore (Lwt_unix.on_signal Sys.sigint (handler "INT") : Lwt_unix.signal_handler_id) ;
ignore (Lwt_unix.on_signal Sys.sigterm (handler "TERM") : Lwt_unix.signal_handler_id)
let run ?verbosity ?sandbox ?checkpoint (config : Node_config_file.t) =
Node_data_version.ensure_data_dir config.data_dir >>=? fun () ->
Lwt_lock_file.create
~unlink_on_exit:true (lock_file config.data_dir) >>=? fun () ->
init_signal () ;
let log_cfg =
match verbosity with
| None -> config.log
| Some default_level -> { config.log with default_level } in
Logging_unix.init ~cfg:log_cfg () >>= fun () ->
Updater.init (protocol_dir config.data_dir) ;
lwt_log_notice "Starting the Tezos node..." >>= fun () ->
init_node ?sandbox ?checkpoint config >>=? fun node ->
init_rpc config.rpc node >>=? fun rpc ->
lwt_log_notice "The Tezos node is now running!" >>= fun () ->
Lwt_exit.termination_thread >>= fun x ->
lwt_log_notice "Shutting down the Tezos node..." >>= fun () ->
Node.shutdown node >>= fun () ->
lwt_log_notice "Shutting down the RPC server..." >>= fun () ->
Lwt_list.iter_s RPC_server.shutdown rpc >>= fun () ->
lwt_log_notice "BYE (%d)" x >>= fun () ->
Logging_unix.close () >>= fun () ->
return_unit
let process sandbox verbosity checkpoint args =
let verbosity =
match verbosity with
| [] -> None
| [_] -> Some Logging.Info
| _ -> Some Logging.Debug in
let run =
Node_shared_arg.read_and_patch_config_file
~ignore_bootstrap_peers:(match sandbox with
| Some _ -> true
| None -> false)
args >>=? fun config ->
begin match sandbox with
| Some _ ->
if config.data_dir = Node_config_file.default_data_dir
then failwith "Cannot use default data directory while in sandbox mode"
else return_unit
| None -> return_unit
end >>=? fun () ->
begin
match checkpoint with
| None -> return_none
| Some s ->
match String.split ',' s with
| [ lvl ; block ] ->
Lwt.return (Block_hash.of_b58check block) >>=? fun block ->
begin
match Int32.of_string_opt lvl with
| None ->
failwith "%s isn't a 32bit integer" lvl
| Some lvl ->
return lvl
end >>=? fun lvl ->
return_some (lvl, block)
| [] -> assert false
| [_] ->
failwith "Checkoints are expected to follow the format \
\"<level>,<block_hash>\". \
The character ',' is not present in %s" s
| _ ->
failwith "Checkoints are expected to follow the format \
\"<level>,<block_hash>\". \
The character ',' is present more than once in %s" s
end >>=? fun checkpoint ->
Lwt_lock_file.is_locked
(lock_file config.data_dir) >>=? function
| false ->
Lwt.catch
(fun () -> run ?sandbox ?verbosity ?checkpoint config)
(function
|Unix.Unix_error(Unix.EADDRINUSE, "bind","") ->
begin match config.rpc.listen_addr with
| None -> assert false
| Some addr ->
Node_config_file.resolve_rpc_listening_addrs addr >>= fun addrlist ->
fail (RPC_Port_already_in_use addrlist)
end
| exn -> Lwt.return (error_exn exn)
)
| true -> failwith "Data directory is locked by another process" in
match Lwt_main.run run with
| Ok () -> `Ok ()
| Error err -> `Error (false, Format.asprintf "%a" pp_print_error err)
module Term = struct
let verbosity =
let open Cmdliner in
let doc =
"Increase log level. Using $(b,-v) is equivalent to \
using $(b,TEZOS_LOG='* -> info'), and $(b,-vv) is equivalent to using \
$(b,TEZOS_LOG='* -> debug')." in
Arg.(value & flag_all &
info ~docs:Node_shared_arg.Manpage.misc_section ~doc ["v"])
let sandbox =
let open Cmdliner in
let doc =
"Run the daemon in sandbox mode. \
P2P to non-localhost addresses are disabled, and constants of \
the economic protocol can be altered with an optional JSON file. \
$(b,IMPORTANT): Using sandbox mode affects the node state and \
subsequent runs of Tezos node must also use sandbox mode. \
In order to run the node in normal mode afterwards, a full reset \
must be performed (by removing the node's data directory)."
in
Arg.(value & opt ~vopt:(Some None) (some (some string)) None &
info ~docs:Node_shared_arg.Manpage.misc_section
~doc ~docv:"FILE.json" ["sandbox"])
let checkpoint =
let open Cmdliner in
let doc =
"When asked to take a block hash as a checkpoint, the daemon \
will only accept the chains that contains that block and those \
that might reach it."
in
Arg.(value & opt (some string) None &
info ~docs:Node_shared_arg.Manpage.misc_section
~doc ~docv:"<level>,<block_hash>" ["checkpoint"])
let term =
Cmdliner.Term.(ret (const process $ sandbox $ verbosity $ checkpoint $
Node_shared_arg.Term.args))
end
module Manpage = struct
let command_description =
"The $(b,run) command is meant to run the Tezos node. \
Most of its command line arguments corresponds to config file \
entries, and will have priority over the latter if used."
let description = [
`S "DESCRIPTION" ;
`P command_description ;
]
let debug =
let log_sections = String.concat " " (List.rev !Logging.sections) in
[
`S "DEBUG" ;
`P ("The environment variable $(b,TEZOS_LOG) is used to fine-tune \
what is going to be logged. The syntax is \
$(b,TEZOS_LOG='<section> -> <level> [ ; ...]') \
where section is one of $(i,"
^ log_sections ^
") and level is one of $(i,fatal), $(i,error), $(i,warn), \
$(i,notice), $(i,info) or $(i,debug). \
A $(b,*) can be used as a wildcard \
in sections, i.e. $(b, client* -> debug). \
The rules are matched left to right, \
therefore the leftmost rule is highest priority ."
) ;
]
let examples =
[
`S "EXAMPLES" ;
`I ("$(b,Run in sandbox mode listening to RPC commands \
at localhost port 8732)",
"$(mname) run --sandbox --data-dir /custom/data/dir \
--rpc-addr localhost:8732" ) ;
`I ("$(b,Run a node that accepts network connections)",
"$(mname) run" ) ;
]
let man =
description @
Node_shared_arg.Manpage.args @
examples @
Node_shared_arg.Manpage.bugs
let info =
Cmdliner.Term.info
~doc:"Run the Tezos node"
~man
"run"
end
let cmd = Term.term, Manpage.info

View File

@ -1,31 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.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. *)
(* *)
(*****************************************************************************)
val cmd: unit Cmdliner.Term.t * Cmdliner.Term.info
module Manpage : sig
val command_description: string
val examples: Cmdliner.Manpage.block list
end

View File

@ -1,339 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* Copyright (c) 2019 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. *)
(* *)
(*****************************************************************************)
open Cmdliner
open Node_logging
let (//) = Filename.concat
type t = {
data_dir: string option ;
config_file: string ;
min_connections: int option ;
expected_connections: int option ;
max_connections: int option ;
max_download_speed: int option ;
max_upload_speed: int option ;
binary_chunks_size: int option ;
peer_table_size: int option ;
expected_pow: float option ;
peers: string list ;
no_bootstrap_peers: bool ;
listen_addr: string option ;
discovery_addr: string option ;
rpc_listen_addr: string option ;
private_mode: bool ;
disable_mempool: bool ;
cors_origins: string list ;
cors_headers: string list ;
rpc_tls: Node_config_file.tls option ;
log_output: Logging_unix.Output.t option ;
bootstrap_threshold: int option ;
}
let wrap
data_dir config_file
connections max_download_speed max_upload_speed binary_chunks_size
peer_table_size
listen_addr discovery_addr peers no_bootstrap_peers
bootstrap_threshold private_mode disable_mempool
expected_pow rpc_listen_addr rpc_tls
cors_origins cors_headers log_output =
let actual_data_dir =
Option.unopt ~default:Node_config_file.default_data_dir data_dir in
let config_file =
Option.unopt ~default:(actual_data_dir // "config.json") config_file in
let rpc_tls =
Option.map
~f:(fun (cert, key) -> { Node_config_file.cert ; key })
rpc_tls in
(* when `--connections` is used,
override all the bounds defined in the configuration file. *)
let bootstrap_threshold,
min_connections, expected_connections, max_connections,
peer_table_size =
match connections with
| None -> bootstrap_threshold, None, None, None, peer_table_size
| Some x ->
let peer_table_size =
match peer_table_size with
| None -> Some (8*x)
| Some _ -> peer_table_size in
begin match bootstrap_threshold with
| None -> Some (min (x/4) 2), Some (x/2), Some x, Some (3*x/2), peer_table_size
| Some bs -> Some bs, Some (x/2), Some x, Some (3*x/2), peer_table_size
end
in
{ data_dir ;
config_file ;
min_connections ;
expected_connections ;
max_connections ;
max_download_speed ;
max_upload_speed ;
binary_chunks_size ;
expected_pow ;
peers ;
no_bootstrap_peers ;
listen_addr ;
discovery_addr ;
rpc_listen_addr ;
private_mode ;
disable_mempool ;
cors_origins ;
cors_headers ;
rpc_tls ;
log_output ;
peer_table_size ;
bootstrap_threshold ;
}
module Manpage = struct
let misc_section = "MISC OPTIONS"
let p2p_section = "P2P OPTIONS"
let rpc_section = "RPC OPTIONS"
let args = [
`S p2p_section ;
`S rpc_section ;
`S misc_section ;
]
let bugs = [
`S "BUGS";
`P "Check bug reports at https://gitlab.com/tezos/tezos/issues.";
]
end
module Term = struct
let log_output_converter =
(fun s -> match Logging_unix.Output.of_string s with
| Some res -> `Ok res
| None -> `Error s),
Logging_unix.Output.pp
(* misc args *)
let docs = Manpage.misc_section
let log_output =
let doc =
"Log output. Either $(i,stdout), $(i,stderr), \
$(i,syslog:<facility>) or a file path." in
Arg.(value & opt (some log_output_converter) None &
info ~docs ~docv:"OUTPUT" ~doc ["log-output"])
let data_dir =
let doc =
"The directory where the Tezos node will store all its data." in
Arg.(value & opt (some string) None &
info ~docs ~doc ~docv:"DIR" ["data-dir"])
let config_file =
let doc = "The main configuration file." in
Arg.(value & opt (some string) None &
info ~docs ~doc ~docv:"FILE" ["config-file"])
(* P2p args *)
let docs = Manpage.p2p_section
let connections =
let doc =
"Sets min_connections, expected_connections, max_connections to NUM / 2, \
NUM, (3 * NUM) / 2, respectively. Sets peer_table_size to 8 * NUM \
unless it is already defined in the configuration file. Sets \
bootstrap_threshold to min(NUM / 4, 2) unless it is already defined in \
the configuration file." in
Arg.(value & opt (some int) None &
info ~docs ~doc ~docv:"NUM" ["connections"])
let max_download_speed =
let doc =
"The maximum number of bytes read per second." in
Arg.(value & opt (some int) None &
info ~docs ~doc ~docv:"NUM" ["max-download-speed"])
let max_upload_speed =
let doc =
"The maximum number of bytes sent per second." in
Arg.(value & opt (some int) None &
info ~docs ~doc ~docv:"NUM" ["max-upload-speed"])
let binary_chunks_size =
let doc =
"Size limit (in kB) of binary blocks that are sent to other peers." in
Arg.(value & opt (some int) None &
info ~docs ~doc ~docv:"NUM" ["binary-chunks-size"])
let peer_table_size =
let doc = "Maximum size of internal peer tables, \
used to store metadata/logs about a peer or about a \
to-be-authenticated host:port couple." in
Arg.(value & opt (some int) None &
info ~docs ~doc ~docv:"NUM" ["peer-table-size"])
let listen_addr =
let doc =
"The TCP address and port at which this instance can be reached." in
Arg.(value & opt (some string) None &
info ~docs ~doc ~docv:"ADDR:PORT" ["net-addr"])
let discovery_addr =
let doc = "The UDP address and port used for local peer discovery." in
Arg.(value & opt (some string) None &
info ~docs ~doc ~docv:"ADDR:PORT" ["discovery-addr"])
let no_bootstrap_peers =
let doc =
"Ignore the peers found in the config file (or the hard-coded \
bootstrap peers in the absence of config file)." in
Arg.(value & flag &
info ~docs ~doc ["no-bootstrap-peers"])
let bootstrap_threshold =
let doc =
"Set the number of peers with whom a chain synchronization must \
be completed to bootstrap the node" in
Arg.(value & opt (some int) None &
info ~docs ~doc ~docv:"NUM" ["bootstrap-threshold"])
let peers =
let doc =
"A peer to bootstrap the network from. \
Can be used several times to add several peers." in
Arg.(value & opt_all string [] &
info ~docs ~doc ~docv:"ADDR:PORT" ["peer"])
let expected_pow =
let doc =
"Expected level of proof-of-work for peers identity." in
Arg.(value & opt (some float) None &
info ~docs ~doc ~docv:"FLOAT" ["expected-pow"])
let private_mode =
let doc =
"Only open outgoing/accept incoming connections to/from peers \
listed in 'bootstrap-peers' or provided with '--peer' option." in
Arg.(value & flag & info ~docs ~doc ["private-mode"])
let disable_mempool =
let doc =
"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." in
Arg.(value & flag & info ~docs ~doc ["disable-mempool"])
(* rpc args *)
let docs = Manpage.rpc_section
let rpc_listen_addr =
let doc =
"The TCP socket address at which this RPC server \
instance can be reached." in
Arg.(value & opt (some string) None &
info ~docs ~doc ~docv:"ADDR:PORT" ["rpc-addr"])
let rpc_tls =
let doc =
"Enable TLS for this RPC server \
with the provided certificate and key." in
Arg.(value & opt (some (pair string string)) None &
info ~docs ~doc ~docv:"crt,key" ["rpc-tls"])
let cors_origins =
let doc =
"CORS origin allowed by the RPC server \
via Access-Control-Allow-Origin; may be used multiple times" in
Arg.(value & opt_all string [] &
info ~docs ~doc ~docv:"ORIGIN" ["cors-origin"])
let cors_headers =
let doc =
"Header reported by Access-Control-Allow-Headers \
reported during CORS preflighting; may be used multiple times" in
Arg.(value & opt_all string [] &
info ~docs ~doc ~docv:"HEADER" ["cors-header"])
let args =
let open Term in
const wrap $ data_dir $ config_file
$ connections
$ max_download_speed $ max_upload_speed $ binary_chunks_size
$ peer_table_size
$ listen_addr $ discovery_addr $ peers $ no_bootstrap_peers
$ bootstrap_threshold
$ private_mode $ disable_mempool
$ expected_pow $ rpc_listen_addr $ rpc_tls
$ cors_origins $ cors_headers
$ log_output
end
let read_and_patch_config_file ?(ignore_bootstrap_peers=false) args =
begin
if Sys.file_exists args.config_file then
Node_config_file.read args.config_file
else
return Node_config_file.default_config
end >>=? fun cfg ->
let { data_dir ;
min_connections ; expected_connections ; max_connections ;
max_download_speed ; max_upload_speed ; binary_chunks_size ;
peer_table_size ;
expected_pow ;
peers ; no_bootstrap_peers ;
listen_addr ; private_mode ;
discovery_addr ;
disable_mempool ;
rpc_listen_addr ; rpc_tls ;
cors_origins ; cors_headers ;
log_output ;
bootstrap_threshold ;
} = args in
let bootstrap_peers =
if no_bootstrap_peers || ignore_bootstrap_peers
then begin
log_info "Ignoring bootstrap peers" ;
peers
end else
cfg.p2p.bootstrap_peers @ peers in
Node_config_file.update
?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 ?discovery_addr ?rpc_listen_addr ~private_mode
~disable_mempool ~cors_origins ~cors_headers ?rpc_tls ?log_output
?bootstrap_threshold cfg

View File

@ -1,64 +0,0 @@
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* Copyright (c) 2019 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. *)
(* *)
(*****************************************************************************)
type t = {
data_dir: string option ;
config_file: string ;
min_connections: int option ;
expected_connections: int option ;
max_connections: int option ;
max_download_speed: int option ;
max_upload_speed: int option ;
binary_chunks_size: int option ;
peer_table_size: int option ;
expected_pow: float option ;
peers: string list ;
no_bootstrap_peers: bool ;
listen_addr: string option ;
discovery_addr: string option ;
rpc_listen_addr: string option ;
private_mode: bool ;
disable_mempool: bool ;
cors_origins: string list ;
cors_headers: string list ;
rpc_tls: Node_config_file.tls option ;
log_output: Logging_unix.Output.t option ;
bootstrap_threshold: int option ;
}
module Term : sig
val args: t Cmdliner.Term.t
val data_dir: string option Cmdliner.Term.t
val config_file: string option Cmdliner.Term.t
end
val read_and_patch_config_file: ?ignore_bootstrap_peers:bool -> t -> Node_config_file.t tzresult Lwt.t
module Manpage : sig
val misc_section: string
val args: Cmdliner.Manpage.block list
val bugs: Cmdliner.Manpage.block list
end

View File

@ -1,29 +0,0 @@
opam-version: "2.0"
maintainer: "contact@tezos.com"
authors: [ "Tezos devteam" ]
homepage: "https://www.tezos.com/"
bug-reports: "https://gitlab.com/tezos/tezos/issues"
dev-repo: "git+https://gitlab.com/tezos/tezos.git"
license: "MIT"
depends: [
"ocamlfind" { build }
"dune" { build & >= "1.0.1" }
"tezos-base"
"tezos-rpc-http"
"tezos-p2p"
"tezos-shell"
"tezos-protocol-updater"
"tezos-embedded-protocol-genesis"
"tezos-embedded-protocol-demo"
"tezos-embedded-protocol-alpha"
"cmdliner"
"tls"
"cstruct" { < "3.4.0" } ## Because "tls" depends on a version of "nocrypto"
## that is not compatible with recent "cstruct"
]
build: [
[ "dune" "build" "-p" name "-j" jobs ]
]
run-test: [
[ "dune" "runtest" "-p" name "-j" jobs ]
]

View File

@ -1,222 +0,0 @@
#! /usr/bin/env bash
set -e
node_dirs=()
node_pids=()
start_sandboxed_node() {
id=$1
max_peer_id=${max_peer_id:-9}
shift 1
port=$((19730 + id))
rpc=$((18730 + id))
expected_pow="${expected_pow:-0.0}"
expected_connections="${expected_connections:-3}"
node_dir="$(mktemp -d -t tezos-node.XXXXXXXX)"
peers=("--no-bootstrap-peers")
for peer_port in $(seq 19730 $((19730 + max_peer_id))); do
peers+=("--peer")
peers+=("127.0.0.1:$peer_port")
done
peers+=("--private-mode")
node="${local_node}"
sandbox_param="--sandbox=$sandbox_file"
if ! [ -f "$sandbox_file" ]; then
cat > "$sandbox_file" <<EOF
{
"genesis_pubkey":
"edpkuSLWfVU1Vq7Jg9FucPyKmma6otcMHac9zG4oU1KMHSTBpJuGQ2"
}
EOF
fi
node_dirs+=("$node_dir")
if [ -n "$USE_TLS" ]; then
$node config init \
--data-dir "$node_dir" \
--net-addr "127.0.0.1:$port" \
--rpc-addr "127.0.0.1:$rpc" \
--rpc-tls "${node_dir}/tezos.crt,${node_dir}/tezos.key" \
--expected-pow "$expected_pow" \
--connections "$expected_connections"
cat > "${node_dir}/tezos.crt" <<EOF
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Easy-RSA CA
Validity
Not Before: Mar 30 13:07:24 2018 GMT
Not After : Mar 27 13:07:24 2028 GMT
Subject: CN=tezos
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:d3:61:ba:81:6a:0d:8f:0b:6f:84:65:ca:73:b5:
c6:2d:89:8e:83:90:9e:2c:e1:16:5f:2c:9d:44:00:
25:dd:a2:73:dc:41:06:81:fb:a1:0c:e9:17:db:63:
6b:c2:46:63:bc:31:4c:bc:76:50:a0:79:15:de:4a:
98:d1:eb:a3:d1:a9:4c:db:32:3e:05:23:be:60:b7:
5c:d1:4f:ec:fe:6d:a3:5f:75:0e:8d:e7:c5:d1:48:
6f:29:84:0a:cc:52:91:8b:8a:67:65:88:82:1a:a7:
31:6c:5c:00:1c:53:0e:fb:98:81:c7:5d:20:e8:72:
15:f1:53:e1:a8:e6:45:92:25:6b:a3:f6:67:da:63:
9f:fd:35:f6:54:04:c1:10:50:e9:5d:95:e3:12:7f:
e1:8f:bc:6c:65:48:f6:0c:eb:9e:d1:cb:30:1f:da:
ff:a2:d5:5d:bb:de:e5:df:b8:52:f3:70:6c:2d:8a:
e9:bb:85:7f:33:14:bc:fa:1e:c5:c4:b3:9f:f3:10:
a3:1c:00:f6:8f:84:ae:a3:a3:08:ae:b8:38:41:0a:
a7:84:88:bf:9d:e3:0d:42:51:75:dd:b2:5c:8b:9c:
fa:82:ff:0d:bd:6f:f7:c3:b5:e4:49:3a:5c:8c:cc:
7f:1c:80:7b:c1:47:ad:2c:fe:44:f1:fc:93:0e:ac:
4f:27
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Subject Key Identifier:
B4:C2:AB:C3:F6:64:80:94:43:46:7F:40:25:E4:D1:CF:01:33:44:DA
X509v3 Authority Key Identifier:
keyid:5E:27:08:3B:81:1D:FA:05:CC:D3:94:D4:2B:9B:92:5B:3B:F9:EA:A1
DirName:/CN=Easy-RSA CA
serial:D5:46:5A:8E:8B:18:BD:2B
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Subject Alternative Name:
DNS:tezos
Signature Algorithm: sha256WithRSAEncryption
2f:23:1a:9e:42:72:2b:57:ec:26:04:a2:a0:22:f3:31:0e:12:
c4:46:92:95:b6:c7:44:bf:ab:5b:5b:15:c3:69:a3:48:79:be:
f9:09:aa:42:8c:8a:83:6a:55:68:b7:6c:02:b4:1a:d4:98:52:
b1:2e:bf:6c:3f:da:ef:93:e0:c8:69:fd:b7:dd:f7:42:65:e1:
66:ab:99:c2:d7:81:62:e2:e9:63:98:8a:24:9b:34:da:8a:82:
03:00:08:29:00:3f:18:cd:94:00:a7:22:0c:25:be:fa:74:64:
ea:45:1f:62:e4:bd:f6:88:42:35:ca:7e:e4:a1:5f:a9:94:6d:
4e:80:38:7b:3c:65:41:c4:e3:bc:40:de:50:b6:61:8c:ae:3a:
de:d9:1e:af:e9:59:e3:c2:b2:5f:47:09:83:66:3c:d7:e5:4f:
ec:27:8c:90:69:1d:6a:95:3e:2f:bf:89:95:58:ae:25:6d:90:
bd:ce:41:63:91:58:e3:16:f9:08:70:c5:c1:5f:5d:f7:0d:a5:
77:e5:a3:84:82:53:bf:30:6a:10:df:1c:b1:1f:81:c8:e0:c7:
48:4d:74:47:21:48:3a:8a:80:f9:3c:43:c1:2c:0e:a4:40:51:
b7:f3:b7:27:98:ab:23:cb:b1:05:67:59:ab:cf:23:f8:1b:9f:
61:0d:8b:5e
-----BEGIN CERTIFICATE-----
MIIDSzCCAjOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDDAtFYXN5
LVJTQSBDQTAeFw0xODAzMzAxMzA3MjRaFw0yODAzMjcxMzA3MjRaMBAxDjAMBgNV
BAMMBXRlem9zMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA02G6gWoN
jwtvhGXKc7XGLYmOg5CeLOEWXyydRAAl3aJz3EEGgfuhDOkX22NrwkZjvDFMvHZQ
oHkV3kqY0euj0alM2zI+BSO+YLdc0U/s/m2jX3UOjefF0UhvKYQKzFKRi4pnZYiC
GqcxbFwAHFMO+5iBx10g6HIV8VPhqOZFkiVro/Zn2mOf/TX2VATBEFDpXZXjEn/h
j7xsZUj2DOue0cswH9r/otVdu97l37hS83BsLYrpu4V/MxS8+h7FxLOf8xCjHAD2
j4Suo6MIrrg4QQqnhIi/neMNQlF13bJci5z6gv8NvW/3w7XkSTpcjMx/HIB7wUet
LP5E8fyTDqxPJwIDAQABo4GpMIGmMAkGA1UdEwQCMAAwHQYDVR0OBBYEFLTCq8P2
ZICUQ0Z/QCXk0c8BM0TaMEYGA1UdIwQ/MD2AFF4nCDuBHfoFzNOU1Cubkls7+eqh
oRqkGDAWMRQwEgYDVQQDDAtFYXN5LVJTQSBDQYIJANVGWo6LGL0rMBMGA1UdJQQM
MAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIFoDAQBgNVHREECTAHggV0ZXpvczANBgkq
hkiG9w0BAQsFAAOCAQEALyMankJyK1fsJgSioCLzMQ4SxEaSlbbHRL+rW1sVw2mj
SHm++QmqQoyKg2pVaLdsArQa1JhSsS6/bD/a75PgyGn9t933QmXhZquZwteBYuLp
Y5iKJJs02oqCAwAIKQA/GM2UAKciDCW++nRk6kUfYuS99ohCNcp+5KFfqZRtToA4
ezxlQcTjvEDeULZhjK463tker+lZ48KyX0cJg2Y81+VP7CeMkGkdapU+L7+JlViu
JW2Qvc5BY5FY4xb5CHDFwV9d9w2ld+WjhIJTvzBqEN8csR+ByODHSE10RyFIOoqA
+TxDwSwOpEBRt/O3J5irI8uxBWdZq88j+BufYQ2LXg==
-----END CERTIFICATE-----
EOF
cat > "${node_dir}/tezos.key" <<EOF
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDTYbqBag2PC2+E
ZcpztcYtiY6DkJ4s4RZfLJ1EACXdonPcQQaB+6EM6RfbY2vCRmO8MUy8dlCgeRXe
SpjR66PRqUzbMj4FI75gt1zRT+z+baNfdQ6N58XRSG8phArMUpGLimdliIIapzFs
XAAcUw77mIHHXSDochXxU+Go5kWSJWuj9mfaY5/9NfZUBMEQUOldleMSf+GPvGxl
SPYM657RyzAf2v+i1V273uXfuFLzcGwtium7hX8zFLz6HsXEs5/zEKMcAPaPhK6j
owiuuDhBCqeEiL+d4w1CUXXdslyLnPqC/w29b/fDteRJOlyMzH8cgHvBR60s/kTx
/JMOrE8nAgMBAAECggEBAKjMC9E4TSeDbEP/vRF1gJHwnLt3Criv7duGlvcsXxCD
n52s13OI6uySXpi05eI3r4EipTKCEJR03P+r9ij70M+mMFeB4YDdMDOveRE0j/4E
s0eRBFRRVuhuvUYbyTusW8lgdnzf63U5OgBb30K/GOHUwR3gwlycbeVOpI7pg3jV
sNdv9rHxQ0n8ohC2GUsrHBxuq83Jk1zeo/9R0ENPqvkReN9n/ldrjbxqDR1EPd/P
AloiZeA/3p3hTqQmaWmwv8nn5tT8SlICbQXgdlLkfBJwQHpsTaflf5oZX2Rafl+9
irFpjDMcCSdgpqbDtYpSiHDgTLaY1cO8P384eL6MXBECgYEA9tfPh36Cn5UnhzYf
MOUSrV7Qu61aFanvKLYq6MEYcIHkXvo59FANM1HTbvhRsyvpmSRZs1F8+hhkTzPh
aziLUGfvpy4MY+KRH1iXnrmySmTAf2Ry3ddmxLVALgSpNR8C+65WygmcRCB2X0Xc
rEbMGflYIet2fMPnndGVo2T0cv0CgYEA2zknU2a/leYxaz7spXEBhcsAtqtlFsHl
o+IybsCHyg8TQMo1pOydgTjEa5uGToTZWwm3hJHmyujQb/Brj/vDxSfAXskbHOIN
NN/P66rfGC25cn6qr459a7RXvhmdsMVisrE4j3sVJBmKBPZSs05drNyYw2INqvQZ
e+WOPGX2nfMCgYByEzQuSvH07ApTe1iY0RR7mLjgMvHR1zHWX7Ge1TYFMJIorn1A
AgrHr8YFn66qHd4bzufBbiRStBkPXUuMsJn5c78WRLqnIpqsoNWZHfpeVQd9GB/Z
k+VDfPwHCFJmYUmQpHYpcp2MAnCSAQhFeYZzbn8jVdzxNdwBXE1KMKqjxQKBgDaI
tjayFbDFbb+/DIFvZjCROmE2q9QIcgbdqywP6veh3mk8pDGdxuSxaXNXYgbAV42l
EikBXodVeRyPk0JjH+U4qUsq/fqmZSClGIUIoazTGxHXXsCDUsHrP/SDTM3/nDjV
iztuI+kyDTqEyDfgo77vtXTNPJctV/WROlveBYZvAoGBANCVDb/9bL+Sknwk8UUN
qqK1s+/HnLDBZZSGD6e3zfUoBsYtN1PkNmhxrLFsSaRzMEEbIgCCt2bs5vl/DWoi
lcQiNhsWRkdUDXpJd0WeqkGK3Gqb4KimoxdGrhhUQ2JmzqanOCuDpmKDDQDGe7Qy
XRWBqNomtTmVA25kchhzSMBQ
-----END PRIVATE KEY-----
EOF
else
$node config init \
--data-dir "$node_dir" \
--net-addr "127.0.0.1:$port" \
--rpc-addr "127.0.0.1:$rpc" \
--expected-pow "$expected_pow" \
--connections "$expected_connections"
fi
$node identity generate "$expected_pow" --data-dir "$node_dir"
$node run --data-dir "$node_dir" "${peers[@]}" "$sandbox_param" "$@" &
node_pids+=("$!")
}
cleanup_nodes() {
[ -z "${node_pids[0]}" ] || kill "${node_pids[@]}"
for pid in "${node_pids[@]}" ; do wait "$pid" ; done
rm -rf "${node_dirs[@]}"
}
main() {
local bin_dir="$(cd "$(dirname "$0")" && echo "$(pwd -P)/")"
if [ $(basename "$bin_dir") = "bin_node" ]; then
local_node="${local_node:-$bin_dir/../../_build/default/src/bin_node/main.exe}"
sandbox_file="${sandbox_file:-$bin_dir/../../scripts/sandbox.json}"
else
local_node="${local_node:-tezos-node}"
sandbox_file="${sandbox_file:-sandbox.json}"
fi
if [ $# -lt 1 ] || [ "$1" -le 0 ] || [ 10 -le "$1" ]; then
echo "Small script to launch local and closed test network with a maximum of 9 nodes."
echo
echo "Usage: $0 <id>"
echo " where <id> should be an integer between 1 and 9."
exit 1
fi
cleanup () {
set +e
echo Cleaning up...
cleanup_nodes
}
trap cleanup EXIT INT
start_sandboxed_node "$@"
wait $node_pids
}
if [ "$0" == "$BASH_SOURCE" ]; then
main "$@"
fi