diff --git a/devtools/testnet_experiment_tools/tool_alpha.ml b/devtools/testnet_experiment_tools/tool_alpha.ml index 2db96ab79bc029c47ceaebff9763a28c7652d4a0..ccc21c83cd537bf53a380780bde8574219dd8cc7 100644 --- a/devtools/testnet_experiment_tools/tool_alpha.ml +++ b/devtools/testnet_experiment_tools/tool_alpha.ml @@ -207,7 +207,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.Consensus_key.make + Baking_state.Key.make ~alias:(Some alias) ~public_key_hash ~public_key @@ -221,8 +221,7 @@ let get_delegates (cctxt : Protocol_client_context.full) = cctxt (List.filter_map (function - | {Baking_state.Consensus_key.alias = Some alias; _} -> Some alias - | _ -> None) + | {Baking_state.Key.alias = Some alias; _} -> Some alias | _ -> None) delegates) in let delegates_no_duplicates = List.sort_uniq compare delegates in diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index b21e6885be24e10e39ed41a5165b70d2d449ac0a..4a81bd540da9e58266aa7186eecd21082d5a4c49 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -57,6 +57,11 @@ RPC Changes a given delegate (``none`` if not yet set), and the list of pending updates to that key in the following cycles. (MR :gl:`!17236`) +- Updated ``GET + /chains//blocks//helpers/validators?delegate=&level=`` + with the new field ``companion_key`` which returns the active companion key for + the given ``delegate`` and ``level``. (MR :gl:`!17703`) + Operation receipts ------------------ diff --git a/src/proto_alpha/lib_delegate/baking_actions.ml b/src/proto_alpha/lib_delegate/baking_actions.ml index b6464b02fc13c4671ac53645c227a06f1fb29cc7..48ca71b4086b17fe653b85db7d9dd30d4b79acd8 100644 --- a/src/proto_alpha/lib_delegate/baking_actions.ml +++ b/src/proto_alpha/lib_delegate/baking_actions.ml @@ -247,7 +247,7 @@ let sign_block_header global_state proposer unsigned_block_header = (may_sign_block cctxt block_location - ~delegate:proposer.Consensus_key.id + ~delegate:proposer.Key.id ~level ~round [@profiler.record_s {verbosity = Debug} "may sign"]) in @@ -964,7 +964,7 @@ let compute_round (proposal : proposal) round_durations = let notice_delegates_without_slots all_delegates delegate_slots level = let delegates_without_slots = List.filter - (fun {Baking_state.Consensus_key.id; _} -> + (fun {Baking_state.Key.id; _} -> not @@ List.exists (fun ({delegate = {consensus_key; _}; _} : delegate_slot) -> diff --git a/src/proto_alpha/lib_delegate/baking_commands.ml b/src/proto_alpha/lib_delegate/baking_commands.ml index 8cb1cbd682297a1c32c143ae49b6dfe0f2d3e542..3bf4630c57d6df3fd51d14e05a7bc53fd2f2b70f 100644 --- a/src/proto_alpha/lib_delegate/baking_commands.ml +++ b/src/proto_alpha/lib_delegate/baking_commands.ml @@ -305,7 +305,7 @@ let get_delegates (cctxt : Protocol_client_context.full) (pkhs : Signature.public_key_hash list) = let open Lwt_result_syntax in let proj_delegate (alias, public_key_hash, public_key, secret_key_uri) = - Baking_state.Consensus_key.make + Baking_state.Key.make ~alias:(Some alias) ~public_key_hash ~public_key @@ -328,8 +328,7 @@ let get_delegates (cctxt : Protocol_client_context.full) cctxt (List.filter_map (function - | {Baking_state.Consensus_key.alias = Some alias; _} -> Some alias - | _ -> None) + | {Baking_state.Key.alias = Some alias; _} -> Some alias | _ -> None) 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 b96204b7fbff80bd277e4c43ba891fc13f4353cf..1a64645fafd29ef936b61deb81f3896e9276a1ed 100644 --- a/src/proto_alpha/lib_delegate/baking_events.ml +++ b/src/proto_alpha/lib_delegate/baking_events.ml @@ -604,13 +604,11 @@ module Delegates = struct Format.fprintf ppf "@[@,%a@]" - Format.( - pp_print_list ~pp_sep:pp_print_cut Baking_state.Consensus_key.pp) + Format.(pp_print_list ~pp_sep:pp_print_cut Baking_state.Key.pp) delegates) ( "delegates", Data_encoding.list - Baking_state.Consensus_key - .consensus_key_without_sk_encoding__cannot_decode ) + Baking_state.Key.consensus_key_without_sk_encoding__cannot_decode ) end module Scheduling = struct @@ -1126,8 +1124,8 @@ module Actions = struct ~msg: "The following delegates have no attesting rights at level {level}: \ {delegates}" - ~pp1:(Format.pp_print_list Baking_state.Consensus_key.pp) - ("delegates", Data_encoding.list Baking_state.Consensus_key.encoding) + ~pp1:(Format.pp_print_list Baking_state.Key.pp) + ("delegates", Data_encoding.list Baking_state.Key.encoding) ~pp2:pp_int32 ("level", Data_encoding.int32) diff --git a/src/proto_alpha/lib_delegate/baking_highwatermarks.ml b/src/proto_alpha/lib_delegate/baking_highwatermarks.ml index 4c9824b6ca9f947d8624cbfe56a28e2e1e3a16a6..55a76f0e43c22c4f27505762f9564be00e4542e9 100644 --- a/src/proto_alpha/lib_delegate/baking_highwatermarks.ml +++ b/src/proto_alpha/lib_delegate/baking_highwatermarks.ml @@ -99,9 +99,9 @@ let () = (fun highwatermark -> Block_previously_attested highwatermark) module DelegateMap = Map.Make (struct - type t = Baking_state.Consensus_key_id.t + type t = Baking_state.Key_id.t - let compare = Baking_state.Consensus_key_id.compare + let compare = Baking_state.Key_id.compare end) let highwatermark_delegate_map_encoding = @@ -112,7 +112,7 @@ let highwatermark_delegate_map_encoding = fun l -> List.fold_left (fun map (k, v) -> add k v map) empty l) (list (obj2 - (req "delegate" Baking_state.Consensus_key_id.encoding) + (req "delegate" Baking_state.Key_id.encoding) (req "highwatermark" highwatermark_encoding))) type highwatermarks = { diff --git a/src/proto_alpha/lib_delegate/baking_highwatermarks.mli b/src/proto_alpha/lib_delegate/baking_highwatermarks.mli index cfc15b69accce94e45c692e499ac8a1feb8c531d..26b9f4acfbcb8bec990653fe0384f5f80ea1558d 100644 --- a/src/proto_alpha/lib_delegate/baking_highwatermarks.mli +++ b/src/proto_alpha/lib_delegate/baking_highwatermarks.mli @@ -43,29 +43,21 @@ val load : val may_sign_block : #Protocol_client_context.full -> [`Highwatermarks] Baking_files.location -> - delegate:Baking_state.Consensus_key_id.t -> + delegate:Baking_state.Key_id.t -> level:int32 -> round:Round.t -> bool tzresult Lwt.t val may_sign_preattestation : - t -> - delegate:Baking_state.Consensus_key_id.t -> - level:int32 -> - round:Round.t -> - bool + t -> delegate:Baking_state.Key_id.t -> level:int32 -> round:Round.t -> bool val may_sign_attestation : - t -> - delegate:Baking_state.Consensus_key_id.t -> - level:int32 -> - round:Round.t -> - bool + t -> delegate:Baking_state.Key_id.t -> level:int32 -> round:Round.t -> bool val record_block : #Protocol_client_context.full -> [`Highwatermarks] Baking_files.location -> - delegate:Baking_state.Consensus_key_id.t -> + delegate:Baking_state.Key_id.t -> level:int32 -> round:Round.t -> unit tzresult Lwt.t @@ -73,7 +65,7 @@ val record_block : val record_preattestation : #Protocol_client_context.full -> [`Highwatermarks] Baking_files.location -> - delegate:Baking_state.Consensus_key_id.t -> + delegate:Baking_state.Key_id.t -> level:int32 -> round:Round.t -> unit tzresult Lwt.t @@ -81,7 +73,7 @@ val record_preattestation : val record_attestation : #Protocol_client_context.full -> [`Highwatermarks] Baking_files.location -> - delegate:Baking_state.Consensus_key_id.t -> + delegate:Baking_state.Key_id.t -> level:int32 -> round:Round.t -> unit tzresult Lwt.t @@ -90,7 +82,7 @@ val record_all_preattestations : t -> #Protocol_client_context.full -> [`Highwatermarks] Baking_files.location -> - delegates:Baking_state.Consensus_key_id.t list -> + delegates:Baking_state.Key_id.t list -> level:int32 -> round:Round.t -> unit tzresult Lwt.t @@ -99,7 +91,7 @@ val record_all_attestations : t -> #Protocol_client_context.full -> [`Highwatermarks] Baking_files.location -> - delegates:Baking_state.Consensus_key_id.t list -> + delegates:Baking_state.Key_id.t list -> level:int32 -> round:Round.t -> unit tzresult Lwt.t diff --git a/src/proto_alpha/lib_delegate/baking_lib.mli b/src/proto_alpha/lib_delegate/baking_lib.mli index 20e2fd4c72c6c1155bbdcd7db76f53a1b072390c..55143721bca7c338039ed2a67eb12788f14dfd22 100644 --- a/src/proto_alpha/lib_delegate/baking_lib.mli +++ b/src/proto_alpha/lib_delegate/baking_lib.mli @@ -43,19 +43,19 @@ val bake : ?count:int -> ?votes:Baking_configuration.per_block_votes_config -> ?state_recorder:Baking_configuration.state_recorder_config -> - Baking_state.Consensus_key.t list -> + Baking_state.Key.t list -> unit tzresult Lwt.t val preattest : Protocol_client_context.full -> ?force:bool -> - Baking_state.Consensus_key.t list -> + Baking_state.Key.t list -> unit tzresult Lwt.t val attest : Protocol_client_context.full -> ?force:bool -> - Baking_state.Consensus_key.t list -> + Baking_state.Key.t list -> unit tzresult Lwt.t val propose : @@ -69,7 +69,7 @@ val propose : ?extra_operations:Baking_configuration.Operations_source.t -> ?context_path:string -> ?state_recorder:Baking_configuration.state_recorder_config -> - Baking_state.Consensus_key.t list -> + Baking_state.Key.t list -> unit tzresult Lwt.t (** [repropose] tries to bake a new block proposal on the same level @@ -80,5 +80,5 @@ val repropose : Protocol_client_context.full -> ?force:bool -> ?force_round:Round.t -> - Baking_state.Consensus_key.t list -> + Baking_state.Key.t list -> unit tzresult Lwt.t diff --git a/src/proto_alpha/lib_delegate/baking_nonces.ml b/src/proto_alpha/lib_delegate/baking_nonces.ml index 7857bb5c071949a4db17a1593a67762ab5c2f2a6..f7e99824a516f158bb9aa70d9e99d20cf452b97d 100644 --- a/src/proto_alpha/lib_delegate/baking_nonces.ml +++ b/src/proto_alpha/lib_delegate/baking_nonces.ml @@ -409,7 +409,7 @@ let generate_deterministic_nonce ?timeout secret_key_uri data = let generate_seed_nonce ?timeout (nonce_config : Baking_configuration.nonce_config) - (delegate : Baking_state.Consensus_key.t) level = + (delegate : Baking_state.Key.t) level = let open Lwt_result_syntax in let* nonce = match nonce_config with diff --git a/src/proto_alpha/lib_delegate/baking_nonces.mli b/src/proto_alpha/lib_delegate/baking_nonces.mli index 44c2ac915b9b45a24ebbebc0524710f02a5269b5..bc2e43fd55cefba1376a8a88a2a0414ce9c49d63 100644 --- a/src/proto_alpha/lib_delegate/baking_nonces.mli +++ b/src/proto_alpha/lib_delegate/baking_nonces.mli @@ -48,7 +48,7 @@ val load : val generate_seed_nonce : ?timeout:float -> Baking_configuration.nonce_config -> - Baking_state.Consensus_key.t -> + Baking_state.Key.t -> Raw_level.t -> (Nonce_hash.t * Nonce.t) tzresult Lwt.t diff --git a/src/proto_alpha/lib_delegate/baking_scheduling.ml b/src/proto_alpha/lib_delegate/baking_scheduling.ml index 6d9c017d813936b4f5cf106396203efc7a48c9fa..803e35d1c65ca800454c7213b346f9c8466caf80 100644 --- a/src/proto_alpha/lib_delegate/baking_scheduling.ml +++ b/src/proto_alpha/lib_delegate/baking_scheduling.ml @@ -897,7 +897,7 @@ let retry (cctxt : #Protocol_client_context.full) ?max_delay ~delay ~factor let try_resolve_consensus_keys cctxt key = let open Lwt_syntax in let levels_to_inspect = 50 in - let pkh = Consensus_key_id.to_pkh key.Consensus_key.id in + let pkh = Key_id.to_pkh key.Key.id in let* res = Plugin.Alpha_services.Delegate.deactivated cctxt (`Main, `Head 0) pkh in @@ -923,7 +923,13 @@ let try_resolve_consensus_keys cctxt key = | Error _ | Ok [] -> try_find_delegate_key (head_offset - 1) | Ok (Plugin.RPC.Validators. - {delegate; level = _; consensus_key = _; slots = _} + { + delegate; + level = _; + consensus_key = _; + companion_key = _; + slots = _; + } :: _) -> (* The primary registered key as delegate found. Return it. *) return delegate diff --git a/src/proto_alpha/lib_delegate/baking_scheduling.mli b/src/proto_alpha/lib_delegate/baking_scheduling.mli index b6f52af181ca3bdf1f0652d6420743cc283c2da9..8d46c9a6cd78a710006ece12e08e3ae5b435d04e 100644 --- a/src/proto_alpha/lib_delegate/baking_scheduling.mli +++ b/src/proto_alpha/lib_delegate/baking_scheduling.mli @@ -81,7 +81,7 @@ val run : ?constants:Constants.t -> chain:Chain_services.chain -> Baking_configuration.t -> - Baking_state.Consensus_key.t list -> + Baking_state.Key.t list -> unit tzresult Lwt.t (** {2 Functions only needed for the baking_lib} *) @@ -145,7 +145,7 @@ val create_initial_state : Operation_worker.t -> current_proposal:proposal -> ?constants:Constants.t -> - Baking_state.Consensus_key.t list -> + Baking_state.Key.t list -> state tzresult Lwt.t (** [automaton_loop ?stop_on_event baking_configuration on_error loop_state diff --git a/src/proto_alpha/lib_delegate/baking_state.ml b/src/proto_alpha/lib_delegate/baking_state.ml index 7a0228cd31a31a32724c330aab363781af3a394a..5a10844ea61aee30eb02205e5894d655f1539a67 100644 --- a/src/proto_alpha/lib_delegate/baking_state.ml +++ b/src/proto_alpha/lib_delegate/baking_state.ml @@ -29,7 +29,7 @@ open Baking_errors module Profiler = (val Profiler.wrap Baking_profiler.baker_profiler) -module Consensus_key_id = struct +module Key_id = struct type t = Signature.Public_key_hash.t let to_pkh pkh = pkh @@ -43,12 +43,12 @@ module Consensus_key_id = struct module Table = Signature.Public_key_hash.Table end -module Consensus_key = struct +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; - id : Consensus_key_id.t; + id : Key_id.t; public_key : Signature.Public_key.t; secret_key_uri : Client_keys.sk_uri; } @@ -110,26 +110,40 @@ module Delegate_id = struct end module Delegate = struct - type t = {consensus_key : Consensus_key.t; delegate_id : Delegate_id.t} + type t = { + consensus_key : Key.t; + companion_key : Key.t option; + delegate_id : Delegate_id.t; + } let encoding = let open Data_encoding in conv - (fun {consensus_key; delegate_id} -> (consensus_key, delegate_id)) - (fun (consensus_key, delegate_id) -> {consensus_key; delegate_id}) - (merge_objs - Consensus_key.encoding - (obj1 (req "delegate" Delegate_id.encoding))) - - let pp fmt {consensus_key; delegate_id} = + (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}) + (obj3 + (req "consensus_key" Key.encoding) + (req "delegate" Delegate_id.encoding) + (opt "companion_key" Key.encoding)) + + 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 - Consensus_key.pp fmt consensus_key + Format.fprintf fmt "%a%s" Key.pp consensus_key str_companion_key else Format.fprintf fmt - "%a@,on behalf of %a" - Consensus_key.pp + "%a%s@,on behalf of %a" + Key.pp consensus_key + str_companion_key Delegate_id.pp delegate_id end @@ -642,7 +656,7 @@ type global_state = { (* the validation mode used by the baker*) validation_mode : validation_mode; (* the delegates on behalf of which the baker is running *) - delegates : Consensus_key.t list; + delegates : Key.t list; cache : cache; dal_node_rpc_ctxt : Tezos_rpc.Context.generic option; } @@ -1059,9 +1073,9 @@ let may_load_attestable_data state = module DelegateSet = struct include Set.Make (struct - type t = Consensus_key.t + type t = Key.t - let compare Consensus_key.{id = pkh; _} Consensus_key.{id = pkh'; _} = + let compare Key.{id = pkh; _} Key.{id = pkh'; _} = Signature.Public_key_hash.compare pkh pkh' end) @@ -1082,16 +1096,29 @@ let delegate_slots attesting_rights delegates = let own_delegate_first_slots, own_delegate_slots, all_delegate_voting_power = List.fold_left (fun (own_list, own_map, all_map) slot -> - let {Plugin.RPC.Validators.consensus_key; delegate; slots; _} = slot in + let { + Plugin.RPC.Validators.consensus_key; + companion_key; + delegate; + slots; + level = _; + } = + slot + 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 = + Option.bind companion_key (fun companion_key -> + DelegateSet.find_pkh (Bls companion_key) own_delegates) + in let attesting_slot = { - delegate = {consensus_key; delegate_id = delegate}; + delegate = + {consensus_key; delegate_id = delegate; companion_key}; first_slot; attesting_power; } @@ -1217,7 +1244,7 @@ let pp_global_state fmt {chain_id; config; validation_mode; delegates; _} = config pp_validation_mode validation_mode - Format.(pp_print_list Consensus_key.pp) + Format.(pp_print_list Key.pp) delegates let pp_option pp fmt = function diff --git a/src/proto_alpha/lib_delegate/baking_state.mli b/src/proto_alpha/lib_delegate/baking_state.mli index 6dd99f47911fdab84eb64c0a52e32a4cae3c67bb..e38bb6b5384779ed08e33628ec808ccbd23f8e84 100644 --- a/src/proto_alpha/lib_delegate/baking_state.mli +++ b/src/proto_alpha/lib_delegate/baking_state.mli @@ -26,8 +26,10 @@ open Protocol open Alpha_context -(** {2 Consensus key type and functions} *) -module Consensus_key_id : sig +(** {2 Key type and functions} + + Used for both consensus keys and companion keys. *) +module Key_id : sig type t (** Only use at library frontiers *) @@ -46,10 +48,10 @@ module Consensus_key_id : sig end end -module Consensus_key : sig +module Key : sig type t = private { alias : string option; - id : Consensus_key_id.t; + id : Key_id.t; public_key : Signature.public_key; secret_key_uri : Client_keys.sk_uri; } @@ -89,7 +91,11 @@ module Delegate_id : sig end module Delegate : sig - type t = {consensus_key : Consensus_key.t; delegate_id : Delegate_id.t} + type t = { + consensus_key : Key.t; + companion_key : Key.t option; + delegate_id : Delegate_id.t; + } val encoding : t Data_encoding.t @@ -145,7 +151,7 @@ val compute_delegate_slots : ?block:Block_services.block -> level:int32 -> chain:Shell_services.chain -> - Consensus_key.t list -> + Key.t list -> delegate_slots tzresult Lwt.t (** {2 Consensus operations types functions} *) @@ -503,7 +509,7 @@ type global_state = { operation_worker : Operation_worker.t; mutable forge_worker_hooks : forge_worker_hooks; validation_mode : validation_mode; - delegates : Consensus_key.t list; + delegates : Key.t list; cache : cache; dal_node_rpc_ctxt : Tezos_rpc.Context.generic option; } diff --git a/src/proto_alpha/lib_delegate/client_daemon.mli b/src/proto_alpha/lib_delegate/client_daemon.mli index b0073a38c7892f4d57c8d215945334b02b87db16..70116a30cd318f85bc2764596f6fc863d7226000 100644 --- a/src/proto_alpha/lib_delegate/client_daemon.mli +++ b/src/proto_alpha/lib_delegate/client_daemon.mli @@ -42,7 +42,7 @@ module Baker : sig ?state_recorder:Baking_configuration.state_recorder_config -> chain:Shell_services.chain -> keep_alive:bool -> - Baking_state.Consensus_key.t list -> + Baking_state.Key.t list -> unit tzresult Lwt.t end diff --git a/src/proto_alpha/lib_delegate/forge_worker.ml b/src/proto_alpha/lib_delegate/forge_worker.ml index 8f61f91647fc68a5272589ceef08dbab09b52c32..fd04a0e3b2da4e3078b07e199fd4fcd37efb0118 100644 --- a/src/proto_alpha/lib_delegate/forge_worker.ml +++ b/src/proto_alpha/lib_delegate/forge_worker.ml @@ -70,7 +70,7 @@ type worker = { push_task : forge_request option -> unit; push_event : forge_event option -> unit; event_stream : forge_event Lwt_stream.t; - delegate_signing_queues : Delegate_signing_queue.t Consensus_key_id.Table.t; + delegate_signing_queues : Delegate_signing_queue.t Key_id.Table.t; } type t = worker @@ -82,7 +82,7 @@ let get_event_stream state = state.event_stream let cancel_all_pending_tasks {delegate_signing_queues; _} = Lwt.dont_wait (fun () -> - Consensus_key_id.Table.iter_p + Key_id.Table.iter_p (fun _ queue -> Delegate_signing_queue.cancel_pending_tasks queue) delegate_signing_queues) (fun _exn -> ()) @@ -90,7 +90,7 @@ let cancel_all_pending_tasks {delegate_signing_queues; _} = let shutdown state = let open Lwt_syntax in let* () = - Consensus_key_id.Table.iter_p + Key_id.Table.iter_p (fun _ queue -> Delegate_signing_queue.cancel_all_tasks_and_close queue) state.delegate_signing_queues in @@ -99,13 +99,13 @@ let shutdown state = let get_or_create_queue worker delegate = match - Consensus_key_id.Table.find_opt + Key_id.Table.find_opt worker.delegate_signing_queues delegate.Baking_state.Delegate.consensus_key.id with | None -> let queue = Delegate_signing_queue.create delegate in - Consensus_key_id.Table.add + Key_id.Table.add worker.delegate_signing_queues delegate.consensus_key.id queue ; @@ -189,7 +189,7 @@ let start (baking_state : Baking_state.global_state) = let open Lwt_result_syntax in let task_stream, push_task = Lwt_stream.create () in let event_stream, push_event = Lwt_stream.create () in - let delegate_signing_queues = Consensus_key_id.Table.create 13 in + let delegate_signing_queues = Key_id.Table.create 13 in let state : worker = {push_task; push_event; event_stream; delegate_signing_queues} in 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 eace277cae55d652ea4239e918fca3aaa76915f2..e3c7ea24343a786fabd3d452f3aceba686309e51 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 @@ -149,7 +149,7 @@ module type Hooks = sig val on_start_baker : baker_position:int -> - delegates:Baking_state.Consensus_key.t list -> + delegates:Baking_state.Key.t list -> cctxt:Protocol_client_context.full -> unit Lwt.t @@ -935,7 +935,7 @@ class tezt_printer : Tezos_client_base.Client_context.printer = end (** Start baker process. *) -let baker_process ~(delegates : Baking_state.Consensus_key.t list) ~base_dir +let baker_process ~(delegates : Baking_state.Key.t list) ~base_dir ~(genesis_block : Block_header.t * Tezos_protocol_environment.rpc_context) ~i ~global_chain_table ~broadcast_pipes ~(user_hooks : (module Hooks)) = let open Lwt_result_syntax in @@ -965,11 +965,10 @@ let baker_process ~(delegates : Baking_state.Consensus_key.t list) ~base_dir let*! () = User_hooks.on_start_baker ~baker_position:i ~delegates ~cctxt in let* () = List.iter_es - (fun ({alias; public_key; id; secret_key_uri} : - Baking_state.Consensus_key.t) -> + (fun ({alias; public_key; id; secret_key_uri} : Baking_state.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.Consensus_key_id.to_pkh id in + let pkh = Baking_state.Key_id.to_pkh id in Client_keys.register_key wallet ~force:false @@ -1288,8 +1287,8 @@ let default_config = let make_baking_delegate ( (account : Alpha_context.Parameters.bootstrap_account), (secret : Tezos_mockup_commands.Mockup_wallet.bootstrap_secret) ) : - Baking_state.Consensus_key.t = - Baking_state.Consensus_key.make + Baking_state.Key.t = + Baking_state.Key.make ~alias:(Some secret.name) ~public_key_hash:account.public_key_hash ~public_key:(account.public_key |> WithExceptions.Option.get ~loc:__LOC__) diff --git a/src/proto_alpha/lib_delegate/test/mockup_simulator/mockup_simulator.mli b/src/proto_alpha/lib_delegate/test/mockup_simulator/mockup_simulator.mli index 4ce76277e3ad609dd7832dada6cc9b86e1f48425..de18ce2d1236e2622f2451152c73b62244b28ba6 100644 --- a/src/proto_alpha/lib_delegate/test/mockup_simulator/mockup_simulator.mli +++ b/src/proto_alpha/lib_delegate/test/mockup_simulator/mockup_simulator.mli @@ -126,7 +126,7 @@ module type Hooks = sig bakers that were started for this run. *) val on_start_baker : baker_position:int -> - delegates:Baking_state.Consensus_key.t list -> + delegates:Baking_state.Key.t list -> cctxt:Protocol_client_context.full -> unit Lwt.t diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index 601ea0c9127d9503d5d26a0a84a440841bb31037..4014e166d12a0e2a54e325dd60560c2195b03573 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -3957,21 +3957,23 @@ module Validators = struct level : Raw_level.t; delegate : Signature.Public_key_hash.t; consensus_key : Signature.public_key_hash; + companion_key : Bls.Public_key_hash.t option; slots : Slot.t list; } let encoding = let open Data_encoding in conv - (fun {level; delegate; consensus_key; slots} -> - (level, delegate, slots, consensus_key)) - (fun (level, delegate, slots, consensus_key) -> - {level; delegate; consensus_key; slots}) - (obj4 + (fun {level; delegate; consensus_key; companion_key; slots} -> + (level, delegate, slots, consensus_key, companion_key)) + (fun (level, delegate, slots, consensus_key, companion_key) -> + {level; delegate; consensus_key; companion_key; slots}) + (obj5 (req "level" Raw_level.encoding) (req "delegate" Signature.Public_key_hash.encoding) (req "slots" (list Slot.encoding)) - (req "consensus_key" Signature.Public_key_hash.encoding)) + (req "consensus_key" Signature.Public_key_hash.encoding) + (opt "companion_key" Bls.Public_key_hash.encoding)) module S = struct open Data_encoding @@ -4016,8 +4018,9 @@ module Validators = struct let+ ctxt, rights = Baking.attesting_rights ctxt level in ( ctxt, Signature.Public_key_hash.Map.fold - (fun _pkh {Baking.delegate; consensus_key; slots} acc -> - {level = level.level; delegate; consensus_key; slots} :: acc) + (fun _pkh {Baking.delegate; consensus_key; companion_key; slots} acc -> + {level = level.level; delegate; consensus_key; companion_key; slots} + :: acc) rights acc ) diff --git a/src/proto_alpha/lib_protocol/baking.ml b/src/proto_alpha/lib_protocol/baking.ml index 0af0632f22b0f4f1db7e2b0fadfd7a8f3d7317dc..3bad0551af7f6ad1d1b93f971e0d2c966eb6b5be 100644 --- a/src/proto_alpha/lib_protocol/baking.ml +++ b/src/proto_alpha/lib_protocol/baking.ml @@ -76,6 +76,7 @@ let bonus_baking_reward ctxt ~attestation_power = type ordered_slots = { delegate : Signature.public_key_hash; consensus_key : Signature.public_key_hash; + companion_key : Bls.Public_key_hash.t option; slots : Slot.t list; } @@ -97,6 +98,7 @@ let attesting_rights (ctxt : t) level = { delegate = consensus_pk.delegate; consensus_key = consensus_pk.consensus_pkh; + companion_key = consensus_pk.companion_pkh; slots = [slot]; } | Some slots -> Some {slots with slots = slot :: slots.slots}) diff --git a/src/proto_alpha/lib_protocol/baking.mli b/src/proto_alpha/lib_protocol/baking.mli index 0aeabf4f5731ba478fe17c2641597f85881caacf..540ec98a72c9eb09fb9e8085050d015b3e536c03 100644 --- a/src/proto_alpha/lib_protocol/baking.mli +++ b/src/proto_alpha/lib_protocol/baking.mli @@ -36,6 +36,7 @@ type error += type ordered_slots = private { delegate : Signature.public_key_hash; consensus_key : Signature.public_key_hash; + companion_key : Bls.Public_key_hash.t option; slots : Slot.t list; } diff --git a/tezt/lib_tezos/agnostic_baker.ml b/tezt/lib_tezos/agnostic_baker.ml index 3d1b0d5c7c0283aee184db09d3d43f93aa00052c..c7806187c749813d1bdf97afc61bffe6ce4c6875 100644 --- a/tezt/lib_tezos/agnostic_baker.ml +++ b/tezt/lib_tezos/agnostic_baker.ml @@ -328,7 +328,17 @@ let log_block_injection ?color baker = let open JSON in let level = event.value |-> "level" |> as_int in let round = event.value |-> "round" |> as_int in - let delegate = event.value |-> "delegate" |-> "alias" |> as_string in + let delegate = + event.value |-> "delegate" |-> "alias" |> as_string_opt + in + let delegate = + match delegate with + | None -> + (* The encoding was changed in Protocol 023 *) + event.value |-> "delegate" |-> "consensus_key" |-> "alias" + |> as_string + | Some delegate -> delegate + in Log.info ?color "[%s] Block injected at level %d round %d for %s." diff --git a/tezt/tests/companion_key.ml b/tezt/tests/companion_key.ml index 1902e7869789fdae1aaf54adabe68b55cc88c19c..43808c870d38456a04328ad1088be2de153976d3 100644 --- a/tezt/tests/companion_key.ml +++ b/tezt/tests/companion_key.ml @@ -44,6 +44,31 @@ let companion_key_typ : companion_key Check.typ = (active_companion_key, pending_companion_keys)) (tuple2 (option string) (list (tuple2 int string)))) +let get_validators_companion_key ?level (delegate : Account.key) client = + let* json = + Client.RPC.call client + @@ RPC.get_chain_block_helper_validators + ?level + ~delegate:delegate.public_key_hash + () + in + let companion_key = JSON.(json |=> 0 |-> "companion_key" |> as_string_opt) in + Log.info + ~color:Log.Color.FG.green + "companion_key = %s" + (match companion_key with Some ck -> ck | None -> "None") ; + return companion_key + +let check_validators_companion_key ~__LOC__ ?level (delegate : Account.key) + client ~expected = + let* companion_key = get_validators_companion_key ?level delegate client in + Check.( + (companion_key = expected) + (option string) + ~__LOC__ + ~error_msg:"Expected %R, got %L") ; + unit + let get_companion_key ?block client (delegate : Account.key) : companion_key Lwt.t = let* json = @@ -88,13 +113,7 @@ let check_companion_key ~__LOC__ delegate ?expected_active ~error_msg:"Expected %R, got %L") ; unit -let test_update_companion_key = - Protocol.register_regression_test - ~__FILE__ - ~title:"update companion key" - ~tags:[team; "companion_key"] - ~supports:(Protocol.From_protocol 023) - @@ fun protocol -> +let init_node_and_client ~protocol = let parameters = (* we update parameters for faster testing: no need to wait 2 cycles for the consensus key to activate. *) @@ -110,10 +129,19 @@ let test_update_companion_key = let* parameter_file = Protocol.write_parameter_file ~base:(Right (protocol, None)) parameters in - let* _, client = + let* node, client = Client.init_with_protocol ~parameter_file ~protocol `Client () in + return (node, client) +let test_update_companion_key = + Protocol.register_regression_test + ~__FILE__ + ~title:"update companion key" + ~tags:[team; "companion_key"] + ~supports:(Protocol.From_protocol 023) + @@ fun protocol -> + let* _node, client = init_node_and_client ~protocol in let delegate = Constant.bootstrap1 in let* consensus_key_bls = Client.gen_and_show_keys ~alias:"consensus_key" ~sig_alg:"bls" client @@ -158,8 +186,67 @@ let test_update_companion_key = ~expected_active:companion_key_bls client in + let* () = + check_validators_companion_key ~__LOC__ delegate ~expected:None client + in + let* current_level = get_current_level client in + let* () = + check_validators_companion_key + ~__LOC__ + ~level:(current_level.level + 1) + delegate + ~expected:(Some companion_key_bls.public_key_hash) + client + in + unit + +let test_update_companion_key_without_consensus_key = + Protocol.register_regression_test + ~__FILE__ + ~title:"update companion key without updating consensus key" + ~tags:[team; "companion_key"] + ~supports:(Protocol.From_protocol 023) + @@ fun protocol -> + let* _node, client = init_node_and_client ~protocol in + let delegate = Constant.bootstrap1 in + let* companion_key_bls = + Client.gen_and_show_keys ~alias:"companion_key" ~sig_alg:"bls" client + in + Log.info "Updating companion key" ; + let* () = + Client.update_companion_key + ~hooks + ~src:delegate.alias + ~pk:companion_key_bls.alias + client + in + let* () = Client.bake_for_and_wait client in + + Log.info "Waiting for companion key activation" ; + let* () = bake_n_cycles (consensus_rights_delay + 1) client in + + Log.info "Checking key is activated" ; + let* () = + check_companion_key + ~__LOC__ + delegate + ~expected_active:companion_key_bls + client + in + let* () = + check_validators_companion_key ~__LOC__ delegate ~expected:None client + in + let* current_level = get_current_level client in + let* () = + check_validators_companion_key + ~__LOC__ + ~level:(current_level.level + 1) + delegate + ~expected:(Some companion_key_bls.public_key_hash) + client + in unit let register ~protocols = - let () = test_update_companion_key protocols in - () + test_update_companion_key protocols ; + test_update_companion_key_without_consensus_key protocols diff --git a/tezt/tests/expected/companion_key.ml/Alpha- update companion key without updating consensus key.out b/tezt/tests/expected/companion_key.ml/Alpha- update companion key without updating consensus key.out new file mode 100644 index 0000000000000000000000000000000000000000..873da678c3bc0b7563a90436f6054bac8507c770 --- /dev/null +++ b/tezt/tests/expected/companion_key.ml/Alpha- update companion key without updating consensus key.out @@ -0,0 +1,27 @@ + +./octez-client --wait none set companion key for bootstrap1 to companion_key +Node is bootstrapped. +Estimated gas: 1744.502 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + octez-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000559 + Expected counter: 1 + Gas limit: 1845 + Storage limit: 0 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000559 + payload fees(the block proposer) ....... +ꜩ0.000559 + Update_companion_key: + Public key hash: [PUBLIC_KEY_HASH] + Proof of possession: [BLS_SIGNATURE] + This companion key update was successfully applied + Consumed gas: 1744.436 +