node_shared_arg.ml 9.3 KB
Newer Older
1 2
(**************************************************************************)
(*                                                                        *)
3
(*    Copyright (c) 2014 - 2018.                                          *)
4 5 6 7 8 9 10
(*    Dynamic Ledger Solutions, Inc. <contact@tezos.com>                  *)
(*                                                                        *)
(*    All rights reserved. No warranty, explicit or implicit, provided.   *)
(*                                                                        *)
(**************************************************************************)

open Cmdliner
11
open Node_logging
12 13 14 15 16 17 18 19 20 21 22

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 ;
23
  binary_chunks_size: int option ;
24
  peer_table_size: int option ;
25 26 27 28 29 30
  expected_pow: float option ;
  peers: string list ;
  no_bootstrap_peers: bool ;
  listen_addr: string option ;
  rpc_listen_addr: string option ;
  closed: bool ;
31
  disable_mempool: bool ;
32 33 34
  cors_origins: string list ;
  cors_headers: string list ;
  rpc_tls: Node_config_file.tls option ;
35
  log_output: Logging_unix.Output.t option ;
36
  bootstrap_threshold: int option ;
37 38 39 40
}

let wrap
    data_dir config_file
41
    connections max_download_speed max_upload_speed binary_chunks_size
42
    peer_table_size
43 44
    listen_addr peers no_bootstrap_peers bootstrap_threshold closed disable_mempool
    expected_pow rpc_listen_addr rpc_tls
45 46 47
    cors_origins cors_headers log_output =

  let actual_data_dir =
48
    Option.unopt ~default:Node_config_file.default_data_dir data_dir in
49 50

  let config_file =
51
    Option.unopt ~default:(actual_data_dir // "config.json") config_file in
52 53

  let rpc_tls =
54
    Option.map
Milo Davis's avatar
Milo Davis committed
55
      ~f:(fun (cert, key) -> { Node_config_file.cert ; key })
56 57 58 59
      rpc_tls in

  (* when `--expected-connections` is used,
     override all the bounds defined in the configuration file. *)
60 61
  let bootstrap_threshold,
      min_connections, expected_connections, max_connections =
62
    match connections with
63 64 65 66 67 68 69
    | None -> bootstrap_threshold, None, None, None
    | Some x ->
        begin match bootstrap_threshold with
          | None -> Some (min (x/4) 2), Some (x/2), Some x, Some (3*x/2)
          | Some bs -> Some bs, Some (x/2), Some x, Some (3*x/2)
        end
  in
70 71 72 73 74 75 76
  { data_dir ;
    config_file ;
    min_connections ;
    expected_connections ;
    max_connections ;
    max_download_speed ;
    max_upload_speed ;
77
    binary_chunks_size ;
78 79 80 81 82 83
    expected_pow ;
    peers ;
    no_bootstrap_peers ;
    listen_addr ;
    rpc_listen_addr ;
    closed ;
84
    disable_mempool ;
85 86 87 88
    cors_origins ;
    cors_headers ;
    rpc_tls ;
    log_output ;
89
    peer_table_size ;
90
    bootstrap_threshold ;
91 92 93 94 95
  }

module Manpage = struct

  let misc_section = "MISC OPTIONS"
96
  let p2p_section = "P2P OPTIONS"
97 98 99
  let rpc_section = "RPC OPTIONS"

  let args = [
100
    `S p2p_section ;
101 102 103 104 105 106
    `S rpc_section ;
    `S misc_section ;
  ]

  let bugs = [
    `S "BUGS";
107
    `P "Check bug reports at https://gitlab.com/tezos/tezos/issues.";
108 109 110 111 112 113 114
  ]

end

module Term = struct

  let log_output_converter =
115
    (fun s -> match Logging_unix.Output.of_string s with
116 117
       | Some res -> `Ok res
       | None -> `Error s),
118
    Logging_unix.Output.pp
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

  (* 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"])

142
  (* P2p args *)
143

144
  let docs = Manpage.p2p_section
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

  let connections =
    let doc =
      "The number of running connections that we aim for." 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"])

164 165 166
  let binary_chunks_size =
    let doc =
      Format.sprintf
Pietro Abate's avatar
Pietro Abate committed
167
        "Size limit (in kB) of binary blocks that are sent to other peers."
168 169 170 171
    in
    Arg.(value & opt (some int) None &
         info ~docs ~doc ~docv:"NUM" ["binary-chunks-size"])

172 173 174 175 176 177 178
  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"])

179 180 181 182 183 184 185 186
  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 no_bootstrap_peers =
    let doc =
187
      "Ignore the peers found in the config file (or the hard-coded \
188 189 190 191
       bootstrap peers in the absence of config file)." in
    Arg.(value & flag &
         info ~docs ~doc ["no-bootstrap-peers"])

192 193 194 195 196 197 198
  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"])

199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
  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 closed =
    let doc =
      "Only accept connections from the configured bootstrap peers." in
    Arg.(value & flag & info ~docs ~doc ["closed"])

217 218 219 220 221 222 223 224 225
  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"])

226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
  (* 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
261
    $ max_download_speed $ max_upload_speed $ binary_chunks_size
262
    $ peer_table_size
263 264
    $ listen_addr $ peers $ no_bootstrap_peers $ bootstrap_threshold $ closed $ disable_mempool
    $ expected_pow $ rpc_listen_addr $ rpc_tls
265 266 267 268 269
    $ cors_origins $ cors_headers
    $ log_output

end

270
let read_and_patch_config_file ?(ignore_bootstrap_peers=false) args =
271 272 273 274 275 276 277 278
  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 ;
279
        max_download_speed ; max_upload_speed ; binary_chunks_size ;
280
        peer_table_size ;
281 282 283
        expected_pow ;
        peers ; no_bootstrap_peers ;
        listen_addr ; closed ;
284
        disable_mempool ;
285 286
        rpc_listen_addr ; rpc_tls ;
        cors_origins ; cors_headers ;
287 288 289
        log_output ;
        bootstrap_threshold ;
      } = args in
290
  let bootstrap_peers =
291
    if no_bootstrap_peers || ignore_bootstrap_peers
292 293 294 295
    then begin
      log_info "Ignoring bootstrap peers" ;
      peers
    end else
296
      cfg.p2p.bootstrap_peers @ peers in
297 298
  Node_config_file.update
    ?data_dir ?min_connections ?expected_connections ?max_connections
299 300
    ?max_download_speed ?max_upload_speed ?binary_chunks_size
    ?peer_table_size ?expected_pow
301
    ~bootstrap_peers ?listen_addr ?rpc_listen_addr
302
    ~closed ~disable_mempool ~cors_origins ~cors_headers ?rpc_tls ?log_output
303
    ?bootstrap_threshold cfg