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
|
|
|
|
2017-02-17 22:12:06 +04:00
|
|
|
open Lwt.Infix
|
2018-06-01 01:05:00 +04:00
|
|
|
open Worker_logging
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
type t = {
|
|
|
|
state: State.t ;
|
2017-02-24 20:17:53 +04:00
|
|
|
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 ;
|
2017-02-24 20:17:53 +04:00
|
|
|
p2p: Distributed_db.p2p ; (* For P2P RPCs *)
|
2016-09-08 21:13:10 +04:00
|
|
|
shutdown: unit -> unit Lwt.t ;
|
|
|
|
}
|
|
|
|
|
2018-05-31 15:19:36 +04:00
|
|
|
|
2018-05-15 15:16:08 +04:00
|
|
|
let peer_metadata_cfg : _ P2p.peer_meta_config = {
|
|
|
|
peer_meta_encoding = Peer_metadata.encoding ;
|
|
|
|
peer_meta_initial = () ;
|
|
|
|
score = fun _ -> 0. ;
|
|
|
|
}
|
|
|
|
|
2018-05-09 21:19:56 +04:00
|
|
|
let connection_metadata_cfg cfg : _ P2p.conn_meta_config = {
|
2018-06-01 19:10:54 +04:00
|
|
|
conn_meta_encoding = Connection_metadata.encoding ;
|
2018-05-31 15:19:36 +04:00
|
|
|
private_node = (fun { private_node } -> private_node) ;
|
2018-05-09 21:19:56 +04:00
|
|
|
conn_meta_value = fun _ -> cfg;
|
2018-05-15 15:16:08 +04:00
|
|
|
}
|
|
|
|
|
2018-05-31 15:19:36 +04:00
|
|
|
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 ->
|
2018-05-31 15:19:36 +04:00
|
|
|
let c_meta = init_connection_metadata None in
|
2018-06-12 23:07:50 +04:00
|
|
|
lwt_log_notice Tag.DSL.(fun f ->
|
|
|
|
f "P2P layer is disabled" -% t event "p2p_disabled") >>= fun () ->
|
2018-06-05 13:41:23 +04:00
|
|
|
return (P2p.faked_network peer_metadata_cfg c_meta)
|
2016-09-08 21:13:10 +04:00
|
|
|
| Some (config, limits) ->
|
2018-05-31 15:19:36 +04:00
|
|
|
let c_meta = init_connection_metadata (Some config) in
|
|
|
|
let conn_metadata_cfg = connection_metadata_cfg c_meta in
|
2018-06-12 23:07:50 +04:00
|
|
|
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
|
2017-02-24 20:17:53 +04:00
|
|
|
P2p.create
|
|
|
|
~config ~limits
|
2018-05-15 15:16:08 +04:00
|
|
|
peer_metadata_cfg
|
2018-05-09 21:19:56 +04:00
|
|
|
conn_metadata_cfg
|
2018-07-17 11:19:44 +04:00
|
|
|
message_cfg >>=? fun p2p ->
|
2017-02-24 20:17:53 +04:00
|
|
|
Lwt.async (fun () -> P2p.maintain p2p) ;
|
2018-06-05 13:41:23 +04:00
|
|
|
return p2p
|
2017-01-23 14:10:02 +04:00
|
|
|
|
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 ;
|
2018-06-02 15:54:16 +04:00
|
|
|
checkpoint: (Int32.t * Block_hash.t) option ;
|
2017-01-23 14:10:07 +04:00
|
|
|
}
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2018-01-22 20:47:18 +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
|
|
|
|
}
|
2017-11-13 17:25:02 +04:00
|
|
|
|
2017-11-29 16:51:06 +04:00
|
|
|
and prevalidator_limits = Prevalidator.limits = {
|
|
|
|
max_refused_operations: int ;
|
2017-11-30 21:34:22 +04:00
|
|
|
operation_timeout: float ;
|
|
|
|
worker_limits : Worker_types.limits ;
|
2017-11-29 16:51:06 +04:00
|
|
|
}
|
|
|
|
|
2018-01-26 16:10:20 +04:00
|
|
|
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 = {
|
2018-01-22 20:21:23 +04:00
|
|
|
bootstrap_threshold: int ;
|
|
|
|
worker_limits : Worker_types.limits ;
|
|
|
|
}
|
|
|
|
|
2018-04-22 02:27:04 +04:00
|
|
|
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. ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-02 15:54:16 +04:00
|
|
|
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 }
|
2018-01-22 20:47:18 +04:00
|
|
|
peer_validator_limits
|
2018-01-26 16:10:20 +04:00
|
|
|
block_validator_limits
|
2018-01-22 20:21:23 +04:00
|
|
|
prevalidator_limits
|
2018-02-16 04:26:24 +04:00
|
|
|
chain_validator_limits =
|
2018-05-17 13:55:22 +04:00
|
|
|
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
|
2018-04-16 02:44:22 +04:00
|
|
|
~store_root ~context_root ?patch_context genesis >>=? fun (state, mainchain_state) ->
|
2018-06-02 15:54:16 +04:00
|
|
|
may_update_checkpoint mainchain_state checkpoint >>= fun () ->
|
2018-06-05 13:41:23 +04:00
|
|
|
let distributed_db = Distributed_db.create state p2p in
|
2018-01-22 20:21:23 +04:00
|
|
|
Validator.create state distributed_db
|
2018-01-22 20:47:18 +04:00
|
|
|
peer_validator_limits
|
2018-01-22 20:21:23 +04:00
|
|
|
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
|
2018-05-17 13:55:22 +04:00
|
|
|
?max_child_ttl ~start_prevalidator mainchain_state >>= fun mainchain_validator ->
|
2016-09-08 21:13:10 +04:00
|
|
|
let shutdown () =
|
2017-02-24 20:17:53 +04:00
|
|
|
P2p.shutdown p2p >>= fun () ->
|
|
|
|
Validator.shutdown validator >>= fun () ->
|
2017-11-28 17:44:22 +04:00
|
|
|
State.close state >>= fun () ->
|
2017-02-24 20:17:53 +04:00
|
|
|
Lwt.return_unit
|
2016-09-08 21:13:10 +04:00
|
|
|
in
|
|
|
|
return {
|
|
|
|
state ;
|
2017-02-24 20:17:53 +04:00
|
|
|
distributed_db ;
|
2016-09-08 21:13:10 +04:00
|
|
|
validator ;
|
2018-02-16 04:26:24 +04:00
|
|
|
mainchain_validator ;
|
2017-02-17 22:12:06 +04:00
|
|
|
p2p ;
|
2016-09-08 21:13:10 +04:00
|
|
|
shutdown ;
|
|
|
|
}
|
|
|
|
|
|
|
|
let shutdown node = node.shutdown ()
|
|
|
|
|
2018-04-16 02:44:24 +04:00
|
|
|
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
|
|
|
|
|
2018-04-21 15:09:59 +04:00
|
|
|
merge (Protocol_directory.build_rpc_directory node.state) ;
|
2018-04-21 16:21:46 +04:00
|
|
|
merge (Monitor_directory.build_rpc_directory
|
2018-04-21 14:57:30 +04:00
|
|
|
node.validator node.mainchain_validator) ;
|
2018-04-21 16:21:46 +04:00
|
|
|
merge (Injection_directory.build_rpc_directory node.validator) ;
|
2018-04-21 14:57:30 +04:00
|
|
|
merge (Chain_directory.build_rpc_directory node.validator) ;
|
2018-04-16 02:44:24 +04:00
|
|
|
merge (P2p.build_rpc_directory node.p2p) ;
|
2018-04-21 17:28:10 +04:00
|
|
|
merge (Worker_directory.build_rpc_directory node.state) ;
|
2018-04-16 02:44:24 +04:00
|
|
|
|
|
|
|
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
|