ligo/src/bin_node/node_identity_command.ml
2018-02-16 02:57:25 +01:00

156 lines
5.9 KiB
OCaml

(**************************************************************************)
(* *)
(* Copyright (c) 2014 - 2018. *)
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* *)
(* All rights reserved. No warranty, explicit or implicit, provided. *)
(* *)
(**************************************************************************)
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 ()
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 ()
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 ()
(** 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