ligo/src/lib_shell/node.ml

238 lines
8.2 KiB
OCaml
Raw Normal View History

2018-06-29 16:08:08 +04:00
(*****************************************************************************)
(* *)
(* 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. *)
(* *)
(*****************************************************************************)
2016-09-08 21:13:10 +04:00
open Lwt.Infix
open Worker_logging
2016-09-08 21:13:10 +04:00
type t = {
state: State.t ;
distributed_db: Distributed_db.t ;
2017-09-29 20:43:13 +04:00
validator: Validator.t ;
2018-02-16 04:26:24 +04:00
mainchain_validator: Chain_validator.t ;
p2p: Distributed_db.p2p ; (* For P2P RPCs *)
2016-09-08 21:13:10 +04:00
shutdown: unit -> unit Lwt.t ;
}
let peer_metadata_cfg : _ P2p.peer_meta_config = {
peer_meta_encoding = Peer_metadata.encoding ;
peer_meta_initial = () ;
score = fun _ -> 0. ;
}
let connection_metadata_cfg cfg : _ P2p.conn_meta_config = {
conn_meta_encoding = Connection_metadata.encoding ;
private_node = (fun { private_node } -> private_node) ;
conn_meta_value = fun _ -> cfg;
}
let init_connection_metadata opt =
let open Connection_metadata in
match opt with
| None ->
{ disable_mempool = false ;
private_node = false }
| Some c ->
{ disable_mempool = c.P2p.disable_mempool ;
private_node = c.P2p.private_mode }
2018-07-17 11:19:44 +04:00
let init_p2p ?(sandboxed = false) p2p_params =
2018-02-16 04:26:24 +04:00
match p2p_params with
2016-09-08 21:13:10 +04:00
| None ->
let c_meta = init_connection_metadata None in
lwt_log_notice Tag.DSL.(fun f ->
f "P2P layer is disabled" -% t event "p2p_disabled") >>= fun () ->
return (P2p.faked_network peer_metadata_cfg c_meta)
2016-09-08 21:13:10 +04:00
| Some (config, limits) ->
let c_meta = init_connection_metadata (Some config) in
let conn_metadata_cfg = connection_metadata_cfg c_meta in
lwt_log_notice Tag.DSL.(fun f ->
f "bootstrapping chain..." -% t event "bootstrapping_chain") >>= fun () ->
2018-07-17 11:19:44 +04:00
let message_cfg =
if sandboxed then
{ Distributed_db_message.cfg with
versions =
List.map
(fun v -> { v with P2p_version.name =
"SANDBOXED_" ^ v.P2p_version.name })
Distributed_db_message.cfg.versions }
else
Distributed_db_message.cfg in
P2p.create
~config ~limits
peer_metadata_cfg
conn_metadata_cfg
2018-07-17 11:19:44 +04:00
message_cfg >>=? fun p2p ->
Lwt.async (fun () -> P2p.maintain p2p) ;
return p2p
2017-01-23 14:10:07 +04:00
type config = {
2018-02-16 04:26:24 +04:00
genesis: State.Chain.genesis ;
2017-01-23 14:10:07 +04:00
store_root: string ;
context_root: string ;
patch_context: (Context.t -> Context.t Lwt.t) option ;
p2p: (P2p.config * P2p.limits) option ;
2018-02-16 04:26:24 +04:00
test_chain_max_tll: int option ;
checkpoint: (Int32.t * Block_hash.t) option ;
2017-01-23 14:10:07 +04:00
}
2016-09-08 21:13:10 +04:00
and peer_validator_limits = Peer_validator.limits = {
new_head_request_timeout: float ;
block_header_timeout: float ;
block_operations_timeout: float ;
protocol_timeout: float ;
worker_limits: Worker_types.limits
}
and prevalidator_limits = Prevalidator.limits = {
max_refused_operations: int ;
operation_timeout: float ;
worker_limits : Worker_types.limits ;
}
and block_validator_limits = Block_validator.limits = {
protocol_timeout: float ;
worker_limits : Worker_types.limits ;
}
2018-02-16 04:26:24 +04:00
and chain_validator_limits = Chain_validator.limits = {
bootstrap_threshold: int ;
worker_limits : Worker_types.limits ;
}
let default_block_validator_limits = {
protocol_timeout = 120. ;
worker_limits = {
backlog_size = 1000 ;
backlog_level = Logging.Debug ;
zombie_lifetime = 3600. ;
zombie_memory = 1800. ;
}
}
let default_prevalidator_limits = {
operation_timeout = 10. ;
max_refused_operations = 1000 ;
worker_limits = {
backlog_size = 1000 ;
backlog_level = Logging.Info ;
zombie_lifetime = 600. ;
zombie_memory = 120. ;
}
}
let default_peer_validator_limits = {
block_header_timeout = 60. ;
block_operations_timeout = 60. ;
protocol_timeout = 120. ;
new_head_request_timeout = 90. ;
worker_limits = {
backlog_size = 1000 ;
backlog_level = Logging.Info ;
zombie_lifetime = 600. ;
zombie_memory = 120. ;
}
}
let default_chain_validator_limits = {
bootstrap_threshold = 4 ;
worker_limits = {
backlog_size = 1000 ;
backlog_level = Logging.Info ;
zombie_lifetime = 600. ;
zombie_memory = 120. ;
}
}
let may_update_checkpoint chain_state checkpoint =
match checkpoint with
| None ->
Lwt.return_unit
| Some checkpoint ->
State.best_known_head_for_checkpoint
chain_state checkpoint >>= fun new_head ->
Chain.set_head chain_state new_head >>= fun _old_head ->
State.Chain.set_checkpoint chain_state checkpoint
2018-07-17 11:19:44 +04:00
let create
?(sandboxed = false)
{ genesis ; store_root ; context_root ;
patch_context ; p2p = p2p_params ;
test_chain_max_tll = max_child_ttl ; checkpoint }
peer_validator_limits
block_validator_limits
prevalidator_limits
2018-02-16 04:26:24 +04:00
chain_validator_limits =
let start_prevalidator =
match p2p_params with
| Some (config, _limits) -> not config.P2p.disable_mempool
| None -> true in
2018-07-17 11:19:44 +04:00
init_p2p ~sandboxed p2p_params >>=? fun p2p ->
2016-09-08 21:13:10 +04:00
State.read
~store_root ~context_root ?patch_context genesis >>=? fun (state, mainchain_state) ->
may_update_checkpoint mainchain_state checkpoint >>= fun () ->
let distributed_db = Distributed_db.create state p2p in
Validator.create state distributed_db
peer_validator_limits
block_validator_limits
prevalidator_limits
2018-02-16 04:26:24 +04:00
chain_validator_limits >>= fun validator ->
2017-09-29 20:43:13 +04:00
Validator.activate validator
?max_child_ttl ~start_prevalidator mainchain_state >>= fun mainchain_validator ->
2016-09-08 21:13:10 +04:00
let shutdown () =
P2p.shutdown p2p >>= fun () ->
Validator.shutdown validator >>= fun () ->
State.close state >>= fun () ->
Lwt.return_unit
2016-09-08 21:13:10 +04:00
in
return {
state ;
distributed_db ;
2016-09-08 21:13:10 +04:00
validator ;
2018-02-16 04:26:24 +04:00
mainchain_validator ;
p2p ;
2016-09-08 21:13:10 +04:00
shutdown ;
}
let shutdown node = node.shutdown ()
let build_rpc_directory node =
let dir : unit RPC_directory.t ref = ref RPC_directory.empty in
let merge d = dir := RPC_directory.merge !dir d in
let register0 s f =
dir := RPC_directory.register !dir s (fun () p q -> f p q) in
merge (Protocol_directory.build_rpc_directory node.state) ;
merge (Monitor_directory.build_rpc_directory
node.validator node.mainchain_validator) ;
merge (Injection_directory.build_rpc_directory node.validator) ;
merge (Chain_directory.build_rpc_directory node.validator) ;
merge (P2p.build_rpc_directory node.p2p) ;
merge (Worker_directory.build_rpc_directory node.state) ;
register0 RPC_service.error_service begin fun () () ->
return (Data_encoding.Json.schema Error_monad.error_encoding)
end ;
RPC_directory.register_describe_directory_service
!dir RPC_service.description_service