Refactor: Move/split P2p_types
into lib_base
This commit is contained in:
parent
be9f068478
commit
7277c9889b
@ -111,15 +111,15 @@ test:p2p:io-scheduler:
|
|||||||
script:
|
script:
|
||||||
- jbuilder build @test/p2p/runtest_p2p_io_scheduler
|
- jbuilder build @test/p2p/runtest_p2p_io_scheduler
|
||||||
|
|
||||||
test:p2p:connection:
|
test:p2p:socket:
|
||||||
<<: *test_definition
|
<<: *test_definition
|
||||||
script:
|
script:
|
||||||
- jbuilder build @test/p2p/runtest_p2p_connection
|
- jbuilder build @test/p2p/runtest_p2p_socket
|
||||||
|
|
||||||
test:p2p:connection-pool:
|
test:p2p:pool:
|
||||||
<<: *test_definition
|
<<: *test_definition
|
||||||
script:
|
script:
|
||||||
- jbuilder build @test/p2p/runtest_p2p_connection_pool
|
- jbuilder build @test/p2p/runtest_p2p_pool
|
||||||
|
|
||||||
test:proto_alpha:transaction:
|
test:proto_alpha:transaction:
|
||||||
<<: *test_definition
|
<<: *test_definition
|
||||||
|
@ -103,7 +103,7 @@ let ballot_forged period prop vote =
|
|||||||
operations = [ballot] }) in
|
operations = [ballot] }) in
|
||||||
forge { net_id = network } op
|
forge { net_id = network } op
|
||||||
|
|
||||||
let identity = P2p_types.Identity.generate Crypto_box.default_target
|
let identity = P2p_identity.generate Crypto_box.default_target
|
||||||
|
|
||||||
(* connect to the network, run an action and then disconnect *)
|
(* connect to the network, run an action and then disconnect *)
|
||||||
let try_action addr port action =
|
let try_action addr port action =
|
||||||
|
@ -529,7 +529,7 @@ let update
|
|||||||
return { data_dir ; net ; rpc ; log ; shell }
|
return { data_dir ; net ; rpc ; log ; shell }
|
||||||
|
|
||||||
let resolve_addr ?default_port ?(passive = false) peer =
|
let resolve_addr ?default_port ?(passive = false) peer =
|
||||||
let addr, port = P2p.Point.parse_addr_port peer in
|
let addr, port = P2p_point.Id.parse_addr_port peer in
|
||||||
let node = if addr = "" || addr = "_" then "::" else addr
|
let node = if addr = "" || addr = "_" then "::" else addr
|
||||||
and service =
|
and service =
|
||||||
match port, default_port with
|
match port, default_port with
|
||||||
|
@ -80,8 +80,8 @@ val to_string: t -> string
|
|||||||
val read: string -> t tzresult Lwt.t
|
val read: string -> t tzresult Lwt.t
|
||||||
val write: string -> t -> unit tzresult Lwt.t
|
val write: string -> t -> unit tzresult Lwt.t
|
||||||
|
|
||||||
val resolve_listening_addrs: string -> (P2p_types.addr * int) list Lwt.t
|
val resolve_listening_addrs: string -> (P2p_addr.t * int) list Lwt.t
|
||||||
val resolve_rpc_listening_addrs: string -> (P2p_types.addr * int) list Lwt.t
|
val resolve_rpc_listening_addrs: string -> (P2p_addr.t * int) list Lwt.t
|
||||||
val resolve_bootstrap_addrs: string list -> (P2p_types.addr * int) list Lwt.t
|
val resolve_bootstrap_addrs: string list -> (P2p_addr.t * int) list Lwt.t
|
||||||
|
|
||||||
val check: t -> unit Lwt.t
|
val check: t -> unit Lwt.t
|
||||||
|
@ -15,7 +15,7 @@ let identity_file data_dir = data_dir // Node_data_version.default_identity_file
|
|||||||
|
|
||||||
let show { Node_config_file.data_dir } =
|
let show { Node_config_file.data_dir } =
|
||||||
Node_identity_file.read (identity_file data_dir) >>=? fun id ->
|
Node_identity_file.read (identity_file data_dir) >>=? fun id ->
|
||||||
Format.printf "Peer_id: %a.@." P2p_types.Peer_id.pp id.peer_id ;
|
Format.printf "Peer_id: %a.@." P2p_peer.Id.pp id.peer_id ;
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let generate { Node_config_file.data_dir ; net } =
|
let generate { Node_config_file.data_dir ; net } =
|
||||||
@ -26,11 +26,11 @@ let generate { Node_config_file.data_dir ; net } =
|
|||||||
let target = Crypto_box.make_target net.expected_pow in
|
let target = Crypto_box.make_target net.expected_pow in
|
||||||
Format.eprintf "Generating a new identity... (level: %.2f) " net.expected_pow ;
|
Format.eprintf "Generating a new identity... (level: %.2f) " net.expected_pow ;
|
||||||
let id =
|
let id =
|
||||||
P2p.Identity.generate_with_animation Format.err_formatter target in
|
P2p_identity.generate_with_animation Format.err_formatter target in
|
||||||
Node_identity_file.write identity_file id >>=? fun () ->
|
Node_identity_file.write identity_file id >>=? fun () ->
|
||||||
Format.eprintf
|
Format.eprintf
|
||||||
"Stored the new identity (%a) into '%s'.@."
|
"Stored the new identity (%a) into '%s'.@."
|
||||||
P2p.Peer_id.pp id.peer_id identity_file ;
|
P2p_peer.Id.pp id.peer_id identity_file ;
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let check { Node_config_file.data_dir ; net = { expected_pow } } =
|
let check { Node_config_file.data_dir ; net = { expected_pow } } =
|
||||||
@ -38,7 +38,7 @@ let check { Node_config_file.data_dir ; net = { expected_pow } } =
|
|||||||
~expected_pow (identity_file data_dir) >>=? fun id ->
|
~expected_pow (identity_file data_dir) >>=? fun id ->
|
||||||
Format.printf
|
Format.printf
|
||||||
"Peer_id: %a. Proof of work is higher than %.2f.@."
|
"Peer_id: %a. Proof of work is higher than %.2f.@."
|
||||||
P2p_types.Peer_id.pp id.peer_id expected_pow ;
|
P2p_peer.Id.pp id.peer_id expected_pow ;
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
(** Main *)
|
(** Main *)
|
||||||
|
@ -47,7 +47,7 @@ let read ?expected_pow file =
|
|||||||
fail (No_identity_file file)
|
fail (No_identity_file file)
|
||||||
| true ->
|
| true ->
|
||||||
Data_encoding_ezjsonm.read_file file >>=? fun json ->
|
Data_encoding_ezjsonm.read_file file >>=? fun json ->
|
||||||
let id = Data_encoding.Json.destruct P2p.Identity.encoding json in
|
let id = Data_encoding.Json.destruct P2p_identity.encoding json in
|
||||||
match expected_pow with
|
match expected_pow with
|
||||||
| None -> return id
|
| None -> return id
|
||||||
| Some expected ->
|
| Some expected ->
|
||||||
@ -81,4 +81,4 @@ let write file identity =
|
|||||||
else
|
else
|
||||||
Node_data_version.ensure_data_dir (Filename.dirname file) >>=? fun () ->
|
Node_data_version.ensure_data_dir (Filename.dirname file) >>=? fun () ->
|
||||||
Data_encoding_ezjsonm.write_file file
|
Data_encoding_ezjsonm.write_file file
|
||||||
(Data_encoding.Json.construct P2p.Identity.encoding identity)
|
(Data_encoding.Json.construct P2p_identity.encoding identity)
|
||||||
|
@ -12,8 +12,8 @@ type error += Insufficient_proof_of_work of { expected: float }
|
|||||||
|
|
||||||
val read:
|
val read:
|
||||||
?expected_pow:float ->
|
?expected_pow:float ->
|
||||||
string -> P2p.Identity.t tzresult Lwt.t
|
string -> P2p_identity.t tzresult Lwt.t
|
||||||
|
|
||||||
type error += Existent_identity_file of string
|
type error += Existent_identity_file of string
|
||||||
|
|
||||||
val write: string -> P2p.Identity.t -> unit tzresult Lwt.t
|
val write: string -> P2p_identity.t -> unit tzresult Lwt.t
|
||||||
|
@ -20,8 +20,8 @@ let genesis : State.Net.genesis = {
|
|||||||
"ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im" ;
|
"ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
type error += Non_private_sandbox of P2p_types.addr
|
type error += Non_private_sandbox of P2p_addr.t
|
||||||
type error += RPC_Port_already_in_use of P2p_types.addr
|
type error += RPC_Port_already_in_use of P2p_addr.t
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
register_error_kind
|
register_error_kind
|
||||||
@ -36,7 +36,7 @@ let () =
|
|||||||
See `%s run --help` on how to change the listening address."
|
See `%s run --help` on how to change the listening address."
|
||||||
Ipaddr.V6.pp_hum addr Sys.argv.(0)
|
Ipaddr.V6.pp_hum addr Sys.argv.(0)
|
||||||
end
|
end
|
||||||
Data_encoding.(obj1 (req "addr" P2p_types.addr_encoding))
|
Data_encoding.(obj1 (req "addr" P2p_addr.encoding))
|
||||||
(function Non_private_sandbox addr -> Some addr | _ -> None)
|
(function Non_private_sandbox addr -> Some addr | _ -> None)
|
||||||
(fun addr -> Non_private_sandbox addr);
|
(fun addr -> Non_private_sandbox addr);
|
||||||
register_error_kind
|
register_error_kind
|
||||||
@ -50,7 +50,7 @@ let () =
|
|||||||
Please choose another RPC port."
|
Please choose another RPC port."
|
||||||
Ipaddr.V6.pp_hum addr
|
Ipaddr.V6.pp_hum addr
|
||||||
end
|
end
|
||||||
Data_encoding.(obj1 (req "addr" P2p_types.addr_encoding))
|
Data_encoding.(obj1 (req "addr" P2p_addr.encoding))
|
||||||
(function RPC_Port_already_in_use addr -> Some addr | _ -> None)
|
(function RPC_Port_already_in_use addr -> Some addr | _ -> None)
|
||||||
(fun addr -> RPC_Port_already_in_use addr)
|
(fun addr -> RPC_Port_already_in_use addr)
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ let init_node ?sandbox (config : Node_config_file.t) =
|
|||||||
Node_data_version.default_identity_file_name) >>=? fun identity ->
|
Node_data_version.default_identity_file_name) >>=? fun identity ->
|
||||||
lwt_log_notice
|
lwt_log_notice
|
||||||
"Peer's global id: %a"
|
"Peer's global id: %a"
|
||||||
P2p.Peer_id.pp identity.peer_id >>= fun () ->
|
P2p_peer.Id.pp identity.peer_id >>= fun () ->
|
||||||
let p2p_config : P2p.config =
|
let p2p_config : P2p.config =
|
||||||
{ listening_addr ;
|
{ listening_addr ;
|
||||||
listening_port ;
|
listening_port ;
|
||||||
|
28
src/lib_base/p2p_addr.ml
Normal file
28
src/lib_base/p2p_addr.ml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type t = Ipaddr.V6.t
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
splitted
|
||||||
|
~json:begin
|
||||||
|
conv
|
||||||
|
Ipaddr.V6.to_string
|
||||||
|
Ipaddr.V6.of_string_exn
|
||||||
|
string
|
||||||
|
end
|
||||||
|
~binary:begin
|
||||||
|
conv
|
||||||
|
Ipaddr.V6.to_bytes
|
||||||
|
Ipaddr.V6.of_bytes_exn
|
||||||
|
string
|
||||||
|
end
|
||||||
|
|
||||||
|
type port = int
|
13
src/lib_base/p2p_addr.mli
Normal file
13
src/lib_base/p2p_addr.mli
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type t = Ipaddr.V6.t
|
||||||
|
type port = int
|
||||||
|
|
||||||
|
val encoding : t Data_encoding.t
|
252
src/lib_base/p2p_connection.ml
Normal file
252
src/lib_base/p2p_connection.ml
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type peer_id = Crypto_box.Public_key_hash.t
|
||||||
|
let peer_id_encoding = Crypto_box.Public_key_hash.encoding
|
||||||
|
let peer_id_pp = Crypto_box.Public_key_hash.pp
|
||||||
|
|
||||||
|
module Id = struct
|
||||||
|
|
||||||
|
(* A net point (address x port). *)
|
||||||
|
type t = P2p_addr.t * P2p_addr.port option
|
||||||
|
let compare (a1, p1) (a2, p2) =
|
||||||
|
match Ipaddr.V6.compare a1 a2 with
|
||||||
|
| 0 -> Pervasives.compare p1 p2
|
||||||
|
| x -> x
|
||||||
|
let equal p1 p2 = compare p1 p2 = 0
|
||||||
|
let hash = Hashtbl.hash
|
||||||
|
let pp ppf (addr, port) =
|
||||||
|
match port with
|
||||||
|
| None ->
|
||||||
|
Format.fprintf ppf "[%a]:??" Ipaddr.V6.pp_hum addr
|
||||||
|
| Some port ->
|
||||||
|
Format.fprintf ppf "[%a]:%d" Ipaddr.V6.pp_hum addr port
|
||||||
|
let pp_opt ppf = function
|
||||||
|
| None -> Format.pp_print_string ppf "none"
|
||||||
|
| Some point -> pp ppf point
|
||||||
|
let to_string t = Format.asprintf "%a" pp t
|
||||||
|
|
||||||
|
let is_local (addr, _) = Ipaddr.V6.is_private addr
|
||||||
|
let is_global (addr, _) = not @@ Ipaddr.V6.is_private addr
|
||||||
|
|
||||||
|
let of_point (addr, port) = addr, Some port
|
||||||
|
let to_point = function
|
||||||
|
| _, None -> None
|
||||||
|
| addr, Some port -> Some (addr, port)
|
||||||
|
let to_point_exn = function
|
||||||
|
| _, None -> invalid_arg "to_point_exn"
|
||||||
|
| addr, Some port -> addr, port
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
(obj2
|
||||||
|
(req "addr" P2p_addr.encoding)
|
||||||
|
(opt "port" uint16))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Map = Map.Make (Id)
|
||||||
|
module Set = Set.Make (Id)
|
||||||
|
module Table = Hashtbl.Make (Id)
|
||||||
|
|
||||||
|
module Info = struct
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
incoming : bool;
|
||||||
|
peer_id : peer_id;
|
||||||
|
id_point : Id.t;
|
||||||
|
remote_socket_port : P2p_addr.port;
|
||||||
|
versions : P2p_version.t list ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { incoming ; peer_id ; id_point ; remote_socket_port ; versions } ->
|
||||||
|
(incoming, peer_id, id_point, remote_socket_port, versions))
|
||||||
|
(fun (incoming, peer_id, id_point, remote_socket_port, versions) ->
|
||||||
|
{ incoming ; peer_id ; id_point ; remote_socket_port ; versions })
|
||||||
|
(obj5
|
||||||
|
(req "incoming" bool)
|
||||||
|
(req "peer_id" peer_id_encoding)
|
||||||
|
(req "id_point" Id.encoding)
|
||||||
|
(req "remote_socket_port" uint16)
|
||||||
|
(req "versions" (list P2p_version.encoding)))
|
||||||
|
|
||||||
|
let pp ppf
|
||||||
|
{ incoming ; id_point = (remote_addr, remote_port) ;
|
||||||
|
remote_socket_port ; peer_id ; versions } =
|
||||||
|
let version = List.hd versions in
|
||||||
|
let point = match remote_port with
|
||||||
|
| None -> remote_addr, remote_socket_port
|
||||||
|
| Some port -> remote_addr, port in
|
||||||
|
Format.fprintf ppf "%s %a %a (%a)"
|
||||||
|
(if incoming then "↘" else "↗")
|
||||||
|
peer_id_pp peer_id
|
||||||
|
P2p_point.Id.pp point
|
||||||
|
P2p_version.pp version
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_event = struct
|
||||||
|
|
||||||
|
(** Pool-level events *)
|
||||||
|
|
||||||
|
type t =
|
||||||
|
|
||||||
|
| Too_few_connections
|
||||||
|
| Too_many_connections
|
||||||
|
|
||||||
|
| New_point of P2p_point.Id.t
|
||||||
|
| New_peer of peer_id
|
||||||
|
|
||||||
|
| Gc_points
|
||||||
|
| Gc_peer_ids
|
||||||
|
|
||||||
|
| Incoming_connection of P2p_point.Id.t
|
||||||
|
| Outgoing_connection of P2p_point.Id.t
|
||||||
|
| Authentication_failed of P2p_point.Id.t
|
||||||
|
| Accepting_request of P2p_point.Id.t * Id.t * peer_id
|
||||||
|
| Rejecting_request of P2p_point.Id.t * Id.t * peer_id
|
||||||
|
| Request_rejected of P2p_point.Id.t * (Id.t * peer_id) option
|
||||||
|
| Connection_established of Id.t * peer_id
|
||||||
|
|
||||||
|
| Swap_request_received of { source : peer_id }
|
||||||
|
| Swap_ack_received of { source : peer_id }
|
||||||
|
| Swap_request_sent of { source : peer_id }
|
||||||
|
| Swap_ack_sent of { source : peer_id }
|
||||||
|
| Swap_request_ignored of { source : peer_id }
|
||||||
|
| Swap_success of { source : peer_id }
|
||||||
|
| Swap_failure of { source : peer_id }
|
||||||
|
|
||||||
|
| Disconnection of peer_id
|
||||||
|
| External_disconnection of peer_id
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
let branch_encoding name obj =
|
||||||
|
conv (fun x -> (), x) (fun ((), x) -> x)
|
||||||
|
(merge_objs
|
||||||
|
(obj1 (req "event" (constant name))) obj) in
|
||||||
|
union ~tag_size:`Uint8 [
|
||||||
|
case (Tag 0) (branch_encoding "too_few_connections" empty)
|
||||||
|
(function Too_few_connections -> Some () | _ -> None)
|
||||||
|
(fun () -> Too_few_connections) ;
|
||||||
|
case (Tag 1) (branch_encoding "too_many_connections" empty)
|
||||||
|
(function Too_many_connections -> Some () | _ -> None)
|
||||||
|
(fun () -> Too_many_connections) ;
|
||||||
|
case (Tag 2) (branch_encoding "new_point"
|
||||||
|
(obj1 (req "point" P2p_point.Id.encoding)))
|
||||||
|
(function New_point p -> Some p | _ -> None)
|
||||||
|
(fun p -> New_point p) ;
|
||||||
|
case (Tag 3) (branch_encoding "new_peer"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function New_peer p -> Some p | _ -> None)
|
||||||
|
(fun p -> New_peer p) ;
|
||||||
|
case (Tag 4) (branch_encoding "incoming_connection"
|
||||||
|
(obj1 (req "point" P2p_point.Id.encoding)))
|
||||||
|
(function Incoming_connection p -> Some p | _ -> None)
|
||||||
|
(fun p -> Incoming_connection p) ;
|
||||||
|
case (Tag 5) (branch_encoding "outgoing_connection"
|
||||||
|
(obj1 (req "point" P2p_point.Id.encoding)))
|
||||||
|
(function Outgoing_connection p -> Some p | _ -> None)
|
||||||
|
(fun p -> Outgoing_connection p) ;
|
||||||
|
case (Tag 6) (branch_encoding "authentication_failed"
|
||||||
|
(obj1 (req "point" P2p_point.Id.encoding)))
|
||||||
|
(function Authentication_failed p -> Some p | _ -> None)
|
||||||
|
(fun p -> Authentication_failed p) ;
|
||||||
|
case (Tag 7) (branch_encoding "accepting_request"
|
||||||
|
(obj3
|
||||||
|
(req "point" P2p_point.Id.encoding)
|
||||||
|
(req "id_point" Id.encoding)
|
||||||
|
(req "peer_id" peer_id_encoding)))
|
||||||
|
(function Accepting_request (p, id_p, g) ->
|
||||||
|
Some (p, id_p, g) | _ -> None)
|
||||||
|
(fun (p, id_p, g) -> Accepting_request (p, id_p, g)) ;
|
||||||
|
case (Tag 8) (branch_encoding "rejecting_request"
|
||||||
|
(obj3
|
||||||
|
(req "point" P2p_point.Id.encoding)
|
||||||
|
(req "id_point" Id.encoding)
|
||||||
|
(req "peer_id" peer_id_encoding)))
|
||||||
|
(function Rejecting_request (p, id_p, g) ->
|
||||||
|
Some (p, id_p, g) | _ -> None)
|
||||||
|
(fun (p, id_p, g) -> Rejecting_request (p, id_p, g)) ;
|
||||||
|
case (Tag 9) (branch_encoding "request_rejected"
|
||||||
|
(obj2
|
||||||
|
(req "point" P2p_point.Id.encoding)
|
||||||
|
(opt "identity"
|
||||||
|
(tup2 Id.encoding peer_id_encoding))))
|
||||||
|
(function Request_rejected (p, id) -> Some (p, id) | _ -> None)
|
||||||
|
(fun (p, id) -> Request_rejected (p, id)) ;
|
||||||
|
case (Tag 10) (branch_encoding "connection_established"
|
||||||
|
(obj2
|
||||||
|
(req "id_point" Id.encoding)
|
||||||
|
(req "peer_id" peer_id_encoding)))
|
||||||
|
(function Connection_established (id_p, g) ->
|
||||||
|
Some (id_p, g) | _ -> None)
|
||||||
|
(fun (id_p, g) -> Connection_established (id_p, g)) ;
|
||||||
|
case (Tag 11) (branch_encoding "disconnection"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function Disconnection g -> Some g | _ -> None)
|
||||||
|
(fun g -> Disconnection g) ;
|
||||||
|
case (Tag 12) (branch_encoding "external_disconnection"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function External_disconnection g -> Some g | _ -> None)
|
||||||
|
(fun g -> External_disconnection g) ;
|
||||||
|
case (Tag 13) (branch_encoding "gc_points" empty)
|
||||||
|
(function Gc_points -> Some () | _ -> None)
|
||||||
|
(fun () -> Gc_points) ;
|
||||||
|
case (Tag 14) (branch_encoding "gc_peer_ids" empty)
|
||||||
|
(function Gc_peer_ids -> Some () | _ -> None)
|
||||||
|
(fun () -> Gc_peer_ids) ;
|
||||||
|
case (Tag 15) (branch_encoding "swap_request_received"
|
||||||
|
(obj1 (req "source" peer_id_encoding)))
|
||||||
|
(function
|
||||||
|
| Swap_request_received { source } -> Some source
|
||||||
|
| _ -> None)
|
||||||
|
(fun source -> Swap_request_received { source }) ;
|
||||||
|
case (Tag 16) (branch_encoding "swap_ack_received"
|
||||||
|
(obj1 (req "source" peer_id_encoding)))
|
||||||
|
(function
|
||||||
|
| Swap_ack_received { source } -> Some source
|
||||||
|
| _ -> None)
|
||||||
|
(fun source -> Swap_ack_received { source }) ;
|
||||||
|
case (Tag 17) (branch_encoding "swap_request_sent"
|
||||||
|
(obj1 (req "source" peer_id_encoding)))
|
||||||
|
(function
|
||||||
|
| Swap_request_sent { source } -> Some source
|
||||||
|
| _ -> None)
|
||||||
|
(fun source -> Swap_request_sent { source }) ;
|
||||||
|
case (Tag 18) (branch_encoding "swap_ack_sent"
|
||||||
|
(obj1 (req "source" peer_id_encoding)))
|
||||||
|
(function
|
||||||
|
| Swap_ack_sent { source } -> Some source
|
||||||
|
| _ -> None)
|
||||||
|
(fun source -> Swap_ack_sent { source }) ;
|
||||||
|
case (Tag 19) (branch_encoding "swap_request_ignored"
|
||||||
|
(obj1 (req "source" peer_id_encoding)))
|
||||||
|
(function
|
||||||
|
| Swap_request_ignored { source } -> Some source
|
||||||
|
| _ -> None)
|
||||||
|
(fun source -> Swap_request_ignored { source }) ;
|
||||||
|
case (Tag 20) (branch_encoding "swap_success"
|
||||||
|
(obj1 (req "source" peer_id_encoding)))
|
||||||
|
(function
|
||||||
|
| Swap_success { source } -> Some source
|
||||||
|
| _ -> None)
|
||||||
|
(fun source -> Swap_success { source }) ;
|
||||||
|
case (Tag 21) (branch_encoding "swap_failure"
|
||||||
|
(obj1 (req "source" peer_id_encoding)))
|
||||||
|
(function
|
||||||
|
| Swap_failure { source } -> Some source
|
||||||
|
| _ -> None)
|
||||||
|
(fun source -> Swap_failure { source }) ;
|
||||||
|
]
|
||||||
|
|
||||||
|
end
|
107
src/lib_base/p2p_connection.mli
Normal file
107
src/lib_base/p2p_connection.mli
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type peer_id = Crypto_box.Public_key_hash.t
|
||||||
|
(* = P2p_peer.Id.t, but we should break cycles *)
|
||||||
|
|
||||||
|
module Id : sig
|
||||||
|
|
||||||
|
type t = P2p_addr.t * P2p_addr.port option
|
||||||
|
val compare : t -> t -> int
|
||||||
|
val equal : t -> t -> bool
|
||||||
|
val pp : Format.formatter -> t -> unit
|
||||||
|
val pp_opt : Format.formatter -> t option -> unit
|
||||||
|
val to_string : t -> string
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
val is_local : t -> bool
|
||||||
|
val is_global : t -> bool
|
||||||
|
val of_point : P2p_point.Id.t -> t
|
||||||
|
val to_point : t -> P2p_point.Id.t option
|
||||||
|
val to_point_exn : t -> P2p_point.Id.t
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Map : Map.S with type key = Id.t
|
||||||
|
module Set : Set.S with type elt = Id.t
|
||||||
|
module Table : Hashtbl.S with type key = Id.t
|
||||||
|
|
||||||
|
(** Information about a connection *)
|
||||||
|
module Info : sig
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
incoming : bool;
|
||||||
|
peer_id : peer_id;
|
||||||
|
id_point : Id.t;
|
||||||
|
remote_socket_port : P2p_addr.port;
|
||||||
|
versions : P2p_version.t list ;
|
||||||
|
}
|
||||||
|
|
||||||
|
val pp : Format.formatter -> t -> unit
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_event : sig
|
||||||
|
|
||||||
|
type t =
|
||||||
|
|
||||||
|
| Too_few_connections
|
||||||
|
| Too_many_connections
|
||||||
|
|
||||||
|
| New_point of P2p_point.Id.t
|
||||||
|
| New_peer of peer_id
|
||||||
|
|
||||||
|
| Gc_points
|
||||||
|
(** Garbage collection of known point table has been triggered. *)
|
||||||
|
|
||||||
|
| Gc_peer_ids
|
||||||
|
(** Garbage collection of known peer_ids table has been triggered. *)
|
||||||
|
|
||||||
|
(* Connection-level events *)
|
||||||
|
|
||||||
|
| Incoming_connection of P2p_point.Id.t
|
||||||
|
(** We accept(2)-ed an incoming connection *)
|
||||||
|
| Outgoing_connection of P2p_point.Id.t
|
||||||
|
(** We connect(2)-ed to a remote endpoint *)
|
||||||
|
| Authentication_failed of P2p_point.Id.t
|
||||||
|
(** Remote point failed authentication *)
|
||||||
|
|
||||||
|
| Accepting_request of P2p_point.Id.t * Id.t * peer_id
|
||||||
|
(** We accepted a connection after authentifying the remote peer. *)
|
||||||
|
| Rejecting_request of P2p_point.Id.t * Id.t * peer_id
|
||||||
|
(** We rejected a connection after authentifying the remote peer. *)
|
||||||
|
| Request_rejected of P2p_point.Id.t * (Id.t * peer_id) option
|
||||||
|
(** The remote peer rejected our connection. *)
|
||||||
|
|
||||||
|
| Connection_established of Id.t * peer_id
|
||||||
|
(** We succesfully established a authentified connection. *)
|
||||||
|
|
||||||
|
| Swap_request_received of { source : peer_id }
|
||||||
|
(** A swap request has been received. *)
|
||||||
|
| Swap_ack_received of { source : peer_id }
|
||||||
|
(** A swap ack has been received *)
|
||||||
|
| Swap_request_sent of { source : peer_id }
|
||||||
|
(** A swap request has been sent *)
|
||||||
|
| Swap_ack_sent of { source : peer_id }
|
||||||
|
(** A swap ack has been sent *)
|
||||||
|
| Swap_request_ignored of { source : peer_id }
|
||||||
|
(** A swap request has been ignored *)
|
||||||
|
| Swap_success of { source : peer_id }
|
||||||
|
(** A swap operation has succeeded *)
|
||||||
|
| Swap_failure of { source : peer_id }
|
||||||
|
(** A swap operation has failed *)
|
||||||
|
|
||||||
|
| Disconnection of peer_id
|
||||||
|
(** We decided to close the connection. *)
|
||||||
|
| External_disconnection of peer_id
|
||||||
|
(** The connection was closed for external reason. *)
|
||||||
|
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
|
||||||
|
end
|
9
src/lib_base/p2p_connection_id.ml
Normal file
9
src/lib_base/p2p_connection_id.ml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
11
src/lib_base/p2p_connection_id.mli
Normal file
11
src/lib_base/p2p_connection_id.mli
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
(** P2p_point representing a reachable socket address *)
|
||||||
|
|
0
src/lib_base/p2p_id_point.ml
Normal file
0
src/lib_base/p2p_id_point.ml
Normal file
9
src/lib_base/p2p_id_point.mli
Normal file
9
src/lib_base/p2p_id_point.mli
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
77
src/lib_base/p2p_identity.ml
Normal file
77
src/lib_base/p2p_identity.ml
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
peer_id : P2p_peer.Id.t ;
|
||||||
|
public_key : Crypto_box.public_key ;
|
||||||
|
secret_key : Crypto_box.secret_key ;
|
||||||
|
proof_of_work_stamp : Crypto_box.nonce ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { public_key ; secret_key ; proof_of_work_stamp ; _ } ->
|
||||||
|
(public_key, secret_key, proof_of_work_stamp))
|
||||||
|
(fun (public_key, secret_key, proof_of_work_stamp) ->
|
||||||
|
let peer_id = Tezos_crypto.Crypto_box.hash public_key in
|
||||||
|
{ peer_id ; public_key ; secret_key ; proof_of_work_stamp })
|
||||||
|
(obj3
|
||||||
|
(req "public_key" Crypto_box.public_key_encoding)
|
||||||
|
(req "secret_key" Crypto_box.secret_key_encoding)
|
||||||
|
(req "proof_of_work_stamp" Crypto_box.nonce_encoding))
|
||||||
|
|
||||||
|
let generate ?max target =
|
||||||
|
let secret_key, public_key, peer_id = Crypto_box.random_keypair () in
|
||||||
|
let proof_of_work_stamp =
|
||||||
|
Crypto_box.generate_proof_of_work ?max public_key target in
|
||||||
|
{ peer_id ; public_key ; secret_key ; proof_of_work_stamp }
|
||||||
|
|
||||||
|
let animation = [|
|
||||||
|
"|.....|" ;
|
||||||
|
"|o....|" ;
|
||||||
|
"|oo...|" ;
|
||||||
|
"|ooo..|" ;
|
||||||
|
"|.ooo.|" ;
|
||||||
|
"|..ooo|" ;
|
||||||
|
"|...oo|" ;
|
||||||
|
"|....o|" ;
|
||||||
|
"|.....|" ;
|
||||||
|
"|.....|" ;
|
||||||
|
"|.....|" ;
|
||||||
|
"|.....|" ;
|
||||||
|
|]
|
||||||
|
|
||||||
|
let init = String.make (String.length animation.(0)) '\ '
|
||||||
|
let clean = String.make (String.length animation.(0)) '\b'
|
||||||
|
let animation = Array.map (fun x -> clean ^ x) animation
|
||||||
|
let animation_size = Array.length animation
|
||||||
|
let duration = 1200 / animation_size
|
||||||
|
|
||||||
|
let generate_with_animation ppf target =
|
||||||
|
Format.fprintf ppf "%s%!" init ;
|
||||||
|
let count = ref 10000 in
|
||||||
|
let rec loop n =
|
||||||
|
let start = Mtime_clock.counter () in
|
||||||
|
Format.fprintf ppf "%s%!" animation.(n mod animation_size);
|
||||||
|
try generate ~max:!count target
|
||||||
|
with Not_found ->
|
||||||
|
let time = Mtime.Span.to_ms (Mtime_clock.count start) in
|
||||||
|
count :=
|
||||||
|
if time <= 0. then
|
||||||
|
!count * 10
|
||||||
|
else
|
||||||
|
!count * duration / int_of_float time ;
|
||||||
|
loop (n+1)
|
||||||
|
in
|
||||||
|
let id = loop 0 in
|
||||||
|
Format.fprintf ppf "%s%s\n%!" clean init ;
|
||||||
|
id
|
||||||
|
|
||||||
|
let generate target = generate target
|
29
src/lib_base/p2p_identity.mli
Normal file
29
src/lib_base/p2p_identity.mli
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
peer_id : P2p_peer.Id.t ;
|
||||||
|
public_key : Crypto_box.public_key ;
|
||||||
|
secret_key : Crypto_box.secret_key ;
|
||||||
|
proof_of_work_stamp : Crypto_box.nonce ;
|
||||||
|
}
|
||||||
|
(** Type of an identity, comprising a peer_id, a crypto keypair, and a
|
||||||
|
proof of work stamp with enough difficulty so that the network
|
||||||
|
accept this identity as genuine. *)
|
||||||
|
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
|
||||||
|
val generate : Crypto_box.target -> t
|
||||||
|
(** [generate target] is a freshly minted identity whose proof of
|
||||||
|
work stamp difficulty is at least equal to [target]. *)
|
||||||
|
|
||||||
|
val generate_with_animation :
|
||||||
|
Format.formatter -> Crypto_box.target -> t
|
||||||
|
(** [generate_with_animation ppf target] is a freshly minted identity
|
||||||
|
whose proof of work stamp difficulty is at least equal to [target]. *)
|
339
src/lib_base/p2p_peer.ml
Normal file
339
src/lib_base/p2p_peer.ml
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
open Error_monad
|
||||||
|
|
||||||
|
module Id = Tezos_crypto.Crypto_box.Public_key_hash
|
||||||
|
|
||||||
|
module Table = Id.Table
|
||||||
|
module Map = Id.Map
|
||||||
|
module Set = Id.Set
|
||||||
|
|
||||||
|
module State = struct
|
||||||
|
|
||||||
|
type t =
|
||||||
|
| Accepted
|
||||||
|
| Running
|
||||||
|
| Disconnected
|
||||||
|
|
||||||
|
let pp_digram ppf = function
|
||||||
|
| Accepted -> Format.fprintf ppf "⚎"
|
||||||
|
| Running -> Format.fprintf ppf "⚌"
|
||||||
|
| Disconnected -> Format.fprintf ppf "⚏"
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
string_enum [
|
||||||
|
"accepted", Accepted ;
|
||||||
|
"running", Running ;
|
||||||
|
"disconnected", Disconnected ;
|
||||||
|
]
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Info = struct
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
score : float ;
|
||||||
|
trusted : bool ;
|
||||||
|
state : State.t ;
|
||||||
|
id_point : P2p_connection.Id.t option ;
|
||||||
|
stat : P2p_stat.t ;
|
||||||
|
last_failed_connection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_rejected_connection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_established_connection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_disconnection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_seen : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_miss : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun (
|
||||||
|
{ score ; trusted ; state ; id_point ; stat ;
|
||||||
|
last_failed_connection ; last_rejected_connection ;
|
||||||
|
last_established_connection ; last_disconnection ;
|
||||||
|
last_seen ; last_miss }) ->
|
||||||
|
((score, trusted, state, id_point, stat),
|
||||||
|
(last_failed_connection, last_rejected_connection,
|
||||||
|
last_established_connection, last_disconnection,
|
||||||
|
last_seen, last_miss)))
|
||||||
|
(fun ((score, trusted, state, id_point, stat),
|
||||||
|
(last_failed_connection, last_rejected_connection,
|
||||||
|
last_established_connection, last_disconnection,
|
||||||
|
last_seen, last_miss)) ->
|
||||||
|
{ score ; trusted ; state ; id_point ; stat ;
|
||||||
|
last_failed_connection ; last_rejected_connection ;
|
||||||
|
last_established_connection ; last_disconnection ;
|
||||||
|
last_seen ; last_miss })
|
||||||
|
(merge_objs
|
||||||
|
(obj5
|
||||||
|
(req "score" float)
|
||||||
|
(req "trusted" bool)
|
||||||
|
(req "state" State.encoding)
|
||||||
|
(opt "reachable_at" P2p_connection.Id.encoding)
|
||||||
|
(req "stat" P2p_stat.encoding))
|
||||||
|
(obj6
|
||||||
|
(opt "last_failed_connection" (tup2 P2p_connection.Id.encoding Time.encoding))
|
||||||
|
(opt "last_rejected_connection" (tup2 P2p_connection.Id.encoding Time.encoding))
|
||||||
|
(opt "last_established_connection" (tup2 P2p_connection.Id.encoding Time.encoding))
|
||||||
|
(opt "last_disconnection" (tup2 P2p_connection.Id.encoding Time.encoding))
|
||||||
|
(opt "last_seen" (tup2 P2p_connection.Id.encoding Time.encoding))
|
||||||
|
(opt "last_miss" (tup2 P2p_connection.Id.encoding Time.encoding))))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Event = struct
|
||||||
|
|
||||||
|
type kind =
|
||||||
|
| Accepting_request
|
||||||
|
| Rejecting_request
|
||||||
|
| Request_rejected
|
||||||
|
| Connection_established
|
||||||
|
| Disconnection
|
||||||
|
| External_disconnection
|
||||||
|
|
||||||
|
let kind_encoding =
|
||||||
|
Data_encoding.string_enum [
|
||||||
|
"incoming_request", Accepting_request ;
|
||||||
|
"rejecting_request", Rejecting_request ;
|
||||||
|
"request_rejected", Request_rejected ;
|
||||||
|
"connection_established", Connection_established ;
|
||||||
|
"disconnection", Disconnection ;
|
||||||
|
"external_disconnection", External_disconnection ;
|
||||||
|
]
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
kind : kind ;
|
||||||
|
timestamp : Time.t ;
|
||||||
|
point : P2p_connection.Id.t ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { kind ; timestamp ; point = (addr, port) } ->
|
||||||
|
(kind, timestamp, addr, port))
|
||||||
|
(fun (kind, timestamp, addr, port) ->
|
||||||
|
{ kind ; timestamp ; point = (addr, port) })
|
||||||
|
(obj4
|
||||||
|
(req "kind" kind_encoding)
|
||||||
|
(req "timestamp" Time.encoding)
|
||||||
|
(req "addr" P2p_addr.encoding)
|
||||||
|
(opt "port" int16))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_info = struct
|
||||||
|
|
||||||
|
type 'data state =
|
||||||
|
| Accepted of { current_point: P2p_connection.Id.t ;
|
||||||
|
cancel: Lwt_canceler.t }
|
||||||
|
| Running of { data: 'data ;
|
||||||
|
current_point: P2p_connection.Id.t }
|
||||||
|
| Disconnected
|
||||||
|
|
||||||
|
type ('conn, 'meta) t = {
|
||||||
|
peer_id : Id.t ;
|
||||||
|
created : Time.t ;
|
||||||
|
mutable state : 'conn state ;
|
||||||
|
mutable metadata : 'meta ;
|
||||||
|
mutable trusted : bool ;
|
||||||
|
mutable last_failed_connection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
mutable last_rejected_connection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
mutable last_established_connection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
mutable last_disconnection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
events : Event.t Ring.t ;
|
||||||
|
watchers : Event.t Lwt_watcher.input ;
|
||||||
|
}
|
||||||
|
type ('conn, 'meta) peer_info = ('conn, 'meta) t
|
||||||
|
|
||||||
|
let compare gi1 gi2 = Id.compare gi1.peer_id gi2.peer_id
|
||||||
|
|
||||||
|
let log_size = 100
|
||||||
|
|
||||||
|
let create ?(created = Time.now ()) ?(trusted = false) ~metadata peer_id =
|
||||||
|
{ peer_id ;
|
||||||
|
created ;
|
||||||
|
state = Disconnected ;
|
||||||
|
metadata ;
|
||||||
|
trusted ;
|
||||||
|
last_failed_connection = None ;
|
||||||
|
last_rejected_connection = None ;
|
||||||
|
last_established_connection = None ;
|
||||||
|
last_disconnection = None ;
|
||||||
|
events = Ring.create log_size ;
|
||||||
|
watchers = Lwt_watcher.create_input () ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoding metadata_encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { peer_id ; trusted ; metadata ; events ; created ;
|
||||||
|
last_failed_connection ; last_rejected_connection ;
|
||||||
|
last_established_connection ; last_disconnection ; _ } ->
|
||||||
|
(peer_id, created, trusted, metadata, Ring.elements events,
|
||||||
|
last_failed_connection, last_rejected_connection,
|
||||||
|
last_established_connection, last_disconnection))
|
||||||
|
(fun (peer_id, created, trusted, metadata, event_list,
|
||||||
|
last_failed_connection, last_rejected_connection,
|
||||||
|
last_established_connection, last_disconnection) ->
|
||||||
|
let info = create ~trusted ~metadata peer_id in
|
||||||
|
let events = Ring.create log_size in
|
||||||
|
Ring.add_list info.events event_list ;
|
||||||
|
{ state = Disconnected ;
|
||||||
|
trusted ; peer_id ; metadata ; created ;
|
||||||
|
last_failed_connection ;
|
||||||
|
last_rejected_connection ;
|
||||||
|
last_established_connection ;
|
||||||
|
last_disconnection ;
|
||||||
|
events ;
|
||||||
|
watchers = Lwt_watcher.create_input () ;
|
||||||
|
})
|
||||||
|
(obj9
|
||||||
|
(req "peer_id" Id.encoding)
|
||||||
|
(req "created" Time.encoding)
|
||||||
|
(dft "trusted" bool false)
|
||||||
|
(req "metadata" metadata_encoding)
|
||||||
|
(dft "events" (list Event.encoding) [])
|
||||||
|
(opt "last_failed_connection"
|
||||||
|
(tup2 P2p_connection.Id.encoding Time.encoding))
|
||||||
|
(opt "last_rejected_connection"
|
||||||
|
(tup2 P2p_connection.Id.encoding Time.encoding))
|
||||||
|
(opt "last_established_connection"
|
||||||
|
(tup2 P2p_connection.Id.encoding Time.encoding))
|
||||||
|
(opt "last_disconnection"
|
||||||
|
(tup2 P2p_connection.Id.encoding Time.encoding)))
|
||||||
|
|
||||||
|
let peer_id { peer_id ; _ } = peer_id
|
||||||
|
let created { created ; _ } = created
|
||||||
|
let metadata { metadata ; _ } = metadata
|
||||||
|
let set_metadata gi metadata = gi.metadata <- metadata
|
||||||
|
let trusted { trusted ; _ } = trusted
|
||||||
|
let set_trusted gi = gi.trusted <- true
|
||||||
|
let unset_trusted gi = gi.trusted <- false
|
||||||
|
let last_established_connection s = s.last_established_connection
|
||||||
|
let last_disconnection s = s.last_disconnection
|
||||||
|
let last_failed_connection s = s.last_failed_connection
|
||||||
|
let last_rejected_connection s = s.last_rejected_connection
|
||||||
|
|
||||||
|
let last_seen s =
|
||||||
|
Time.recent
|
||||||
|
s.last_established_connection
|
||||||
|
(Time.recent s.last_rejected_connection s.last_disconnection)
|
||||||
|
let last_miss s =
|
||||||
|
Time.recent
|
||||||
|
s.last_failed_connection
|
||||||
|
(Time.recent s.last_rejected_connection s.last_disconnection)
|
||||||
|
|
||||||
|
let log { events ; watchers ; _ } ?(timestamp = Time.now ()) point kind =
|
||||||
|
let event = { Event.kind ; timestamp ; point } in
|
||||||
|
Ring.add events event ;
|
||||||
|
Lwt_watcher.notify watchers event
|
||||||
|
|
||||||
|
let log_incoming_rejection ?timestamp peer_info point =
|
||||||
|
log peer_info ?timestamp point Rejecting_request
|
||||||
|
|
||||||
|
module File = struct
|
||||||
|
|
||||||
|
let load path metadata_encoding =
|
||||||
|
let enc = Data_encoding.list (encoding metadata_encoding) in
|
||||||
|
if path <> "/dev/null" && Sys.file_exists path then
|
||||||
|
Data_encoding_ezjsonm.read_file path >>=? fun json ->
|
||||||
|
return (Data_encoding.Json.destruct enc json)
|
||||||
|
else
|
||||||
|
return []
|
||||||
|
|
||||||
|
let save path metadata_encoding peers =
|
||||||
|
let open Data_encoding in
|
||||||
|
Data_encoding_ezjsonm.write_file path @@
|
||||||
|
Json.construct (list (encoding metadata_encoding)) peers
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_event = struct
|
||||||
|
include Event
|
||||||
|
let watch { Pool_info.watchers ; _ } = Lwt_watcher.create_stream watchers
|
||||||
|
let fold { Pool_info.events ; _ } ~init ~f = Ring.fold events ~init ~f
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_state = struct
|
||||||
|
|
||||||
|
type 'data t = 'data Pool_info.state =
|
||||||
|
| Accepted of { current_point: P2p_connection.Id.t ;
|
||||||
|
cancel: Lwt_canceler.t }
|
||||||
|
| Running of { data: 'data ;
|
||||||
|
current_point: P2p_connection.Id.t }
|
||||||
|
| Disconnected
|
||||||
|
type 'data state = 'data t
|
||||||
|
|
||||||
|
let pp ppf = function
|
||||||
|
| Accepted { current_point ; _ } ->
|
||||||
|
Format.fprintf ppf "accepted %a" P2p_connection.Id.pp current_point
|
||||||
|
| Running { current_point ; _ } ->
|
||||||
|
Format.fprintf ppf "running %a" P2p_connection.Id.pp current_point
|
||||||
|
| Disconnected ->
|
||||||
|
Format.fprintf ppf "disconnected"
|
||||||
|
|
||||||
|
let get { Pool_info.state ; _ } = state
|
||||||
|
|
||||||
|
let is_disconnected { Pool_info.state ; _ } =
|
||||||
|
match state with
|
||||||
|
| Disconnected -> true
|
||||||
|
| Accepted _ | Running _ -> false
|
||||||
|
|
||||||
|
let set_accepted
|
||||||
|
?(timestamp = Time.now ())
|
||||||
|
peer_info current_point cancel =
|
||||||
|
assert begin
|
||||||
|
match peer_info.Pool_info.state with
|
||||||
|
| Accepted _ | Running _ -> false
|
||||||
|
| Disconnected -> true
|
||||||
|
end ;
|
||||||
|
peer_info.state <- Accepted { current_point ; cancel } ;
|
||||||
|
Pool_info.log peer_info ~timestamp current_point Accepting_request
|
||||||
|
|
||||||
|
let set_running
|
||||||
|
?(timestamp = Time.now ())
|
||||||
|
peer_info point data =
|
||||||
|
assert begin
|
||||||
|
match peer_info.Pool_info.state with
|
||||||
|
| Disconnected -> true (* request to unknown peer_id. *)
|
||||||
|
| Running _ -> false
|
||||||
|
| Accepted { current_point ; _ } ->
|
||||||
|
P2p_connection.Id.equal point current_point
|
||||||
|
end ;
|
||||||
|
peer_info.state <- Running { data ; current_point = point } ;
|
||||||
|
peer_info.last_established_connection <- Some (point, timestamp) ;
|
||||||
|
Pool_info.log peer_info ~timestamp point Connection_established
|
||||||
|
|
||||||
|
let set_disconnected
|
||||||
|
?(timestamp = Time.now ()) ?(requested = false) peer_info =
|
||||||
|
let current_point, (event : Event.kind) =
|
||||||
|
match peer_info.Pool_info.state with
|
||||||
|
| Accepted { current_point ; _ } ->
|
||||||
|
peer_info.last_rejected_connection <-
|
||||||
|
Some (current_point, timestamp) ;
|
||||||
|
current_point, Request_rejected
|
||||||
|
| Running { current_point ; _ } ->
|
||||||
|
peer_info.last_disconnection <-
|
||||||
|
Some (current_point, timestamp) ;
|
||||||
|
current_point,
|
||||||
|
if requested then Disconnection else External_disconnection
|
||||||
|
| Disconnected -> assert false
|
||||||
|
in
|
||||||
|
peer_info.state <- Disconnected ;
|
||||||
|
Pool_info.log peer_info ~timestamp current_point event
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
184
src/lib_base/p2p_peer.mli
Normal file
184
src/lib_base/p2p_peer.mli
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
open Error_monad
|
||||||
|
|
||||||
|
module Id = Tezos_crypto.Crypto_box.Public_key_hash
|
||||||
|
|
||||||
|
module Map = Id.Map
|
||||||
|
module Set = Id.Set
|
||||||
|
module Table = Id.Table
|
||||||
|
|
||||||
|
module State : sig
|
||||||
|
|
||||||
|
type t =
|
||||||
|
| Accepted
|
||||||
|
| Running
|
||||||
|
| Disconnected
|
||||||
|
|
||||||
|
val pp_digram : Format.formatter -> t -> unit
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Info : sig
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
score : float ;
|
||||||
|
trusted : bool ;
|
||||||
|
state : State.t ;
|
||||||
|
id_point : P2p_connection.Id.t option ;
|
||||||
|
stat : P2p_stat.t ;
|
||||||
|
last_failed_connection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_rejected_connection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_established_connection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_disconnection : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_seen : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
last_miss : (P2p_connection.Id.t * Time.t) option ;
|
||||||
|
}
|
||||||
|
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
(** P2p_peer.Id info: current and historical information about a peer_id *)
|
||||||
|
|
||||||
|
module Pool_info : sig
|
||||||
|
|
||||||
|
type ('conn, 'meta) t
|
||||||
|
type ('conn, 'meta) peer_info = ('conn, 'meta) t
|
||||||
|
|
||||||
|
val compare : ('conn, 'meta) t -> ('conn, 'meta) t -> int
|
||||||
|
|
||||||
|
val create :
|
||||||
|
?created:Time.t ->
|
||||||
|
?trusted:bool ->
|
||||||
|
metadata:'meta ->
|
||||||
|
Id.t -> ('conn, 'meta) peer_info
|
||||||
|
(** [create ~trusted ~meta peer_id] is a freshly minted peer_id info for
|
||||||
|
[peer_id]. *)
|
||||||
|
|
||||||
|
val peer_id : ('conn, 'meta) peer_info -> Id.t
|
||||||
|
|
||||||
|
val created : ('conn, 'meta) peer_info -> Time.t
|
||||||
|
val metadata : ('conn, 'meta) peer_info -> 'meta
|
||||||
|
val set_metadata : ('conn, 'meta) peer_info -> 'meta -> unit
|
||||||
|
|
||||||
|
val trusted : ('conn, 'meta) peer_info -> bool
|
||||||
|
val set_trusted : ('conn, 'meta) peer_info -> unit
|
||||||
|
val unset_trusted : ('conn, 'meta) peer_info -> unit
|
||||||
|
|
||||||
|
val last_failed_connection :
|
||||||
|
('conn, 'meta) peer_info -> (P2p_connection.Id.t * Time.t) option
|
||||||
|
val last_rejected_connection :
|
||||||
|
('conn, 'meta) peer_info -> (P2p_connection.Id.t * Time.t) option
|
||||||
|
val last_established_connection :
|
||||||
|
('conn, 'meta) peer_info -> (P2p_connection.Id.t * Time.t) option
|
||||||
|
val last_disconnection :
|
||||||
|
('conn, 'meta) peer_info -> (P2p_connection.Id.t * Time.t) option
|
||||||
|
|
||||||
|
val last_seen :
|
||||||
|
('conn, 'meta) peer_info -> (P2p_connection.Id.t * Time.t) option
|
||||||
|
(** [last_seen gi] is the most recent of:
|
||||||
|
|
||||||
|
* last established connection
|
||||||
|
* last rejected connection
|
||||||
|
* last disconnection
|
||||||
|
*)
|
||||||
|
|
||||||
|
val last_miss :
|
||||||
|
('conn, 'meta) peer_info -> (P2p_connection.Id.t * Time.t) option
|
||||||
|
(** [last_miss gi] is the most recent of:
|
||||||
|
|
||||||
|
* last failed connection
|
||||||
|
* last rejected connection
|
||||||
|
* last disconnection
|
||||||
|
*)
|
||||||
|
|
||||||
|
val log_incoming_rejection :
|
||||||
|
?timestamp:Time.t ->
|
||||||
|
('conn, 'meta) peer_info -> P2p_connection.Id.t -> unit
|
||||||
|
|
||||||
|
module File : sig
|
||||||
|
val load :
|
||||||
|
string -> 'meta Data_encoding.t ->
|
||||||
|
('conn, 'meta) peer_info list tzresult Lwt.t
|
||||||
|
val save :
|
||||||
|
string -> 'meta Data_encoding.t ->
|
||||||
|
('conn, 'meta) peer_info list -> unit tzresult Lwt.t
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_state : sig
|
||||||
|
|
||||||
|
type 'conn t =
|
||||||
|
| Accepted of { current_point: P2p_connection.Id.t ;
|
||||||
|
cancel: Lwt_canceler.t }
|
||||||
|
(** We accepted a incoming connection, we greeted back and
|
||||||
|
we are waiting for an acknowledgement. *)
|
||||||
|
| Running of { data: 'conn ;
|
||||||
|
current_point: P2p_connection.Id.t }
|
||||||
|
(** Successfully authentificated connection, normal business. *)
|
||||||
|
| Disconnected
|
||||||
|
(** No connection established currently. *)
|
||||||
|
type 'conn state = 'conn t
|
||||||
|
|
||||||
|
val pp : Format.formatter -> 'conn t -> unit
|
||||||
|
|
||||||
|
val get : ('conn, 'meta) Pool_info.t -> 'conn state
|
||||||
|
|
||||||
|
val is_disconnected : ('conn, 'meta) Pool_info.t -> bool
|
||||||
|
|
||||||
|
val set_accepted :
|
||||||
|
?timestamp:Time.t ->
|
||||||
|
('conn, 'meta) Pool_info.t -> P2p_connection.Id.t -> Lwt_canceler.t -> unit
|
||||||
|
|
||||||
|
val set_running :
|
||||||
|
?timestamp:Time.t ->
|
||||||
|
('conn, 'meta) Pool_info.t -> P2p_connection.Id.t -> 'conn -> unit
|
||||||
|
|
||||||
|
val set_disconnected :
|
||||||
|
?timestamp:Time.t ->
|
||||||
|
?requested:bool ->
|
||||||
|
('conn, 'meta) Pool_info.t -> unit
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_event : sig
|
||||||
|
|
||||||
|
type kind =
|
||||||
|
| Accepting_request
|
||||||
|
(** We accepted a connection after authentifying the remote peer. *)
|
||||||
|
| Rejecting_request
|
||||||
|
(** We rejected a connection after authentifying the remote peer. *)
|
||||||
|
| Request_rejected
|
||||||
|
(** The remote peer rejected our connection. *)
|
||||||
|
| Connection_established
|
||||||
|
(** We succesfully established a authentified connection. *)
|
||||||
|
| Disconnection
|
||||||
|
(** We decided to close the connection. *)
|
||||||
|
| External_disconnection
|
||||||
|
(** The connection was closed for external reason. *)
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
kind : kind ;
|
||||||
|
timestamp : Time.t ;
|
||||||
|
point : P2p_connection.Id.t ;
|
||||||
|
}
|
||||||
|
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
|
||||||
|
val fold :
|
||||||
|
('conn, 'meta) Pool_info.t -> init:'a -> f:('a -> t -> 'a) -> 'a
|
||||||
|
|
||||||
|
val watch :
|
||||||
|
('conn, 'meta) Pool_info.t -> t Lwt_stream.t * Lwt_watcher.stopper
|
||||||
|
|
||||||
|
end
|
477
src/lib_base/p2p_point.ml
Normal file
477
src/lib_base/p2p_point.ml
Normal file
@ -0,0 +1,477 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type peer_id = Crypto_box.Public_key_hash.t
|
||||||
|
let peer_id_encoding = Crypto_box.Public_key_hash.encoding
|
||||||
|
let peer_id_pp = Crypto_box.Public_key_hash.pp
|
||||||
|
let peer_id_equal = Crypto_box.Public_key_hash.equal
|
||||||
|
|
||||||
|
module Id = struct
|
||||||
|
|
||||||
|
(* A net point (address x port). *)
|
||||||
|
type t = P2p_addr.t * P2p_addr.port
|
||||||
|
let compare (a1, p1) (a2, p2) =
|
||||||
|
match Ipaddr.V6.compare a1 a2 with
|
||||||
|
| 0 -> p1 - p2
|
||||||
|
| x -> x
|
||||||
|
let equal p1 p2 = compare p1 p2 = 0
|
||||||
|
let hash = Hashtbl.hash
|
||||||
|
let pp ppf (addr, port) =
|
||||||
|
match Ipaddr.v4_of_v6 addr with
|
||||||
|
| Some addr ->
|
||||||
|
Format.fprintf ppf "%a:%d" Ipaddr.V4.pp_hum addr port
|
||||||
|
| None ->
|
||||||
|
Format.fprintf ppf "[%a]:%d" Ipaddr.V6.pp_hum addr port
|
||||||
|
let pp_opt ppf = function
|
||||||
|
| None -> Format.pp_print_string ppf "none"
|
||||||
|
| Some point -> pp ppf point
|
||||||
|
|
||||||
|
let is_local (addr, _) = Ipaddr.V6.is_private addr
|
||||||
|
let is_global (addr, _) = not @@ Ipaddr.V6.is_private addr
|
||||||
|
|
||||||
|
let check_port port =
|
||||||
|
if TzString.mem_char port '[' ||
|
||||||
|
TzString.mem_char port ']' ||
|
||||||
|
TzString.mem_char port ':' then
|
||||||
|
invalid_arg "Utils.parse_addr_port (invalid character in port)"
|
||||||
|
|
||||||
|
let parse_addr_port s =
|
||||||
|
let len = String.length s in
|
||||||
|
if len = 0 then
|
||||||
|
("", "")
|
||||||
|
else if s.[0] = '[' then begin (* inline IPv6 *)
|
||||||
|
match String.rindex s ']' with
|
||||||
|
| exception Not_found ->
|
||||||
|
invalid_arg "Utils.parse_addr_port (missing ']')"
|
||||||
|
| pos ->
|
||||||
|
let addr = String.sub s 1 (pos - 1) in
|
||||||
|
let port =
|
||||||
|
if pos = len - 1 then
|
||||||
|
""
|
||||||
|
else if s.[pos+1] <> ':' then
|
||||||
|
invalid_arg "Utils.parse_addr_port (unexpected char after ']')"
|
||||||
|
else
|
||||||
|
String.sub s (pos + 2) (len - pos - 2) in
|
||||||
|
check_port port ;
|
||||||
|
addr, port
|
||||||
|
end else begin
|
||||||
|
match String.rindex s ']' with
|
||||||
|
| _pos ->
|
||||||
|
invalid_arg "Utils.parse_addr_port (unexpected char ']')"
|
||||||
|
| exception Not_found ->
|
||||||
|
match String.index s ':' with
|
||||||
|
| exception _ -> s, ""
|
||||||
|
| pos ->
|
||||||
|
match String.index_from s (pos+1) ':' with
|
||||||
|
| exception _ ->
|
||||||
|
let addr = String.sub s 0 pos in
|
||||||
|
let port = String.sub s (pos + 1) (len - pos - 1) in
|
||||||
|
check_port port ;
|
||||||
|
addr, port
|
||||||
|
| _pos ->
|
||||||
|
invalid_arg "Utils.parse_addr_port: IPv6 addresses must be bracketed"
|
||||||
|
end
|
||||||
|
|
||||||
|
let of_string_exn str =
|
||||||
|
let addr, port = parse_addr_port str in
|
||||||
|
let port = int_of_string port in
|
||||||
|
if port < 0 && port > 1 lsl 16 - 1 then
|
||||||
|
invalid_arg "port must be between 0 and 65535" ;
|
||||||
|
match Ipaddr.of_string_exn addr with
|
||||||
|
| V4 addr -> Ipaddr.v6_of_v4 addr, port
|
||||||
|
| V6 addr -> addr, port
|
||||||
|
|
||||||
|
let of_string str =
|
||||||
|
try Ok (of_string_exn str) with
|
||||||
|
| Invalid_argument s -> Error s
|
||||||
|
| Failure s -> Error s
|
||||||
|
| _ -> Error "P2p_point.of_string"
|
||||||
|
|
||||||
|
let to_string saddr = Format.asprintf "%a" pp saddr
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
Data_encoding.conv to_string of_string_exn Data_encoding.string
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Map = Map.Make (Id)
|
||||||
|
module Set = Set.Make (Id)
|
||||||
|
module Table = Hashtbl.Make (Id)
|
||||||
|
|
||||||
|
module State = struct
|
||||||
|
|
||||||
|
type t =
|
||||||
|
| Requested
|
||||||
|
| Accepted of peer_id
|
||||||
|
| Running of peer_id
|
||||||
|
| Disconnected
|
||||||
|
|
||||||
|
let of_peer_id = function
|
||||||
|
| Requested -> None
|
||||||
|
| Accepted pi -> Some pi
|
||||||
|
| Running pi -> Some pi
|
||||||
|
| Disconnected -> None
|
||||||
|
|
||||||
|
let of_peerid_state state pi =
|
||||||
|
match state, pi with
|
||||||
|
| Requested, _ -> Requested
|
||||||
|
| Accepted _, Some pi -> Accepted pi
|
||||||
|
| Running _, Some pi -> Running pi
|
||||||
|
| Disconnected, _ -> Disconnected
|
||||||
|
| _ -> invalid_arg "state_of_state_peerid"
|
||||||
|
|
||||||
|
let pp_digram ppf = function
|
||||||
|
| Requested -> Format.fprintf ppf "⚎"
|
||||||
|
| Accepted _ -> Format.fprintf ppf "⚍"
|
||||||
|
| Running _ -> Format.fprintf ppf "⚌"
|
||||||
|
| Disconnected -> Format.fprintf ppf "⚏"
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
let branch_encoding name obj =
|
||||||
|
conv (fun x -> (), x) (fun ((), x) -> x)
|
||||||
|
(merge_objs
|
||||||
|
(obj1 (req "event_kind" (constant name))) obj) in
|
||||||
|
union ~tag_size:`Uint8 [
|
||||||
|
case (Tag 0) (branch_encoding "requested" empty)
|
||||||
|
(function Requested -> Some () | _ -> None)
|
||||||
|
(fun () -> Requested) ;
|
||||||
|
case (Tag 1) (branch_encoding "accepted"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function Accepted peer_id -> Some peer_id | _ -> None)
|
||||||
|
(fun peer_id -> Accepted peer_id) ;
|
||||||
|
case (Tag 2) (branch_encoding "running"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function Running peer_id -> Some peer_id | _ -> None)
|
||||||
|
(fun peer_id -> Running peer_id) ;
|
||||||
|
case (Tag 3) (branch_encoding "disconnected" empty)
|
||||||
|
(function Disconnected -> Some () | _ -> None)
|
||||||
|
(fun () -> Disconnected) ;
|
||||||
|
]
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Info = struct
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
trusted : bool ;
|
||||||
|
greylisted_until : Time.t ;
|
||||||
|
state : State.t ;
|
||||||
|
last_failed_connection : Time.t option ;
|
||||||
|
last_rejected_connection : (peer_id * Time.t) option ;
|
||||||
|
last_established_connection : (peer_id * Time.t) option ;
|
||||||
|
last_disconnection : (peer_id * Time.t) option ;
|
||||||
|
last_seen : (peer_id * Time.t) option ;
|
||||||
|
last_miss : Time.t option ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { trusted ; greylisted_until ; state ;
|
||||||
|
last_failed_connection ; last_rejected_connection ;
|
||||||
|
last_established_connection ; last_disconnection ;
|
||||||
|
last_seen ; last_miss } ->
|
||||||
|
let peer_id = State.of_peer_id state in
|
||||||
|
(trusted, greylisted_until, state, peer_id,
|
||||||
|
last_failed_connection, last_rejected_connection,
|
||||||
|
last_established_connection, last_disconnection,
|
||||||
|
last_seen, last_miss))
|
||||||
|
(fun (trusted, greylisted_until, state, peer_id,
|
||||||
|
last_failed_connection, last_rejected_connection,
|
||||||
|
last_established_connection, last_disconnection,
|
||||||
|
last_seen, last_miss) ->
|
||||||
|
let state = State.of_peerid_state state peer_id in
|
||||||
|
{ trusted ; greylisted_until ; state ;
|
||||||
|
last_failed_connection ; last_rejected_connection ;
|
||||||
|
last_established_connection ; last_disconnection ;
|
||||||
|
last_seen ; last_miss })
|
||||||
|
(obj10
|
||||||
|
(req "trusted" bool)
|
||||||
|
(dft "greylisted_until" Time.encoding Time.epoch)
|
||||||
|
(req "state" State.encoding)
|
||||||
|
(opt "peer_id" peer_id_encoding)
|
||||||
|
(opt "last_failed_connection" Time.encoding)
|
||||||
|
(opt "last_rejected_connection" (tup2 peer_id_encoding Time.encoding))
|
||||||
|
(opt "last_established_connection" (tup2 peer_id_encoding Time.encoding))
|
||||||
|
(opt "last_disconnection" (tup2 peer_id_encoding Time.encoding))
|
||||||
|
(opt "last_seen" (tup2 peer_id_encoding Time.encoding))
|
||||||
|
(opt "last_miss" Time.encoding))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Event = struct
|
||||||
|
|
||||||
|
type kind =
|
||||||
|
| Outgoing_request
|
||||||
|
| Accepting_request of peer_id
|
||||||
|
| Rejecting_request of peer_id
|
||||||
|
| Request_rejected of peer_id option
|
||||||
|
| Connection_established of peer_id
|
||||||
|
| Disconnection of peer_id
|
||||||
|
| External_disconnection of peer_id
|
||||||
|
|
||||||
|
let kind_encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
let branch_encoding name obj =
|
||||||
|
conv (fun x -> (), x) (fun ((), x) -> x)
|
||||||
|
(merge_objs
|
||||||
|
(obj1 (req "event_kind" (constant name))) obj) in
|
||||||
|
union ~tag_size:`Uint8 [
|
||||||
|
case (Tag 0) (branch_encoding "outgoing_request" empty)
|
||||||
|
(function Outgoing_request -> Some () | _ -> None)
|
||||||
|
(fun () -> Outgoing_request) ;
|
||||||
|
case (Tag 1) (branch_encoding "accepting_request"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function Accepting_request peer_id -> Some peer_id | _ -> None)
|
||||||
|
(fun peer_id -> Accepting_request peer_id) ;
|
||||||
|
case (Tag 2) (branch_encoding "rejecting_request"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function Rejecting_request peer_id -> Some peer_id | _ -> None)
|
||||||
|
(fun peer_id -> Rejecting_request peer_id) ;
|
||||||
|
case (Tag 3) (branch_encoding "request_rejected"
|
||||||
|
(obj1 (opt "peer_id" peer_id_encoding)))
|
||||||
|
(function Request_rejected peer_id -> Some peer_id | _ -> None)
|
||||||
|
(fun peer_id -> Request_rejected peer_id) ;
|
||||||
|
case (Tag 4) (branch_encoding "rejecting_request"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function Connection_established peer_id -> Some peer_id | _ -> None)
|
||||||
|
(fun peer_id -> Connection_established peer_id) ;
|
||||||
|
case (Tag 5) (branch_encoding "rejecting_request"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function Disconnection peer_id -> Some peer_id | _ -> None)
|
||||||
|
(fun peer_id -> Disconnection peer_id) ;
|
||||||
|
case (Tag 6) (branch_encoding "rejecting_request"
|
||||||
|
(obj1 (req "peer_id" peer_id_encoding)))
|
||||||
|
(function External_disconnection peer_id -> Some peer_id | _ -> None)
|
||||||
|
(fun peer_id -> External_disconnection peer_id) ;
|
||||||
|
]
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
kind : kind ;
|
||||||
|
timestamp : Time.t ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { kind ; timestamp ; } -> (kind, timestamp))
|
||||||
|
(fun (kind, timestamp) -> { kind ; timestamp ; })
|
||||||
|
(obj2
|
||||||
|
(req "kind" kind_encoding)
|
||||||
|
(req "timestamp" Time.encoding))
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_info = struct
|
||||||
|
|
||||||
|
type 'data state =
|
||||||
|
| Requested of { cancel: Lwt_canceler.t }
|
||||||
|
| Accepted of { current_peer_id: peer_id ;
|
||||||
|
cancel: Lwt_canceler.t }
|
||||||
|
| Running of { data: 'data ;
|
||||||
|
current_peer_id: peer_id }
|
||||||
|
| Disconnected
|
||||||
|
|
||||||
|
type greylisting_config = {
|
||||||
|
factor: float ;
|
||||||
|
initial_delay: int ;
|
||||||
|
disconnection_delay: int ;
|
||||||
|
}
|
||||||
|
|
||||||
|
type 'data t = {
|
||||||
|
point : Id.t ;
|
||||||
|
mutable trusted : bool ;
|
||||||
|
mutable state : 'data state ;
|
||||||
|
mutable last_failed_connection : Time.t option ;
|
||||||
|
mutable last_rejected_connection : (peer_id * Time.t) option ;
|
||||||
|
mutable last_established_connection : (peer_id * Time.t) option ;
|
||||||
|
mutable last_disconnection : (peer_id * Time.t) option ;
|
||||||
|
greylisting : greylisting_config ;
|
||||||
|
mutable greylisting_delay : float ;
|
||||||
|
mutable greylisting_end : Time.t ;
|
||||||
|
events : Event.t Ring.t ;
|
||||||
|
watchers : Event.t Lwt_watcher.input ;
|
||||||
|
}
|
||||||
|
type 'data point_info = 'data t
|
||||||
|
|
||||||
|
let compare pi1 pi2 = Id.compare pi1.point pi2.point
|
||||||
|
|
||||||
|
let log_size = 100
|
||||||
|
|
||||||
|
let default_greylisting_config = {
|
||||||
|
factor = 1.2 ;
|
||||||
|
initial_delay = 1 ;
|
||||||
|
disconnection_delay = 60 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let create
|
||||||
|
?(trusted = false)
|
||||||
|
?(greylisting_config = default_greylisting_config) addr port = {
|
||||||
|
point = (addr, port) ;
|
||||||
|
trusted ;
|
||||||
|
state = Disconnected ;
|
||||||
|
last_failed_connection = None ;
|
||||||
|
last_rejected_connection = None ;
|
||||||
|
last_established_connection = None ;
|
||||||
|
last_disconnection = None ;
|
||||||
|
events = Ring.create log_size ;
|
||||||
|
greylisting = greylisting_config ;
|
||||||
|
greylisting_delay = 1. ;
|
||||||
|
greylisting_end = Time.epoch ;
|
||||||
|
watchers = Lwt_watcher.create_input () ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let point s = s.point
|
||||||
|
let trusted s = s.trusted
|
||||||
|
let set_trusted gi = gi.trusted <- true
|
||||||
|
let unset_trusted gi = gi.trusted <- false
|
||||||
|
let last_established_connection s = s.last_established_connection
|
||||||
|
let last_disconnection s = s.last_disconnection
|
||||||
|
let last_failed_connection s = s.last_failed_connection
|
||||||
|
let last_rejected_connection s = s.last_rejected_connection
|
||||||
|
let greylisted ?(now = Time.now ()) s =
|
||||||
|
Time.compare now s.greylisting_end <= 0
|
||||||
|
let greylisted_until s = s.greylisting_end
|
||||||
|
|
||||||
|
let last_seen s =
|
||||||
|
Time.recent s.last_rejected_connection
|
||||||
|
(Time.recent s.last_established_connection s.last_disconnection)
|
||||||
|
let last_miss s =
|
||||||
|
match
|
||||||
|
s.last_failed_connection,
|
||||||
|
(Option.map ~f:(fun (_, time) -> time) @@
|
||||||
|
Time.recent s.last_rejected_connection s.last_disconnection) with
|
||||||
|
| (None, None) -> None
|
||||||
|
| (None, (Some _ as a))
|
||||||
|
| (Some _ as a, None) -> a
|
||||||
|
| (Some t1 as a1 , (Some t2 as a2)) ->
|
||||||
|
if Time.compare t1 t2 < 0 then a2 else a1
|
||||||
|
|
||||||
|
let log { events ; watchers ; _ } ?(timestamp = Time.now ()) kind =
|
||||||
|
let event = { Event.kind ; timestamp } in
|
||||||
|
Ring.add events event ;
|
||||||
|
Lwt_watcher.notify watchers event
|
||||||
|
|
||||||
|
let log_incoming_rejection ?timestamp point_info peer_id =
|
||||||
|
log point_info ?timestamp (Rejecting_request peer_id)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_event = struct
|
||||||
|
|
||||||
|
include Event
|
||||||
|
|
||||||
|
let fold { Pool_info.events ; _ } ~init ~f = Ring.fold events ~init ~f
|
||||||
|
|
||||||
|
let watch { Pool_info.watchers ; _ } = Lwt_watcher.create_stream watchers
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_state = struct
|
||||||
|
|
||||||
|
type 'data t = 'data Pool_info.state =
|
||||||
|
| Requested of { cancel: Lwt_canceler.t }
|
||||||
|
| Accepted of { current_peer_id: peer_id ;
|
||||||
|
cancel: Lwt_canceler.t }
|
||||||
|
| Running of { data: 'data ;
|
||||||
|
current_peer_id: peer_id }
|
||||||
|
| Disconnected
|
||||||
|
type 'data state = 'data t
|
||||||
|
|
||||||
|
let pp ppf = function
|
||||||
|
| Requested _ ->
|
||||||
|
Format.fprintf ppf "requested"
|
||||||
|
| Accepted { current_peer_id ; _ } ->
|
||||||
|
Format.fprintf ppf "accepted %a" peer_id_pp current_peer_id
|
||||||
|
| Running { current_peer_id ; _ } ->
|
||||||
|
Format.fprintf ppf "running %a" peer_id_pp current_peer_id
|
||||||
|
| Disconnected ->
|
||||||
|
Format.fprintf ppf "disconnected"
|
||||||
|
|
||||||
|
let get { Pool_info.state ; _ } = state
|
||||||
|
|
||||||
|
let is_disconnected { Pool_info.state ; _ } =
|
||||||
|
match state with
|
||||||
|
| Disconnected -> true
|
||||||
|
| Requested _ | Accepted _ | Running _ -> false
|
||||||
|
|
||||||
|
let set_requested ?timestamp point_info cancel =
|
||||||
|
assert begin
|
||||||
|
match point_info.Pool_info.state with
|
||||||
|
| Requested _ -> true
|
||||||
|
| Accepted _ | Running _ -> false
|
||||||
|
| Disconnected -> true
|
||||||
|
end ;
|
||||||
|
point_info.state <- Requested { cancel } ;
|
||||||
|
Pool_info.log point_info ?timestamp Outgoing_request
|
||||||
|
|
||||||
|
let set_accepted
|
||||||
|
?(timestamp = Time.now ())
|
||||||
|
point_info current_peer_id cancel =
|
||||||
|
(* log_notice "SET_ACCEPTED %a@." P2p_point.pp point_info.point ; *)
|
||||||
|
assert begin
|
||||||
|
match point_info.Pool_info.state with
|
||||||
|
| Accepted _ | Running _ -> false
|
||||||
|
| Requested _ | Disconnected -> true
|
||||||
|
end ;
|
||||||
|
point_info.state <- Accepted { current_peer_id ; cancel } ;
|
||||||
|
Pool_info.log point_info ~timestamp (Accepting_request current_peer_id)
|
||||||
|
|
||||||
|
let set_running
|
||||||
|
?(timestamp = Time.now ())
|
||||||
|
point_info peer_id data =
|
||||||
|
assert begin
|
||||||
|
match point_info.Pool_info.state with
|
||||||
|
| Disconnected -> true (* request to unknown peer_id. *)
|
||||||
|
| Running _ -> false
|
||||||
|
| Accepted { current_peer_id ; _ } -> peer_id_equal peer_id current_peer_id
|
||||||
|
| Requested _ -> true
|
||||||
|
end ;
|
||||||
|
point_info.state <- Running { data ; current_peer_id = peer_id } ;
|
||||||
|
point_info.last_established_connection <- Some (peer_id, timestamp) ;
|
||||||
|
Pool_info.log point_info ~timestamp (Connection_established peer_id)
|
||||||
|
|
||||||
|
let set_greylisted timestamp point_info =
|
||||||
|
point_info.Pool_info.greylisting_end <-
|
||||||
|
Time.add
|
||||||
|
timestamp
|
||||||
|
(Int64.of_float point_info.Pool_info.greylisting_delay) ;
|
||||||
|
point_info.greylisting_delay <-
|
||||||
|
point_info.greylisting_delay *. point_info.greylisting.factor
|
||||||
|
|
||||||
|
let set_disconnected
|
||||||
|
?(timestamp = Time.now ()) ?(requested = false) point_info =
|
||||||
|
let event : Event.kind =
|
||||||
|
match point_info.Pool_info.state with
|
||||||
|
| Requested _ ->
|
||||||
|
set_greylisted timestamp point_info ;
|
||||||
|
point_info.last_failed_connection <- Some timestamp ;
|
||||||
|
Request_rejected None
|
||||||
|
| Accepted { current_peer_id ; _ } ->
|
||||||
|
set_greylisted timestamp point_info ;
|
||||||
|
point_info.last_rejected_connection <-
|
||||||
|
Some (current_peer_id, timestamp) ;
|
||||||
|
Request_rejected (Some current_peer_id)
|
||||||
|
| Running { current_peer_id ; _ } ->
|
||||||
|
point_info.greylisting_delay <-
|
||||||
|
float_of_int point_info.greylisting.initial_delay ;
|
||||||
|
point_info.greylisting_end <-
|
||||||
|
Time.add timestamp
|
||||||
|
(Int64.of_int point_info.greylisting.disconnection_delay) ;
|
||||||
|
point_info.last_disconnection <- Some (current_peer_id, timestamp) ;
|
||||||
|
if requested
|
||||||
|
then Disconnection current_peer_id
|
||||||
|
else External_disconnection current_peer_id
|
||||||
|
| Disconnected ->
|
||||||
|
assert false
|
||||||
|
in
|
||||||
|
point_info.state <- Disconnected ;
|
||||||
|
Pool_info.log point_info ~timestamp event
|
||||||
|
|
||||||
|
end
|
207
src/lib_base/p2p_point.mli
Normal file
207
src/lib_base/p2p_point.mli
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type peer_id = Crypto_box.Public_key_hash.t
|
||||||
|
(* = P2p_peer.Id.t, but we should break cycles *)
|
||||||
|
|
||||||
|
module Id : sig
|
||||||
|
|
||||||
|
type t = P2p_addr.t * P2p_addr.port
|
||||||
|
val compare : t -> t -> int
|
||||||
|
|
||||||
|
val pp : Format.formatter -> t -> unit
|
||||||
|
val pp_opt : Format.formatter -> t option -> unit
|
||||||
|
|
||||||
|
val of_string_exn : string -> t
|
||||||
|
val of_string : string -> (t, string) result
|
||||||
|
val to_string : t -> string
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
val is_local : t -> bool
|
||||||
|
val is_global : t -> bool
|
||||||
|
val parse_addr_port : string -> string * string
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Map : Map.S with type key = Id.t
|
||||||
|
module Set : Set.S with type elt = Id.t
|
||||||
|
module Table : Hashtbl.S with type key = Id.t
|
||||||
|
|
||||||
|
module State : sig
|
||||||
|
|
||||||
|
type t =
|
||||||
|
| Requested
|
||||||
|
| Accepted of peer_id
|
||||||
|
| Running of peer_id
|
||||||
|
| Disconnected
|
||||||
|
|
||||||
|
val pp_digram : Format.formatter -> t -> unit
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
|
||||||
|
val of_peer_id : t -> peer_id option
|
||||||
|
val of_peerid_state : t -> peer_id option -> t
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Info : sig
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
trusted : bool ;
|
||||||
|
greylisted_until : Time.t ;
|
||||||
|
state : State.t ;
|
||||||
|
last_failed_connection : Time.t option ;
|
||||||
|
last_rejected_connection : (peer_id * Time.t) option ;
|
||||||
|
last_established_connection : (peer_id * Time.t) option ;
|
||||||
|
last_disconnection : (peer_id * Time.t) option ;
|
||||||
|
last_seen : (peer_id * Time.t) option ;
|
||||||
|
last_miss : Time.t option ;
|
||||||
|
}
|
||||||
|
|
||||||
|
val encoding: t Data_encoding.t
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_info : sig
|
||||||
|
|
||||||
|
type 'conn t
|
||||||
|
type 'conn point_info = 'conn t
|
||||||
|
(** Type of info associated to a point. *)
|
||||||
|
|
||||||
|
val compare : 'conn point_info -> 'conn point_info -> int
|
||||||
|
|
||||||
|
type greylisting_config = {
|
||||||
|
factor: float ;
|
||||||
|
initial_delay: int ;
|
||||||
|
disconnection_delay: int ;
|
||||||
|
}
|
||||||
|
|
||||||
|
val create :
|
||||||
|
?trusted:bool ->
|
||||||
|
?greylisting_config:greylisting_config ->
|
||||||
|
P2p_addr.t -> P2p_addr.port -> 'conn point_info
|
||||||
|
(** [create ~trusted addr port] is a freshly minted point_info. If
|
||||||
|
[trusted] is true, this point is considered trusted and will
|
||||||
|
be treated as such. *)
|
||||||
|
|
||||||
|
val trusted : 'conn point_info -> bool
|
||||||
|
(** [trusted pi] is [true] iff [pi] has is trusted,
|
||||||
|
i.e. "whitelisted". *)
|
||||||
|
|
||||||
|
val set_trusted : 'conn point_info -> unit
|
||||||
|
val unset_trusted : 'conn point_info -> unit
|
||||||
|
|
||||||
|
val last_failed_connection :
|
||||||
|
'conn point_info -> Time.t option
|
||||||
|
val last_rejected_connection :
|
||||||
|
'conn point_info -> (peer_id * Time.t) option
|
||||||
|
val last_established_connection :
|
||||||
|
'conn point_info -> (peer_id * Time.t) option
|
||||||
|
val last_disconnection :
|
||||||
|
'conn point_info -> (peer_id * Time.t) option
|
||||||
|
|
||||||
|
val last_seen :
|
||||||
|
'conn point_info -> (peer_id * Time.t) option
|
||||||
|
(** [last_seen pi] is the most recent of:
|
||||||
|
|
||||||
|
* last established connection
|
||||||
|
* last rejected connection
|
||||||
|
* last disconnection
|
||||||
|
*)
|
||||||
|
|
||||||
|
val last_miss :
|
||||||
|
'conn point_info -> Time.t option
|
||||||
|
(** [last_miss pi] is the most recent of:
|
||||||
|
|
||||||
|
* last failed connection
|
||||||
|
* last rejected connection
|
||||||
|
* last disconnection
|
||||||
|
*)
|
||||||
|
|
||||||
|
val greylisted :
|
||||||
|
?now:Time.t -> 'conn point_info -> bool
|
||||||
|
|
||||||
|
val greylisted_until : 'conn point_info -> Time.t
|
||||||
|
|
||||||
|
val point : 'conn point_info -> Id.t
|
||||||
|
|
||||||
|
val log_incoming_rejection :
|
||||||
|
?timestamp:Time.t -> 'conn point_info -> peer_id -> unit
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_state : sig
|
||||||
|
|
||||||
|
type 'conn t =
|
||||||
|
| Requested of { cancel: Lwt_canceler.t }
|
||||||
|
(** We initiated a connection. *)
|
||||||
|
| Accepted of { current_peer_id: peer_id ;
|
||||||
|
cancel: Lwt_canceler.t }
|
||||||
|
(** We accepted a incoming connection. *)
|
||||||
|
| Running of { data: 'conn ;
|
||||||
|
current_peer_id: peer_id }
|
||||||
|
(** Successfully authentificated connection, normal business. *)
|
||||||
|
| Disconnected
|
||||||
|
(** No connection established currently. *)
|
||||||
|
type 'conn state = 'conn t
|
||||||
|
|
||||||
|
val pp : Format.formatter -> 'conn t -> unit
|
||||||
|
|
||||||
|
val get : 'conn Pool_info.t -> 'conn state
|
||||||
|
|
||||||
|
val is_disconnected : 'conn Pool_info.t -> bool
|
||||||
|
|
||||||
|
val set_requested :
|
||||||
|
?timestamp:Time.t ->
|
||||||
|
'conn Pool_info.t -> Lwt_canceler.t -> unit
|
||||||
|
|
||||||
|
val set_accepted :
|
||||||
|
?timestamp:Time.t ->
|
||||||
|
'conn Pool_info.t -> peer_id -> Lwt_canceler.t -> unit
|
||||||
|
|
||||||
|
val set_running :
|
||||||
|
?timestamp:Time.t -> 'conn Pool_info.t -> peer_id -> 'conn -> unit
|
||||||
|
|
||||||
|
val set_disconnected :
|
||||||
|
?timestamp:Time.t -> ?requested:bool -> 'conn Pool_info.t -> unit
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module Pool_event : sig
|
||||||
|
|
||||||
|
type kind =
|
||||||
|
| Outgoing_request
|
||||||
|
(** We initiated a connection. *)
|
||||||
|
| Accepting_request of peer_id
|
||||||
|
(** We accepted a connection after authentifying the remote peer. *)
|
||||||
|
| Rejecting_request of peer_id
|
||||||
|
(** We rejected a connection after authentifying the remote peer. *)
|
||||||
|
| Request_rejected of peer_id option
|
||||||
|
(** The remote peer rejected our connection. *)
|
||||||
|
| Connection_established of peer_id
|
||||||
|
(** We succesfully established a authentified connection. *)
|
||||||
|
| Disconnection of peer_id
|
||||||
|
(** We decided to close the connection. *)
|
||||||
|
| External_disconnection of peer_id
|
||||||
|
(** The connection was closed for external reason. *)
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
kind : kind ;
|
||||||
|
timestamp : Time.t ;
|
||||||
|
}
|
||||||
|
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
|
||||||
|
val fold :
|
||||||
|
'conn Pool_info.t -> init:'a -> f:('a -> t -> 'a) -> 'a
|
||||||
|
|
||||||
|
val watch :
|
||||||
|
'conn Pool_info.t -> t Lwt_stream.t * Lwt_watcher.stopper
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
64
src/lib_base/p2p_stat.ml
Normal file
64
src/lib_base/p2p_stat.ml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
total_sent : int64 ;
|
||||||
|
total_recv : int64 ;
|
||||||
|
current_inflow : int ;
|
||||||
|
current_outflow : int ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let empty = {
|
||||||
|
total_sent = 0L ;
|
||||||
|
total_recv = 0L ;
|
||||||
|
current_inflow = 0 ;
|
||||||
|
current_outflow = 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let print_size ppf sz =
|
||||||
|
let ratio n = (float_of_int sz /. float_of_int (1 lsl n)) in
|
||||||
|
if sz < 1 lsl 10 then
|
||||||
|
Format.fprintf ppf "%d B" sz
|
||||||
|
else if sz < 1 lsl 20 then
|
||||||
|
Format.fprintf ppf "%.2f kiB" (ratio 10)
|
||||||
|
else
|
||||||
|
Format.fprintf ppf "%.2f MiB" (ratio 20)
|
||||||
|
|
||||||
|
let print_size64 ppf sz =
|
||||||
|
let open Int64 in
|
||||||
|
let ratio n = (to_float sz /. float_of_int (1 lsl n)) in
|
||||||
|
if sz < shift_left 1L 10 then
|
||||||
|
Format.fprintf ppf "%Ld B" sz
|
||||||
|
else if sz < shift_left 1L 20 then
|
||||||
|
Format.fprintf ppf "%.2f kiB" (ratio 10)
|
||||||
|
else if sz < shift_left 1L 30 then
|
||||||
|
Format.fprintf ppf "%.2f MiB" (ratio 20)
|
||||||
|
else if sz < shift_left 1L 40 then
|
||||||
|
Format.fprintf ppf "%.2f GiB" (ratio 30)
|
||||||
|
else
|
||||||
|
Format.fprintf ppf "%.2f TiB" (ratio 40)
|
||||||
|
|
||||||
|
let pp ppf stat =
|
||||||
|
Format.fprintf ppf
|
||||||
|
"↗ %a (%a/s) ↘ %a (%a/s)"
|
||||||
|
print_size64 stat.total_sent print_size stat.current_outflow
|
||||||
|
print_size64 stat.total_recv print_size stat.current_inflow
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { total_sent ; total_recv ; current_inflow ; current_outflow } ->
|
||||||
|
(total_sent, total_recv, current_inflow, current_outflow))
|
||||||
|
(fun (total_sent, total_recv, current_inflow, current_outflow) ->
|
||||||
|
{ total_sent ; total_recv ; current_inflow ; current_outflow })
|
||||||
|
(obj4
|
||||||
|
(req "total_sent" int64)
|
||||||
|
(req "total_recv" int64)
|
||||||
|
(req "current_inflow" int31)
|
||||||
|
(req "current_outflow" int31))
|
21
src/lib_base/p2p_stat.mli
Normal file
21
src/lib_base/p2p_stat.mli
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
(** Bandwidth usage statistics *)
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
total_sent : int64 ;
|
||||||
|
total_recv : int64 ;
|
||||||
|
current_inflow : int ;
|
||||||
|
current_outflow : int ;
|
||||||
|
}
|
||||||
|
|
||||||
|
val empty : t
|
||||||
|
val pp : Format.formatter -> t -> unit
|
||||||
|
val encoding : t Data_encoding.t
|
40
src/lib_base/p2p_version.ml
Normal file
40
src/lib_base/p2p_version.ml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
name : string ;
|
||||||
|
major : int ;
|
||||||
|
minor : int ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pp ppf { name ; major ; minor } =
|
||||||
|
Format.fprintf ppf "%s.%d.%d" name major minor
|
||||||
|
|
||||||
|
let encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { name; major; minor } -> (name, major, minor))
|
||||||
|
(fun (name, major, minor) -> { name; major; minor })
|
||||||
|
(obj3
|
||||||
|
(req "name" string)
|
||||||
|
(req "major" int8)
|
||||||
|
(req "minor" int8))
|
||||||
|
|
||||||
|
(* the common version for a pair of peers, if any, is the maximum one,
|
||||||
|
in lexicographic order *)
|
||||||
|
let common la lb =
|
||||||
|
let la = List.sort (fun l r -> compare r l) la in
|
||||||
|
let lb = List.sort (fun l r -> compare r l) lb in
|
||||||
|
let rec find = function
|
||||||
|
| [], _ | _, [] -> None
|
||||||
|
| ((a :: ta) as la), ((b :: tb) as lb) ->
|
||||||
|
if a = b then Some a
|
||||||
|
else if a < b then find (ta, lb)
|
||||||
|
else find (la, tb)
|
||||||
|
in find (la, lb)
|
22
src/lib_base/p2p_version.mli
Normal file
22
src/lib_base/p2p_version.mli
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
(**************************************************************************)
|
||||||
|
(* *)
|
||||||
|
(* Copyright (c) 2014 - 2017. *)
|
||||||
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
||||||
|
(* *)
|
||||||
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
||||||
|
(* *)
|
||||||
|
(**************************************************************************)
|
||||||
|
|
||||||
|
(** Protocol version *)
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
name : string ;
|
||||||
|
major : int ;
|
||||||
|
minor : int ;
|
||||||
|
}
|
||||||
|
(** Type of a protocol version. *)
|
||||||
|
|
||||||
|
val pp : Format.formatter -> t -> unit
|
||||||
|
val encoding : t Data_encoding.t
|
||||||
|
val common : t list -> t list -> t option
|
||||||
|
|
@ -24,6 +24,14 @@ module T = struct
|
|||||||
let incr_sign = res >= a in
|
let incr_sign = res >= a in
|
||||||
if sign = incr_sign then res else invalid_arg "Time.add" ;;
|
if sign = incr_sign then res else invalid_arg "Time.add" ;;
|
||||||
|
|
||||||
|
let recent a1 a2 =
|
||||||
|
match a1, a2 with
|
||||||
|
| (None, None) -> None
|
||||||
|
| (None, (Some _ as a))
|
||||||
|
| (Some _ as a, None) -> a
|
||||||
|
| (Some (_, t1), Some (_, t2)) ->
|
||||||
|
if compare t1 t2 < 0 then a2 else a1
|
||||||
|
|
||||||
let hash = to_int
|
let hash = to_int
|
||||||
let (=) = equal
|
let (=) = equal
|
||||||
let (<>) x y = compare x y <> 0
|
let (<>) x y = compare x y <> 0
|
||||||
|
@ -56,3 +56,6 @@ val timed_encoding : 'a Data_encoding.t -> 'a timed_data Data_encoding.t
|
|||||||
module Set : Set.S with type elt = t
|
module Set : Set.S with type elt = t
|
||||||
module Map : Map.S with type key = t
|
module Map : Map.S with type key = t
|
||||||
module Table : Hashtbl.S with type key = t
|
module Table : Hashtbl.S with type key = t
|
||||||
|
|
||||||
|
val recent :
|
||||||
|
('a * t) option -> ('a * t) option -> ('a * t) option
|
||||||
|
@ -44,5 +44,13 @@ module Preapply_result = Preapply_result
|
|||||||
module Block_locator = Block_locator
|
module Block_locator = Block_locator
|
||||||
module Mempool = Mempool
|
module Mempool = Mempool
|
||||||
|
|
||||||
|
module P2p_addr = P2p_addr
|
||||||
|
module P2p_identity = P2p_identity
|
||||||
|
module P2p_peer = P2p_peer
|
||||||
|
module P2p_point = P2p_point
|
||||||
|
module P2p_connection = P2p_connection
|
||||||
|
module P2p_stat = P2p_stat
|
||||||
|
module P2p_version = P2p_version
|
||||||
|
|
||||||
include Utils.Infix
|
include Utils.Infix
|
||||||
include Error_monad
|
include Error_monad
|
||||||
|
@ -42,5 +42,13 @@ module Operation_list_list_hash = Operation_list_list_hash
|
|||||||
module Context_hash = Context_hash
|
module Context_hash = Context_hash
|
||||||
module Protocol_hash = Protocol_hash
|
module Protocol_hash = Protocol_hash
|
||||||
|
|
||||||
|
module P2p_addr = P2p_addr
|
||||||
|
module P2p_identity = P2p_identity
|
||||||
|
module P2p_peer = P2p_peer
|
||||||
|
module P2p_point = P2p_point
|
||||||
|
module P2p_connection = P2p_connection
|
||||||
|
module P2p_stat = P2p_stat
|
||||||
|
module P2p_version = P2p_version
|
||||||
|
|
||||||
include (module type of (struct include Utils.Infix end))
|
include (module type of (struct include Utils.Infix end))
|
||||||
include (module type of (struct include Error_monad end))
|
include (module type of (struct include Error_monad end))
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
|
|
||||||
let group =
|
let group =
|
||||||
{ Cli_entries.name = "network" ;
|
{ Cli_entries.name = "network" ;
|
||||||
title = "Commands for monitoring and controlling network state" }
|
title = "Commands for monitoring and controlling network state" }
|
||||||
@ -23,47 +21,47 @@ let commands () = [
|
|||||||
Client_node_rpcs.Network.peers cctxt >>=? fun peers ->
|
Client_node_rpcs.Network.peers cctxt >>=? fun peers ->
|
||||||
Client_node_rpcs.Network.points cctxt >>=? fun points ->
|
Client_node_rpcs.Network.points cctxt >>=? fun points ->
|
||||||
cctxt#message "GLOBAL STATS" >>= fun () ->
|
cctxt#message "GLOBAL STATS" >>= fun () ->
|
||||||
cctxt#message " %a" Stat.pp stat >>= fun () ->
|
cctxt#message " %a" P2p_stat.pp stat >>= fun () ->
|
||||||
cctxt#message "CONNECTIONS" >>= fun () ->
|
cctxt#message "CONNECTIONS" >>= fun () ->
|
||||||
let incoming, outgoing =
|
let incoming, outgoing =
|
||||||
List.partition (fun c -> c.Connection_info.incoming) conns in
|
List.partition (fun c -> c.P2p_connection.Info.incoming) conns in
|
||||||
Lwt_list.iter_s begin fun conn ->
|
Lwt_list.iter_s begin fun conn ->
|
||||||
cctxt#message " %a" Connection_info.pp conn
|
cctxt#message " %a" P2p_connection.Info.pp conn
|
||||||
end incoming >>= fun () ->
|
end incoming >>= fun () ->
|
||||||
Lwt_list.iter_s begin fun conn ->
|
Lwt_list.iter_s begin fun conn ->
|
||||||
cctxt#message " %a" Connection_info.pp conn
|
cctxt#message " %a" P2p_connection.Info.pp conn
|
||||||
end outgoing >>= fun () ->
|
end outgoing >>= fun () ->
|
||||||
cctxt#message "KNOWN PEERS" >>= fun () ->
|
cctxt#message "KNOWN PEERS" >>= fun () ->
|
||||||
Lwt_list.iter_s begin fun (p, pi) ->
|
Lwt_list.iter_s begin fun (p, pi) ->
|
||||||
cctxt#message " %a %.0f %a %a %s"
|
cctxt#message " %a %.0f %a %a %s"
|
||||||
Peer_state.pp_digram pi.Peer_info.state
|
P2p_peer.State.pp_digram pi.P2p_peer.Info.state
|
||||||
pi.score
|
pi.score
|
||||||
Peer_id.pp p
|
P2p_peer.Id.pp p
|
||||||
Stat.pp pi.stat
|
P2p_stat.pp pi.stat
|
||||||
(if pi.trusted then "★" else " ")
|
(if pi.trusted then "★" else " ")
|
||||||
end peers >>= fun () ->
|
end peers >>= fun () ->
|
||||||
cctxt#message "KNOWN POINTS" >>= fun () ->
|
cctxt#message "KNOWN POINTS" >>= fun () ->
|
||||||
Lwt_list.iter_s begin fun (p, pi) ->
|
Lwt_list.iter_s begin fun (p, pi) ->
|
||||||
match pi.Point_info.state with
|
match pi.P2p_point.Info.state with
|
||||||
| Running peer_id ->
|
| Running peer_id ->
|
||||||
cctxt#message " %a %a %a %s"
|
cctxt#message " %a %a %a %s"
|
||||||
Point_state.pp_digram pi.state
|
P2p_point.State.pp_digram pi.state
|
||||||
Point.pp p
|
P2p_point.Id.pp p
|
||||||
Peer_id.pp peer_id
|
P2p_peer.Id.pp peer_id
|
||||||
(if pi.trusted then "★" else " ")
|
(if pi.trusted then "★" else " ")
|
||||||
| _ ->
|
| _ ->
|
||||||
match pi.last_seen with
|
match pi.last_seen with
|
||||||
| Some (peer_id, ts) ->
|
| Some (peer_id, ts) ->
|
||||||
cctxt#message " %a %a (last seen: %a %a) %s"
|
cctxt#message " %a %a (last seen: %a %a) %s"
|
||||||
Point_state.pp_digram pi.state
|
P2p_point.State.pp_digram pi.state
|
||||||
Point.pp p
|
P2p_point.Id.pp p
|
||||||
Peer_id.pp peer_id
|
P2p_peer.Id.pp peer_id
|
||||||
Time.pp_hum ts
|
Time.pp_hum ts
|
||||||
(if pi.trusted then "★" else " ")
|
(if pi.trusted then "★" else " ")
|
||||||
| None ->
|
| None ->
|
||||||
cctxt#message " %a %a %s"
|
cctxt#message " %a %a %s"
|
||||||
Point_state.pp_digram pi.state
|
P2p_point.State.pp_digram pi.state
|
||||||
Point.pp p
|
P2p_point.Id.pp p
|
||||||
(if pi.trusted then "★" else " ")
|
(if pi.trusted then "★" else " ")
|
||||||
end points >>= fun () ->
|
end points >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
@ -155,19 +155,17 @@ val bootstrapped:
|
|||||||
|
|
||||||
module Network : sig
|
module Network : sig
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
|
|
||||||
val stat:
|
val stat:
|
||||||
#Client_rpcs.ctxt -> Stat.t tzresult Lwt.t
|
#Client_rpcs.ctxt -> P2p_stat.t tzresult Lwt.t
|
||||||
|
|
||||||
val connections:
|
val connections:
|
||||||
#Client_rpcs.ctxt -> Connection_info.t list tzresult Lwt.t
|
#Client_rpcs.ctxt -> P2p_connection.Info.t list tzresult Lwt.t
|
||||||
|
|
||||||
val peers:
|
val peers:
|
||||||
#Client_rpcs.ctxt -> (Peer_id.t * P2p_types.Peer_info.t) list tzresult Lwt.t
|
#Client_rpcs.ctxt -> (P2p_peer.Id.t * P2p_peer.Info.t) list tzresult Lwt.t
|
||||||
|
|
||||||
val points:
|
val points:
|
||||||
#Client_rpcs.ctxt -> (Point.t * P2p_types.Point_info.t) list tzresult Lwt.t
|
#Client_rpcs.ctxt -> (P2p_point.Id.t * P2p_point.Info.t) list tzresult Lwt.t
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -7,17 +7,15 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
include P2p_types
|
|
||||||
|
|
||||||
include Logging.Make(struct let name = "p2p" end)
|
include Logging.Make(struct let name = "p2p" end)
|
||||||
|
|
||||||
type 'meta meta_config = 'meta P2p_connection_pool.meta_config = {
|
type 'meta meta_config = 'meta P2p_pool.meta_config = {
|
||||||
encoding : 'meta Data_encoding.t;
|
encoding : 'meta Data_encoding.t;
|
||||||
initial : 'meta;
|
initial : 'meta;
|
||||||
score : 'meta -> float
|
score : 'meta -> float
|
||||||
}
|
}
|
||||||
|
|
||||||
type 'msg app_message_encoding = 'msg P2p_connection_pool.encoding =
|
type 'msg app_message_encoding = 'msg P2p_pool.encoding =
|
||||||
Encoding : {
|
Encoding : {
|
||||||
tag: int ;
|
tag: int ;
|
||||||
encoding: 'a Data_encoding.t ;
|
encoding: 'a Data_encoding.t ;
|
||||||
@ -26,18 +24,18 @@ type 'msg app_message_encoding = 'msg P2p_connection_pool.encoding =
|
|||||||
max_length: int option ;
|
max_length: int option ;
|
||||||
} -> 'msg app_message_encoding
|
} -> 'msg app_message_encoding
|
||||||
|
|
||||||
type 'msg message_config = 'msg P2p_connection_pool.message_config = {
|
type 'msg message_config = 'msg P2p_pool.message_config = {
|
||||||
encoding : 'msg app_message_encoding list ;
|
encoding : 'msg app_message_encoding list ;
|
||||||
versions : Version.t list;
|
versions : P2p_version.t list;
|
||||||
}
|
}
|
||||||
|
|
||||||
type config = {
|
type config = {
|
||||||
listening_port : port option;
|
listening_port : P2p_addr.port option;
|
||||||
listening_addr : addr option;
|
listening_addr : P2p_addr.t option;
|
||||||
trusted_points : Point.t list ;
|
trusted_points : P2p_point.Id.t list ;
|
||||||
peers_file : string ;
|
peers_file : string ;
|
||||||
closed_network : bool ;
|
closed_network : bool ;
|
||||||
identity : Identity.t ;
|
identity : P2p_identity.t ;
|
||||||
proof_of_work_target : Crypto_box.target ;
|
proof_of_work_target : Crypto_box.target ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +85,7 @@ let create_scheduler limits =
|
|||||||
|
|
||||||
let create_connection_pool config limits meta_cfg msg_cfg io_sched =
|
let create_connection_pool config limits meta_cfg msg_cfg io_sched =
|
||||||
let pool_cfg = {
|
let pool_cfg = {
|
||||||
P2p_connection_pool.identity = config.identity ;
|
P2p_pool.identity = config.identity ;
|
||||||
proof_of_work_target = config.proof_of_work_target ;
|
proof_of_work_target = config.proof_of_work_target ;
|
||||||
listening_port = config.listening_port ;
|
listening_port = config.listening_port ;
|
||||||
trusted_points = config.trusted_points ;
|
trusted_points = config.trusted_points ;
|
||||||
@ -109,7 +107,7 @@ let create_connection_pool config limits meta_cfg msg_cfg io_sched =
|
|||||||
}
|
}
|
||||||
in
|
in
|
||||||
let pool =
|
let pool =
|
||||||
P2p_connection_pool.create pool_cfg meta_cfg msg_cfg io_sched in
|
P2p_pool.create pool_cfg meta_cfg msg_cfg io_sched in
|
||||||
pool
|
pool
|
||||||
|
|
||||||
let bounds ~min ~expected ~max =
|
let bounds ~min ~expected ~max =
|
||||||
@ -149,7 +147,7 @@ let may_create_welcome_worker config limits pool =
|
|||||||
port >>= fun w ->
|
port >>= fun w ->
|
||||||
Lwt.return (Some w)
|
Lwt.return (Some w)
|
||||||
|
|
||||||
type ('msg, 'meta) connection = ('msg, 'meta) P2p_connection_pool.connection
|
type ('msg, 'meta) connection = ('msg, 'meta) P2p_pool.connection
|
||||||
|
|
||||||
module Real = struct
|
module Real = struct
|
||||||
|
|
||||||
@ -157,7 +155,7 @@ module Real = struct
|
|||||||
config: config ;
|
config: config ;
|
||||||
limits: limits ;
|
limits: limits ;
|
||||||
io_sched: P2p_io_scheduler.t ;
|
io_sched: P2p_io_scheduler.t ;
|
||||||
pool: ('msg, 'meta) P2p_connection_pool.t ;
|
pool: ('msg, 'meta) P2p_pool.t ;
|
||||||
discoverer: P2p_discovery.t option ;
|
discoverer: P2p_discovery.t option ;
|
||||||
maintenance: 'meta P2p_maintenance.t ;
|
maintenance: 'meta P2p_maintenance.t ;
|
||||||
welcome: P2p_welcome.t option ;
|
welcome: P2p_welcome.t option ;
|
||||||
@ -193,119 +191,119 @@ module Real = struct
|
|||||||
Lwt_utils.may ~f:P2p_welcome.shutdown net.welcome >>= fun () ->
|
Lwt_utils.may ~f:P2p_welcome.shutdown net.welcome >>= fun () ->
|
||||||
P2p_maintenance.shutdown net.maintenance >>= fun () ->
|
P2p_maintenance.shutdown net.maintenance >>= fun () ->
|
||||||
Lwt_utils.may ~f:P2p_discovery.shutdown net.discoverer >>= fun () ->
|
Lwt_utils.may ~f:P2p_discovery.shutdown net.discoverer >>= fun () ->
|
||||||
P2p_connection_pool.destroy net.pool >>= fun () ->
|
P2p_pool.destroy net.pool >>= fun () ->
|
||||||
P2p_io_scheduler.shutdown ~timeout:3.0 net.io_sched
|
P2p_io_scheduler.shutdown ~timeout:3.0 net.io_sched
|
||||||
|
|
||||||
let connections { pool } () =
|
let connections { pool } () =
|
||||||
P2p_connection_pool.Connection.fold pool
|
P2p_pool.Connection.fold pool
|
||||||
~init:[] ~f:(fun _peer_id c acc -> c :: acc)
|
~init:[] ~f:(fun _peer_id c acc -> c :: acc)
|
||||||
let find_connection { pool } peer_id =
|
let find_connection { pool } peer_id =
|
||||||
P2p_connection_pool.Connection.find_by_peer_id pool peer_id
|
P2p_pool.Connection.find_by_peer_id pool peer_id
|
||||||
let disconnect ?wait conn =
|
let disconnect ?wait conn =
|
||||||
P2p_connection_pool.disconnect ?wait conn
|
P2p_pool.disconnect ?wait conn
|
||||||
let connection_info _net conn =
|
let connection_info _net conn =
|
||||||
P2p_connection_pool.Connection.info conn
|
P2p_pool.Connection.info conn
|
||||||
let connection_stat _net conn =
|
let connection_stat _net conn =
|
||||||
P2p_connection_pool.Connection.stat conn
|
P2p_pool.Connection.stat conn
|
||||||
let global_stat { pool } () =
|
let global_stat { pool } () =
|
||||||
P2p_connection_pool.pool_stat pool
|
P2p_pool.pool_stat pool
|
||||||
let set_metadata { pool } conn meta =
|
let set_metadata { pool } conn meta =
|
||||||
P2p_connection_pool.Peer_ids.set_metadata pool conn meta
|
P2p_pool.Peers.set_metadata pool conn meta
|
||||||
let get_metadata { pool } conn =
|
let get_metadata { pool } conn =
|
||||||
P2p_connection_pool.Peer_ids.get_metadata pool conn
|
P2p_pool.Peers.get_metadata pool conn
|
||||||
|
|
||||||
let recv _net conn =
|
let recv _net conn =
|
||||||
P2p_connection_pool.read conn >>=? fun msg ->
|
P2p_pool.read conn >>=? fun msg ->
|
||||||
lwt_debug "message read from %a"
|
lwt_debug "message read from %a"
|
||||||
Connection_info.pp
|
P2p_connection.Info.pp
|
||||||
(P2p_connection_pool.Connection.info conn) >>= fun () ->
|
(P2p_pool.Connection.info conn) >>= fun () ->
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
let rec recv_any net () =
|
let rec recv_any net () =
|
||||||
let pipes =
|
let pipes =
|
||||||
P2p_connection_pool.Connection.fold
|
P2p_pool.Connection.fold
|
||||||
net.pool ~init:[]
|
net.pool ~init:[]
|
||||||
~f:begin fun _peer_id conn acc ->
|
~f:begin fun _peer_id conn acc ->
|
||||||
(P2p_connection_pool.is_readable conn >>= function
|
(P2p_pool.is_readable conn >>= function
|
||||||
| Ok () -> Lwt.return (Some conn)
|
| Ok () -> Lwt.return (Some conn)
|
||||||
| Error _ -> Lwt_utils.never_ending) :: acc
|
| Error _ -> Lwt_utils.never_ending) :: acc
|
||||||
end in
|
end in
|
||||||
Lwt.pick (
|
Lwt.pick (
|
||||||
( P2p_connection_pool.Pool_event.wait_new_connection net.pool >>= fun () ->
|
( P2p_pool.Pool_event.wait_new_connection net.pool >>= fun () ->
|
||||||
Lwt.return_none )::
|
Lwt.return_none )::
|
||||||
pipes) >>= function
|
pipes) >>= function
|
||||||
| None -> recv_any net ()
|
| None -> recv_any net ()
|
||||||
| Some conn ->
|
| Some conn ->
|
||||||
P2p_connection_pool.read conn >>= function
|
P2p_pool.read conn >>= function
|
||||||
| Ok msg ->
|
| Ok msg ->
|
||||||
lwt_debug "message read from %a"
|
lwt_debug "message read from %a"
|
||||||
Connection_info.pp
|
P2p_connection.Info.pp
|
||||||
(P2p_connection_pool.Connection.info conn) >>= fun () ->
|
(P2p_pool.Connection.info conn) >>= fun () ->
|
||||||
Lwt.return (conn, msg)
|
Lwt.return (conn, msg)
|
||||||
| Error _ ->
|
| Error _ ->
|
||||||
lwt_debug "error reading message from %a"
|
lwt_debug "error reading message from %a"
|
||||||
Connection_info.pp
|
P2p_connection.Info.pp
|
||||||
(P2p_connection_pool.Connection.info conn) >>= fun () ->
|
(P2p_pool.Connection.info conn) >>= fun () ->
|
||||||
Lwt_unix.yield () >>= fun () ->
|
Lwt_unix.yield () >>= fun () ->
|
||||||
recv_any net ()
|
recv_any net ()
|
||||||
|
|
||||||
let send _net conn m =
|
let send _net conn m =
|
||||||
P2p_connection_pool.write conn m >>= function
|
P2p_pool.write conn m >>= function
|
||||||
| Ok () ->
|
| Ok () ->
|
||||||
lwt_debug "message sent to %a"
|
lwt_debug "message sent to %a"
|
||||||
Connection_info.pp
|
P2p_connection.Info.pp
|
||||||
(P2p_connection_pool.Connection.info conn) >>= fun () ->
|
(P2p_pool.Connection.info conn) >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
| Error err ->
|
| Error err ->
|
||||||
lwt_debug "error sending message from %a: %a"
|
lwt_debug "error sending message from %a: %a"
|
||||||
Connection_info.pp
|
P2p_connection.Info.pp
|
||||||
(P2p_connection_pool.Connection.info conn)
|
(P2p_pool.Connection.info conn)
|
||||||
pp_print_error err >>= fun () ->
|
pp_print_error err >>= fun () ->
|
||||||
Lwt.return (Error err)
|
Lwt.return (Error err)
|
||||||
|
|
||||||
let try_send _net conn v =
|
let try_send _net conn v =
|
||||||
match P2p_connection_pool.write_now conn v with
|
match P2p_pool.write_now conn v with
|
||||||
| Ok v ->
|
| Ok v ->
|
||||||
debug "message trysent to %a"
|
debug "message trysent to %a"
|
||||||
Connection_info.pp
|
P2p_connection.Info.pp
|
||||||
(P2p_connection_pool.Connection.info conn) ;
|
(P2p_pool.Connection.info conn) ;
|
||||||
v
|
v
|
||||||
| Error err ->
|
| Error err ->
|
||||||
debug "error trysending message to %a@ %a"
|
debug "error trysending message to %a@ %a"
|
||||||
Connection_info.pp
|
P2p_connection.Info.pp
|
||||||
(P2p_connection_pool.Connection.info conn)
|
(P2p_pool.Connection.info conn)
|
||||||
pp_print_error err ;
|
pp_print_error err ;
|
||||||
false
|
false
|
||||||
|
|
||||||
let broadcast { pool } msg =
|
let broadcast { pool } msg =
|
||||||
P2p_connection_pool.write_all pool msg ;
|
P2p_pool.write_all pool msg ;
|
||||||
debug "message broadcasted"
|
debug "message broadcasted"
|
||||||
|
|
||||||
let fold_connections { pool } ~init ~f =
|
let fold_connections { pool } ~init ~f =
|
||||||
P2p_connection_pool.Connection.fold pool ~init ~f
|
P2p_pool.Connection.fold pool ~init ~f
|
||||||
|
|
||||||
let iter_connections { pool } f =
|
let iter_connections { pool } f =
|
||||||
P2p_connection_pool.Connection.fold pool
|
P2p_pool.Connection.fold pool
|
||||||
~init:()
|
~init:()
|
||||||
~f:(fun gid conn () -> f gid conn)
|
~f:(fun gid conn () -> f gid conn)
|
||||||
|
|
||||||
let on_new_connection { pool } f =
|
let on_new_connection { pool } f =
|
||||||
P2p_connection_pool.on_new_connection pool f
|
P2p_pool.on_new_connection pool f
|
||||||
|
|
||||||
let pool { pool } = pool
|
let pool { pool } = pool
|
||||||
end
|
end
|
||||||
|
|
||||||
module Fake = struct
|
module Fake = struct
|
||||||
|
|
||||||
let id = Identity.generate (Crypto_box.make_target 0.)
|
let id = P2p_identity.generate (Crypto_box.make_target 0.)
|
||||||
let empty_stat = {
|
let empty_stat = {
|
||||||
Stat.total_sent = 0L ;
|
P2p_stat.total_sent = 0L ;
|
||||||
total_recv = 0L ;
|
total_recv = 0L ;
|
||||||
current_inflow = 0 ;
|
current_inflow = 0 ;
|
||||||
current_outflow = 0 ;
|
current_outflow = 0 ;
|
||||||
}
|
}
|
||||||
let connection_info = {
|
let connection_info = {
|
||||||
Connection_info.incoming = false ;
|
P2p_connection.Info.incoming = false ;
|
||||||
peer_id = id.peer_id ;
|
peer_id = id.peer_id ;
|
||||||
id_point = (Ipaddr.V6.unspecified, None) ;
|
id_point = (Ipaddr.V6.unspecified, None) ;
|
||||||
remote_socket_port = 0 ;
|
remote_socket_port = 0 ;
|
||||||
@ -315,28 +313,28 @@ module Fake = struct
|
|||||||
end
|
end
|
||||||
|
|
||||||
type ('msg, 'meta) t = {
|
type ('msg, 'meta) t = {
|
||||||
peer_id : Peer_id.t ;
|
peer_id : P2p_peer.Id.t ;
|
||||||
maintain : unit -> unit Lwt.t ;
|
maintain : unit -> unit Lwt.t ;
|
||||||
roll : unit -> unit Lwt.t ;
|
roll : unit -> unit Lwt.t ;
|
||||||
shutdown : unit -> unit Lwt.t ;
|
shutdown : unit -> unit Lwt.t ;
|
||||||
connections : unit -> ('msg, 'meta) connection list ;
|
connections : unit -> ('msg, 'meta) connection list ;
|
||||||
find_connection : Peer_id.t -> ('msg, 'meta) connection option ;
|
find_connection : P2p_peer.Id.t -> ('msg, 'meta) connection option ;
|
||||||
disconnect : ?wait:bool -> ('msg, 'meta) connection -> unit Lwt.t ;
|
disconnect : ?wait:bool -> ('msg, 'meta) connection -> unit Lwt.t ;
|
||||||
connection_info : ('msg, 'meta) connection -> Connection_info.t ;
|
connection_info : ('msg, 'meta) connection -> P2p_connection.Info.t ;
|
||||||
connection_stat : ('msg, 'meta) connection -> Stat.t ;
|
connection_stat : ('msg, 'meta) connection -> P2p_stat.t ;
|
||||||
global_stat : unit -> Stat.t ;
|
global_stat : unit -> P2p_stat.t ;
|
||||||
get_metadata : Peer_id.t -> 'meta ;
|
get_metadata : P2p_peer.Id.t -> 'meta ;
|
||||||
set_metadata : Peer_id.t -> 'meta -> unit ;
|
set_metadata : P2p_peer.Id.t -> 'meta -> unit ;
|
||||||
recv : ('msg, 'meta) connection -> 'msg tzresult Lwt.t ;
|
recv : ('msg, 'meta) connection -> 'msg tzresult Lwt.t ;
|
||||||
recv_any : unit -> (('msg, 'meta) connection * 'msg) Lwt.t ;
|
recv_any : unit -> (('msg, 'meta) connection * 'msg) Lwt.t ;
|
||||||
send : ('msg, 'meta) connection -> 'msg -> unit tzresult Lwt.t ;
|
send : ('msg, 'meta) connection -> 'msg -> unit tzresult Lwt.t ;
|
||||||
try_send : ('msg, 'meta) connection -> 'msg -> bool ;
|
try_send : ('msg, 'meta) connection -> 'msg -> bool ;
|
||||||
broadcast : 'msg -> unit ;
|
broadcast : 'msg -> unit ;
|
||||||
pool : ('msg, 'meta) P2p_connection_pool.t option ;
|
pool : ('msg, 'meta) P2p_pool.t option ;
|
||||||
fold_connections :
|
fold_connections :
|
||||||
'a. init:'a -> f:(Peer_id.t -> ('msg, 'meta) connection -> 'a -> 'a) -> 'a ;
|
'a. init:'a -> f:(P2p_peer.Id.t -> ('msg, 'meta) connection -> 'a -> 'a) -> 'a ;
|
||||||
iter_connections : (Peer_id.t -> ('msg, 'meta) connection -> unit) -> unit ;
|
iter_connections : (P2p_peer.Id.t -> ('msg, 'meta) connection -> unit) -> unit ;
|
||||||
on_new_connection : (Peer_id.t -> ('msg, 'meta) connection -> unit) -> unit ;
|
on_new_connection : (P2p_peer.Id.t -> ('msg, 'meta) connection -> unit) -> unit ;
|
||||||
}
|
}
|
||||||
type ('msg, 'meta) net = ('msg, 'meta) t
|
type ('msg, 'meta) net = ('msg, 'meta) t
|
||||||
|
|
||||||
@ -374,7 +372,7 @@ let check_limits =
|
|||||||
begin
|
begin
|
||||||
match c.binary_chunks_size with
|
match c.binary_chunks_size with
|
||||||
| None -> return ()
|
| None -> return ()
|
||||||
| Some size -> P2p_connection.check_binary_chunks_size size
|
| Some size -> P2p_socket.check_binary_chunks_size size
|
||||||
end >>=? fun () ->
|
end >>=? fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
@ -420,7 +418,7 @@ let faked_network meta_config = {
|
|||||||
set_metadata = (fun _ _ -> ()) ;
|
set_metadata = (fun _ _ -> ()) ;
|
||||||
recv = (fun _ -> Lwt_utils.never_ending) ;
|
recv = (fun _ -> Lwt_utils.never_ending) ;
|
||||||
recv_any = (fun () -> Lwt_utils.never_ending) ;
|
recv_any = (fun () -> Lwt_utils.never_ending) ;
|
||||||
send = (fun _ _ -> fail P2p_connection_pool.Connection_closed) ;
|
send = (fun _ _ -> fail P2p_pool.Connection_closed) ;
|
||||||
try_send = (fun _ _ -> false) ;
|
try_send = (fun _ _ -> false) ;
|
||||||
fold_connections = (fun ~init ~f:_ -> init) ;
|
fold_connections = (fun ~init ~f:_ -> init) ;
|
||||||
iter_connections = (fun _f -> ()) ;
|
iter_connections = (fun _f -> ()) ;
|
||||||
@ -451,35 +449,33 @@ let iter_connections net = net.iter_connections
|
|||||||
let on_new_connection net = net.on_new_connection
|
let on_new_connection net = net.on_new_connection
|
||||||
|
|
||||||
module Raw = struct
|
module Raw = struct
|
||||||
type 'a t = 'a P2p_connection_pool.Message.t =
|
type 'a t = 'a P2p_pool.Message.t =
|
||||||
| Bootstrap
|
| Bootstrap
|
||||||
| Advertise of P2p_types.Point.t list
|
| Advertise of P2p_point.Id.t list
|
||||||
| Swap_request of Point.t * Peer_id.t
|
| Swap_request of P2p_point.Id.t * P2p_peer.Id.t
|
||||||
| Swap_ack of Point.t * Peer_id.t
|
| Swap_ack of P2p_point.Id.t * P2p_peer.Id.t
|
||||||
| Message of 'a
|
| Message of 'a
|
||||||
| Disconnect
|
| Disconnect
|
||||||
let encoding = P2p_connection_pool.Message.encoding
|
let encoding = P2p_pool.Message.encoding
|
||||||
end
|
end
|
||||||
|
|
||||||
module RPC = struct
|
module RPC = struct
|
||||||
|
|
||||||
let stat net =
|
let stat net =
|
||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> Stat.empty
|
| None -> P2p_stat.empty
|
||||||
| Some pool -> P2p_connection_pool.pool_stat pool
|
| Some pool -> P2p_pool.pool_stat pool
|
||||||
|
|
||||||
module Event = P2p_connection_pool.Log_event
|
|
||||||
|
|
||||||
let watch net =
|
let watch net =
|
||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> Lwt_watcher.create_fake_stream ()
|
| None -> Lwt_watcher.create_fake_stream ()
|
||||||
| Some pool -> P2p_connection_pool.watch pool
|
| Some pool -> P2p_pool.watch pool
|
||||||
|
|
||||||
let connect net point timeout =
|
let connect net point timeout =
|
||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> failwith "fake net"
|
| None -> failwith "fake net"
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
P2p_connection_pool.connect ~timeout pool point >>|? ignore
|
P2p_pool.connect ~timeout pool point >>|? ignore
|
||||||
|
|
||||||
module Connection = struct
|
module Connection = struct
|
||||||
let info net peer_id =
|
let info net peer_id =
|
||||||
@ -487,46 +483,45 @@ module RPC = struct
|
|||||||
| None -> None
|
| None -> None
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
Option.map
|
Option.map
|
||||||
(P2p_connection_pool.Connection.find_by_peer_id pool peer_id)
|
(P2p_pool.Connection.find_by_peer_id pool peer_id)
|
||||||
~f:P2p_connection_pool.Connection.info
|
~f:P2p_pool.Connection.info
|
||||||
|
|
||||||
let kick net peer_id wait =
|
let kick net peer_id wait =
|
||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> Lwt.return_unit
|
| None -> Lwt.return_unit
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
match P2p_connection_pool.Connection.find_by_peer_id pool peer_id with
|
match P2p_pool.Connection.find_by_peer_id pool peer_id with
|
||||||
| None -> Lwt.return_unit
|
| None -> Lwt.return_unit
|
||||||
| Some conn -> P2p_connection_pool.disconnect ~wait conn
|
| Some conn -> P2p_pool.disconnect ~wait conn
|
||||||
|
|
||||||
let list net =
|
let list net =
|
||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> []
|
| None -> []
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
P2p_connection_pool.Connection.fold
|
P2p_pool.Connection.fold
|
||||||
pool ~init:[]
|
pool ~init:[]
|
||||||
~f:begin fun _peer_id c acc ->
|
~f:begin fun _peer_id c acc ->
|
||||||
P2p_connection_pool.Connection.info c :: acc
|
P2p_pool.Connection.info c :: acc
|
||||||
end
|
end
|
||||||
|
|
||||||
let count net =
|
let count net =
|
||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> 0
|
| None -> 0
|
||||||
| Some pool -> P2p_connection_pool.active_connections pool
|
| Some pool -> P2p_pool.active_connections pool
|
||||||
end
|
end
|
||||||
|
|
||||||
module Point = struct
|
module Point = struct
|
||||||
|
|
||||||
open P2p_types.Point_info
|
open P2p_point.Info
|
||||||
open P2p_types.Point_state
|
open P2p_point.State
|
||||||
|
|
||||||
let info_of_point_info i =
|
let info_of_point_info i =
|
||||||
let open P2p_connection_pool_types in
|
let state = match P2p_point.Pool_state.get i with
|
||||||
let state = match Point_info.State.get i with
|
|
||||||
| Requested _ -> Requested
|
| Requested _ -> Requested
|
||||||
| Accepted { current_peer_id ; _ } -> Accepted current_peer_id
|
| Accepted { current_peer_id ; _ } -> Accepted current_peer_id
|
||||||
| Running { current_peer_id ; _ } -> Running current_peer_id
|
| Running { current_peer_id ; _ } -> Running current_peer_id
|
||||||
| Disconnected -> Disconnected in
|
| Disconnected -> Disconnected in
|
||||||
Point_info.{
|
P2p_point.Pool_info.{
|
||||||
trusted = trusted i ;
|
trusted = trusted i ;
|
||||||
state ;
|
state ;
|
||||||
greylisted_until = greylisted_until i ;
|
greylisted_until = greylisted_until i ;
|
||||||
@ -543,21 +538,19 @@ module RPC = struct
|
|||||||
| None -> None
|
| None -> None
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
Option.map
|
Option.map
|
||||||
(P2p_connection_pool.Points.info pool point)
|
(P2p_pool.Points.info pool point)
|
||||||
~f:info_of_point_info
|
~f:info_of_point_info
|
||||||
|
|
||||||
module Event = P2p_connection_pool_types.Point_info.Event
|
|
||||||
|
|
||||||
let events ?(max=max_int) ?(rev=false) net point =
|
let events ?(max=max_int) ?(rev=false) net point =
|
||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> []
|
| None -> []
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
Option.unopt_map
|
Option.unopt_map
|
||||||
(P2p_connection_pool.Points.info pool point)
|
(P2p_pool.Points.info pool point)
|
||||||
~default:[]
|
~default:[]
|
||||||
~f:begin fun pi ->
|
~f:begin fun pi ->
|
||||||
let evts =
|
let evts =
|
||||||
P2p_connection_pool_types.Point_info.fold_events
|
P2p_point.Pool_event.fold
|
||||||
pi ~init:[] ~f:(fun a e -> e :: a) in
|
pi ~init:[] ~f:(fun a e -> e :: a) in
|
||||||
(if rev then List.rev_sub else List.sub) evts max
|
(if rev then List.rev_sub else List.sub) evts max
|
||||||
end
|
end
|
||||||
@ -566,15 +559,15 @@ module RPC = struct
|
|||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> raise Not_found
|
| None -> raise Not_found
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
match P2p_connection_pool.Points.info pool point with
|
match P2p_pool.Points.info pool point with
|
||||||
| None -> raise Not_found
|
| None -> raise Not_found
|
||||||
| Some pi -> P2p_connection_pool_types.Point_info.watch pi
|
| Some pi -> P2p_point.Pool_event.watch pi
|
||||||
|
|
||||||
let list ?(restrict=[]) net =
|
let list ?(restrict=[]) net =
|
||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> []
|
| None -> []
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
P2p_connection_pool.Points.fold_known
|
P2p_pool.Points.fold_known
|
||||||
pool ~init:[]
|
pool ~init:[]
|
||||||
~f:begin fun point i a ->
|
~f:begin fun point i a ->
|
||||||
let info = info_of_point_info i in
|
let info = info_of_point_info i in
|
||||||
@ -588,24 +581,22 @@ module RPC = struct
|
|||||||
|
|
||||||
module Peer_id = struct
|
module Peer_id = struct
|
||||||
|
|
||||||
open P2p_types.Peer_info
|
open P2p_peer.Info
|
||||||
open P2p_types.Peer_state
|
open P2p_peer.State
|
||||||
|
|
||||||
let info_of_peer_info pool i =
|
let info_of_peer_info pool i =
|
||||||
let open P2p_connection_pool in
|
let state, id_point = match P2p_peer.Pool_state.get i with
|
||||||
let open P2p_connection_pool_types in
|
|
||||||
let state, id_point = match Peer_info.State.get i with
|
|
||||||
| Accepted { current_point } -> Accepted, Some current_point
|
| Accepted { current_point } -> Accepted, Some current_point
|
||||||
| Running { current_point } -> Running, Some current_point
|
| Running { current_point } -> Running, Some current_point
|
||||||
| Disconnected -> Disconnected, None
|
| Disconnected -> Disconnected, None
|
||||||
in
|
in
|
||||||
let peer_id = Peer_info.peer_id i in
|
let peer_id = P2p_peer.Pool_info.peer_id i in
|
||||||
let score = Peer_ids.get_score pool peer_id in
|
let score = P2p_pool.Peers.get_score pool peer_id in
|
||||||
let stat =
|
let stat =
|
||||||
match P2p_connection_pool.Connection.find_by_peer_id pool peer_id with
|
match P2p_pool.Connection.find_by_peer_id pool peer_id with
|
||||||
| None -> Stat.empty
|
| None -> P2p_stat.empty
|
||||||
| Some conn -> P2p_connection_pool.Connection.stat conn
|
| Some conn -> P2p_pool.Connection.stat conn
|
||||||
in Peer_info.{
|
in P2p_peer.Pool_info.{
|
||||||
score ;
|
score ;
|
||||||
trusted = trusted i ;
|
trusted = trusted i ;
|
||||||
state ;
|
state ;
|
||||||
@ -623,7 +614,7 @@ module RPC = struct
|
|||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> None
|
| None -> None
|
||||||
| Some pool -> begin
|
| Some pool -> begin
|
||||||
match P2p_connection_pool.Peer_ids.info pool peer_id with
|
match P2p_pool.Peers.info pool peer_id with
|
||||||
| Some info -> Some (info_of_peer_info pool info)
|
| Some info -> Some (info_of_peer_info pool info)
|
||||||
| None -> None
|
| None -> None
|
||||||
end
|
end
|
||||||
@ -633,10 +624,10 @@ module RPC = struct
|
|||||||
| None -> []
|
| None -> []
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
Option.unopt_map
|
Option.unopt_map
|
||||||
(P2p_connection_pool.Peer_ids.info pool peer_id)
|
(P2p_pool.Peers.info pool peer_id)
|
||||||
~default:[]
|
~default:[]
|
||||||
~f:begin fun gi ->
|
~f:begin fun gi ->
|
||||||
let evts = P2p_connection_pool_types.Peer_info.fold_events gi
|
let evts = P2p_peer.Pool_event.fold gi
|
||||||
~init:[] ~f:(fun a e -> e :: a) in
|
~init:[] ~f:(fun a e -> e :: a) in
|
||||||
(if rev then List.rev_sub else List.sub) evts max
|
(if rev then List.rev_sub else List.sub) evts max
|
||||||
end
|
end
|
||||||
@ -645,15 +636,15 @@ module RPC = struct
|
|||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> raise Not_found
|
| None -> raise Not_found
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
match P2p_connection_pool.Peer_ids.info pool peer_id with
|
match P2p_pool.Peers.info pool peer_id with
|
||||||
| None -> raise Not_found
|
| None -> raise Not_found
|
||||||
| Some gi -> P2p_connection_pool_types.Peer_info.watch gi
|
| Some gi -> P2p_peer.Pool_event.watch gi
|
||||||
|
|
||||||
let list ?(restrict=[]) net =
|
let list ?(restrict=[]) net =
|
||||||
match net.pool with
|
match net.pool with
|
||||||
| None -> []
|
| None -> []
|
||||||
| Some pool ->
|
| Some pool ->
|
||||||
P2p_connection_pool.Peer_ids.fold_known pool
|
P2p_pool.Peers.fold_known pool
|
||||||
~init:[]
|
~init:[]
|
||||||
~f:begin fun peer_id i a ->
|
~f:begin fun peer_id i a ->
|
||||||
let info = info_of_peer_info pool i in
|
let info = info_of_peer_info pool i in
|
||||||
|
@ -9,28 +9,6 @@
|
|||||||
|
|
||||||
(** Tezos Shell Net - Low level API for the Gossip network *)
|
(** Tezos Shell Net - Low level API for the Gossip network *)
|
||||||
|
|
||||||
(** A peer connection address *)
|
|
||||||
type addr = Ipaddr.V6.t
|
|
||||||
|
|
||||||
(** A peer connection port *)
|
|
||||||
type port = int
|
|
||||||
|
|
||||||
(** A p2p protocol version *)
|
|
||||||
module Version = P2p_types.Version
|
|
||||||
|
|
||||||
(** A global identifier for a peer, a.k.a. an identity *)
|
|
||||||
module Peer_id = P2p_types.Peer_id
|
|
||||||
|
|
||||||
module Identity = P2p_types.Identity
|
|
||||||
|
|
||||||
module Point = P2p_types.Point
|
|
||||||
|
|
||||||
module Id_point = P2p_types.Id_point
|
|
||||||
|
|
||||||
module Connection_info = P2p_types.Connection_info
|
|
||||||
|
|
||||||
module Stat = P2p_types.Stat
|
|
||||||
|
|
||||||
type 'meta meta_config = {
|
type 'meta meta_config = {
|
||||||
encoding : 'meta Data_encoding.t;
|
encoding : 'meta Data_encoding.t;
|
||||||
initial : 'meta;
|
initial : 'meta;
|
||||||
@ -47,21 +25,21 @@ type 'msg app_message_encoding = Encoding : {
|
|||||||
|
|
||||||
type 'msg message_config = {
|
type 'msg message_config = {
|
||||||
encoding : 'msg app_message_encoding list ;
|
encoding : 'msg app_message_encoding list ;
|
||||||
versions : Version.t list;
|
versions : P2p_version.t list;
|
||||||
}
|
}
|
||||||
|
|
||||||
(** Network configuration *)
|
(** Network configuration *)
|
||||||
type config = {
|
type config = {
|
||||||
|
|
||||||
listening_port : port option;
|
listening_port : P2p_addr.port option;
|
||||||
(** Tells if incoming connections accepted, precising the TCP port
|
(** Tells if incoming connections accepted, precising the TCP port
|
||||||
on which the peer can be reached *)
|
on which the peer can be reached *)
|
||||||
|
|
||||||
listening_addr : addr option;
|
listening_addr : P2p_addr.t option;
|
||||||
(** When incoming connections are accepted, precising on which
|
(** When incoming connections are accepted, precising on which
|
||||||
IP adddress the node listen (default: [[::]]). *)
|
IP adddress the node listen (default: [[::]]). *)
|
||||||
|
|
||||||
trusted_points : Point.t list ;
|
trusted_points : P2p_point.Id.t list ;
|
||||||
(** List of hard-coded known peers to bootstrap the network from. *)
|
(** List of hard-coded known peers to bootstrap the network from. *)
|
||||||
|
|
||||||
peers_file : string ;
|
peers_file : string ;
|
||||||
@ -72,7 +50,7 @@ type config = {
|
|||||||
(** If [true], the only accepted connections are from peers whose
|
(** If [true], the only accepted connections are from peers whose
|
||||||
addresses are in [trusted_peers]. *)
|
addresses are in [trusted_peers]. *)
|
||||||
|
|
||||||
identity : Identity.t ;
|
identity : P2p_identity.t ;
|
||||||
(** Cryptographic identity of the peer. *)
|
(** Cryptographic identity of the peer. *)
|
||||||
|
|
||||||
proof_of_work_target : Crypto_box.target ;
|
proof_of_work_target : Crypto_box.target ;
|
||||||
@ -148,7 +126,7 @@ val create :
|
|||||||
'meta meta_config -> 'msg message_config -> ('msg, 'meta) net tzresult Lwt.t
|
'meta meta_config -> 'msg message_config -> ('msg, 'meta) net tzresult Lwt.t
|
||||||
|
|
||||||
(** Return one's peer_id *)
|
(** Return one's peer_id *)
|
||||||
val peer_id : ('msg, 'meta) net -> Peer_id.t
|
val peer_id : ('msg, 'meta) net -> P2p_peer.Id.t
|
||||||
|
|
||||||
(** A maintenance operation : try and reach the ideal number of peers *)
|
(** A maintenance operation : try and reach the ideal number of peers *)
|
||||||
val maintain : ('msg, 'meta) net -> unit Lwt.t
|
val maintain : ('msg, 'meta) net -> unit Lwt.t
|
||||||
@ -166,23 +144,23 @@ type ('msg, 'meta) connection
|
|||||||
val connections : ('msg, 'meta) net -> ('msg, 'meta) connection list
|
val connections : ('msg, 'meta) net -> ('msg, 'meta) connection list
|
||||||
|
|
||||||
(** Return the active peer with identity [peer_id] *)
|
(** Return the active peer with identity [peer_id] *)
|
||||||
val find_connection : ('msg, 'meta) net -> Peer_id.t -> ('msg, 'meta) connection option
|
val find_connection : ('msg, 'meta) net -> P2p_peer.Id.t -> ('msg, 'meta) connection option
|
||||||
|
|
||||||
(** Access the info of an active peer, if available *)
|
(** Access the info of an active peer, if available *)
|
||||||
val connection_info :
|
val connection_info :
|
||||||
('msg, 'meta) net -> ('msg, 'meta) connection -> Connection_info.t
|
('msg, 'meta) net -> ('msg, 'meta) connection -> P2p_connection.Info.t
|
||||||
val connection_stat :
|
val connection_stat :
|
||||||
('msg, 'meta) net -> ('msg, 'meta) connection -> Stat.t
|
('msg, 'meta) net -> ('msg, 'meta) connection -> P2p_stat.t
|
||||||
|
|
||||||
(** Cleanly closes a connection. *)
|
(** Cleanly closes a connection. *)
|
||||||
val disconnect :
|
val disconnect :
|
||||||
('msg, 'meta) net -> ?wait:bool -> ('msg, 'meta) connection -> unit Lwt.t
|
('msg, 'meta) net -> ?wait:bool -> ('msg, 'meta) connection -> unit Lwt.t
|
||||||
|
|
||||||
val global_stat : ('msg, 'meta) net -> Stat.t
|
val global_stat : ('msg, 'meta) net -> P2p_stat.t
|
||||||
|
|
||||||
(** Accessors for meta information about a global identifier *)
|
(** Accessors for meta information about a global identifier *)
|
||||||
val get_metadata : ('msg, 'meta) net -> Peer_id.t -> 'meta
|
val get_metadata : ('msg, 'meta) net -> P2p_peer.Id.t -> 'meta
|
||||||
val set_metadata : ('msg, 'meta) net -> Peer_id.t -> 'meta -> unit
|
val set_metadata : ('msg, 'meta) net -> P2p_peer.Id.t -> 'meta -> unit
|
||||||
|
|
||||||
(** Wait for a message from a given connection. *)
|
(** Wait for a message from a given connection. *)
|
||||||
val recv :
|
val recv :
|
||||||
@ -207,56 +185,56 @@ val broadcast : ('msg, 'meta) net -> 'msg -> unit
|
|||||||
|
|
||||||
module RPC : sig
|
module RPC : sig
|
||||||
|
|
||||||
val stat : ('msg, 'meta) net -> Stat.t
|
val stat : ('msg, 'meta) net -> P2p_stat.t
|
||||||
|
|
||||||
val watch :
|
val watch :
|
||||||
('msg, 'meta) net ->
|
('msg, 'meta) net ->
|
||||||
P2p_types.Connection_pool_log_event.t Lwt_stream.t * Lwt_watcher.stopper
|
P2p_connection.Pool_event.t Lwt_stream.t * Lwt_watcher.stopper
|
||||||
val connect : ('msg, 'meta) net -> Point.t -> float -> unit tzresult Lwt.t
|
val connect : ('msg, 'meta) net -> P2p_point.Id.t -> float -> unit tzresult Lwt.t
|
||||||
|
|
||||||
module Connection : sig
|
module Connection : sig
|
||||||
val info : ('msg, 'meta) net -> Peer_id.t -> Connection_info.t option
|
val info : ('msg, 'meta) net -> P2p_peer.Id.t -> P2p_connection.Info.t option
|
||||||
val kick : ('msg, 'meta) net -> Peer_id.t -> bool -> unit Lwt.t
|
val kick : ('msg, 'meta) net -> P2p_peer.Id.t -> bool -> unit Lwt.t
|
||||||
val list : ('msg, 'meta) net -> Connection_info.t list
|
val list : ('msg, 'meta) net -> P2p_connection.Info.t list
|
||||||
val count : ('msg, 'meta) net -> int
|
val count : ('msg, 'meta) net -> int
|
||||||
end
|
end
|
||||||
|
|
||||||
module Point : sig
|
module Point : sig
|
||||||
|
|
||||||
val info :
|
val info :
|
||||||
('msg, 'meta) net -> Point.t -> P2p_types.Point_info.t option
|
('msg, 'meta) net -> P2p_point.Id.t -> P2p_point.Info.t option
|
||||||
|
|
||||||
val list :
|
val list :
|
||||||
?restrict: P2p_types.Point_state.t list ->
|
?restrict: P2p_point.State.t list ->
|
||||||
('msg, 'meta) net -> (Point.t * P2p_types.Point_info.t) list
|
('msg, 'meta) net -> (P2p_point.Id.t * P2p_point.Info.t) list
|
||||||
|
|
||||||
val events :
|
val events :
|
||||||
?max:int -> ?rev:bool -> ('msg, 'meta) net -> Point.t ->
|
?max:int -> ?rev:bool -> ('msg, 'meta) net -> P2p_point.Id.t ->
|
||||||
P2p_connection_pool_types.Point_info.Event.t list
|
P2p_point.Pool_event.t list
|
||||||
|
|
||||||
val watch :
|
val watch :
|
||||||
('msg, 'meta) net -> Point.t ->
|
('msg, 'meta) net -> P2p_point.Id.t ->
|
||||||
P2p_connection_pool_types.Point_info.Event.t Lwt_stream.t * Lwt_watcher.stopper
|
P2p_point.Pool_event.t Lwt_stream.t * Lwt_watcher.stopper
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Peer_id : sig
|
module Peer_id : sig
|
||||||
|
|
||||||
val info :
|
val info :
|
||||||
('msg, 'meta) net -> Peer_id.t -> P2p_types.Peer_info.t option
|
('msg, 'meta) net -> P2p_peer.Id.t -> P2p_peer.Info.t option
|
||||||
|
|
||||||
val list :
|
val list :
|
||||||
?restrict: P2p_types.Peer_state.t list ->
|
?restrict: P2p_peer.State.t list ->
|
||||||
('msg, 'meta) net -> (Peer_id.t * P2p_types.Peer_info.t) list
|
('msg, 'meta) net -> (P2p_peer.Id.t * P2p_peer.Info.t) list
|
||||||
|
|
||||||
val events :
|
val events :
|
||||||
?max: int -> ?rev: bool ->
|
?max: int -> ?rev: bool ->
|
||||||
('msg, 'meta) net -> Peer_id.t ->
|
('msg, 'meta) net -> P2p_peer.Id.t ->
|
||||||
P2p_connection_pool_types.Peer_info.Event.t list
|
P2p_peer.Pool_event.t list
|
||||||
|
|
||||||
val watch :
|
val watch :
|
||||||
('msg, 'meta) net -> Peer_id.t ->
|
('msg, 'meta) net -> P2p_peer.Id.t ->
|
||||||
P2p_connection_pool_types.Peer_info.Event.t Lwt_stream.t * Lwt_watcher.stopper
|
P2p_peer.Pool_event.t Lwt_stream.t * Lwt_watcher.stopper
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -264,24 +242,24 @@ end
|
|||||||
|
|
||||||
val fold_connections :
|
val fold_connections :
|
||||||
('msg, 'meta) net ->
|
('msg, 'meta) net ->
|
||||||
init:'a -> f:(Peer_id.t -> ('msg, 'meta) connection -> 'a -> 'a) -> 'a
|
init:'a -> f:(P2p_peer.Id.t -> ('msg, 'meta) connection -> 'a -> 'a) -> 'a
|
||||||
|
|
||||||
val iter_connections :
|
val iter_connections :
|
||||||
('msg, 'meta) net ->
|
('msg, 'meta) net ->
|
||||||
(Peer_id.t -> ('msg, 'meta) connection -> unit) -> unit
|
(P2p_peer.Id.t -> ('msg, 'meta) connection -> unit) -> unit
|
||||||
|
|
||||||
val on_new_connection :
|
val on_new_connection :
|
||||||
('msg, 'meta) net ->
|
('msg, 'meta) net ->
|
||||||
(Peer_id.t -> ('msg, 'meta) connection -> unit) -> unit
|
(P2p_peer.Id.t -> ('msg, 'meta) connection -> unit) -> unit
|
||||||
|
|
||||||
(**/**)
|
(**/**)
|
||||||
|
|
||||||
module Raw : sig
|
module Raw : sig
|
||||||
type 'a t =
|
type 'a t =
|
||||||
| Bootstrap
|
| Bootstrap
|
||||||
| Advertise of P2p_types.Point.t list
|
| Advertise of P2p_point.Id.t list
|
||||||
| Swap_request of Point.t * Peer_id.t
|
| Swap_request of P2p_point.Id.t * P2p_peer.Id.t
|
||||||
| Swap_ack of Point.t * Peer_id.t
|
| Swap_ack of P2p_point.Id.t * P2p_peer.Id.t
|
||||||
| Message of 'a
|
| Message of 'a
|
||||||
| Disconnect
|
| Disconnect
|
||||||
val encoding: 'msg app_message_encoding list -> 'msg t Data_encoding.t
|
val encoding: 'msg app_message_encoding list -> 'msg t Data_encoding.t
|
||||||
|
@ -20,7 +20,7 @@ let inet_addr = Unix.inet_addr_of_string "ff0e::54:455a:3053"
|
|||||||
module Message = struct
|
module Message = struct
|
||||||
|
|
||||||
let encoding =
|
let encoding =
|
||||||
Data_encoding.(tup3 (Fixed.string 10) Peer_id.encoding int16)
|
Data_encoding.(tup3 (Fixed.string 10) P2p_peer.Id.encoding int16)
|
||||||
|
|
||||||
let length = Data_encoding.Binary.fixed_length_exn encoding
|
let length = Data_encoding.Binary.fixed_length_exn encoding
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ let sender sock saddr my_peer_id inco_port cancelation restart =
|
|||||||
Lwt.return_unit)
|
Lwt.return_unit)
|
||||||
(fun exn ->
|
(fun exn ->
|
||||||
lwt_debug "(%a) error broadcasting a discovery request: %a"
|
lwt_debug "(%a) error broadcasting a discovery request: %a"
|
||||||
Peer_id.pp my_peer_id Error_monad.pp (Exn exn)) >>= fun () ->
|
P2p_peer.Id.pp my_peer_id Error_monad.pp (Exn exn)) >>= fun () ->
|
||||||
Lwt.pick
|
Lwt.pick
|
||||||
[ (Lwt_unix.sleep delay >>= fun () -> Lwt.return (Some (delay, n + 1))) ;
|
[ (Lwt_unix.sleep delay >>= fun () -> Lwt.return (Some (delay, n + 1))) ;
|
||||||
(cancelation () >>= fun () -> Lwt.return_none) ;
|
(cancelation () >>= fun () -> Lwt.return_none) ;
|
||||||
@ -100,7 +100,7 @@ module Answerer = struct
|
|||||||
Lwt.catch
|
Lwt.catch
|
||||||
(fun () ->
|
(fun () ->
|
||||||
Lwt_utils.worker
|
Lwt_utils.worker
|
||||||
(Format.asprintf "(%a) discovery answerer" Peer_id.pp my_peer_id)
|
(Format.asprintf "(%a) discovery answerer" P2p_peer.Id.pp my_peer_id)
|
||||||
(fun () -> answerer fd my_peer_id cancelation callback)
|
(fun () -> answerer fd my_peer_id cancelation callback)
|
||||||
cancel)
|
cancel)
|
||||||
(fun exn ->
|
(fun exn ->
|
||||||
@ -118,7 +118,7 @@ let discovery_sender =
|
|||||||
Discovery.sender fd
|
Discovery.sender fd
|
||||||
saddr my_peer_id inco_port cancelation restart_discovery in
|
saddr my_peer_id inco_port cancelation restart_discovery in
|
||||||
Lwt_utils.worker
|
Lwt_utils.worker
|
||||||
(Format.asprintf "(%a) discovery sender" Peer_id.pp my_peer_id)
|
(Format.asprintf "(%a) discovery sender" P2p_peer.Id.pp my_peer_id)
|
||||||
sender cancel)
|
sender cancel)
|
||||||
(fun exn ->
|
(fun exn ->
|
||||||
lwt_log_error "Discovery sender not started: %a"
|
lwt_log_error "Discovery sender not started: %a"
|
||||||
|
@ -8,6 +8,6 @@
|
|||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
type t
|
type t
|
||||||
val create : ('msg, 'meta) P2p_connection_pool.pool -> t
|
val create : ('msg, 'meta) P2p_pool.t -> t
|
||||||
val restart : t -> unit
|
val restart : t -> unit
|
||||||
val shutdown : t -> unit Lwt.t
|
val shutdown : t -> unit Lwt.t
|
||||||
|
@ -17,7 +17,6 @@ let () =
|
|||||||
if Sys.os_type <> "Win32" then
|
if Sys.os_type <> "Win32" then
|
||||||
Sys.(set_signal sigpipe Signal_ignore)
|
Sys.(set_signal sigpipe Signal_ignore)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
include Logging.Make (struct let name = "p2p.io-scheduler" end)
|
include Logging.Make (struct let name = "p2p.io-scheduler" end)
|
||||||
|
|
||||||
module Inttbl = Hashtbl.Make(struct
|
module Inttbl = Hashtbl.Make(struct
|
||||||
@ -457,7 +456,7 @@ let read_full conn ?pos ?len buf =
|
|||||||
loop pos len
|
loop pos len
|
||||||
|
|
||||||
let convert ~ws ~rs =
|
let convert ~ws ~rs =
|
||||||
{ Stat.total_sent = ws.Moving_average.total ;
|
{ P2p_stat.total_sent = ws.Moving_average.total ;
|
||||||
total_recv = rs.Moving_average.total ;
|
total_recv = rs.Moving_average.total ;
|
||||||
current_outflow = ws.average ;
|
current_outflow = ws.average ;
|
||||||
current_inflow = rs.average ;
|
current_inflow = rs.average ;
|
||||||
|
@ -23,8 +23,6 @@
|
|||||||
num_connections).
|
num_connections).
|
||||||
*)
|
*)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
|
|
||||||
type connection
|
type connection
|
||||||
(** Type of a connection. *)
|
(** Type of a connection. *)
|
||||||
|
|
||||||
@ -71,11 +69,11 @@ val read_full:
|
|||||||
connection -> ?pos:int -> ?len:int -> MBytes.t -> unit tzresult Lwt.t
|
connection -> ?pos:int -> ?len:int -> MBytes.t -> unit tzresult Lwt.t
|
||||||
(** Like [read], but blits exactly [len] bytes in [buf]. *)
|
(** Like [read], but blits exactly [len] bytes in [buf]. *)
|
||||||
|
|
||||||
val stat: connection -> Stat.t
|
val stat: connection -> P2p_stat.t
|
||||||
(** [stat conn] is a snapshot of current bandwidth usage for
|
(** [stat conn] is a snapshot of current bandwidth usage for
|
||||||
[conn]. *)
|
[conn]. *)
|
||||||
|
|
||||||
val global_stat: t -> Stat.t
|
val global_stat: t -> P2p_stat.t
|
||||||
(** [global_stat sched] is a snapshot of [sched]'s bandwidth usage
|
(** [global_stat sched] is a snapshot of [sched]'s bandwidth usage
|
||||||
(sum of [stat conn] for each [conn] in [sched]). *)
|
(sum of [stat conn] for each [conn] in [sched]). *)
|
||||||
|
|
||||||
|
@ -7,9 +7,6 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
open P2p_connection_pool_types
|
|
||||||
|
|
||||||
include Logging.Make (struct let name = "p2p.maintenance" end)
|
include Logging.Make (struct let name = "p2p.maintenance" end)
|
||||||
|
|
||||||
type bounds = {
|
type bounds = {
|
||||||
@ -19,7 +16,7 @@ type bounds = {
|
|||||||
max_threshold: int ;
|
max_threshold: int ;
|
||||||
}
|
}
|
||||||
|
|
||||||
type 'meta pool = Pool : ('msg, 'meta) P2p_connection_pool.t -> 'meta pool
|
type 'meta pool = Pool : ('msg, 'meta) P2p_pool.t -> 'meta pool
|
||||||
|
|
||||||
type 'meta t = {
|
type 'meta t = {
|
||||||
canceler: Lwt_canceler.t ;
|
canceler: Lwt_canceler.t ;
|
||||||
@ -41,7 +38,7 @@ let connectable st start_time expected =
|
|||||||
let now = Time.now () in
|
let now = Time.now () in
|
||||||
let module Bounded_point_info =
|
let module Bounded_point_info =
|
||||||
List.Bounded(struct
|
List.Bounded(struct
|
||||||
type t = (Time.t option * Point.t)
|
type t = (Time.t option * P2p_point.Id.t)
|
||||||
let compare (t1, _) (t2, _) =
|
let compare (t1, _) (t2, _) =
|
||||||
match t1, t2 with
|
match t1, t2 with
|
||||||
| None, None -> 0
|
| None, None -> 0
|
||||||
@ -50,13 +47,13 @@ let connectable st start_time expected =
|
|||||||
| Some t1, Some t2 -> Time.compare t2 t1
|
| Some t1, Some t2 -> Time.compare t2 t1
|
||||||
end) in
|
end) in
|
||||||
let acc = Bounded_point_info.create expected in
|
let acc = Bounded_point_info.create expected in
|
||||||
P2p_connection_pool.Points.fold_known pool ~init:()
|
P2p_pool.Points.fold_known pool ~init:()
|
||||||
~f:begin fun point pi () ->
|
~f:begin fun point pi () ->
|
||||||
match Point_info.State.get pi with
|
match P2p_point.Pool_state.get pi with
|
||||||
| Disconnected -> begin
|
| Disconnected -> begin
|
||||||
match Point_info.last_miss pi with
|
match P2p_point.Pool_info.last_miss pi with
|
||||||
| Some last when Time.(start_time < last)
|
| Some last when Time.(start_time < last)
|
||||||
|| Point_info.greylisted ~now pi -> ()
|
|| P2p_point.Pool_info.greylisted ~now pi -> ()
|
||||||
| last ->
|
| last ->
|
||||||
Bounded_point_info.insert (last, point) acc
|
Bounded_point_info.insert (last, point) acc
|
||||||
end
|
end
|
||||||
@ -83,7 +80,7 @@ let rec try_to_contact
|
|||||||
else
|
else
|
||||||
List.fold_left
|
List.fold_left
|
||||||
(fun acc point ->
|
(fun acc point ->
|
||||||
P2p_connection_pool.connect
|
P2p_pool.connect
|
||||||
~timeout:st.connection_timeout pool point >>= function
|
~timeout:st.connection_timeout pool point >>= function
|
||||||
| Ok _ -> acc >|= succ
|
| Ok _ -> acc >|= succ
|
||||||
| Error _ -> acc)
|
| Error _ -> acc)
|
||||||
@ -96,7 +93,7 @@ let rec try_to_contact
|
|||||||
of connections is between `min_threshold` and `max_threshold`. *)
|
of connections is between `min_threshold` and `max_threshold`. *)
|
||||||
let rec maintain st =
|
let rec maintain st =
|
||||||
let Pool pool = st.pool in
|
let Pool pool = st.pool in
|
||||||
let n_connected = P2p_connection_pool.active_connections pool in
|
let n_connected = P2p_pool.active_connections pool in
|
||||||
if n_connected < st.bounds.min_threshold then
|
if n_connected < st.bounds.min_threshold then
|
||||||
too_few_connections st n_connected
|
too_few_connections st n_connected
|
||||||
else if st.bounds.max_threshold < n_connected then
|
else if st.bounds.max_threshold < n_connected then
|
||||||
@ -121,10 +118,10 @@ and too_few_connections st n_connected =
|
|||||||
(* not enough contacts, ask the pals of our pals,
|
(* not enough contacts, ask the pals of our pals,
|
||||||
discover the local network and then wait *)
|
discover the local network and then wait *)
|
||||||
Option.iter ~f:P2p_discovery.restart st.disco ;
|
Option.iter ~f:P2p_discovery.restart st.disco ;
|
||||||
P2p_connection_pool.broadcast_bootstrap_msg pool ;
|
P2p_pool.broadcast_bootstrap_msg pool ;
|
||||||
Lwt_utils.protect ~canceler:st.canceler begin fun () ->
|
Lwt_utils.protect ~canceler:st.canceler begin fun () ->
|
||||||
Lwt.pick [
|
Lwt.pick [
|
||||||
P2p_connection_pool.Pool_event.wait_new_peer pool ;
|
P2p_pool.Pool_event.wait_new_peer pool ;
|
||||||
Lwt_unix.sleep 5.0 (* TODO exponential back-off ??
|
Lwt_unix.sleep 5.0 (* TODO exponential back-off ??
|
||||||
or wait for the existence of a
|
or wait for the existence of a
|
||||||
non grey-listed peer ?? *)
|
non grey-listed peer ?? *)
|
||||||
@ -138,11 +135,11 @@ and too_many_connections st n_connected =
|
|||||||
(* too many connections, start the russian roulette *)
|
(* too many connections, start the russian roulette *)
|
||||||
let to_kill = n_connected - st.bounds.max_target in
|
let to_kill = n_connected - st.bounds.max_target in
|
||||||
lwt_debug "Too many connections, will kill %d" to_kill >>= fun () ->
|
lwt_debug "Too many connections, will kill %d" to_kill >>= fun () ->
|
||||||
snd @@ P2p_connection_pool.Connection.fold pool
|
snd @@ P2p_pool.Connection.fold pool
|
||||||
~init:(to_kill, Lwt.return_unit)
|
~init:(to_kill, Lwt.return_unit)
|
||||||
~f:(fun _ conn (i, t) ->
|
~f:(fun _ conn (i, t) ->
|
||||||
if i = 0 then (0, t)
|
if i = 0 then (0, t)
|
||||||
else (i - 1, t >>= fun () -> P2p_connection_pool.disconnect conn))
|
else (i - 1, t >>= fun () -> P2p_pool.disconnect conn))
|
||||||
>>= fun () ->
|
>>= fun () ->
|
||||||
maintain st
|
maintain st
|
||||||
|
|
||||||
@ -153,17 +150,17 @@ let rec worker_loop st =
|
|||||||
Lwt.pick [
|
Lwt.pick [
|
||||||
Lwt_unix.sleep 120. ; (* every two minutes *)
|
Lwt_unix.sleep 120. ; (* every two minutes *)
|
||||||
Lwt_condition.wait st.please_maintain ; (* when asked *)
|
Lwt_condition.wait st.please_maintain ; (* when asked *)
|
||||||
P2p_connection_pool.Pool_event.wait_too_few_connections pool ; (* limits *)
|
P2p_pool.Pool_event.wait_too_few_connections pool ; (* limits *)
|
||||||
P2p_connection_pool.Pool_event.wait_too_many_connections pool
|
P2p_pool.Pool_event.wait_too_many_connections pool
|
||||||
] >>= fun () ->
|
] >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
end >>=? fun () ->
|
end >>=? fun () ->
|
||||||
let n_connected = P2p_connection_pool.active_connections pool in
|
let n_connected = P2p_pool.active_connections pool in
|
||||||
if n_connected < st.bounds.min_threshold
|
if n_connected < st.bounds.min_threshold
|
||||||
|| st.bounds.max_threshold < n_connected then
|
|| st.bounds.max_threshold < n_connected then
|
||||||
maintain st
|
maintain st
|
||||||
else begin
|
else begin
|
||||||
P2p_connection_pool.send_swap_request pool ;
|
P2p_pool.send_swap_request pool ;
|
||||||
return ()
|
return ()
|
||||||
end
|
end
|
||||||
end >>= function
|
end >>= function
|
||||||
|
@ -36,7 +36,7 @@ type 'meta t
|
|||||||
val run:
|
val run:
|
||||||
connection_timeout:float ->
|
connection_timeout:float ->
|
||||||
bounds ->
|
bounds ->
|
||||||
('msg, 'meta) P2p_connection_pool.t ->
|
('msg, 'meta) P2p_pool.t ->
|
||||||
P2p_discovery.t option ->
|
P2p_discovery.t option ->
|
||||||
'meta t
|
'meta t
|
||||||
|
|
||||||
|
@ -15,9 +15,6 @@
|
|||||||
|
|
||||||
(* TODO allow to track "requested peer_ids" when we reconnect to a point. *)
|
(* TODO allow to track "requested peer_ids" when we reconnect to a point. *)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
open P2p_connection_pool_types
|
|
||||||
|
|
||||||
include Logging.Make (struct let name = "p2p.connection-pool" end)
|
include Logging.Make (struct let name = "p2p.connection-pool" end)
|
||||||
|
|
||||||
type 'msg encoding = Encoding : {
|
type 'msg encoding = Encoding : {
|
||||||
@ -32,9 +29,9 @@ module Message = struct
|
|||||||
|
|
||||||
type 'msg t =
|
type 'msg t =
|
||||||
| Bootstrap
|
| Bootstrap
|
||||||
| Advertise of Point.t list
|
| Advertise of P2p_point.Id.t list
|
||||||
| Swap_request of Point.t * Peer_id.t
|
| Swap_request of P2p_point.Id.t * P2p_peer.Id.t
|
||||||
| Swap_ack of Point.t * Peer_id.t
|
| Swap_ack of P2p_point.Id.t * P2p_peer.Id.t
|
||||||
| Message of 'msg
|
| Message of 'msg
|
||||||
| Disconnect
|
| Disconnect
|
||||||
|
|
||||||
@ -48,15 +45,15 @@ module Message = struct
|
|||||||
case (Tag 0x02) null
|
case (Tag 0x02) null
|
||||||
(function Bootstrap -> Some () | _ -> None)
|
(function Bootstrap -> Some () | _ -> None)
|
||||||
(fun () -> Bootstrap);
|
(fun () -> Bootstrap);
|
||||||
case (Tag 0x03) (Variable.list Point.encoding)
|
case (Tag 0x03) (Variable.list P2p_point.Id.encoding)
|
||||||
(function Advertise points -> Some points | _ -> None)
|
(function Advertise points -> Some points | _ -> None)
|
||||||
(fun points -> Advertise points);
|
(fun points -> Advertise points);
|
||||||
case (Tag 0x04) (tup2 Point.encoding Peer_id.encoding)
|
case (Tag 0x04) (tup2 P2p_point.Id.encoding P2p_peer.Id.encoding)
|
||||||
(function
|
(function
|
||||||
| Swap_request (point, peer_id) -> Some (point, peer_id)
|
| Swap_request (point, peer_id) -> Some (point, peer_id)
|
||||||
| _ -> None)
|
| _ -> None)
|
||||||
(fun (point, peer_id) -> Swap_request (point, peer_id)) ;
|
(fun (point, peer_id) -> Swap_request (point, peer_id)) ;
|
||||||
case (Tag 0x05) (tup2 Point.encoding Peer_id.encoding)
|
case (Tag 0x05) (tup2 P2p_point.Id.encoding P2p_peer.Id.encoding)
|
||||||
(function
|
(function
|
||||||
| Swap_ack (point, peer_id) -> Some (point, peer_id)
|
| Swap_ack (point, peer_id) -> Some (point, peer_id)
|
||||||
| _ -> None)
|
| _ -> None)
|
||||||
@ -74,16 +71,16 @@ end
|
|||||||
module Answerer = struct
|
module Answerer = struct
|
||||||
|
|
||||||
type 'msg callback = {
|
type 'msg callback = {
|
||||||
bootstrap: unit -> Point.t list Lwt.t ;
|
bootstrap: unit -> P2p_point.Id.t list Lwt.t ;
|
||||||
advertise: Point.t list -> unit Lwt.t ;
|
advertise: P2p_point.Id.t list -> unit Lwt.t ;
|
||||||
message: int -> 'msg -> unit Lwt.t ;
|
message: int -> 'msg -> unit Lwt.t ;
|
||||||
swap_request: Point.t -> Peer_id.t -> unit Lwt.t ;
|
swap_request: P2p_point.Id.t -> P2p_peer.Id.t -> unit Lwt.t ;
|
||||||
swap_ack: Point.t -> Peer_id.t -> unit Lwt.t ;
|
swap_ack: P2p_point.Id.t -> P2p_peer.Id.t -> unit Lwt.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
type 'msg t = {
|
type 'msg t = {
|
||||||
canceler: Lwt_canceler.t ;
|
canceler: Lwt_canceler.t ;
|
||||||
conn: 'msg Message.t P2p_connection.t ;
|
conn: 'msg Message.t P2p_socket.t ;
|
||||||
callback: 'msg callback ;
|
callback: 'msg callback ;
|
||||||
mutable worker: unit Lwt.t ;
|
mutable worker: unit Lwt.t ;
|
||||||
}
|
}
|
||||||
@ -91,14 +88,14 @@ module Answerer = struct
|
|||||||
let rec worker_loop st =
|
let rec worker_loop st =
|
||||||
Lwt_unix.yield () >>= fun () ->
|
Lwt_unix.yield () >>= fun () ->
|
||||||
Lwt_utils.protect ~canceler:st.canceler begin fun () ->
|
Lwt_utils.protect ~canceler:st.canceler begin fun () ->
|
||||||
P2p_connection.read st.conn
|
P2p_socket.read st.conn
|
||||||
end >>= function
|
end >>= function
|
||||||
| Ok (_, Bootstrap) -> begin
|
| Ok (_, Bootstrap) -> begin
|
||||||
st.callback.bootstrap () >>= function
|
st.callback.bootstrap () >>= function
|
||||||
| [] ->
|
| [] ->
|
||||||
worker_loop st
|
worker_loop st
|
||||||
| points ->
|
| points ->
|
||||||
match P2p_connection.write_now st.conn (Advertise points) with
|
match P2p_socket.write_now st.conn (Advertise points) with
|
||||||
| Ok _sent ->
|
| Ok _sent ->
|
||||||
(* if not sent then ?? TODO count dropped message ?? *)
|
(* if not sent then ?? TODO count dropped message ?? *)
|
||||||
worker_loop st
|
worker_loop st
|
||||||
@ -121,7 +118,7 @@ module Answerer = struct
|
|||||||
| Ok (_, Disconnect) | Error [P2p_io_scheduler.Connection_closed] ->
|
| Ok (_, Disconnect) | Error [P2p_io_scheduler.Connection_closed] ->
|
||||||
Lwt_canceler.cancel st.canceler >>= fun () ->
|
Lwt_canceler.cancel st.canceler >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Error [P2p_connection.Decoding_error] ->
|
| Error [P2p_socket.Decoding_error] ->
|
||||||
(* TODO: Penalize peer... *)
|
(* TODO: Penalize peer... *)
|
||||||
Lwt_canceler.cancel st.canceler >>= fun () ->
|
Lwt_canceler.cancel st.canceler >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
@ -150,18 +147,16 @@ module Answerer = struct
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Log_event = Connection_pool_log_event
|
|
||||||
|
|
||||||
type config = {
|
type config = {
|
||||||
|
|
||||||
identity : Identity.t ;
|
identity : P2p_identity.t ;
|
||||||
proof_of_work_target : Crypto_box.target ;
|
proof_of_work_target : Crypto_box.target ;
|
||||||
|
|
||||||
trusted_points : Point.t list ;
|
trusted_points : P2p_point.Id.t list ;
|
||||||
peers_file : string ;
|
peers_file : string ;
|
||||||
closed_network : bool ;
|
closed_network : bool ;
|
||||||
|
|
||||||
listening_port : port option ;
|
listening_port : P2p_addr.port option ;
|
||||||
min_connections : int ;
|
min_connections : int ;
|
||||||
max_connections : int ;
|
max_connections : int ;
|
||||||
max_incoming_connections : int ;
|
max_incoming_connections : int ;
|
||||||
@ -189,27 +184,27 @@ type 'meta meta_config = {
|
|||||||
|
|
||||||
type 'msg message_config = {
|
type 'msg message_config = {
|
||||||
encoding : 'msg encoding list ;
|
encoding : 'msg encoding list ;
|
||||||
versions : P2p_types.Version.t list;
|
versions : P2p_version.t list;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ('msg, 'meta) t = {
|
type ('msg, 'meta) t = {
|
||||||
config : config ;
|
config : config ;
|
||||||
meta_config : 'meta meta_config ;
|
meta_config : 'meta meta_config ;
|
||||||
message_config : 'msg message_config ;
|
message_config : 'msg message_config ;
|
||||||
my_id_points : unit Point.Table.t ;
|
my_id_points : unit P2p_point.Table.t ;
|
||||||
known_peer_ids :
|
known_peer_ids :
|
||||||
(('msg, 'meta) connection, 'meta) Peer_info.t Peer_id.Table.t ;
|
(('msg, 'meta) connection, 'meta) P2p_peer.Pool_info.t P2p_peer.Table.t ;
|
||||||
connected_peer_ids :
|
connected_peer_ids :
|
||||||
(('msg, 'meta) connection, 'meta) Peer_info.t Peer_id.Table.t ;
|
(('msg, 'meta) connection, 'meta) P2p_peer.Pool_info.t P2p_peer.Table.t ;
|
||||||
known_points : ('msg, 'meta) connection Point_info.t Point.Table.t ;
|
known_points : ('msg, 'meta) connection P2p_point.Pool_info.t P2p_point.Table.t ;
|
||||||
connected_points : ('msg, 'meta) connection Point_info.t Point.Table.t ;
|
connected_points : ('msg, 'meta) connection P2p_point.Pool_info.t P2p_point.Table.t ;
|
||||||
incoming : Lwt_canceler.t Point.Table.t ;
|
incoming : Lwt_canceler.t P2p_point.Table.t ;
|
||||||
io_sched : P2p_io_scheduler.t ;
|
io_sched : P2p_io_scheduler.t ;
|
||||||
encoding : 'msg Message.t Data_encoding.t ;
|
encoding : 'msg Message.t Data_encoding.t ;
|
||||||
events : events ;
|
events : events ;
|
||||||
watcher : Log_event.t Lwt_watcher.input ;
|
watcher : P2p_connection.Pool_event.t Lwt_watcher.input ;
|
||||||
mutable new_connection_hook :
|
mutable new_connection_hook :
|
||||||
(Peer_id.t -> ('msg, 'meta) connection -> unit) list ;
|
(P2p_peer.Id.t -> ('msg, 'meta) connection -> unit) list ;
|
||||||
mutable latest_accepted_swap : Time.t ;
|
mutable latest_accepted_swap : Time.t ;
|
||||||
mutable latest_succesfull_swap : Time.t ;
|
mutable latest_succesfull_swap : Time.t ;
|
||||||
}
|
}
|
||||||
@ -224,11 +219,11 @@ and events = {
|
|||||||
and ('msg, 'meta) connection = {
|
and ('msg, 'meta) connection = {
|
||||||
canceler : Lwt_canceler.t ;
|
canceler : Lwt_canceler.t ;
|
||||||
messages : (int * 'msg) Lwt_pipe.t ;
|
messages : (int * 'msg) Lwt_pipe.t ;
|
||||||
conn : 'msg Message.t P2p_connection.t ;
|
conn : 'msg Message.t P2p_socket.t ;
|
||||||
peer_info : (('msg, 'meta) connection, 'meta) Peer_info.t ;
|
peer_info : (('msg, 'meta) connection, 'meta) P2p_peer.Pool_info.t ;
|
||||||
point_info : ('msg, 'meta) connection Point_info.t option ;
|
point_info : ('msg, 'meta) connection P2p_point.Pool_info.t option ;
|
||||||
answerer : 'msg Answerer.t Lazy.t ;
|
answerer : 'msg Answerer.t Lazy.t ;
|
||||||
mutable last_sent_swap_request : (Time.t * Peer_id.t) option ;
|
mutable last_sent_swap_request : (Time.t * P2p_peer.Id.t) option ;
|
||||||
mutable wait_close : bool ;
|
mutable wait_close : bool ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,8 +243,8 @@ end
|
|||||||
let watch { watcher } = Lwt_watcher.create_stream watcher
|
let watch { watcher } = Lwt_watcher.create_stream watcher
|
||||||
let log { watcher } event = Lwt_watcher.notify watcher event
|
let log { watcher } event = Lwt_watcher.notify watcher event
|
||||||
|
|
||||||
module GcPointSet = List.Bounded(struct
|
module Gc_point_set = List.Bounded(struct
|
||||||
type t = Time.t * Point.t
|
type t = Time.t * P2p_point.Id.t
|
||||||
let compare (x, _) (y, _) = - (Time.compare x y)
|
let compare (x, _) (y, _) = - (Time.compare x y)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -258,37 +253,37 @@ let gc_points ({ config = { max_known_points } ; known_points } as pool) =
|
|||||||
| None -> ()
|
| None -> ()
|
||||||
| Some (_, target) ->
|
| Some (_, target) ->
|
||||||
let now = Time.now () in (* TODO: maybe time of discovery? *)
|
let now = Time.now () in (* TODO: maybe time of discovery? *)
|
||||||
let table = GcPointSet.create target in
|
let table = Gc_point_set.create target in
|
||||||
Point.Table.iter (fun p point_info ->
|
P2p_point.Table.iter (fun p point_info ->
|
||||||
if Point_info.State.is_disconnected point_info then
|
if P2p_point.Pool_state.is_disconnected point_info then
|
||||||
let time =
|
let time =
|
||||||
match Point_info.last_miss point_info with
|
match P2p_point.Pool_info.last_miss point_info with
|
||||||
| None -> now
|
| None -> now
|
||||||
| Some t -> t in
|
| Some t -> t in
|
||||||
GcPointSet.insert (time, p) table
|
Gc_point_set.insert (time, p) table
|
||||||
) known_points ;
|
) known_points ;
|
||||||
let to_remove = GcPointSet.get table in
|
let to_remove = Gc_point_set.get table in
|
||||||
ListLabels.iter to_remove ~f:begin fun (_, p) ->
|
ListLabels.iter to_remove ~f:begin fun (_, p) ->
|
||||||
Point.Table.remove known_points p
|
P2p_point.Table.remove known_points p
|
||||||
end ;
|
end ;
|
||||||
log pool Gc_points
|
log pool Gc_points
|
||||||
|
|
||||||
let register_point pool ?trusted _source_peer_id (addr, port as point) =
|
let register_point pool ?trusted _source_peer_id (addr, port as point) =
|
||||||
match Point.Table.find pool.known_points point with
|
match P2p_point.Table.find pool.known_points point with
|
||||||
| exception Not_found ->
|
| exception Not_found ->
|
||||||
let point_info = Point_info.create ?trusted addr port in
|
let point_info = P2p_point.Pool_info.create ?trusted addr port in
|
||||||
Option.iter pool.config.max_known_points ~f:begin fun (max, _) ->
|
Option.iter pool.config.max_known_points ~f:begin fun (max, _) ->
|
||||||
if Point.Table.length pool.known_points >= max then gc_points pool
|
if P2p_point.Table.length pool.known_points >= max then gc_points pool
|
||||||
end ;
|
end ;
|
||||||
Point.Table.add pool.known_points point point_info ;
|
P2p_point.Table.add pool.known_points point point_info ;
|
||||||
log pool (New_point point) ;
|
log pool (New_point point) ;
|
||||||
point_info
|
point_info
|
||||||
| point_info -> point_info
|
| point_info -> point_info
|
||||||
|
|
||||||
let may_register_my_id_point pool = function
|
let may_register_my_id_point pool = function
|
||||||
| [P2p_connection.Myself (addr, Some port)] ->
|
| [P2p_socket.Myself (addr, Some port)] ->
|
||||||
Point.Table.add pool.my_id_points (addr, port) () ;
|
P2p_point.Table.add pool.my_id_points (addr, port) () ;
|
||||||
Point.Table.remove pool.known_points (addr, port)
|
P2p_point.Table.remove pool.known_points (addr, port)
|
||||||
| _ -> ()
|
| _ -> ()
|
||||||
|
|
||||||
|
|
||||||
@ -299,8 +294,8 @@ let may_register_my_id_point pool = function
|
|||||||
case of a flood attack, the newly added infos will probably belong
|
case of a flood attack, the newly added infos will probably belong
|
||||||
to peer_ids with the same (low) score and removing the most recent ones
|
to peer_ids with the same (low) score and removing the most recent ones
|
||||||
ensure that older (and probably legit) peer_id infos are kept. *)
|
ensure that older (and probably legit) peer_id infos are kept. *)
|
||||||
module GcPeer_idSet = List.Bounded(struct
|
module Gc_peer_set = List.Bounded(struct
|
||||||
type t = float * Time.t * Peer_id.t
|
type t = float * Time.t * P2p_peer.Id.t
|
||||||
let compare (s, t, _) (s', t', _) =
|
let compare (s, t, _) (s', t', _) =
|
||||||
let score_cmp = Pervasives.compare s s' in
|
let score_cmp = Pervasives.compare s s' in
|
||||||
if score_cmp = 0 then Time.compare t t' else - score_cmp
|
if score_cmp = 0 then Time.compare t t' else - score_cmp
|
||||||
@ -312,27 +307,27 @@ let gc_peer_ids ({ meta_config = { score } ;
|
|||||||
match max_known_peer_ids with
|
match max_known_peer_ids with
|
||||||
| None -> ()
|
| None -> ()
|
||||||
| Some (_, target) ->
|
| Some (_, target) ->
|
||||||
let table = GcPeer_idSet.create target in
|
let table = Gc_peer_set.create target in
|
||||||
Peer_id.Table.iter (fun peer_id peer_info ->
|
P2p_peer.Table.iter (fun peer_id peer_info ->
|
||||||
let created = Peer_info.created peer_info in
|
let created = P2p_peer.Pool_info.created peer_info in
|
||||||
let score = score @@ Peer_info.metadata peer_info in
|
let score = score @@ P2p_peer.Pool_info.metadata peer_info in
|
||||||
GcPeer_idSet.insert (score, created, peer_id) table
|
Gc_peer_set.insert (score, created, peer_id) table
|
||||||
) known_peer_ids ;
|
) known_peer_ids ;
|
||||||
let to_remove = GcPeer_idSet.get table in
|
let to_remove = Gc_peer_set.get table in
|
||||||
ListLabels.iter to_remove ~f:begin fun (_, _, peer_id) ->
|
ListLabels.iter to_remove ~f:begin fun (_, _, peer_id) ->
|
||||||
Peer_id.Table.remove known_peer_ids peer_id
|
P2p_peer.Table.remove known_peer_ids peer_id
|
||||||
end ;
|
end ;
|
||||||
log pool Gc_peer_ids
|
log pool Gc_peer_ids
|
||||||
|
|
||||||
let register_peer pool peer_id =
|
let register_peer pool peer_id =
|
||||||
match Peer_id.Table.find pool.known_peer_ids peer_id with
|
match P2p_peer.Table.find pool.known_peer_ids peer_id with
|
||||||
| exception Not_found ->
|
| exception Not_found ->
|
||||||
Lwt_condition.broadcast pool.events.new_peer () ;
|
Lwt_condition.broadcast pool.events.new_peer () ;
|
||||||
let peer = Peer_info.create peer_id ~metadata:pool.meta_config.initial in
|
let peer = P2p_peer.Pool_info.create peer_id ~metadata:pool.meta_config.initial in
|
||||||
Option.iter pool.config.max_known_peer_ids ~f:begin fun (max, _) ->
|
Option.iter pool.config.max_known_peer_ids ~f:begin fun (max, _) ->
|
||||||
if Peer_id.Table.length pool.known_peer_ids >= max then gc_peer_ids pool
|
if P2p_peer.Table.length pool.known_peer_ids >= max then gc_peer_ids pool
|
||||||
end ;
|
end ;
|
||||||
Peer_id.Table.add pool.known_peer_ids peer_id peer ;
|
P2p_peer.Table.add pool.known_peer_ids peer_id peer ;
|
||||||
log pool (New_peer peer_id) ;
|
log pool (New_peer peer_id) ;
|
||||||
peer
|
peer
|
||||||
| peer -> peer
|
| peer -> peer
|
||||||
@ -344,7 +339,7 @@ let read { messages ; conn } =
|
|||||||
Lwt.catch
|
Lwt.catch
|
||||||
(fun () -> Lwt_pipe.pop messages >>= fun (s, msg) ->
|
(fun () -> Lwt_pipe.pop messages >>= fun (s, msg) ->
|
||||||
lwt_debug "%d bytes message popped from queue %a\027[0m"
|
lwt_debug "%d bytes message popped from queue %a\027[0m"
|
||||||
s Connection_info.pp (P2p_connection.info conn) >>= fun () ->
|
s P2p_connection.Info.pp (P2p_socket.info conn) >>= fun () ->
|
||||||
return msg)
|
return msg)
|
||||||
(fun _ (* Closed *) -> fail P2p_io_scheduler.Connection_closed)
|
(fun _ (* Closed *) -> fail P2p_io_scheduler.Connection_closed)
|
||||||
|
|
||||||
@ -354,111 +349,111 @@ let is_readable { messages } =
|
|||||||
(fun _ (* Closed *) -> fail P2p_io_scheduler.Connection_closed)
|
(fun _ (* Closed *) -> fail P2p_io_scheduler.Connection_closed)
|
||||||
|
|
||||||
let write { conn } msg =
|
let write { conn } msg =
|
||||||
P2p_connection.write conn (Message msg)
|
P2p_socket.write conn (Message msg)
|
||||||
|
|
||||||
let write_sync { conn } msg =
|
let write_sync { conn } msg =
|
||||||
P2p_connection.write_sync conn (Message msg)
|
P2p_socket.write_sync conn (Message msg)
|
||||||
|
|
||||||
let raw_write_sync { conn } buf =
|
let raw_write_sync { conn } buf =
|
||||||
P2p_connection.raw_write_sync conn buf
|
P2p_socket.raw_write_sync conn buf
|
||||||
|
|
||||||
let write_now { conn } msg =
|
let write_now { conn } msg =
|
||||||
P2p_connection.write_now conn (Message msg)
|
P2p_socket.write_now conn (Message msg)
|
||||||
|
|
||||||
let write_all pool msg =
|
let write_all pool msg =
|
||||||
Peer_id.Table.iter
|
P2p_peer.Table.iter
|
||||||
(fun _peer_id peer_info ->
|
(fun _peer_id peer_info ->
|
||||||
match Peer_info.State.get peer_info with
|
match P2p_peer.Pool_state.get peer_info with
|
||||||
| Running { data = conn } ->
|
| Running { data = conn } ->
|
||||||
ignore (write_now conn msg : bool tzresult )
|
ignore (write_now conn msg : bool tzresult )
|
||||||
| _ -> ())
|
| _ -> ())
|
||||||
pool.connected_peer_ids
|
pool.connected_peer_ids
|
||||||
|
|
||||||
let broadcast_bootstrap_msg pool =
|
let broadcast_bootstrap_msg pool =
|
||||||
Peer_id.Table.iter
|
P2p_peer.Table.iter
|
||||||
(fun _peer_id peer_info ->
|
(fun _peer_id peer_info ->
|
||||||
match Peer_info.State.get peer_info with
|
match P2p_peer.Pool_state.get peer_info with
|
||||||
| Running { data = { conn } } ->
|
| Running { data = { conn } } ->
|
||||||
ignore (P2p_connection.write_now conn Bootstrap : bool tzresult )
|
ignore (P2p_socket.write_now conn Bootstrap : bool tzresult )
|
||||||
| _ -> ())
|
| _ -> ())
|
||||||
pool.connected_peer_ids
|
pool.connected_peer_ids
|
||||||
|
|
||||||
|
|
||||||
(***************************************************************************)
|
(***************************************************************************)
|
||||||
|
|
||||||
module Peer_ids = struct
|
module Peers = struct
|
||||||
|
|
||||||
type ('msg, 'meta) info = (('msg, 'meta) connection, 'meta) Peer_info.t
|
type ('msg, 'meta) info = (('msg, 'meta) connection, 'meta) P2p_peer.Pool_info.t
|
||||||
|
|
||||||
let info { known_peer_ids } point =
|
let info { known_peer_ids } point =
|
||||||
try Some (Peer_id.Table.find known_peer_ids point)
|
try Some (P2p_peer.Table.find known_peer_ids point)
|
||||||
with Not_found -> None
|
with Not_found -> None
|
||||||
|
|
||||||
let get_metadata pool peer_id =
|
let get_metadata pool peer_id =
|
||||||
try Peer_info.metadata (Peer_id.Table.find pool.known_peer_ids peer_id)
|
try P2p_peer.Pool_info.metadata (P2p_peer.Table.find pool.known_peer_ids peer_id)
|
||||||
with Not_found -> pool.meta_config.initial
|
with Not_found -> pool.meta_config.initial
|
||||||
|
|
||||||
let get_score pool peer_id =
|
let get_score pool peer_id =
|
||||||
pool.meta_config.score (get_metadata pool peer_id)
|
pool.meta_config.score (get_metadata pool peer_id)
|
||||||
|
|
||||||
let set_metadata pool peer_id data =
|
let set_metadata pool peer_id data =
|
||||||
Peer_info.set_metadata (register_peer pool peer_id) data
|
P2p_peer.Pool_info.set_metadata (register_peer pool peer_id) data
|
||||||
|
|
||||||
let get_trusted pool peer_id =
|
let get_trusted pool peer_id =
|
||||||
try Peer_info.trusted (Peer_id.Table.find pool.known_peer_ids peer_id)
|
try P2p_peer.Pool_info.trusted (P2p_peer.Table.find pool.known_peer_ids peer_id)
|
||||||
with Not_found -> false
|
with Not_found -> false
|
||||||
|
|
||||||
let set_trusted pool peer_id =
|
let set_trusted pool peer_id =
|
||||||
try Peer_info.set_trusted (register_peer pool peer_id)
|
try P2p_peer.Pool_info.set_trusted (register_peer pool peer_id)
|
||||||
with Not_found -> ()
|
with Not_found -> ()
|
||||||
|
|
||||||
let unset_trusted pool peer_id =
|
let unset_trusted pool peer_id =
|
||||||
try Peer_info.unset_trusted (Peer_id.Table.find pool.known_peer_ids peer_id)
|
try P2p_peer.Pool_info.unset_trusted (P2p_peer.Table.find pool.known_peer_ids peer_id)
|
||||||
with Not_found -> ()
|
with Not_found -> ()
|
||||||
|
|
||||||
let fold_known pool ~init ~f =
|
let fold_known pool ~init ~f =
|
||||||
Peer_id.Table.fold f pool.known_peer_ids init
|
P2p_peer.Table.fold f pool.known_peer_ids init
|
||||||
|
|
||||||
let fold_connected pool ~init ~f =
|
let fold_connected pool ~init ~f =
|
||||||
Peer_id.Table.fold f pool.connected_peer_ids init
|
P2p_peer.Table.fold f pool.connected_peer_ids init
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Points = struct
|
module Points = struct
|
||||||
|
|
||||||
type ('msg, 'meta) info = ('msg, 'meta) connection Point_info.t
|
type ('msg, 'meta) info = ('msg, 'meta) connection P2p_point.Pool_info.t
|
||||||
|
|
||||||
let info { known_points } point =
|
let info { known_points } point =
|
||||||
try Some (Point.Table.find known_points point)
|
try Some (P2p_point.Table.find known_points point)
|
||||||
with Not_found -> None
|
with Not_found -> None
|
||||||
|
|
||||||
let get_trusted pool point =
|
let get_trusted pool point =
|
||||||
try Point_info.trusted (Point.Table.find pool.known_points point)
|
try P2p_point.Pool_info.trusted (P2p_point.Table.find pool.known_points point)
|
||||||
with Not_found -> false
|
with Not_found -> false
|
||||||
|
|
||||||
let set_trusted pool point =
|
let set_trusted pool point =
|
||||||
try
|
try
|
||||||
Point_info.set_trusted
|
P2p_point.Pool_info.set_trusted
|
||||||
(register_point pool pool.config.identity.peer_id point)
|
(register_point pool pool.config.identity.peer_id point)
|
||||||
with Not_found -> ()
|
with Not_found -> ()
|
||||||
|
|
||||||
let unset_trusted pool peer_id =
|
let unset_trusted pool peer_id =
|
||||||
try Point_info.unset_trusted (Point.Table.find pool.known_points peer_id)
|
try P2p_point.Pool_info.unset_trusted (P2p_point.Table.find pool.known_points peer_id)
|
||||||
with Not_found -> ()
|
with Not_found -> ()
|
||||||
|
|
||||||
let fold_known pool ~init ~f =
|
let fold_known pool ~init ~f =
|
||||||
Point.Table.fold f pool.known_points init
|
P2p_point.Table.fold f pool.known_points init
|
||||||
|
|
||||||
let fold_connected pool ~init ~f =
|
let fold_connected pool ~init ~f =
|
||||||
Point.Table.fold f pool.connected_points init
|
P2p_point.Table.fold f pool.connected_points init
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Connection = struct
|
module Connection = struct
|
||||||
|
|
||||||
let fold pool ~init ~f =
|
let fold pool ~init ~f =
|
||||||
Peer_ids.fold_connected pool ~init ~f:begin fun peer_id peer_info acc ->
|
Peers.fold_connected pool ~init ~f:begin fun peer_id peer_info acc ->
|
||||||
match Peer_info.State.get peer_info with
|
match P2p_peer.Pool_state.get peer_info with
|
||||||
| Running { data } -> f peer_id data acc
|
| Running { data } -> f peer_id data acc
|
||||||
| _ -> acc
|
| _ -> acc
|
||||||
end
|
end
|
||||||
@ -471,7 +466,7 @@ module Connection = struct
|
|||||||
fold pool ~init:[] ~f:begin fun _peer conn acc ->
|
fold pool ~init:[] ~f:begin fun _peer conn acc ->
|
||||||
match different_than with
|
match different_than with
|
||||||
| Some excluded_conn
|
| Some excluded_conn
|
||||||
when P2p_connection.equal conn.conn excluded_conn.conn -> acc
|
when P2p_socket.equal conn.conn excluded_conn.conn -> acc
|
||||||
| Some _ | None -> conn :: acc
|
| Some _ | None -> conn :: acc
|
||||||
end in
|
end in
|
||||||
match candidates with
|
match candidates with
|
||||||
@ -484,9 +479,9 @@ module Connection = struct
|
|||||||
fold pool ~init:[] ~f:begin fun _peer conn acc ->
|
fold pool ~init:[] ~f:begin fun _peer conn acc ->
|
||||||
match different_than with
|
match different_than with
|
||||||
| Some excluded_conn
|
| Some excluded_conn
|
||||||
when P2p_connection.equal conn.conn excluded_conn.conn -> acc
|
when P2p_socket.equal conn.conn excluded_conn.conn -> acc
|
||||||
| Some _ | None ->
|
| Some _ | None ->
|
||||||
let ci = P2p_connection.info conn.conn in
|
let ci = P2p_socket.info conn.conn in
|
||||||
match ci.id_point with
|
match ci.id_point with
|
||||||
| _, None -> acc
|
| _, None -> acc
|
||||||
| addr, Some port -> ((addr, port), ci.peer_id, conn) :: acc
|
| addr, Some port -> ((addr, port), ci.peer_id, conn) :: acc
|
||||||
@ -497,18 +492,18 @@ module Connection = struct
|
|||||||
Some (List.nth candidates (Random.int @@ List.length candidates))
|
Some (List.nth candidates (Random.int @@ List.length candidates))
|
||||||
|
|
||||||
let stat { conn } =
|
let stat { conn } =
|
||||||
P2p_connection.stat conn
|
P2p_socket.stat conn
|
||||||
|
|
||||||
let score { meta_config = { score }} meta = score meta
|
let score { meta_config = { score }} meta = score meta
|
||||||
|
|
||||||
let info { conn } =
|
let info { conn } =
|
||||||
P2p_connection.info conn
|
P2p_socket.info conn
|
||||||
|
|
||||||
let find_by_peer_id pool peer_id =
|
let find_by_peer_id pool peer_id =
|
||||||
Option.apply
|
Option.apply
|
||||||
(Peer_ids.info pool peer_id)
|
(Peers.info pool peer_id)
|
||||||
~f:(fun p ->
|
~f:(fun p ->
|
||||||
match Peer_info.State.get p with
|
match P2p_peer.Pool_state.get p with
|
||||||
| Running { data } -> Some data
|
| Running { data } -> Some data
|
||||||
| _ -> None)
|
| _ -> None)
|
||||||
|
|
||||||
@ -516,7 +511,7 @@ module Connection = struct
|
|||||||
Option.apply
|
Option.apply
|
||||||
(Points.info pool point)
|
(Points.info pool point)
|
||||||
~f:(fun p ->
|
~f:(fun p ->
|
||||||
match Point_info.State.get p with
|
match P2p_point.Pool_state.get p with
|
||||||
| Running { data } -> Some data
|
| Running { data } -> Some data
|
||||||
| _ -> None)
|
| _ -> None)
|
||||||
|
|
||||||
@ -528,7 +523,7 @@ let pool_stat { io_sched } =
|
|||||||
|
|
||||||
(***************************************************************************)
|
(***************************************************************************)
|
||||||
|
|
||||||
type error += Rejected of Peer_id.t
|
type error += Rejected of P2p_peer.Id.t
|
||||||
type error += Pending_connection
|
type error += Pending_connection
|
||||||
type error += Connected
|
type error += Connected
|
||||||
type error += Connection_closed = P2p_io_scheduler.Connection_closed
|
type error += Connection_closed = P2p_io_scheduler.Connection_closed
|
||||||
@ -537,13 +532,13 @@ type error += Closed_network
|
|||||||
type error += Too_many_connections
|
type error += Too_many_connections
|
||||||
|
|
||||||
let fail_unless_disconnected_point point_info =
|
let fail_unless_disconnected_point point_info =
|
||||||
match Point_info.State.get point_info with
|
match P2p_point.Pool_state.get point_info with
|
||||||
| Disconnected -> return ()
|
| Disconnected -> return ()
|
||||||
| Requested _ | Accepted _ -> fail Pending_connection
|
| Requested _ | Accepted _ -> fail Pending_connection
|
||||||
| Running _ -> fail Connected
|
| Running _ -> fail Connected
|
||||||
|
|
||||||
let fail_unless_disconnected_peer_id peer_info =
|
let fail_unless_disconnected_peer_id peer_info =
|
||||||
match Peer_info.State.get peer_info with
|
match P2p_peer.Pool_state.get peer_info with
|
||||||
| Disconnected -> return ()
|
| Disconnected -> return ()
|
||||||
| Accepted _ -> fail Pending_connection
|
| Accepted _ -> fail Pending_connection
|
||||||
| Running _ -> fail Connected
|
| Running _ -> fail Connected
|
||||||
@ -551,10 +546,10 @@ let fail_unless_disconnected_peer_id peer_info =
|
|||||||
let compare_known_point_info p1 p2 =
|
let compare_known_point_info p1 p2 =
|
||||||
(* The most-recently disconnected peers are greater. *)
|
(* The most-recently disconnected peers are greater. *)
|
||||||
(* Then come long-standing connected peers. *)
|
(* Then come long-standing connected peers. *)
|
||||||
let disconnected1 = Point_info.State.is_disconnected p1
|
let disconnected1 = P2p_point.Pool_state.is_disconnected p1
|
||||||
and disconnected2 = Point_info.State.is_disconnected p2 in
|
and disconnected2 = P2p_point.Pool_state.is_disconnected p2 in
|
||||||
let compare_last_seen p1 p2 =
|
let compare_last_seen p1 p2 =
|
||||||
match Point_info.last_seen p1, Point_info.last_seen p2 with
|
match P2p_point.Pool_info.last_seen p1, P2p_point.Pool_info.last_seen p2 with
|
||||||
| None, None -> Random.int 2 * 2 - 1 (* HACK... *)
|
| None, None -> Random.int 2 * 2 - 1 (* HACK... *)
|
||||||
| Some _, None -> 1
|
| Some _, None -> 1
|
||||||
| None, Some _ -> -1
|
| None, Some _ -> -1
|
||||||
@ -576,40 +571,40 @@ let rec connect ~timeout pool point =
|
|||||||
Lwt_utils.with_timeout ~canceler timeout begin fun canceler ->
|
Lwt_utils.with_timeout ~canceler timeout begin fun canceler ->
|
||||||
let point_info =
|
let point_info =
|
||||||
register_point pool pool.config.identity.peer_id point in
|
register_point pool pool.config.identity.peer_id point in
|
||||||
let addr, port as point = Point_info.point point_info in
|
let addr, port as point = P2p_point.Pool_info.point point_info in
|
||||||
fail_unless
|
fail_unless
|
||||||
(not pool.config.closed_network || Point_info.trusted point_info)
|
(not pool.config.closed_network || P2p_point.Pool_info.trusted point_info)
|
||||||
Closed_network >>=? fun () ->
|
Closed_network >>=? fun () ->
|
||||||
fail_unless_disconnected_point point_info >>=? fun () ->
|
fail_unless_disconnected_point point_info >>=? fun () ->
|
||||||
Point_info.State.set_requested point_info canceler ;
|
P2p_point.Pool_state.set_requested point_info canceler ;
|
||||||
let fd = Lwt_unix.socket PF_INET6 SOCK_STREAM 0 in
|
let fd = Lwt_unix.socket PF_INET6 SOCK_STREAM 0 in
|
||||||
let uaddr =
|
let uaddr =
|
||||||
Lwt_unix.ADDR_INET (Ipaddr_unix.V6.to_inet_addr addr, port) in
|
Lwt_unix.ADDR_INET (Ipaddr_unix.V6.to_inet_addr addr, port) in
|
||||||
lwt_debug "connect: %a" Point.pp point >>= fun () ->
|
lwt_debug "connect: %a" P2p_point.Id.pp point >>= fun () ->
|
||||||
Lwt_utils.protect ~canceler begin fun () ->
|
Lwt_utils.protect ~canceler begin fun () ->
|
||||||
log pool (Outgoing_connection point) ;
|
log pool (Outgoing_connection point) ;
|
||||||
Lwt_unix.connect fd uaddr >>= fun () ->
|
Lwt_unix.connect fd uaddr >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
end ~on_error: begin fun err ->
|
end ~on_error: begin fun err ->
|
||||||
lwt_debug "connect: %a -> disconnect" Point.pp point >>= fun () ->
|
lwt_debug "connect: %a -> disconnect" P2p_point.Id.pp point >>= fun () ->
|
||||||
Point_info.State.set_disconnected point_info ;
|
P2p_point.Pool_state.set_disconnected point_info ;
|
||||||
Lwt_utils.safe_close fd >>= fun () ->
|
Lwt_utils.safe_close fd >>= fun () ->
|
||||||
match err with
|
match err with
|
||||||
| [Exn (Unix.Unix_error (Unix.ECONNREFUSED, _, _))] ->
|
| [Exn (Unix.Unix_error (Unix.ECONNREFUSED, _, _))] ->
|
||||||
fail Connection_refused
|
fail Connection_refused
|
||||||
| err -> Lwt.return (Error err)
|
| err -> Lwt.return (Error err)
|
||||||
end >>=? fun () ->
|
end >>=? fun () ->
|
||||||
lwt_debug "connect: %a -> authenticate" Point.pp point >>= fun () ->
|
lwt_debug "connect: %a -> authenticate" P2p_point.Id.pp point >>= fun () ->
|
||||||
authenticate pool ~point_info canceler fd point
|
authenticate pool ~point_info canceler fd point
|
||||||
end
|
end
|
||||||
|
|
||||||
and authenticate pool ?point_info canceler fd point =
|
and authenticate pool ?point_info canceler fd point =
|
||||||
let incoming = point_info = None in
|
let incoming = point_info = None in
|
||||||
lwt_debug "authenticate: %a%s"
|
lwt_debug "authenticate: %a%s"
|
||||||
Point.pp point
|
P2p_point.Id.pp point
|
||||||
(if incoming then " incoming" else "") >>= fun () ->
|
(if incoming then " incoming" else "") >>= fun () ->
|
||||||
Lwt_utils.protect ~canceler begin fun () ->
|
Lwt_utils.protect ~canceler begin fun () ->
|
||||||
P2p_connection.authenticate
|
P2p_socket.authenticate
|
||||||
~proof_of_work_target:pool.config.proof_of_work_target
|
~proof_of_work_target:pool.config.proof_of_work_target
|
||||||
~incoming (P2p_io_scheduler.register pool.io_sched fd) point
|
~incoming (P2p_io_scheduler.register pool.io_sched fd) point
|
||||||
?listening_port:pool.config.listening_port
|
?listening_port:pool.config.listening_port
|
||||||
@ -620,31 +615,31 @@ and authenticate pool ?point_info canceler fd point =
|
|||||||
| [ Lwt_utils.Canceled ] ->
|
| [ Lwt_utils.Canceled ] ->
|
||||||
(* Currently only on time out *)
|
(* Currently only on time out *)
|
||||||
lwt_debug "authenticate: %a%s -> canceled"
|
lwt_debug "authenticate: %a%s -> canceled"
|
||||||
Point.pp point
|
P2p_point.Id.pp point
|
||||||
(if incoming then " incoming" else "")
|
(if incoming then " incoming" else "")
|
||||||
| err ->
|
| err ->
|
||||||
(* Authentication incorrect! *)
|
(* Authentication incorrect! *)
|
||||||
lwt_debug "@[authenticate: %a%s -> failed@ %a@]"
|
lwt_debug "@[authenticate: %a%s -> failed@ %a@]"
|
||||||
Point.pp point
|
P2p_point.Id.pp point
|
||||||
(if incoming then " incoming" else "")
|
(if incoming then " incoming" else "")
|
||||||
pp_print_error err
|
pp_print_error err
|
||||||
end >>= fun () ->
|
end >>= fun () ->
|
||||||
may_register_my_id_point pool err ;
|
may_register_my_id_point pool err ;
|
||||||
log pool (Authentication_failed point) ;
|
log pool (Authentication_failed point) ;
|
||||||
if incoming then
|
if incoming then
|
||||||
Point.Table.remove pool.incoming point
|
P2p_point.Table.remove pool.incoming point
|
||||||
else
|
else
|
||||||
Option.iter ~f:Point_info.State.set_disconnected point_info ;
|
Option.iter ~f:P2p_point.Pool_state.set_disconnected point_info ;
|
||||||
Lwt.return (Error err)
|
Lwt.return (Error err)
|
||||||
end >>=? fun (info, auth_fd) ->
|
end >>=? fun (info, auth_fd) ->
|
||||||
(* Authentication correct! *)
|
(* Authentication correct! *)
|
||||||
lwt_debug "authenticate: %a -> auth %a"
|
lwt_debug "authenticate: %a -> auth %a"
|
||||||
Point.pp point
|
P2p_point.Id.pp point
|
||||||
Connection_info.pp info >>= fun () ->
|
P2p_connection.Info.pp info >>= fun () ->
|
||||||
let remote_point_info =
|
let remote_point_info =
|
||||||
match info.id_point with
|
match info.id_point with
|
||||||
| addr, Some port
|
| addr, Some port
|
||||||
when not (Point.Table.mem pool.my_id_points (addr, port)) ->
|
when not (P2p_point.Table.mem pool.my_id_points (addr, port)) ->
|
||||||
Some (register_point pool info.peer_id (addr, port))
|
Some (register_point pool info.peer_id (addr, port))
|
||||||
| _ -> None in
|
| _ -> None in
|
||||||
let connection_point_info =
|
let connection_point_info =
|
||||||
@ -653,22 +648,22 @@ and authenticate pool ?point_info canceler fd point =
|
|||||||
| Some _ as point_info, _ | _, (Some _ as point_info) -> point_info in
|
| Some _ as point_info, _ | _, (Some _ as point_info) -> point_info in
|
||||||
let peer_info = register_peer pool info.peer_id in
|
let peer_info = register_peer pool info.peer_id in
|
||||||
let acceptable_versions =
|
let acceptable_versions =
|
||||||
Version.common info.versions pool.message_config.versions
|
P2p_version.common info.versions pool.message_config.versions
|
||||||
in
|
in
|
||||||
let acceptable_point =
|
let acceptable_point =
|
||||||
Option.unopt_map connection_point_info
|
Option.unopt_map connection_point_info
|
||||||
~default:(not pool.config.closed_network)
|
~default:(not pool.config.closed_network)
|
||||||
~f:begin fun connection_point_info ->
|
~f:begin fun connection_point_info ->
|
||||||
match Point_info.State.get connection_point_info with
|
match P2p_point.Pool_state.get connection_point_info with
|
||||||
| Requested _ -> not incoming
|
| Requested _ -> not incoming
|
||||||
| Disconnected ->
|
| Disconnected ->
|
||||||
not pool.config.closed_network
|
not pool.config.closed_network
|
||||||
|| Point_info.trusted connection_point_info
|
|| P2p_point.Pool_info.trusted connection_point_info
|
||||||
| Accepted _ | Running _ -> false
|
| Accepted _ | Running _ -> false
|
||||||
end
|
end
|
||||||
in
|
in
|
||||||
let acceptable_peer_id =
|
let acceptable_peer_id =
|
||||||
match Peer_info.State.get peer_info with
|
match P2p_peer.Pool_state.get peer_info with
|
||||||
| Accepted _ ->
|
| Accepted _ ->
|
||||||
(* TODO: in some circumstances cancel and accept... *)
|
(* TODO: in some circumstances cancel and accept... *)
|
||||||
false
|
false
|
||||||
@ -676,41 +671,41 @@ and authenticate pool ?point_info canceler fd point =
|
|||||||
| Disconnected -> true
|
| Disconnected -> true
|
||||||
in
|
in
|
||||||
if incoming then
|
if incoming then
|
||||||
Point.Table.remove pool.incoming point ;
|
P2p_point.Table.remove pool.incoming point ;
|
||||||
match acceptable_versions with
|
match acceptable_versions with
|
||||||
| Some version when acceptable_peer_id && acceptable_point -> begin
|
| Some version when acceptable_peer_id && acceptable_point -> begin
|
||||||
log pool (Accepting_request (point, info.id_point, info.peer_id)) ;
|
log pool (Accepting_request (point, info.id_point, info.peer_id)) ;
|
||||||
Option.iter connection_point_info
|
Option.iter connection_point_info
|
||||||
~f:(fun point_info ->
|
~f:(fun point_info ->
|
||||||
Point_info.State.set_accepted point_info info.peer_id canceler) ;
|
P2p_point.Pool_state.set_accepted point_info info.peer_id canceler) ;
|
||||||
Peer_info.State.set_accepted peer_info info.id_point canceler ;
|
P2p_peer.Pool_state.set_accepted peer_info info.id_point canceler ;
|
||||||
lwt_debug "authenticate: %a -> accept %a"
|
lwt_debug "authenticate: %a -> accept %a"
|
||||||
Point.pp point
|
P2p_point.Id.pp point
|
||||||
Connection_info.pp info >>= fun () ->
|
P2p_connection.Info.pp info >>= fun () ->
|
||||||
Lwt_utils.protect ~canceler begin fun () ->
|
Lwt_utils.protect ~canceler begin fun () ->
|
||||||
P2p_connection.accept
|
P2p_socket.accept
|
||||||
?incoming_message_queue_size:pool.config.incoming_message_queue_size
|
?incoming_message_queue_size:pool.config.incoming_message_queue_size
|
||||||
?outgoing_message_queue_size:pool.config.outgoing_message_queue_size
|
?outgoing_message_queue_size:pool.config.outgoing_message_queue_size
|
||||||
?binary_chunks_size:pool.config.binary_chunks_size
|
?binary_chunks_size:pool.config.binary_chunks_size
|
||||||
auth_fd pool.encoding >>= fun conn ->
|
auth_fd pool.encoding >>= fun conn ->
|
||||||
lwt_debug "authenticate: %a -> Connected %a"
|
lwt_debug "authenticate: %a -> Connected %a"
|
||||||
Point.pp point
|
P2p_point.Id.pp point
|
||||||
Connection_info.pp info >>= fun () ->
|
P2p_connection.Info.pp info >>= fun () ->
|
||||||
Lwt.return conn
|
Lwt.return conn
|
||||||
end ~on_error: begin fun err ->
|
end ~on_error: begin fun err ->
|
||||||
if incoming then
|
if incoming then
|
||||||
log pool
|
log pool
|
||||||
(Request_rejected (point, Some (info.id_point, info.peer_id))) ;
|
(Request_rejected (point, Some (info.id_point, info.peer_id))) ;
|
||||||
lwt_debug "authenticate: %a -> rejected %a"
|
lwt_debug "authenticate: %a -> rejected %a"
|
||||||
Point.pp point
|
P2p_point.Id.pp point
|
||||||
Connection_info.pp info >>= fun () ->
|
P2p_connection.Info.pp info >>= fun () ->
|
||||||
Option.iter connection_point_info
|
Option.iter connection_point_info
|
||||||
~f:Point_info.State.set_disconnected ;
|
~f:P2p_point.Pool_state.set_disconnected ;
|
||||||
Peer_info.State.set_disconnected peer_info ;
|
P2p_peer.Pool_state.set_disconnected peer_info ;
|
||||||
Lwt.return (Error err)
|
Lwt.return (Error err)
|
||||||
end >>=? fun conn ->
|
end >>=? fun conn ->
|
||||||
let id_point =
|
let id_point =
|
||||||
match info.id_point, Option.map ~f:Point_info.point point_info with
|
match info.id_point, Option.map ~f:P2p_point.Pool_info.point point_info with
|
||||||
| (addr, _), Some (_, port) -> addr, Some port
|
| (addr, _), Some (_, port) -> addr, Some port
|
||||||
| id_point, None -> id_point in
|
| id_point, None -> id_point in
|
||||||
return
|
return
|
||||||
@ -721,19 +716,19 @@ and authenticate pool ?point_info canceler fd point =
|
|||||||
| _ -> begin
|
| _ -> begin
|
||||||
log pool (Rejecting_request (point, info.id_point, info.peer_id)) ;
|
log pool (Rejecting_request (point, info.id_point, info.peer_id)) ;
|
||||||
lwt_debug "authenticate: %a -> kick %a point: %B peer_id: %B"
|
lwt_debug "authenticate: %a -> kick %a point: %B peer_id: %B"
|
||||||
Point.pp point
|
P2p_point.Id.pp point
|
||||||
Connection_info.pp info
|
P2p_connection.Info.pp info
|
||||||
acceptable_point acceptable_peer_id >>= fun () ->
|
acceptable_point acceptable_peer_id >>= fun () ->
|
||||||
P2p_connection.kick auth_fd >>= fun () ->
|
P2p_socket.kick auth_fd >>= fun () ->
|
||||||
if not incoming then begin
|
if not incoming then begin
|
||||||
Option.iter ~f:Point_info.State.set_disconnected point_info ;
|
Option.iter ~f:P2p_point.Pool_state.set_disconnected point_info ;
|
||||||
(* FIXME Peer_info.State.set_disconnected ~requested:true peer_info ; *)
|
(* FIXME P2p_peer.Pool_state.set_disconnected ~requested:true peer_info ; *)
|
||||||
end ;
|
end ;
|
||||||
fail (Rejected info.peer_id)
|
fail (Rejected info.peer_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
and create_connection pool p2p_conn id_point point_info peer_info _version =
|
and create_connection pool p2p_conn id_point point_info peer_info _version =
|
||||||
let peer_id = Peer_info.peer_id peer_info in
|
let peer_id = P2p_peer.Pool_info.peer_id peer_info in
|
||||||
let canceler = Lwt_canceler.create () in
|
let canceler = Lwt_canceler.create () in
|
||||||
let size =
|
let size =
|
||||||
Option.map pool.config.incoming_app_message_queue_size
|
Option.map pool.config.incoming_app_message_queue_size
|
||||||
@ -759,30 +754,30 @@ and create_connection pool p2p_conn id_point point_info peer_info _version =
|
|||||||
last_sent_swap_request = None } in
|
last_sent_swap_request = None } in
|
||||||
ignore (Lazy.force answerer) ;
|
ignore (Lazy.force answerer) ;
|
||||||
Option.iter point_info ~f:begin fun point_info ->
|
Option.iter point_info ~f:begin fun point_info ->
|
||||||
let point = Point_info.point point_info in
|
let point = P2p_point.Pool_info.point point_info in
|
||||||
Point_info.State.set_running point_info peer_id conn ;
|
P2p_point.Pool_state.set_running point_info peer_id conn ;
|
||||||
Point.Table.add pool.connected_points point point_info ;
|
P2p_point.Table.add pool.connected_points point point_info ;
|
||||||
end ;
|
end ;
|
||||||
log pool (Connection_established (id_point, peer_id)) ;
|
log pool (Connection_established (id_point, peer_id)) ;
|
||||||
Peer_info.State.set_running peer_info id_point conn ;
|
P2p_peer.Pool_state.set_running peer_info id_point conn ;
|
||||||
Peer_id.Table.add pool.connected_peer_ids peer_id peer_info ;
|
P2p_peer.Table.add pool.connected_peer_ids peer_id peer_info ;
|
||||||
Lwt_condition.broadcast pool.events.new_connection () ;
|
Lwt_condition.broadcast pool.events.new_connection () ;
|
||||||
Lwt_canceler.on_cancel canceler begin fun () ->
|
Lwt_canceler.on_cancel canceler begin fun () ->
|
||||||
lwt_debug "Disconnect: %a (%a)"
|
lwt_debug "Disconnect: %a (%a)"
|
||||||
Peer_id.pp peer_id Id_point.pp id_point >>= fun () ->
|
P2p_peer.Id.pp peer_id P2p_connection.Id.pp id_point >>= fun () ->
|
||||||
Option.iter ~f:Point_info.State.set_disconnected point_info ;
|
Option.iter ~f:P2p_point.Pool_state.set_disconnected point_info ;
|
||||||
log pool (Disconnection peer_id) ;
|
log pool (Disconnection peer_id) ;
|
||||||
Peer_info.State.set_disconnected peer_info ;
|
P2p_peer.Pool_state.set_disconnected peer_info ;
|
||||||
Option.iter point_info ~f:begin fun point_info ->
|
Option.iter point_info ~f:begin fun point_info ->
|
||||||
Point.Table.remove pool.connected_points (Point_info.point point_info) ;
|
P2p_point.Table.remove pool.connected_points (P2p_point.Pool_info.point point_info) ;
|
||||||
end ;
|
end ;
|
||||||
Peer_id.Table.remove pool.connected_peer_ids peer_id ;
|
P2p_peer.Table.remove pool.connected_peer_ids peer_id ;
|
||||||
if pool.config.max_connections <= active_connections pool then begin
|
if pool.config.max_connections <= active_connections pool then begin
|
||||||
Lwt_condition.broadcast pool.events.too_many_connections () ;
|
Lwt_condition.broadcast pool.events.too_many_connections () ;
|
||||||
log pool Too_many_connections ;
|
log pool Too_many_connections ;
|
||||||
end ;
|
end ;
|
||||||
Lwt_pipe.close messages ;
|
Lwt_pipe.close messages ;
|
||||||
P2p_connection.close ~wait:conn.wait_close conn.conn
|
P2p_socket.close ~wait:conn.wait_close conn.conn
|
||||||
end ;
|
end ;
|
||||||
List.iter (fun f -> f peer_id conn) pool.new_connection_hook ;
|
List.iter (fun f -> f peer_id conn) pool.new_connection_hook ;
|
||||||
if active_connections pool < pool.config.min_connections then begin
|
if active_connections pool < pool.config.min_connections then begin
|
||||||
@ -796,31 +791,31 @@ and disconnect ?(wait = false) conn =
|
|||||||
Answerer.shutdown (Lazy.force conn.answerer)
|
Answerer.shutdown (Lazy.force conn.answerer)
|
||||||
|
|
||||||
and register_new_points pool conn =
|
and register_new_points pool conn =
|
||||||
let source_peer_id = Peer_info.peer_id conn.peer_info in
|
let source_peer_id = P2p_peer.Pool_info.peer_id conn.peer_info in
|
||||||
fun points ->
|
fun points ->
|
||||||
List.iter (register_new_point pool source_peer_id) points ;
|
List.iter (register_new_point pool source_peer_id) points ;
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
|
|
||||||
and register_new_point pool _source_peer_id point =
|
and register_new_point pool _source_peer_id point =
|
||||||
if not (Point.Table.mem pool.my_id_points point) then
|
if not (P2p_point.Table.mem pool.my_id_points point) then
|
||||||
ignore (register_point pool _source_peer_id point)
|
ignore (register_point pool _source_peer_id point)
|
||||||
|
|
||||||
and list_known_points pool _conn () =
|
and list_known_points pool _conn () =
|
||||||
let knowns =
|
let knowns =
|
||||||
Point.Table.fold
|
P2p_point.Table.fold
|
||||||
(fun _ point_info acc -> point_info :: acc)
|
(fun _ point_info acc -> point_info :: acc)
|
||||||
pool.known_points [] in
|
pool.known_points [] in
|
||||||
let best_knowns =
|
let best_knowns =
|
||||||
List.take_n ~compare:compare_known_point_info 50 knowns in
|
List.take_n ~compare:compare_known_point_info 50 knowns in
|
||||||
Lwt.return (List.map Point_info.point best_knowns)
|
Lwt.return (List.map P2p_point.Pool_info.point best_knowns)
|
||||||
|
|
||||||
and active_connections pool = Peer_id.Table.length pool.connected_peer_ids
|
and active_connections pool = P2p_peer.Table.length pool.connected_peer_ids
|
||||||
|
|
||||||
and swap_request pool conn new_point _new_peer_id =
|
and swap_request pool conn new_point _new_peer_id =
|
||||||
let source_peer_id = Peer_info.peer_id conn.peer_info in
|
let source_peer_id = P2p_peer.Pool_info.peer_id conn.peer_info in
|
||||||
log pool (Swap_request_received { source = source_peer_id }) ;
|
log pool (Swap_request_received { source = source_peer_id }) ;
|
||||||
lwt_log_info
|
lwt_log_info
|
||||||
"Swap request received from %a" Peer_id.pp source_peer_id >>= fun () ->
|
"Swap request received from %a" P2p_peer.Id.pp source_peer_id >>= fun () ->
|
||||||
(* Ignore if already connected to peer or already swapped less
|
(* Ignore if already connected to peer or already swapped less
|
||||||
than <swap_linger> seconds ago. *)
|
than <swap_linger> seconds ago. *)
|
||||||
let now = Time.now () in
|
let now = Time.now () in
|
||||||
@ -830,16 +825,16 @@ and swap_request pool conn new_point _new_peer_id =
|
|||||||
(Time.max pool.latest_succesfull_swap pool.latest_accepted_swap) in
|
(Time.max pool.latest_succesfull_swap pool.latest_accepted_swap) in
|
||||||
let new_point_info = register_point pool source_peer_id new_point in
|
let new_point_info = register_point pool source_peer_id new_point in
|
||||||
if span_since_last_swap < int_of_float pool.config.swap_linger
|
if span_since_last_swap < int_of_float pool.config.swap_linger
|
||||||
|| not (Point_info.State.is_disconnected new_point_info) then begin
|
|| not (P2p_point.Pool_state.is_disconnected new_point_info) then begin
|
||||||
log pool (Swap_request_ignored { source = source_peer_id }) ;
|
log pool (Swap_request_ignored { source = source_peer_id }) ;
|
||||||
lwt_log_info "Ignoring swap request from %a" Peer_id.pp source_peer_id
|
lwt_log_info "Ignoring swap request from %a" P2p_peer.Id.pp source_peer_id
|
||||||
end else begin
|
end else begin
|
||||||
match Connection.random_lowid pool with
|
match Connection.random_lowid pool with
|
||||||
| None ->
|
| None ->
|
||||||
lwt_log_info
|
lwt_log_info
|
||||||
"No swap candidate for %a" Peer_id.pp source_peer_id
|
"No swap candidate for %a" P2p_peer.Id.pp source_peer_id
|
||||||
| Some (proposed_point, proposed_peer_id, _proposed_conn) ->
|
| Some (proposed_point, proposed_peer_id, _proposed_conn) ->
|
||||||
match P2p_connection.write_now
|
match P2p_socket.write_now
|
||||||
conn.conn (Swap_ack (proposed_point, proposed_peer_id)) with
|
conn.conn (Swap_ack (proposed_point, proposed_peer_id)) with
|
||||||
| Ok true ->
|
| Ok true ->
|
||||||
log pool (Swap_ack_sent { source = source_peer_id }) ;
|
log pool (Swap_ack_sent { source = source_peer_id }) ;
|
||||||
@ -854,10 +849,10 @@ and swap_request pool conn new_point _new_peer_id =
|
|||||||
end
|
end
|
||||||
|
|
||||||
and swap_ack pool conn new_point _new_peer_id =
|
and swap_ack pool conn new_point _new_peer_id =
|
||||||
let source_peer_id = Peer_info.peer_id conn.peer_info in
|
let source_peer_id = P2p_peer.Pool_info.peer_id conn.peer_info in
|
||||||
log pool (Swap_ack_received { source = source_peer_id }) ;
|
log pool (Swap_ack_received { source = source_peer_id }) ;
|
||||||
lwt_log_info
|
lwt_log_info
|
||||||
"Swap ack received from %a" Peer_id.pp source_peer_id >>= fun () ->
|
"Swap ack received from %a" P2p_peer.Id.pp source_peer_id >>= fun () ->
|
||||||
match conn.last_sent_swap_request with
|
match conn.last_sent_swap_request with
|
||||||
| None -> Lwt.return_unit (* ignore *)
|
| None -> Lwt.return_unit (* ignore *)
|
||||||
| Some (_time, proposed_peer_id) ->
|
| Some (_time, proposed_peer_id) ->
|
||||||
@ -869,13 +864,13 @@ and swap_ack pool conn new_point _new_peer_id =
|
|||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
|
|
||||||
and swap pool conn current_peer_id new_point =
|
and swap pool conn current_peer_id new_point =
|
||||||
let source_peer_id = Peer_info.peer_id conn.peer_info in
|
let source_peer_id = P2p_peer.Pool_info.peer_id conn.peer_info in
|
||||||
pool.latest_accepted_swap <- Time.now () ;
|
pool.latest_accepted_swap <- Time.now () ;
|
||||||
connect ~timeout:10. pool new_point >>= function
|
connect ~timeout:10. pool new_point >>= function
|
||||||
| Ok _new_conn -> begin
|
| Ok _new_conn -> begin
|
||||||
pool.latest_succesfull_swap <- Time.now () ;
|
pool.latest_succesfull_swap <- Time.now () ;
|
||||||
log pool (Swap_success { source = source_peer_id }) ;
|
log pool (Swap_success { source = source_peer_id }) ;
|
||||||
lwt_log_info "Swap to %a succeeded" Point.pp new_point >>= fun () ->
|
lwt_log_info "Swap to %a succeeded" P2p_point.Id.pp new_point >>= fun () ->
|
||||||
match Connection.find_by_peer_id pool current_peer_id with
|
match Connection.find_by_peer_id pool current_peer_id with
|
||||||
| None -> Lwt.return_unit
|
| None -> Lwt.return_unit
|
||||||
| Some conn ->
|
| Some conn ->
|
||||||
@ -888,20 +883,20 @@ and swap pool conn current_peer_id new_point =
|
|||||||
match err with
|
match err with
|
||||||
| [ Lwt_utils.Timeout ] ->
|
| [ Lwt_utils.Timeout ] ->
|
||||||
lwt_debug "Swap to %a was interupted: %a"
|
lwt_debug "Swap to %a was interupted: %a"
|
||||||
Point.pp new_point pp_print_error err
|
P2p_point.Id.pp new_point pp_print_error err
|
||||||
| _ ->
|
| _ ->
|
||||||
lwt_log_error "Swap to %a failed: %a"
|
lwt_log_error "Swap to %a failed: %a"
|
||||||
Point.pp new_point pp_print_error err
|
P2p_point.Id.pp new_point pp_print_error err
|
||||||
end
|
end
|
||||||
|
|
||||||
let accept pool fd point =
|
let accept pool fd point =
|
||||||
log pool (Incoming_connection point) ;
|
log pool (Incoming_connection point) ;
|
||||||
if pool.config.max_incoming_connections <= Point.Table.length pool.incoming
|
if pool.config.max_incoming_connections <= P2p_point.Table.length pool.incoming
|
||||||
|| pool.config.max_connections <= active_connections pool then
|
|| pool.config.max_connections <= active_connections pool then
|
||||||
Lwt.async (fun () -> Lwt_utils.safe_close fd)
|
Lwt.async (fun () -> Lwt_utils.safe_close fd)
|
||||||
else
|
else
|
||||||
let canceler = Lwt_canceler.create () in
|
let canceler = Lwt_canceler.create () in
|
||||||
Point.Table.add pool.incoming point canceler ;
|
P2p_point.Table.add pool.incoming point canceler ;
|
||||||
Lwt.async begin fun () ->
|
Lwt.async begin fun () ->
|
||||||
Lwt_utils.with_timeout
|
Lwt_utils.with_timeout
|
||||||
~canceler pool.config.authentification_timeout
|
~canceler pool.config.authentification_timeout
|
||||||
@ -919,7 +914,7 @@ let send_swap_request pool =
|
|||||||
log pool (Swap_request_sent { source = recipient_peer_id }) ;
|
log pool (Swap_request_sent { source = recipient_peer_id }) ;
|
||||||
recipient.last_sent_swap_request <-
|
recipient.last_sent_swap_request <-
|
||||||
Some (Time.now (), proposed_peer_id) ;
|
Some (Time.now (), proposed_peer_id) ;
|
||||||
ignore (P2p_connection.write_now recipient.conn
|
ignore (P2p_socket.write_now recipient.conn
|
||||||
(Swap_request (proposed_point, proposed_peer_id)))
|
(Swap_request (proposed_point, proposed_peer_id)))
|
||||||
|
|
||||||
(***************************************************************************)
|
(***************************************************************************)
|
||||||
@ -933,12 +928,12 @@ let create config meta_config message_config io_sched =
|
|||||||
} in
|
} in
|
||||||
let pool = {
|
let pool = {
|
||||||
config ; meta_config ; message_config ;
|
config ; meta_config ; message_config ;
|
||||||
my_id_points = Point.Table.create 7 ;
|
my_id_points = P2p_point.Table.create 7 ;
|
||||||
known_peer_ids = Peer_id.Table.create 53 ;
|
known_peer_ids = P2p_peer.Table.create 53 ;
|
||||||
connected_peer_ids = Peer_id.Table.create 53 ;
|
connected_peer_ids = P2p_peer.Table.create 53 ;
|
||||||
known_points = Point.Table.create 53 ;
|
known_points = P2p_point.Table.create 53 ;
|
||||||
connected_points = Point.Table.create 53 ;
|
connected_points = P2p_point.Table.create 53 ;
|
||||||
incoming = Point.Table.create 53 ;
|
incoming = P2p_point.Table.create 53 ;
|
||||||
io_sched ;
|
io_sched ;
|
||||||
encoding = Message.encoding message_config.encoding ;
|
encoding = Message.encoding message_config.encoding ;
|
||||||
events ;
|
events ;
|
||||||
@ -948,12 +943,12 @@ let create config meta_config message_config io_sched =
|
|||||||
latest_succesfull_swap = Time.epoch ;
|
latest_succesfull_swap = Time.epoch ;
|
||||||
} in
|
} in
|
||||||
List.iter (Points.set_trusted pool) config.trusted_points ;
|
List.iter (Points.set_trusted pool) config.trusted_points ;
|
||||||
Peer_info.File.load config.peers_file meta_config.encoding >>= function
|
P2p_peer.Pool_info.File.load config.peers_file meta_config.encoding >>= function
|
||||||
| Ok peer_ids ->
|
| Ok peer_ids ->
|
||||||
List.iter
|
List.iter
|
||||||
(fun peer_info ->
|
(fun peer_info ->
|
||||||
let peer_id = Peer_info.peer_id peer_info in
|
let peer_id = P2p_peer.Pool_info.peer_id peer_info in
|
||||||
Peer_id.Table.add pool.known_peer_ids peer_id peer_info)
|
P2p_peer.Table.add pool.known_peer_ids peer_id peer_info)
|
||||||
peer_ids ;
|
peer_ids ;
|
||||||
Lwt.return pool
|
Lwt.return pool
|
||||||
| Error err ->
|
| Error err ->
|
||||||
@ -962,23 +957,23 @@ let create config meta_config message_config io_sched =
|
|||||||
Lwt.return pool
|
Lwt.return pool
|
||||||
|
|
||||||
let destroy pool =
|
let destroy pool =
|
||||||
Point.Table.fold (fun _point point_info acc ->
|
P2p_point.Table.fold (fun _point point_info acc ->
|
||||||
match Point_info.State.get point_info with
|
match P2p_point.Pool_state.get point_info with
|
||||||
| Requested { cancel } | Accepted { cancel } ->
|
| Requested { cancel } | Accepted { cancel } ->
|
||||||
Lwt_canceler.cancel cancel >>= fun () -> acc
|
Lwt_canceler.cancel cancel >>= fun () -> acc
|
||||||
| Running { data = conn } ->
|
| Running { data = conn } ->
|
||||||
disconnect conn >>= fun () -> acc
|
disconnect conn >>= fun () -> acc
|
||||||
| Disconnected -> acc)
|
| Disconnected -> acc)
|
||||||
pool.known_points @@
|
pool.known_points @@
|
||||||
Peer_id.Table.fold (fun _peer_id peer_info acc ->
|
P2p_peer.Table.fold (fun _peer_id peer_info acc ->
|
||||||
match Peer_info.State.get peer_info with
|
match P2p_peer.Pool_state.get peer_info with
|
||||||
| Accepted { cancel } ->
|
| Accepted { cancel } ->
|
||||||
Lwt_canceler.cancel cancel >>= fun () -> acc
|
Lwt_canceler.cancel cancel >>= fun () -> acc
|
||||||
| Running { data = conn } ->
|
| Running { data = conn } ->
|
||||||
disconnect conn >>= fun () -> acc
|
disconnect conn >>= fun () -> acc
|
||||||
| Disconnected -> acc)
|
| Disconnected -> acc)
|
||||||
pool.known_peer_ids @@
|
pool.known_peer_ids @@
|
||||||
Point.Table.fold (fun _point canceler acc ->
|
P2p_point.Table.fold (fun _point canceler acc ->
|
||||||
Lwt_canceler.cancel canceler >>= fun () -> acc)
|
Lwt_canceler.cancel canceler >>= fun () -> acc)
|
||||||
pool.incoming Lwt.return_unit
|
pool.incoming Lwt.return_unit
|
||||||
|
|
@ -22,9 +22,6 @@
|
|||||||
worker and thus never propagated above.
|
worker and thus never propagated above.
|
||||||
*)
|
*)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
open P2p_connection_pool_types
|
|
||||||
|
|
||||||
type 'msg encoding = Encoding : {
|
type 'msg encoding = Encoding : {
|
||||||
tag: int ;
|
tag: int ;
|
||||||
encoding: 'a Data_encoding.t ;
|
encoding: 'a Data_encoding.t ;
|
||||||
@ -43,13 +40,13 @@ type ('msg, 'meta) pool = ('msg, 'meta) t
|
|||||||
|
|
||||||
type config = {
|
type config = {
|
||||||
|
|
||||||
identity : Identity.t ;
|
identity : P2p_identity.t ;
|
||||||
(** Our identity. *)
|
(** Our identity. *)
|
||||||
|
|
||||||
proof_of_work_target : Crypto_box.target ;
|
proof_of_work_target : Crypto_box.target ;
|
||||||
(** The proof of work target we require from peers. *)
|
(** The proof of work target we require from peers. *)
|
||||||
|
|
||||||
trusted_points : Point.t list ;
|
trusted_points : P2p_point.Id.t list ;
|
||||||
(** List of hard-coded known peers to bootstrap the network from. *)
|
(** List of hard-coded known peers to bootstrap the network from. *)
|
||||||
|
|
||||||
peers_file : string ;
|
peers_file : string ;
|
||||||
@ -60,7 +57,7 @@ type config = {
|
|||||||
(** If [true], the only accepted connections are from peers whose
|
(** If [true], the only accepted connections are from peers whose
|
||||||
addresses are in [trusted_peers]. *)
|
addresses are in [trusted_peers]. *)
|
||||||
|
|
||||||
listening_port : port option ;
|
listening_port : P2p_addr.port option ;
|
||||||
(** If provided, it will be passed to [P2p_connection.authenticate]
|
(** If provided, it will be passed to [P2p_connection.authenticate]
|
||||||
when we authenticate against a new peer. *)
|
when we authenticate against a new peer. *)
|
||||||
|
|
||||||
@ -126,7 +123,7 @@ type 'meta meta_config = {
|
|||||||
|
|
||||||
type 'msg message_config = {
|
type 'msg message_config = {
|
||||||
encoding : 'msg encoding list ;
|
encoding : 'msg encoding list ;
|
||||||
versions : P2p_types.Version.t list;
|
versions : P2p_version.t list;
|
||||||
}
|
}
|
||||||
|
|
||||||
val create:
|
val create:
|
||||||
@ -146,7 +143,7 @@ val active_connections: ('msg, 'meta) pool -> int
|
|||||||
(** [active_connections pool] is the number of connections inside
|
(** [active_connections pool] is the number of connections inside
|
||||||
[pool]. *)
|
[pool]. *)
|
||||||
|
|
||||||
val pool_stat: ('msg, 'meta) pool -> Stat.t
|
val pool_stat: ('msg, 'meta) pool -> P2p_stat.t
|
||||||
(** [pool_stat pool] is a snapshot of current bandwidth usage for the
|
(** [pool_stat pool] is a snapshot of current bandwidth usage for the
|
||||||
entire [pool]. *)
|
entire [pool]. *)
|
||||||
|
|
||||||
@ -186,19 +183,19 @@ type ('msg, 'meta) connection
|
|||||||
type error += Pending_connection
|
type error += Pending_connection
|
||||||
type error += Connected
|
type error += Connected
|
||||||
type error += Connection_refused
|
type error += Connection_refused
|
||||||
type error += Rejected of Peer_id.t
|
type error += Rejected of P2p_peer.Id.t
|
||||||
type error += Too_many_connections
|
type error += Too_many_connections
|
||||||
type error += Closed_network
|
type error += Closed_network
|
||||||
|
|
||||||
val connect:
|
val connect:
|
||||||
timeout:float ->
|
timeout:float ->
|
||||||
('msg, 'meta) pool -> Point.t ->
|
('msg, 'meta) pool -> P2p_point.Id.t ->
|
||||||
('msg, 'meta) connection tzresult Lwt.t
|
('msg, 'meta) connection tzresult Lwt.t
|
||||||
(** [connect ~timeout pool point] tries to add a
|
(** [connect ~timeout pool point] tries to add a
|
||||||
connection to [point] in [pool] in less than [timeout] seconds. *)
|
connection to [point] in [pool] in less than [timeout] seconds. *)
|
||||||
|
|
||||||
val accept:
|
val accept:
|
||||||
('msg, 'meta) pool -> Lwt_unix.file_descr -> Point.t -> unit
|
('msg, 'meta) pool -> Lwt_unix.file_descr -> P2p_point.Id.t -> unit
|
||||||
(** [accept pool fd point] instructs [pool] to start the process of
|
(** [accept pool fd point] instructs [pool] to start the process of
|
||||||
accepting a connection from [fd]. Used by [P2p]. *)
|
accepting a connection from [fd]. Used by [P2p]. *)
|
||||||
|
|
||||||
@ -209,32 +206,32 @@ val disconnect:
|
|||||||
|
|
||||||
module Connection : sig
|
module Connection : sig
|
||||||
|
|
||||||
val info: ('msg, 'meta) connection -> Connection_info.t
|
val info: ('msg, 'meta) connection -> P2p_connection.Info.t
|
||||||
|
|
||||||
val stat: ('msg, 'meta) connection -> Stat.t
|
val stat: ('msg, 'meta) connection -> P2p_stat.t
|
||||||
(** [stat conn] is a snapshot of current bandwidth usage for
|
(** [stat conn] is a snapshot of current bandwidth usage for
|
||||||
[conn]. *)
|
[conn]. *)
|
||||||
|
|
||||||
val fold:
|
val fold:
|
||||||
('msg, 'meta) pool ->
|
('msg, 'meta) pool ->
|
||||||
init:'a ->
|
init:'a ->
|
||||||
f:(Peer_id.t -> ('msg, 'meta) connection -> 'a -> 'a) ->
|
f:(P2p_peer.Id.t -> ('msg, 'meta) connection -> 'a -> 'a) ->
|
||||||
'a
|
'a
|
||||||
|
|
||||||
val list:
|
val list:
|
||||||
('msg, 'meta) pool -> (Peer_id.t * ('msg, 'meta) connection) list
|
('msg, 'meta) pool -> (P2p_peer.Id.t * ('msg, 'meta) connection) list
|
||||||
|
|
||||||
val find_by_point:
|
val find_by_point:
|
||||||
('msg, 'meta) pool -> Point.t -> ('msg, 'meta) connection option
|
('msg, 'meta) pool -> P2p_point.Id.t -> ('msg, 'meta) connection option
|
||||||
|
|
||||||
val find_by_peer_id:
|
val find_by_peer_id:
|
||||||
('msg, 'meta) pool -> Peer_id.t -> ('msg, 'meta) connection option
|
('msg, 'meta) pool -> P2p_peer.Id.t -> ('msg, 'meta) connection option
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
val on_new_connection:
|
val on_new_connection:
|
||||||
('msg, 'meta) pool ->
|
('msg, 'meta) pool ->
|
||||||
(Peer_id.t -> ('msg, 'meta) connection -> unit) -> unit
|
(P2p_peer.Id.t -> ('msg, 'meta) connection -> unit) -> unit
|
||||||
|
|
||||||
(** {1 I/O on connections} *)
|
(** {1 I/O on connections} *)
|
||||||
|
|
||||||
@ -277,31 +274,31 @@ val broadcast_bootstrap_msg: ('msg, 'meta) pool -> unit
|
|||||||
|
|
||||||
(** {1 Functions on [Peer_id]} *)
|
(** {1 Functions on [Peer_id]} *)
|
||||||
|
|
||||||
module Peer_ids : sig
|
module Peers : sig
|
||||||
|
|
||||||
type ('msg, 'meta) info = (('msg, 'meta) connection, 'meta) Peer_info.t
|
type ('msg, 'meta) info = (('msg, 'meta) connection, 'meta) P2p_peer.Pool_info.t
|
||||||
|
|
||||||
val info:
|
val info:
|
||||||
('msg, 'meta) pool -> Peer_id.t -> ('msg, 'meta) info option
|
('msg, 'meta) pool -> P2p_peer.Id.t -> ('msg, 'meta) info option
|
||||||
|
|
||||||
val get_metadata: ('msg, 'meta) pool -> Peer_id.t -> 'meta
|
val get_metadata: ('msg, 'meta) pool -> P2p_peer.Id.t -> 'meta
|
||||||
val set_metadata: ('msg, 'meta) pool -> Peer_id.t -> 'meta -> unit
|
val set_metadata: ('msg, 'meta) pool -> P2p_peer.Id.t -> 'meta -> unit
|
||||||
val get_score: ('msg, 'meta) pool -> Peer_id.t -> float
|
val get_score: ('msg, 'meta) pool -> P2p_peer.Id.t -> float
|
||||||
|
|
||||||
val get_trusted: ('msg, 'meta) pool -> Peer_id.t -> bool
|
val get_trusted: ('msg, 'meta) pool -> P2p_peer.Id.t -> bool
|
||||||
val set_trusted: ('msg, 'meta) pool -> Peer_id.t -> unit
|
val set_trusted: ('msg, 'meta) pool -> P2p_peer.Id.t -> unit
|
||||||
val unset_trusted: ('msg, 'meta) pool -> Peer_id.t -> unit
|
val unset_trusted: ('msg, 'meta) pool -> P2p_peer.Id.t -> unit
|
||||||
|
|
||||||
val fold_known:
|
val fold_known:
|
||||||
('msg, 'meta) pool ->
|
('msg, 'meta) pool ->
|
||||||
init:'a ->
|
init:'a ->
|
||||||
f:(Peer_id.t -> ('msg, 'meta) info -> 'a -> 'a) ->
|
f:(P2p_peer.Id.t -> ('msg, 'meta) info -> 'a -> 'a) ->
|
||||||
'a
|
'a
|
||||||
|
|
||||||
val fold_connected:
|
val fold_connected:
|
||||||
('msg, 'meta) pool ->
|
('msg, 'meta) pool ->
|
||||||
init:'a ->
|
init:'a ->
|
||||||
f:(Peer_id.t -> ('msg, 'meta) info -> 'a -> 'a) ->
|
f:(P2p_peer.Id.t -> ('msg, 'meta) info -> 'a -> 'a) ->
|
||||||
'a
|
'a
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -310,32 +307,30 @@ end
|
|||||||
|
|
||||||
module Points : sig
|
module Points : sig
|
||||||
|
|
||||||
type ('msg, 'meta) info = ('msg, 'meta) connection Point_info.t
|
type ('msg, 'meta) info = ('msg, 'meta) connection P2p_point.Pool_info.t
|
||||||
|
|
||||||
val info:
|
val info:
|
||||||
('msg, 'meta) pool -> Point.t -> ('msg, 'meta) info option
|
('msg, 'meta) pool -> P2p_point.Id.t -> ('msg, 'meta) info option
|
||||||
|
|
||||||
val get_trusted: ('msg, 'meta) pool -> Point.t -> bool
|
val get_trusted: ('msg, 'meta) pool -> P2p_point.Id.t -> bool
|
||||||
val set_trusted: ('msg, 'meta) pool -> Point.t -> unit
|
val set_trusted: ('msg, 'meta) pool -> P2p_point.Id.t -> unit
|
||||||
val unset_trusted: ('msg, 'meta) pool -> Point.t -> unit
|
val unset_trusted: ('msg, 'meta) pool -> P2p_point.Id.t -> unit
|
||||||
|
|
||||||
val fold_known:
|
val fold_known:
|
||||||
('msg, 'meta) pool ->
|
('msg, 'meta) pool ->
|
||||||
init:'a ->
|
init:'a ->
|
||||||
f:(Point.t -> ('msg, 'meta) info -> 'a -> 'a) ->
|
f:(P2p_point.Id.t -> ('msg, 'meta) info -> 'a -> 'a) ->
|
||||||
'a
|
'a
|
||||||
|
|
||||||
val fold_connected:
|
val fold_connected:
|
||||||
('msg, 'meta) pool ->
|
('msg, 'meta) pool ->
|
||||||
init:'a ->
|
init:'a ->
|
||||||
f:(Point.t -> ('msg, 'meta) info -> 'a -> 'a) ->
|
f:(P2p_point.Id.t -> ('msg, 'meta) info -> 'a -> 'a) ->
|
||||||
'a
|
'a
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Log_event = Connection_pool_log_event
|
val watch: ('msg, 'meta) pool -> P2p_connection.Pool_event.t Lwt_stream.t * Lwt_watcher.stopper
|
||||||
|
|
||||||
val watch: ('msg, 'meta) pool -> Log_event.t Lwt_stream.t * Lwt_watcher.stopper
|
|
||||||
(** [watch pool] is a [stream, close] a [stream] of events and a
|
(** [watch pool] is a [stream, close] a [stream] of events and a
|
||||||
[close] function for this stream. *)
|
[close] function for this stream. *)
|
||||||
|
|
||||||
@ -345,9 +340,9 @@ module Message : sig
|
|||||||
|
|
||||||
type 'msg t =
|
type 'msg t =
|
||||||
| Bootstrap
|
| Bootstrap
|
||||||
| Advertise of Point.t list
|
| Advertise of P2p_point.Id.t list
|
||||||
| Swap_request of Point.t * Peer_id.t
|
| Swap_request of P2p_point.Id.t * P2p_peer.Id.t
|
||||||
| Swap_ack of Point.t * Peer_id.t
|
| Swap_ack of P2p_point.Id.t * P2p_peer.Id.t
|
||||||
| Message of 'msg
|
| Message of 'msg
|
||||||
| Disconnect
|
| Disconnect
|
||||||
|
|
@ -19,8 +19,6 @@
|
|||||||
infinitly. This would avoid the real peer to talk with us. And
|
infinitly. This would avoid the real peer to talk with us. And
|
||||||
this might also have an influence on its "score". *)
|
this might also have an influence on its "score". *)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
|
|
||||||
include Logging.Make(struct let name = "p2p.connection" end)
|
include Logging.Make(struct let name = "p2p.connection" end)
|
||||||
|
|
||||||
type error += Decipher_error
|
type error += Decipher_error
|
||||||
@ -28,8 +26,8 @@ type error += Invalid_message_size
|
|||||||
type error += Encoding_error
|
type error += Encoding_error
|
||||||
type error += Rejected
|
type error += Rejected
|
||||||
type error += Decoding_error
|
type error += Decoding_error
|
||||||
type error += Myself of Id_point.t
|
type error += Myself of P2p_connection.Id.t
|
||||||
type error += Not_enough_proof_of_work of Peer_id.t
|
type error += Not_enough_proof_of_work of P2p_peer.Id.t
|
||||||
type error += Invalid_auth
|
type error += Invalid_auth
|
||||||
type error += Invalid_chunks_size of { value: int ; min: int ; max: int }
|
type error += Invalid_chunks_size of { value: int ; min: int ; max: int }
|
||||||
|
|
||||||
@ -94,7 +92,7 @@ module Connection_message = struct
|
|||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
port : int option ;
|
port : int option ;
|
||||||
versions : Version.t list ;
|
versions : P2p_version.t list ;
|
||||||
public_key : Crypto_box.public_key ;
|
public_key : Crypto_box.public_key ;
|
||||||
proof_of_work_stamp : Crypto_box.nonce ;
|
proof_of_work_stamp : Crypto_box.nonce ;
|
||||||
message_nonce : Crypto_box.nonce ;
|
message_nonce : Crypto_box.nonce ;
|
||||||
@ -118,7 +116,7 @@ module Connection_message = struct
|
|||||||
(req "pubkey" Crypto_box.public_key_encoding)
|
(req "pubkey" Crypto_box.public_key_encoding)
|
||||||
(req "proof_of_work_stamp" Crypto_box.nonce_encoding)
|
(req "proof_of_work_stamp" Crypto_box.nonce_encoding)
|
||||||
(req "message_nonce" Crypto_box.nonce_encoding)
|
(req "message_nonce" Crypto_box.nonce_encoding)
|
||||||
(req "versions" (Variable.list Version.encoding)))
|
(req "versions" (Variable.list P2p_version.encoding)))
|
||||||
|
|
||||||
let write fd message =
|
let write fd message =
|
||||||
let encoded_message_len =
|
let encoded_message_len =
|
||||||
@ -172,7 +170,7 @@ module Ack = struct
|
|||||||
end
|
end
|
||||||
|
|
||||||
type authenticated_fd =
|
type authenticated_fd =
|
||||||
P2p_io_scheduler.connection * Connection_info.t * Crypto.data
|
P2p_io_scheduler.connection * P2p_connection.Info.t * Crypto.data
|
||||||
|
|
||||||
let kick (fd, _ , cryptobox_data) =
|
let kick (fd, _ , cryptobox_data) =
|
||||||
Ack.write fd cryptobox_data Nack >>= fun _ ->
|
Ack.write fd cryptobox_data Nack >>= fun _ ->
|
||||||
@ -187,9 +185,9 @@ let authenticate
|
|||||||
~incoming fd (remote_addr, remote_socket_port as point)
|
~incoming fd (remote_addr, remote_socket_port as point)
|
||||||
?listening_port identity supported_versions =
|
?listening_port identity supported_versions =
|
||||||
let local_nonce = Crypto_box.random_nonce () in
|
let local_nonce = Crypto_box.random_nonce () in
|
||||||
lwt_debug "Sending authenfication to %a" Point.pp point >>= fun () ->
|
lwt_debug "Sending authenfication to %a" P2p_point.Id.pp point >>= fun () ->
|
||||||
Connection_message.write fd
|
Connection_message.write fd
|
||||||
{ public_key = identity.Identity.public_key ;
|
{ public_key = identity.P2p_identity.public_key ;
|
||||||
proof_of_work_stamp = identity.proof_of_work_stamp ;
|
proof_of_work_stamp = identity.proof_of_work_stamp ;
|
||||||
message_nonce = local_nonce ;
|
message_nonce = local_nonce ;
|
||||||
port = listening_port ;
|
port = listening_port ;
|
||||||
@ -200,16 +198,16 @@ let authenticate
|
|||||||
let id_point = remote_addr, remote_listening_port in
|
let id_point = remote_addr, remote_listening_port in
|
||||||
let remote_peer_id = Crypto_box.hash msg.public_key in
|
let remote_peer_id = Crypto_box.hash msg.public_key in
|
||||||
fail_unless
|
fail_unless
|
||||||
(remote_peer_id <> identity.Identity.peer_id)
|
(remote_peer_id <> identity.P2p_identity.peer_id)
|
||||||
(Myself id_point) >>=? fun () ->
|
(Myself id_point) >>=? fun () ->
|
||||||
fail_unless
|
fail_unless
|
||||||
(Crypto_box.check_proof_of_work
|
(Crypto_box.check_proof_of_work
|
||||||
msg.public_key msg.proof_of_work_stamp proof_of_work_target)
|
msg.public_key msg.proof_of_work_stamp proof_of_work_target)
|
||||||
(Not_enough_proof_of_work remote_peer_id) >>=? fun () ->
|
(Not_enough_proof_of_work remote_peer_id) >>=? fun () ->
|
||||||
let channel_key =
|
let channel_key =
|
||||||
Crypto_box.precompute identity.Identity.secret_key msg.public_key in
|
Crypto_box.precompute identity.P2p_identity.secret_key msg.public_key in
|
||||||
let info =
|
let info =
|
||||||
{ Connection_info.peer_id = remote_peer_id ;
|
{ P2p_connection.Info.peer_id = remote_peer_id ;
|
||||||
versions = msg.versions ; incoming ;
|
versions = msg.versions ; incoming ;
|
||||||
id_point ; remote_socket_port ;} in
|
id_point ; remote_socket_port ;} in
|
||||||
let cryptobox_data =
|
let cryptobox_data =
|
||||||
@ -219,7 +217,7 @@ let authenticate
|
|||||||
|
|
||||||
type connection = {
|
type connection = {
|
||||||
id : int ;
|
id : int ;
|
||||||
info : Connection_info.t ;
|
info : P2p_connection.Info.t ;
|
||||||
fd : P2p_io_scheduler.connection ;
|
fd : P2p_io_scheduler.connection ;
|
||||||
cryptobox_data : Crypto.data ;
|
cryptobox_data : Crypto.data ;
|
||||||
}
|
}
|
||||||
@ -254,7 +252,7 @@ module Reader = struct
|
|||||||
end >>=? fun buf ->
|
end >>=? fun buf ->
|
||||||
lwt_debug
|
lwt_debug
|
||||||
"reading %d bytes from %a"
|
"reading %d bytes from %a"
|
||||||
(MBytes.length buf) Connection_info.pp st.conn.info >>= fun () ->
|
(MBytes.length buf) P2p_connection.Info.pp st.conn.info >>= fun () ->
|
||||||
loop (decode_next_buf buf) in
|
loop (decode_next_buf buf) in
|
||||||
loop
|
loop
|
||||||
(Data_encoding.Binary.read_stream_of_bytes ~init:init_mbytes st.encoding)
|
(Data_encoding.Binary.read_stream_of_bytes ~init:init_mbytes st.encoding)
|
||||||
@ -282,7 +280,7 @@ module Reader = struct
|
|||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Error [Lwt_utils.Canceled | Exn Lwt_pipe.Closed] ->
|
| Error [Lwt_utils.Canceled | Exn Lwt_pipe.Closed] ->
|
||||||
lwt_debug "connection closed to %a"
|
lwt_debug "connection closed to %a"
|
||||||
Connection_info.pp st.conn.info >>= fun () ->
|
P2p_connection.Info.pp st.conn.info >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Error _ as err ->
|
| Error _ as err ->
|
||||||
Lwt_pipe.safe_push_now st.messages err ;
|
Lwt_pipe.safe_push_now st.messages err ;
|
||||||
@ -335,7 +333,7 @@ module Writer = struct
|
|||||||
Crypto.write_chunk st.conn.fd st.conn.cryptobox_data buf
|
Crypto.write_chunk st.conn.fd st.conn.cryptobox_data buf
|
||||||
end >>=? fun () ->
|
end >>=? fun () ->
|
||||||
lwt_debug "writing %d bytes to %a"
|
lwt_debug "writing %d bytes to %a"
|
||||||
(MBytes.length buf) Connection_info.pp st.conn.info >>= fun () ->
|
(MBytes.length buf) P2p_connection.Info.pp st.conn.info >>= fun () ->
|
||||||
loop l in
|
loop l in
|
||||||
loop buf
|
loop buf
|
||||||
|
|
||||||
@ -350,12 +348,12 @@ module Writer = struct
|
|||||||
end >>= function
|
end >>= function
|
||||||
| Error [Lwt_utils.Canceled | Exn Lwt_pipe.Closed] ->
|
| Error [Lwt_utils.Canceled | Exn Lwt_pipe.Closed] ->
|
||||||
lwt_debug "connection closed to %a"
|
lwt_debug "connection closed to %a"
|
||||||
Connection_info.pp st.conn.info >>= fun () ->
|
P2p_connection.Info.pp st.conn.info >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Error err ->
|
| Error err ->
|
||||||
lwt_log_error
|
lwt_log_error
|
||||||
"@[<v 2>error writing to %a@ %a@]"
|
"@[<v 2>error writing to %a@ %a@]"
|
||||||
Connection_info.pp st.conn.info pp_print_error err >>= fun () ->
|
P2p_connection.Info.pp st.conn.info pp_print_error err >>= fun () ->
|
||||||
Lwt_canceler.cancel st.canceler >>= fun () ->
|
Lwt_canceler.cancel st.canceler >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Ok (buf, wakener) ->
|
| Ok (buf, wakener) ->
|
||||||
@ -372,17 +370,17 @@ module Writer = struct
|
|||||||
match err with
|
match err with
|
||||||
| [ Lwt_utils.Canceled | Exn Lwt_pipe.Closed ] ->
|
| [ Lwt_utils.Canceled | Exn Lwt_pipe.Closed ] ->
|
||||||
lwt_debug "connection closed to %a"
|
lwt_debug "connection closed to %a"
|
||||||
Connection_info.pp st.conn.info >>= fun () ->
|
P2p_connection.Info.pp st.conn.info >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| [ P2p_io_scheduler.Connection_closed ] ->
|
| [ P2p_io_scheduler.Connection_closed ] ->
|
||||||
lwt_debug "connection closed to %a"
|
lwt_debug "connection closed to %a"
|
||||||
Connection_info.pp st.conn.info >>= fun () ->
|
P2p_connection.Info.pp st.conn.info >>= fun () ->
|
||||||
Lwt_canceler.cancel st.canceler >>= fun () ->
|
Lwt_canceler.cancel st.canceler >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| err ->
|
| err ->
|
||||||
lwt_log_error
|
lwt_log_error
|
||||||
"@[<v 2>error writing to %a@ %a@]"
|
"@[<v 2>error writing to %a@ %a@]"
|
||||||
Connection_info.pp st.conn.info
|
P2p_connection.Info.pp st.conn.info
|
||||||
pp_print_error err >>= fun () ->
|
pp_print_error err >>= fun () ->
|
||||||
Lwt_canceler.cancel st.canceler >>= fun () ->
|
Lwt_canceler.cancel st.canceler >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
@ -447,7 +445,7 @@ type 'msg t = {
|
|||||||
|
|
||||||
let equal { conn = { id = id1 } } { conn = { id = id2 } } = id1 = id2
|
let equal { conn = { id = id1 } } { conn = { id = id2 } } = id1 = id2
|
||||||
|
|
||||||
let pp ppf { conn } = Connection_info.pp ppf conn.info
|
let pp ppf { conn } = P2p_connection.Info.pp ppf conn.info
|
||||||
let info { conn } = conn.info
|
let info { conn } = conn.info
|
||||||
|
|
||||||
let accept
|
let accept
|
||||||
@ -497,7 +495,7 @@ let pp_json encoding ppf msg =
|
|||||||
let write { writer ; conn } msg =
|
let write { writer ; conn } msg =
|
||||||
catch_closed_pipe begin fun () ->
|
catch_closed_pipe begin fun () ->
|
||||||
debug "Sending message to %a: %a"
|
debug "Sending message to %a: %a"
|
||||||
P2p_types.Peer_id.pp_short conn.info.peer_id (pp_json writer.encoding) msg ;
|
P2p_peer.Id.pp_short conn.info.peer_id (pp_json writer.encoding) msg ;
|
||||||
Lwt.return (Writer.encode_message writer msg) >>=? fun buf ->
|
Lwt.return (Writer.encode_message writer msg) >>=? fun buf ->
|
||||||
Lwt_pipe.push writer.messages (buf, None) >>= return
|
Lwt_pipe.push writer.messages (buf, None) >>= return
|
||||||
end
|
end
|
||||||
@ -506,7 +504,7 @@ let write_sync { writer ; conn } msg =
|
|||||||
catch_closed_pipe begin fun () ->
|
catch_closed_pipe begin fun () ->
|
||||||
let waiter, wakener = Lwt.wait () in
|
let waiter, wakener = Lwt.wait () in
|
||||||
debug "Sending message to %a: %a"
|
debug "Sending message to %a: %a"
|
||||||
P2p_types.Peer_id.pp_short conn.info.peer_id (pp_json writer.encoding) msg ;
|
P2p_peer.Id.pp_short conn.info.peer_id (pp_json writer.encoding) msg ;
|
||||||
Lwt.return (Writer.encode_message writer msg) >>=? fun buf ->
|
Lwt.return (Writer.encode_message writer msg) >>=? fun buf ->
|
||||||
Lwt_pipe.push writer.messages (buf, Some wakener) >>= fun () ->
|
Lwt_pipe.push writer.messages (buf, Some wakener) >>= fun () ->
|
||||||
waiter
|
waiter
|
||||||
@ -514,7 +512,7 @@ let write_sync { writer ; conn } msg =
|
|||||||
|
|
||||||
let write_now { writer ; conn } msg =
|
let write_now { writer ; conn } msg =
|
||||||
debug "Try sending message to %a: %a"
|
debug "Try sending message to %a: %a"
|
||||||
P2p_types.Peer_id.pp_short conn.info.peer_id (pp_json writer.encoding) msg ;
|
P2p_peer.Id.pp_short conn.info.peer_id (pp_json writer.encoding) msg ;
|
||||||
Writer.encode_message writer msg >>? fun buf ->
|
Writer.encode_message writer msg >>? fun buf ->
|
||||||
try Ok (Lwt_pipe.push_now writer.messages (buf, None))
|
try Ok (Lwt_pipe.push_now writer.messages (buf, None))
|
||||||
with Lwt_pipe.Closed -> Error [P2p_io_scheduler.Connection_closed]
|
with Lwt_pipe.Closed -> Error [P2p_io_scheduler.Connection_closed]
|
@ -15,8 +15,6 @@
|
|||||||
limited by providing corresponding arguments to [accept].
|
limited by providing corresponding arguments to [accept].
|
||||||
*)
|
*)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
|
|
||||||
(** {1 Types} *)
|
(** {1 Types} *)
|
||||||
|
|
||||||
type error += Decipher_error
|
type error += Decipher_error
|
||||||
@ -24,8 +22,8 @@ type error += Invalid_message_size
|
|||||||
type error += Encoding_error
|
type error += Encoding_error
|
||||||
type error += Decoding_error
|
type error += Decoding_error
|
||||||
type error += Rejected
|
type error += Rejected
|
||||||
type error += Myself of Id_point.t
|
type error += Myself of P2p_connection.Id.t
|
||||||
type error += Not_enough_proof_of_work of Peer_id.t
|
type error += Not_enough_proof_of_work of P2p_peer.Id.t
|
||||||
type error += Invalid_auth
|
type error += Invalid_auth
|
||||||
type error += Invalid_chunks_size of { value: int ; min: int ; max: int }
|
type error += Invalid_chunks_size of { value: int ; min: int ; max: int }
|
||||||
|
|
||||||
@ -40,17 +38,17 @@ type 'msg t
|
|||||||
val equal: 'mst t -> 'msg t -> bool
|
val equal: 'mst t -> 'msg t -> bool
|
||||||
|
|
||||||
val pp: Format.formatter -> 'msg t -> unit
|
val pp: Format.formatter -> 'msg t -> unit
|
||||||
val info: 'msg t -> Connection_info.t
|
val info: 'msg t -> P2p_connection.Info.t
|
||||||
|
|
||||||
(** {1 Low-level functions (do not use directly)} *)
|
(** {1 Low-level functions (do not use directly)} *)
|
||||||
|
|
||||||
val authenticate:
|
val authenticate:
|
||||||
proof_of_work_target:Crypto_box.target ->
|
proof_of_work_target:Crypto_box.target ->
|
||||||
incoming:bool ->
|
incoming:bool ->
|
||||||
P2p_io_scheduler.connection -> Point.t ->
|
P2p_io_scheduler.connection -> P2p_point.Id.t ->
|
||||||
?listening_port: int ->
|
?listening_port: int ->
|
||||||
Identity.t -> Version.t list ->
|
P2p_identity.t -> P2p_version.t list ->
|
||||||
(Connection_info.t * authenticated_fd) tzresult Lwt.t
|
(P2p_connection.Info.t * authenticated_fd) tzresult Lwt.t
|
||||||
(** (Low-level) (Cancelable) Authentication function of a remote
|
(** (Low-level) (Cancelable) Authentication function of a remote
|
||||||
peer. Used in [P2p_connection_pool], to promote a
|
peer. Used in [P2p_connection_pool], to promote a
|
||||||
[P2P_io_scheduler.connection] into an [authenticated_fd] (auth
|
[P2P_io_scheduler.connection] into an [authenticated_fd] (auth
|
||||||
@ -112,7 +110,7 @@ val read_now: 'msg t -> (int * 'msg) tzresult option
|
|||||||
is not empty, [None] if it is empty, or fails with a correponding
|
is not empty, [None] if it is empty, or fails with a correponding
|
||||||
error otherwise. *)
|
error otherwise. *)
|
||||||
|
|
||||||
val stat: 'msg t -> Stat.t
|
val stat: 'msg t -> P2p_stat.t
|
||||||
(** [stat conn] is a snapshot of current bandwidth usage for
|
(** [stat conn] is a snapshot of current bandwidth usage for
|
||||||
[conn]. *)
|
[conn]. *)
|
||||||
|
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
include Logging.Make (struct let name = "p2p.welcome" end)
|
include Logging.Make (struct let name = "p2p.welcome" end)
|
||||||
|
|
||||||
type pool = Pool : ('msg, 'meta) P2p_connection_pool.t -> pool
|
type pool = Pool : ('msg, 'meta) P2p_pool.t -> pool
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
socket: Lwt_unix.file_descr ;
|
socket: Lwt_unix.file_descr ;
|
||||||
@ -30,7 +30,7 @@ let rec worker_loop st =
|
|||||||
| Lwt_unix.ADDR_UNIX _ -> assert false
|
| Lwt_unix.ADDR_UNIX _ -> assert false
|
||||||
| Lwt_unix.ADDR_INET (addr, port) ->
|
| Lwt_unix.ADDR_INET (addr, port) ->
|
||||||
(Ipaddr_unix.V6.of_inet_addr_exn addr, port) in
|
(Ipaddr_unix.V6.of_inet_addr_exn addr, port) in
|
||||||
P2p_connection_pool.accept pool fd point ;
|
P2p_pool.accept pool fd point ;
|
||||||
worker_loop st
|
worker_loop st
|
||||||
| Error [Lwt_utils.Canceled] ->
|
| Error [Lwt_utils.Canceled] ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
|
|
||||||
(** Welcome worker. Accept incoming connections and add them to its
|
(** Welcome worker. Accept incoming connections and add them to its
|
||||||
connection pool. *)
|
connection pool. *)
|
||||||
|
|
||||||
@ -18,8 +16,8 @@ type t
|
|||||||
|
|
||||||
val run:
|
val run:
|
||||||
backlog:int ->
|
backlog:int ->
|
||||||
('msg, 'meta) P2p_connection_pool.t ->
|
('msg, 'meta) P2p_pool.t ->
|
||||||
?addr:addr -> port -> t Lwt.t
|
?addr:P2p_addr.t -> P2p_addr.port -> t Lwt.t
|
||||||
(** [run ~backlog ~addr pool port] returns a running welcome worker
|
(** [run ~backlog ~addr pool port] returns a running welcome worker
|
||||||
feeding [pool] listening at [(addr, port)]. [backlog] is the
|
feeding [pool] listening at [(addr, port)]. [backlog] is the
|
||||||
argument passed to [Lwt_unix.accept]. *)
|
argument passed to [Lwt_unix.accept]. *)
|
||||||
|
@ -1,526 +0,0 @@
|
|||||||
(**************************************************************************)
|
|
||||||
(* *)
|
|
||||||
(* Copyright (c) 2014 - 2017. *)
|
|
||||||
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
||||||
(* *)
|
|
||||||
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
||||||
(* *)
|
|
||||||
(**************************************************************************)
|
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
|
|
||||||
module Point_info = struct
|
|
||||||
|
|
||||||
type 'data state =
|
|
||||||
| Requested of { cancel: Lwt_canceler.t }
|
|
||||||
| Accepted of { current_peer_id: Peer_id.t ;
|
|
||||||
cancel: Lwt_canceler.t }
|
|
||||||
| Running of { data: 'data ;
|
|
||||||
current_peer_id: Peer_id.t }
|
|
||||||
| Disconnected
|
|
||||||
|
|
||||||
module Event = struct
|
|
||||||
|
|
||||||
type kind =
|
|
||||||
| Outgoing_request
|
|
||||||
| Accepting_request of Peer_id.t
|
|
||||||
| Rejecting_request of Peer_id.t
|
|
||||||
| Request_rejected of Peer_id.t option
|
|
||||||
| Connection_established of Peer_id.t
|
|
||||||
| Disconnection of Peer_id.t
|
|
||||||
| External_disconnection of Peer_id.t
|
|
||||||
|
|
||||||
let kind_encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
let branch_encoding name obj =
|
|
||||||
conv (fun x -> (), x) (fun ((), x) -> x)
|
|
||||||
(merge_objs
|
|
||||||
(obj1 (req "event_kind" (constant name))) obj) in
|
|
||||||
union ~tag_size:`Uint8 [
|
|
||||||
case (Tag 0) (branch_encoding "outgoing_request" empty)
|
|
||||||
(function Outgoing_request -> Some () | _ -> None)
|
|
||||||
(fun () -> Outgoing_request) ;
|
|
||||||
case (Tag 1) (branch_encoding "accepting_request"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Accepting_request peer_id -> Some peer_id | _ -> None)
|
|
||||||
(fun peer_id -> Accepting_request peer_id) ;
|
|
||||||
case (Tag 2) (branch_encoding "rejecting_request"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Rejecting_request peer_id -> Some peer_id | _ -> None)
|
|
||||||
(fun peer_id -> Rejecting_request peer_id) ;
|
|
||||||
case (Tag 3) (branch_encoding "request_rejected"
|
|
||||||
(obj1 (opt "peer_id" Peer_id.encoding)))
|
|
||||||
(function Request_rejected peer_id -> Some peer_id | _ -> None)
|
|
||||||
(fun peer_id -> Request_rejected peer_id) ;
|
|
||||||
case (Tag 4) (branch_encoding "rejecting_request"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Connection_established peer_id -> Some peer_id | _ -> None)
|
|
||||||
(fun peer_id -> Connection_established peer_id) ;
|
|
||||||
case (Tag 5) (branch_encoding "rejecting_request"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Disconnection peer_id -> Some peer_id | _ -> None)
|
|
||||||
(fun peer_id -> Disconnection peer_id) ;
|
|
||||||
case (Tag 6) (branch_encoding "rejecting_request"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function External_disconnection peer_id -> Some peer_id | _ -> None)
|
|
||||||
(fun peer_id -> External_disconnection peer_id) ;
|
|
||||||
]
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
kind : kind ;
|
|
||||||
timestamp : Time.t ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
conv
|
|
||||||
(fun { kind ; timestamp ; } -> (kind, timestamp))
|
|
||||||
(fun (kind, timestamp) -> { kind ; timestamp ; })
|
|
||||||
(obj2
|
|
||||||
(req "kind" kind_encoding)
|
|
||||||
(req "timestamp" Time.encoding))
|
|
||||||
end
|
|
||||||
|
|
||||||
type greylisting_config = {
|
|
||||||
factor: float ;
|
|
||||||
initial_delay: int ;
|
|
||||||
disconnection_delay: int ;
|
|
||||||
}
|
|
||||||
|
|
||||||
type 'data t = {
|
|
||||||
point : Point.t ;
|
|
||||||
mutable trusted : bool ;
|
|
||||||
mutable state : 'data state ;
|
|
||||||
mutable last_failed_connection : Time.t option ;
|
|
||||||
mutable last_rejected_connection : (Peer_id.t * Time.t) option ;
|
|
||||||
mutable last_established_connection : (Peer_id.t * Time.t) option ;
|
|
||||||
mutable last_disconnection : (Peer_id.t * Time.t) option ;
|
|
||||||
greylisting : greylisting_config ;
|
|
||||||
mutable greylisting_delay : float ;
|
|
||||||
mutable greylisting_end : Time.t ;
|
|
||||||
events : Event.t Ring.t ;
|
|
||||||
watchers : Event.t Lwt_watcher.input ;
|
|
||||||
}
|
|
||||||
type 'data point_info = 'data t
|
|
||||||
|
|
||||||
let compare pi1 pi2 = Point.compare pi1.point pi2.point
|
|
||||||
|
|
||||||
let log_size = 100
|
|
||||||
|
|
||||||
let default_greylisting_config = {
|
|
||||||
factor = 1.2 ;
|
|
||||||
initial_delay = 1 ;
|
|
||||||
disconnection_delay = 60 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let create
|
|
||||||
?(trusted = false)
|
|
||||||
?(greylisting_config = default_greylisting_config) addr port = {
|
|
||||||
point = (addr, port) ;
|
|
||||||
trusted ;
|
|
||||||
state = Disconnected ;
|
|
||||||
last_failed_connection = None ;
|
|
||||||
last_rejected_connection = None ;
|
|
||||||
last_established_connection = None ;
|
|
||||||
last_disconnection = None ;
|
|
||||||
events = Ring.create log_size ;
|
|
||||||
greylisting = greylisting_config ;
|
|
||||||
greylisting_delay = 1. ;
|
|
||||||
greylisting_end = Time.epoch ;
|
|
||||||
watchers = Lwt_watcher.create_input () ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let point s = s.point
|
|
||||||
let trusted s = s.trusted
|
|
||||||
let set_trusted gi = gi.trusted <- true
|
|
||||||
let unset_trusted gi = gi.trusted <- false
|
|
||||||
let last_established_connection s = s.last_established_connection
|
|
||||||
let last_disconnection s = s.last_disconnection
|
|
||||||
let last_failed_connection s = s.last_failed_connection
|
|
||||||
let last_rejected_connection s = s.last_rejected_connection
|
|
||||||
let greylisted ?(now = Time.now ()) s =
|
|
||||||
Time.compare now s.greylisting_end <= 0
|
|
||||||
let greylisted_until s = s.greylisting_end
|
|
||||||
|
|
||||||
let recent a1 a2 =
|
|
||||||
match a1, a2 with
|
|
||||||
| (None, None) -> None
|
|
||||||
| (None, (Some _ as a))
|
|
||||||
| (Some _ as a, None) -> a
|
|
||||||
| (Some (_, t1), Some (_, t2)) ->
|
|
||||||
if Time.compare t1 t2 < 0 then a2 else a1
|
|
||||||
let last_seen s =
|
|
||||||
recent s.last_rejected_connection
|
|
||||||
(recent s.last_established_connection s.last_disconnection)
|
|
||||||
let last_miss s =
|
|
||||||
match
|
|
||||||
s.last_failed_connection,
|
|
||||||
(Option.map ~f:(fun (_, time) -> time) @@
|
|
||||||
recent s.last_rejected_connection s.last_disconnection) with
|
|
||||||
| (None, None) -> None
|
|
||||||
| (None, (Some _ as a))
|
|
||||||
| (Some _ as a, None) -> a
|
|
||||||
| (Some t1 as a1 , (Some t2 as a2)) ->
|
|
||||||
if Time.compare t1 t2 < 0 then a2 else a1
|
|
||||||
|
|
||||||
let fold_events { events ; _ } ~init ~f = Ring.fold events ~init ~f
|
|
||||||
|
|
||||||
let watch { watchers ; _ } = Lwt_watcher.create_stream watchers
|
|
||||||
|
|
||||||
let log { events ; watchers ; _ } ?(timestamp = Time.now ()) kind =
|
|
||||||
let event = { Event.kind ; timestamp } in
|
|
||||||
Ring.add events event ;
|
|
||||||
Lwt_watcher.notify watchers event
|
|
||||||
|
|
||||||
let log_incoming_rejection ?timestamp point_info peer_id =
|
|
||||||
log point_info ?timestamp (Rejecting_request peer_id)
|
|
||||||
|
|
||||||
module State = struct
|
|
||||||
|
|
||||||
type 'data t = 'data state =
|
|
||||||
| Requested of { cancel: Lwt_canceler.t }
|
|
||||||
| Accepted of { current_peer_id: Peer_id.t ;
|
|
||||||
cancel: Lwt_canceler.t }
|
|
||||||
| Running of { data: 'data ;
|
|
||||||
current_peer_id: Peer_id.t }
|
|
||||||
| Disconnected
|
|
||||||
type 'data state = 'data t
|
|
||||||
|
|
||||||
let pp ppf = function
|
|
||||||
| Requested _ ->
|
|
||||||
Format.fprintf ppf "requested"
|
|
||||||
| Accepted { current_peer_id ; _ } ->
|
|
||||||
Format.fprintf ppf "accepted %a" Peer_id.pp current_peer_id
|
|
||||||
| Running { current_peer_id ; _ } ->
|
|
||||||
Format.fprintf ppf "running %a" Peer_id.pp current_peer_id
|
|
||||||
| Disconnected ->
|
|
||||||
Format.fprintf ppf "disconnected"
|
|
||||||
|
|
||||||
let get { state ; _ } = state
|
|
||||||
|
|
||||||
let is_disconnected { state ; _ } =
|
|
||||||
match state with
|
|
||||||
| Disconnected -> true
|
|
||||||
| Requested _ | Accepted _ | Running _ -> false
|
|
||||||
|
|
||||||
let set_requested ?timestamp point_info cancel =
|
|
||||||
assert begin
|
|
||||||
match point_info.state with
|
|
||||||
| Requested _ -> true
|
|
||||||
| Accepted _ | Running _ -> false
|
|
||||||
| Disconnected -> true
|
|
||||||
end ;
|
|
||||||
point_info.state <- Requested { cancel } ;
|
|
||||||
log point_info ?timestamp Outgoing_request
|
|
||||||
|
|
||||||
let set_accepted
|
|
||||||
?(timestamp = Time.now ())
|
|
||||||
point_info current_peer_id cancel =
|
|
||||||
(* log_notice "SET_ACCEPTED %a@." Point.pp point_info.point ; *)
|
|
||||||
assert begin
|
|
||||||
match point_info.state with
|
|
||||||
| Accepted _ | Running _ -> false
|
|
||||||
| Requested _ | Disconnected -> true
|
|
||||||
end ;
|
|
||||||
point_info.state <- Accepted { current_peer_id ; cancel } ;
|
|
||||||
log point_info ~timestamp (Accepting_request current_peer_id)
|
|
||||||
|
|
||||||
let set_running
|
|
||||||
?(timestamp = Time.now ())
|
|
||||||
point_info peer_id data =
|
|
||||||
assert begin
|
|
||||||
match point_info.state with
|
|
||||||
| Disconnected -> true (* request to unknown peer_id. *)
|
|
||||||
| Running _ -> false
|
|
||||||
| Accepted { current_peer_id ; _ } -> Peer_id.equal peer_id current_peer_id
|
|
||||||
| Requested _ -> true
|
|
||||||
end ;
|
|
||||||
point_info.state <- Running { data ; current_peer_id = peer_id } ;
|
|
||||||
point_info.last_established_connection <- Some (peer_id, timestamp) ;
|
|
||||||
log point_info ~timestamp (Connection_established peer_id)
|
|
||||||
|
|
||||||
let set_greylisted timestamp point_info =
|
|
||||||
point_info.greylisting_end <-
|
|
||||||
Time.add
|
|
||||||
timestamp
|
|
||||||
(Int64.of_float point_info.greylisting_delay) ;
|
|
||||||
point_info.greylisting_delay <-
|
|
||||||
point_info.greylisting_delay *. point_info.greylisting.factor
|
|
||||||
|
|
||||||
let set_disconnected
|
|
||||||
?(timestamp = Time.now ()) ?(requested = false) point_info =
|
|
||||||
let event : Event.kind =
|
|
||||||
match point_info.state with
|
|
||||||
| Requested _ ->
|
|
||||||
set_greylisted timestamp point_info ;
|
|
||||||
point_info.last_failed_connection <- Some timestamp ;
|
|
||||||
Request_rejected None
|
|
||||||
| Accepted { current_peer_id ; _ } ->
|
|
||||||
set_greylisted timestamp point_info ;
|
|
||||||
point_info.last_rejected_connection <-
|
|
||||||
Some (current_peer_id, timestamp) ;
|
|
||||||
Request_rejected (Some current_peer_id)
|
|
||||||
| Running { current_peer_id ; _ } ->
|
|
||||||
point_info.greylisting_delay <-
|
|
||||||
float_of_int point_info.greylisting.initial_delay ;
|
|
||||||
point_info.greylisting_end <-
|
|
||||||
Time.add timestamp
|
|
||||||
(Int64.of_int point_info.greylisting.disconnection_delay) ;
|
|
||||||
point_info.last_disconnection <- Some (current_peer_id, timestamp) ;
|
|
||||||
if requested
|
|
||||||
then Disconnection current_peer_id
|
|
||||||
else External_disconnection current_peer_id
|
|
||||||
| Disconnected ->
|
|
||||||
assert false
|
|
||||||
in
|
|
||||||
point_info.state <- Disconnected ;
|
|
||||||
log point_info ~timestamp event
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Peer_info = struct
|
|
||||||
|
|
||||||
type 'data state =
|
|
||||||
| Accepted of { current_point: Id_point.t ;
|
|
||||||
cancel: Lwt_canceler.t }
|
|
||||||
| Running of { data: 'data ;
|
|
||||||
current_point: Id_point.t }
|
|
||||||
| Disconnected
|
|
||||||
|
|
||||||
module Event = struct
|
|
||||||
|
|
||||||
type kind =
|
|
||||||
| Accepting_request
|
|
||||||
| Rejecting_request
|
|
||||||
| Request_rejected
|
|
||||||
| Connection_established
|
|
||||||
| Disconnection
|
|
||||||
| External_disconnection
|
|
||||||
|
|
||||||
let kind_encoding =
|
|
||||||
Data_encoding.string_enum [
|
|
||||||
"incoming_request", Accepting_request ;
|
|
||||||
"rejecting_request", Rejecting_request ;
|
|
||||||
"request_rejected", Request_rejected ;
|
|
||||||
"connection_established", Connection_established ;
|
|
||||||
"disconnection", Disconnection ;
|
|
||||||
"external_disconnection", External_disconnection ;
|
|
||||||
]
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
kind : kind ;
|
|
||||||
timestamp : Time.t ;
|
|
||||||
point : Id_point.t ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
conv
|
|
||||||
(fun { kind ; timestamp ; point = (addr, port) } ->
|
|
||||||
(kind, timestamp, addr, port))
|
|
||||||
(fun (kind, timestamp, addr, port) ->
|
|
||||||
{ kind ; timestamp ; point = (addr, port) })
|
|
||||||
(obj4
|
|
||||||
(req "kind" kind_encoding)
|
|
||||||
(req "timestamp" Time.encoding)
|
|
||||||
(req "addr" P2p_types.addr_encoding)
|
|
||||||
(opt "port" int16))
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
type ('conn, 'meta) t = {
|
|
||||||
peer_id : Peer_id.t ;
|
|
||||||
created : Time.t ;
|
|
||||||
mutable state : 'conn state ;
|
|
||||||
mutable metadata : 'meta ;
|
|
||||||
mutable trusted : bool ;
|
|
||||||
mutable last_failed_connection : (Id_point.t * Time.t) option ;
|
|
||||||
mutable last_rejected_connection : (Id_point.t * Time.t) option ;
|
|
||||||
mutable last_established_connection : (Id_point.t * Time.t) option ;
|
|
||||||
mutable last_disconnection : (Id_point.t * Time.t) option ;
|
|
||||||
events : Event.t Ring.t ;
|
|
||||||
watchers : Event.t Lwt_watcher.input ;
|
|
||||||
}
|
|
||||||
type ('conn, 'meta) peer_info = ('conn, 'meta) t
|
|
||||||
|
|
||||||
let compare gi1 gi2 = Peer_id.compare gi1.peer_id gi2.peer_id
|
|
||||||
|
|
||||||
let log_size = 100
|
|
||||||
|
|
||||||
let create ?(created = Time.now ()) ?(trusted = false) ~metadata peer_id =
|
|
||||||
{ peer_id ;
|
|
||||||
created ;
|
|
||||||
state = Disconnected ;
|
|
||||||
metadata ;
|
|
||||||
trusted ;
|
|
||||||
last_failed_connection = None ;
|
|
||||||
last_rejected_connection = None ;
|
|
||||||
last_established_connection = None ;
|
|
||||||
last_disconnection = None ;
|
|
||||||
events = Ring.create log_size ;
|
|
||||||
watchers = Lwt_watcher.create_input () ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encoding metadata_encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
conv
|
|
||||||
(fun { peer_id ; trusted ; metadata ; events ; created ;
|
|
||||||
last_failed_connection ; last_rejected_connection ;
|
|
||||||
last_established_connection ; last_disconnection ; _ } ->
|
|
||||||
(peer_id, created, trusted, metadata, Ring.elements events,
|
|
||||||
last_failed_connection, last_rejected_connection,
|
|
||||||
last_established_connection, last_disconnection))
|
|
||||||
(fun (peer_id, created, trusted, metadata, event_list,
|
|
||||||
last_failed_connection, last_rejected_connection,
|
|
||||||
last_established_connection, last_disconnection) ->
|
|
||||||
let info = create ~trusted ~metadata peer_id in
|
|
||||||
let events = Ring.create log_size in
|
|
||||||
Ring.add_list info.events event_list ;
|
|
||||||
{ state = Disconnected ;
|
|
||||||
trusted ; peer_id ; metadata ; created ;
|
|
||||||
last_failed_connection ;
|
|
||||||
last_rejected_connection ;
|
|
||||||
last_established_connection ;
|
|
||||||
last_disconnection ;
|
|
||||||
events ;
|
|
||||||
watchers = Lwt_watcher.create_input () ;
|
|
||||||
})
|
|
||||||
(obj9
|
|
||||||
(req "peer_id" Peer_id.encoding)
|
|
||||||
(req "created" Time.encoding)
|
|
||||||
(dft "trusted" bool false)
|
|
||||||
(req "metadata" metadata_encoding)
|
|
||||||
(dft "events" (list Event.encoding) [])
|
|
||||||
(opt "last_failed_connection"
|
|
||||||
(tup2 Id_point.encoding Time.encoding))
|
|
||||||
(opt "last_rejected_connection"
|
|
||||||
(tup2 Id_point.encoding Time.encoding))
|
|
||||||
(opt "last_established_connection"
|
|
||||||
(tup2 Id_point.encoding Time.encoding))
|
|
||||||
(opt "last_disconnection"
|
|
||||||
(tup2 Id_point.encoding Time.encoding)))
|
|
||||||
|
|
||||||
let peer_id { peer_id ; _ } = peer_id
|
|
||||||
let created { created ; _ } = created
|
|
||||||
let metadata { metadata ; _ } = metadata
|
|
||||||
let set_metadata gi metadata = gi.metadata <- metadata
|
|
||||||
let trusted { trusted ; _ } = trusted
|
|
||||||
let set_trusted gi = gi.trusted <- true
|
|
||||||
let unset_trusted gi = gi.trusted <- false
|
|
||||||
let fold_events { events ; _ } ~init ~f = Ring.fold events ~init ~f
|
|
||||||
|
|
||||||
let last_established_connection s = s.last_established_connection
|
|
||||||
let last_disconnection s = s.last_disconnection
|
|
||||||
let last_failed_connection s = s.last_failed_connection
|
|
||||||
let last_rejected_connection s = s.last_rejected_connection
|
|
||||||
|
|
||||||
let recent = Point_info.recent
|
|
||||||
let last_seen s =
|
|
||||||
recent
|
|
||||||
s.last_established_connection
|
|
||||||
(recent s.last_rejected_connection s.last_disconnection)
|
|
||||||
let last_miss s =
|
|
||||||
recent
|
|
||||||
s.last_failed_connection
|
|
||||||
(recent s.last_rejected_connection s.last_disconnection)
|
|
||||||
|
|
||||||
let log { events ; watchers ; _ } ?(timestamp = Time.now ()) point kind =
|
|
||||||
let event = { Event.kind ; timestamp ; point } in
|
|
||||||
Ring.add events event ;
|
|
||||||
Lwt_watcher.notify watchers event
|
|
||||||
|
|
||||||
let watch { watchers ; _ } = Lwt_watcher.create_stream watchers
|
|
||||||
|
|
||||||
let log_incoming_rejection ?timestamp peer_info point =
|
|
||||||
log peer_info ?timestamp point Rejecting_request
|
|
||||||
|
|
||||||
module State = struct
|
|
||||||
|
|
||||||
type 'data t = 'data state =
|
|
||||||
| Accepted of { current_point: Id_point.t ;
|
|
||||||
cancel: Lwt_canceler.t }
|
|
||||||
| Running of { data: 'data ;
|
|
||||||
current_point: Id_point.t }
|
|
||||||
| Disconnected
|
|
||||||
type 'data state = 'data t
|
|
||||||
|
|
||||||
let pp ppf = function
|
|
||||||
| Accepted { current_point ; _ } ->
|
|
||||||
Format.fprintf ppf "accepted %a" Id_point.pp current_point
|
|
||||||
| Running { current_point ; _ } ->
|
|
||||||
Format.fprintf ppf "running %a" Id_point.pp current_point
|
|
||||||
| Disconnected ->
|
|
||||||
Format.fprintf ppf "disconnected"
|
|
||||||
|
|
||||||
let get { state ; _ } = state
|
|
||||||
|
|
||||||
let is_disconnected { state ; _ } =
|
|
||||||
match state with
|
|
||||||
| Disconnected -> true
|
|
||||||
| Accepted _ | Running _ -> false
|
|
||||||
|
|
||||||
let set_accepted
|
|
||||||
?(timestamp = Time.now ())
|
|
||||||
peer_info current_point cancel =
|
|
||||||
assert begin
|
|
||||||
match peer_info.state with
|
|
||||||
| Accepted _ | Running _ -> false
|
|
||||||
| Disconnected -> true
|
|
||||||
end ;
|
|
||||||
peer_info.state <- Accepted { current_point ; cancel } ;
|
|
||||||
log peer_info ~timestamp current_point Accepting_request
|
|
||||||
|
|
||||||
let set_running
|
|
||||||
?(timestamp = Time.now ())
|
|
||||||
peer_info point data =
|
|
||||||
assert begin
|
|
||||||
match peer_info.state with
|
|
||||||
| Disconnected -> true (* request to unknown peer_id. *)
|
|
||||||
| Running _ -> false
|
|
||||||
| Accepted { current_point ; _ } ->
|
|
||||||
Id_point.equal point current_point
|
|
||||||
end ;
|
|
||||||
peer_info.state <- Running { data ; current_point = point } ;
|
|
||||||
peer_info.last_established_connection <- Some (point, timestamp) ;
|
|
||||||
log peer_info ~timestamp point Connection_established
|
|
||||||
|
|
||||||
let set_disconnected
|
|
||||||
?(timestamp = Time.now ()) ?(requested = false) peer_info =
|
|
||||||
let current_point, (event : Event.kind) =
|
|
||||||
match peer_info.state with
|
|
||||||
| Accepted { current_point ; _ } ->
|
|
||||||
peer_info.last_rejected_connection <-
|
|
||||||
Some (current_point, timestamp) ;
|
|
||||||
current_point, Request_rejected
|
|
||||||
| Running { current_point ; _ } ->
|
|
||||||
peer_info.last_disconnection <-
|
|
||||||
Some (current_point, timestamp) ;
|
|
||||||
current_point,
|
|
||||||
if requested then Disconnection else External_disconnection
|
|
||||||
| Disconnected -> assert false
|
|
||||||
in
|
|
||||||
peer_info.state <- Disconnected ;
|
|
||||||
log peer_info ~timestamp current_point event
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module File = struct
|
|
||||||
|
|
||||||
let load path metadata_encoding =
|
|
||||||
let enc = Data_encoding.list (encoding metadata_encoding) in
|
|
||||||
if path <> "/dev/null" && Sys.file_exists path then
|
|
||||||
Data_encoding_ezjsonm.read_file path >>=? fun json ->
|
|
||||||
return (Data_encoding.Json.destruct enc json)
|
|
||||||
else
|
|
||||||
return []
|
|
||||||
|
|
||||||
let save path metadata_encoding peers =
|
|
||||||
let open Data_encoding in
|
|
||||||
Data_encoding_ezjsonm.write_file path @@
|
|
||||||
Json.construct (list (encoding metadata_encoding)) peers
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,284 +0,0 @@
|
|||||||
(**************************************************************************)
|
|
||||||
(* *)
|
|
||||||
(* Copyright (c) 2014 - 2017. *)
|
|
||||||
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
||||||
(* *)
|
|
||||||
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
||||||
(* *)
|
|
||||||
(**************************************************************************)
|
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
|
|
||||||
module Point_info : sig
|
|
||||||
|
|
||||||
type 'conn t
|
|
||||||
type 'conn point_info = 'conn t
|
|
||||||
(** Type of info associated to a point. *)
|
|
||||||
|
|
||||||
val compare : 'conn point_info -> 'conn point_info -> int
|
|
||||||
|
|
||||||
type greylisting_config = {
|
|
||||||
factor: float ;
|
|
||||||
initial_delay: int ;
|
|
||||||
disconnection_delay: int ;
|
|
||||||
}
|
|
||||||
|
|
||||||
val create :
|
|
||||||
?trusted:bool ->
|
|
||||||
?greylisting_config:greylisting_config ->
|
|
||||||
addr -> port -> 'conn point_info
|
|
||||||
(** [create ~trusted addr port] is a freshly minted point_info. If
|
|
||||||
[trusted] is true, this point is considered trusted and will
|
|
||||||
be treated as such. *)
|
|
||||||
|
|
||||||
val trusted : 'conn point_info -> bool
|
|
||||||
(** [trusted pi] is [true] iff [pi] has is trusted,
|
|
||||||
i.e. "whitelisted". *)
|
|
||||||
|
|
||||||
val set_trusted : 'conn point_info -> unit
|
|
||||||
val unset_trusted : 'conn point_info -> unit
|
|
||||||
|
|
||||||
val last_failed_connection :
|
|
||||||
'conn point_info -> Time.t option
|
|
||||||
val last_rejected_connection :
|
|
||||||
'conn point_info -> (Peer_id.t * Time.t) option
|
|
||||||
val last_established_connection :
|
|
||||||
'conn point_info -> (Peer_id.t * Time.t) option
|
|
||||||
val last_disconnection :
|
|
||||||
'conn point_info -> (Peer_id.t * Time.t) option
|
|
||||||
|
|
||||||
val last_seen :
|
|
||||||
'conn point_info -> (Peer_id.t * Time.t) option
|
|
||||||
(** [last_seen pi] is the most recent of:
|
|
||||||
|
|
||||||
* last established connection
|
|
||||||
* last rejected connection
|
|
||||||
* last disconnection
|
|
||||||
*)
|
|
||||||
|
|
||||||
val last_miss :
|
|
||||||
'conn point_info -> Time.t option
|
|
||||||
(** [last_miss pi] is the most recent of:
|
|
||||||
|
|
||||||
* last failed connection
|
|
||||||
* last rejected connection
|
|
||||||
* last disconnection
|
|
||||||
*)
|
|
||||||
|
|
||||||
val greylisted :
|
|
||||||
?now:Time.t -> 'conn point_info -> bool
|
|
||||||
|
|
||||||
val greylisted_until : 'conn point_info -> Time.t
|
|
||||||
|
|
||||||
val point : 'conn point_info -> Point.t
|
|
||||||
|
|
||||||
module State : sig
|
|
||||||
|
|
||||||
type 'conn t =
|
|
||||||
| Requested of { cancel: Lwt_canceler.t }
|
|
||||||
(** We initiated a connection. *)
|
|
||||||
| Accepted of { current_peer_id: Peer_id.t ;
|
|
||||||
cancel: Lwt_canceler.t }
|
|
||||||
(** We accepted a incoming connection. *)
|
|
||||||
| Running of { data: 'conn ;
|
|
||||||
current_peer_id: Peer_id.t }
|
|
||||||
(** Successfully authentificated connection, normal business. *)
|
|
||||||
| Disconnected
|
|
||||||
(** No connection established currently. *)
|
|
||||||
type 'conn state = 'conn t
|
|
||||||
|
|
||||||
val pp : Format.formatter -> 'conn t -> unit
|
|
||||||
|
|
||||||
val get : 'conn point_info -> 'conn state
|
|
||||||
|
|
||||||
val is_disconnected : 'conn point_info -> bool
|
|
||||||
|
|
||||||
val set_requested :
|
|
||||||
?timestamp:Time.t ->
|
|
||||||
'conn point_info -> Lwt_canceler.t -> unit
|
|
||||||
|
|
||||||
val set_accepted :
|
|
||||||
?timestamp:Time.t ->
|
|
||||||
'conn point_info -> Peer_id.t -> Lwt_canceler.t -> unit
|
|
||||||
|
|
||||||
val set_running :
|
|
||||||
?timestamp:Time.t -> 'conn point_info -> Peer_id.t -> 'conn -> unit
|
|
||||||
|
|
||||||
val set_disconnected :
|
|
||||||
?timestamp:Time.t -> ?requested:bool -> 'conn point_info -> unit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Event : sig
|
|
||||||
|
|
||||||
type kind =
|
|
||||||
| Outgoing_request
|
|
||||||
(** We initiated a connection. *)
|
|
||||||
| Accepting_request of Peer_id.t
|
|
||||||
(** We accepted a connection after authentifying the remote peer. *)
|
|
||||||
| Rejecting_request of Peer_id.t
|
|
||||||
(** We rejected a connection after authentifying the remote peer. *)
|
|
||||||
| Request_rejected of Peer_id.t option
|
|
||||||
(** The remote peer rejected our connection. *)
|
|
||||||
| Connection_established of Peer_id.t
|
|
||||||
(** We succesfully established a authentified connection. *)
|
|
||||||
| Disconnection of Peer_id.t
|
|
||||||
(** We decided to close the connection. *)
|
|
||||||
| External_disconnection of Peer_id.t
|
|
||||||
(** The connection was closed for external reason. *)
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
kind : kind ;
|
|
||||||
timestamp : Time.t ;
|
|
||||||
}
|
|
||||||
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
val fold_events :
|
|
||||||
'conn point_info -> init:'a -> f:('a -> Event.t -> 'a) -> 'a
|
|
||||||
|
|
||||||
val watch :
|
|
||||||
'conn point_info -> Event.t Lwt_stream.t * Lwt_watcher.stopper
|
|
||||||
|
|
||||||
val log_incoming_rejection :
|
|
||||||
?timestamp:Time.t -> 'conn point_info -> Peer_id.t -> unit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
(** Peer_id info: current and historical information about a peer_id *)
|
|
||||||
|
|
||||||
module Peer_info : sig
|
|
||||||
|
|
||||||
type ('conn, 'meta) t
|
|
||||||
type ('conn, 'meta) peer_info = ('conn, 'meta) t
|
|
||||||
|
|
||||||
val compare : ('conn, 'meta) t -> ('conn, 'meta) t -> int
|
|
||||||
|
|
||||||
val create :
|
|
||||||
?created:Time.t ->
|
|
||||||
?trusted:bool ->
|
|
||||||
metadata:'meta ->
|
|
||||||
Peer_id.t -> ('conn, 'meta) peer_info
|
|
||||||
(** [create ~trusted ~meta peer_id] is a freshly minted peer_id info for
|
|
||||||
[peer_id]. *)
|
|
||||||
|
|
||||||
val peer_id : ('conn, 'meta) peer_info -> Peer_id.t
|
|
||||||
|
|
||||||
val created : ('conn, 'meta) peer_info -> Time.t
|
|
||||||
val metadata : ('conn, 'meta) peer_info -> 'meta
|
|
||||||
val set_metadata : ('conn, 'meta) peer_info -> 'meta -> unit
|
|
||||||
|
|
||||||
val trusted : ('conn, 'meta) peer_info -> bool
|
|
||||||
val set_trusted : ('conn, 'meta) peer_info -> unit
|
|
||||||
val unset_trusted : ('conn, 'meta) peer_info -> unit
|
|
||||||
|
|
||||||
val last_failed_connection :
|
|
||||||
('conn, 'meta) peer_info -> (Id_point.t * Time.t) option
|
|
||||||
val last_rejected_connection :
|
|
||||||
('conn, 'meta) peer_info -> (Id_point.t * Time.t) option
|
|
||||||
val last_established_connection :
|
|
||||||
('conn, 'meta) peer_info -> (Id_point.t * Time.t) option
|
|
||||||
val last_disconnection :
|
|
||||||
('conn, 'meta) peer_info -> (Id_point.t * Time.t) option
|
|
||||||
|
|
||||||
val last_seen :
|
|
||||||
('conn, 'meta) peer_info -> (Id_point.t * Time.t) option
|
|
||||||
(** [last_seen gi] is the most recent of:
|
|
||||||
|
|
||||||
* last established connection
|
|
||||||
* last rejected connection
|
|
||||||
* last disconnection
|
|
||||||
*)
|
|
||||||
|
|
||||||
val last_miss :
|
|
||||||
('conn, 'meta) peer_info -> (Id_point.t * Time.t) option
|
|
||||||
(** [last_miss gi] is the most recent of:
|
|
||||||
|
|
||||||
* last failed connection
|
|
||||||
* last rejected connection
|
|
||||||
* last disconnection
|
|
||||||
*)
|
|
||||||
|
|
||||||
module State : sig
|
|
||||||
|
|
||||||
type 'conn t =
|
|
||||||
| Accepted of { current_point: Id_point.t ;
|
|
||||||
cancel: Lwt_canceler.t }
|
|
||||||
(** We accepted a incoming connection, we greeted back and
|
|
||||||
we are waiting for an acknowledgement. *)
|
|
||||||
| Running of { data: 'conn ;
|
|
||||||
current_point: Id_point.t }
|
|
||||||
(** Successfully authentificated connection, normal business. *)
|
|
||||||
| Disconnected
|
|
||||||
(** No connection established currently. *)
|
|
||||||
type 'conn state = 'conn t
|
|
||||||
|
|
||||||
val pp : Format.formatter -> 'conn t -> unit
|
|
||||||
|
|
||||||
val get : ('conn, 'meta) peer_info -> 'conn state
|
|
||||||
|
|
||||||
val is_disconnected : ('conn, 'meta) peer_info -> bool
|
|
||||||
|
|
||||||
val set_accepted :
|
|
||||||
?timestamp:Time.t ->
|
|
||||||
('conn, 'meta) peer_info -> Id_point.t -> Lwt_canceler.t -> unit
|
|
||||||
|
|
||||||
val set_running :
|
|
||||||
?timestamp:Time.t ->
|
|
||||||
('conn, 'meta) peer_info -> Id_point.t -> 'conn -> unit
|
|
||||||
|
|
||||||
val set_disconnected :
|
|
||||||
?timestamp:Time.t ->
|
|
||||||
?requested:bool ->
|
|
||||||
('conn, 'meta) peer_info -> unit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Event : sig
|
|
||||||
|
|
||||||
type kind =
|
|
||||||
| Accepting_request
|
|
||||||
(** We accepted a connection after authentifying the remote peer. *)
|
|
||||||
| Rejecting_request
|
|
||||||
(** We rejected a connection after authentifying the remote peer. *)
|
|
||||||
| Request_rejected
|
|
||||||
(** The remote peer rejected our connection. *)
|
|
||||||
| Connection_established
|
|
||||||
(** We succesfully established a authentified connection. *)
|
|
||||||
| Disconnection
|
|
||||||
(** We decided to close the connection. *)
|
|
||||||
| External_disconnection
|
|
||||||
(** The connection was closed for external reason. *)
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
kind : kind ;
|
|
||||||
timestamp : Time.t ;
|
|
||||||
point : Id_point.t ;
|
|
||||||
}
|
|
||||||
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
end
|
|
||||||
|
|
||||||
val fold_events :
|
|
||||||
('conn, 'meta) peer_info -> init:'a -> f:('a -> Event.t -> 'a) -> 'a
|
|
||||||
|
|
||||||
val watch :
|
|
||||||
('conn, 'meta) peer_info -> Event.t Lwt_stream.t * Lwt_watcher.stopper
|
|
||||||
|
|
||||||
val log_incoming_rejection :
|
|
||||||
?timestamp:Time.t ->
|
|
||||||
('conn, 'meta) peer_info -> Id_point.t -> unit
|
|
||||||
|
|
||||||
module File : sig
|
|
||||||
val load :
|
|
||||||
string -> 'meta Data_encoding.t ->
|
|
||||||
('conn, 'meta) peer_info list tzresult Lwt.t
|
|
||||||
val save :
|
|
||||||
string -> 'meta Data_encoding.t ->
|
|
||||||
('conn, 'meta) peer_info list -> unit tzresult Lwt.t
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -7,17 +7,15 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
open P2p_types
|
let (peer_id_arg : P2p_peer.Id.t RPC_arg.arg) =
|
||||||
|
|
||||||
let (peer_id_arg : P2p_types.Peer_id.t RPC_arg.arg) =
|
|
||||||
Crypto_box.Public_key_hash.rpc_arg
|
Crypto_box.Public_key_hash.rpc_arg
|
||||||
|
|
||||||
let point_arg =
|
let point_arg =
|
||||||
RPC_arg.make
|
RPC_arg.make
|
||||||
~name:"point"
|
~name:"point"
|
||||||
~descr:"A network point (ipv4:port or [ipv6]:port)."
|
~descr:"A network point (ipv4:port or [ipv6]:port)."
|
||||||
~destruct:Point.of_string
|
~destruct:P2p_point.Id.of_string
|
||||||
~construct:Point.to_string
|
~construct:P2p_point.Id.to_string
|
||||||
()
|
()
|
||||||
|
|
||||||
let versions =
|
let versions =
|
||||||
@ -25,7 +23,7 @@ let versions =
|
|||||||
~description:"Supported network layer versions."
|
~description:"Supported network layer versions."
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: Data_encoding.empty
|
~input: Data_encoding.empty
|
||||||
~output: (Data_encoding.list P2p_types.Version.encoding)
|
~output: (Data_encoding.list P2p_version.encoding)
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
RPC_path.(root / "network" / "versions")
|
RPC_path.(root / "network" / "versions")
|
||||||
|
|
||||||
@ -34,7 +32,7 @@ let stat =
|
|||||||
~description:"Global network bandwidth statistics in B/s."
|
~description:"Global network bandwidth statistics in B/s."
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: Data_encoding.empty
|
~input: Data_encoding.empty
|
||||||
~output: P2p_types.Stat.encoding
|
~output: P2p_stat.encoding
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
RPC_path.(root / "network" / "stat")
|
RPC_path.(root / "network" / "stat")
|
||||||
|
|
||||||
@ -43,7 +41,7 @@ let events =
|
|||||||
~description:"Stream of all network events"
|
~description:"Stream of all network events"
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: Data_encoding.empty
|
~input: Data_encoding.empty
|
||||||
~output: P2p_types.Connection_pool_log_event.encoding
|
~output: P2p_connection.Pool_event.encoding
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
RPC_path.(root / "network" / "log")
|
RPC_path.(root / "network" / "log")
|
||||||
|
|
||||||
@ -65,7 +63,7 @@ module Connection = struct
|
|||||||
~description:"List the running P2P connection."
|
~description:"List the running P2P connection."
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: Data_encoding.empty
|
~input: Data_encoding.empty
|
||||||
~output: (Data_encoding.list P2p_types.Connection_info.encoding)
|
~output: (Data_encoding.list P2p_connection.Info.encoding)
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
RPC_path.(root / "network" / "connection")
|
RPC_path.(root / "network" / "connection")
|
||||||
|
|
||||||
@ -73,7 +71,7 @@ module Connection = struct
|
|||||||
RPC_service.post_service
|
RPC_service.post_service
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: Data_encoding.empty
|
~input: Data_encoding.empty
|
||||||
~output: (Data_encoding.option P2p_types.Connection_info.encoding)
|
~output: (Data_encoding.option P2p_connection.Info.encoding)
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
~description:"Details about the current P2P connection to the given peer."
|
~description:"Details about the current P2P connection to the given peer."
|
||||||
RPC_path.(root / "network" / "connection" /: peer_id_arg)
|
RPC_path.(root / "network" / "connection" /: peer_id_arg)
|
||||||
@ -95,7 +93,7 @@ module Point = struct
|
|||||||
RPC_service.post_service
|
RPC_service.post_service
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: Data_encoding.empty
|
~input: Data_encoding.empty
|
||||||
~output: (Data_encoding.option P2p_types.Point_info.encoding)
|
~output: (Data_encoding.option P2p_point.Info.encoding)
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
~description: "Details about a given `IP:addr`."
|
~description: "Details about a given `IP:addr`."
|
||||||
RPC_path.(root / "network" / "point" /: point_arg)
|
RPC_path.(root / "network" / "point" /: point_arg)
|
||||||
@ -105,7 +103,7 @@ module Point = struct
|
|||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: monitor_encoding
|
~input: monitor_encoding
|
||||||
~output: (Data_encoding.list
|
~output: (Data_encoding.list
|
||||||
P2p_connection_pool_types.Point_info.Event.encoding)
|
P2p_point.Pool_event.encoding)
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
~description: "Monitor network events related to an `IP:addr`."
|
~description: "Monitor network events related to an `IP:addr`."
|
||||||
RPC_path.(root / "network" / "point" /: point_arg / "log")
|
RPC_path.(root / "network" / "point" /: point_arg / "log")
|
||||||
@ -113,14 +111,14 @@ module Point = struct
|
|||||||
let list =
|
let list =
|
||||||
let filter =
|
let filter =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
obj1 (dft "filter" (list P2p_types.Point_state.encoding) []) in
|
obj1 (dft "filter" (list P2p_point.State.encoding) []) in
|
||||||
RPC_service.post_service
|
RPC_service.post_service
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: filter
|
~input: filter
|
||||||
~output:
|
~output:
|
||||||
Data_encoding.(list (tup2
|
Data_encoding.(list (tup2
|
||||||
P2p_types.Point.encoding
|
P2p_point.Id.encoding
|
||||||
P2p_types.Point_info.encoding))
|
P2p_point.Info.encoding))
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
~description:"List the pool of known `IP:port` \
|
~description:"List the pool of known `IP:port` \
|
||||||
used for establishing P2P connections ."
|
used for establishing P2P connections ."
|
||||||
@ -134,7 +132,7 @@ module Peer_id = struct
|
|||||||
RPC_service.post_service
|
RPC_service.post_service
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: Data_encoding.empty
|
~input: Data_encoding.empty
|
||||||
~output: (Data_encoding.option P2p_types.Peer_info.encoding)
|
~output: (Data_encoding.option P2p_peer.Info.encoding)
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
~description:"Details about a given peer."
|
~description:"Details about a given peer."
|
||||||
RPC_path.(root / "network" / "peer_id" /: peer_id_arg)
|
RPC_path.(root / "network" / "peer_id" /: peer_id_arg)
|
||||||
@ -144,7 +142,7 @@ module Peer_id = struct
|
|||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: monitor_encoding
|
~input: monitor_encoding
|
||||||
~output: (Data_encoding.list
|
~output: (Data_encoding.list
|
||||||
P2p_connection_pool_types.Peer_info.Event.encoding)
|
P2p_peer.Pool_event.encoding)
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
~description:"Monitor network events related to a given peer."
|
~description:"Monitor network events related to a given peer."
|
||||||
RPC_path.(root / "network" / "peer_id" /: peer_id_arg / "log")
|
RPC_path.(root / "network" / "peer_id" /: peer_id_arg / "log")
|
||||||
@ -152,14 +150,14 @@ module Peer_id = struct
|
|||||||
let list =
|
let list =
|
||||||
let filter =
|
let filter =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
obj1 (dft "filter" (list P2p_types.Peer_state.encoding) []) in
|
obj1 (dft "filter" (list P2p_peer.State.encoding) []) in
|
||||||
RPC_service.post_service
|
RPC_service.post_service
|
||||||
~query: RPC_query.empty
|
~query: RPC_query.empty
|
||||||
~input: filter
|
~input: filter
|
||||||
~output:
|
~output:
|
||||||
Data_encoding.(list (tup2
|
Data_encoding.(list (tup2
|
||||||
P2p_types.Peer_id.encoding
|
P2p_peer.Id.encoding
|
||||||
P2p_types.Peer_info.encoding))
|
P2p_peer.Info.encoding))
|
||||||
~error: Data_encoding.empty
|
~error: Data_encoding.empty
|
||||||
~description:"List the peers the node ever met."
|
~description:"List the peers the node ever met."
|
||||||
RPC_path.(root / "network" / "peer_id")
|
RPC_path.(root / "network" / "peer_id")
|
||||||
|
@ -7,26 +7,24 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
|
|
||||||
val stat :
|
val stat :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit, unit, unit,
|
unit, unit, unit,
|
||||||
Stat.t, unit) RPC_service.t
|
P2p_stat.t, unit) RPC_service.t
|
||||||
|
|
||||||
val versions :
|
val versions :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit, unit, unit,
|
unit, unit, unit,
|
||||||
Version.t list, unit) RPC_service.t
|
P2p_version.t list, unit) RPC_service.t
|
||||||
|
|
||||||
val events :
|
val events :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit, unit, unit,
|
unit, unit, unit,
|
||||||
Connection_pool_log_event.t, unit) RPC_service.t
|
P2p_connection.Pool_event.t, unit) RPC_service.t
|
||||||
|
|
||||||
val connect :
|
val connect :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit * Point.t, unit, float,
|
unit * P2p_point.Id.t, unit, float,
|
||||||
unit tzresult, unit) RPC_service.t
|
unit tzresult, unit) RPC_service.t
|
||||||
|
|
||||||
module Connection : sig
|
module Connection : sig
|
||||||
@ -34,16 +32,16 @@ module Connection : sig
|
|||||||
val list :
|
val list :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit, unit, unit,
|
unit, unit, unit,
|
||||||
Connection_info.t list, unit) RPC_service.t
|
P2p_connection.Info.t list, unit) RPC_service.t
|
||||||
|
|
||||||
val info :
|
val info :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit * Peer_id.t, unit, unit,
|
unit * P2p_peer.Id.t, unit, unit,
|
||||||
Connection_info.t option, unit) RPC_service.t
|
P2p_connection.Info.t option, unit) RPC_service.t
|
||||||
|
|
||||||
val kick :
|
val kick :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit * Peer_id.t, unit, bool,
|
unit * P2p_peer.Id.t, unit, bool,
|
||||||
unit, unit) RPC_service.t
|
unit, unit) RPC_service.t
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -51,33 +49,33 @@ end
|
|||||||
module Point : sig
|
module Point : sig
|
||||||
val list :
|
val list :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit, unit, Point_state.t list,
|
unit, unit, P2p_point.State.t list,
|
||||||
(Point.t * Point_info.t) list, unit) RPC_service.t
|
(P2p_point.Id.t * P2p_point.Info.t) list, unit) RPC_service.t
|
||||||
val info :
|
val info :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit * Point.t, unit, unit,
|
unit * P2p_point.Id.t, unit, unit,
|
||||||
Point_info.t option, unit) RPC_service.t
|
P2p_point.Info.t option, unit) RPC_service.t
|
||||||
val events :
|
val events :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit * Point.t, unit, bool,
|
unit * P2p_point.Id.t, unit, bool,
|
||||||
P2p_connection_pool_types.Point_info.Event.t list, unit) RPC_service.t
|
P2p_point.Pool_event.t list, unit) RPC_service.t
|
||||||
end
|
end
|
||||||
|
|
||||||
module Peer_id : sig
|
module Peer_id : sig
|
||||||
|
|
||||||
val list :
|
val list :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit, unit, Peer_state.t list,
|
unit, unit, P2p_peer.State.t list,
|
||||||
(Peer_id.t * Peer_info.t) list, unit) RPC_service.t
|
(P2p_peer.Id.t * P2p_peer.Info.t) list, unit) RPC_service.t
|
||||||
|
|
||||||
val info :
|
val info :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit * Peer_id.t, unit, unit,
|
unit * P2p_peer.Id.t, unit, unit,
|
||||||
Peer_info.t option, unit) RPC_service.t
|
P2p_peer.Info.t option, unit) RPC_service.t
|
||||||
|
|
||||||
val events :
|
val events :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit * Peer_id.t, unit, bool,
|
unit * P2p_peer.Id.t, unit, bool,
|
||||||
P2p_connection_pool_types.Peer_info.Event.t list, unit) RPC_service.t
|
P2p_peer.Pool_event.t list, unit) RPC_service.t
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,717 +0,0 @@
|
|||||||
(**************************************************************************)
|
|
||||||
(* *)
|
|
||||||
(* Copyright (c) 2014 - 2017. *)
|
|
||||||
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
||||||
(* *)
|
|
||||||
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
||||||
(* *)
|
|
||||||
(**************************************************************************)
|
|
||||||
|
|
||||||
module Version = struct
|
|
||||||
type t = {
|
|
||||||
name : string ;
|
|
||||||
major : int ;
|
|
||||||
minor : int ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let pp ppf { name ; major ; minor } =
|
|
||||||
Format.fprintf ppf "%s.%d.%d" name major minor
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
conv
|
|
||||||
(fun { name; major; minor } -> (name, major, minor))
|
|
||||||
(fun (name, major, minor) -> { name; major; minor })
|
|
||||||
(obj3
|
|
||||||
(req "name" string)
|
|
||||||
(req "major" int8)
|
|
||||||
(req "minor" int8))
|
|
||||||
|
|
||||||
(* the common version for a pair of peers, if any, is the maximum one,
|
|
||||||
in lexicographic order *)
|
|
||||||
let common la lb =
|
|
||||||
let la = List.sort (fun l r -> compare r l) la in
|
|
||||||
let lb = List.sort (fun l r -> compare r l) lb in
|
|
||||||
let rec find = function
|
|
||||||
| [], _ | _, [] -> None
|
|
||||||
| ((a :: ta) as la), ((b :: tb) as lb) ->
|
|
||||||
if a = b then Some a
|
|
||||||
else if a < b then find (ta, lb)
|
|
||||||
else find (la, tb)
|
|
||||||
in find (la, lb)
|
|
||||||
end
|
|
||||||
|
|
||||||
module Stat = struct
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
total_sent : int64 ;
|
|
||||||
total_recv : int64 ;
|
|
||||||
current_inflow : int ;
|
|
||||||
current_outflow : int ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let empty = {
|
|
||||||
total_sent = 0L ;
|
|
||||||
total_recv = 0L ;
|
|
||||||
current_inflow = 0 ;
|
|
||||||
current_outflow = 0 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let print_size ppf sz =
|
|
||||||
let ratio n = (float_of_int sz /. float_of_int (1 lsl n)) in
|
|
||||||
if sz < 1 lsl 10 then
|
|
||||||
Format.fprintf ppf "%d B" sz
|
|
||||||
else if sz < 1 lsl 20 then
|
|
||||||
Format.fprintf ppf "%.2f kiB" (ratio 10)
|
|
||||||
else
|
|
||||||
Format.fprintf ppf "%.2f MiB" (ratio 20)
|
|
||||||
|
|
||||||
let print_size64 ppf sz =
|
|
||||||
let open Int64 in
|
|
||||||
let ratio n = (to_float sz /. float_of_int (1 lsl n)) in
|
|
||||||
if sz < shift_left 1L 10 then
|
|
||||||
Format.fprintf ppf "%Ld B" sz
|
|
||||||
else if sz < shift_left 1L 20 then
|
|
||||||
Format.fprintf ppf "%.2f kiB" (ratio 10)
|
|
||||||
else if sz < shift_left 1L 30 then
|
|
||||||
Format.fprintf ppf "%.2f MiB" (ratio 20)
|
|
||||||
else if sz < shift_left 1L 40 then
|
|
||||||
Format.fprintf ppf "%.2f GiB" (ratio 30)
|
|
||||||
else
|
|
||||||
Format.fprintf ppf "%.2f TiB" (ratio 40)
|
|
||||||
|
|
||||||
let pp ppf stat =
|
|
||||||
Format.fprintf ppf
|
|
||||||
"↗ %a (%a/s) ↘ %a (%a/s)"
|
|
||||||
print_size64 stat.total_sent print_size stat.current_outflow
|
|
||||||
print_size64 stat.total_recv print_size stat.current_inflow
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
conv
|
|
||||||
(fun { total_sent ; total_recv ; current_inflow ; current_outflow } ->
|
|
||||||
(total_sent, total_recv, current_inflow, current_outflow))
|
|
||||||
(fun (total_sent, total_recv, current_inflow, current_outflow) ->
|
|
||||||
{ total_sent ; total_recv ; current_inflow ; current_outflow })
|
|
||||||
(obj4
|
|
||||||
(req "total_sent" int64)
|
|
||||||
(req "total_recv" int64)
|
|
||||||
(req "current_inflow" int31)
|
|
||||||
(req "current_outflow" int31))
|
|
||||||
end
|
|
||||||
|
|
||||||
(* public types *)
|
|
||||||
type addr = Ipaddr.V6.t
|
|
||||||
|
|
||||||
let addr_encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
splitted
|
|
||||||
~json:begin
|
|
||||||
conv
|
|
||||||
Ipaddr.V6.to_string
|
|
||||||
Ipaddr.V6.of_string_exn
|
|
||||||
string
|
|
||||||
end
|
|
||||||
~binary:begin
|
|
||||||
conv
|
|
||||||
Ipaddr.V6.to_bytes
|
|
||||||
Ipaddr.V6.of_bytes_exn
|
|
||||||
string
|
|
||||||
end
|
|
||||||
|
|
||||||
type port = int
|
|
||||||
|
|
||||||
|
|
||||||
module Id_point = struct
|
|
||||||
|
|
||||||
module T = struct
|
|
||||||
|
|
||||||
(* A net point (address x port). *)
|
|
||||||
type t = addr * port option
|
|
||||||
let compare (a1, p1) (a2, p2) =
|
|
||||||
match Ipaddr.V6.compare a1 a2 with
|
|
||||||
| 0 -> Pervasives.compare p1 p2
|
|
||||||
| x -> x
|
|
||||||
let equal p1 p2 = compare p1 p2 = 0
|
|
||||||
let hash = Hashtbl.hash
|
|
||||||
let pp ppf (addr, port) =
|
|
||||||
match port with
|
|
||||||
| None ->
|
|
||||||
Format.fprintf ppf "[%a]:??" Ipaddr.V6.pp_hum addr
|
|
||||||
| Some port ->
|
|
||||||
Format.fprintf ppf "[%a]:%d" Ipaddr.V6.pp_hum addr port
|
|
||||||
let pp_opt ppf = function
|
|
||||||
| None -> Format.pp_print_string ppf "none"
|
|
||||||
| Some point -> pp ppf point
|
|
||||||
let to_string t = Format.asprintf "%a" pp t
|
|
||||||
|
|
||||||
let is_local (addr, _) = Ipaddr.V6.is_private addr
|
|
||||||
let is_global (addr, _) = not @@ Ipaddr.V6.is_private addr
|
|
||||||
|
|
||||||
let of_point (addr, port) = addr, Some port
|
|
||||||
let to_point = function
|
|
||||||
| _, None -> None
|
|
||||||
| addr, Some port -> Some (addr, port)
|
|
||||||
let to_point_exn = function
|
|
||||||
| _, None -> invalid_arg "to_point_exn"
|
|
||||||
| addr, Some port -> addr, port
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
(obj2
|
|
||||||
(req "addr" addr_encoding)
|
|
||||||
(opt "port" uint16))
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
include T
|
|
||||||
|
|
||||||
module Map = Map.Make (T)
|
|
||||||
module Set = Set.Make (T)
|
|
||||||
module Table = Hashtbl.Make (T)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Peer_id = Crypto_box.Public_key_hash
|
|
||||||
|
|
||||||
module Peer_state = struct
|
|
||||||
|
|
||||||
type t =
|
|
||||||
| Accepted
|
|
||||||
| Running
|
|
||||||
| Disconnected
|
|
||||||
|
|
||||||
let pp_digram ppf = function
|
|
||||||
| Accepted -> Format.fprintf ppf "⚎"
|
|
||||||
| Running -> Format.fprintf ppf "⚌"
|
|
||||||
| Disconnected -> Format.fprintf ppf "⚏"
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
string_enum [
|
|
||||||
"accepted", Accepted ;
|
|
||||||
"running", Running ;
|
|
||||||
"disconnected", Disconnected ;
|
|
||||||
]
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Peer_info = struct
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
score : float ;
|
|
||||||
trusted : bool ;
|
|
||||||
state : Peer_state.t ;
|
|
||||||
id_point : Id_point.t option ;
|
|
||||||
stat : Stat.t ;
|
|
||||||
last_failed_connection : (Id_point.t * Time.t) option ;
|
|
||||||
last_rejected_connection : (Id_point.t * Time.t) option ;
|
|
||||||
last_established_connection : (Id_point.t * Time.t) option ;
|
|
||||||
last_disconnection : (Id_point.t * Time.t) option ;
|
|
||||||
last_seen : (Id_point.t * Time.t) option ;
|
|
||||||
last_miss : (Id_point.t * Time.t) option ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
conv
|
|
||||||
(fun (
|
|
||||||
{ score ; trusted ; state ; id_point ; stat ;
|
|
||||||
last_failed_connection ; last_rejected_connection ;
|
|
||||||
last_established_connection ; last_disconnection ;
|
|
||||||
last_seen ; last_miss }) ->
|
|
||||||
((score, trusted, state, id_point, stat),
|
|
||||||
(last_failed_connection, last_rejected_connection,
|
|
||||||
last_established_connection, last_disconnection,
|
|
||||||
last_seen, last_miss)))
|
|
||||||
(fun ((score, trusted, state, id_point, stat),
|
|
||||||
(last_failed_connection, last_rejected_connection,
|
|
||||||
last_established_connection, last_disconnection,
|
|
||||||
last_seen, last_miss)) ->
|
|
||||||
{ score ; trusted ; state ; id_point ; stat ;
|
|
||||||
last_failed_connection ; last_rejected_connection ;
|
|
||||||
last_established_connection ; last_disconnection ;
|
|
||||||
last_seen ; last_miss })
|
|
||||||
(merge_objs
|
|
||||||
(obj5
|
|
||||||
(req "score" float)
|
|
||||||
(req "trusted" bool)
|
|
||||||
(req "state" Peer_state.encoding)
|
|
||||||
(opt "reachable_at" Id_point.encoding)
|
|
||||||
(req "stat" Stat.encoding))
|
|
||||||
(obj6
|
|
||||||
(opt "last_failed_connection" (tup2 Id_point.encoding Time.encoding))
|
|
||||||
(opt "last_rejected_connection" (tup2 Id_point.encoding Time.encoding))
|
|
||||||
(opt "last_established_connection" (tup2 Id_point.encoding Time.encoding))
|
|
||||||
(opt "last_disconnection" (tup2 Id_point.encoding Time.encoding))
|
|
||||||
(opt "last_seen" (tup2 Id_point.encoding Time.encoding))
|
|
||||||
(opt "last_miss" (tup2 Id_point.encoding Time.encoding))))
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Point = struct
|
|
||||||
|
|
||||||
module T = struct
|
|
||||||
|
|
||||||
(* A net point (address x port). *)
|
|
||||||
type t = addr * port
|
|
||||||
let compare (a1, p1) (a2, p2) =
|
|
||||||
match Ipaddr.V6.compare a1 a2 with
|
|
||||||
| 0 -> p1 - p2
|
|
||||||
| x -> x
|
|
||||||
let equal p1 p2 = compare p1 p2 = 0
|
|
||||||
let hash = Hashtbl.hash
|
|
||||||
let pp ppf (addr, port) =
|
|
||||||
match Ipaddr.v4_of_v6 addr with
|
|
||||||
| Some addr ->
|
|
||||||
Format.fprintf ppf "%a:%d" Ipaddr.V4.pp_hum addr port
|
|
||||||
| None ->
|
|
||||||
Format.fprintf ppf "[%a]:%d" Ipaddr.V6.pp_hum addr port
|
|
||||||
let pp_opt ppf = function
|
|
||||||
| None -> Format.pp_print_string ppf "none"
|
|
||||||
| Some point -> pp ppf point
|
|
||||||
|
|
||||||
let is_local (addr, _) = Ipaddr.V6.is_private addr
|
|
||||||
let is_global (addr, _) = not @@ Ipaddr.V6.is_private addr
|
|
||||||
|
|
||||||
let check_port port =
|
|
||||||
if TzString.mem_char port '[' ||
|
|
||||||
TzString.mem_char port ']' ||
|
|
||||||
TzString.mem_char port ':' then
|
|
||||||
invalid_arg "Utils.parse_addr_port (invalid character in port)"
|
|
||||||
|
|
||||||
let parse_addr_port s =
|
|
||||||
let len = String.length s in
|
|
||||||
if len = 0 then
|
|
||||||
("", "")
|
|
||||||
else if s.[0] = '[' then begin (* inline IPv6 *)
|
|
||||||
match String.rindex s ']' with
|
|
||||||
| exception Not_found ->
|
|
||||||
invalid_arg "Utils.parse_addr_port (missing ']')"
|
|
||||||
| pos ->
|
|
||||||
let addr = String.sub s 1 (pos - 1) in
|
|
||||||
let port =
|
|
||||||
if pos = len - 1 then
|
|
||||||
""
|
|
||||||
else if s.[pos+1] <> ':' then
|
|
||||||
invalid_arg "Utils.parse_addr_port (unexpected char after ']')"
|
|
||||||
else
|
|
||||||
String.sub s (pos + 2) (len - pos - 2) in
|
|
||||||
check_port port ;
|
|
||||||
addr, port
|
|
||||||
end else begin
|
|
||||||
match String.rindex s ']' with
|
|
||||||
| _pos ->
|
|
||||||
invalid_arg "Utils.parse_addr_port (unexpected char ']')"
|
|
||||||
| exception Not_found ->
|
|
||||||
match String.index s ':' with
|
|
||||||
| exception _ -> s, ""
|
|
||||||
| pos ->
|
|
||||||
match String.index_from s (pos+1) ':' with
|
|
||||||
| exception _ ->
|
|
||||||
let addr = String.sub s 0 pos in
|
|
||||||
let port = String.sub s (pos + 1) (len - pos - 1) in
|
|
||||||
check_port port ;
|
|
||||||
addr, port
|
|
||||||
| _pos ->
|
|
||||||
invalid_arg "Utils.parse_addr_port: IPv6 addresses must be bracketed"
|
|
||||||
end
|
|
||||||
|
|
||||||
let of_string_exn str =
|
|
||||||
let addr, port = parse_addr_port str in
|
|
||||||
let port = int_of_string port in
|
|
||||||
if port < 0 && port > 1 lsl 16 - 1 then
|
|
||||||
invalid_arg "port must be between 0 and 65535" ;
|
|
||||||
match Ipaddr.of_string_exn addr with
|
|
||||||
| V4 addr -> Ipaddr.v6_of_v4 addr, port
|
|
||||||
| V6 addr -> addr, port
|
|
||||||
|
|
||||||
let of_string str =
|
|
||||||
try Ok (of_string_exn str) with
|
|
||||||
| Invalid_argument s -> Error s
|
|
||||||
| Failure s -> Error s
|
|
||||||
| _ -> Error "Point.of_string"
|
|
||||||
|
|
||||||
let to_string saddr = Format.asprintf "%a" pp saddr
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
Data_encoding.conv to_string of_string_exn Data_encoding.string
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
include T
|
|
||||||
|
|
||||||
module Map = Map.Make (T)
|
|
||||||
module Set = Set.Make (T)
|
|
||||||
module Table = Hashtbl.Make (T)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Point_state = struct
|
|
||||||
|
|
||||||
type t =
|
|
||||||
| Requested
|
|
||||||
| Accepted of Peer_id.t
|
|
||||||
| Running of Peer_id.t
|
|
||||||
| Disconnected
|
|
||||||
|
|
||||||
let of_peer_id = function
|
|
||||||
| Requested -> None
|
|
||||||
| Accepted pi -> Some pi
|
|
||||||
| Running pi -> Some pi
|
|
||||||
| Disconnected -> None
|
|
||||||
|
|
||||||
let of_peerid_state state pi =
|
|
||||||
match state, pi with
|
|
||||||
| Requested, _ -> Requested
|
|
||||||
| Accepted _, Some pi -> Accepted pi
|
|
||||||
| Running _, Some pi -> Running pi
|
|
||||||
| Disconnected, _ -> Disconnected
|
|
||||||
| _ -> invalid_arg "state_of_state_peerid"
|
|
||||||
|
|
||||||
let pp_digram ppf = function
|
|
||||||
| Requested -> Format.fprintf ppf "⚎"
|
|
||||||
| Accepted _ -> Format.fprintf ppf "⚍"
|
|
||||||
| Running _ -> Format.fprintf ppf "⚌"
|
|
||||||
| Disconnected -> Format.fprintf ppf "⚏"
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
let branch_encoding name obj =
|
|
||||||
conv (fun x -> (), x) (fun ((), x) -> x)
|
|
||||||
(merge_objs
|
|
||||||
(obj1 (req "event_kind" (constant name))) obj) in
|
|
||||||
union ~tag_size:`Uint8 [
|
|
||||||
case (Tag 0) (branch_encoding "requested" empty)
|
|
||||||
(function Requested -> Some () | _ -> None)
|
|
||||||
(fun () -> Requested) ;
|
|
||||||
case (Tag 1) (branch_encoding "accepted"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Accepted peer_id -> Some peer_id | _ -> None)
|
|
||||||
(fun peer_id -> Accepted peer_id) ;
|
|
||||||
case (Tag 2) (branch_encoding "running"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Running peer_id -> Some peer_id | _ -> None)
|
|
||||||
(fun peer_id -> Running peer_id) ;
|
|
||||||
case (Tag 3) (branch_encoding "disconnected" empty)
|
|
||||||
(function Disconnected -> Some () | _ -> None)
|
|
||||||
(fun () -> Disconnected) ;
|
|
||||||
]
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Point_info = struct
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
trusted : bool ;
|
|
||||||
greylisted_until : Time.t ;
|
|
||||||
state : Point_state.t ;
|
|
||||||
last_failed_connection : Time.t option ;
|
|
||||||
last_rejected_connection : (Peer_id.t * Time.t) option ;
|
|
||||||
last_established_connection : (Peer_id.t * Time.t) option ;
|
|
||||||
last_disconnection : (Peer_id.t * Time.t) option ;
|
|
||||||
last_seen : (Peer_id.t * Time.t) option ;
|
|
||||||
last_miss : Time.t option ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
conv
|
|
||||||
(fun { trusted ; greylisted_until ; state ;
|
|
||||||
last_failed_connection ; last_rejected_connection ;
|
|
||||||
last_established_connection ; last_disconnection ;
|
|
||||||
last_seen ; last_miss } ->
|
|
||||||
let peer_id = Point_state.of_peer_id state in
|
|
||||||
(trusted, greylisted_until, state, peer_id,
|
|
||||||
last_failed_connection, last_rejected_connection,
|
|
||||||
last_established_connection, last_disconnection,
|
|
||||||
last_seen, last_miss))
|
|
||||||
(fun (trusted, greylisted_until, state, peer_id,
|
|
||||||
last_failed_connection, last_rejected_connection,
|
|
||||||
last_established_connection, last_disconnection,
|
|
||||||
last_seen, last_miss) ->
|
|
||||||
let state = Point_state.of_peerid_state state peer_id in
|
|
||||||
{ trusted ; greylisted_until ; state ;
|
|
||||||
last_failed_connection ; last_rejected_connection ;
|
|
||||||
last_established_connection ; last_disconnection ;
|
|
||||||
last_seen ; last_miss })
|
|
||||||
(obj10
|
|
||||||
(req "trusted" bool)
|
|
||||||
(dft "greylisted_until" Time.encoding Time.epoch)
|
|
||||||
(req "state" Point_state.encoding)
|
|
||||||
(opt "peer_id" Peer_id.encoding)
|
|
||||||
(opt "last_failed_connection" Time.encoding)
|
|
||||||
(opt "last_rejected_connection" (tup2 Peer_id.encoding Time.encoding))
|
|
||||||
(opt "last_established_connection" (tup2 Peer_id.encoding Time.encoding))
|
|
||||||
(opt "last_disconnection" (tup2 Peer_id.encoding Time.encoding))
|
|
||||||
(opt "last_seen" (tup2 Peer_id.encoding Time.encoding))
|
|
||||||
(opt "last_miss" Time.encoding))
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
module Identity = struct
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
peer_id : Peer_id.t ;
|
|
||||||
public_key : Crypto_box.public_key ;
|
|
||||||
secret_key : Crypto_box.secret_key ;
|
|
||||||
proof_of_work_stamp : Crypto_box.nonce ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
conv
|
|
||||||
(fun { public_key ; secret_key ; proof_of_work_stamp ; _ } ->
|
|
||||||
(public_key, secret_key, proof_of_work_stamp))
|
|
||||||
(fun (public_key, secret_key, proof_of_work_stamp) ->
|
|
||||||
let peer_id = Crypto_box.hash public_key in
|
|
||||||
{ peer_id ; public_key ; secret_key ; proof_of_work_stamp })
|
|
||||||
(obj3
|
|
||||||
(req "public_key" Crypto_box.public_key_encoding)
|
|
||||||
(req "secret_key" Crypto_box.secret_key_encoding)
|
|
||||||
(req "proof_of_work_stamp" Crypto_box.nonce_encoding))
|
|
||||||
|
|
||||||
let generate ?max target =
|
|
||||||
let secret_key, public_key, peer_id = Crypto_box.random_keypair () in
|
|
||||||
let proof_of_work_stamp =
|
|
||||||
Crypto_box.generate_proof_of_work ?max public_key target in
|
|
||||||
{ peer_id ; public_key ; secret_key ; proof_of_work_stamp }
|
|
||||||
|
|
||||||
let animation = [|
|
|
||||||
"|.....|" ;
|
|
||||||
"|o....|" ;
|
|
||||||
"|oo...|" ;
|
|
||||||
"|ooo..|" ;
|
|
||||||
"|.ooo.|" ;
|
|
||||||
"|..ooo|" ;
|
|
||||||
"|...oo|" ;
|
|
||||||
"|....o|" ;
|
|
||||||
"|.....|" ;
|
|
||||||
"|.....|" ;
|
|
||||||
"|.....|" ;
|
|
||||||
"|.....|" ;
|
|
||||||
|]
|
|
||||||
|
|
||||||
let init = String.make (String.length animation.(0)) '\ '
|
|
||||||
let clean = String.make (String.length animation.(0)) '\b'
|
|
||||||
let animation = Array.map (fun x -> clean ^ x) animation
|
|
||||||
let animation_size = Array.length animation
|
|
||||||
let duration = 1200 / animation_size
|
|
||||||
|
|
||||||
let generate_with_animation ppf target =
|
|
||||||
Format.fprintf ppf "%s%!" init ;
|
|
||||||
let count = ref 10000 in
|
|
||||||
let rec loop n =
|
|
||||||
let start = Mtime_clock.counter () in
|
|
||||||
Format.fprintf ppf "%s%!" animation.(n mod animation_size);
|
|
||||||
try generate ~max:!count target
|
|
||||||
with Not_found ->
|
|
||||||
let time = Mtime.Span.to_ms (Mtime_clock.count start) in
|
|
||||||
count :=
|
|
||||||
if time <= 0. then
|
|
||||||
!count * 10
|
|
||||||
else
|
|
||||||
!count * duration / int_of_float time ;
|
|
||||||
loop (n+1)
|
|
||||||
in
|
|
||||||
let id = loop 0 in
|
|
||||||
Format.fprintf ppf "%s%s\n%!" clean init ;
|
|
||||||
id
|
|
||||||
|
|
||||||
let generate target = generate target
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Connection_info = struct
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
incoming : bool;
|
|
||||||
peer_id : Peer_id.t;
|
|
||||||
id_point : Id_point.t;
|
|
||||||
remote_socket_port : port;
|
|
||||||
versions : Version.t list ;
|
|
||||||
}
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
conv
|
|
||||||
(fun { incoming ; peer_id ; id_point ; remote_socket_port ; versions } ->
|
|
||||||
(incoming, peer_id, id_point, remote_socket_port, versions))
|
|
||||||
(fun (incoming, peer_id, id_point, remote_socket_port, versions) ->
|
|
||||||
{ incoming ; peer_id ; id_point ; remote_socket_port ; versions })
|
|
||||||
(obj5
|
|
||||||
(req "incoming" bool)
|
|
||||||
(req "peer_id" Peer_id.encoding)
|
|
||||||
(req "id_point" Id_point.encoding)
|
|
||||||
(req "remote_socket_port" uint16)
|
|
||||||
(req "versions" (list Version.encoding)))
|
|
||||||
|
|
||||||
let pp ppf
|
|
||||||
{ incoming ; id_point = (remote_addr, remote_port) ;
|
|
||||||
remote_socket_port ; peer_id ; versions } =
|
|
||||||
let version = List.hd versions in
|
|
||||||
let point = match remote_port with
|
|
||||||
| None -> remote_addr, remote_socket_port
|
|
||||||
| Some port -> remote_addr, port in
|
|
||||||
Format.fprintf ppf "%s %a %a (%a)"
|
|
||||||
(if incoming then "↘" else "↗")
|
|
||||||
Peer_id.pp peer_id
|
|
||||||
Point.pp point
|
|
||||||
Version.pp version
|
|
||||||
end
|
|
||||||
|
|
||||||
module Connection_pool_log_event = struct
|
|
||||||
|
|
||||||
type t =
|
|
||||||
|
|
||||||
| Too_few_connections
|
|
||||||
| Too_many_connections
|
|
||||||
|
|
||||||
| New_point of Point.t
|
|
||||||
| New_peer of Peer_id.t
|
|
||||||
|
|
||||||
| Gc_points
|
|
||||||
| Gc_peer_ids
|
|
||||||
|
|
||||||
| Incoming_connection of Point.t
|
|
||||||
| Outgoing_connection of Point.t
|
|
||||||
| Authentication_failed of Point.t
|
|
||||||
| Accepting_request of Point.t * Id_point.t * Peer_id.t
|
|
||||||
| Rejecting_request of Point.t * Id_point.t * Peer_id.t
|
|
||||||
| Request_rejected of Point.t * (Id_point.t * Peer_id.t) option
|
|
||||||
| Connection_established of Id_point.t * Peer_id.t
|
|
||||||
|
|
||||||
| Swap_request_received of { source : Peer_id.t }
|
|
||||||
| Swap_ack_received of { source : Peer_id.t }
|
|
||||||
| Swap_request_sent of { source : Peer_id.t }
|
|
||||||
| Swap_ack_sent of { source : Peer_id.t }
|
|
||||||
| Swap_request_ignored of { source : Peer_id.t }
|
|
||||||
| Swap_success of { source : Peer_id.t }
|
|
||||||
| Swap_failure of { source : Peer_id.t }
|
|
||||||
|
|
||||||
| Disconnection of Peer_id.t
|
|
||||||
| External_disconnection of Peer_id.t
|
|
||||||
|
|
||||||
let encoding =
|
|
||||||
let open Data_encoding in
|
|
||||||
let branch_encoding name obj =
|
|
||||||
conv (fun x -> (), x) (fun ((), x) -> x)
|
|
||||||
(merge_objs
|
|
||||||
(obj1 (req "event" (constant name))) obj) in
|
|
||||||
union ~tag_size:`Uint8 [
|
|
||||||
case (Tag 0) (branch_encoding "too_few_connections" empty)
|
|
||||||
(function Too_few_connections -> Some () | _ -> None)
|
|
||||||
(fun () -> Too_few_connections) ;
|
|
||||||
case (Tag 1) (branch_encoding "too_many_connections" empty)
|
|
||||||
(function Too_many_connections -> Some () | _ -> None)
|
|
||||||
(fun () -> Too_many_connections) ;
|
|
||||||
case (Tag 2) (branch_encoding "new_point"
|
|
||||||
(obj1 (req "point" Point.encoding)))
|
|
||||||
(function New_point p -> Some p | _ -> None)
|
|
||||||
(fun p -> New_point p) ;
|
|
||||||
case (Tag 3) (branch_encoding "new_peer"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function New_peer p -> Some p | _ -> None)
|
|
||||||
(fun p -> New_peer p) ;
|
|
||||||
case (Tag 4) (branch_encoding "incoming_connection"
|
|
||||||
(obj1 (req "point" Point.encoding)))
|
|
||||||
(function Incoming_connection p -> Some p | _ -> None)
|
|
||||||
(fun p -> Incoming_connection p) ;
|
|
||||||
case (Tag 5) (branch_encoding "outgoing_connection"
|
|
||||||
(obj1 (req "point" Point.encoding)))
|
|
||||||
(function Outgoing_connection p -> Some p | _ -> None)
|
|
||||||
(fun p -> Outgoing_connection p) ;
|
|
||||||
case (Tag 6) (branch_encoding "authentication_failed"
|
|
||||||
(obj1 (req "point" Point.encoding)))
|
|
||||||
(function Authentication_failed p -> Some p | _ -> None)
|
|
||||||
(fun p -> Authentication_failed p) ;
|
|
||||||
case (Tag 7) (branch_encoding "accepting_request"
|
|
||||||
(obj3
|
|
||||||
(req "point" Point.encoding)
|
|
||||||
(req "id_point" Id_point.encoding)
|
|
||||||
(req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Accepting_request (p, id_p, g) ->
|
|
||||||
Some (p, id_p, g) | _ -> None)
|
|
||||||
(fun (p, id_p, g) -> Accepting_request (p, id_p, g)) ;
|
|
||||||
case (Tag 8) (branch_encoding "rejecting_request"
|
|
||||||
(obj3
|
|
||||||
(req "point" Point.encoding)
|
|
||||||
(req "id_point" Id_point.encoding)
|
|
||||||
(req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Rejecting_request (p, id_p, g) ->
|
|
||||||
Some (p, id_p, g) | _ -> None)
|
|
||||||
(fun (p, id_p, g) -> Rejecting_request (p, id_p, g)) ;
|
|
||||||
case (Tag 9) (branch_encoding "request_rejected"
|
|
||||||
(obj2
|
|
||||||
(req "point" Point.encoding)
|
|
||||||
(opt "identity"
|
|
||||||
(tup2 Id_point.encoding Peer_id.encoding))))
|
|
||||||
(function Request_rejected (p, id) -> Some (p, id) | _ -> None)
|
|
||||||
(fun (p, id) -> Request_rejected (p, id)) ;
|
|
||||||
case (Tag 10) (branch_encoding "connection_established"
|
|
||||||
(obj2
|
|
||||||
(req "id_point" Id_point.encoding)
|
|
||||||
(req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Connection_established (id_p, g) ->
|
|
||||||
Some (id_p, g) | _ -> None)
|
|
||||||
(fun (id_p, g) -> Connection_established (id_p, g)) ;
|
|
||||||
case (Tag 11) (branch_encoding "disconnection"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function Disconnection g -> Some g | _ -> None)
|
|
||||||
(fun g -> Disconnection g) ;
|
|
||||||
case (Tag 12) (branch_encoding "external_disconnection"
|
|
||||||
(obj1 (req "peer_id" Peer_id.encoding)))
|
|
||||||
(function External_disconnection g -> Some g | _ -> None)
|
|
||||||
(fun g -> External_disconnection g) ;
|
|
||||||
case (Tag 13) (branch_encoding "gc_points" empty)
|
|
||||||
(function Gc_points -> Some () | _ -> None)
|
|
||||||
(fun () -> Gc_points) ;
|
|
||||||
case (Tag 14) (branch_encoding "gc_peer_ids" empty)
|
|
||||||
(function Gc_peer_ids -> Some () | _ -> None)
|
|
||||||
(fun () -> Gc_peer_ids) ;
|
|
||||||
case (Tag 15) (branch_encoding "swap_request_received"
|
|
||||||
(obj1 (req "source" Peer_id.encoding)))
|
|
||||||
(function
|
|
||||||
| Swap_request_received { source } -> Some source
|
|
||||||
| _ -> None)
|
|
||||||
(fun source -> Swap_request_received { source }) ;
|
|
||||||
case (Tag 16) (branch_encoding "swap_ack_received"
|
|
||||||
(obj1 (req "source" Peer_id.encoding)))
|
|
||||||
(function
|
|
||||||
| Swap_ack_received { source } -> Some source
|
|
||||||
| _ -> None)
|
|
||||||
(fun source -> Swap_ack_received { source }) ;
|
|
||||||
case (Tag 17) (branch_encoding "swap_request_sent"
|
|
||||||
(obj1 (req "source" Peer_id.encoding)))
|
|
||||||
(function
|
|
||||||
| Swap_request_sent { source } -> Some source
|
|
||||||
| _ -> None)
|
|
||||||
(fun source -> Swap_request_sent { source }) ;
|
|
||||||
case (Tag 18) (branch_encoding "swap_ack_sent"
|
|
||||||
(obj1 (req "source" Peer_id.encoding)))
|
|
||||||
(function
|
|
||||||
| Swap_ack_sent { source } -> Some source
|
|
||||||
| _ -> None)
|
|
||||||
(fun source -> Swap_ack_sent { source }) ;
|
|
||||||
case (Tag 19) (branch_encoding "swap_request_ignored"
|
|
||||||
(obj1 (req "source" Peer_id.encoding)))
|
|
||||||
(function
|
|
||||||
| Swap_request_ignored { source } -> Some source
|
|
||||||
| _ -> None)
|
|
||||||
(fun source -> Swap_request_ignored { source }) ;
|
|
||||||
case (Tag 20) (branch_encoding "swap_success"
|
|
||||||
(obj1 (req "source" Peer_id.encoding)))
|
|
||||||
(function
|
|
||||||
| Swap_success { source } -> Some source
|
|
||||||
| _ -> None)
|
|
||||||
(fun source -> Swap_success { source }) ;
|
|
||||||
case (Tag 21) (branch_encoding "swap_failure"
|
|
||||||
(obj1 (req "source" Peer_id.encoding)))
|
|
||||||
(function
|
|
||||||
| Swap_failure { source } -> Some source
|
|
||||||
| _ -> None)
|
|
||||||
(fun source -> Swap_failure { source }) ;
|
|
||||||
]
|
|
||||||
|
|
||||||
end
|
|
@ -1,263 +0,0 @@
|
|||||||
(**************************************************************************)
|
|
||||||
(* *)
|
|
||||||
(* Copyright (c) 2014 - 2017. *)
|
|
||||||
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
||||||
(* *)
|
|
||||||
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
||||||
(* *)
|
|
||||||
(**************************************************************************)
|
|
||||||
|
|
||||||
(** Protocol version *)
|
|
||||||
|
|
||||||
module Version : sig
|
|
||||||
type t = {
|
|
||||||
name : string ;
|
|
||||||
major : int ;
|
|
||||||
minor : int ;
|
|
||||||
}
|
|
||||||
(** Type of a protocol version. *)
|
|
||||||
|
|
||||||
val pp : Format.formatter -> t -> unit
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
val common : t list -> t list -> t option
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
(** Peer_id, i.e. persistent peer identifier *)
|
|
||||||
|
|
||||||
module Peer_id : Tezos_crypto.S.INTERNAL_HASH
|
|
||||||
with type t = Crypto_box.Public_key_hash.t
|
|
||||||
|
|
||||||
type addr = Ipaddr.V6.t
|
|
||||||
type port = int
|
|
||||||
|
|
||||||
val addr_encoding : addr Data_encoding.t
|
|
||||||
|
|
||||||
(** Point, i.e. socket address *)
|
|
||||||
|
|
||||||
module Point : sig
|
|
||||||
|
|
||||||
type t = addr * port
|
|
||||||
val compare : t -> t -> int
|
|
||||||
|
|
||||||
val pp : Format.formatter -> t -> unit
|
|
||||||
val pp_opt : Format.formatter -> t option -> unit
|
|
||||||
|
|
||||||
val of_string_exn : string -> t
|
|
||||||
val of_string : string -> (t, string) result
|
|
||||||
val to_string : t -> string
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
val is_local : t -> bool
|
|
||||||
val is_global : t -> bool
|
|
||||||
val parse_addr_port : string -> string * string
|
|
||||||
|
|
||||||
module Map : Map.S with type key = t
|
|
||||||
module Set : Set.S with type elt = t
|
|
||||||
module Table : Hashtbl.S with type key = t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
(** Point representing a reachable socket address *)
|
|
||||||
|
|
||||||
module Id_point : sig
|
|
||||||
type t = addr * port option
|
|
||||||
val compare : t -> t -> int
|
|
||||||
val equal : t -> t -> bool
|
|
||||||
val pp : Format.formatter -> t -> unit
|
|
||||||
val pp_opt : Format.formatter -> t option -> unit
|
|
||||||
val to_string : t -> string
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
val is_local : t -> bool
|
|
||||||
val is_global : t -> bool
|
|
||||||
val of_point : Point.t -> t
|
|
||||||
val to_point : t -> Point.t option
|
|
||||||
val to_point_exn : t -> Point.t
|
|
||||||
module Map : Map.S with type key = t
|
|
||||||
module Set : Set.S with type elt = t
|
|
||||||
module Table : Hashtbl.S with type key = t
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
(** Identity *)
|
|
||||||
|
|
||||||
module Identity : sig
|
|
||||||
type t = {
|
|
||||||
peer_id : Peer_id.t ;
|
|
||||||
public_key : Crypto_box.public_key ;
|
|
||||||
secret_key : Crypto_box.secret_key ;
|
|
||||||
proof_of_work_stamp : Crypto_box.nonce ;
|
|
||||||
}
|
|
||||||
(** Type of an identity, comprising a peer_id, a crypto keypair, and a
|
|
||||||
proof of work stamp with enough difficulty so that the network
|
|
||||||
accept this identity as genuine. *)
|
|
||||||
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
|
|
||||||
val generate : Crypto_box.target -> t
|
|
||||||
(** [generate target] is a freshly minted identity whose proof of
|
|
||||||
work stamp difficulty is at least equal to [target]. *)
|
|
||||||
|
|
||||||
val generate_with_animation :
|
|
||||||
Format.formatter -> Crypto_box.target -> t
|
|
||||||
(** [generate_with_animation ppf target] is a freshly minted identity
|
|
||||||
whose proof of work stamp difficulty is at least equal to [target]. *)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
(** Bandwidth usage statistics *)
|
|
||||||
|
|
||||||
module Stat : sig
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
total_sent : int64 ;
|
|
||||||
total_recv : int64 ;
|
|
||||||
current_inflow : int ;
|
|
||||||
current_outflow : int ;
|
|
||||||
}
|
|
||||||
|
|
||||||
val empty : t
|
|
||||||
val pp : Format.formatter -> t -> unit
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
end
|
|
||||||
|
|
||||||
(** Information about a connection *)
|
|
||||||
|
|
||||||
module Connection_info : sig
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
incoming : bool;
|
|
||||||
peer_id : Peer_id.t;
|
|
||||||
id_point : Id_point.t;
|
|
||||||
remote_socket_port : port;
|
|
||||||
versions : Version.t list ;
|
|
||||||
}
|
|
||||||
|
|
||||||
val pp : Format.formatter -> t -> unit
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
(** Pool-level events *)
|
|
||||||
|
|
||||||
module Connection_pool_log_event : sig
|
|
||||||
|
|
||||||
type t =
|
|
||||||
|
|
||||||
| Too_few_connections
|
|
||||||
| Too_many_connections
|
|
||||||
|
|
||||||
| New_point of Point.t
|
|
||||||
| New_peer of Peer_id.t
|
|
||||||
|
|
||||||
| Gc_points
|
|
||||||
(** Garbage collection of known point table has been triggered. *)
|
|
||||||
|
|
||||||
| Gc_peer_ids
|
|
||||||
(** Garbage collection of known peer_ids table has been triggered. *)
|
|
||||||
|
|
||||||
(* Connection-level events *)
|
|
||||||
|
|
||||||
| Incoming_connection of Point.t
|
|
||||||
(** We accept(2)-ed an incoming connection *)
|
|
||||||
| Outgoing_connection of Point.t
|
|
||||||
(** We connect(2)-ed to a remote endpoint *)
|
|
||||||
| Authentication_failed of Point.t
|
|
||||||
(** Remote point failed authentication *)
|
|
||||||
|
|
||||||
| Accepting_request of Point.t * Id_point.t * Peer_id.t
|
|
||||||
(** We accepted a connection after authentifying the remote peer. *)
|
|
||||||
| Rejecting_request of Point.t * Id_point.t * Peer_id.t
|
|
||||||
(** We rejected a connection after authentifying the remote peer. *)
|
|
||||||
| Request_rejected of Point.t * (Id_point.t * Peer_id.t) option
|
|
||||||
(** The remote peer rejected our connection. *)
|
|
||||||
|
|
||||||
| Connection_established of Id_point.t * Peer_id.t
|
|
||||||
(** We succesfully established a authentified connection. *)
|
|
||||||
|
|
||||||
| Swap_request_received of { source : Peer_id.t }
|
|
||||||
(** A swap request has been received. *)
|
|
||||||
| Swap_ack_received of { source : Peer_id.t }
|
|
||||||
(** A swap ack has been received *)
|
|
||||||
| Swap_request_sent of { source : Peer_id.t }
|
|
||||||
(** A swap request has been sent *)
|
|
||||||
| Swap_ack_sent of { source : Peer_id.t }
|
|
||||||
(** A swap ack has been sent *)
|
|
||||||
| Swap_request_ignored of { source : Peer_id.t }
|
|
||||||
(** A swap request has been ignored *)
|
|
||||||
| Swap_success of { source : Peer_id.t }
|
|
||||||
(** A swap operation has succeeded *)
|
|
||||||
| Swap_failure of { source : Peer_id.t }
|
|
||||||
(** A swap operation has failed *)
|
|
||||||
|
|
||||||
| Disconnection of Peer_id.t
|
|
||||||
(** We decided to close the connection. *)
|
|
||||||
| External_disconnection of Peer_id.t
|
|
||||||
(** The connection was closed for external reason. *)
|
|
||||||
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Point_state : sig
|
|
||||||
|
|
||||||
type t =
|
|
||||||
| Requested
|
|
||||||
| Accepted of Peer_id.t
|
|
||||||
| Running of Peer_id.t
|
|
||||||
| Disconnected
|
|
||||||
|
|
||||||
val pp_digram : Format.formatter -> t -> unit
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Point_info : sig
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
trusted : bool ;
|
|
||||||
greylisted_until : Time.t ;
|
|
||||||
state : Point_state.t ;
|
|
||||||
last_failed_connection : Time.t option ;
|
|
||||||
last_rejected_connection : (Peer_id.t * Time.t) option ;
|
|
||||||
last_established_connection : (Peer_id.t * Time.t) option ;
|
|
||||||
last_disconnection : (Peer_id.t * Time.t) option ;
|
|
||||||
last_seen : (Peer_id.t * Time.t) option ;
|
|
||||||
last_miss : Time.t option ;
|
|
||||||
}
|
|
||||||
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Peer_state : sig
|
|
||||||
|
|
||||||
type t =
|
|
||||||
| Accepted
|
|
||||||
| Running
|
|
||||||
| Disconnected
|
|
||||||
|
|
||||||
val pp_digram : Format.formatter -> t -> unit
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Peer_info : sig
|
|
||||||
|
|
||||||
type t = {
|
|
||||||
score : float ;
|
|
||||||
trusted : bool ;
|
|
||||||
state : Peer_state.t ;
|
|
||||||
id_point : Id_point.t option ;
|
|
||||||
stat : Stat.t ;
|
|
||||||
last_failed_connection : (Id_point.t * Time.t) option ;
|
|
||||||
last_rejected_connection : (Id_point.t * Time.t) option ;
|
|
||||||
last_established_connection : (Id_point.t * Time.t) option ;
|
|
||||||
last_disconnection : (Id_point.t * Time.t) option ;
|
|
||||||
last_seen : (Id_point.t * Time.t) option ;
|
|
||||||
last_miss : (Id_point.t * Time.t) option ;
|
|
||||||
}
|
|
||||||
val encoding : t Data_encoding.t
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
@ -40,7 +40,7 @@ module Request = struct
|
|||||||
net_db: Distributed_db.net_db ;
|
net_db: Distributed_db.net_db ;
|
||||||
notify_new_block: State.Block.t -> unit ;
|
notify_new_block: State.Block.t -> unit ;
|
||||||
canceler: Lwt_canceler.t option ;
|
canceler: Lwt_canceler.t option ;
|
||||||
peer: P2p.Peer_id.t option ;
|
peer: P2p_peer.Id.t option ;
|
||||||
hash: Block_hash.t ;
|
hash: Block_hash.t ;
|
||||||
header: Block_header.t ;
|
header: Block_header.t ;
|
||||||
operations: Operation.t list list ;
|
operations: Operation.t list list ;
|
||||||
|
@ -22,7 +22,7 @@ val create:
|
|||||||
val validate:
|
val validate:
|
||||||
t ->
|
t ->
|
||||||
?canceler:Lwt_canceler.t ->
|
?canceler:Lwt_canceler.t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?notify_new_block:(State.Block.t -> unit) ->
|
?notify_new_block:(State.Block.t -> unit) ->
|
||||||
Distributed_db.net_db ->
|
Distributed_db.net_db ->
|
||||||
Block_hash.t -> Block_header.t -> Operation.t list list ->
|
Block_hash.t -> Block_header.t -> Operation.t list list ->
|
||||||
@ -30,7 +30,7 @@ val validate:
|
|||||||
|
|
||||||
val fetch_and_compile_protocol:
|
val fetch_and_compile_protocol:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
Protocol_hash.t -> State.Registred_protocol.t tzresult Lwt.t
|
Protocol_hash.t -> State.Registred_protocol.t tzresult Lwt.t
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
include Logging.Make(struct let name = "node.validator.bootstrap_pipeline" end)
|
include Logging.Make(struct let name = "node.validator.bootstrap_pipeline" end)
|
||||||
|
|
||||||
type error += Invalid_locator of P2p.Peer_id.t * Block_locator.t
|
type error += Invalid_locator of P2p_peer.Id.t * Block_locator.t
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
canceler: Lwt_canceler.t ;
|
canceler: Lwt_canceler.t ;
|
||||||
@ -18,7 +18,7 @@ type t = {
|
|||||||
mutable headers_fetch_worker: unit Lwt.t ;
|
mutable headers_fetch_worker: unit Lwt.t ;
|
||||||
mutable operations_fetch_worker: unit Lwt.t ;
|
mutable operations_fetch_worker: unit Lwt.t ;
|
||||||
mutable validation_worker: unit Lwt.t ;
|
mutable validation_worker: unit Lwt.t ;
|
||||||
peer_id: P2p.Peer_id.t ;
|
peer_id: P2p_peer.Id.t ;
|
||||||
net_db: Distributed_db.net_db ;
|
net_db: Distributed_db.net_db ;
|
||||||
locator: Block_locator.t ;
|
locator: Block_locator.t ;
|
||||||
block_validator: Block_validator.t ;
|
block_validator: Block_validator.t ;
|
||||||
@ -37,24 +37,24 @@ let fetch_step pipeline (step : Block_locator_iterator.step) =
|
|||||||
Block_hash.pp_short step.predecessor
|
Block_hash.pp_short step.predecessor
|
||||||
step.step
|
step.step
|
||||||
(if step.strict_step then "" else " max")
|
(if step.strict_step then "" else " max")
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
let rec fetch_loop acc hash cpt =
|
let rec fetch_loop acc hash cpt =
|
||||||
Lwt_unix.yield () >>= fun () ->
|
Lwt_unix.yield () >>= fun () ->
|
||||||
if cpt < 0 then
|
if cpt < 0 then
|
||||||
lwt_log_info "invalid step from peer %a (too long)."
|
lwt_log_info "invalid step from peer %a (too long)."
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
fail (Invalid_locator (pipeline.peer_id, pipeline.locator))
|
fail (Invalid_locator (pipeline.peer_id, pipeline.locator))
|
||||||
else if Block_hash.equal hash step.predecessor then
|
else if Block_hash.equal hash step.predecessor then
|
||||||
if step.strict_step && cpt <> 0 then
|
if step.strict_step && cpt <> 0 then
|
||||||
lwt_log_info "invalid step from peer %a (too short)."
|
lwt_log_info "invalid step from peer %a (too short)."
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
fail (Invalid_locator (pipeline.peer_id, pipeline.locator))
|
fail (Invalid_locator (pipeline.peer_id, pipeline.locator))
|
||||||
else
|
else
|
||||||
return acc
|
return acc
|
||||||
else
|
else
|
||||||
lwt_debug "fetching block header %a from peer %a."
|
lwt_debug "fetching block header %a from peer %a."
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
Lwt_utils.protect ~canceler:pipeline.canceler begin fun () ->
|
Lwt_utils.protect ~canceler:pipeline.canceler begin fun () ->
|
||||||
Distributed_db.Block_header.fetch
|
Distributed_db.Block_header.fetch
|
||||||
~timeout:pipeline.block_header_timeout
|
~timeout:pipeline.block_header_timeout
|
||||||
@ -63,7 +63,7 @@ let fetch_step pipeline (step : Block_locator_iterator.step) =
|
|||||||
end >>=? fun header ->
|
end >>=? fun header ->
|
||||||
lwt_debug "fetched block header %a from peer %a."
|
lwt_debug "fetched block header %a from peer %a."
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
fetch_loop ((hash, header) :: acc) header.shell.predecessor (cpt - 1)
|
fetch_loop ((hash, header) :: acc) header.shell.predecessor (cpt - 1)
|
||||||
in
|
in
|
||||||
fetch_loop [] step.block step.step >>=? fun headers ->
|
fetch_loop [] step.block step.step >>=? fun headers ->
|
||||||
@ -84,7 +84,7 @@ let headers_fetch_worker_loop pipeline =
|
|||||||
end >>= function
|
end >>= function
|
||||||
| Ok () ->
|
| Ok () ->
|
||||||
lwt_log_info "fetched all step from peer %a."
|
lwt_log_info "fetched all step from peer %a."
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
Lwt_pipe.close pipeline.fetched_headers ;
|
Lwt_pipe.close pipeline.fetched_headers ;
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Error [Exn Lwt.Canceled | Lwt_utils.Canceled | Exn Lwt_pipe.Closed] ->
|
| Error [Exn Lwt.Canceled | Lwt_utils.Canceled | Exn Lwt_pipe.Closed] ->
|
||||||
@ -92,7 +92,7 @@ let headers_fetch_worker_loop pipeline =
|
|||||||
| Error [ Distributed_db.Block_header.Timeout bh ] ->
|
| Error [ Distributed_db.Block_header.Timeout bh ] ->
|
||||||
lwt_log_info "request for header %a from peer %a timed out."
|
lwt_log_info "request for header %a from peer %a timed out."
|
||||||
Block_hash.pp_short bh
|
Block_hash.pp_short bh
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
Lwt_canceler.cancel pipeline.canceler >>= fun () ->
|
Lwt_canceler.cancel pipeline.canceler >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Error err ->
|
| Error err ->
|
||||||
@ -110,7 +110,7 @@ let rec operations_fetch_worker_loop pipeline =
|
|||||||
end >>=? fun (hash, header) ->
|
end >>=? fun (hash, header) ->
|
||||||
lwt_log_info "fetching operations of block %a from peer %a."
|
lwt_log_info "fetching operations of block %a from peer %a."
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
map_p
|
map_p
|
||||||
(fun i ->
|
(fun i ->
|
||||||
Lwt_utils.protect ~canceler:pipeline.canceler begin fun () ->
|
Lwt_utils.protect ~canceler:pipeline.canceler begin fun () ->
|
||||||
@ -122,7 +122,7 @@ let rec operations_fetch_worker_loop pipeline =
|
|||||||
(0 -- (header.shell.validation_passes - 1)) >>=? fun operations ->
|
(0 -- (header.shell.validation_passes - 1)) >>=? fun operations ->
|
||||||
lwt_log_info "fetched operations of block %a from peer %a."
|
lwt_log_info "fetched operations of block %a from peer %a."
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
Lwt_utils.protect ~canceler:pipeline.canceler begin fun () ->
|
Lwt_utils.protect ~canceler:pipeline.canceler begin fun () ->
|
||||||
Lwt_pipe.push pipeline.fetched_blocks
|
Lwt_pipe.push pipeline.fetched_blocks
|
||||||
(hash, header, operations) >>= return
|
(hash, header, operations) >>= return
|
||||||
@ -136,7 +136,7 @@ let rec operations_fetch_worker_loop pipeline =
|
|||||||
| Error [ Distributed_db.Operations.Timeout (bh, n) ] ->
|
| Error [ Distributed_db.Operations.Timeout (bh, n) ] ->
|
||||||
lwt_log_info "request for operations %a:%d from peer %a timed out."
|
lwt_log_info "request for operations %a:%d from peer %a timed out."
|
||||||
Block_hash.pp_short bh n
|
Block_hash.pp_short bh n
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
Lwt_canceler.cancel pipeline.canceler >>= fun () ->
|
Lwt_canceler.cancel pipeline.canceler >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Error err ->
|
| Error err ->
|
||||||
@ -154,7 +154,7 @@ let rec validation_worker_loop pipeline =
|
|||||||
end >>=? fun (hash, header, operations) ->
|
end >>=? fun (hash, header, operations) ->
|
||||||
lwt_log_info "requesting validation for block %a from peer %a."
|
lwt_log_info "requesting validation for block %a from peer %a."
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
Lwt_utils.protect ~canceler:pipeline.canceler begin fun () ->
|
Lwt_utils.protect ~canceler:pipeline.canceler begin fun () ->
|
||||||
Block_validator.validate
|
Block_validator.validate
|
||||||
~canceler:pipeline.canceler
|
~canceler:pipeline.canceler
|
||||||
@ -164,7 +164,7 @@ let rec validation_worker_loop pipeline =
|
|||||||
end >>=? fun _block ->
|
end >>=? fun _block ->
|
||||||
lwt_log_info "validated block %a from peer %a."
|
lwt_log_info "validated block %a from peer %a."
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pipeline.peer_id >>= fun () ->
|
P2p_peer.Id.pp_short pipeline.peer_id >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
end >>= function
|
end >>= function
|
||||||
| Ok () -> validation_worker_loop pipeline
|
| Ok () -> validation_worker_loop pipeline
|
||||||
@ -214,19 +214,19 @@ let create
|
|||||||
pipeline.headers_fetch_worker <-
|
pipeline.headers_fetch_worker <-
|
||||||
Lwt_utils.worker
|
Lwt_utils.worker
|
||||||
(Format.asprintf "bootstrap_pipeline-headers_fetch.%a.%a"
|
(Format.asprintf "bootstrap_pipeline-headers_fetch.%a.%a"
|
||||||
P2p.Peer_id.pp_short peer_id Block_hash.pp_short hash)
|
P2p_peer.Id.pp_short peer_id Block_hash.pp_short hash)
|
||||||
~run:(fun () -> headers_fetch_worker_loop pipeline)
|
~run:(fun () -> headers_fetch_worker_loop pipeline)
|
||||||
~cancel:(fun () -> Lwt_canceler.cancel pipeline.canceler) ;
|
~cancel:(fun () -> Lwt_canceler.cancel pipeline.canceler) ;
|
||||||
pipeline.operations_fetch_worker <-
|
pipeline.operations_fetch_worker <-
|
||||||
Lwt_utils.worker
|
Lwt_utils.worker
|
||||||
(Format.asprintf "bootstrap_pipeline-operations_fetch.%a.%a"
|
(Format.asprintf "bootstrap_pipeline-operations_fetch.%a.%a"
|
||||||
P2p.Peer_id.pp_short peer_id Block_hash.pp_short hash)
|
P2p_peer.Id.pp_short peer_id Block_hash.pp_short hash)
|
||||||
~run:(fun () -> operations_fetch_worker_loop pipeline)
|
~run:(fun () -> operations_fetch_worker_loop pipeline)
|
||||||
~cancel:(fun () -> Lwt_canceler.cancel pipeline.canceler) ;
|
~cancel:(fun () -> Lwt_canceler.cancel pipeline.canceler) ;
|
||||||
pipeline.validation_worker <-
|
pipeline.validation_worker <-
|
||||||
Lwt_utils.worker
|
Lwt_utils.worker
|
||||||
(Format.asprintf "bootstrap_pipeline-validation.%a.%a"
|
(Format.asprintf "bootstrap_pipeline-validation.%a.%a"
|
||||||
P2p.Peer_id.pp_short peer_id Block_hash.pp_short hash)
|
P2p_peer.Id.pp_short peer_id Block_hash.pp_short hash)
|
||||||
~run:(fun () -> validation_worker_loop pipeline)
|
~run:(fun () -> validation_worker_loop pipeline)
|
||||||
~cancel:(fun () -> Lwt_canceler.cancel pipeline.canceler) ;
|
~cancel:(fun () -> Lwt_canceler.cancel pipeline.canceler) ;
|
||||||
pipeline
|
pipeline
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
|
|
||||||
type t
|
type t
|
||||||
|
|
||||||
type error += Invalid_locator of P2p.Peer_id.t * Block_locator.t
|
type error += Invalid_locator of P2p_peer.Id.t * Block_locator.t
|
||||||
|
|
||||||
val create:
|
val create:
|
||||||
?notify_new_block: (State.Block.t -> unit) ->
|
?notify_new_block: (State.Block.t -> unit) ->
|
||||||
block_header_timeout:float ->
|
block_header_timeout:float ->
|
||||||
block_operations_timeout: float ->
|
block_operations_timeout: float ->
|
||||||
Block_validator.t ->
|
Block_validator.t ->
|
||||||
P2p.Peer_id.t -> Distributed_db.net_db ->
|
P2p_peer.Id.t -> Distributed_db.net_db ->
|
||||||
Block_locator.t -> t
|
Block_locator.t -> t
|
||||||
|
|
||||||
val wait: t -> unit tzresult Lwt.t
|
val wait: t -> unit tzresult Lwt.t
|
||||||
|
@ -15,8 +15,8 @@ type connection = (Message.t, Metadata.t) P2p.connection
|
|||||||
|
|
||||||
type 'a request_param = {
|
type 'a request_param = {
|
||||||
data: 'a ;
|
data: 'a ;
|
||||||
active: unit -> P2p.Peer_id.Set.t ;
|
active: unit -> P2p_peer.Set.t ;
|
||||||
send: P2p.Peer_id.t -> Message.t -> unit ;
|
send: P2p_peer.Id.t -> Message.t -> unit ;
|
||||||
}
|
}
|
||||||
|
|
||||||
module Make_raw
|
module Make_raw
|
||||||
@ -292,15 +292,15 @@ module Raw_protocol =
|
|||||||
|
|
||||||
type callback = {
|
type callback = {
|
||||||
notify_branch:
|
notify_branch:
|
||||||
P2p.Peer_id.t -> Block_locator.t -> unit ;
|
P2p_peer.Id.t -> Block_locator.t -> unit ;
|
||||||
notify_head:
|
notify_head:
|
||||||
P2p.Peer_id.t -> Block_header.t -> Mempool.t -> unit ;
|
P2p_peer.Id.t -> Block_header.t -> Mempool.t -> unit ;
|
||||||
disconnection: P2p.Peer_id.t -> unit ;
|
disconnection: P2p_peer.Id.t -> unit ;
|
||||||
}
|
}
|
||||||
|
|
||||||
type db = {
|
type db = {
|
||||||
p2p: p2p ;
|
p2p: p2p ;
|
||||||
p2p_readers: p2p_reader P2p.Peer_id.Table.t ;
|
p2p_readers: p2p_reader P2p_peer.Table.t ;
|
||||||
disk: State.t ;
|
disk: State.t ;
|
||||||
active_nets: net_db Net_id.Table.t ;
|
active_nets: net_db Net_id.Table.t ;
|
||||||
protocol_db: Raw_protocol.t ;
|
protocol_db: Raw_protocol.t ;
|
||||||
@ -316,12 +316,12 @@ and net_db = {
|
|||||||
operation_hashes_db: Raw_operation_hashes.t ;
|
operation_hashes_db: Raw_operation_hashes.t ;
|
||||||
operations_db: Raw_operations.t ;
|
operations_db: Raw_operations.t ;
|
||||||
mutable callback: callback ;
|
mutable callback: callback ;
|
||||||
active_peers: P2p.Peer_id.Set.t ref ;
|
active_peers: P2p_peer.Set.t ref ;
|
||||||
active_connections: p2p_reader P2p.Peer_id.Table.t ;
|
active_connections: p2p_reader P2p_peer.Table.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
and p2p_reader = {
|
and p2p_reader = {
|
||||||
gid: P2p.Peer_id.t ;
|
gid: P2p_peer.Id.t ;
|
||||||
conn: connection ;
|
conn: connection ;
|
||||||
peer_active_nets: net_db Net_id.Table.t ;
|
peer_active_nets: net_db Net_id.Table.t ;
|
||||||
canceler: Lwt_canceler.t ;
|
canceler: Lwt_canceler.t ;
|
||||||
@ -418,8 +418,8 @@ module P2p_reader = struct
|
|||||||
match Net_id.Table.find global_db.active_nets net_id with
|
match Net_id.Table.find global_db.active_nets net_id with
|
||||||
| net_db ->
|
| net_db ->
|
||||||
net_db.active_peers :=
|
net_db.active_peers :=
|
||||||
P2p.Peer_id.Set.add state.gid !(net_db.active_peers) ;
|
P2p_peer.Set.add state.gid !(net_db.active_peers) ;
|
||||||
P2p.Peer_id.Table.add net_db.active_connections
|
P2p_peer.Table.add net_db.active_connections
|
||||||
state.gid state ;
|
state.gid state ;
|
||||||
Net_id.Table.add state.peer_active_nets net_id net_db ;
|
Net_id.Table.add state.peer_active_nets net_id net_db ;
|
||||||
f net_db
|
f net_db
|
||||||
@ -430,8 +430,8 @@ module P2p_reader = struct
|
|||||||
let deactivate state net_db =
|
let deactivate state net_db =
|
||||||
net_db.callback.disconnection state.gid ;
|
net_db.callback.disconnection state.gid ;
|
||||||
net_db.active_peers :=
|
net_db.active_peers :=
|
||||||
P2p.Peer_id.Set.remove state.gid !(net_db.active_peers) ;
|
P2p_peer.Set.remove state.gid !(net_db.active_peers) ;
|
||||||
P2p.Peer_id.Table.remove net_db.active_connections state.gid
|
P2p_peer.Table.remove net_db.active_connections state.gid
|
||||||
|
|
||||||
let may_handle state net_id f =
|
let may_handle state net_id f =
|
||||||
match Net_id.Table.find state.peer_active_nets net_id with
|
match Net_id.Table.find state.peer_active_nets net_id with
|
||||||
@ -456,7 +456,7 @@ module P2p_reader = struct
|
|||||||
let open Logging in
|
let open Logging in
|
||||||
|
|
||||||
lwt_debug "Read message from %a: %a"
|
lwt_debug "Read message from %a: %a"
|
||||||
P2p.Peer_id.pp_short state.gid Message.pp_json msg >>= fun () ->
|
P2p_peer.Id.pp_short state.gid Message.pp_json msg >>= fun () ->
|
||||||
|
|
||||||
match msg with
|
match msg with
|
||||||
|
|
||||||
@ -639,7 +639,7 @@ module P2p_reader = struct
|
|||||||
Net_id.Table.iter
|
Net_id.Table.iter
|
||||||
(fun _ -> deactivate state)
|
(fun _ -> deactivate state)
|
||||||
state.peer_active_nets ;
|
state.peer_active_nets ;
|
||||||
P2p.Peer_id.Table.remove global_db.p2p_readers state.gid ;
|
P2p_peer.Table.remove global_db.p2p_readers state.gid ;
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
|
|
||||||
let run db gid conn =
|
let run db gid conn =
|
||||||
@ -657,10 +657,10 @@ module P2p_reader = struct
|
|||||||
state.worker <-
|
state.worker <-
|
||||||
Lwt_utils.worker
|
Lwt_utils.worker
|
||||||
(Format.asprintf "db_network_reader.%a"
|
(Format.asprintf "db_network_reader.%a"
|
||||||
P2p.Peer_id.pp_short gid)
|
P2p_peer.Id.pp_short gid)
|
||||||
~run:(fun () -> worker_loop db state)
|
~run:(fun () -> worker_loop db state)
|
||||||
~cancel:(fun () -> Lwt_canceler.cancel canceler) ;
|
~cancel:(fun () -> Lwt_canceler.cancel canceler) ;
|
||||||
P2p.Peer_id.Table.add db.p2p_readers gid state
|
P2p_peer.Table.add db.p2p_readers gid state
|
||||||
|
|
||||||
let shutdown s =
|
let shutdown s =
|
||||||
Lwt_canceler.cancel s.canceler >>= fun () ->
|
Lwt_canceler.cancel s.canceler >>= fun () ->
|
||||||
@ -671,9 +671,9 @@ end
|
|||||||
let active_peer_ids p2p () =
|
let active_peer_ids p2p () =
|
||||||
List.fold_left
|
List.fold_left
|
||||||
(fun acc conn ->
|
(fun acc conn ->
|
||||||
let { P2p.Connection_info.peer_id } = P2p.connection_info p2p conn in
|
let { P2p_connection.Info.peer_id } = P2p.connection_info p2p conn in
|
||||||
P2p.Peer_id.Set.add peer_id acc)
|
P2p_peer.Set.add peer_id acc)
|
||||||
P2p.Peer_id.Set.empty
|
P2p_peer.Set.empty
|
||||||
(P2p.connections p2p)
|
(P2p.connections p2p)
|
||||||
|
|
||||||
let raw_try_send p2p peer_id msg =
|
let raw_try_send p2p peer_id msg =
|
||||||
@ -689,7 +689,7 @@ let create disk p2p =
|
|||||||
} in
|
} in
|
||||||
let protocol_db = Raw_protocol.create global_request disk in
|
let protocol_db = Raw_protocol.create global_request disk in
|
||||||
let active_nets = Net_id.Table.create 17 in
|
let active_nets = Net_id.Table.create 17 in
|
||||||
let p2p_readers = P2p.Peer_id.Table.create 17 in
|
let p2p_readers = P2p_peer.Table.create 17 in
|
||||||
let block_input = Lwt_watcher.create_input () in
|
let block_input = Lwt_watcher.create_input () in
|
||||||
let operation_input = Lwt_watcher.create_input () in
|
let operation_input = Lwt_watcher.create_input () in
|
||||||
let db =
|
let db =
|
||||||
@ -704,7 +704,7 @@ let activate ({ p2p ; active_nets } as global_db) net_state =
|
|||||||
let net_id = State.Net.id net_state in
|
let net_id = State.Net.id net_state in
|
||||||
match Net_id.Table.find active_nets net_id with
|
match Net_id.Table.find active_nets net_id with
|
||||||
| exception Not_found ->
|
| exception Not_found ->
|
||||||
let active_peers = ref P2p.Peer_id.Set.empty in
|
let active_peers = ref P2p_peer.Set.empty in
|
||||||
let p2p_request =
|
let p2p_request =
|
||||||
{ data = () ;
|
{ data = () ;
|
||||||
active = (fun () -> !active_peers) ;
|
active = (fun () -> !active_peers) ;
|
||||||
@ -724,7 +724,7 @@ let activate ({ p2p ; active_nets } as global_db) net_state =
|
|||||||
global_db ; operation_db ; block_header_db ;
|
global_db ; operation_db ; block_header_db ;
|
||||||
operation_hashes_db ; operations_db ;
|
operation_hashes_db ; operations_db ;
|
||||||
net_state ; callback = noop_callback ; active_peers ;
|
net_state ; callback = noop_callback ; active_peers ;
|
||||||
active_connections = P2p.Peer_id.Table.create 53 ;
|
active_connections = P2p_peer.Table.create 53 ;
|
||||||
} in
|
} in
|
||||||
P2p.iter_connections p2p (fun _peer_id conn ->
|
P2p.iter_connections p2p (fun _peer_id conn ->
|
||||||
Lwt.async begin fun () ->
|
Lwt.async begin fun () ->
|
||||||
@ -742,7 +742,7 @@ let deactivate net_db =
|
|||||||
let { active_nets ; p2p } = net_db.global_db in
|
let { active_nets ; p2p } = net_db.global_db in
|
||||||
let net_id = State.Net.id net_db.net_state in
|
let net_id = State.Net.id net_db.net_state in
|
||||||
Net_id.Table.remove active_nets net_id ;
|
Net_id.Table.remove active_nets net_id ;
|
||||||
P2p.Peer_id.Table.iter
|
P2p_peer.Table.iter
|
||||||
(fun _peer_id reader ->
|
(fun _peer_id reader ->
|
||||||
P2p_reader.deactivate reader net_db ;
|
P2p_reader.deactivate reader net_db ;
|
||||||
Lwt.async begin fun () ->
|
Lwt.async begin fun () ->
|
||||||
@ -764,7 +764,7 @@ let disconnect { global_db = { p2p } } peer_id =
|
|||||||
| Some conn -> P2p.disconnect p2p conn
|
| Some conn -> P2p.disconnect p2p conn
|
||||||
|
|
||||||
let shutdown { p2p ; p2p_readers ; active_nets } =
|
let shutdown { p2p ; p2p_readers ; active_nets } =
|
||||||
P2p.Peer_id.Table.fold
|
P2p_peer.Table.fold
|
||||||
(fun _peer_id reader acc ->
|
(fun _peer_id reader acc ->
|
||||||
P2p_reader.shutdown reader >>= fun () -> acc)
|
P2p_reader.shutdown reader >>= fun () -> acc)
|
||||||
p2p_readers
|
p2p_readers
|
||||||
@ -829,12 +829,12 @@ module type DISTRIBUTED_DB = sig
|
|||||||
type error += Timeout of key
|
type error += Timeout of key
|
||||||
val fetch:
|
val fetch:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
key -> param -> value tzresult Lwt.t
|
key -> param -> value tzresult Lwt.t
|
||||||
val prefetch:
|
val prefetch:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
key -> param -> unit
|
key -> param -> unit
|
||||||
type error += Canceled of key
|
type error += Canceled of key
|
||||||
@ -913,14 +913,14 @@ end
|
|||||||
|
|
||||||
|
|
||||||
let broadcast net_db msg =
|
let broadcast net_db msg =
|
||||||
P2p.Peer_id.Table.iter
|
P2p_peer.Table.iter
|
||||||
(fun _peer_id state ->
|
(fun _peer_id state ->
|
||||||
ignore (P2p.try_send net_db.global_db.p2p state.conn msg))
|
ignore (P2p.try_send net_db.global_db.p2p state.conn msg))
|
||||||
net_db.active_connections
|
net_db.active_connections
|
||||||
|
|
||||||
let try_send net_db peer_id msg =
|
let try_send net_db peer_id msg =
|
||||||
try
|
try
|
||||||
let conn = P2p.Peer_id.Table.find net_db.active_connections peer_id in
|
let conn = P2p_peer.Table.find net_db.active_connections peer_id in
|
||||||
ignore (P2p.try_send net_db.global_db.p2p conn.conn msg : bool)
|
ignore (P2p.try_send net_db.global_db.p2p conn.conn msg : bool)
|
||||||
with Not_found -> ()
|
with Not_found -> ()
|
||||||
|
|
||||||
|
@ -40,9 +40,9 @@ val get_net: t -> Net_id.t -> net_db option
|
|||||||
val deactivate: net_db -> unit Lwt.t
|
val deactivate: net_db -> unit Lwt.t
|
||||||
|
|
||||||
type callback = {
|
type callback = {
|
||||||
notify_branch: P2p.Peer_id.t -> Block_locator.t -> unit ;
|
notify_branch: P2p_peer.Id.t -> Block_locator.t -> unit ;
|
||||||
notify_head: P2p.Peer_id.t -> Block_header.t -> Mempool.t -> unit ;
|
notify_head: P2p_peer.Id.t -> Block_header.t -> Mempool.t -> unit ;
|
||||||
disconnection: P2p.Peer_id.t -> unit ;
|
disconnection: P2p_peer.Id.t -> unit ;
|
||||||
}
|
}
|
||||||
|
|
||||||
(** Register all the possible callback from the distributed DB to the
|
(** Register all the possible callback from the distributed DB to the
|
||||||
@ -50,7 +50,7 @@ type callback = {
|
|||||||
val set_callback: net_db -> callback -> unit
|
val set_callback: net_db -> callback -> unit
|
||||||
|
|
||||||
(** Kick a given peer. *)
|
(** Kick a given peer. *)
|
||||||
val disconnect: net_db -> P2p.Peer_id.t -> unit Lwt.t
|
val disconnect: net_db -> P2p_peer.Id.t -> unit Lwt.t
|
||||||
|
|
||||||
(** Various accessors. *)
|
(** Various accessors. *)
|
||||||
val net_state: net_db -> State.Net.t
|
val net_state: net_db -> State.Net.t
|
||||||
@ -63,12 +63,12 @@ module Request : sig
|
|||||||
(** Send to a given peer, or to all known active peers for the
|
(** Send to a given peer, or to all known active peers for the
|
||||||
network, a friendly request "Hey, what's your current branch
|
network, a friendly request "Hey, what's your current branch
|
||||||
?". The expected answer is a `Block_locator.t.`. *)
|
?". The expected answer is a `Block_locator.t.`. *)
|
||||||
val current_branch: net_db -> ?peer:P2p.Peer_id.t -> unit -> unit
|
val current_branch: net_db -> ?peer:P2p_peer.Id.t -> unit -> unit
|
||||||
|
|
||||||
(** Send to a given peer, or to all known active peers for the
|
(** Send to a given peer, or to all known active peers for the
|
||||||
given network, a friendly request "Hey, what's your current
|
given network, a friendly request "Hey, what's your current
|
||||||
branch ?". The expected answer is a `Block_locator.t.`. *)
|
branch ?". The expected answer is a `Block_locator.t.`. *)
|
||||||
val current_head: net_db -> ?peer:P2p.Peer_id.t -> unit -> unit
|
val current_head: net_db -> ?peer:P2p_peer.Id.t -> unit -> unit
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -77,13 +77,13 @@ module Advertise : sig
|
|||||||
(** Notify a given peer, or all known active peers for the
|
(** Notify a given peer, or all known active peers for the
|
||||||
network, of a new head and possibly of new operations. *)
|
network, of a new head and possibly of new operations. *)
|
||||||
val current_head:
|
val current_head:
|
||||||
net_db -> ?peer:P2p.Peer_id.t ->
|
net_db -> ?peer:P2p_peer.Id.t ->
|
||||||
?mempool:Mempool.t -> State.Block.t -> unit
|
?mempool:Mempool.t -> State.Block.t -> unit
|
||||||
|
|
||||||
(** Notify a given peer, or all known active peers for the
|
(** Notify a given peer, or all known active peers for the
|
||||||
network, of a new head and its sparse history. *)
|
network, of a new head and its sparse history. *)
|
||||||
val current_branch:
|
val current_branch:
|
||||||
net_db -> ?peer:P2p.Peer_id.t ->
|
net_db -> ?peer:P2p_peer.Id.t ->
|
||||||
Block_locator.t -> unit Lwt.t
|
Block_locator.t -> unit Lwt.t
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -145,7 +145,7 @@ module type DISTRIBUTED_DB = sig
|
|||||||
peer (at each retry). *)
|
peer (at each retry). *)
|
||||||
val fetch:
|
val fetch:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
key -> param -> value tzresult Lwt.t
|
key -> param -> value tzresult Lwt.t
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ module type DISTRIBUTED_DB = sig
|
|||||||
stored in the local index when received. *)
|
stored in the local index when received. *)
|
||||||
val prefetch:
|
val prefetch:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
key -> param -> unit
|
key -> param -> unit
|
||||||
|
|
||||||
@ -257,6 +257,6 @@ val commit_protocol:
|
|||||||
|
|
||||||
module Raw : sig
|
module Raw : sig
|
||||||
val encoding: Message.t P2p.Raw.t Data_encoding.t
|
val encoding: Message.t P2p.Raw.t Data_encoding.t
|
||||||
val supported_versions: P2p_types.Version.t list
|
val supported_versions: P2p_version.t list
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,13 +26,13 @@ module type DISTRIBUTED_DB = sig
|
|||||||
|
|
||||||
val prefetch:
|
val prefetch:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
key -> param -> unit
|
key -> param -> unit
|
||||||
|
|
||||||
val fetch:
|
val fetch:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
key -> param -> value tzresult Lwt.t
|
key -> param -> value tzresult Lwt.t
|
||||||
|
|
||||||
@ -68,12 +68,12 @@ end
|
|||||||
module type SCHEDULER_EVENTS = sig
|
module type SCHEDULER_EVENTS = sig
|
||||||
type t
|
type t
|
||||||
type key
|
type key
|
||||||
val request: t -> P2p.Peer_id.t option -> key -> unit
|
val request: t -> P2p_peer.Id.t option -> key -> unit
|
||||||
val notify: t -> P2p.Peer_id.t -> key -> unit
|
val notify: t -> P2p_peer.Id.t -> key -> unit
|
||||||
val notify_cancelation: t -> key -> unit
|
val notify_cancelation: t -> key -> unit
|
||||||
val notify_unrequested: t -> P2p.Peer_id.t -> key -> unit
|
val notify_unrequested: t -> P2p_peer.Id.t -> key -> unit
|
||||||
val notify_duplicate: t -> P2p.Peer_id.t -> key -> unit
|
val notify_duplicate: t -> P2p_peer.Id.t -> key -> unit
|
||||||
val notify_invalid: t -> P2p.Peer_id.t -> key -> unit
|
val notify_invalid: t -> P2p_peer.Id.t -> key -> unit
|
||||||
end
|
end
|
||||||
|
|
||||||
module type PRECHECK = sig
|
module type PRECHECK = sig
|
||||||
@ -103,7 +103,7 @@ module Make_table
|
|||||||
val create:
|
val create:
|
||||||
?global_input:(key * value) Lwt_watcher.input ->
|
?global_input:(key * value) Lwt_watcher.input ->
|
||||||
Scheduler.t -> Disk_table.store -> t
|
Scheduler.t -> Disk_table.store -> t
|
||||||
val notify: t -> P2p.Peer_id.t -> key -> Precheck.notified_value -> unit Lwt.t
|
val notify: t -> P2p_peer.Id.t -> key -> Precheck.notified_value -> unit Lwt.t
|
||||||
|
|
||||||
end = struct
|
end = struct
|
||||||
|
|
||||||
@ -306,8 +306,8 @@ end
|
|||||||
module type REQUEST = sig
|
module type REQUEST = sig
|
||||||
type key
|
type key
|
||||||
type param
|
type param
|
||||||
val active : param -> P2p.Peer_id.Set.t
|
val active : param -> P2p_peer.Set.t
|
||||||
val send : param -> P2p.Peer_id.t -> key list -> unit
|
val send : param -> P2p_peer.Id.t -> key list -> unit
|
||||||
end
|
end
|
||||||
|
|
||||||
module Make_request_scheduler
|
module Make_request_scheduler
|
||||||
@ -343,24 +343,24 @@ end = struct
|
|||||||
}
|
}
|
||||||
|
|
||||||
and status = {
|
and status = {
|
||||||
peers: P2p.Peer_id.Set.t ;
|
peers: P2p_peer.Set.t ;
|
||||||
next_request: float ;
|
next_request: float ;
|
||||||
delay: float ;
|
delay: float ;
|
||||||
}
|
}
|
||||||
|
|
||||||
and event =
|
and event =
|
||||||
| Request of P2p.Peer_id.t option * key
|
| Request of P2p_peer.Id.t option * key
|
||||||
| Notify of P2p.Peer_id.t * key
|
| Notify of P2p_peer.Id.t * key
|
||||||
| Notify_cancelation of key
|
| Notify_cancelation of key
|
||||||
| Notify_invalid of P2p.Peer_id.t * key
|
| Notify_invalid of P2p_peer.Id.t * key
|
||||||
| Notify_duplicate of P2p.Peer_id.t * key
|
| Notify_duplicate of P2p_peer.Id.t * key
|
||||||
| Notify_unrequested of P2p.Peer_id.t * key
|
| Notify_unrequested of P2p_peer.Id.t * key
|
||||||
|
|
||||||
let request t p k =
|
let request t p k =
|
||||||
assert (Lwt_pipe.push_now t.queue (Request (p, k)))
|
assert (Lwt_pipe.push_now t.queue (Request (p, k)))
|
||||||
let notify t p k =
|
let notify t p k =
|
||||||
debug "push received %a from %a"
|
debug "push received %a from %a"
|
||||||
Hash.pp k P2p.Peer_id.pp_short p ;
|
Hash.pp k P2p_peer.Id.pp_short p ;
|
||||||
assert (Lwt_pipe.push_now t.queue (Notify (p, k)))
|
assert (Lwt_pipe.push_now t.queue (Notify (p, k)))
|
||||||
let notify_cancelation t k =
|
let notify_cancelation t k =
|
||||||
debug "push cancelation %a"
|
debug "push cancelation %a"
|
||||||
@ -368,15 +368,15 @@ end = struct
|
|||||||
assert (Lwt_pipe.push_now t.queue (Notify_cancelation k))
|
assert (Lwt_pipe.push_now t.queue (Notify_cancelation k))
|
||||||
let notify_invalid t p k =
|
let notify_invalid t p k =
|
||||||
debug "push received invalid %a from %a"
|
debug "push received invalid %a from %a"
|
||||||
Hash.pp k P2p.Peer_id.pp_short p ;
|
Hash.pp k P2p_peer.Id.pp_short p ;
|
||||||
assert (Lwt_pipe.push_now t.queue (Notify_invalid (p, k)))
|
assert (Lwt_pipe.push_now t.queue (Notify_invalid (p, k)))
|
||||||
let notify_duplicate t p k =
|
let notify_duplicate t p k =
|
||||||
debug "push received duplicate %a from %a"
|
debug "push received duplicate %a from %a"
|
||||||
Hash.pp k P2p.Peer_id.pp_short p ;
|
Hash.pp k P2p_peer.Id.pp_short p ;
|
||||||
assert (Lwt_pipe.push_now t.queue (Notify_duplicate (p, k)))
|
assert (Lwt_pipe.push_now t.queue (Notify_duplicate (p, k)))
|
||||||
let notify_unrequested t p k =
|
let notify_unrequested t p k =
|
||||||
debug "push received unrequested %a from %a"
|
debug "push received unrequested %a from %a"
|
||||||
Hash.pp k P2p.Peer_id.pp_short p ;
|
Hash.pp k P2p_peer.Id.pp_short p ;
|
||||||
assert (Lwt_pipe.push_now t.queue (Notify_unrequested (p, k)))
|
assert (Lwt_pipe.push_now t.queue (Notify_unrequested (p, k)))
|
||||||
|
|
||||||
let compute_timeout state =
|
let compute_timeout state =
|
||||||
@ -399,7 +399,7 @@ end = struct
|
|||||||
|
|
||||||
let may_pp_peer ppf = function
|
let may_pp_peer ppf = function
|
||||||
| None -> ()
|
| None -> ()
|
||||||
| Some peer -> P2p.Peer_id.pp_short ppf peer
|
| Some peer -> P2p_peer.Id.pp_short ppf peer
|
||||||
|
|
||||||
(* TODO should depend on the ressource kind... *)
|
(* TODO should depend on the ressource kind... *)
|
||||||
let initial_delay = 0.1
|
let initial_delay = 0.1
|
||||||
@ -413,7 +413,7 @@ end = struct
|
|||||||
let peers =
|
let peers =
|
||||||
match peer with
|
match peer with
|
||||||
| None -> data.peers
|
| None -> data.peers
|
||||||
| Some peer -> P2p.Peer_id.Set.add peer data.peers in
|
| Some peer -> P2p_peer.Set.add peer data.peers in
|
||||||
Table.replace state.pending key {
|
Table.replace state.pending key {
|
||||||
delay = initial_delay ;
|
delay = initial_delay ;
|
||||||
next_request = min data.next_request (now +. initial_delay) ;
|
next_request = min data.next_request (now +. initial_delay) ;
|
||||||
@ -425,8 +425,8 @@ end = struct
|
|||||||
with Not_found ->
|
with Not_found ->
|
||||||
let peers =
|
let peers =
|
||||||
match peer with
|
match peer with
|
||||||
| None -> P2p.Peer_id.Set.empty
|
| None -> P2p_peer.Set.empty
|
||||||
| Some peer -> P2p.Peer_id.Set.singleton peer in
|
| Some peer -> P2p_peer.Set.singleton peer in
|
||||||
Table.add state.pending key {
|
Table.add state.pending key {
|
||||||
peers ;
|
peers ;
|
||||||
next_request = now ;
|
next_request = now ;
|
||||||
@ -439,7 +439,7 @@ end = struct
|
|||||||
| Notify (peer, key) ->
|
| Notify (peer, key) ->
|
||||||
Table.remove state.pending key ;
|
Table.remove state.pending key ;
|
||||||
lwt_debug "received %a from %a"
|
lwt_debug "received %a from %a"
|
||||||
Hash.pp key P2p.Peer_id.pp_short peer >>= fun () ->
|
Hash.pp key P2p_peer.Id.pp_short peer >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Notify_cancelation key ->
|
| Notify_cancelation key ->
|
||||||
Table.remove state.pending key ;
|
Table.remove state.pending key ;
|
||||||
@ -448,17 +448,17 @@ end = struct
|
|||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Notify_invalid (peer, key) ->
|
| Notify_invalid (peer, key) ->
|
||||||
lwt_debug "received invalid %a from %a"
|
lwt_debug "received invalid %a from %a"
|
||||||
Hash.pp key P2p.Peer_id.pp_short peer >>= fun () ->
|
Hash.pp key P2p_peer.Id.pp_short peer >>= fun () ->
|
||||||
(* TODO *)
|
(* TODO *)
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Notify_unrequested (peer, key) ->
|
| Notify_unrequested (peer, key) ->
|
||||||
lwt_debug "received unrequested %a from %a"
|
lwt_debug "received unrequested %a from %a"
|
||||||
Hash.pp key P2p.Peer_id.pp_short peer >>= fun () ->
|
Hash.pp key P2p_peer.Id.pp_short peer >>= fun () ->
|
||||||
(* TODO *)
|
(* TODO *)
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Notify_duplicate (peer, key) ->
|
| Notify_duplicate (peer, key) ->
|
||||||
lwt_debug "received duplicate %a from %a"
|
lwt_debug "received duplicate %a from %a"
|
||||||
Hash.pp key P2p.Peer_id.pp_short peer >>= fun () ->
|
Hash.pp key P2p_peer.Id.pp_short peer >>= fun () ->
|
||||||
(* TODO *)
|
(* TODO *)
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
|
|
||||||
@ -487,14 +487,14 @@ end = struct
|
|||||||
acc
|
acc
|
||||||
else
|
else
|
||||||
let remaining_peers =
|
let remaining_peers =
|
||||||
P2p.Peer_id.Set.inter peers active_peers in
|
P2p_peer.Set.inter peers active_peers in
|
||||||
if P2p.Peer_id.Set.is_empty remaining_peers &&
|
if P2p_peer.Set.is_empty remaining_peers &&
|
||||||
not (P2p.Peer_id.Set.is_empty peers) then
|
not (P2p_peer.Set.is_empty peers) then
|
||||||
( Table.remove state.pending key ; acc )
|
( Table.remove state.pending key ; acc )
|
||||||
else
|
else
|
||||||
let requested_peer =
|
let requested_peer =
|
||||||
P2p.Peer_id.random_set_elt
|
P2p_peer.Id.random_set_elt
|
||||||
(if P2p.Peer_id.Set.is_empty remaining_peers
|
(if P2p_peer.Set.is_empty remaining_peers
|
||||||
then active_peers
|
then active_peers
|
||||||
else remaining_peers) in
|
else remaining_peers) in
|
||||||
let next = { peers = remaining_peers ;
|
let next = { peers = remaining_peers ;
|
||||||
@ -502,16 +502,16 @@ end = struct
|
|||||||
delay = delay *. 1.2 } in
|
delay = delay *. 1.2 } in
|
||||||
Table.replace state.pending key next ;
|
Table.replace state.pending key next ;
|
||||||
let requests =
|
let requests =
|
||||||
try key :: P2p_types.Peer_id.Map.find requested_peer acc
|
try key :: P2p_peer.Map.find requested_peer acc
|
||||||
with Not_found -> [key] in
|
with Not_found -> [key] in
|
||||||
P2p_types.Peer_id.Map.add requested_peer requests acc)
|
P2p_peer.Map.add requested_peer requests acc)
|
||||||
state.pending P2p_types.Peer_id.Map.empty in
|
state.pending P2p_peer.Map.empty in
|
||||||
P2p_types.Peer_id.Map.iter (Request.send state.param) requests ;
|
P2p_peer.Map.iter (Request.send state.param) requests ;
|
||||||
P2p_types.Peer_id.Map.fold begin fun peer request acc ->
|
P2p_peer.Map.fold begin fun peer request acc ->
|
||||||
acc >>= fun () ->
|
acc >>= fun () ->
|
||||||
Lwt_list.iter_s (fun key ->
|
Lwt_list.iter_s (fun key ->
|
||||||
lwt_debug "requested %a from %a"
|
lwt_debug "requested %a from %a"
|
||||||
Hash.pp key P2p.Peer_id.pp_short peer)
|
Hash.pp key P2p_peer.Id.pp_short peer)
|
||||||
request
|
request
|
||||||
end requests Lwt.return_unit >>= fun () ->
|
end requests Lwt.return_unit >>= fun () ->
|
||||||
worker_loop state
|
worker_loop state
|
||||||
|
@ -29,13 +29,13 @@ module type DISTRIBUTED_DB = sig
|
|||||||
|
|
||||||
val prefetch:
|
val prefetch:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
key -> param -> unit
|
key -> param -> unit
|
||||||
|
|
||||||
val fetch:
|
val fetch:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
key -> param -> value tzresult Lwt.t
|
key -> param -> value tzresult Lwt.t
|
||||||
|
|
||||||
@ -72,12 +72,12 @@ end
|
|||||||
module type SCHEDULER_EVENTS = sig
|
module type SCHEDULER_EVENTS = sig
|
||||||
type t
|
type t
|
||||||
type key
|
type key
|
||||||
val request: t -> P2p.Peer_id.t option -> key -> unit
|
val request: t -> P2p_peer.Id.t option -> key -> unit
|
||||||
val notify: t -> P2p.Peer_id.t -> key -> unit
|
val notify: t -> P2p_peer.Id.t -> key -> unit
|
||||||
val notify_cancelation: t -> key -> unit
|
val notify_cancelation: t -> key -> unit
|
||||||
val notify_unrequested: t -> P2p.Peer_id.t -> key -> unit
|
val notify_unrequested: t -> P2p_peer.Id.t -> key -> unit
|
||||||
val notify_duplicate: t -> P2p.Peer_id.t -> key -> unit
|
val notify_duplicate: t -> P2p_peer.Id.t -> key -> unit
|
||||||
val notify_invalid: t -> P2p.Peer_id.t -> key -> unit
|
val notify_invalid: t -> P2p_peer.Id.t -> key -> unit
|
||||||
end
|
end
|
||||||
|
|
||||||
module type PRECHECK = sig
|
module type PRECHECK = sig
|
||||||
@ -107,15 +107,15 @@ module Make_table
|
|||||||
val create:
|
val create:
|
||||||
?global_input:(key * value) Lwt_watcher.input ->
|
?global_input:(key * value) Lwt_watcher.input ->
|
||||||
Scheduler.t -> Disk_table.store -> t
|
Scheduler.t -> Disk_table.store -> t
|
||||||
val notify: t -> P2p.Peer_id.t -> key -> Precheck.notified_value -> unit Lwt.t
|
val notify: t -> P2p_peer.Id.t -> key -> Precheck.notified_value -> unit Lwt.t
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module type REQUEST = sig
|
module type REQUEST = sig
|
||||||
type key
|
type key
|
||||||
type param
|
type param
|
||||||
val active : param -> P2p.Peer_id.Set.t
|
val active : param -> P2p_peer.Set.t
|
||||||
val send : param -> P2p.Peer_id.t -> key list -> unit
|
val send : param -> P2p_peer.Id.t -> key list -> unit
|
||||||
end
|
end
|
||||||
|
|
||||||
module Make_request_scheduler
|
module Make_request_scheduler
|
||||||
|
@ -169,7 +169,7 @@ let encoding =
|
|||||||
]
|
]
|
||||||
|
|
||||||
let versions =
|
let versions =
|
||||||
let open P2p.Version in
|
let open P2p_version in
|
||||||
[ { name = "TEZOS" ;
|
[ { name = "TEZOS" ;
|
||||||
major = 0 ;
|
major = 0 ;
|
||||||
minor = 27 ;
|
minor = 27 ;
|
||||||
|
@ -57,17 +57,17 @@ module Types = struct
|
|||||||
mutable child:
|
mutable child:
|
||||||
(state * (unit -> unit Lwt.t (* shutdown *))) option ;
|
(state * (unit -> unit Lwt.t (* shutdown *))) option ;
|
||||||
prevalidator: Prevalidator.t ;
|
prevalidator: Prevalidator.t ;
|
||||||
active_peers: Peer_validator.t Lwt.t P2p.Peer_id.Table.t ;
|
active_peers: Peer_validator.t Lwt.t P2p_peer.Table.t ;
|
||||||
bootstrapped_peers: unit P2p.Peer_id.Table.t ;
|
bootstrapped_peers: unit P2p_peer.Table.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
let view (state : state) _ : view =
|
let view (state : state) _ : view =
|
||||||
let { bootstrapped ; active_peers ; bootstrapped_peers } = state in
|
let { bootstrapped ; active_peers ; bootstrapped_peers } = state in
|
||||||
{ bootstrapped ;
|
{ bootstrapped ;
|
||||||
active_peers =
|
active_peers =
|
||||||
P2p.Peer_id.Table.fold (fun id _ l -> id :: l) active_peers [] ;
|
P2p_peer.Table.fold (fun id _ l -> id :: l) active_peers [] ;
|
||||||
bootstrapped_peers =
|
bootstrapped_peers =
|
||||||
P2p.Peer_id.Table.fold (fun id _ l -> id :: l) bootstrapped_peers [] }
|
P2p_peer.Table.fold (fun id _ l -> id :: l) bootstrapped_peers [] }
|
||||||
end
|
end
|
||||||
|
|
||||||
module Worker = Worker.Make (Name) (Event) (Request) (Types)
|
module Worker = Worker.Make (Name) (Event) (Request) (Types)
|
||||||
@ -99,7 +99,7 @@ let notify_new_block w block =
|
|||||||
let may_toggle_bootstrapped_network w =
|
let may_toggle_bootstrapped_network w =
|
||||||
let nv = Worker.state w in
|
let nv = Worker.state w in
|
||||||
if not nv.bootstrapped &&
|
if not nv.bootstrapped &&
|
||||||
P2p.Peer_id.Table.length nv.bootstrapped_peers >= nv.parameters.limits.bootstrap_threshold
|
P2p_peer.Table.length nv.bootstrapped_peers >= nv.parameters.limits.bootstrap_threshold
|
||||||
then begin
|
then begin
|
||||||
nv.bootstrapped <- true ;
|
nv.bootstrapped <- true ;
|
||||||
Lwt.wakeup_later nv.bootstrapped_wakener () ;
|
Lwt.wakeup_later nv.bootstrapped_wakener () ;
|
||||||
@ -107,24 +107,24 @@ let may_toggle_bootstrapped_network w =
|
|||||||
|
|
||||||
let may_activate_peer_validator w peer_id =
|
let may_activate_peer_validator w peer_id =
|
||||||
let nv = Worker.state w in
|
let nv = Worker.state w in
|
||||||
try P2p.Peer_id.Table.find nv.active_peers peer_id
|
try P2p_peer.Table.find nv.active_peers peer_id
|
||||||
with Not_found ->
|
with Not_found ->
|
||||||
let pv =
|
let pv =
|
||||||
Peer_validator.create
|
Peer_validator.create
|
||||||
~notify_new_block:(notify_new_block w)
|
~notify_new_block:(notify_new_block w)
|
||||||
~notify_bootstrapped: begin fun () ->
|
~notify_bootstrapped: begin fun () ->
|
||||||
P2p.Peer_id.Table.add nv.bootstrapped_peers peer_id () ;
|
P2p_peer.Table.add nv.bootstrapped_peers peer_id () ;
|
||||||
may_toggle_bootstrapped_network w
|
may_toggle_bootstrapped_network w
|
||||||
end
|
end
|
||||||
~notify_termination: begin fun _pv ->
|
~notify_termination: begin fun _pv ->
|
||||||
P2p.Peer_id.Table.remove nv.active_peers peer_id ;
|
P2p_peer.Table.remove nv.active_peers peer_id ;
|
||||||
P2p.Peer_id.Table.remove nv.bootstrapped_peers peer_id ;
|
P2p_peer.Table.remove nv.bootstrapped_peers peer_id ;
|
||||||
end
|
end
|
||||||
nv.parameters.peer_validator_limits
|
nv.parameters.peer_validator_limits
|
||||||
nv.parameters.block_validator
|
nv.parameters.block_validator
|
||||||
nv.parameters.net_db
|
nv.parameters.net_db
|
||||||
peer_id in
|
peer_id in
|
||||||
P2p.Peer_id.Table.add nv.active_peers peer_id pv ;
|
P2p_peer.Table.add nv.active_peers peer_id pv ;
|
||||||
pv
|
pv
|
||||||
|
|
||||||
let may_switch_test_network w spawn_child block =
|
let may_switch_test_network w spawn_child block =
|
||||||
@ -260,7 +260,7 @@ let on_close w =
|
|||||||
Lwt.join
|
Lwt.join
|
||||||
(Prevalidator.shutdown nv.prevalidator ::
|
(Prevalidator.shutdown nv.prevalidator ::
|
||||||
Lwt_utils.may ~f:(fun (_, shutdown) -> shutdown ()) nv.child ::
|
Lwt_utils.may ~f:(fun (_, shutdown) -> shutdown ()) nv.child ::
|
||||||
P2p.Peer_id.Table.fold
|
P2p_peer.Table.fold
|
||||||
(fun _ pv acc -> (pv >>= Peer_validator.shutdown) :: acc)
|
(fun _ pv acc -> (pv >>= Peer_validator.shutdown) :: acc)
|
||||||
nv.active_peers []) >>= fun () ->
|
nv.active_peers []) >>= fun () ->
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
@ -280,9 +280,9 @@ let on_launch w _ parameters =
|
|||||||
bootstrapped_waiter ;
|
bootstrapped_waiter ;
|
||||||
bootstrapped = (parameters.limits.bootstrap_threshold <= 0) ;
|
bootstrapped = (parameters.limits.bootstrap_threshold <= 0) ;
|
||||||
active_peers =
|
active_peers =
|
||||||
P2p.Peer_id.Table.create 50 ; (* TODO use `2 * max_connection` *)
|
P2p_peer.Table.create 50 ; (* TODO use `2 * max_connection` *)
|
||||||
bootstrapped_peers =
|
bootstrapped_peers =
|
||||||
P2p.Peer_id.Table.create 50 ; (* TODO use `2 * max_connection` *)
|
P2p_peer.Table.create 50 ; (* TODO use `2 * max_connection` *)
|
||||||
child = None ;
|
child = None ;
|
||||||
prevalidator } in
|
prevalidator } in
|
||||||
if nv.bootstrapped then Lwt.wakeup_later bootstrapped_wakener () ;
|
if nv.bootstrapped then Lwt.wakeup_later bootstrapped_wakener () ;
|
||||||
|
@ -129,58 +129,56 @@ module RPC : sig
|
|||||||
|
|
||||||
module Network : sig
|
module Network : sig
|
||||||
|
|
||||||
open P2p_types
|
val stat : t -> P2p_stat.t
|
||||||
|
|
||||||
val stat : t -> Stat.t
|
|
||||||
|
|
||||||
val watch :
|
val watch :
|
||||||
t ->
|
t ->
|
||||||
P2p_types.Connection_pool_log_event.t Lwt_stream.t * Lwt_watcher.stopper
|
P2p_connection.Pool_event.t Lwt_stream.t * Lwt_watcher.stopper
|
||||||
val connect : t -> Point.t -> float -> unit tzresult Lwt.t
|
val connect : t -> P2p_point.Id.t -> float -> unit tzresult Lwt.t
|
||||||
|
|
||||||
module Connection : sig
|
module Connection : sig
|
||||||
val info : t -> Peer_id.t -> Connection_info.t option
|
val info : t -> P2p_peer.Id.t -> P2p_connection.Info.t option
|
||||||
val kick : t -> Peer_id.t -> bool -> unit Lwt.t
|
val kick : t -> P2p_peer.Id.t -> bool -> unit Lwt.t
|
||||||
val list : t -> Connection_info.t list
|
val list : t -> P2p_connection.Info.t list
|
||||||
val count : t -> int
|
val count : t -> int
|
||||||
end
|
end
|
||||||
|
|
||||||
module Point : sig
|
module Point : sig
|
||||||
|
|
||||||
val info :
|
val info :
|
||||||
t -> Point.t -> P2p_types.Point_info.t option
|
t -> P2p_point.Id.t -> P2p_point.Info.t option
|
||||||
|
|
||||||
val list :
|
val list :
|
||||||
?restrict: P2p_types.Point_state.t list ->
|
?restrict: P2p_point.State.t list ->
|
||||||
t -> (Point.t * P2p_types.Point_info.t) list
|
t -> (P2p_point.Id.t * P2p_point.Info.t) list
|
||||||
|
|
||||||
val events :
|
val events :
|
||||||
?max:int -> ?rev:bool -> t -> Point.t ->
|
?max:int -> ?rev:bool -> t -> P2p_point.Id.t ->
|
||||||
P2p_connection_pool_types.Point_info.Event.t list
|
P2p_point.Pool_event.t list
|
||||||
|
|
||||||
val watch :
|
val watch :
|
||||||
t -> Point.t ->
|
t -> P2p_point.Id.t ->
|
||||||
P2p_connection_pool_types.Point_info.Event.t Lwt_stream.t * Lwt_watcher.stopper
|
P2p_point.Pool_event.t Lwt_stream.t * Lwt_watcher.stopper
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module Peer_id : sig
|
module Peer_id : sig
|
||||||
|
|
||||||
val info :
|
val info :
|
||||||
t -> Peer_id.t -> P2p_types.Peer_info.t option
|
t -> P2p_peer.Id.t -> P2p_peer.Info.t option
|
||||||
|
|
||||||
val list :
|
val list :
|
||||||
?restrict: P2p_types.Peer_state.t list ->
|
?restrict: P2p_peer.State.t list ->
|
||||||
t -> (Peer_id.t * P2p_types.Peer_info.t) list
|
t -> (P2p_peer.Id.t * P2p_peer.Info.t) list
|
||||||
|
|
||||||
val events :
|
val events :
|
||||||
?max: int -> ?rev: bool ->
|
?max: int -> ?rev: bool ->
|
||||||
t -> Peer_id.t ->
|
t -> P2p_peer.Id.t ->
|
||||||
P2p_connection_pool_types.Peer_info.Event.t list
|
P2p_peer.Pool_event.t list
|
||||||
|
|
||||||
val watch :
|
val watch :
|
||||||
t -> Peer_id.t ->
|
t -> P2p_peer.Id.t ->
|
||||||
P2p_connection_pool_types.Peer_info.Event.t Lwt_stream.t * Lwt_watcher.stopper
|
P2p_peer.Pool_event.t Lwt_stream.t * Lwt_watcher.stopper
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
open Peer_validator_worker_state
|
open Peer_validator_worker_state
|
||||||
|
|
||||||
module Name = struct
|
module Name = struct
|
||||||
type t = Net_id.t * P2p.Peer_id.t
|
type t = Net_id.t * P2p_peer.Id.t
|
||||||
let encoding =
|
let encoding =
|
||||||
Data_encoding.tup2 Net_id.encoding P2p.Peer_id.encoding
|
Data_encoding.tup2 Net_id.encoding P2p_peer.Id.encoding
|
||||||
let base = [ "peer_validator" ]
|
let base = [ "peer_validator" ]
|
||||||
let pp ppf (net, peer) =
|
let pp ppf (net, peer) =
|
||||||
Format.fprintf ppf "%a:%a"
|
Format.fprintf ppf "%a:%a"
|
||||||
Net_id.pp_short net P2p.Peer_id.pp_short peer
|
Net_id.pp_short net P2p_peer.Id.pp_short peer
|
||||||
end
|
end
|
||||||
|
|
||||||
module Request = struct
|
module Request = struct
|
||||||
@ -57,7 +57,7 @@ module Types = struct
|
|||||||
}
|
}
|
||||||
|
|
||||||
type state = {
|
type state = {
|
||||||
peer_id: P2p.Peer_id.t ;
|
peer_id: P2p_peer.Id.t ;
|
||||||
parameters : parameters ;
|
parameters : parameters ;
|
||||||
mutable bootstrapped: bool ;
|
mutable bootstrapped: bool ;
|
||||||
mutable last_validated_head: Block_header.t ;
|
mutable last_validated_head: Block_header.t ;
|
||||||
@ -96,7 +96,7 @@ let bootstrap_new_branch w _ancestor _head unknown_prefix =
|
|||||||
let len = Block_locator_iterator.estimated_length unknown_prefix in
|
let len = Block_locator_iterator.estimated_length unknown_prefix in
|
||||||
debug w
|
debug w
|
||||||
"validating new branch from peer %a (approx. %d blocks)"
|
"validating new branch from peer %a (approx. %d blocks)"
|
||||||
P2p.Peer_id.pp_short pv.peer_id len ;
|
P2p_peer.Id.pp_short pv.peer_id len ;
|
||||||
let pipeline =
|
let pipeline =
|
||||||
Bootstrap_pipeline.create
|
Bootstrap_pipeline.create
|
||||||
~notify_new_block:pv.parameters.notify_new_block
|
~notify_new_block:pv.parameters.notify_new_block
|
||||||
@ -116,7 +116,7 @@ let bootstrap_new_branch w _ancestor _head unknown_prefix =
|
|||||||
set_bootstrapped pv ;
|
set_bootstrapped pv ;
|
||||||
debug w
|
debug w
|
||||||
"done validating new branch from peer %a."
|
"done validating new branch from peer %a."
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let validate_new_head w hash (header : Block_header.t) =
|
let validate_new_head w hash (header : Block_header.t) =
|
||||||
@ -127,14 +127,14 @@ let validate_new_head w hash (header : Block_header.t) =
|
|||||||
debug w
|
debug w
|
||||||
"missing predecessor for new head %a from peer %a"
|
"missing predecessor for new head %a from peer %a"
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
Distributed_db.Request.current_branch pv.parameters.net_db ~peer:pv.peer_id () ;
|
Distributed_db.Request.current_branch pv.parameters.net_db ~peer:pv.peer_id () ;
|
||||||
return ()
|
return ()
|
||||||
| true ->
|
| true ->
|
||||||
debug w
|
debug w
|
||||||
"fetching operations for new head %a from peer %a"
|
"fetching operations for new head %a from peer %a"
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
map_p
|
map_p
|
||||||
(fun i ->
|
(fun i ->
|
||||||
Worker.protect w begin fun () ->
|
Worker.protect w begin fun () ->
|
||||||
@ -147,7 +147,7 @@ let validate_new_head w hash (header : Block_header.t) =
|
|||||||
debug w
|
debug w
|
||||||
"requesting validation for new head %a from peer %a"
|
"requesting validation for new head %a from peer %a"
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
Block_validator.validate
|
Block_validator.validate
|
||||||
~notify_new_block:pv.parameters.notify_new_block
|
~notify_new_block:pv.parameters.notify_new_block
|
||||||
pv.parameters.block_validator pv.parameters.net_db
|
pv.parameters.block_validator pv.parameters.net_db
|
||||||
@ -155,7 +155,7 @@ let validate_new_head w hash (header : Block_header.t) =
|
|||||||
debug w
|
debug w
|
||||||
"end of validation for new head %a from peer %a"
|
"end of validation for new head %a from peer %a"
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
set_bootstrapped pv ;
|
set_bootstrapped pv ;
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ let only_if_fitness_increases w distant_header cont =
|
|||||||
debug w
|
debug w
|
||||||
"ignoring head %a with non increasing fitness from peer: %a."
|
"ignoring head %a with non increasing fitness from peer: %a."
|
||||||
Block_hash.pp_short (Block_header.hash distant_header)
|
Block_hash.pp_short (Block_header.hash distant_header)
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
(* Don't download a branch that cannot beat the current head. *)
|
(* Don't download a branch that cannot beat the current head. *)
|
||||||
return ()
|
return ()
|
||||||
end else cont ()
|
end else cont ()
|
||||||
@ -185,7 +185,7 @@ let may_validate_new_head w hash header =
|
|||||||
debug w
|
debug w
|
||||||
"ignoring previously validated block %a from peer %a"
|
"ignoring previously validated block %a from peer %a"
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
set_bootstrapped pv ;
|
set_bootstrapped pv ;
|
||||||
pv.last_validated_head <- header ;
|
pv.last_validated_head <- header ;
|
||||||
return ()
|
return ()
|
||||||
@ -193,7 +193,7 @@ let may_validate_new_head w hash header =
|
|||||||
debug w
|
debug w
|
||||||
"ignoring known invalid block %a from peer %a"
|
"ignoring known invalid block %a from peer %a"
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
fail Known_invalid
|
fail Known_invalid
|
||||||
end
|
end
|
||||||
| false ->
|
| false ->
|
||||||
@ -210,7 +210,7 @@ let may_validate_new_branch w distant_hash locator =
|
|||||||
debug w
|
debug w
|
||||||
"ignoring branch %a without common ancestor from peer: %a."
|
"ignoring branch %a without common ancestor from peer: %a."
|
||||||
Block_hash.pp_short distant_hash
|
Block_hash.pp_short distant_hash
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
fail Unknown_ancestor
|
fail Unknown_ancestor
|
||||||
| Some (ancestor, unknown_prefix) ->
|
| Some (ancestor, unknown_prefix) ->
|
||||||
bootstrap_new_branch w ancestor distant_header unknown_prefix
|
bootstrap_new_branch w ancestor distant_header unknown_prefix
|
||||||
@ -218,7 +218,7 @@ let may_validate_new_branch w distant_hash locator =
|
|||||||
let on_no_request w =
|
let on_no_request w =
|
||||||
let pv = Worker.state w in
|
let pv = Worker.state w in
|
||||||
debug w "no new head from peer %a for %g seconds."
|
debug w "no new head from peer %a for %g seconds."
|
||||||
P2p.Peer_id.pp_short pv.peer_id
|
P2p_peer.Id.pp_short pv.peer_id
|
||||||
pv.parameters.limits.new_head_request_timeout ;
|
pv.parameters.limits.new_head_request_timeout ;
|
||||||
Distributed_db.Request.current_head pv.parameters.net_db ~peer:pv.peer_id () ;
|
Distributed_db.Request.current_head pv.parameters.net_db ~peer:pv.peer_id () ;
|
||||||
return ()
|
return ()
|
||||||
@ -230,13 +230,13 @@ let on_request (type a) w (req : a Request.t) : a tzresult Lwt.t =
|
|||||||
debug w
|
debug w
|
||||||
"processing new head %a from peer %a."
|
"processing new head %a from peer %a."
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
may_validate_new_head w hash header
|
may_validate_new_head w hash header
|
||||||
| Request.New_branch (hash, locator) ->
|
| Request.New_branch (hash, locator) ->
|
||||||
(* TODO penalize empty locator... ?? *)
|
(* TODO penalize empty locator... ?? *)
|
||||||
debug w "processing new branch %a from peer %a."
|
debug w "processing new branch %a from peer %a."
|
||||||
Block_hash.pp_short hash
|
Block_hash.pp_short hash
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
may_validate_new_branch w hash locator
|
may_validate_new_branch w hash locator
|
||||||
|
|
||||||
let on_completion w r _ st =
|
let on_completion w r _ st =
|
||||||
@ -252,7 +252,7 @@ let on_error w r st errs =
|
|||||||
(* TODO ban the peer_id... *)
|
(* TODO ban the peer_id... *)
|
||||||
debug w
|
debug w
|
||||||
"Terminating the validation worker for peer %a (kickban)."
|
"Terminating the validation worker for peer %a (kickban)."
|
||||||
P2p.Peer_id.pp_short pv.peer_id ;
|
P2p_peer.Id.pp_short pv.peer_id ;
|
||||||
debug w "%a" Error_monad.pp_print_error errors ;
|
debug w "%a" Error_monad.pp_print_error errors ;
|
||||||
Worker.trigger_shutdown w ;
|
Worker.trigger_shutdown w ;
|
||||||
Worker.record_event w (Event.Request (r, st, Some errs)) ;
|
Worker.record_event w (Event.Request (r, st, Some errs)) ;
|
||||||
@ -269,7 +269,7 @@ let on_error w r st errs =
|
|||||||
debug w
|
debug w
|
||||||
"Terminating the validation worker for peer %a \
|
"Terminating the validation worker for peer %a \
|
||||||
(missing protocol %a)."
|
(missing protocol %a)."
|
||||||
P2p.Peer_id.pp_short pv.peer_id
|
P2p_peer.Id.pp_short pv.peer_id
|
||||||
Protocol_hash.pp_short protocol ;
|
Protocol_hash.pp_short protocol ;
|
||||||
Worker.record_event w (Event.Request (r, st, Some errs)) ;
|
Worker.record_event w (Event.Request (r, st, Some errs)) ;
|
||||||
Lwt.return (Error errs)
|
Lwt.return (Error errs)
|
||||||
|
@ -17,7 +17,7 @@ type limits = {
|
|||||||
worker_limits: Worker_types.limits
|
worker_limits: Worker_types.limits
|
||||||
}
|
}
|
||||||
|
|
||||||
val peer_id: t -> P2p.Peer_id.t
|
val peer_id: t -> P2p_peer.Id.t
|
||||||
val bootstrapped: t -> bool
|
val bootstrapped: t -> bool
|
||||||
val current_head: t -> Block_header.t
|
val current_head: t -> Block_header.t
|
||||||
|
|
||||||
@ -27,13 +27,13 @@ val create:
|
|||||||
?notify_termination: (unit -> unit) ->
|
?notify_termination: (unit -> unit) ->
|
||||||
limits ->
|
limits ->
|
||||||
Block_validator.t ->
|
Block_validator.t ->
|
||||||
Distributed_db.net_db -> P2p.Peer_id.t -> t Lwt.t
|
Distributed_db.net_db -> P2p_peer.Id.t -> t Lwt.t
|
||||||
val shutdown: t -> unit Lwt.t
|
val shutdown: t -> unit Lwt.t
|
||||||
|
|
||||||
val notify_branch: t -> Block_locator.t -> unit
|
val notify_branch: t -> Block_locator.t -> unit
|
||||||
val notify_head: t -> Block_header.t -> unit
|
val notify_head: t -> Block_header.t -> unit
|
||||||
|
|
||||||
val running_workers: unit -> ((Net_id.t * P2p.Peer_id.t) * t) list
|
val running_workers: unit -> ((Net_id.t * P2p_peer.Id.t) * t) list
|
||||||
val status: t -> Worker_types.worker_status
|
val status: t -> Worker_types.worker_status
|
||||||
|
|
||||||
val current_request : t -> (Time.t * Time.t * Peer_validator_worker_state.Request.view) option
|
val current_request : t -> (Time.t * Time.t * Peer_validator_worker_state.Request.view) option
|
||||||
|
@ -40,7 +40,7 @@ type error += Closed of Net_id.t
|
|||||||
|
|
||||||
val create: limits -> Distributed_db.net_db -> t Lwt.t
|
val create: limits -> Distributed_db.net_db -> t Lwt.t
|
||||||
val shutdown: t -> unit Lwt.t
|
val shutdown: t -> unit Lwt.t
|
||||||
val notify_operations: t -> P2p.Peer_id.t -> Mempool.t -> unit
|
val notify_operations: t -> P2p_peer.Id.t -> Mempool.t -> unit
|
||||||
val inject_operation: t -> Operation.t -> unit tzresult Lwt.t
|
val inject_operation: t -> Operation.t -> unit tzresult Lwt.t
|
||||||
val flush: t -> Block_hash.t -> unit tzresult Lwt.t
|
val flush: t -> Block_hash.t -> unit tzresult Lwt.t
|
||||||
val timestamp: t -> Time.t
|
val timestamp: t -> Time.t
|
||||||
|
@ -28,19 +28,19 @@ val shutdown: t -> unit Lwt.t
|
|||||||
|
|
||||||
val fetch_and_compile_protocol:
|
val fetch_and_compile_protocol:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
Protocol_hash.t -> State.Registred_protocol.t tzresult Lwt.t
|
Protocol_hash.t -> State.Registred_protocol.t tzresult Lwt.t
|
||||||
|
|
||||||
val fetch_and_compile_protocols:
|
val fetch_and_compile_protocols:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
State.Block.t -> unit tzresult Lwt.t
|
State.Block.t -> unit tzresult Lwt.t
|
||||||
|
|
||||||
val prefetch_and_compile_protocols:
|
val prefetch_and_compile_protocols:
|
||||||
t ->
|
t ->
|
||||||
?peer:P2p.Peer_id.t ->
|
?peer:P2p_peer.Id.t ->
|
||||||
?timeout:float ->
|
?timeout:float ->
|
||||||
State.Block.t -> unit
|
State.Block.t -> unit
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ module Request = struct
|
|||||||
type view = {
|
type view = {
|
||||||
net_id : Net_id.t ;
|
net_id : Net_id.t ;
|
||||||
block : Block_hash.t ;
|
block : Block_hash.t ;
|
||||||
peer : P2p_types.Peer_id.t option ;
|
peer : P2p_peer.Id.t option ;
|
||||||
}
|
}
|
||||||
let encoding =
|
let encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
@ -21,7 +21,7 @@ module Request = struct
|
|||||||
(obj3
|
(obj3
|
||||||
(req "block" Block_hash.encoding)
|
(req "block" Block_hash.encoding)
|
||||||
(req "net_id" Net_id.encoding)
|
(req "net_id" Net_id.encoding)
|
||||||
(opt "peer" P2p_types.Peer_id.encoding))
|
(opt "peer" P2p_peer.Id.encoding))
|
||||||
|
|
||||||
let pp ppf { net_id ; block ; peer } =
|
let pp ppf { net_id ; block ; peer } =
|
||||||
Format.fprintf ppf "Validation of %a (net: %a)"
|
Format.fprintf ppf "Validation of %a (net: %a)"
|
||||||
@ -31,7 +31,7 @@ module Request = struct
|
|||||||
| None -> ()
|
| None -> ()
|
||||||
| Some peer ->
|
| Some peer ->
|
||||||
Format.fprintf ppf "from peer %a"
|
Format.fprintf ppf "from peer %a"
|
||||||
P2p_types.Peer_id.pp_short peer
|
P2p_peer.Id.pp_short peer
|
||||||
end
|
end
|
||||||
|
|
||||||
module Event = struct
|
module Event = struct
|
||||||
|
@ -11,7 +11,7 @@ module Request : sig
|
|||||||
type view = {
|
type view = {
|
||||||
net_id : Net_id.t ;
|
net_id : Net_id.t ;
|
||||||
block : Block_hash.t ;
|
block : Block_hash.t ;
|
||||||
peer: P2p_types.Peer_id.t option ;
|
peer: P2p_peer.Id.t option ;
|
||||||
}
|
}
|
||||||
val encoding : view Data_encoding.encoding
|
val encoding : view Data_encoding.encoding
|
||||||
val pp : Format.formatter -> view -> unit
|
val pp : Format.formatter -> view -> unit
|
||||||
|
@ -89,8 +89,8 @@ end
|
|||||||
|
|
||||||
module Worker_state = struct
|
module Worker_state = struct
|
||||||
type view =
|
type view =
|
||||||
{ active_peers : P2p_types.Peer_id.t list ;
|
{ active_peers : P2p_peer.Id.t list ;
|
||||||
bootstrapped_peers : P2p_types.Peer_id.t list ;
|
bootstrapped_peers : P2p_peer.Id.t list ;
|
||||||
bootstrapped : bool }
|
bootstrapped : bool }
|
||||||
let encoding =
|
let encoding =
|
||||||
let open Data_encoding in
|
let open Data_encoding in
|
||||||
@ -101,8 +101,8 @@ module Worker_state = struct
|
|||||||
{ bootstrapped ; bootstrapped_peers ; active_peers })
|
{ bootstrapped ; bootstrapped_peers ; active_peers })
|
||||||
(obj3
|
(obj3
|
||||||
(req "bootstrapped" bool)
|
(req "bootstrapped" bool)
|
||||||
(req "bootstrapped_peers" (list P2p_types.Peer_id.encoding))
|
(req "bootstrapped_peers" (list P2p_peer.Id.encoding))
|
||||||
(req "active_peers" (list P2p_types.Peer_id.encoding)))
|
(req "active_peers" (list P2p_peer.Id.encoding)))
|
||||||
|
|
||||||
let pp ppf { bootstrapped ; bootstrapped_peers ; active_peers } =
|
let pp ppf { bootstrapped ; bootstrapped_peers ; active_peers } =
|
||||||
Format.fprintf ppf
|
Format.fprintf ppf
|
||||||
@ -110,8 +110,8 @@ module Worker_state = struct
|
|||||||
@[<v 2>Active peers:%a@]@,\
|
@[<v 2>Active peers:%a@]@,\
|
||||||
@[<v 2>Bootstrapped peers:%a@]@]"
|
@[<v 2>Bootstrapped peers:%a@]@]"
|
||||||
(if bootstrapped then "" else " not yet")
|
(if bootstrapped then "" else " not yet")
|
||||||
(fun ppf -> List.iter (Format.fprintf ppf "@,- %a" P2p_types.Peer_id.pp))
|
(fun ppf -> List.iter (Format.fprintf ppf "@,- %a" P2p_peer.Id.pp))
|
||||||
active_peers
|
active_peers
|
||||||
(fun ppf -> List.iter (Format.fprintf ppf "@,- %a" P2p_types.Peer_id.pp))
|
(fun ppf -> List.iter (Format.fprintf ppf "@,- %a" P2p_peer.Id.pp))
|
||||||
bootstrapped_peers
|
bootstrapped_peers
|
||||||
end
|
end
|
||||||
|
@ -32,8 +32,8 @@ end
|
|||||||
|
|
||||||
module Worker_state : sig
|
module Worker_state : sig
|
||||||
type view =
|
type view =
|
||||||
{ active_peers : P2p_types.Peer_id.t list ;
|
{ active_peers : P2p_peer.Id.t list ;
|
||||||
bootstrapped_peers : P2p_types.Peer_id.t list ;
|
bootstrapped_peers : P2p_peer.Id.t list ;
|
||||||
bootstrapped : bool }
|
bootstrapped : bool }
|
||||||
val encoding : view Data_encoding.encoding
|
val encoding : view Data_encoding.encoding
|
||||||
val pp : Format.formatter -> view -> unit
|
val pp : Format.formatter -> view -> unit
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
module Request = struct
|
module Request = struct
|
||||||
type 'a t =
|
type 'a t =
|
||||||
| Flush : Block_hash.t -> unit t
|
| Flush : Block_hash.t -> unit t
|
||||||
| Notify : P2p_types.Peer_id.t * Mempool.t -> unit t
|
| Notify : P2p_peer.Id.t * Mempool.t -> unit t
|
||||||
| Inject : Operation.t -> unit tzresult t
|
| Inject : Operation.t -> unit tzresult t
|
||||||
| Arrived : Operation_hash.t * Operation.t -> unit t
|
| Arrived : Operation_hash.t * Operation.t -> unit t
|
||||||
| Advertise : unit t
|
| Advertise : unit t
|
||||||
@ -30,7 +30,7 @@ module Request = struct
|
|||||||
case (Tag 1)
|
case (Tag 1)
|
||||||
(obj3
|
(obj3
|
||||||
(req "request" (constant "notify"))
|
(req "request" (constant "notify"))
|
||||||
(req "peer" P2p_types.Peer_id.encoding)
|
(req "peer" P2p_peer.Id.encoding)
|
||||||
(req "mempool" Mempool.encoding))
|
(req "mempool" Mempool.encoding))
|
||||||
(function View (Notify (peer, mempool)) -> Some ((), peer, mempool) | _ -> None)
|
(function View (Notify (peer, mempool)) -> Some ((), peer, mempool) | _ -> None)
|
||||||
(fun ((), peer, mempool) -> View (Notify (peer, mempool))) ;
|
(fun ((), peer, mempool) -> View (Notify (peer, mempool))) ;
|
||||||
@ -58,7 +58,7 @@ module Request = struct
|
|||||||
Block_hash.pp hash
|
Block_hash.pp hash
|
||||||
| Notify (id, { Mempool.known_valid ; pending }) ->
|
| Notify (id, { Mempool.known_valid ; pending }) ->
|
||||||
Format.fprintf ppf "@[<v 2>notified by %a of operations"
|
Format.fprintf ppf "@[<v 2>notified by %a of operations"
|
||||||
P2p_types.Peer_id.pp id ;
|
P2p_peer.Id.pp id ;
|
||||||
List.iter
|
List.iter
|
||||||
(fun oph ->
|
(fun oph ->
|
||||||
Format.fprintf ppf "@,%a (applied)"
|
Format.fprintf ppf "@,%a (applied)"
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
module Request : sig
|
module Request : sig
|
||||||
type 'a t =
|
type 'a t =
|
||||||
| Flush : Block_hash.t -> unit t
|
| Flush : Block_hash.t -> unit t
|
||||||
| Notify : P2p_types.Peer_id.t * Mempool.t -> unit t
|
| Notify : P2p_peer.Id.t * Mempool.t -> unit t
|
||||||
| Inject : Operation.t -> unit tzresult t
|
| Inject : Operation.t -> unit tzresult t
|
||||||
| Arrived : Operation_hash.t * Operation.t -> unit t
|
| Arrived : Operation_hash.t * Operation.t -> unit t
|
||||||
| Advertise : unit t
|
| Advertise : unit t
|
||||||
|
@ -558,14 +558,14 @@ module Workers = struct
|
|||||||
~construct:Net_id.to_b58check
|
~construct:Net_id.to_b58check
|
||||||
()
|
()
|
||||||
|
|
||||||
let (peer_id_arg : P2p_types.Peer_id.t RPC_arg.t) =
|
let (peer_id_arg : P2p_peer.Id.t RPC_arg.t) =
|
||||||
RPC_arg.make
|
RPC_arg.make
|
||||||
~name:"peer_id"
|
~name:"peer_id"
|
||||||
~descr:"The peer identifier of whom the prevalidator is responsible."
|
~descr:"The peer identifier of whom the prevalidator is responsible."
|
||||||
~destruct:(fun s -> try
|
~destruct:(fun s -> try
|
||||||
Ok (P2p_types.Peer_id.of_b58check_exn s)
|
Ok (P2p_peer.Id.of_b58check_exn s)
|
||||||
with Failure msg -> Error msg)
|
with Failure msg -> Error msg)
|
||||||
~construct:P2p_types.Peer_id.to_b58check
|
~construct:P2p_peer.Id.to_b58check
|
||||||
()
|
()
|
||||||
|
|
||||||
let list =
|
let list =
|
||||||
@ -577,7 +577,7 @@ module Workers = struct
|
|||||||
~output:
|
~output:
|
||||||
(list
|
(list
|
||||||
(obj2
|
(obj2
|
||||||
(req "peer_id" P2p_types.Peer_id.encoding)
|
(req "peer_id" P2p_peer.Id.encoding)
|
||||||
(req "status" (Worker_types.worker_status_encoding RPC_error.encoding))))
|
(req "status" (Worker_types.worker_status_encoding RPC_error.encoding))))
|
||||||
RPC_path.(root / "workers" / "peer_validators" /: net_id_arg)
|
RPC_path.(root / "workers" / "peer_validators" /: net_id_arg)
|
||||||
|
|
||||||
|
@ -201,11 +201,11 @@ module Workers : sig
|
|||||||
val list :
|
val list :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
unit * Net_id.t, unit, unit,
|
unit * Net_id.t, unit, unit,
|
||||||
(P2p_types.Peer_id.t * Worker_types.worker_status) list, unit) RPC_service.t
|
(P2p_peer.Id.t * Worker_types.worker_status) list, unit) RPC_service.t
|
||||||
|
|
||||||
val state :
|
val state :
|
||||||
([ `POST ], unit,
|
([ `POST ], unit,
|
||||||
(unit * Net_id.t) * P2p_types.Peer_id.t, unit, unit,
|
(unit * Net_id.t) * P2p_peer.Id.t, unit, unit,
|
||||||
(Request.view, Event.t) Worker_types.full_status, unit)
|
(Request.view, Event.t) Worker_types.full_status, unit)
|
||||||
RPC_service.t
|
RPC_service.t
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
(jbuild_version 1)
|
(jbuild_version 1)
|
||||||
|
|
||||||
(executables
|
(executables
|
||||||
((names (test_p2p_connection
|
((names (test_p2p_socket
|
||||||
test_p2p_connection_pool
|
test_p2p_pool
|
||||||
test_p2p_io_scheduler))
|
test_p2p_io_scheduler))
|
||||||
(libraries (tezos-base
|
(libraries (tezos-base
|
||||||
tezos-p2p-services
|
tezos-p2p-services
|
||||||
@ -18,17 +18,17 @@
|
|||||||
|
|
||||||
(alias
|
(alias
|
||||||
((name buildtest)
|
((name buildtest)
|
||||||
(deps (test_p2p_connection.exe
|
(deps (test_p2p_socket.exe
|
||||||
test_p2p_connection_pool.exe
|
test_p2p_pool.exe
|
||||||
test_p2p_io_scheduler.exe))))
|
test_p2p_io_scheduler.exe))))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
((name runtest_p2p_connection)
|
((name runtest_p2p_socket)
|
||||||
(action (run ${exe:test_p2p_connection.exe} -v))))
|
(action (run ${exe:test_p2p_socket.exe} -v))))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
((name runtest_p2p_connection_pool)
|
((name runtest_p2p_pool)
|
||||||
(action (run ${exe:test_p2p_connection_pool.exe} --clients 10 --repeat 5 -v))))
|
(action (run ${exe:test_p2p_pool.exe} --clients 10 --repeat 5 -v))))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
((name runtest_p2p_io_scheduler)
|
((name runtest_p2p_io_scheduler)
|
||||||
@ -40,8 +40,8 @@
|
|||||||
|
|
||||||
(alias
|
(alias
|
||||||
((name runtest)
|
((name runtest)
|
||||||
(deps ((alias runtest_p2p_connection)
|
(deps ((alias runtest_p2p_socket)
|
||||||
(alias runtest_p2p_connection_pool)
|
(alias runtest_p2p_pool)
|
||||||
(alias runtest_p2p_io_scheduler)))))
|
(alias runtest_p2p_io_scheduler)))))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
include Logging.Make (struct let name = "test-p2p-io-scheduler" end)
|
include Logging.Make (struct let name = "test-p2p-io-scheduler" end)
|
||||||
|
|
||||||
exception Error of error list
|
exception Error of error list
|
||||||
@ -89,18 +88,18 @@ let server
|
|||||||
~read_buffer_size
|
~read_buffer_size
|
||||||
() in
|
() in
|
||||||
Moving_average.on_update begin fun () ->
|
Moving_average.on_update begin fun () ->
|
||||||
log_notice "Stat: %a" Stat.pp (P2p_io_scheduler.global_stat sched) ;
|
log_notice "Stat: %a" P2p_stat.pp (P2p_io_scheduler.global_stat sched) ;
|
||||||
if display_client_stat then
|
if display_client_stat then
|
||||||
P2p_io_scheduler.iter_connection sched
|
P2p_io_scheduler.iter_connection sched
|
||||||
(fun id conn ->
|
(fun id conn ->
|
||||||
log_notice " client(%d) %a" id Stat.pp (P2p_io_scheduler.stat conn)) ;
|
log_notice " client(%d) %a" id P2p_stat.pp (P2p_io_scheduler.stat conn)) ;
|
||||||
end ;
|
end ;
|
||||||
(* Accept and read message until the connection is closed. *)
|
(* Accept and read message until the connection is closed. *)
|
||||||
accept_n main_socket n >>=? fun conns ->
|
accept_n main_socket n >>=? fun conns ->
|
||||||
let conns = List.map (P2p_io_scheduler.register sched) conns in
|
let conns = List.map (P2p_io_scheduler.register sched) conns in
|
||||||
Lwt.join (List.map receive conns) >>= fun () ->
|
Lwt.join (List.map receive conns) >>= fun () ->
|
||||||
iter_p P2p_io_scheduler.close conns >>=? fun () ->
|
iter_p P2p_io_scheduler.close conns >>=? fun () ->
|
||||||
log_notice "OK %a" Stat.pp (P2p_io_scheduler.global_stat sched) ;
|
log_notice "OK %a" P2p_stat.pp (P2p_io_scheduler.global_stat sched) ;
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let max_size ?max_upload_speed () =
|
let max_size ?max_upload_speed () =
|
||||||
@ -131,7 +130,7 @@ let client ?max_upload_speed ?write_queue_size addr port time _n =
|
|||||||
Lwt_unix.sleep time >>= return ] >>=? fun () ->
|
Lwt_unix.sleep time >>= return ] >>=? fun () ->
|
||||||
P2p_io_scheduler.close conn >>=? fun () ->
|
P2p_io_scheduler.close conn >>=? fun () ->
|
||||||
let stat = P2p_io_scheduler.stat conn in
|
let stat = P2p_io_scheduler.stat conn in
|
||||||
lwt_log_notice "Client OK %a" Stat.pp stat >>= fun () ->
|
lwt_log_notice "Client OK %a" P2p_stat.pp stat >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let run
|
let run
|
||||||
|
@ -7,16 +7,15 @@
|
|||||||
(* *)
|
(* *)
|
||||||
(**************************************************************************)
|
(**************************************************************************)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
include Logging.Make (struct let name = "test.p2p.connection-pool" end)
|
include Logging.Make (struct let name = "test.p2p.connection-pool" end)
|
||||||
|
|
||||||
type message =
|
type message =
|
||||||
| Ping
|
| Ping
|
||||||
|
|
||||||
|
|
||||||
let msg_config : message P2p_connection_pool.message_config = {
|
let msg_config : message P2p_pool.message_config = {
|
||||||
encoding = [
|
encoding = [
|
||||||
P2p_connection_pool.Encoding {
|
P2p_pool.Encoding {
|
||||||
tag = 0x10 ;
|
tag = 0x10 ;
|
||||||
encoding = Data_encoding.empty ;
|
encoding = Data_encoding.empty ;
|
||||||
wrap = (function () -> Ping) ;
|
wrap = (function () -> Ping) ;
|
||||||
@ -24,12 +23,12 @@ let msg_config : message P2p_connection_pool.message_config = {
|
|||||||
max_length = None ;
|
max_length = None ;
|
||||||
} ;
|
} ;
|
||||||
] ;
|
] ;
|
||||||
versions = Version.[ { name = "TEST" ; major = 0 ; minor = 0 } ] ;
|
versions = P2p_version.[ { name = "TEST" ; major = 0 ; minor = 0 } ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
type metadata = unit
|
type metadata = unit
|
||||||
|
|
||||||
let meta_config : metadata P2p_connection_pool.meta_config = {
|
let meta_config : metadata P2p_pool.meta_config = {
|
||||||
encoding = Data_encoding.empty ;
|
encoding = Data_encoding.empty ;
|
||||||
initial = () ;
|
initial = () ;
|
||||||
score = fun () -> 0. ;
|
score = fun () -> 0. ;
|
||||||
@ -59,9 +58,9 @@ let sync_nodes nodes =
|
|||||||
let detach_node f points n =
|
let detach_node f points n =
|
||||||
let (addr, port), points = List.select n points in
|
let (addr, port), points = List.select n points in
|
||||||
let proof_of_work_target = Crypto_box.make_target 0. in
|
let proof_of_work_target = Crypto_box.make_target 0. in
|
||||||
let identity = Identity.generate proof_of_work_target in
|
let identity = P2p_identity.generate proof_of_work_target in
|
||||||
let nb_points = List.length points in
|
let nb_points = List.length points in
|
||||||
let config = P2p_connection_pool.{
|
let config = P2p_pool.{
|
||||||
identity ;
|
identity ;
|
||||||
proof_of_work_target ;
|
proof_of_work_target ;
|
||||||
trusted_points = points ;
|
trusted_points = points ;
|
||||||
@ -83,10 +82,10 @@ let detach_node f points n =
|
|||||||
binary_chunks_size = None
|
binary_chunks_size = None
|
||||||
} in
|
} in
|
||||||
Process.detach
|
Process.detach
|
||||||
~prefix:(Format.asprintf "%a: " Peer_id.pp_short identity.peer_id)
|
~prefix:(Format.asprintf "%a: " P2p_peer.Id.pp_short identity.peer_id)
|
||||||
begin fun channel ->
|
begin fun channel ->
|
||||||
let sched = P2p_io_scheduler.create ~read_buffer_size:(1 lsl 12) () in
|
let sched = P2p_io_scheduler.create ~read_buffer_size:(1 lsl 12) () in
|
||||||
P2p_connection_pool.create
|
P2p_pool.create
|
||||||
config meta_config msg_config sched >>= fun pool ->
|
config meta_config msg_config sched >>= fun pool ->
|
||||||
P2p_welcome.run ~backlog:10 pool ~addr port >>= fun welcome ->
|
P2p_welcome.run ~backlog:10 pool ~addr port >>= fun welcome ->
|
||||||
lwt_log_info "Node ready (port: %d)" port >>= fun () ->
|
lwt_log_info "Node ready (port: %d)" port >>= fun () ->
|
||||||
@ -94,7 +93,7 @@ let detach_node f points n =
|
|||||||
f channel pool points >>=? fun () ->
|
f channel pool points >>=? fun () ->
|
||||||
lwt_log_info "Shutting down..." >>= fun () ->
|
lwt_log_info "Shutting down..." >>= fun () ->
|
||||||
P2p_welcome.shutdown welcome >>= fun () ->
|
P2p_welcome.shutdown welcome >>= fun () ->
|
||||||
P2p_connection_pool.destroy pool >>= fun () ->
|
P2p_pool.destroy pool >>= fun () ->
|
||||||
P2p_io_scheduler.shutdown sched >>= fun () ->
|
P2p_io_scheduler.shutdown sched >>= fun () ->
|
||||||
lwt_log_info "Bye." >>= fun () ->
|
lwt_log_info "Bye." >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
@ -112,34 +111,34 @@ type error += Connect | Write | Read
|
|||||||
module Simple = struct
|
module Simple = struct
|
||||||
|
|
||||||
let rec connect ~timeout pool point =
|
let rec connect ~timeout pool point =
|
||||||
lwt_log_info "Connect to %a" Point.pp point >>= fun () ->
|
lwt_log_info "Connect to %a" P2p_point.Id.pp point >>= fun () ->
|
||||||
P2p_connection_pool.connect pool point ~timeout >>= function
|
P2p_pool.connect pool point ~timeout >>= function
|
||||||
| Error [P2p_connection_pool.Connected] -> begin
|
| Error [P2p_pool.Connected] -> begin
|
||||||
match P2p_connection_pool.Connection.find_by_point pool point with
|
match P2p_pool.Connection.find_by_point pool point with
|
||||||
| Some conn -> return conn
|
| Some conn -> return conn
|
||||||
| None -> failwith "Woops..."
|
| None -> failwith "Woops..."
|
||||||
end
|
end
|
||||||
| Error ([ P2p_connection_pool.Connection_refused
|
| Error ([ P2p_pool.Connection_refused
|
||||||
| P2p_connection_pool.Pending_connection
|
| P2p_pool.Pending_connection
|
||||||
| P2p_connection.Rejected
|
| P2p_socket.Rejected
|
||||||
| Lwt_utils.Canceled
|
| Lwt_utils.Canceled
|
||||||
| Lwt_utils.Timeout
|
| Lwt_utils.Timeout
|
||||||
| P2p_connection_pool.Rejected _ as err ]) ->
|
| P2p_pool.Rejected _ as err ]) ->
|
||||||
lwt_log_info "Connection to %a failed (%a)"
|
lwt_log_info "Connection to %a failed (%a)"
|
||||||
Point.pp point
|
P2p_point.Id.pp point
|
||||||
(fun ppf err -> match err with
|
(fun ppf err -> match err with
|
||||||
| P2p_connection_pool.Connection_refused ->
|
| P2p_pool.Connection_refused ->
|
||||||
Format.fprintf ppf "connection refused"
|
Format.fprintf ppf "connection refused"
|
||||||
| P2p_connection_pool.Pending_connection ->
|
| P2p_pool.Pending_connection ->
|
||||||
Format.fprintf ppf "pending connection"
|
Format.fprintf ppf "pending connection"
|
||||||
| P2p_connection.Rejected ->
|
| P2p_socket.Rejected ->
|
||||||
Format.fprintf ppf "rejected"
|
Format.fprintf ppf "rejected"
|
||||||
| Lwt_utils.Canceled ->
|
| Lwt_utils.Canceled ->
|
||||||
Format.fprintf ppf "canceled"
|
Format.fprintf ppf "canceled"
|
||||||
| Lwt_utils.Timeout ->
|
| Lwt_utils.Timeout ->
|
||||||
Format.fprintf ppf "timeout"
|
Format.fprintf ppf "timeout"
|
||||||
| P2p_connection_pool.Rejected peer ->
|
| P2p_pool.Rejected peer ->
|
||||||
Format.fprintf ppf "rejected (%a)" Peer_id.pp peer
|
Format.fprintf ppf "rejected (%a)" P2p_peer.Id.pp peer
|
||||||
| _ -> assert false) err >>= fun () ->
|
| _ -> assert false) err >>= fun () ->
|
||||||
Lwt_unix.sleep (0.5 +. Random.float 2.) >>= fun () ->
|
Lwt_unix.sleep (0.5 +. Random.float 2.) >>= fun () ->
|
||||||
connect ~timeout pool point
|
connect ~timeout pool point
|
||||||
@ -151,18 +150,18 @@ module Simple = struct
|
|||||||
let write_all conns msg =
|
let write_all conns msg =
|
||||||
iter_p
|
iter_p
|
||||||
(fun conn ->
|
(fun conn ->
|
||||||
trace Write @@ P2p_connection_pool.write_sync conn msg)
|
trace Write @@ P2p_pool.write_sync conn msg)
|
||||||
conns
|
conns
|
||||||
|
|
||||||
let read_all conns =
|
let read_all conns =
|
||||||
iter_p
|
iter_p
|
||||||
(fun conn ->
|
(fun conn ->
|
||||||
trace Read @@ P2p_connection_pool.read conn >>=? fun Ping ->
|
trace Read @@ P2p_pool.read conn >>=? fun Ping ->
|
||||||
return ())
|
return ())
|
||||||
conns
|
conns
|
||||||
|
|
||||||
let close_all conns =
|
let close_all conns =
|
||||||
Lwt_list.iter_p P2p_connection_pool.disconnect conns
|
Lwt_list.iter_p P2p_pool.disconnect conns
|
||||||
|
|
||||||
let node channel pool points =
|
let node channel pool points =
|
||||||
connect_all ~timeout:2. pool points >>=? fun conns ->
|
connect_all ~timeout:2. pool points >>=? fun conns ->
|
||||||
@ -187,10 +186,10 @@ module Random_connections = struct
|
|||||||
let rec connect_random pool total rem point n =
|
let rec connect_random pool total rem point n =
|
||||||
Lwt_unix.sleep (0.2 +. Random.float 1.0) >>= fun () ->
|
Lwt_unix.sleep (0.2 +. Random.float 1.0) >>= fun () ->
|
||||||
(trace Connect @@ Simple.connect ~timeout:2. pool point) >>=? fun conn ->
|
(trace Connect @@ Simple.connect ~timeout:2. pool point) >>=? fun conn ->
|
||||||
(trace Write @@ P2p_connection_pool.write conn Ping) >>= fun _ ->
|
(trace Write @@ P2p_pool.write conn Ping) >>= fun _ ->
|
||||||
(trace Read @@ P2p_connection_pool.read conn) >>=? fun Ping ->
|
(trace Read @@ P2p_pool.read conn) >>=? fun Ping ->
|
||||||
Lwt_unix.sleep (0.2 +. Random.float 1.0) >>= fun () ->
|
Lwt_unix.sleep (0.2 +. Random.float 1.0) >>= fun () ->
|
||||||
P2p_connection_pool.disconnect conn >>= fun () ->
|
P2p_pool.disconnect conn >>= fun () ->
|
||||||
begin
|
begin
|
||||||
decr rem ;
|
decr rem ;
|
||||||
if !rem mod total = 0 then
|
if !rem mod total = 0 then
|
||||||
@ -231,7 +230,7 @@ module Garbled = struct
|
|||||||
let bad_msg = MBytes.of_string (String.make 16 '\000') in
|
let bad_msg = MBytes.of_string (String.make 16 '\000') in
|
||||||
iter_p
|
iter_p
|
||||||
(fun conn ->
|
(fun conn ->
|
||||||
trace Write @@ P2p_connection_pool.raw_write_sync conn bad_msg)
|
trace Write @@ P2p_pool.raw_write_sync conn bad_msg)
|
||||||
conns
|
conns
|
||||||
|
|
||||||
let node ch pool points =
|
let node ch pool points =
|
@ -10,20 +10,19 @@
|
|||||||
(* TODO Use Kaputt on the client side and remove `assert` from the
|
(* TODO Use Kaputt on the client side and remove `assert` from the
|
||||||
server. *)
|
server. *)
|
||||||
|
|
||||||
open P2p_types
|
|
||||||
include Logging.Make (struct let name = "test.p2p.connection" end)
|
include Logging.Make (struct let name = "test.p2p.connection" end)
|
||||||
|
|
||||||
let default_addr = Ipaddr.V6.localhost
|
let default_addr = Ipaddr.V6.localhost
|
||||||
|
|
||||||
let proof_of_work_target = Crypto_box.make_target 16.
|
let proof_of_work_target = Crypto_box.make_target 16.
|
||||||
let id1 = Identity.generate proof_of_work_target
|
let id1 = P2p_identity.generate proof_of_work_target
|
||||||
let id2 = Identity.generate proof_of_work_target
|
let id2 = P2p_identity.generate proof_of_work_target
|
||||||
|
|
||||||
let id0 =
|
let id0 =
|
||||||
(* Luckilly, this will be an insuficient proof of work! *)
|
(* Luckilly, this will be an insuficient proof of work! *)
|
||||||
Identity.generate (Crypto_box.make_target 0.)
|
P2p_identity.generate (Crypto_box.make_target 0.)
|
||||||
|
|
||||||
let versions = Version.[{ name = "TEST" ; minor = 0 ; major = 0 }]
|
let versions = P2p_version.[{ name = "TEST" ; minor = 0 ; major = 0 }]
|
||||||
|
|
||||||
let random_bytes len =
|
let random_bytes len =
|
||||||
let msg = MBytes.create len in
|
let msg = MBytes.create len in
|
||||||
@ -104,7 +103,7 @@ let raw_accept sched main_socket =
|
|||||||
|
|
||||||
let accept sched main_socket =
|
let accept sched main_socket =
|
||||||
raw_accept sched main_socket >>= fun (fd, point) ->
|
raw_accept sched main_socket >>= fun (fd, point) ->
|
||||||
P2p_connection.authenticate
|
P2p_socket.authenticate
|
||||||
~proof_of_work_target
|
~proof_of_work_target
|
||||||
~incoming:true fd point id1 versions
|
~incoming:true fd point id1 versions
|
||||||
|
|
||||||
@ -118,11 +117,11 @@ let raw_connect sched addr port =
|
|||||||
|
|
||||||
let connect sched addr port id =
|
let connect sched addr port id =
|
||||||
raw_connect sched addr port >>= fun fd ->
|
raw_connect sched addr port >>= fun fd ->
|
||||||
P2p_connection.authenticate
|
P2p_socket.authenticate
|
||||||
~proof_of_work_target
|
~proof_of_work_target
|
||||||
~incoming:false fd (addr, port) id versions >>=? fun (info, auth_fd) ->
|
~incoming:false fd (addr, port) id versions >>=? fun (info, auth_fd) ->
|
||||||
_assert (not info.incoming) __LOC__ "" >>=? fun () ->
|
_assert (not info.incoming) __LOC__ "" >>=? fun () ->
|
||||||
_assert (Peer_id.compare info.peer_id id1.peer_id = 0)
|
_assert (P2p_peer.Id.compare info.peer_id id1.peer_id = 0)
|
||||||
__LOC__ "" >>=? fun () ->
|
__LOC__ "" >>=? fun () ->
|
||||||
return auth_fd
|
return auth_fd
|
||||||
|
|
||||||
@ -134,7 +133,7 @@ let is_connection_closed = function
|
|||||||
false
|
false
|
||||||
|
|
||||||
let is_decoding_error = function
|
let is_decoding_error = function
|
||||||
| Error [P2p_connection.Decoding_error] -> true
|
| Error [P2p_socket.Decoding_error] -> true
|
||||||
| Ok _ -> false
|
| Ok _ -> false
|
||||||
| Error err ->
|
| Error err ->
|
||||||
log_notice "Error: %a" pp_print_error err ;
|
log_notice "Error: %a" pp_print_error err ;
|
||||||
@ -167,7 +166,7 @@ module Kick = struct
|
|||||||
let encoding = Data_encoding.bytes
|
let encoding = Data_encoding.bytes
|
||||||
|
|
||||||
let is_rejected = function
|
let is_rejected = function
|
||||||
| Error [P2p_connection.Rejected] -> true
|
| Error [P2p_socket.Rejected] -> true
|
||||||
| Ok _ -> false
|
| Ok _ -> false
|
||||||
| Error err ->
|
| Error err ->
|
||||||
log_notice "Error: %a" pp_print_error err ;
|
log_notice "Error: %a" pp_print_error err ;
|
||||||
@ -176,14 +175,14 @@ module Kick = struct
|
|||||||
let server _ch sched socket =
|
let server _ch sched socket =
|
||||||
accept sched socket >>=? fun (info, auth_fd) ->
|
accept sched socket >>=? fun (info, auth_fd) ->
|
||||||
_assert (info.incoming) __LOC__ "" >>=? fun () ->
|
_assert (info.incoming) __LOC__ "" >>=? fun () ->
|
||||||
_assert (Peer_id.compare info.peer_id id2.peer_id = 0)
|
_assert (P2p_peer.Id.compare info.peer_id id2.peer_id = 0)
|
||||||
__LOC__ "" >>=? fun () ->
|
__LOC__ "" >>=? fun () ->
|
||||||
P2p_connection.kick auth_fd >>= fun () ->
|
P2p_socket.kick auth_fd >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let client _ch sched addr port =
|
let client _ch sched addr port =
|
||||||
connect sched addr port id2 >>=? fun auth_fd ->
|
connect sched addr port id2 >>=? fun auth_fd ->
|
||||||
P2p_connection.accept auth_fd encoding >>= fun conn ->
|
P2p_socket.accept auth_fd encoding >>= fun conn ->
|
||||||
_assert (is_rejected conn) __LOC__ "" >>=? fun () ->
|
_assert (is_rejected conn) __LOC__ "" >>=? fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
@ -197,13 +196,13 @@ module Kicked = struct
|
|||||||
|
|
||||||
let server _ch sched socket =
|
let server _ch sched socket =
|
||||||
accept sched socket >>=? fun (_info, auth_fd) ->
|
accept sched socket >>=? fun (_info, auth_fd) ->
|
||||||
P2p_connection.accept auth_fd encoding >>= fun conn ->
|
P2p_socket.accept auth_fd encoding >>= fun conn ->
|
||||||
_assert (Kick.is_rejected conn) __LOC__ "" >>=? fun () ->
|
_assert (Kick.is_rejected conn) __LOC__ "" >>=? fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let client _ch sched addr port =
|
let client _ch sched addr port =
|
||||||
connect sched addr port id2 >>=? fun auth_fd ->
|
connect sched addr port id2 >>=? fun auth_fd ->
|
||||||
P2p_connection.kick auth_fd >>= fun () ->
|
P2p_socket.kick auth_fd >>= fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let run _dir = run_nodes client server
|
let run _dir = run_nodes client server
|
||||||
@ -219,22 +218,22 @@ module Simple_message = struct
|
|||||||
|
|
||||||
let server ch sched socket =
|
let server ch sched socket =
|
||||||
accept sched socket >>=? fun (_info, auth_fd) ->
|
accept sched socket >>=? fun (_info, auth_fd) ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
P2p_connection.write_sync conn simple_msg >>=? fun () ->
|
P2p_socket.write_sync conn simple_msg >>=? fun () ->
|
||||||
P2p_connection.read conn >>=? fun (_msg_size, msg) ->
|
P2p_socket.read conn >>=? fun (_msg_size, msg) ->
|
||||||
_assert (MBytes.compare simple_msg2 msg = 0) __LOC__ "" >>=? fun () ->
|
_assert (MBytes.compare simple_msg2 msg = 0) __LOC__ "" >>=? fun () ->
|
||||||
sync ch >>=? fun () ->
|
sync ch >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let client ch sched addr port =
|
let client ch sched addr port =
|
||||||
connect sched addr port id2 >>=? fun auth_fd ->
|
connect sched addr port id2 >>=? fun auth_fd ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
P2p_connection.write_sync conn simple_msg2 >>=? fun () ->
|
P2p_socket.write_sync conn simple_msg2 >>=? fun () ->
|
||||||
P2p_connection.read conn >>=? fun (_msg_size, msg) ->
|
P2p_socket.read conn >>=? fun (_msg_size, msg) ->
|
||||||
_assert (MBytes.compare simple_msg msg = 0) __LOC__ "" >>=? fun () ->
|
_assert (MBytes.compare simple_msg msg = 0) __LOC__ "" >>=? fun () ->
|
||||||
sync ch >>=? fun () ->
|
sync ch >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let run _dir = run_nodes client server
|
let run _dir = run_nodes client server
|
||||||
@ -250,24 +249,24 @@ module Chunked_message = struct
|
|||||||
|
|
||||||
let server ch sched socket =
|
let server ch sched socket =
|
||||||
accept sched socket >>=? fun (_info, auth_fd) ->
|
accept sched socket >>=? fun (_info, auth_fd) ->
|
||||||
P2p_connection.accept
|
P2p_socket.accept
|
||||||
~binary_chunks_size:21 auth_fd encoding >>=? fun conn ->
|
~binary_chunks_size:21 auth_fd encoding >>=? fun conn ->
|
||||||
P2p_connection.write_sync conn simple_msg >>=? fun () ->
|
P2p_socket.write_sync conn simple_msg >>=? fun () ->
|
||||||
P2p_connection.read conn >>=? fun (_msg_size, msg) ->
|
P2p_socket.read conn >>=? fun (_msg_size, msg) ->
|
||||||
_assert (MBytes.compare simple_msg2 msg = 0) __LOC__ "" >>=? fun () ->
|
_assert (MBytes.compare simple_msg2 msg = 0) __LOC__ "" >>=? fun () ->
|
||||||
sync ch >>=? fun () ->
|
sync ch >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let client ch sched addr port =
|
let client ch sched addr port =
|
||||||
connect sched addr port id2 >>=? fun auth_fd ->
|
connect sched addr port id2 >>=? fun auth_fd ->
|
||||||
P2p_connection.accept
|
P2p_socket.accept
|
||||||
~binary_chunks_size:21 auth_fd encoding >>=? fun conn ->
|
~binary_chunks_size:21 auth_fd encoding >>=? fun conn ->
|
||||||
P2p_connection.write_sync conn simple_msg2 >>=? fun () ->
|
P2p_socket.write_sync conn simple_msg2 >>=? fun () ->
|
||||||
P2p_connection.read conn >>=? fun (_msg_size, msg) ->
|
P2p_socket.read conn >>=? fun (_msg_size, msg) ->
|
||||||
_assert (MBytes.compare simple_msg msg = 0) __LOC__ "" >>=? fun () ->
|
_assert (MBytes.compare simple_msg msg = 0) __LOC__ "" >>=? fun () ->
|
||||||
sync ch >>=? fun () ->
|
sync ch >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let run _dir = run_nodes client server
|
let run _dir = run_nodes client server
|
||||||
@ -283,22 +282,22 @@ module Oversized_message = struct
|
|||||||
|
|
||||||
let server ch sched socket =
|
let server ch sched socket =
|
||||||
accept sched socket >>=? fun (_info, auth_fd) ->
|
accept sched socket >>=? fun (_info, auth_fd) ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
P2p_connection.write_sync conn simple_msg >>=? fun () ->
|
P2p_socket.write_sync conn simple_msg >>=? fun () ->
|
||||||
P2p_connection.read conn >>=? fun (_msg_size, msg) ->
|
P2p_socket.read conn >>=? fun (_msg_size, msg) ->
|
||||||
_assert (MBytes.compare simple_msg2 msg = 0) __LOC__ "" >>=? fun () ->
|
_assert (MBytes.compare simple_msg2 msg = 0) __LOC__ "" >>=? fun () ->
|
||||||
sync ch >>=? fun () ->
|
sync ch >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let client ch sched addr port =
|
let client ch sched addr port =
|
||||||
connect sched addr port id2 >>=? fun auth_fd ->
|
connect sched addr port id2 >>=? fun auth_fd ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
P2p_connection.write_sync conn simple_msg2 >>=? fun () ->
|
P2p_socket.write_sync conn simple_msg2 >>=? fun () ->
|
||||||
P2p_connection.read conn >>=? fun (_msg_size, msg) ->
|
P2p_socket.read conn >>=? fun (_msg_size, msg) ->
|
||||||
_assert (MBytes.compare simple_msg msg = 0) __LOC__ "" >>=? fun () ->
|
_assert (MBytes.compare simple_msg msg = 0) __LOC__ "" >>=? fun () ->
|
||||||
sync ch >>=? fun () ->
|
sync ch >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let run _dir = run_nodes client server
|
let run _dir = run_nodes client server
|
||||||
@ -313,18 +312,18 @@ module Close_on_read = struct
|
|||||||
|
|
||||||
let server ch sched socket =
|
let server ch sched socket =
|
||||||
accept sched socket >>=? fun (_info, auth_fd) ->
|
accept sched socket >>=? fun (_info, auth_fd) ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
sync ch >>=? fun () ->
|
sync ch >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let client ch sched addr port =
|
let client ch sched addr port =
|
||||||
connect sched addr port id2 >>=? fun auth_fd ->
|
connect sched addr port id2 >>=? fun auth_fd ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
sync ch >>=? fun () ->
|
sync ch >>=? fun () ->
|
||||||
P2p_connection.read conn >>= fun err ->
|
P2p_socket.read conn >>= fun err ->
|
||||||
_assert (is_connection_closed err) __LOC__ "" >>=? fun () ->
|
_assert (is_connection_closed err) __LOC__ "" >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let run _dir = run_nodes client server
|
let run _dir = run_nodes client server
|
||||||
@ -339,19 +338,19 @@ module Close_on_write = struct
|
|||||||
|
|
||||||
let server ch sched socket =
|
let server ch sched socket =
|
||||||
accept sched socket >>=? fun (_info, auth_fd) ->
|
accept sched socket >>=? fun (_info, auth_fd) ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
sync ch >>=? fun ()->
|
sync ch >>=? fun ()->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let client ch sched addr port =
|
let client ch sched addr port =
|
||||||
connect sched addr port id2 >>=? fun auth_fd ->
|
connect sched addr port id2 >>=? fun auth_fd ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
sync ch >>=? fun ()->
|
sync ch >>=? fun ()->
|
||||||
Lwt_unix.sleep 0.1 >>= fun () ->
|
Lwt_unix.sleep 0.1 >>= fun () ->
|
||||||
P2p_connection.write_sync conn simple_msg >>= fun err ->
|
P2p_socket.write_sync conn simple_msg >>= fun err ->
|
||||||
_assert (is_connection_closed err) __LOC__ "" >>=? fun () ->
|
_assert (is_connection_closed err) __LOC__ "" >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let run _dir = run_nodes client server
|
let run _dir = run_nodes client server
|
||||||
@ -376,19 +375,19 @@ module Garbled_data = struct
|
|||||||
|
|
||||||
let server _ch sched socket =
|
let server _ch sched socket =
|
||||||
accept sched socket >>=? fun (_info, auth_fd) ->
|
accept sched socket >>=? fun (_info, auth_fd) ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
P2p_connection.raw_write_sync conn garbled_msg >>=? fun () ->
|
P2p_socket.raw_write_sync conn garbled_msg >>=? fun () ->
|
||||||
P2p_connection.read conn >>= fun err ->
|
P2p_socket.read conn >>= fun err ->
|
||||||
_assert (is_connection_closed err) __LOC__ "" >>=? fun () ->
|
_assert (is_connection_closed err) __LOC__ "" >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let client _ch sched addr port =
|
let client _ch sched addr port =
|
||||||
connect sched addr port id2 >>=? fun auth_fd ->
|
connect sched addr port id2 >>=? fun auth_fd ->
|
||||||
P2p_connection.accept auth_fd encoding >>=? fun conn ->
|
P2p_socket.accept auth_fd encoding >>=? fun conn ->
|
||||||
P2p_connection.read conn >>= fun err ->
|
P2p_socket.read conn >>= fun err ->
|
||||||
_assert (is_decoding_error err) __LOC__ "" >>=? fun () ->
|
_assert (is_decoding_error err) __LOC__ "" >>=? fun () ->
|
||||||
P2p_connection.close conn >>= fun _stat ->
|
P2p_socket.close conn >>= fun _stat ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
let run _dir = run_nodes client server
|
let run _dir = run_nodes client server
|
Loading…
Reference in New Issue
Block a user