Client/Endorser: simpler state

This commit is contained in:
Mathias 2018-05-22 15:22:38 +02:00 committed by Grégoire Henry
parent d33568464a
commit 8e40873a51
2 changed files with 72 additions and 55 deletions

View File

@ -106,12 +106,19 @@ let check_endorsement cctxt level pkh =
else else
return () return ()
let previously_endorsed_level cctxt pkh new_lvl =
State.get_endorsement cctxt pkh >>=? function
| None -> return false
| Some last_lvl ->
return (not Raw_level.(last_lvl < new_lvl))
let forge_endorsement (cctxt : #Proto_alpha.full) let forge_endorsement (cctxt : #Proto_alpha.full)
?(chain = `Main) block ?(chain = `Main) block ?async
~src_sk ?slots src_pk = ~src_sk ?slots src_pk =
let src_pkh = Signature.Public_key.hash src_pk in let src_pkh = Signature.Public_key.hash src_pk in
Alpha_block_services.metadata cctxt Alpha_block_services.metadata cctxt
~chain ~block () >>=? fun { protocol_data = { level = { level } } } -> ~chain ~block () >>=? fun { protocol_data = { level = { level } } } ->
check_endorsement cctxt level src_pkh >>=? fun () ->
begin begin
match slots with match slots with
| Some slots -> return slots | Some slots -> return slots
@ -122,7 +129,7 @@ let forge_endorsement (cctxt : #Proto_alpha.full)
| slots -> return slots | slots -> return slots
end >>=? fun slots -> end >>=? fun slots ->
check_endorsement cctxt level src_pkh >>=? fun () -> check_endorsement cctxt level src_pkh >>=? fun () ->
inject_endorsement cctxt ~chain block level src_sk slots src_pkh inject_endorsement cctxt ~chain ?async block level src_sk slots src_pkh
(** Worker *) (** Worker *)
@ -166,7 +173,7 @@ let drop_old_endorsement ~before state =
(fun { block } -> Fitness.compare before block.fitness <= 0) (fun { block } -> Fitness.compare before block.fitness <= 0)
state.to_endorse state.to_endorse
let schedule_endorsements (cctxt : #Proto_alpha.full) state bi = let schedule_endorsements (cctxt : #Proto_alpha.full) ~(max_past:Time.t) state bis =
let may_endorse (block: Client_baking_blocks.block_info) delegate time = let may_endorse (block: Client_baking_blocks.block_info) delegate time =
Client_keys.Public_key_hash.name cctxt delegate >>=? fun name -> Client_keys.Public_key_hash.name cctxt delegate >>=? fun name ->
lwt_log_info "May endorse block %a for %s" lwt_log_info "May endorse block %a for %s"
@ -176,61 +183,67 @@ let schedule_endorsements (cctxt : #Proto_alpha.full) state bi =
get_signing_slots cctxt b delegate level >>=? fun slots -> get_signing_slots cctxt b delegate level >>=? fun slots ->
lwt_debug "Found %d slots for %a/%s" lwt_debug "Found %d slots for %a/%s"
(List.length slots) Block_hash.pp_short block.hash name >>= fun () -> (List.length slots) Block_hash.pp_short block.hash name >>= fun () ->
previously_endorsed_level cctxt delegate level >>=? function
if Fitness.compare state.best.fitness block.fitness < 0 then begin | true ->
state.best <- block ; lwt_debug "Level %a : previously endorsed."
drop_old_endorsement ~before:block.fitness state ; Raw_level.pp level >>= return
end ; | false ->
begin try if Fitness.compare state.best.fitness block.fitness < 0 then begin
let same_slot endorsement = state.best <- block ;
endorsement.block.level = block.level && endorsement.slots = slots in drop_old_endorsement ~before:block.fitness state ;
let old = List.find same_slot state.to_endorse in end ;
if Fitness.compare old.block.fitness block.fitness < 0 begin try
then begin let same_slot endorsement =
lwt_log_info endorsement.block.level = block.level && endorsement.slots = slots in
"Schedule endorsement for block %a \ let old = List.find same_slot state.to_endorse in
(level %a, slots { %a }, time %a) (replace block %a)" if Fitness.compare old.block.fitness block.fitness < 0
Block_hash.pp_short block.hash then begin
Raw_level.pp level lwt_log_info
(Format.pp_print_list Format.pp_print_int) slots "Schedule endorsement for block %a \
Time.pp_hum time (level %a, slots { %a }, time %a) (replace block %a)"
Block_hash.pp_short old.block.hash Block_hash.pp_short block.hash
>>= fun () -> Raw_level.pp level
state.to_endorse <- (Format.pp_print_list Format.pp_print_int) slots
insert Time.pp_hum time
{ time ; delegate ; block ; slots } Block_hash.pp_short old.block.hash
(List.filter >>= fun () ->
(fun e -> not (same_slot e)) state.to_endorse <-
state.to_endorse) ; insert
return () { time ; delegate ; block ; slots }
end else begin (List.filter
lwt_debug (fun e -> not (same_slot e))
"slot { %a } : better pending endorsement" state.to_endorse) ;
(Format.pp_print_list Format.pp_print_int) slots >>= fun () -> return ()
return () end else begin
lwt_debug
"slot { %a } : better pending endorsement"
(Format.pp_print_list Format.pp_print_int) slots >>= fun () ->
return ()
end
with Not_found ->
lwt_log_info
"Schedule endorsement for block %a \
(level %a, slot { %a }, time %a)"
Block_hash.pp_short block.hash
Raw_level.pp level
(Format.pp_print_list Format.pp_print_int) slots
Time.pp_hum time >>= fun () ->
state.to_endorse <-
insert { time ; delegate ; block ; slots } state.to_endorse ;
return ()
end end
with Not_found ->
lwt_log_info
"Schedule endorsement for block %a \
(level %a, slot { %a }, time %a)"
Block_hash.pp_short block.hash
Raw_level.pp level
(Format.pp_print_list Format.pp_print_int) slots
Time.pp_hum time >>= fun () ->
state.to_endorse <-
insert { time ; delegate ; block ; slots } state.to_endorse ;
return ()
end
in in
let time = Time.(add (now ()) state.delay) in let time = Time.(add (now ()) state.delay) in
get_delegates cctxt state >>=? fun delegates -> get_delegates cctxt state >>=? fun delegates ->
ignore max_past;
iter_s iter_s
(fun delegate -> may_endorse bi delegate time) (fun delegate -> may_endorse bis delegate time)
delegates delegates
let schedule_endorsements (cctxt : #Proto_alpha.full) state bis = let schedule_endorsements (cctxt : #Proto_alpha.full) ~max_past state bis =
schedule_endorsements cctxt state bis >>= function schedule_endorsements cctxt ~max_past state bis >>= function
| Error exns -> | Error exns ->
lwt_log_error lwt_log_error
"@[<v 2>Error(s) while scheduling endorsements@,%a@]" "@[<v 2>Error(s) while scheduling endorsements@,%a@]"
@ -279,7 +292,8 @@ let compute_timeout state =
else else
Lwt_unix.sleep (Int64.to_float delay) Lwt_unix.sleep (Int64.to_float delay)
let create (cctxt : #Proto_alpha.full) ~delay contracts block_stream =
let create (cctxt : #Proto_alpha.full) ?(max_past=(Time.of_seconds 110L)) ~delay contracts block_stream =
lwt_log_info "Starting endorsement daemon" >>= fun () -> lwt_log_info "Starting endorsement daemon" >>= fun () ->
Lwt_stream.get block_stream >>= function Lwt_stream.get block_stream >>= function
| None | Some (Error _) -> | None | Some (Error _) ->
@ -303,7 +317,7 @@ let create (cctxt : #Proto_alpha.full) ~delay contracts block_stream =
| `Hash (Some (Ok bi)) -> | `Hash (Some (Ok bi)) ->
Lwt.cancel timeout ; Lwt.cancel timeout ;
last_get_block := None ; last_get_block := None ;
schedule_endorsements cctxt state bi >>= fun () -> schedule_endorsements cctxt ~max_past state bi >>= fun () ->
worker_loop () worker_loop ()
| `Timeout -> | `Timeout ->
begin begin
@ -316,5 +330,6 @@ let create (cctxt : #Proto_alpha.full) ~delay contracts block_stream =
Lwt.return_unit Lwt.return_unit
end >>= fun () -> end >>= fun () ->
worker_loop () in worker_loop () in
schedule_endorsements cctxt state head >>= fun () ->
schedule_endorsements cctxt ~max_past state head >>= fun () ->
worker_loop () worker_loop ()

View File

@ -14,6 +14,7 @@ val forge_endorsement:
#Proto_alpha.full -> #Proto_alpha.full ->
?chain:Chain_services.chain -> ?chain:Chain_services.chain ->
Block_services.block -> Block_services.block ->
?async: bool ->
src_sk:Client_keys.sk_uri -> src_sk:Client_keys.sk_uri ->
?slots:int list -> ?slots:int list ->
public_key -> public_key ->
@ -21,6 +22,7 @@ val forge_endorsement:
val create : val create :
#Proto_alpha.full -> #Proto_alpha.full ->
?max_past:Time.t ->
delay:int -> delay:int ->
public_key_hash list -> public_key_hash list ->
Client_baking_blocks.block_info tzresult Lwt_stream.t -> unit Lwt.t Client_baking_blocks.block_info tzresult Lwt_stream.t -> unit Lwt.t