2016-09-08 21:13:10 +04:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
2018-02-06 00:17:03 +04:00
|
|
|
(* Copyright (c) 2014 - 2018. *)
|
2016-09-08 21:13:10 +04:00
|
|
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
2016-12-03 16:05:02 +04:00
|
|
|
type ('a, 'b) lwt_format =
|
|
|
|
('a, Format.formatter, unit, 'b Lwt.t) format4
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2017-11-07 20:38:11 +04:00
|
|
|
class type logger_sig = object
|
|
|
|
method error : ('a, 'b) lwt_format -> 'a
|
|
|
|
method warning : ('a, unit) lwt_format -> 'a
|
|
|
|
method message : ('a, unit) lwt_format -> 'a
|
|
|
|
method answer : ('a, unit) lwt_format -> 'a
|
|
|
|
method log : string -> ('a, unit) lwt_format -> 'a
|
|
|
|
end
|
|
|
|
|
|
|
|
class logger log =
|
|
|
|
let message =
|
|
|
|
(fun x ->
|
|
|
|
Format.kasprintf (fun msg -> log "stdout" msg) x) in
|
|
|
|
object
|
|
|
|
method error : type a b. (a, b) lwt_format -> a =
|
|
|
|
Format.kasprintf
|
|
|
|
(fun msg ->
|
|
|
|
Lwt.fail (Failure msg))
|
|
|
|
method warning : type a. (a, unit) lwt_format -> a =
|
|
|
|
Format.kasprintf
|
|
|
|
(fun msg -> log "stderr" msg)
|
|
|
|
method message : type a. (a, unit) lwt_format -> a = message
|
|
|
|
method answer : type a. (a, unit) lwt_format -> a = message
|
|
|
|
method log : type a. string -> (a, unit) lwt_format -> a =
|
|
|
|
fun name ->
|
|
|
|
Format.kasprintf
|
|
|
|
(fun msg -> log name msg)
|
|
|
|
end
|
|
|
|
|
|
|
|
class type wallet = object
|
|
|
|
method load : string -> default:'a -> 'a Data_encoding.encoding -> 'a tzresult Lwt.t
|
|
|
|
method write : string -> 'a -> 'a Data_encoding.encoding -> unit tzresult Lwt.t
|
|
|
|
end
|
|
|
|
|
|
|
|
class type block = object
|
2018-01-26 16:07:49 +04:00
|
|
|
method block : Block_services.block
|
2017-11-07 20:38:11 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
class type logging_wallet = object
|
|
|
|
inherit logger
|
|
|
|
inherit wallet
|
|
|
|
end
|
|
|
|
|
|
|
|
class type logging_rpcs = object
|
|
|
|
inherit logger
|
2018-02-11 22:17:39 +04:00
|
|
|
inherit RPC_client.ctxt
|
2017-11-07 20:38:11 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
class type full_context = object
|
|
|
|
inherit logger
|
|
|
|
inherit wallet
|
2018-02-11 22:17:39 +04:00
|
|
|
inherit RPC_client.ctxt
|
2017-11-07 20:38:11 +04:00
|
|
|
inherit block
|
|
|
|
end
|
|
|
|
|
2018-02-11 22:17:40 +04:00
|
|
|
class proxy_context (obj : full_context) = object
|
|
|
|
method block = obj#block
|
|
|
|
method answer : type a. (a, unit) lwt_format -> a = obj#answer
|
|
|
|
method call_service :
|
|
|
|
'm 'p 'q 'i 'o.
|
|
|
|
([< Resto.meth ] as 'm, 'pr, 'p, 'q, 'i, 'o) RPC_service.t ->
|
|
|
|
'p -> 'q -> 'i -> 'o tzresult Lwt.t = obj#call_service
|
|
|
|
method call_streamed_service :
|
|
|
|
'm 'p 'q 'i 'o.
|
|
|
|
([< Resto.meth ] as 'm, 'pr, 'p, 'q, 'i, 'o) RPC_service.t ->
|
|
|
|
on_chunk: ('o -> unit) ->
|
|
|
|
on_close: (unit -> unit) ->
|
|
|
|
'p -> 'q -> 'i -> (unit -> unit) tzresult Lwt.t = obj#call_streamed_service
|
|
|
|
method error : type a b. (a, b) lwt_format -> a = obj#error
|
|
|
|
method generic_json_call = obj#generic_json_call
|
|
|
|
method load : type a. string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t = obj#load
|
|
|
|
method log : type a. string -> (a, unit) lwt_format -> a = obj#log
|
|
|
|
method message : type a. (a, unit) lwt_format -> a = obj#message
|
|
|
|
method warning : type a. (a, unit) lwt_format -> a = obj#warning
|
|
|
|
method write : type a. string -> a -> a Data_encoding.encoding -> unit tzresult Lwt.t = obj#write
|
|
|
|
end
|
|
|
|
|
2017-11-07 20:38:11 +04:00
|
|
|
|
|
|
|
class file_wallet dir : wallet = object (self)
|
|
|
|
method private filename alias_name =
|
|
|
|
Filename.concat
|
|
|
|
dir
|
2018-02-15 14:07:42 +04:00
|
|
|
(Re_str.(global_replace (regexp_string " ") "_" alias_name) ^ "s")
|
2017-11-07 20:38:11 +04:00
|
|
|
|
|
|
|
method load : type a. string -> default:a -> a Data_encoding.encoding -> a tzresult Lwt.t =
|
|
|
|
fun alias_name ~default encoding ->
|
|
|
|
let filename = self#filename alias_name in
|
|
|
|
if not (Sys.file_exists filename) then
|
|
|
|
return default
|
|
|
|
else
|
2018-02-08 13:51:01 +04:00
|
|
|
Lwt_utils_unix.Json.read_file filename
|
2017-11-07 20:38:11 +04:00
|
|
|
|> generic_trace
|
|
|
|
"couldn't to read the %s file" alias_name >>=? fun json ->
|
|
|
|
match Data_encoding.Json.destruct encoding json with
|
|
|
|
| exception _ -> (* TODO print_error *)
|
|
|
|
failwith "didn't understand the %s file" alias_name
|
|
|
|
| data ->
|
|
|
|
return data
|
|
|
|
|
|
|
|
method write :
|
|
|
|
type a. string -> a -> a Data_encoding.encoding -> unit tzresult Lwt.t =
|
|
|
|
fun alias_name list encoding ->
|
|
|
|
Lwt.catch
|
|
|
|
(fun () ->
|
2018-02-08 13:51:01 +04:00
|
|
|
Lwt_utils_unix.create_dir dir >>= fun () ->
|
2017-11-07 20:38:11 +04:00
|
|
|
let filename = self#filename alias_name in
|
|
|
|
let json = Data_encoding.Json.construct encoding list in
|
2018-02-08 13:51:01 +04:00
|
|
|
Lwt_utils_unix.Json.write_file filename json)
|
2017-11-07 20:38:11 +04:00
|
|
|
(fun exn -> Lwt.return (error_exn exn))
|
|
|
|
|> generic_trace "could not write the %s alias file." alias_name
|
|
|
|
end
|
|
|
|
|
|
|
|
type command = (full_context, unit) Cli_entries.command
|
2016-12-03 16:05:02 +04:00
|
|
|
|
2017-03-15 04:17:20 +04:00
|
|
|
(* Default config *)
|
|
|
|
|
|
|
|
let (//) = Filename.concat
|
|
|
|
|
2017-03-31 02:42:13 +04:00
|
|
|
let home =
|
|
|
|
try Sys.getenv "HOME"
|
|
|
|
with Not_found -> "/root"
|
|
|
|
|
|
|
|
let default_base_dir = home // ".tezos-client"
|
|
|
|
|
2017-11-07 20:38:11 +04:00
|
|
|
let default_block = `Prevalidation
|
|
|
|
|
|
|
|
let default_log ~base_dir channel msg =
|
|
|
|
let startup =
|
|
|
|
CalendarLib.Printer.Precise_Calendar.sprint
|
|
|
|
"%Y-%m-%dT%H:%M:%SZ"
|
|
|
|
(CalendarLib.Calendar.Precise.now ()) in
|
|
|
|
match channel with
|
|
|
|
| "stdout" ->
|
|
|
|
print_endline msg ;
|
|
|
|
Lwt.return ()
|
|
|
|
| "stderr" ->
|
|
|
|
prerr_endline msg ;
|
|
|
|
Lwt.return ()
|
|
|
|
| log ->
|
|
|
|
let (//) = Filename.concat in
|
2018-02-08 13:51:01 +04:00
|
|
|
Lwt_utils_unix.create_dir (base_dir // "logs" // log) >>= fun () ->
|
2017-11-07 20:38:11 +04:00
|
|
|
Lwt_io.with_file
|
|
|
|
~flags: Unix.[ O_APPEND ; O_CREAT ; O_WRONLY ]
|
|
|
|
~mode: Lwt_io.Output
|
|
|
|
(base_dir // "logs" // log // startup)
|
|
|
|
(fun chan -> Lwt_io.write chan msg)
|
2017-03-15 04:17:20 +04:00
|
|
|
|
2017-04-05 01:35:41 +04:00
|
|
|
let make_context
|
2017-11-07 20:38:11 +04:00
|
|
|
?(base_dir = default_base_dir)
|
|
|
|
?(block = default_block)
|
2018-02-11 22:17:39 +04:00
|
|
|
?(rpc_config = RPC_client.default_config)
|
2017-04-05 01:35:41 +04:00
|
|
|
log =
|
2017-11-07 20:38:11 +04:00
|
|
|
object
|
|
|
|
inherit logger log
|
|
|
|
inherit file_wallet base_dir
|
2018-02-11 22:17:39 +04:00
|
|
|
inherit RPC_client.http_ctxt rpc_config Media_type.all_media_types
|
2017-11-07 20:38:11 +04:00
|
|
|
method block = block
|
|
|
|
end
|
2016-12-03 16:05:02 +04:00
|
|
|
|
|
|
|
let ignore_context =
|
|
|
|
make_context (fun _ _ -> Lwt.return ())
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
exception Version_not_found
|
|
|
|
|
2017-02-24 20:17:53 +04:00
|
|
|
let versions = Protocol_hash.Table.create 7
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let get_versions () =
|
2017-02-24 20:17:53 +04:00
|
|
|
Protocol_hash.Table.fold
|
2016-09-08 21:13:10 +04:00
|
|
|
(fun k c acc -> (k, c) :: acc)
|
|
|
|
versions
|
|
|
|
[]
|
|
|
|
|
|
|
|
let register name commands =
|
|
|
|
let previous =
|
2017-02-24 20:17:53 +04:00
|
|
|
try Protocol_hash.Table.find versions name
|
2016-09-08 21:13:10 +04:00
|
|
|
with Not_found -> [] in
|
2017-11-27 02:17:25 +04:00
|
|
|
Protocol_hash.Table.replace versions name (commands @ previous)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
let commands_for_version version =
|
2017-02-24 20:17:53 +04:00
|
|
|
try Protocol_hash.Table.find versions version
|
2016-09-08 21:13:10 +04:00
|
|
|
with Not_found -> raise Version_not_found
|
2017-11-07 17:23:01 +04:00
|
|
|
|
2018-01-29 13:43:07 +04:00
|
|
|
let force_switch ?(doc = "Silence any warnings and some checks.") () =
|
|
|
|
Cli_entries.switch ~parameter:"-force" ~doc
|