diff --git a/devtools/testnet_experiment_tools/tool_023_PtSeouLo.ml b/devtools/testnet_experiment_tools/tool_023_PtSeouLo.ml index 6249f3c50bb7d278d88348ebca20c121bcb48c12..96cb4eb890a0c4496523b6937e83ee998b82d042 100644 --- a/devtools/testnet_experiment_tools/tool_023_PtSeouLo.ml +++ b/devtools/testnet_experiment_tools/tool_023_PtSeouLo.ml @@ -209,7 +209,7 @@ let load_client_context (cctxt : ctxt_kind) = let get_delegates (cctxt : Protocol_client_context.full) = let proj_delegate (alias, public_key_hash, public_key, secret_key_uri) = Baking_state_types.Key.make - ~alias:(Some alias) + ~alias ~public_key_hash ~public_key ~secret_key_uri @@ -220,10 +220,8 @@ let get_delegates (cctxt : Protocol_client_context.full) = let* () = Tezos_signer_backends.Encrypted.decrypt_list cctxt - (List.filter_map - (function - | {Baking_state_types.Key.alias = Some alias; _} -> Some alias - | _ -> None) + (List.map + (function {Baking_state_types.Key.alias; _} -> alias) delegates) in let delegates_no_duplicates = List.sort_uniq compare delegates in diff --git a/devtools/testnet_experiment_tools/tool_alpha.ml b/devtools/testnet_experiment_tools/tool_alpha.ml index aa8325f9b5d9b5d3fb5eefa596686efe6b2b9b64..a23a16b73475841e01e6521d4980c79549632946 100644 --- a/devtools/testnet_experiment_tools/tool_alpha.ml +++ b/devtools/testnet_experiment_tools/tool_alpha.ml @@ -208,7 +208,7 @@ let load_client_context (cctxt : ctxt_kind) = let get_delegates (cctxt : Protocol_client_context.full) = let proj_delegate (alias, public_key_hash, public_key, secret_key_uri) = Baking_state_types.Key.make - ~alias:(Some alias) + ~alias ~public_key_hash ~public_key ~secret_key_uri @@ -219,10 +219,8 @@ let get_delegates (cctxt : Protocol_client_context.full) = let* () = Tezos_signer_backends.Encrypted.decrypt_list cctxt - (List.filter_map - (function - | {Baking_state_types.Key.alias = Some alias; _} -> Some alias - | _ -> None) + (List.map + (function {Baking_state_types.Key.alias; _} -> alias) delegates) in let delegates_no_duplicates = List.sort_uniq compare delegates in diff --git a/docs/CHANGES.rst b/docs/CHANGES.rst index d7bf646881b8997f98e30518bb9b451b9f89774b..d698deb410c044f257a9e37a0eb1c36b9064e6f7 100644 --- a/docs/CHANGES.rst +++ b/docs/CHANGES.rst @@ -138,6 +138,10 @@ Baker Please remove it from your CLI and configuration, as the support will be removed in the next release. (MR :gl:`!18138`) +- Updates many baker events to better display information related to + consensus operations, delegates, and keys. Note that these changes + may break automatic event parsing. (MR :gl:`!18330`) + Agnostic Baker -------------- diff --git a/src/lib_crypto/signature_v1.ml b/src/lib_crypto/signature_v1.ml index 345909694c2b3d72ab0a1e98ccbe71e1fdc1a21f..eda2ee432446dc1bea042608562524f17f96f0e9 100644 --- a/src/lib_crypto/signature_v1.ml +++ b/src/lib_crypto/signature_v1.ml @@ -62,6 +62,10 @@ module Public_key_hash = struct let title = "A Ed25519, Secp256k1, P256, or BLS public key hash" + let is_bls : t -> bool = function + | Bls _ -> true + | Ed25519 _ | Secp256k1 _ | P256 _ -> false + type Base58.data += Data of t (* unused *) let b58check_encoding = diff --git a/src/lib_crypto/signature_v1.mli b/src/lib_crypto/signature_v1.mli index 22f1856bc0bc57cd3d54a4063477d5c2247f0d47..3e152ac2edae343059391783121c344bb1b58827 100644 --- a/src/lib_crypto/signature_v1.mli +++ b/src/lib_crypto/signature_v1.mli @@ -72,6 +72,12 @@ include and type prefix := prefix and type t = signature +module Public_key_hash : sig + include module type of Public_key_hash + + val is_bls : t -> bool +end + (** [append sk buf] is the concatenation of [buf] and the serialization of the signature of [buf] signed by [sk]. *) val append : ?watermark:watermark -> secret_key -> Bytes.t -> Bytes.t diff --git a/src/lib_crypto/signature_v2.ml b/src/lib_crypto/signature_v2.ml index 1982945d8845105a07af0eeab62657794c5e4ec5..615f2540747ccc9c27f14da915f5297cf029d2db 100644 --- a/src/lib_crypto/signature_v2.ml +++ b/src/lib_crypto/signature_v2.ml @@ -42,6 +42,10 @@ module Public_key_hash = struct let title = "A Ed25519, Secp256k1, P256, or BLS public key hash" + let is_bls : t -> bool = function + | Bls _ -> true + | Ed25519 _ | Secp256k1 _ | P256 _ -> false + type Base58.data += Data of t (* unused *) let b58check_encoding = diff --git a/src/lib_crypto/signature_v2.mli b/src/lib_crypto/signature_v2.mli index 8d436671eab15a0052d7b2acab0e8f7cfd576c5f..5209c2efc72e7265d430822da318856c17ff67f6 100644 --- a/src/lib_crypto/signature_v2.mli +++ b/src/lib_crypto/signature_v2.mli @@ -53,6 +53,12 @@ include and type prefix := prefix and type t = signature +module Public_key_hash : sig + include module type of Public_key_hash + + val is_bls : t -> bool +end + (** [append sk buf] is the concatenation of [buf] and the serialization of the signature of [buf] signed by [sk]. *) val append : ?watermark:watermark -> secret_key -> Bytes.t -> Bytes.t diff --git a/src/proto_023_PtSeouLo/lib_delegate/baking_actions.ml b/src/proto_023_PtSeouLo/lib_delegate/baking_actions.ml index 6288dc4f8cd68d6576293b1061b4c6656453d2b0..5a8e2e58485475a0645a7a762ac109f202ff3254 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/baking_actions.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/baking_actions.ml @@ -562,10 +562,11 @@ let may_get_dal_content state consensus_vote = ( Raw_level.to_int32 vote_consensus_content.level, vote_consensus_content.round ) in + let delegate_id = Delegate.delegate_id delegate in let promise_opt = List.assoc_opt ~equal:Delegate_id.equal - delegate.delegate_id + delegate_id state.level_state.dal_attestable_slots in match promise_opt with @@ -585,7 +586,7 @@ let may_get_dal_content state consensus_vote = Lwt.return (`RPC_result tz_res)); ] in - process_dal_rpc_result state delegate.delegate_id level round res + process_dal_rpc_result state delegate_id level round res let is_authorized (global_state : global_state) highwatermarks consensus_vote = let {delegate; vote_consensus_content; _} = consensus_vote in @@ -696,48 +697,56 @@ let forge_and_sign_consensus_vote global_state ~branch unsigned_consensus_vote : | Attestation -> Operation.(to_watermark (Attestation chain_id)) in let bls_mode = - match delegate.consensus_key.public_key with - | Bls _ -> global_state.constants.parametric.aggregate_attestation - | _ -> false + Key.is_bls delegate.consensus_key + && global_state.constants.parametric.aggregate_attestation in - let* Contents_list contents, companion_key_opt = + let* dal_content, companion_key_opt = match vote_kind with | Preattestation -> - return - (Contents_list (Single (Preattestation vote_consensus_content)), None) - | Attestation -> - let* dal_content, companion_key_opt = - if not bls_mode then return (dal_content, None) - else - match dal_content with - | None -> return (dal_content, None) - | Some _ -> ( - match delegate.companion_key with - | None -> - let*! () = - Events.( - emit - missing_companion_key_for_dal_with_bls - ( delegate.delegate_id, - Raw_level.to_int32 vote_consensus_content.level )) - in - return (None, None) - | Some companion_key -> return (dal_content, Some companion_key) - ) - in - return - ( Contents_list - (Single - (Attestation - {consensus_content = vote_consensus_content; dal_content})), - companion_key_opt ) + (* Preattestations cannot have a dal_content and do not use + the companion key. *) + return (None, None) + | Attestation -> ( + if not bls_mode then + (* If not in BLS mode, leave the dal_content unchanged and do + not use the companion key. *) + return (dal_content, None) + else if Option.is_none dal_content then + (* No dal_content: the companion key will not be used. *) + return (dal_content, None) + else + match delegate.companion_key with + | None -> + (* There is an available dal_content, but the BLS + consensus key does not have an associated companion + key (whether because the delegate has not registered + any companion key, or because it has not been + provided to the baker): signing an attestation with + DAL is not possible. Set the dal_content to None and + issue a warning. *) + let*! () = + Events.( + emit + missing_companion_key_for_dal_with_bls + ( Delegate.delegate_id delegate, + Raw_level.to_int32 vote_consensus_content.level )) + in + return (None, None) + | Some companion_key -> + (* We have everything we need to issue a BLS attestation with DAL. *) + return (dal_content, Some companion_key)) in - let signing_request = + let (Contents_list contents as packed_contents_list) = match vote_kind with - | Preattestation -> `Preattestation - | Attestation -> `Attestation + | Preattestation -> + Contents_list (Single (Preattestation vote_consensus_content)) + | Attestation -> + Contents_list + (Single + (Attestation + {consensus_content = vote_consensus_content; dal_content})) in - let unsigned_operation = (shell, Contents_list contents) in + let unsigned_operation = (shell, packed_contents_list) in let encoding = if bls_mode then Operation.bls_mode_unsigned_encoding else Operation.unsigned_encoding @@ -745,6 +754,11 @@ let forge_and_sign_consensus_vote global_state ~branch unsigned_consensus_vote : let unsigned_operation_bytes = Data_encoding.Binary.to_bytes_exn encoding unsigned_operation in + let signing_request = + match vote_kind with + | Preattestation -> `Preattestation + | Attestation -> `Attestation + in let sk_consensus_uri = delegate.consensus_key.secret_key_uri in let* consensus_sig = sign @@ -763,7 +777,7 @@ let forge_and_sign_consensus_vote global_state ~branch unsigned_consensus_vote : companion_key_opt *) return consensus_sig | Some _, None -> - (* dal_content has been discarded from contents *) + (* only possible in non-BLS mode *) return consensus_sig | Some {attestation = dal_attestation}, Some companion_key -> ( let sk_companion_uri = companion_key.secret_key_uri in @@ -818,6 +832,9 @@ let forge_and_sign_consensus_vote global_state ~branch unsigned_consensus_vote : in let protocol_data = Operation_data {contents; signature = Some signature} in let signed_operation : Operation.packed = {shell; protocol_data} in + (* Also update unsigned_consensus_vote: dal_content may have been + set to None. *) + let unsigned_consensus_vote = {unsigned_consensus_vote with dal_content} in return {unsigned_consensus_vote; signed_operation} let sign_consensus_votes (global_state : global_state) @@ -835,7 +852,7 @@ let sign_consensus_votes (global_state : global_state) List.filter_map_es (fun ({delegate; vote_kind; vote_consensus_content; _} as unsigned_consensus_vote) -> - let*! () = Events.(emit signing_consensus_vote (vote_kind, delegate)) in + let*! () = Events.emit_signing_consensus_op unsigned_consensus_vote in let*! signed_consensus_vote_r = (forge_and_sign_consensus_vote global_state @@ -876,11 +893,6 @@ let inject_consensus_vote state (signed_consensus_vote : signed_consensus_vote) let chain_id = state.global_state.chain_id in let unsigned_consensus_vote = signed_consensus_vote.unsigned_consensus_vote in let delegate = unsigned_consensus_vote.delegate in - let vote_consensus_content = unsigned_consensus_vote.vote_consensus_content in - let level, round = - ( Raw_level.to_int32 vote_consensus_content.level, - vote_consensus_content.round ) - in protect ~on_error:(fun err -> let*! () = @@ -905,10 +917,7 @@ let inject_consensus_vote state (signed_consensus_vote : signed_consensus_vote) | Attestation -> "attestation"))]) in let*! () = - Events.( - emit - consensus_vote_injected - (unsigned_consensus_vote.vote_kind, oph, delegate, level, round)) + Events.emit_consensus_op_injected unsigned_consensus_vote oph in return_unit) diff --git a/src/proto_023_PtSeouLo/lib_delegate/baking_commands.ml b/src/proto_023_PtSeouLo/lib_delegate/baking_commands.ml index c2bb33b27851a5c87f5e4e3294cdf080c3138198..7e2b6e981fb974e3e6c2961f483ab4ce2f2ac334 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/baking_commands.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/baking_commands.ml @@ -219,7 +219,7 @@ let get_delegates (cctxt : Protocol_client_context.full) let open Lwt_result_syntax in let proj_delegate (alias, public_key_hash, public_key, secret_key_uri) = Baking_state_types.Key.make - ~alias:(Some alias) + ~alias ~public_key_hash ~public_key ~secret_key_uri @@ -239,10 +239,8 @@ let get_delegates (cctxt : Protocol_client_context.full) let* () = Tezos_signer_backends.Encrypted.decrypt_list cctxt - (List.filter_map - (function - | {Baking_state_types.Key.alias = Some alias; _} -> Some alias - | _ -> None) + (List.map + (function {Baking_state_types.Key.alias; _} -> alias) delegates) in let delegates_no_duplicates = List.sort_uniq compare delegates in diff --git a/src/proto_023_PtSeouLo/lib_delegate/baking_events.ml b/src/proto_023_PtSeouLo/lib_delegate/baking_events.ml index a5c510d7f92e24dc5b63174058fc43f898189def..abc3bb75ffc5f5b8cfa7649d5d16a83e86319331 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/baking_events.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/baking_events.ml @@ -25,6 +25,8 @@ open Protocol open Alpha_context +open Baking_state_types +open Baking_state let section = [Protocol.name; "baker"] @@ -34,6 +36,139 @@ let pp_int64 fmt n = Format.fprintf fmt "%Ld" n let waiting_color = Internal_event.Magenta +module Op_info_for_logging = struct + type kind = Preattestation | Attestation_without_dal | Attestation_with_dal + + type t = { + kind : kind; + level : Protocol.Alpha_context.Raw_level.t; + round : Protocol.Alpha_context.Round.t; + delegate : Delegate.t; + } + + let pp_kind fmt = function + | Preattestation -> Format.fprintf fmt "preattestation" + | Attestation_without_dal -> Format.fprintf fmt "attestation (without DAL)" + | Attestation_with_dal -> Format.fprintf fmt "attestation (with DAL)" + + let pp fmt {kind; delegate; level; round} = + let companion_key_is_relevant = + match kind with + | Attestation_with_dal -> Key.is_bls delegate.consensus_key + | Attestation_without_dal | Preattestation -> false + in + Format.fprintf + fmt + "%a@ for level %a, round %a@ for delegate@ %a" + pp_kind + kind + Protocol.Alpha_context.Raw_level.pp + level + Protocol.Alpha_context.Round.pp + round + (if companion_key_is_relevant then Delegate.pp + else Delegate.pp_without_companion_key) + delegate + + let kind_encoding = + Data_encoding.string_enum + [ + ("preattestation", Preattestation); + ("attestation_without_dal", Attestation_without_dal); + ("attestation_with_dal", Attestation_with_dal); + ] + + let encoding : t Data_encoding.t = + let open Data_encoding in + conv + (fun {kind; level; round; delegate} -> (kind, level, round, delegate)) + (fun (kind, level, round, delegate) -> {kind; level; round; delegate}) + (obj4 + (req "op_kind" kind_encoding) + (req "level" Protocol.Alpha_context.Raw_level.encoding) + (req "round" Protocol.Alpha_context.Round.encoding) + (req "delegate" Delegate.encoding_for_logging__cannot_decode)) + + let of_unsigned_consensus_vote + (unsigned_consensus_vote : unsigned_consensus_vote) = + let kind = + match unsigned_consensus_vote.vote_kind with + | Preattestation -> Preattestation + | Attestation -> + if Option.is_some unsigned_consensus_vote.dal_content then + Attestation_with_dal + else Attestation_without_dal + in + { + kind; + delegate = unsigned_consensus_vote.delegate; + level = unsigned_consensus_vote.vote_consensus_content.level; + round = unsigned_consensus_vote.vote_consensus_content.round; + } +end + +let pp_unsigned_consensus_vote fmt unsigned_consensus_vote = + Op_info_for_logging.( + pp fmt (of_unsigned_consensus_vote unsigned_consensus_vote)) + +let pp_signed_consensus_vote fmt {unsigned_consensus_vote; _} = + pp_unsigned_consensus_vote fmt unsigned_consensus_vote + +let pp_forge_event fmt = function + | Block_ready {signed_block_header; round; delegate; _} -> + Format.fprintf + fmt + "block ready@ at level %ld, round %a@ for@ delegate@ %a " + signed_block_header.shell.level + Round.pp + round + Delegate.pp_without_companion_key + delegate + | Preattestation_ready signed_op | Attestation_ready signed_op -> + Format.fprintf + fmt + "operation ready:@ %a" + pp_signed_consensus_vote + signed_op + +let pp_event fmt = + let open Baking_state in + function + | New_valid_proposal proposal -> + Format.fprintf + fmt + "new valid proposal received: %a" + pp_block_info + proposal.block + | New_head_proposal proposal -> + Format.fprintf + fmt + "new head proposal received: %a" + pp_block_info + proposal.block + | Prequorum_reached (candidate, preattestations) -> + Format.fprintf + fmt + "prequorum reached with %d preattestations for %a at round %a" + (List.length preattestations) + Block_hash.pp + candidate.Operation_worker.hash + Round.pp + candidate.round_watched + | Quorum_reached (candidate, attestations) -> + Format.fprintf + fmt + "quorum reached with %d attestations for %a at round %a" + (List.length attestations) + Block_hash.pp + candidate.Operation_worker.hash + Round.pp + candidate.round_watched + | New_forge_event forge_event -> + Format.fprintf fmt "new forge event: %a" pp_forge_event forge_event + | Timeout kind -> + Format.fprintf fmt "timeout reached: %a" pp_timeout_kind kind + module Commands = struct include Internal_event.Simple @@ -147,11 +282,10 @@ module State_transitions = struct () let new_forge_event = - let open Baking_state in declare_1 ~section ~name:"new_forge_event" - ~level:Notice + ~level:Info ~msg:"received new forge event: {event}" ~pp1:pp_forge_event ("event", forge_event_encoding_for_logging__cannot_decode) @@ -185,9 +319,8 @@ module State_transitions = struct ("level", Data_encoding.int32) ~pp3:Round.pp ("next_round", Round.encoding) - ~pp4:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp4:Delegate.pp_without_companion_key + ("delegate", Delegate.encoding_for_logging__cannot_decode) let new_head_while_waiting_for_qc = declare_0 @@ -381,10 +514,13 @@ module State_transitions = struct ~section ~name:"preparing_fresh_block" ~level:Info - ~msg:"preparing fresh block for {delegate} at round {round}" - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~msg:"preparing fresh block at round {round}{delegate}" + ~pp1:(fun fmt -> + Format.fprintf + fmt + "@ for@ delegate@ %a" + Delegate.pp_without_companion_key) + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:Round.pp ("round", Round.encoding) @@ -437,10 +573,10 @@ module State_transitions = struct ~name:"step_current_phase" ~level:Debug ~msg:"automaton step: current phase {phase}, event {event}" - ~pp1:Baking_state.pp_phase - ("phase", Baking_state.phase_encoding) - ~pp2:Baking_state.pp_event - ("event", Baking_state.event_encoding_for_logging__cannot_decode) + ~pp1:pp_phase + ("phase", phase_encoding) + ~pp2:pp_event + ("event", event_encoding_for_logging__cannot_decode) let discarding_preattestation = declare_3 @@ -450,9 +586,8 @@ module State_transitions = struct ~msg: "discarding outdated preattestation for {delegate} at level {level}, \ round {round}" - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:pp_int32 ("level", Data_encoding.int32) ~pp3:Round.pp @@ -466,9 +601,8 @@ module State_transitions = struct ~msg: "discarding outdated attestation for {delegate} at level {level}, \ round {round}" - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:pp_int32 ("level", Data_encoding.int32) ~pp3:Round.pp @@ -483,9 +617,8 @@ module State_transitions = struct "discarding preattestation for {delegate} with payload {payload} at \ level {level}, round {round} where the prequorum was locked on a \ different payload {state_payload}." - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:Block_payload_hash.pp ("payload", Block_payload_hash.encoding) ~pp3:pp_int32 @@ -503,9 +636,8 @@ module State_transitions = struct ~msg: "discarding attestation for {delegate} at level {level}, round {round} \ where no prequorum was reached." - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:pp_int32 ("level", Data_encoding.int32) ~pp3:Round.pp @@ -520,9 +652,8 @@ module State_transitions = struct "discarding attestation for {delegate} with payload {payload} at level \ {level}, round {round} where the prequorum was on a different payload \ {state_payload}." - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:Block_payload_hash.pp ("payload", Block_payload_hash.encoding) ~pp3:pp_int32 @@ -542,8 +673,8 @@ module State_transitions = struct {phase} phase." ~pp1:Block_hash.pp ("candidate", Block_hash.encoding) - ~pp2:Baking_state.pp_phase - ("phase", Baking_state.phase_encoding) + ~pp2:pp_phase + ("phase", phase_encoding) let discarding_unexpected_quorum_reached = declare_2 @@ -555,8 +686,8 @@ module State_transitions = struct phase." ~pp1:Block_hash.pp ("candidate", Block_hash.encoding) - ~pp2:Baking_state.pp_phase - ("phase", Baking_state.phase_encoding) + ~pp2:pp_phase + ("phase", phase_encoding) end module Node_rpc = struct @@ -591,27 +722,21 @@ module Node_rpc = struct ("chain_id", Chain_id.encoding) end -module Delegates = struct +module Launch = struct include Internal_event.Simple - let section = section @ ["delegates"] + let section = section @ ["launch"] - let delegates_used = + let keys_used = declare_1 ~section ~alternative_color:Internal_event.Cyan - ~name:"delegates_used" + ~name:"keys_used" ~level:Notice - ~msg:"Baker will run with the following delegates:{delegates}" - ~pp1:(fun ppf delegates -> - Format.fprintf - ppf - "@[@,%a@]" - Format.(pp_print_list ~pp_sep:pp_print_cut Baking_state_types.Key.pp) - delegates) - ( "delegates", - Data_encoding.list - Baking_state_types.Key.encoding_for_logging__cannot_decode ) + ~msg:"Baker will run with the following keys:{keys}" + ~pp1:(fun ppf keys -> + Format.fprintf ppf "@[@,%a@]" (Format.pp_print_list Key.pp) keys) + ("keys", Data_encoding.list Key.encoding_for_logging__cannot_decode) end module Scheduling = struct @@ -656,17 +781,20 @@ module Scheduling = struct ~name:"next_potential_slot" ~level:Info ~msg: - "next potential slot for level {level} is at round {round} at \ - {timestamp} for {delegate}" + "next potential slot for level {level} is at round \ + {round}{timestamp}{delegate}" ~pp1:pp_int32 ("level", Data_encoding.int32) ~pp2:Round.pp ("round", Round.encoding) - ~pp3:Timestamp.pp + ~pp3:(fun fmt -> Format.fprintf fmt "@ at %a" Timestamp.pp) ("timestamp", Timestamp.encoding) - ~pp4:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp4:(fun fmt -> + Format.fprintf + fmt + "@ for@ delegate@ %a" + Delegate.pp_without_companion_key) + ("delegate", Delegate.encoding_for_logging__cannot_decode) let waiting_end_of_round = declare_3 @@ -799,12 +927,12 @@ module Lib = struct ~name:"attempting_preattest_proposal" ~level:Debug ~msg:"attempting to {action} proposal {proposal}" - ("action", Baking_state.consensus_vote_kind_encoding) + ("action", consensus_vote_kind_encoding) ~pp1:(fun fmt -> function - | Baking_state.Preattestation -> Format.fprintf fmt "preattest" + | Preattestation -> Format.fprintf fmt "preattest" | Attestation -> Format.fprintf fmt "attest") - ("proposal", Baking_state.proposal_encoding) - ~pp2:Baking_state.pp_proposal + ("proposal", proposal_encoding) + ~pp2:pp_proposal let waiting_block_timestamp = declare_2 @@ -832,11 +960,10 @@ module Actions = struct ~msg: "unable to sign {vote_kind} for {delegate} at level {level}, round \ {round} -- {trace}" - ~pp1:Baking_state.pp_consensus_vote_kind - ("vote_kind", Baking_state.consensus_vote_kind_encoding) - ~pp2:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:pp_consensus_vote_kind + ("vote_kind", consensus_vote_kind_encoding) + ~pp2:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp3:pp_int32 ("level", Data_encoding.int32) ~pp4:Round.pp @@ -850,7 +977,7 @@ module Actions = struct ~name:"failed_to_get_attestations" ~level:Error ~msg:"unable to get DAL attestation for {delegate} -- {trace}" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) ~pp2:Error_monad.pp_print_trace ("trace", Error_monad.trace_encoding) @@ -860,7 +987,7 @@ module Actions = struct ~name:"failed_to_get_attestations_in_time" ~level:Error ~msg:"unable to get DAL attestation for {delegate} in time" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) let failed_to_inject_consensus_vote = declare_3 @@ -868,11 +995,10 @@ module Actions = struct ~name:"failed_to_inject_consensus_vote" ~level:Error ~msg:"failed to inject {vote_kind} for {delegate} -- {trace}" - ~pp1:Baking_state.pp_consensus_vote_kind - ("vote_kind", Baking_state.consensus_vote_kind_encoding) - ~pp2:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:pp_consensus_vote_kind + ("vote_kind", consensus_vote_kind_encoding) + ~pp2:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp3:Error_monad.pp_print_trace ("trace", Error_monad.trace_encoding) @@ -882,9 +1008,8 @@ module Actions = struct ~name:"failed_to_forge_block" ~level:Error ~msg:"failed to forge block for {delegate} -- {trace}" - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:Error_monad.pp_print_trace ("trace", Error_monad.trace_encoding) @@ -899,25 +1024,23 @@ module Actions = struct ("level", Data_encoding.int32) ("round", Round.encoding) - let consensus_vote_injected = - declare_5 + let consensus_op_injected = + declare_2 ~section - ~name:"consensus_vote_injected" + ~name:"consensus_operation_injected" ~level:Notice - ~msg: - "injected {vote_kind} {ophash} for {delegate} for level {level}, round \ - {round}" - ~pp1:Baking_state.pp_consensus_vote_kind - ("vote_kind", Baking_state.consensus_vote_kind_encoding) - ~pp2:Operation_hash.pp - ("ophash", Operation_hash.encoding) - ~pp3:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) - ~pp4:pp_int32 - ("level", Data_encoding.int32) - ~pp5:Round.pp - ("round", Round.encoding) + ~msg:"injected {operation_information}{operation_hash}" + ~pp1:Op_info_for_logging.pp + ("operation_information", Op_info_for_logging.encoding) + ~pp2:(fun fmt oph -> + Format.fprintf fmt "@ (operation hash: %a)" Operation_hash.pp oph) + ("operation_hash", Operation_hash.encoding) + + let emit_consensus_op_injected unsigned_consensus_op ophash = + emit + consensus_op_injected + ( Op_info_for_logging.of_unsigned_consensus_vote unsigned_consensus_op, + ophash ) let attach_dal_attestation = declare_5 @@ -928,7 +1051,7 @@ module Actions = struct "ready to attach DAL attestation for level {attestation_level}, round \ {round}, with bitset {bitset} for {delegate} to attest slots \ published at level {published_level}" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) ~pp2:Z.pp_print ("bitset", Data_encoding.n) ("published_level", Data_encoding.int32) @@ -941,7 +1064,7 @@ module Actions = struct ~name:"not_in_dal_committee" ~level:Notice ~msg:"{delegate} has no assigned DAL shards at level {attestation_level}" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) ("attestation_level", Data_encoding.int32) let missing_companion_key_for_dal_with_bls = @@ -953,7 +1076,7 @@ module Actions = struct "Cannot issue an attestation with DAL because the BLS consensus key \ has no corresponding companion key. Crafting the attestation without \ DAL at level {attestation_level} for {delegate}" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) ("attestation_level", Data_encoding.int32) let synchronizing_round = @@ -974,11 +1097,10 @@ module Actions = struct "prepare forging block at level {level}, round {round} for {delegate}" ~pp1:pp_int32 ~pp2:Round.pp - ~pp3:Baking_state_types.Delegate.pp + ~pp3:Delegate.pp ("level", Data_encoding.int32) ("round", Round.encoding) - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ("delegate", Delegate.encoding_for_logging__cannot_decode) let forging_block = declare_4 @@ -986,15 +1108,18 @@ module Actions = struct ~name:"forging_block" ~level:Info ~msg: - "forging block at level {level}, round {round} for {delegate} (force \ - apply: {force_apply})" + "forging block at level {level}, round {round}{delegate}(force apply: \ + {force_apply})" ~pp1:pp_int32 ~pp2:Round.pp - ~pp3:Baking_state_types.Delegate.pp + ~pp3:(fun fmt -> + Format.fprintf + fmt + "@ for@ delegate@ %a@ " + Delegate.pp_without_companion_key) ("level", Data_encoding.int32) ("round", Round.encoding) - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ("delegate", Delegate.encoding_for_logging__cannot_decode) ("force_apply", Data_encoding.bool) let delayed_block_injection = @@ -1011,9 +1136,8 @@ module Actions = struct ~pp2:pp_int32 ("round", Round.encoding) ~pp3:Round.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) - ~pp4:Baking_state_types.Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) + ~pp4:Delegate.pp let injecting_block = declare_3 @@ -1023,11 +1147,10 @@ module Actions = struct ~msg:"injecting block at level {level}, round {round} for {delegate}" ~pp1:pp_int32 ~pp2:Round.pp - ~pp3:Baking_state_types.Delegate.pp + ~pp3:Delegate.pp ("level", Data_encoding.int32) ("round", Round.encoding) - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ("delegate", Delegate.encoding_for_logging__cannot_decode) let block_injected = declare_5 @@ -1036,28 +1159,31 @@ module Actions = struct ~name:"block_injected" ~level:Notice ~msg: - "block {block} at level {level}, round {round} injected for \ - {delegate}{manager_operations_infos}" + "block {block} at level {level}, round {round} \ + injected{delegate}{manager_operations_infos}" ~pp1:Block_hash.pp ~pp2:pp_int32 ~pp3:Round.pp - ~pp4:Baking_state_types.Delegate.pp + ~pp4:(fun fmt -> + Format.fprintf + fmt + "@ for@ delegate@ %a" + Delegate.pp_without_companion_key) ~pp5: (Format.pp_print_option - (fun fmt Baking_state.{manager_operation_number; total_fees} -> + (fun fmt {manager_operation_number; total_fees} -> Format.fprintf fmt - " with %d manager operations summing %a μtz in fees" + "@ with %d manager operations@ summing up to %a μtz in fees" manager_operation_number pp_int64 total_fees)) ("block", Block_hash.encoding) ("level", Data_encoding.int32) ("round", Round.encoding) - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ("delegate", Delegate.encoding_for_logging__cannot_decode) ( "manager_operations_infos", - Data_encoding.option Baking_state.manager_operations_infos_encoding ) + Data_encoding.option manager_operations_infos_encoding ) let block_injection_failed = declare_2 @@ -1070,17 +1196,19 @@ module Actions = struct ("trace", Error_monad.trace_encoding) ~pp2:Error_monad.pp_print_trace - let signing_consensus_vote = - declare_2 + let signing_consensus_op = + declare_1 ~section - ~name:"signing_consensus_vote" + ~name:"signing_consensus_operation" ~level:Info - ~msg:"signing {vote_kind} for {delegate}" - ~pp1:Baking_state.pp_consensus_vote_kind - ("vote_kind", Baking_state.consensus_vote_kind_encoding) - ~pp2:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~msg:"signing {operation_information}" + ~pp1:Op_info_for_logging.pp + ("operation_information", Op_info_for_logging.encoding) + + let emit_signing_consensus_op unsigned_consensus_op = + emit + signing_consensus_op + (Op_info_for_logging.of_unsigned_consensus_vote unsigned_consensus_op) let invalid_json_file = declare_1 @@ -1150,10 +1278,8 @@ module Actions = struct ~msg: "The following delegates have no attesting rights at level {level}: \ {delegates}" - ~pp1:(Format.pp_print_list Baking_state_types.Key.pp) - ( "delegates", - Data_encoding.list - Baking_state_types.Key.encoding_for_logging__cannot_decode ) + ~pp1:(Format.pp_print_list Key.pp) + ("delegates", Data_encoding.list Key.encoding_for_logging__cannot_decode) ~pp2:pp_int32 ("level", Data_encoding.int32) diff --git a/src/proto_023_PtSeouLo/lib_delegate/baking_lib.ml b/src/proto_023_PtSeouLo/lib_delegate/baking_lib.ml index 45260ca319cc30744331da2a427a101f8d68e5df..ccfe3895e16251d931e8b7b6ca1958fa5dfb6945 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/baking_lib.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/baking_lib.ml @@ -85,7 +85,7 @@ let preattest (cctxt : Protocol_client_context.full) ?(force = false) delegates = let open State_transitions in let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let cache = Baking_cache.Block_cache.create 10 in let* _, current_proposal = get_current_proposal cctxt ~cache () in let config = Baking_configuration.make ~force () in @@ -128,7 +128,7 @@ let preattest (cctxt : Protocol_client_context.full) ?(force = false) delegates let attest (cctxt : Protocol_client_context.full) ?(force = false) delegates = let open State_transitions in let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let cache = Baking_cache.Block_cache.create 10 in let* _, current_proposal = get_current_proposal cctxt ~cache () in let config = Baking_configuration.make ~force () in @@ -369,7 +369,7 @@ let propose (cctxt : Protocol_client_context.full) ?minimal_fees ?force_apply_from_round ?(force = false) ?(minimal_timestamp = false) ?extra_operations ?data_dir ?state_recorder delegates = let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let cache = Baking_cache.Block_cache.create 10 in let* _block_stream, current_proposal = get_current_proposal cctxt ~cache () in let config = @@ -538,7 +538,7 @@ let repropose (cctxt : Protocol_client_context.full) ?(force = false) delegates = let open Lwt_result_syntax in let open Baking_state in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let cache = Baking_cache.Block_cache.create 10 in let* _block_stream, current_proposal = get_current_proposal cctxt ~cache () in let config = Baking_configuration.make ~force () in @@ -821,7 +821,7 @@ let bake (cctxt : Protocol_client_context.full) ?dal_node_rpc_ctxt ?minimal_fees ?extra_operations ?(monitor_node_mempool = true) ?data_dir ?(count = 1) ?votes ?state_recorder delegates = let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let config = Baking_configuration.make ?minimal_fees diff --git a/src/proto_023_PtSeouLo/lib_delegate/baking_scheduling.ml b/src/proto_023_PtSeouLo/lib_delegate/baking_scheduling.ml index b007199c193018ea0589f1a4c6cde047c1c9acfd..3a65c8616a61e362a2e1aff2b5f594608003736c 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/baking_scheduling.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/baking_scheduling.ml @@ -988,7 +988,7 @@ let run cctxt ?dal_node_rpc_ctxt ?canceler ?(stop_on_event = fun _ -> false) ?(on_error = fun _ -> Lwt_result_syntax.return_unit) ?constants ~chain config delegates = let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let* chain_id = Shell_services.Chain.chain_id cctxt ~chain () in let*! () = Events.emit Baking_events.Node_rpc.chain_id chain_id in let* constants = diff --git a/src/proto_023_PtSeouLo/lib_delegate/baking_state.ml b/src/proto_023_PtSeouLo/lib_delegate/baking_state.ml index bee661d3fe7225cce293f0319423eec060f87d6f..fbf2fe724983b8bea1eca6563c07fdd04f2f57aa 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/baking_state.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/baking_state.ml @@ -803,17 +803,6 @@ module Events = struct ~level:Warning ~msg:"found an outdated or corrupted baking state: discarding it" () - - let companion_key_is_not_in_wallet = - declare_2 - ~section:[Protocol.name; "baker"; "delegates"] - ~name:"companion_key_is_not_in_wallet" - ~level:Error - ~msg: - "Companion key {companion_key} is not provided in the wallet but \ - registered in the protocol for {delegate}" - ("delegate", Baking_state_types.Delegate_id.encoding) - ("companion_key", Environment.Bls.Public_key_hash.encoding) end type state_data = { @@ -975,81 +964,22 @@ let may_load_attestable_data state = (* Helpers *) -module DelegateSet = struct - include Set.Make (struct - type t = Baking_state_types.Key.t - - let compare Baking_state_types.Key.{id = pkh; _} - Baking_state_types.Key.{id = pkh'; _} = - Baking_state_types.Key_id.compare pkh pkh' - end) - - let find_pkh pkh s = - let exception Found of elt in - try - iter - (fun ({id; _} as delegate) -> - if - Signature.Public_key_hash.equal - pkh - (Baking_state_types.Key_id.to_pkh id) - then raise (Found delegate) - else ()) - s ; - None - with Found d -> Some d -end - let delegate_slots attesting_rights delegates = let open Lwt_syntax in - let own_delegates = DelegateSet.of_list delegates in + let known_keys = Key.Set.of_list delegates in let* own_delegate_first_slots, own_delegate_slots, all_delegate_voting_power = Lwt_list.fold_left_s - (fun (own_list, own_map, all_map) slot -> - let { - Plugin.RPC.Validators.consensus_key; - companion_key; - delegate; - slots; - level = _; - } = - slot - in + (fun (own_list, own_map, all_map) validator -> + let {Plugin.RPC.Validators.slots; _} = validator in let first_slot = Stdlib.List.hd slots in let attesting_power = List.length slots in let all_map = SlotMap.add first_slot attesting_power all_map in let* own_list, own_map = - match DelegateSet.find_pkh consensus_key own_delegates with - | Some consensus_key -> - let* companion_key = - match companion_key with - | None -> return None - | Some companion_key -> ( - match - DelegateSet.find_pkh (Bls companion_key) own_delegates - with - | None -> - let* () = - Events.( - emit - companion_key_is_not_in_wallet - (Delegate_id.of_pkh delegate, companion_key)) - in - return None - | Some companion_key -> return (Some companion_key)) - in - let attesting_slot = - { - delegate = - { - consensus_key; - delegate_id = Delegate_id.of_pkh delegate; - companion_key; - }; - first_slot; - attesting_power; - } - in + let* delegate_opt = Delegate.of_validator ~known_keys validator in + match delegate_opt with + | None -> return (own_list, own_map) + | Some delegate -> + let attesting_slot = {delegate; first_slot; attesting_power} in return ( attesting_slot :: own_list, List.fold_left @@ -1057,7 +987,6 @@ let delegate_slots attesting_rights delegates = SlotMap.add slot attesting_slot own_map) own_map slots ) - | None -> return (own_list, own_map) in return (own_list, own_map, all_map)) ([], SlotMap.empty, SlotMap.empty) @@ -1394,77 +1323,6 @@ let pp_timeout_kind fmt = function Round.pp at_round -let pp_forge_event fmt = - let open Format in - let pp_signed_consensus_vote fmt {unsigned_consensus_vote; _} = - fprintf - fmt - "for delegate %a at level %ld (round %a)" - Delegate.pp - unsigned_consensus_vote.delegate - (Raw_level.to_int32 unsigned_consensus_vote.vote_consensus_content.level) - Round.pp - unsigned_consensus_vote.vote_consensus_content.round - in - function - | Block_ready {signed_block_header; round; delegate; _} -> - fprintf - fmt - "block ready for delegate: %a at level %ld (round: %a)" - Delegate.pp - delegate - signed_block_header.shell.level - Round.pp - round - | Preattestation_ready signed_preattestation -> - fprintf - fmt - "preattestation ready %a" - pp_signed_consensus_vote - signed_preattestation - | Attestation_ready signed_attestation -> - fprintf - fmt - "attestation ready %a" - pp_signed_consensus_vote - signed_attestation - -let pp_event fmt = function - | New_valid_proposal proposal -> - Format.fprintf - fmt - "new valid proposal received: %a" - pp_block_info - proposal.block - | New_head_proposal proposal -> - Format.fprintf - fmt - "new head proposal received: %a" - pp_block_info - proposal.block - | Prequorum_reached (candidate, preattestations) -> - Format.fprintf - fmt - "prequorum reached with %d preattestations for %a at round %a" - (List.length preattestations) - Block_hash.pp - candidate.Operation_worker.hash - Round.pp - candidate.round_watched - | Quorum_reached (candidate, attestations) -> - Format.fprintf - fmt - "quorum reached with %d attestations for %a at round %a" - (List.length attestations) - Block_hash.pp - candidate.Operation_worker.hash - Round.pp - candidate.round_watched - | New_forge_event forge_event -> - Format.fprintf fmt "new forge event: %a" pp_forge_event forge_event - | Timeout kind -> - Format.fprintf fmt "timeout reached: %a" pp_timeout_kind kind - let pp_short_event fmt = let open Format in function diff --git a/src/proto_023_PtSeouLo/lib_delegate/baking_state.mli b/src/proto_023_PtSeouLo/lib_delegate/baking_state.mli index 5c236fbe16b46b55c92dd1e725ee743b1b5df9be..b16fc761fe6a5e30b18fed59bfd75532b71be045 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/baking_state.mli +++ b/src/proto_023_PtSeouLo/lib_delegate/baking_state.mli @@ -409,8 +409,6 @@ type forge_event = val forge_event_encoding_for_logging__cannot_decode : forge_event Data_encoding.t -val pp_forge_event : Format.formatter -> forge_event -> unit - (** [forge_worker_hooks] type that allows interactions with the forge worker. Hooks are needed in order to break a circular dependency. *) type forge_worker_hooks = { @@ -552,6 +550,4 @@ type event = fail. *) val event_encoding_for_logging__cannot_decode : event Data_encoding.t -val pp_event : Format.formatter -> event -> unit - val pp_short_event : Format.formatter -> event -> unit diff --git a/src/proto_023_PtSeouLo/lib_delegate/baking_state_types.ml b/src/proto_023_PtSeouLo/lib_delegate/baking_state_types.ml index b264ff029cfe6baa40880ab1e406cb7a5a0f66af..043219aa990cfd421fe894f3adf95f354c7141c8 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/baking_state_types.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/baking_state_types.ml @@ -12,6 +12,8 @@ module Key_id = struct let compare = Signature.Public_key_hash.compare + let equal = Signature.Public_key_hash.equal + let encoding = Signature.Public_key_hash.encoding let pp = Signature.Public_key_hash.pp @@ -23,7 +25,7 @@ module Key = struct (** A consensus key (aka, a validator) is identified by its alias name, its public key, its public key hash, and its secret key. *) type t = { - alias : string option; + alias : string; id : Key_id.t; public_key : Signature.Public_key.t; secret_key_uri : Client_keys.sk_uri; @@ -44,66 +46,158 @@ module Key = struct logging; decoding is impossible (%s)" __LOC__)) (obj3 - (req "alias" (option string)) + (req "alias" string) (req "public_key" Signature.Public_key.encoding) (req "public_key_hash" Signature.Public_key_hash.encoding)) let pp fmt {alias; id; _} = - match alias with - | None -> Format.fprintf fmt "%a" Signature.Public_key_hash.pp id - | Some alias -> - Format.fprintf fmt "%s (%a)" alias Signature.Public_key_hash.pp id + Format.fprintf fmt "'%s' (%a)" alias Signature.Public_key_hash.pp id + + let is_bls t = Signature.Public_key_hash.is_bls (Key_id.to_pkh t.id) + + module Set = struct + include Set.Make (struct + type nonrec t = t + + let compare {id; _} {id = id'; _} = Key_id.compare id id' + end) + + let find_pkh pkh s = + let exception Found of elt in + try + iter + (fun ({id; _} as delegate) -> + if Signature.Public_key_hash.equal pkh (Key_id.to_pkh id) then + raise (Found delegate) + else ()) + s ; + None + with Found d -> Some d + end end -module Delegate_id = struct - type t = Signature.public_key_hash +module Maybe_known_key = struct + type t = Known_key of Key.t | Id_only of Key_id.t - let of_pkh pkh = pkh + let key_id = function Known_key key -> key.id | Id_only id -> id - let to_pkh pkh = pkh - - let equal = Signature.Public_key_hash.equal + let encoding_for_logging__cannot_decode = + let open Data_encoding in + conv + (function + | Known_key {alias; public_key; id; _} -> + (Some alias, Some public_key, id) + | Id_only pkh -> (None, None, pkh)) + (fun _ -> + Stdlib.failwith + (Format.sprintf + "This event should only be used to encode events; decoding is \ + impossible: %s" + __LOC__)) + (obj3 + (opt "alias" string) + (opt "public_key" Signature.Public_key.encoding) + (req "public_key_hash" Signature.Public_key_hash.encoding)) - let encoding = Signature.Public_key_hash.encoding + let pp fmt = function + | Known_key key -> Key.pp fmt key + | Id_only id -> Key_id.pp fmt id - let pp = Signature.Public_key_hash.pp + let make ~known_keys pkh = + match Key.Set.find_pkh pkh known_keys with + | None -> Id_only pkh + | Some key -> Known_key key end +module Delegate_id = Key_id + module Delegate = struct + type manager_key = Maybe_known_key.t + type t = { + manager_key : manager_key; consensus_key : Key.t; companion_key : Key.t option; - delegate_id : Delegate_id.t; } + let delegate_id t = Maybe_known_key.key_id t.manager_key + let encoding_for_logging__cannot_decode = let open Data_encoding in conv - (fun {consensus_key; companion_key; delegate_id} -> - (consensus_key, delegate_id, companion_key)) - (fun (consensus_key, delegate_id, companion_key) -> - {consensus_key; delegate_id; companion_key}) + (fun {manager_key; consensus_key; companion_key} -> + (manager_key, consensus_key, companion_key)) + (fun (manager_key, consensus_key, companion_key) -> + {manager_key; consensus_key; companion_key}) (obj3 + (req "manager_key" Maybe_known_key.encoding_for_logging__cannot_decode) (req "consensus_key" Key.encoding_for_logging__cannot_decode) - (req "delegate" Delegate_id.encoding) (opt "companion_key" Key.encoding_for_logging__cannot_decode)) - let pp fmt {consensus_key; delegate_id; companion_key} = - let str_companion_key = - match companion_key with - | Some companion_key -> - Format.asprintf " with companion key %a" Key.pp companion_key - | None -> "" - in - if Signature.Public_key_hash.equal consensus_key.id delegate_id then - Format.fprintf fmt "%a%s" Key.pp consensus_key str_companion_key - else - Format.fprintf - fmt - "%a%s@,on behalf of %a" - Key.pp - consensus_key - str_companion_key - Delegate_id.pp - delegate_id + let pp_without_companion_key fmt + {manager_key; consensus_key; companion_key = _} = + Format.fprintf + fmt + "%a@ with@ consensus key@ %a" + Maybe_known_key.pp + manager_key + Key.pp + consensus_key + + let pp fmt ({manager_key = _; consensus_key = _; companion_key} as t) = + pp_without_companion_key fmt t ; + match companion_key with + | None -> () + | Some companion_key -> + Format.fprintf fmt "@ and@ companion key@ %a" Key.pp companion_key + + let companion_key_is_not_in_wallet = + let open Internal_event.Simple in + declare_2 + ~section:[Protocol.name; "baker"; "delegates"] + ~name:"companion_key_is_not_in_wallet" + ~level:Error + ~msg: + "Companion key {companion_key} for {delegate} is absent from the \ + client wallet. The baker will only be able to issue attestations \ + without DAL for this delegate, and the delegate will lose DAL \ + rewards." + ("delegate", encoding_for_logging__cannot_decode) + ("companion_key", Environment.Bls.Public_key_hash.encoding) + + let of_validator ~known_keys + { + Plugin.RPC.Validators.consensus_key = consensus_pkh; + companion_key = companion_bls_pkh_opt; + delegate = manager_pkh; + slots = _; + level = _; + } = + let open Lwt_syntax in + match Key.Set.find_pkh consensus_pkh known_keys with + | None -> return_none + | Some consensus_key -> + let manager_key = Maybe_known_key.make ~known_keys manager_pkh in + let* companion_key = + match companion_bls_pkh_opt with + | None -> return_none + | Some companion_bls_pkh -> + let companion_key = + Key.Set.find_pkh (Bls companion_bls_pkh) known_keys + in + let* () = + if + Option.is_none companion_key + && Signature.Public_key_hash.is_bls consensus_pkh + then + Events.( + emit + companion_key_is_not_in_wallet + ( {manager_key; consensus_key; companion_key}, + companion_bls_pkh )) + else return_unit + in + return companion_key + in + return_some {manager_key; consensus_key; companion_key} end diff --git a/src/proto_023_PtSeouLo/lib_delegate/baking_state_types.mli b/src/proto_023_PtSeouLo/lib_delegate/baking_state_types.mli index 5a0a268003709aae3896aac4ce567b16457c0c38..a1df3f4d7fb76dd2fab1f4b7e98275f1e9567e4a 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/baking_state_types.mli +++ b/src/proto_023_PtSeouLo/lib_delegate/baking_state_types.mli @@ -16,6 +16,8 @@ module Key_id : sig val compare : t -> t -> int + val equal : t -> t -> bool + val encoding : t Data_encoding.t val pp : Format.formatter -> t -> unit @@ -29,14 +31,14 @@ end module Key : sig type t = private { - alias : string option; + alias : string; id : Key_id.t; public_key : Signature.public_key; secret_key_uri : Client_keys.sk_uri; } val make : - alias:string option -> + alias:string -> public_key:Signature.public_key -> public_key_hash:Signature.public_key_hash -> secret_key_uri:Client_keys.sk_uri -> @@ -51,32 +53,26 @@ module Key : sig val encoding_for_logging__cannot_decode : t Data_encoding.t val pp : Format.formatter -> t -> unit -end - -(** {2 Delegates slots type and functions} *) -module Delegate_id : sig - type t - (** Only use at library frontiers *) - val of_pkh : Signature.public_key_hash -> t - - (** Only use at library frontiers *) - val to_pkh : t -> Signature.public_key_hash - - val equal : t -> t -> bool + val is_bls : t -> bool - val encoding : t Data_encoding.t - - val pp : Format.formatter -> t -> unit + module Set : Set.S with type elt = t end +(** {2 Delegates slots type and functions} *) +module Delegate_id : module type of Key_id + module Delegate : sig - type t = { + type manager_key + + type t = private { + manager_key : manager_key; consensus_key : Key.t; companion_key : Key.t option; - delegate_id : Delegate_id.t; } + val delegate_id : t -> Delegate_id.t + (** Partial encoding for {!t} that omits secret keys to avoid leaking them in event logs; see {!Key.encoding_for_logging__cannot_decode}. @@ -86,4 +82,19 @@ module Delegate : sig val encoding_for_logging__cannot_decode : t Data_encoding.t val pp : Format.formatter -> t -> unit + + (** Prints the manager key and consensus key but not the companion + key. *) + val pp_without_companion_key : Format.formatter -> t -> unit + + (** Builds a {!t} from an element of the output of + {!Plugin.RPC.Validators.get}, if the consensus key is present in + [known_keys]; otherwise, returns [None]. + + If the consensus key is a known BLS key and the validator + argument contains a companion key but that companion key is not + in [known_keys], emits an error event but nevertheless returns a + {!t} where [companion_key = None]. (This function is in Lwt to + be able to emit this event.) *) + val of_validator : known_keys:Key.Set.t -> RPC.Validators.t -> t option Lwt.t end diff --git a/src/proto_023_PtSeouLo/lib_delegate/node_rpc.ml b/src/proto_023_PtSeouLo/lib_delegate/node_rpc.ml index 92d0e8a2d58e458044fde4975e6d8ec6ba49cf10..4ebee80710fe868437a5300d54c28cb97d24f2f5 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/node_rpc.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/node_rpc.ml @@ -436,7 +436,9 @@ let dal_attestable_slots (dal_node_rpc_ctxt : Tezos_rpc.Context.generic) let attested_level = Int32.succ attestation_level in List.map (fun (delegate_slot : delegate_slot) -> - let delegate_id = delegate_slot.delegate.delegate_id in + let delegate_id = + Baking_state_types.Delegate.delegate_id delegate_slot.delegate + in ( delegate_id, get_attestable_slots dal_node_rpc_ctxt delegate_id ~attested_level )) delegate_slots diff --git a/src/proto_023_PtSeouLo/lib_delegate/test/mockup_simulator/mockup_simulator.ml b/src/proto_023_PtSeouLo/lib_delegate/test/mockup_simulator/mockup_simulator.ml index 93bc24fe6f00ffae6cb40dffe91a8bfd444e41ce..ab5c92ded09044674465b7207a9fb289dd87df9b 100644 --- a/src/proto_023_PtSeouLo/lib_delegate/test/mockup_simulator/mockup_simulator.ml +++ b/src/proto_023_PtSeouLo/lib_delegate/test/mockup_simulator/mockup_simulator.ml @@ -966,7 +966,6 @@ let baker_process ~(delegates : Baking_state_types.Key.t list) ~base_dir let* () = List.iter_es (fun ({alias; public_key; id; secret_key_uri} : Baking_state_types.Key.t) -> - let name = alias |> WithExceptions.Option.get ~loc:__LOC__ in let* public_key_uri = Client_keys.neuterize secret_key_uri in let pkh = Baking_state_types.Key_id.to_pkh id in Client_keys.register_key @@ -974,7 +973,7 @@ let baker_process ~(delegates : Baking_state_types.Key.t list) ~base_dir ~force:false (pkh, public_key_uri, secret_key_uri) ~public_key - name) + alias) delegates in let context_index = @@ -1289,7 +1288,7 @@ let make_baking_delegate (secret : Tezos_mockup_commands.Mockup_wallet.bootstrap_secret) ) : Baking_state_types.Key.t = Baking_state_types.Key.make - ~alias:(Some secret.name) + ~alias:secret.name ~public_key_hash:account.public_key_hash ~public_key:(account.public_key |> WithExceptions.Option.get ~loc:__LOC__) ~secret_key_uri:secret.sk_uri diff --git a/src/proto_alpha/lib_delegate/baking_actions.ml b/src/proto_alpha/lib_delegate/baking_actions.ml index 6288dc4f8cd68d6576293b1061b4c6656453d2b0..5a8e2e58485475a0645a7a762ac109f202ff3254 100644 --- a/src/proto_alpha/lib_delegate/baking_actions.ml +++ b/src/proto_alpha/lib_delegate/baking_actions.ml @@ -562,10 +562,11 @@ let may_get_dal_content state consensus_vote = ( Raw_level.to_int32 vote_consensus_content.level, vote_consensus_content.round ) in + let delegate_id = Delegate.delegate_id delegate in let promise_opt = List.assoc_opt ~equal:Delegate_id.equal - delegate.delegate_id + delegate_id state.level_state.dal_attestable_slots in match promise_opt with @@ -585,7 +586,7 @@ let may_get_dal_content state consensus_vote = Lwt.return (`RPC_result tz_res)); ] in - process_dal_rpc_result state delegate.delegate_id level round res + process_dal_rpc_result state delegate_id level round res let is_authorized (global_state : global_state) highwatermarks consensus_vote = let {delegate; vote_consensus_content; _} = consensus_vote in @@ -696,48 +697,56 @@ let forge_and_sign_consensus_vote global_state ~branch unsigned_consensus_vote : | Attestation -> Operation.(to_watermark (Attestation chain_id)) in let bls_mode = - match delegate.consensus_key.public_key with - | Bls _ -> global_state.constants.parametric.aggregate_attestation - | _ -> false + Key.is_bls delegate.consensus_key + && global_state.constants.parametric.aggregate_attestation in - let* Contents_list contents, companion_key_opt = + let* dal_content, companion_key_opt = match vote_kind with | Preattestation -> - return - (Contents_list (Single (Preattestation vote_consensus_content)), None) - | Attestation -> - let* dal_content, companion_key_opt = - if not bls_mode then return (dal_content, None) - else - match dal_content with - | None -> return (dal_content, None) - | Some _ -> ( - match delegate.companion_key with - | None -> - let*! () = - Events.( - emit - missing_companion_key_for_dal_with_bls - ( delegate.delegate_id, - Raw_level.to_int32 vote_consensus_content.level )) - in - return (None, None) - | Some companion_key -> return (dal_content, Some companion_key) - ) - in - return - ( Contents_list - (Single - (Attestation - {consensus_content = vote_consensus_content; dal_content})), - companion_key_opt ) + (* Preattestations cannot have a dal_content and do not use + the companion key. *) + return (None, None) + | Attestation -> ( + if not bls_mode then + (* If not in BLS mode, leave the dal_content unchanged and do + not use the companion key. *) + return (dal_content, None) + else if Option.is_none dal_content then + (* No dal_content: the companion key will not be used. *) + return (dal_content, None) + else + match delegate.companion_key with + | None -> + (* There is an available dal_content, but the BLS + consensus key does not have an associated companion + key (whether because the delegate has not registered + any companion key, or because it has not been + provided to the baker): signing an attestation with + DAL is not possible. Set the dal_content to None and + issue a warning. *) + let*! () = + Events.( + emit + missing_companion_key_for_dal_with_bls + ( Delegate.delegate_id delegate, + Raw_level.to_int32 vote_consensus_content.level )) + in + return (None, None) + | Some companion_key -> + (* We have everything we need to issue a BLS attestation with DAL. *) + return (dal_content, Some companion_key)) in - let signing_request = + let (Contents_list contents as packed_contents_list) = match vote_kind with - | Preattestation -> `Preattestation - | Attestation -> `Attestation + | Preattestation -> + Contents_list (Single (Preattestation vote_consensus_content)) + | Attestation -> + Contents_list + (Single + (Attestation + {consensus_content = vote_consensus_content; dal_content})) in - let unsigned_operation = (shell, Contents_list contents) in + let unsigned_operation = (shell, packed_contents_list) in let encoding = if bls_mode then Operation.bls_mode_unsigned_encoding else Operation.unsigned_encoding @@ -745,6 +754,11 @@ let forge_and_sign_consensus_vote global_state ~branch unsigned_consensus_vote : let unsigned_operation_bytes = Data_encoding.Binary.to_bytes_exn encoding unsigned_operation in + let signing_request = + match vote_kind with + | Preattestation -> `Preattestation + | Attestation -> `Attestation + in let sk_consensus_uri = delegate.consensus_key.secret_key_uri in let* consensus_sig = sign @@ -763,7 +777,7 @@ let forge_and_sign_consensus_vote global_state ~branch unsigned_consensus_vote : companion_key_opt *) return consensus_sig | Some _, None -> - (* dal_content has been discarded from contents *) + (* only possible in non-BLS mode *) return consensus_sig | Some {attestation = dal_attestation}, Some companion_key -> ( let sk_companion_uri = companion_key.secret_key_uri in @@ -818,6 +832,9 @@ let forge_and_sign_consensus_vote global_state ~branch unsigned_consensus_vote : in let protocol_data = Operation_data {contents; signature = Some signature} in let signed_operation : Operation.packed = {shell; protocol_data} in + (* Also update unsigned_consensus_vote: dal_content may have been + set to None. *) + let unsigned_consensus_vote = {unsigned_consensus_vote with dal_content} in return {unsigned_consensus_vote; signed_operation} let sign_consensus_votes (global_state : global_state) @@ -835,7 +852,7 @@ let sign_consensus_votes (global_state : global_state) List.filter_map_es (fun ({delegate; vote_kind; vote_consensus_content; _} as unsigned_consensus_vote) -> - let*! () = Events.(emit signing_consensus_vote (vote_kind, delegate)) in + let*! () = Events.emit_signing_consensus_op unsigned_consensus_vote in let*! signed_consensus_vote_r = (forge_and_sign_consensus_vote global_state @@ -876,11 +893,6 @@ let inject_consensus_vote state (signed_consensus_vote : signed_consensus_vote) let chain_id = state.global_state.chain_id in let unsigned_consensus_vote = signed_consensus_vote.unsigned_consensus_vote in let delegate = unsigned_consensus_vote.delegate in - let vote_consensus_content = unsigned_consensus_vote.vote_consensus_content in - let level, round = - ( Raw_level.to_int32 vote_consensus_content.level, - vote_consensus_content.round ) - in protect ~on_error:(fun err -> let*! () = @@ -905,10 +917,7 @@ let inject_consensus_vote state (signed_consensus_vote : signed_consensus_vote) | Attestation -> "attestation"))]) in let*! () = - Events.( - emit - consensus_vote_injected - (unsigned_consensus_vote.vote_kind, oph, delegate, level, round)) + Events.emit_consensus_op_injected unsigned_consensus_vote oph in return_unit) diff --git a/src/proto_alpha/lib_delegate/baking_commands.ml b/src/proto_alpha/lib_delegate/baking_commands.ml index c2bb33b27851a5c87f5e4e3294cdf080c3138198..7e2b6e981fb974e3e6c2961f483ab4ce2f2ac334 100644 --- a/src/proto_alpha/lib_delegate/baking_commands.ml +++ b/src/proto_alpha/lib_delegate/baking_commands.ml @@ -219,7 +219,7 @@ let get_delegates (cctxt : Protocol_client_context.full) let open Lwt_result_syntax in let proj_delegate (alias, public_key_hash, public_key, secret_key_uri) = Baking_state_types.Key.make - ~alias:(Some alias) + ~alias ~public_key_hash ~public_key ~secret_key_uri @@ -239,10 +239,8 @@ let get_delegates (cctxt : Protocol_client_context.full) let* () = Tezos_signer_backends.Encrypted.decrypt_list cctxt - (List.filter_map - (function - | {Baking_state_types.Key.alias = Some alias; _} -> Some alias - | _ -> None) + (List.map + (function {Baking_state_types.Key.alias; _} -> alias) delegates) in let delegates_no_duplicates = List.sort_uniq compare delegates in diff --git a/src/proto_alpha/lib_delegate/baking_events.ml b/src/proto_alpha/lib_delegate/baking_events.ml index a5c510d7f92e24dc5b63174058fc43f898189def..abc3bb75ffc5f5b8cfa7649d5d16a83e86319331 100644 --- a/src/proto_alpha/lib_delegate/baking_events.ml +++ b/src/proto_alpha/lib_delegate/baking_events.ml @@ -25,6 +25,8 @@ open Protocol open Alpha_context +open Baking_state_types +open Baking_state let section = [Protocol.name; "baker"] @@ -34,6 +36,139 @@ let pp_int64 fmt n = Format.fprintf fmt "%Ld" n let waiting_color = Internal_event.Magenta +module Op_info_for_logging = struct + type kind = Preattestation | Attestation_without_dal | Attestation_with_dal + + type t = { + kind : kind; + level : Protocol.Alpha_context.Raw_level.t; + round : Protocol.Alpha_context.Round.t; + delegate : Delegate.t; + } + + let pp_kind fmt = function + | Preattestation -> Format.fprintf fmt "preattestation" + | Attestation_without_dal -> Format.fprintf fmt "attestation (without DAL)" + | Attestation_with_dal -> Format.fprintf fmt "attestation (with DAL)" + + let pp fmt {kind; delegate; level; round} = + let companion_key_is_relevant = + match kind with + | Attestation_with_dal -> Key.is_bls delegate.consensus_key + | Attestation_without_dal | Preattestation -> false + in + Format.fprintf + fmt + "%a@ for level %a, round %a@ for delegate@ %a" + pp_kind + kind + Protocol.Alpha_context.Raw_level.pp + level + Protocol.Alpha_context.Round.pp + round + (if companion_key_is_relevant then Delegate.pp + else Delegate.pp_without_companion_key) + delegate + + let kind_encoding = + Data_encoding.string_enum + [ + ("preattestation", Preattestation); + ("attestation_without_dal", Attestation_without_dal); + ("attestation_with_dal", Attestation_with_dal); + ] + + let encoding : t Data_encoding.t = + let open Data_encoding in + conv + (fun {kind; level; round; delegate} -> (kind, level, round, delegate)) + (fun (kind, level, round, delegate) -> {kind; level; round; delegate}) + (obj4 + (req "op_kind" kind_encoding) + (req "level" Protocol.Alpha_context.Raw_level.encoding) + (req "round" Protocol.Alpha_context.Round.encoding) + (req "delegate" Delegate.encoding_for_logging__cannot_decode)) + + let of_unsigned_consensus_vote + (unsigned_consensus_vote : unsigned_consensus_vote) = + let kind = + match unsigned_consensus_vote.vote_kind with + | Preattestation -> Preattestation + | Attestation -> + if Option.is_some unsigned_consensus_vote.dal_content then + Attestation_with_dal + else Attestation_without_dal + in + { + kind; + delegate = unsigned_consensus_vote.delegate; + level = unsigned_consensus_vote.vote_consensus_content.level; + round = unsigned_consensus_vote.vote_consensus_content.round; + } +end + +let pp_unsigned_consensus_vote fmt unsigned_consensus_vote = + Op_info_for_logging.( + pp fmt (of_unsigned_consensus_vote unsigned_consensus_vote)) + +let pp_signed_consensus_vote fmt {unsigned_consensus_vote; _} = + pp_unsigned_consensus_vote fmt unsigned_consensus_vote + +let pp_forge_event fmt = function + | Block_ready {signed_block_header; round; delegate; _} -> + Format.fprintf + fmt + "block ready@ at level %ld, round %a@ for@ delegate@ %a " + signed_block_header.shell.level + Round.pp + round + Delegate.pp_without_companion_key + delegate + | Preattestation_ready signed_op | Attestation_ready signed_op -> + Format.fprintf + fmt + "operation ready:@ %a" + pp_signed_consensus_vote + signed_op + +let pp_event fmt = + let open Baking_state in + function + | New_valid_proposal proposal -> + Format.fprintf + fmt + "new valid proposal received: %a" + pp_block_info + proposal.block + | New_head_proposal proposal -> + Format.fprintf + fmt + "new head proposal received: %a" + pp_block_info + proposal.block + | Prequorum_reached (candidate, preattestations) -> + Format.fprintf + fmt + "prequorum reached with %d preattestations for %a at round %a" + (List.length preattestations) + Block_hash.pp + candidate.Operation_worker.hash + Round.pp + candidate.round_watched + | Quorum_reached (candidate, attestations) -> + Format.fprintf + fmt + "quorum reached with %d attestations for %a at round %a" + (List.length attestations) + Block_hash.pp + candidate.Operation_worker.hash + Round.pp + candidate.round_watched + | New_forge_event forge_event -> + Format.fprintf fmt "new forge event: %a" pp_forge_event forge_event + | Timeout kind -> + Format.fprintf fmt "timeout reached: %a" pp_timeout_kind kind + module Commands = struct include Internal_event.Simple @@ -147,11 +282,10 @@ module State_transitions = struct () let new_forge_event = - let open Baking_state in declare_1 ~section ~name:"new_forge_event" - ~level:Notice + ~level:Info ~msg:"received new forge event: {event}" ~pp1:pp_forge_event ("event", forge_event_encoding_for_logging__cannot_decode) @@ -185,9 +319,8 @@ module State_transitions = struct ("level", Data_encoding.int32) ~pp3:Round.pp ("next_round", Round.encoding) - ~pp4:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp4:Delegate.pp_without_companion_key + ("delegate", Delegate.encoding_for_logging__cannot_decode) let new_head_while_waiting_for_qc = declare_0 @@ -381,10 +514,13 @@ module State_transitions = struct ~section ~name:"preparing_fresh_block" ~level:Info - ~msg:"preparing fresh block for {delegate} at round {round}" - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~msg:"preparing fresh block at round {round}{delegate}" + ~pp1:(fun fmt -> + Format.fprintf + fmt + "@ for@ delegate@ %a" + Delegate.pp_without_companion_key) + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:Round.pp ("round", Round.encoding) @@ -437,10 +573,10 @@ module State_transitions = struct ~name:"step_current_phase" ~level:Debug ~msg:"automaton step: current phase {phase}, event {event}" - ~pp1:Baking_state.pp_phase - ("phase", Baking_state.phase_encoding) - ~pp2:Baking_state.pp_event - ("event", Baking_state.event_encoding_for_logging__cannot_decode) + ~pp1:pp_phase + ("phase", phase_encoding) + ~pp2:pp_event + ("event", event_encoding_for_logging__cannot_decode) let discarding_preattestation = declare_3 @@ -450,9 +586,8 @@ module State_transitions = struct ~msg: "discarding outdated preattestation for {delegate} at level {level}, \ round {round}" - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:pp_int32 ("level", Data_encoding.int32) ~pp3:Round.pp @@ -466,9 +601,8 @@ module State_transitions = struct ~msg: "discarding outdated attestation for {delegate} at level {level}, \ round {round}" - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:pp_int32 ("level", Data_encoding.int32) ~pp3:Round.pp @@ -483,9 +617,8 @@ module State_transitions = struct "discarding preattestation for {delegate} with payload {payload} at \ level {level}, round {round} where the prequorum was locked on a \ different payload {state_payload}." - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:Block_payload_hash.pp ("payload", Block_payload_hash.encoding) ~pp3:pp_int32 @@ -503,9 +636,8 @@ module State_transitions = struct ~msg: "discarding attestation for {delegate} at level {level}, round {round} \ where no prequorum was reached." - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:pp_int32 ("level", Data_encoding.int32) ~pp3:Round.pp @@ -520,9 +652,8 @@ module State_transitions = struct "discarding attestation for {delegate} with payload {payload} at level \ {level}, round {round} where the prequorum was on a different payload \ {state_payload}." - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:Block_payload_hash.pp ("payload", Block_payload_hash.encoding) ~pp3:pp_int32 @@ -542,8 +673,8 @@ module State_transitions = struct {phase} phase." ~pp1:Block_hash.pp ("candidate", Block_hash.encoding) - ~pp2:Baking_state.pp_phase - ("phase", Baking_state.phase_encoding) + ~pp2:pp_phase + ("phase", phase_encoding) let discarding_unexpected_quorum_reached = declare_2 @@ -555,8 +686,8 @@ module State_transitions = struct phase." ~pp1:Block_hash.pp ("candidate", Block_hash.encoding) - ~pp2:Baking_state.pp_phase - ("phase", Baking_state.phase_encoding) + ~pp2:pp_phase + ("phase", phase_encoding) end module Node_rpc = struct @@ -591,27 +722,21 @@ module Node_rpc = struct ("chain_id", Chain_id.encoding) end -module Delegates = struct +module Launch = struct include Internal_event.Simple - let section = section @ ["delegates"] + let section = section @ ["launch"] - let delegates_used = + let keys_used = declare_1 ~section ~alternative_color:Internal_event.Cyan - ~name:"delegates_used" + ~name:"keys_used" ~level:Notice - ~msg:"Baker will run with the following delegates:{delegates}" - ~pp1:(fun ppf delegates -> - Format.fprintf - ppf - "@[@,%a@]" - Format.(pp_print_list ~pp_sep:pp_print_cut Baking_state_types.Key.pp) - delegates) - ( "delegates", - Data_encoding.list - Baking_state_types.Key.encoding_for_logging__cannot_decode ) + ~msg:"Baker will run with the following keys:{keys}" + ~pp1:(fun ppf keys -> + Format.fprintf ppf "@[@,%a@]" (Format.pp_print_list Key.pp) keys) + ("keys", Data_encoding.list Key.encoding_for_logging__cannot_decode) end module Scheduling = struct @@ -656,17 +781,20 @@ module Scheduling = struct ~name:"next_potential_slot" ~level:Info ~msg: - "next potential slot for level {level} is at round {round} at \ - {timestamp} for {delegate}" + "next potential slot for level {level} is at round \ + {round}{timestamp}{delegate}" ~pp1:pp_int32 ("level", Data_encoding.int32) ~pp2:Round.pp ("round", Round.encoding) - ~pp3:Timestamp.pp + ~pp3:(fun fmt -> Format.fprintf fmt "@ at %a" Timestamp.pp) ("timestamp", Timestamp.encoding) - ~pp4:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp4:(fun fmt -> + Format.fprintf + fmt + "@ for@ delegate@ %a" + Delegate.pp_without_companion_key) + ("delegate", Delegate.encoding_for_logging__cannot_decode) let waiting_end_of_round = declare_3 @@ -799,12 +927,12 @@ module Lib = struct ~name:"attempting_preattest_proposal" ~level:Debug ~msg:"attempting to {action} proposal {proposal}" - ("action", Baking_state.consensus_vote_kind_encoding) + ("action", consensus_vote_kind_encoding) ~pp1:(fun fmt -> function - | Baking_state.Preattestation -> Format.fprintf fmt "preattest" + | Preattestation -> Format.fprintf fmt "preattest" | Attestation -> Format.fprintf fmt "attest") - ("proposal", Baking_state.proposal_encoding) - ~pp2:Baking_state.pp_proposal + ("proposal", proposal_encoding) + ~pp2:pp_proposal let waiting_block_timestamp = declare_2 @@ -832,11 +960,10 @@ module Actions = struct ~msg: "unable to sign {vote_kind} for {delegate} at level {level}, round \ {round} -- {trace}" - ~pp1:Baking_state.pp_consensus_vote_kind - ("vote_kind", Baking_state.consensus_vote_kind_encoding) - ~pp2:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:pp_consensus_vote_kind + ("vote_kind", consensus_vote_kind_encoding) + ~pp2:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp3:pp_int32 ("level", Data_encoding.int32) ~pp4:Round.pp @@ -850,7 +977,7 @@ module Actions = struct ~name:"failed_to_get_attestations" ~level:Error ~msg:"unable to get DAL attestation for {delegate} -- {trace}" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) ~pp2:Error_monad.pp_print_trace ("trace", Error_monad.trace_encoding) @@ -860,7 +987,7 @@ module Actions = struct ~name:"failed_to_get_attestations_in_time" ~level:Error ~msg:"unable to get DAL attestation for {delegate} in time" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) let failed_to_inject_consensus_vote = declare_3 @@ -868,11 +995,10 @@ module Actions = struct ~name:"failed_to_inject_consensus_vote" ~level:Error ~msg:"failed to inject {vote_kind} for {delegate} -- {trace}" - ~pp1:Baking_state.pp_consensus_vote_kind - ("vote_kind", Baking_state.consensus_vote_kind_encoding) - ~pp2:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:pp_consensus_vote_kind + ("vote_kind", consensus_vote_kind_encoding) + ~pp2:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp3:Error_monad.pp_print_trace ("trace", Error_monad.trace_encoding) @@ -882,9 +1008,8 @@ module Actions = struct ~name:"failed_to_forge_block" ~level:Error ~msg:"failed to forge block for {delegate} -- {trace}" - ~pp1:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~pp1:Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) ~pp2:Error_monad.pp_print_trace ("trace", Error_monad.trace_encoding) @@ -899,25 +1024,23 @@ module Actions = struct ("level", Data_encoding.int32) ("round", Round.encoding) - let consensus_vote_injected = - declare_5 + let consensus_op_injected = + declare_2 ~section - ~name:"consensus_vote_injected" + ~name:"consensus_operation_injected" ~level:Notice - ~msg: - "injected {vote_kind} {ophash} for {delegate} for level {level}, round \ - {round}" - ~pp1:Baking_state.pp_consensus_vote_kind - ("vote_kind", Baking_state.consensus_vote_kind_encoding) - ~pp2:Operation_hash.pp - ("ophash", Operation_hash.encoding) - ~pp3:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) - ~pp4:pp_int32 - ("level", Data_encoding.int32) - ~pp5:Round.pp - ("round", Round.encoding) + ~msg:"injected {operation_information}{operation_hash}" + ~pp1:Op_info_for_logging.pp + ("operation_information", Op_info_for_logging.encoding) + ~pp2:(fun fmt oph -> + Format.fprintf fmt "@ (operation hash: %a)" Operation_hash.pp oph) + ("operation_hash", Operation_hash.encoding) + + let emit_consensus_op_injected unsigned_consensus_op ophash = + emit + consensus_op_injected + ( Op_info_for_logging.of_unsigned_consensus_vote unsigned_consensus_op, + ophash ) let attach_dal_attestation = declare_5 @@ -928,7 +1051,7 @@ module Actions = struct "ready to attach DAL attestation for level {attestation_level}, round \ {round}, with bitset {bitset} for {delegate} to attest slots \ published at level {published_level}" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) ~pp2:Z.pp_print ("bitset", Data_encoding.n) ("published_level", Data_encoding.int32) @@ -941,7 +1064,7 @@ module Actions = struct ~name:"not_in_dal_committee" ~level:Notice ~msg:"{delegate} has no assigned DAL shards at level {attestation_level}" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) ("attestation_level", Data_encoding.int32) let missing_companion_key_for_dal_with_bls = @@ -953,7 +1076,7 @@ module Actions = struct "Cannot issue an attestation with DAL because the BLS consensus key \ has no corresponding companion key. Crafting the attestation without \ DAL at level {attestation_level} for {delegate}" - ("delegate", Baking_state_types.Delegate_id.encoding) + ("delegate", Delegate_id.encoding) ("attestation_level", Data_encoding.int32) let synchronizing_round = @@ -974,11 +1097,10 @@ module Actions = struct "prepare forging block at level {level}, round {round} for {delegate}" ~pp1:pp_int32 ~pp2:Round.pp - ~pp3:Baking_state_types.Delegate.pp + ~pp3:Delegate.pp ("level", Data_encoding.int32) ("round", Round.encoding) - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ("delegate", Delegate.encoding_for_logging__cannot_decode) let forging_block = declare_4 @@ -986,15 +1108,18 @@ module Actions = struct ~name:"forging_block" ~level:Info ~msg: - "forging block at level {level}, round {round} for {delegate} (force \ - apply: {force_apply})" + "forging block at level {level}, round {round}{delegate}(force apply: \ + {force_apply})" ~pp1:pp_int32 ~pp2:Round.pp - ~pp3:Baking_state_types.Delegate.pp + ~pp3:(fun fmt -> + Format.fprintf + fmt + "@ for@ delegate@ %a@ " + Delegate.pp_without_companion_key) ("level", Data_encoding.int32) ("round", Round.encoding) - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ("delegate", Delegate.encoding_for_logging__cannot_decode) ("force_apply", Data_encoding.bool) let delayed_block_injection = @@ -1011,9 +1136,8 @@ module Actions = struct ~pp2:pp_int32 ("round", Round.encoding) ~pp3:Round.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) - ~pp4:Baking_state_types.Delegate.pp + ("delegate", Delegate.encoding_for_logging__cannot_decode) + ~pp4:Delegate.pp let injecting_block = declare_3 @@ -1023,11 +1147,10 @@ module Actions = struct ~msg:"injecting block at level {level}, round {round} for {delegate}" ~pp1:pp_int32 ~pp2:Round.pp - ~pp3:Baking_state_types.Delegate.pp + ~pp3:Delegate.pp ("level", Data_encoding.int32) ("round", Round.encoding) - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ("delegate", Delegate.encoding_for_logging__cannot_decode) let block_injected = declare_5 @@ -1036,28 +1159,31 @@ module Actions = struct ~name:"block_injected" ~level:Notice ~msg: - "block {block} at level {level}, round {round} injected for \ - {delegate}{manager_operations_infos}" + "block {block} at level {level}, round {round} \ + injected{delegate}{manager_operations_infos}" ~pp1:Block_hash.pp ~pp2:pp_int32 ~pp3:Round.pp - ~pp4:Baking_state_types.Delegate.pp + ~pp4:(fun fmt -> + Format.fprintf + fmt + "@ for@ delegate@ %a" + Delegate.pp_without_companion_key) ~pp5: (Format.pp_print_option - (fun fmt Baking_state.{manager_operation_number; total_fees} -> + (fun fmt {manager_operation_number; total_fees} -> Format.fprintf fmt - " with %d manager operations summing %a μtz in fees" + "@ with %d manager operations@ summing up to %a μtz in fees" manager_operation_number pp_int64 total_fees)) ("block", Block_hash.encoding) ("level", Data_encoding.int32) ("round", Round.encoding) - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ("delegate", Delegate.encoding_for_logging__cannot_decode) ( "manager_operations_infos", - Data_encoding.option Baking_state.manager_operations_infos_encoding ) + Data_encoding.option manager_operations_infos_encoding ) let block_injection_failed = declare_2 @@ -1070,17 +1196,19 @@ module Actions = struct ("trace", Error_monad.trace_encoding) ~pp2:Error_monad.pp_print_trace - let signing_consensus_vote = - declare_2 + let signing_consensus_op = + declare_1 ~section - ~name:"signing_consensus_vote" + ~name:"signing_consensus_operation" ~level:Info - ~msg:"signing {vote_kind} for {delegate}" - ~pp1:Baking_state.pp_consensus_vote_kind - ("vote_kind", Baking_state.consensus_vote_kind_encoding) - ~pp2:Baking_state_types.Delegate.pp - ( "delegate", - Baking_state_types.Delegate.encoding_for_logging__cannot_decode ) + ~msg:"signing {operation_information}" + ~pp1:Op_info_for_logging.pp + ("operation_information", Op_info_for_logging.encoding) + + let emit_signing_consensus_op unsigned_consensus_op = + emit + signing_consensus_op + (Op_info_for_logging.of_unsigned_consensus_vote unsigned_consensus_op) let invalid_json_file = declare_1 @@ -1150,10 +1278,8 @@ module Actions = struct ~msg: "The following delegates have no attesting rights at level {level}: \ {delegates}" - ~pp1:(Format.pp_print_list Baking_state_types.Key.pp) - ( "delegates", - Data_encoding.list - Baking_state_types.Key.encoding_for_logging__cannot_decode ) + ~pp1:(Format.pp_print_list Key.pp) + ("delegates", Data_encoding.list Key.encoding_for_logging__cannot_decode) ~pp2:pp_int32 ("level", Data_encoding.int32) diff --git a/src/proto_alpha/lib_delegate/baking_lib.ml b/src/proto_alpha/lib_delegate/baking_lib.ml index 45260ca319cc30744331da2a427a101f8d68e5df..ccfe3895e16251d931e8b7b6ca1958fa5dfb6945 100644 --- a/src/proto_alpha/lib_delegate/baking_lib.ml +++ b/src/proto_alpha/lib_delegate/baking_lib.ml @@ -85,7 +85,7 @@ let preattest (cctxt : Protocol_client_context.full) ?(force = false) delegates = let open State_transitions in let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let cache = Baking_cache.Block_cache.create 10 in let* _, current_proposal = get_current_proposal cctxt ~cache () in let config = Baking_configuration.make ~force () in @@ -128,7 +128,7 @@ let preattest (cctxt : Protocol_client_context.full) ?(force = false) delegates let attest (cctxt : Protocol_client_context.full) ?(force = false) delegates = let open State_transitions in let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let cache = Baking_cache.Block_cache.create 10 in let* _, current_proposal = get_current_proposal cctxt ~cache () in let config = Baking_configuration.make ~force () in @@ -369,7 +369,7 @@ let propose (cctxt : Protocol_client_context.full) ?minimal_fees ?force_apply_from_round ?(force = false) ?(minimal_timestamp = false) ?extra_operations ?data_dir ?state_recorder delegates = let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let cache = Baking_cache.Block_cache.create 10 in let* _block_stream, current_proposal = get_current_proposal cctxt ~cache () in let config = @@ -538,7 +538,7 @@ let repropose (cctxt : Protocol_client_context.full) ?(force = false) delegates = let open Lwt_result_syntax in let open Baking_state in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let cache = Baking_cache.Block_cache.create 10 in let* _block_stream, current_proposal = get_current_proposal cctxt ~cache () in let config = Baking_configuration.make ~force () in @@ -821,7 +821,7 @@ let bake (cctxt : Protocol_client_context.full) ?dal_node_rpc_ctxt ?minimal_fees ?extra_operations ?(monitor_node_mempool = true) ?data_dir ?(count = 1) ?votes ?state_recorder delegates = let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let config = Baking_configuration.make ?minimal_fees diff --git a/src/proto_alpha/lib_delegate/baking_scheduling.ml b/src/proto_alpha/lib_delegate/baking_scheduling.ml index b007199c193018ea0589f1a4c6cde047c1c9acfd..3a65c8616a61e362a2e1aff2b5f594608003736c 100644 --- a/src/proto_alpha/lib_delegate/baking_scheduling.ml +++ b/src/proto_alpha/lib_delegate/baking_scheduling.ml @@ -988,7 +988,7 @@ let run cctxt ?dal_node_rpc_ctxt ?canceler ?(stop_on_event = fun _ -> false) ?(on_error = fun _ -> Lwt_result_syntax.return_unit) ?constants ~chain config delegates = let open Lwt_result_syntax in - let*! () = Events.(emit Baking_events.Delegates.delegates_used delegates) in + let*! () = Events.(emit Baking_events.Launch.keys_used delegates) in let* chain_id = Shell_services.Chain.chain_id cctxt ~chain () in let*! () = Events.emit Baking_events.Node_rpc.chain_id chain_id in let* constants = diff --git a/src/proto_alpha/lib_delegate/baking_state.ml b/src/proto_alpha/lib_delegate/baking_state.ml index bee661d3fe7225cce293f0319423eec060f87d6f..fbf2fe724983b8bea1eca6563c07fdd04f2f57aa 100644 --- a/src/proto_alpha/lib_delegate/baking_state.ml +++ b/src/proto_alpha/lib_delegate/baking_state.ml @@ -803,17 +803,6 @@ module Events = struct ~level:Warning ~msg:"found an outdated or corrupted baking state: discarding it" () - - let companion_key_is_not_in_wallet = - declare_2 - ~section:[Protocol.name; "baker"; "delegates"] - ~name:"companion_key_is_not_in_wallet" - ~level:Error - ~msg: - "Companion key {companion_key} is not provided in the wallet but \ - registered in the protocol for {delegate}" - ("delegate", Baking_state_types.Delegate_id.encoding) - ("companion_key", Environment.Bls.Public_key_hash.encoding) end type state_data = { @@ -975,81 +964,22 @@ let may_load_attestable_data state = (* Helpers *) -module DelegateSet = struct - include Set.Make (struct - type t = Baking_state_types.Key.t - - let compare Baking_state_types.Key.{id = pkh; _} - Baking_state_types.Key.{id = pkh'; _} = - Baking_state_types.Key_id.compare pkh pkh' - end) - - let find_pkh pkh s = - let exception Found of elt in - try - iter - (fun ({id; _} as delegate) -> - if - Signature.Public_key_hash.equal - pkh - (Baking_state_types.Key_id.to_pkh id) - then raise (Found delegate) - else ()) - s ; - None - with Found d -> Some d -end - let delegate_slots attesting_rights delegates = let open Lwt_syntax in - let own_delegates = DelegateSet.of_list delegates in + let known_keys = Key.Set.of_list delegates in let* own_delegate_first_slots, own_delegate_slots, all_delegate_voting_power = Lwt_list.fold_left_s - (fun (own_list, own_map, all_map) slot -> - let { - Plugin.RPC.Validators.consensus_key; - companion_key; - delegate; - slots; - level = _; - } = - slot - in + (fun (own_list, own_map, all_map) validator -> + let {Plugin.RPC.Validators.slots; _} = validator in let first_slot = Stdlib.List.hd slots in let attesting_power = List.length slots in let all_map = SlotMap.add first_slot attesting_power all_map in let* own_list, own_map = - match DelegateSet.find_pkh consensus_key own_delegates with - | Some consensus_key -> - let* companion_key = - match companion_key with - | None -> return None - | Some companion_key -> ( - match - DelegateSet.find_pkh (Bls companion_key) own_delegates - with - | None -> - let* () = - Events.( - emit - companion_key_is_not_in_wallet - (Delegate_id.of_pkh delegate, companion_key)) - in - return None - | Some companion_key -> return (Some companion_key)) - in - let attesting_slot = - { - delegate = - { - consensus_key; - delegate_id = Delegate_id.of_pkh delegate; - companion_key; - }; - first_slot; - attesting_power; - } - in + let* delegate_opt = Delegate.of_validator ~known_keys validator in + match delegate_opt with + | None -> return (own_list, own_map) + | Some delegate -> + let attesting_slot = {delegate; first_slot; attesting_power} in return ( attesting_slot :: own_list, List.fold_left @@ -1057,7 +987,6 @@ let delegate_slots attesting_rights delegates = SlotMap.add slot attesting_slot own_map) own_map slots ) - | None -> return (own_list, own_map) in return (own_list, own_map, all_map)) ([], SlotMap.empty, SlotMap.empty) @@ -1394,77 +1323,6 @@ let pp_timeout_kind fmt = function Round.pp at_round -let pp_forge_event fmt = - let open Format in - let pp_signed_consensus_vote fmt {unsigned_consensus_vote; _} = - fprintf - fmt - "for delegate %a at level %ld (round %a)" - Delegate.pp - unsigned_consensus_vote.delegate - (Raw_level.to_int32 unsigned_consensus_vote.vote_consensus_content.level) - Round.pp - unsigned_consensus_vote.vote_consensus_content.round - in - function - | Block_ready {signed_block_header; round; delegate; _} -> - fprintf - fmt - "block ready for delegate: %a at level %ld (round: %a)" - Delegate.pp - delegate - signed_block_header.shell.level - Round.pp - round - | Preattestation_ready signed_preattestation -> - fprintf - fmt - "preattestation ready %a" - pp_signed_consensus_vote - signed_preattestation - | Attestation_ready signed_attestation -> - fprintf - fmt - "attestation ready %a" - pp_signed_consensus_vote - signed_attestation - -let pp_event fmt = function - | New_valid_proposal proposal -> - Format.fprintf - fmt - "new valid proposal received: %a" - pp_block_info - proposal.block - | New_head_proposal proposal -> - Format.fprintf - fmt - "new head proposal received: %a" - pp_block_info - proposal.block - | Prequorum_reached (candidate, preattestations) -> - Format.fprintf - fmt - "prequorum reached with %d preattestations for %a at round %a" - (List.length preattestations) - Block_hash.pp - candidate.Operation_worker.hash - Round.pp - candidate.round_watched - | Quorum_reached (candidate, attestations) -> - Format.fprintf - fmt - "quorum reached with %d attestations for %a at round %a" - (List.length attestations) - Block_hash.pp - candidate.Operation_worker.hash - Round.pp - candidate.round_watched - | New_forge_event forge_event -> - Format.fprintf fmt "new forge event: %a" pp_forge_event forge_event - | Timeout kind -> - Format.fprintf fmt "timeout reached: %a" pp_timeout_kind kind - let pp_short_event fmt = let open Format in function diff --git a/src/proto_alpha/lib_delegate/baking_state.mli b/src/proto_alpha/lib_delegate/baking_state.mli index 5c236fbe16b46b55c92dd1e725ee743b1b5df9be..b16fc761fe6a5e30b18fed59bfd75532b71be045 100644 --- a/src/proto_alpha/lib_delegate/baking_state.mli +++ b/src/proto_alpha/lib_delegate/baking_state.mli @@ -409,8 +409,6 @@ type forge_event = val forge_event_encoding_for_logging__cannot_decode : forge_event Data_encoding.t -val pp_forge_event : Format.formatter -> forge_event -> unit - (** [forge_worker_hooks] type that allows interactions with the forge worker. Hooks are needed in order to break a circular dependency. *) type forge_worker_hooks = { @@ -552,6 +550,4 @@ type event = fail. *) val event_encoding_for_logging__cannot_decode : event Data_encoding.t -val pp_event : Format.formatter -> event -> unit - val pp_short_event : Format.formatter -> event -> unit diff --git a/src/proto_alpha/lib_delegate/baking_state_types.ml b/src/proto_alpha/lib_delegate/baking_state_types.ml index b264ff029cfe6baa40880ab1e406cb7a5a0f66af..043219aa990cfd421fe894f3adf95f354c7141c8 100644 --- a/src/proto_alpha/lib_delegate/baking_state_types.ml +++ b/src/proto_alpha/lib_delegate/baking_state_types.ml @@ -12,6 +12,8 @@ module Key_id = struct let compare = Signature.Public_key_hash.compare + let equal = Signature.Public_key_hash.equal + let encoding = Signature.Public_key_hash.encoding let pp = Signature.Public_key_hash.pp @@ -23,7 +25,7 @@ module Key = struct (** A consensus key (aka, a validator) is identified by its alias name, its public key, its public key hash, and its secret key. *) type t = { - alias : string option; + alias : string; id : Key_id.t; public_key : Signature.Public_key.t; secret_key_uri : Client_keys.sk_uri; @@ -44,66 +46,158 @@ module Key = struct logging; decoding is impossible (%s)" __LOC__)) (obj3 - (req "alias" (option string)) + (req "alias" string) (req "public_key" Signature.Public_key.encoding) (req "public_key_hash" Signature.Public_key_hash.encoding)) let pp fmt {alias; id; _} = - match alias with - | None -> Format.fprintf fmt "%a" Signature.Public_key_hash.pp id - | Some alias -> - Format.fprintf fmt "%s (%a)" alias Signature.Public_key_hash.pp id + Format.fprintf fmt "'%s' (%a)" alias Signature.Public_key_hash.pp id + + let is_bls t = Signature.Public_key_hash.is_bls (Key_id.to_pkh t.id) + + module Set = struct + include Set.Make (struct + type nonrec t = t + + let compare {id; _} {id = id'; _} = Key_id.compare id id' + end) + + let find_pkh pkh s = + let exception Found of elt in + try + iter + (fun ({id; _} as delegate) -> + if Signature.Public_key_hash.equal pkh (Key_id.to_pkh id) then + raise (Found delegate) + else ()) + s ; + None + with Found d -> Some d + end end -module Delegate_id = struct - type t = Signature.public_key_hash +module Maybe_known_key = struct + type t = Known_key of Key.t | Id_only of Key_id.t - let of_pkh pkh = pkh + let key_id = function Known_key key -> key.id | Id_only id -> id - let to_pkh pkh = pkh - - let equal = Signature.Public_key_hash.equal + let encoding_for_logging__cannot_decode = + let open Data_encoding in + conv + (function + | Known_key {alias; public_key; id; _} -> + (Some alias, Some public_key, id) + | Id_only pkh -> (None, None, pkh)) + (fun _ -> + Stdlib.failwith + (Format.sprintf + "This event should only be used to encode events; decoding is \ + impossible: %s" + __LOC__)) + (obj3 + (opt "alias" string) + (opt "public_key" Signature.Public_key.encoding) + (req "public_key_hash" Signature.Public_key_hash.encoding)) - let encoding = Signature.Public_key_hash.encoding + let pp fmt = function + | Known_key key -> Key.pp fmt key + | Id_only id -> Key_id.pp fmt id - let pp = Signature.Public_key_hash.pp + let make ~known_keys pkh = + match Key.Set.find_pkh pkh known_keys with + | None -> Id_only pkh + | Some key -> Known_key key end +module Delegate_id = Key_id + module Delegate = struct + type manager_key = Maybe_known_key.t + type t = { + manager_key : manager_key; consensus_key : Key.t; companion_key : Key.t option; - delegate_id : Delegate_id.t; } + let delegate_id t = Maybe_known_key.key_id t.manager_key + let encoding_for_logging__cannot_decode = let open Data_encoding in conv - (fun {consensus_key; companion_key; delegate_id} -> - (consensus_key, delegate_id, companion_key)) - (fun (consensus_key, delegate_id, companion_key) -> - {consensus_key; delegate_id; companion_key}) + (fun {manager_key; consensus_key; companion_key} -> + (manager_key, consensus_key, companion_key)) + (fun (manager_key, consensus_key, companion_key) -> + {manager_key; consensus_key; companion_key}) (obj3 + (req "manager_key" Maybe_known_key.encoding_for_logging__cannot_decode) (req "consensus_key" Key.encoding_for_logging__cannot_decode) - (req "delegate" Delegate_id.encoding) (opt "companion_key" Key.encoding_for_logging__cannot_decode)) - let pp fmt {consensus_key; delegate_id; companion_key} = - let str_companion_key = - match companion_key with - | Some companion_key -> - Format.asprintf " with companion key %a" Key.pp companion_key - | None -> "" - in - if Signature.Public_key_hash.equal consensus_key.id delegate_id then - Format.fprintf fmt "%a%s" Key.pp consensus_key str_companion_key - else - Format.fprintf - fmt - "%a%s@,on behalf of %a" - Key.pp - consensus_key - str_companion_key - Delegate_id.pp - delegate_id + let pp_without_companion_key fmt + {manager_key; consensus_key; companion_key = _} = + Format.fprintf + fmt + "%a@ with@ consensus key@ %a" + Maybe_known_key.pp + manager_key + Key.pp + consensus_key + + let pp fmt ({manager_key = _; consensus_key = _; companion_key} as t) = + pp_without_companion_key fmt t ; + match companion_key with + | None -> () + | Some companion_key -> + Format.fprintf fmt "@ and@ companion key@ %a" Key.pp companion_key + + let companion_key_is_not_in_wallet = + let open Internal_event.Simple in + declare_2 + ~section:[Protocol.name; "baker"; "delegates"] + ~name:"companion_key_is_not_in_wallet" + ~level:Error + ~msg: + "Companion key {companion_key} for {delegate} is absent from the \ + client wallet. The baker will only be able to issue attestations \ + without DAL for this delegate, and the delegate will lose DAL \ + rewards." + ("delegate", encoding_for_logging__cannot_decode) + ("companion_key", Environment.Bls.Public_key_hash.encoding) + + let of_validator ~known_keys + { + Plugin.RPC.Validators.consensus_key = consensus_pkh; + companion_key = companion_bls_pkh_opt; + delegate = manager_pkh; + slots = _; + level = _; + } = + let open Lwt_syntax in + match Key.Set.find_pkh consensus_pkh known_keys with + | None -> return_none + | Some consensus_key -> + let manager_key = Maybe_known_key.make ~known_keys manager_pkh in + let* companion_key = + match companion_bls_pkh_opt with + | None -> return_none + | Some companion_bls_pkh -> + let companion_key = + Key.Set.find_pkh (Bls companion_bls_pkh) known_keys + in + let* () = + if + Option.is_none companion_key + && Signature.Public_key_hash.is_bls consensus_pkh + then + Events.( + emit + companion_key_is_not_in_wallet + ( {manager_key; consensus_key; companion_key}, + companion_bls_pkh )) + else return_unit + in + return companion_key + in + return_some {manager_key; consensus_key; companion_key} end diff --git a/src/proto_alpha/lib_delegate/baking_state_types.mli b/src/proto_alpha/lib_delegate/baking_state_types.mli index 5a0a268003709aae3896aac4ce567b16457c0c38..a1df3f4d7fb76dd2fab1f4b7e98275f1e9567e4a 100644 --- a/src/proto_alpha/lib_delegate/baking_state_types.mli +++ b/src/proto_alpha/lib_delegate/baking_state_types.mli @@ -16,6 +16,8 @@ module Key_id : sig val compare : t -> t -> int + val equal : t -> t -> bool + val encoding : t Data_encoding.t val pp : Format.formatter -> t -> unit @@ -29,14 +31,14 @@ end module Key : sig type t = private { - alias : string option; + alias : string; id : Key_id.t; public_key : Signature.public_key; secret_key_uri : Client_keys.sk_uri; } val make : - alias:string option -> + alias:string -> public_key:Signature.public_key -> public_key_hash:Signature.public_key_hash -> secret_key_uri:Client_keys.sk_uri -> @@ -51,32 +53,26 @@ module Key : sig val encoding_for_logging__cannot_decode : t Data_encoding.t val pp : Format.formatter -> t -> unit -end - -(** {2 Delegates slots type and functions} *) -module Delegate_id : sig - type t - (** Only use at library frontiers *) - val of_pkh : Signature.public_key_hash -> t - - (** Only use at library frontiers *) - val to_pkh : t -> Signature.public_key_hash - - val equal : t -> t -> bool + val is_bls : t -> bool - val encoding : t Data_encoding.t - - val pp : Format.formatter -> t -> unit + module Set : Set.S with type elt = t end +(** {2 Delegates slots type and functions} *) +module Delegate_id : module type of Key_id + module Delegate : sig - type t = { + type manager_key + + type t = private { + manager_key : manager_key; consensus_key : Key.t; companion_key : Key.t option; - delegate_id : Delegate_id.t; } + val delegate_id : t -> Delegate_id.t + (** Partial encoding for {!t} that omits secret keys to avoid leaking them in event logs; see {!Key.encoding_for_logging__cannot_decode}. @@ -86,4 +82,19 @@ module Delegate : sig val encoding_for_logging__cannot_decode : t Data_encoding.t val pp : Format.formatter -> t -> unit + + (** Prints the manager key and consensus key but not the companion + key. *) + val pp_without_companion_key : Format.formatter -> t -> unit + + (** Builds a {!t} from an element of the output of + {!Plugin.RPC.Validators.get}, if the consensus key is present in + [known_keys]; otherwise, returns [None]. + + If the consensus key is a known BLS key and the validator + argument contains a companion key but that companion key is not + in [known_keys], emits an error event but nevertheless returns a + {!t} where [companion_key = None]. (This function is in Lwt to + be able to emit this event.) *) + val of_validator : known_keys:Key.Set.t -> RPC.Validators.t -> t option Lwt.t end diff --git a/src/proto_alpha/lib_delegate/node_rpc.ml b/src/proto_alpha/lib_delegate/node_rpc.ml index 3fe3094d37b6742caed48ff508853bd0936e6e99..309901416ea2745531c3d746fd7a8555043724f8 100644 --- a/src/proto_alpha/lib_delegate/node_rpc.ml +++ b/src/proto_alpha/lib_delegate/node_rpc.ml @@ -425,7 +425,9 @@ let dal_attestable_slots (dal_node_rpc_ctxt : Tezos_rpc.Context.generic) let attested_level = Int32.succ attestation_level in List.map (fun (delegate_slot : delegate_slot) -> - let delegate_id = delegate_slot.delegate.delegate_id in + let delegate_id = + Baking_state_types.Delegate.delegate_id delegate_slot.delegate + in ( delegate_id, get_attestable_slots dal_node_rpc_ctxt delegate_id ~attested_level )) delegate_slots diff --git a/src/proto_alpha/lib_delegate/test/mockup_simulator/mockup_simulator.ml b/src/proto_alpha/lib_delegate/test/mockup_simulator/mockup_simulator.ml index 93bc24fe6f00ffae6cb40dffe91a8bfd444e41ce..ab5c92ded09044674465b7207a9fb289dd87df9b 100644 --- a/src/proto_alpha/lib_delegate/test/mockup_simulator/mockup_simulator.ml +++ b/src/proto_alpha/lib_delegate/test/mockup_simulator/mockup_simulator.ml @@ -966,7 +966,6 @@ let baker_process ~(delegates : Baking_state_types.Key.t list) ~base_dir let* () = List.iter_es (fun ({alias; public_key; id; secret_key_uri} : Baking_state_types.Key.t) -> - let name = alias |> WithExceptions.Option.get ~loc:__LOC__ in let* public_key_uri = Client_keys.neuterize secret_key_uri in let pkh = Baking_state_types.Key_id.to_pkh id in Client_keys.register_key @@ -974,7 +973,7 @@ let baker_process ~(delegates : Baking_state_types.Key.t list) ~base_dir ~force:false (pkh, public_key_uri, secret_key_uri) ~public_key - name) + alias) delegates in let context_index = @@ -1289,7 +1288,7 @@ let make_baking_delegate (secret : Tezos_mockup_commands.Mockup_wallet.bootstrap_secret) ) : Baking_state_types.Key.t = Baking_state_types.Key.make - ~alias:(Some secret.name) + ~alias:secret.name ~public_key_hash:account.public_key_hash ~public_key:(account.public_key |> WithExceptions.Option.get ~loc:__LOC__) ~secret_key_uri:secret.sk_uri