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. *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
|
|
|
open Logging.Updater
|
|
|
|
|
|
|
|
let (//) = Filename.concat
|
|
|
|
|
2018-02-05 14:32:12 +04:00
|
|
|
module Raw = struct
|
|
|
|
|
|
|
|
type validation_result = {
|
|
|
|
context: Context.t ;
|
|
|
|
fitness: Fitness.t ;
|
|
|
|
message: string option ;
|
|
|
|
max_operation_data_length: int ;
|
|
|
|
max_operations_ttl: int ;
|
|
|
|
}
|
|
|
|
|
|
|
|
type quota = {
|
|
|
|
max_size: int ;
|
|
|
|
max_op: int option ;
|
|
|
|
}
|
|
|
|
|
|
|
|
type rpc_context = {
|
|
|
|
block_hash: Block_hash.t ;
|
|
|
|
block_header: Block_header.t ;
|
|
|
|
operation_hashes: unit -> Operation_hash.t list list Lwt.t ;
|
|
|
|
operations: unit -> Operation.t list list Lwt.t ;
|
|
|
|
context: Context.t ;
|
|
|
|
}
|
|
|
|
|
|
|
|
let activate = Context.set_protocol
|
|
|
|
let fork_test_network = Context.fork_test_network
|
|
|
|
|
|
|
|
(** Compiler *)
|
|
|
|
|
|
|
|
let datadir = ref None
|
|
|
|
let get_datadir () =
|
|
|
|
match !datadir with
|
|
|
|
| None ->
|
|
|
|
fatal_error "Node not initialized" ;
|
|
|
|
Lwt_exit.exit 1
|
|
|
|
| Some m -> m
|
|
|
|
|
|
|
|
let init dir =
|
|
|
|
datadir := Some dir
|
|
|
|
|
|
|
|
let compiler_name = "tezos-protocol-compiler"
|
|
|
|
|
|
|
|
let do_compile hash p =
|
|
|
|
assert (p.Protocol.expected_env = V1) ;
|
|
|
|
let datadir = get_datadir () in
|
|
|
|
let source_dir = datadir // Protocol_hash.to_short_b58check hash // "src" in
|
|
|
|
let log_file = datadir // Protocol_hash.to_short_b58check hash // "LOG" in
|
|
|
|
let plugin_file = datadir // Protocol_hash.to_short_b58check hash //
|
|
|
|
Format.asprintf "protocol_%a.cmxs" Protocol_hash.pp hash
|
|
|
|
in
|
2018-02-08 13:51:01 +04:00
|
|
|
begin
|
|
|
|
Lwt_utils_unix.Protocol.write_dir source_dir ~hash p >>=? fun () ->
|
|
|
|
let compiler_command =
|
|
|
|
(Sys.executable_name,
|
|
|
|
Array.of_list [compiler_name; "-register"; plugin_file; source_dir]) in
|
|
|
|
let fd = Unix.(openfile log_file [O_WRONLY; O_CREAT; O_TRUNC] 0o644) in
|
2018-02-05 14:32:12 +04:00
|
|
|
Lwt_process.exec
|
|
|
|
~stdin:`Close ~stdout:(`FD_copy fd) ~stderr:(`FD_move fd)
|
2018-02-08 13:51:01 +04:00
|
|
|
compiler_command >>= return
|
|
|
|
end >>= function
|
|
|
|
| Error err ->
|
|
|
|
log_error "Error %a" pp_print_error err ;
|
|
|
|
Lwt.return false
|
|
|
|
| Ok (Unix.WSIGNALED _ | Unix.WSTOPPED _) ->
|
2018-02-05 14:32:12 +04:00
|
|
|
log_error "INTERRUPTED COMPILATION (%s)" log_file;
|
2016-09-08 21:13:10 +04:00
|
|
|
Lwt.return false
|
2018-02-08 13:51:01 +04:00
|
|
|
| Ok (Unix.WEXITED x) when x <> 0 ->
|
2018-02-05 14:32:12 +04:00
|
|
|
log_error "COMPILATION ERROR (%s)" log_file;
|
|
|
|
Lwt.return false
|
2018-02-08 13:51:01 +04:00
|
|
|
| Ok (Unix.WEXITED _) ->
|
2018-02-05 14:32:12 +04:00
|
|
|
try Dynlink.loadfile_private plugin_file; Lwt.return true
|
|
|
|
with Dynlink.Error err ->
|
|
|
|
log_error "Can't load plugin: %s (%s)"
|
|
|
|
(Dynlink.error_message err) plugin_file;
|
|
|
|
Lwt.return false
|
|
|
|
|
|
|
|
let compile hash p =
|
|
|
|
if Tezos_protocol_registerer.Registerer.mem hash then
|
|
|
|
Lwt.return true
|
|
|
|
else begin
|
|
|
|
do_compile hash p >>= fun success ->
|
|
|
|
let loaded = Tezos_protocol_registerer.Registerer.mem hash in
|
|
|
|
if success && not loaded then
|
|
|
|
log_error "Internal error while compiling %a" Protocol_hash.pp hash;
|
|
|
|
Lwt.return loaded
|
|
|
|
end
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2018-02-05 14:32:12 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
include Raw
|
2017-10-09 12:55:12 +04:00
|
|
|
|
2018-02-11 22:17:39 +04:00
|
|
|
module type NODE_PROTOCOL = Protocol_environment.T
|
|
|
|
with type context := Context.t
|
|
|
|
and type validation_result := validation_result
|
|
|
|
and type quota := quota
|
|
|
|
and type rpc_context := rpc_context
|
|
|
|
and type 'a tzresult := 'a tzresult
|
|
|
|
|
2017-10-27 20:53:07 +04:00
|
|
|
module Node_protocol_environment_sigs = struct
|
|
|
|
|
2018-02-11 22:17:39 +04:00
|
|
|
module type V1 = Protocol_environment.V1
|
|
|
|
with type Context.t = Context.t
|
|
|
|
and type Updater.validation_result = validation_result
|
|
|
|
and type Updater.quota = quota
|
|
|
|
and type Updater.rpc_context = rpc_context
|
2017-10-27 20:53:07 +04:00
|
|
|
|
|
|
|
end
|
|
|
|
|
2018-02-05 14:32:12 +04:00
|
|
|
module MakeV1(Name : sig val name: string end)()
|
|
|
|
: Node_protocol_environment_sigs.V1 =
|
|
|
|
Protocol_environment.MakeV1(Name)(Context)(Raw)()
|
|
|
|
|