2016-09-08 21:13:10 +04:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
2017-11-14 03:36:14 +04:00
|
|
|
(* Copyright (c) 2014 - 2017. *)
|
2016-09-08 21:13:10 +04:00
|
|
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
|
|
|
type operation = {
|
|
|
|
hash: Operation_hash.t ;
|
2017-04-19 23:46:10 +04:00
|
|
|
content: Operation.t option
|
2016-09-08 21:13:10 +04:00
|
|
|
}
|
|
|
|
|
2016-12-03 16:05:02 +04:00
|
|
|
let monitor cctxt ?contents ?check () =
|
2017-04-05 01:35:41 +04:00
|
|
|
Client_node_rpcs.Operations.monitor cctxt ?contents () >>=? fun ops_stream ->
|
2016-09-08 21:13:10 +04:00
|
|
|
let convert ops =
|
2017-04-05 01:35:41 +04:00
|
|
|
map_s
|
2017-03-30 16:31:16 +04:00
|
|
|
(fun (hash, op) ->
|
|
|
|
match op with
|
2017-04-05 01:35:41 +04:00
|
|
|
| None -> return { hash; content = None }
|
2017-04-19 21:21:23 +04:00
|
|
|
| Some (op : Operation.raw) ->
|
2017-03-30 16:31:16 +04:00
|
|
|
Client_proto_rpcs.Helpers.Parse.operations cctxt
|
2017-04-05 01:35:41 +04:00
|
|
|
`Prevalidation ?check [op] >>=? function
|
|
|
|
| [proto] ->
|
2017-04-19 21:21:23 +04:00
|
|
|
return { hash ; content = Some proto }
|
2017-04-05 01:35:41 +04:00
|
|
|
| _ -> failwith "Error while parsing the operation")
|
2017-11-13 19:34:00 +04:00
|
|
|
(List.concat ops)
|
2016-09-08 21:13:10 +04:00
|
|
|
in
|
2017-04-05 01:35:41 +04:00
|
|
|
return (Lwt_stream.map_s convert ops_stream)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
|
|
|
|
type valid_endorsement = {
|
|
|
|
hash: Operation_hash.t ;
|
|
|
|
source: public_key_hash ;
|
|
|
|
block: Block_hash.t ;
|
|
|
|
slots: int list ;
|
|
|
|
}
|
|
|
|
|
2017-04-27 03:01:05 +04:00
|
|
|
(*
|
2017-04-19 21:21:23 +04:00
|
|
|
let filter_valid_endorsement cctxt ({ hash ; content } : operation) =
|
2016-09-08 21:13:10 +04:00
|
|
|
let open Tezos_context in
|
|
|
|
match content with
|
|
|
|
| None
|
2017-04-19 21:21:23 +04:00
|
|
|
| Some { contents = Anonymous_operations _ }
|
|
|
|
| Some { contents = Sourced_operations (Dictator_operation _ ) }
|
|
|
|
| Some { contents = Sourced_operations (Manager_operations _ ) } ->
|
2016-09-08 21:13:10 +04:00
|
|
|
Lwt.return_none
|
2017-04-19 21:21:23 +04:00
|
|
|
| Some { shell = {net_id} ;
|
|
|
|
contents =
|
|
|
|
Sourced_operations (Delegate_operations { source ; operations }) } ->
|
2017-02-28 05:56:40 +04:00
|
|
|
let source = Ed25519.Public_key.hash source in
|
2016-09-08 21:13:10 +04:00
|
|
|
let endorsements =
|
|
|
|
Utils.unopt_list @@ List.map
|
|
|
|
(function
|
|
|
|
| Endorsement { block ; slot } -> Some (block, slot)
|
|
|
|
| _ -> None)
|
|
|
|
operations in
|
|
|
|
match endorsements with
|
|
|
|
| [] -> Lwt.return_none
|
|
|
|
| ((block, _) :: _) as slots ->
|
|
|
|
try
|
|
|
|
let slots =
|
|
|
|
List.map
|
|
|
|
(fun (block', slot) ->
|
|
|
|
if not (Block_hash.equal block block') then raise Not_found ;
|
|
|
|
slot)
|
|
|
|
slots in
|
|
|
|
(* Ensure thath the block has been previously validated by
|
|
|
|
the node. This might took some times... *)
|
2016-12-03 16:05:02 +04:00
|
|
|
Client_node_rpcs.validate_block cctxt net_id block >>= function
|
2016-09-08 21:13:10 +04:00
|
|
|
| Error error ->
|
|
|
|
lwt_log_info
|
|
|
|
"@[<v 2>Found endorsement for an invalid block@,%a@["
|
|
|
|
pp_print_error error >>= fun () ->
|
|
|
|
Lwt.return_none
|
|
|
|
| Ok () ->
|
2017-04-19 23:46:10 +04:00
|
|
|
Client_node_rpcs.Blocks.preapply
|
|
|
|
cctxt (`Hash block) [Client_node_rpcs.Hash hash] >>= function
|
2016-09-08 21:13:10 +04:00
|
|
|
| Ok _ ->
|
|
|
|
Lwt.return (Some { hash ; source ; block ; slots })
|
|
|
|
| Error error ->
|
|
|
|
lwt_log_error
|
|
|
|
"@[<v 2>Error while prevalidating endorsements@,%a@["
|
|
|
|
pp_print_error error >>= fun () ->
|
|
|
|
Lwt.return_none
|
|
|
|
with Not_found -> Lwt.return_none
|
|
|
|
|
2016-12-03 16:05:02 +04:00
|
|
|
let monitor_endorsement cctxt =
|
2017-04-05 01:35:41 +04:00
|
|
|
monitor cctxt ~contents:true ~check:true () >>=? fun ops_stream ->
|
2016-09-08 21:13:10 +04:00
|
|
|
let endorsement_stream, push = Lwt_stream.create () in
|
2017-01-14 16:12:55 +04:00
|
|
|
Lwt.async begin fun () ->
|
|
|
|
Lwt_stream.closed ops_stream >|= fun () -> push None
|
2017-02-16 00:18:48 +04:00
|
|
|
end ;
|
2017-01-14 16:12:55 +04:00
|
|
|
Lwt.async begin fun () ->
|
|
|
|
Lwt_stream.iter_p
|
2017-04-05 01:35:41 +04:00
|
|
|
(fun ops ->
|
|
|
|
match ops with
|
|
|
|
| Error _ as err ->
|
|
|
|
push (Some err) ;
|
|
|
|
Lwt.return_unit
|
|
|
|
| Ok ops ->
|
|
|
|
Lwt_list.iter_p
|
|
|
|
(fun e ->
|
|
|
|
filter_valid_endorsement cctxt e >>= function
|
|
|
|
| None -> Lwt.return_unit
|
|
|
|
| Some e -> push (Some (Ok e)) ; Lwt.return_unit)
|
|
|
|
ops)
|
2017-01-14 16:12:55 +04:00
|
|
|
ops_stream
|
|
|
|
end ;
|
2017-04-05 01:35:41 +04:00
|
|
|
return endorsement_stream
|
2017-04-27 03:01:05 +04:00
|
|
|
*)
|
|
|
|
|
|
|
|
(* Temporary desactivate the monitoring of endorsement:
|
|
|
|
too slow for now. *)
|
|
|
|
let monitor_endorsement _ =
|
|
|
|
let stream, _push = Lwt_stream.create () in
|
|
|
|
return stream
|
|
|
|
|