diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 585fcce1d9f3a13b3708e5d4f0d922d0cb75f8eb..bfa87a9c92fdce8113f1a2b46b0414fd49d38779 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2372,7 +2372,8 @@ module Delegate : sig context -> public_key_hash -> Cycle.t tzresult Lwt.t module Consensus_key : sig - val check_not_tz4 : Signature.public_key -> unit tzresult + val check_not_tz4 : + Operation_repr.consensus_key_kind -> Signature.public_key -> unit tzresult val active_pubkey : context -> public_key_hash -> Consensus_key.pk tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/delegate_consensus_key.ml b/src/proto_alpha/lib_protocol/delegate_consensus_key.ml index af07fa07ffddc811bc3a80a20e5ad77d1da47137..a8220c2e955bed92d6d217cb9f83162b466d486a 100644 --- a/src/proto_alpha/lib_protocol/delegate_consensus_key.ml +++ b/src/proto_alpha/lib_protocol/delegate_consensus_key.ml @@ -26,9 +26,12 @@ type error += | Invalid_consensus_key_update_noop of (Cycle_repr.t * Operation_repr.consensus_key_kind) - | Invalid_consensus_key_update_active of Signature.Public_key_hash.t - | Invalid_consensus_key_update_tz4 of Bls.Public_key.t - | Invalid_consensus_key_update_another_delegate of Signature.Public_key_hash.t + | Invalid_consensus_key_update_active of + (Signature.Public_key_hash.t * Operation_repr.consensus_key_kind) + | Invalid_consensus_key_update_tz4 of + (Bls.Public_key.t * Operation_repr.consensus_key_kind) + | Invalid_consensus_key_update_another_delegate of + (Signature.Public_key_hash.t * Operation_repr.consensus_key_kind) let () = register_error_kind @@ -54,50 +57,62 @@ let () = `Permanent ~id:"delegate.consensus_key.active" ~title:"Active consensus key" - ~description: - "The delegate consensus key is already used by another delegate" - ~pp:(fun ppf pkh -> + ~description:"The delegate consensus key is already used" + ~pp:(fun ppf (pkh, kind) -> Format.fprintf ppf - "The delegate consensus key %a is already used by another delegate" + "The delegate %a key %a is already used as another consensus or \ + companion key" + Operation_repr.pp_consensus_key_kind + kind Signature.Public_key_hash.pp pkh) Data_encoding.( - obj1 (req "consensus_pkh" Signature.Public_key_hash.encoding)) - (function Invalid_consensus_key_update_active pkh -> Some pkh | _ -> None) - (fun pkh -> Invalid_consensus_key_update_active pkh) ; + obj2 + (req "consensus_pkh" Signature.Public_key_hash.encoding) + (req "kind" Operation_repr.consensus_key_kind_encoding)) + (function Invalid_consensus_key_update_active c -> Some c | _ -> None) + (fun c -> Invalid_consensus_key_update_active c) ; register_error_kind `Permanent ~id:"delegate.consensus_key.tz4" ~title:"Consensus key cannot be a tz4" ~description:"Consensus key cannot be a tz4 (BLS public key)." - ~pp:(fun ppf pk -> + ~pp:(fun ppf (pk, kind) -> Format.fprintf ppf - "The consensus key %a is forbidden as it is a BLS public key." + "The %a key %a is forbidden as it is a BLS public key." + Operation_repr.pp_consensus_key_kind + kind Bls.Public_key_hash.pp (Bls.Public_key.hash pk)) - Data_encoding.(obj1 (req "delegate_pk" Bls.Public_key.encoding)) - (function Invalid_consensus_key_update_tz4 pk -> Some pk | _ -> None) - (fun pk -> Invalid_consensus_key_update_tz4 pk) ; + Data_encoding.( + obj2 + (req "delegate_pk" Bls.Public_key.encoding) + (req "kind" Operation_repr.consensus_key_kind_encoding)) + (function Invalid_consensus_key_update_tz4 c -> Some c | _ -> None) + (fun c -> Invalid_consensus_key_update_tz4 c) ; register_error_kind `Permanent ~id:"delegate.consensus_key.another_delegate" ~title:"Consensus key cannot be another delegate" ~description:"Consensus key cannot be another delegate" - ~pp:(fun ppf pkh -> + ~pp:(fun ppf (pkh, kind) -> Format.fprintf ppf - "The key %a cannot be registered as a consensus key, as it is the \ - manager key of another registered delegate." + "The key %a cannot be registered as a %a key, as it is the manager key \ + of another registered delegate." Signature.Public_key_hash.pp - pkh) + pkh + Operation_repr.pp_consensus_key_kind + kind) Data_encoding.( - obj1 (req "consensus_pkh" Signature.Public_key_hash.encoding)) + obj2 + (req "consensus_pkh" Signature.Public_key_hash.encoding) + (req "kind" Operation_repr.consensus_key_kind_encoding)) (function - | Invalid_consensus_key_update_another_delegate pkh -> Some pkh - | _ -> None) - (fun pkh -> Invalid_consensus_key_update_another_delegate pkh) + | Invalid_consensus_key_update_another_delegate c -> Some c | _ -> None) + (fun c -> Invalid_consensus_key_update_another_delegate c) type 'a typed_kind = | Consensus : Signature.public_key typed_kind @@ -161,25 +176,25 @@ let pp ppf {delegate; consensus_pkh} = companion) that will be active at cycle `current + consensus_rights_delay + 1`. *) -let check_unused ctxt pkh = +let check_unused ctxt kind pkh = let open Lwt_result_syntax in let*! is_active = Storage.Consensus_keys.mem ctxt pkh in - fail_when is_active (Invalid_consensus_key_update_active pkh) + fail_when is_active (Invalid_consensus_key_update_active (pkh, kind)) -let check_not_tz4 : Signature.Public_key.t -> unit tzresult = +let check_not_tz4 kind : Signature.Public_key.t -> unit tzresult = let open Result_syntax in function - | Bls pk -> tzfail (Invalid_consensus_key_update_tz4 pk) + | Bls pk -> tzfail (Invalid_consensus_key_update_tz4 (pk, kind)) | Ed25519 _ | Secp256k1 _ | P256 _ -> return_unit -let check_is_not_another_delegate ctxt pkh delegate = +let check_is_not_another_delegate ctxt kind pkh delegate = let open Lwt_result_syntax in if Signature.Public_key_hash.equal pkh delegate then return_unit else let*! is_another_delegate = Storage.Delegates.mem ctxt pkh in fail_when is_another_delegate - (Invalid_consensus_key_update_another_delegate pkh) + (Invalid_consensus_key_update_another_delegate (pkh, kind)) let set_unused = Storage.Consensus_keys.remove @@ -188,7 +203,7 @@ let set_used = Storage.Consensus_keys.add let init ctxt delegate pk = let open Lwt_result_syntax in let pkh = Signature.Public_key.hash pk in - let* () = check_unused ctxt pkh in + let* () = check_unused ctxt Consensus pkh in let*! ctxt = set_used ctxt pkh in Storage.Contract.Consensus_key.init ctxt (Contract_repr.Implicit delegate) pk @@ -302,8 +317,8 @@ let register_update ctxt delegate pk = (Invalid_consensus_key_update_noop (first_active_cycle, Consensus)) in let pkh = Signature.Public_key.hash pk in - let* () = check_unused ctxt pkh in - let* () = check_is_not_another_delegate ctxt pkh delegate in + let* () = check_unused ctxt Consensus pkh in + let* () = check_is_not_another_delegate ctxt Consensus pkh delegate in let*! ctxt = set_used ctxt pkh in let* {consensus_pkh = old_pkh; _} = active_pubkey_for_cycle ctxt delegate update_cycle @@ -338,8 +353,8 @@ let register_update_companion ctxt delegate pk = let pkh : Signature.public_key_hash = Signature.Bls (Bls.Public_key.hash pk) in - let* () = check_unused ctxt pkh in - let* () = check_is_not_another_delegate ctxt pkh delegate in + let* () = check_unused ctxt Companion pkh in + let* () = check_is_not_another_delegate ctxt Companion pkh delegate in let*! ctxt = set_used ctxt pkh in let* {companion_pkh = old_pkh; _} = active_pubkey_for_cycle ctxt delegate update_cycle diff --git a/src/proto_alpha/lib_protocol/delegate_consensus_key.mli b/src/proto_alpha/lib_protocol/delegate_consensus_key.mli index bbd0d14954547254822d53efb586fdeac18d31bc..18b7addb9fbbdbb88e10581c0e7ecdaf831b21a2 100644 --- a/src/proto_alpha/lib_protocol/delegate_consensus_key.mli +++ b/src/proto_alpha/lib_protocol/delegate_consensus_key.mli @@ -34,9 +34,12 @@ type error += | Invalid_consensus_key_update_noop of (Cycle_repr.t * Operation_repr.consensus_key_kind) - | Invalid_consensus_key_update_active of Signature.Public_key_hash.t - | Invalid_consensus_key_update_tz4 of Bls.Public_key.t - | Invalid_consensus_key_update_another_delegate of Signature.Public_key_hash.t + | Invalid_consensus_key_update_active of + (Signature.Public_key_hash.t * Operation_repr.consensus_key_kind) + | Invalid_consensus_key_update_tz4 of + (Bls.Public_key.t * Operation_repr.consensus_key_kind) + | Invalid_consensus_key_update_another_delegate of + (Signature.Public_key_hash.t * Operation_repr.consensus_key_kind) (** The public key of a consensus key and the associated delegate. *) type pk = Raw_context.consensus_pk = { @@ -62,7 +65,8 @@ val pp : Format.formatter -> t -> unit val pkh : pk -> t (** [check_not_tz4 pk] checks that [pk] is not a BLS address. *) -val check_not_tz4 : Signature.public_key -> unit tzresult +val check_not_tz4 : + Operation_repr.consensus_key_kind -> Signature.public_key -> unit tzresult (** Initialize the consensus key when registering a delegate. *) val init : diff --git a/src/proto_alpha/lib_protocol/test/integration/consensus/test_companion_key.ml b/src/proto_alpha/lib_protocol/test/integration/consensus/test_companion_key.ml index 49ef87123c8cce3532b887eaf812676a30fade4a..67f207d4600ac61f012cfa6c0ec0928efbfe622f 100644 --- a/src/proto_alpha/lib_protocol/test/integration/consensus/test_companion_key.ml +++ b/src/proto_alpha/lib_protocol/test/integration/consensus/test_companion_key.ml @@ -68,23 +68,24 @@ type key_kind = Protocol.Operation_repr.consensus_key_kind = | Consensus | Companion -let check_error_invalid_consensus_key_update_active ~loc ~pkh errs = +let check_error_invalid_consensus_key_update_active ~loc ~pkh ~kind errs = Assert.expect_error ~loc errs (function | [ Protocol.Delegate_consensus_key.Invalid_consensus_key_update_active - err_pkh; + (err_pkh, err_kind); ] - when Signature.Public_key_hash.equal pkh err_pkh -> + when Signature.Public_key_hash.equal pkh err_pkh && kind = err_kind -> true | _ -> false) -let check_error_invalid_consensus_key_update_another_delegate ~loc ~pkh errs = +let check_error_invalid_consensus_key_update_another_delegate ~loc ~pkh ~kind + errs = Assert.expect_error ~loc errs (function | [ Protocol.Delegate_consensus_key - .Invalid_consensus_key_update_another_delegate err_pkh; + .Invalid_consensus_key_update_another_delegate (err_pkh, err_kind); ] - when Signature.Public_key_hash.equal pkh err_pkh -> + when Signature.Public_key_hash.equal pkh err_pkh && kind = err_kind -> true | _ -> false) @@ -336,13 +337,21 @@ let test_register_other_accounts_as_ck = ~loc:__LOC__ ~expected_error:(fun (_block, state) err -> let pkh = (State.find_account "victim_1" state).pkh in - check_error_invalid_consensus_key_update_active ~loc:__LOC__ ~pkh err) + check_error_invalid_consensus_key_update_active + ~loc:__LOC__ + ~pkh + ~kind:Consensus + err) (update_consensus_key ~ck_name:"victim_1" "delegate") --> assert_failure ~loc:__LOC__ ~expected_error:(fun (_block, state) err -> let pkh = (State.find_account "victim_2" state).pkh in - check_error_invalid_consensus_key_update_active ~loc:__LOC__ ~pkh err) + check_error_invalid_consensus_key_update_active + ~loc:__LOC__ + ~pkh + ~kind:Companion + err) (update_companion_key ~ck_name:"victim_2" "delegate") (* ... So we give them other consensus keys. Note that the algo is not defined, so it is chosen at random. *) @@ -358,6 +367,7 @@ let test_register_other_accounts_as_ck = check_error_invalid_consensus_key_update_another_delegate ~loc:__LOC__ ~pkh + ~kind:Consensus err) (update_consensus_key ~ck_name:"victim_1" "delegate") --> assert_failure @@ -367,6 +377,7 @@ let test_register_other_accounts_as_ck = check_error_invalid_consensus_key_update_another_delegate ~loc:__LOC__ ~pkh + ~kind:Companion err) (update_companion_key ~ck_name:"victim_2" "delegate") @@ -390,7 +401,11 @@ let test_self_register_as_companion = ~loc:__LOC__ ~expected_error:(fun (_block, state) err -> let pkh = (State.find_account delegate state).pkh in - check_error_invalid_consensus_key_update_active ~loc:__LOC__ ~pkh err) + check_error_invalid_consensus_key_update_active + ~loc:__LOC__ + ~pkh + ~kind:Companion + err) (update_companion_key ~ck_name:delegate delegate) (* We can change that *) --> add_account "consensus_key" @@ -447,7 +462,11 @@ let test_self_register_as_companion = ~loc:__LOC__ ~expected_error:(fun (_block, state) err -> let pkh = (State.find_account delegate state).pkh in - check_error_invalid_consensus_key_update_active ~loc:__LOC__ ~pkh err) + check_error_invalid_consensus_key_update_active + ~loc:__LOC__ + ~pkh + ~kind:Consensus + err) (update_consensus_key ~ck_name:delegate delegate) --> add_account ~algo:Bls "companion_key" --> update_companion_key ~ck_name:"companion_key" delegate @@ -538,6 +557,7 @@ let test_register_same_key_multiple_times = check_error_invalid_consensus_key_update_active ~loc:__LOC__ ~pkh:ck.pkh + ~kind:Consensus err) (update_consensus_key ~ck_name:ck delegate) --> assert_failure @@ -566,6 +586,7 @@ let test_register_same_key_multiple_times = check_error_invalid_consensus_key_update_active ~loc:__LOC__ ~pkh:ck.pkh + ~kind:Companion err) (update_companion_key ~ck_name:ck delegate) in @@ -839,11 +860,12 @@ let test_forbidden_tz4 = Assert.expect_error ~loc:__LOC__ err (function | [ Protocol.Delegate_consensus_key - .Invalid_consensus_key_update_tz4 err_ck_bls_pk; + .Invalid_consensus_key_update_tz4 (err_ck_bls_pk, err_kind); ] -> - Signature.Public_key.equal - (Bls err_ck_bls_pk) - ck_account.pk + kind = err_kind + && Signature.Public_key.equal + (Bls err_ck_bls_pk) + ck_account.pk | _ -> false)) (update_key ~kind ~ck_name:"ck" "delegate")) [("update consensus", Consensus); ("update companion", Companion)] @@ -920,6 +942,7 @@ let test_fail_already_registered = check_error_invalid_consensus_key_update_active ~loc:__LOC__ ~pkh + ~kind err) (update_key ~kind ~ck_name:"ck" delegate)) [("update consensus", Consensus); ("update companion", Companion)] diff --git a/src/proto_alpha/lib_protocol/test/integration/consensus/test_consensus_key.ml b/src/proto_alpha/lib_protocol/test/integration/consensus/test_consensus_key.ml index e7401d26766fcaa9c7a36ac3eed405bdfb962b73..3d06ba09e26083ae8209d4f21164dd853001771e 100644 --- a/src/proto_alpha/lib_protocol/test/integration/consensus/test_consensus_key.ml +++ b/src/proto_alpha/lib_protocol/test/integration/consensus/test_consensus_key.ml @@ -294,9 +294,9 @@ let test_tz4_consensus_key ~allow_tz4_delegate_enable () = let expect_failure = function | [ Environment.Ecoproto_error - (Delegate_consensus_key.Invalid_consensus_key_update_tz4 pk); + (Delegate_consensus_key.Invalid_consensus_key_update_tz4 (pk, kind)); ] - when Signature.Bls.Public_key.(pk = tz4_pk) -> + when Signature.Bls.Public_key.(pk = tz4_pk) && kind = Consensus -> return_unit | err -> failwith diff --git a/src/proto_alpha/lib_protocol/test/unit/test_consensus_key.ml b/src/proto_alpha/lib_protocol/test/unit/test_consensus_key.ml index 3cbf14100f98a75d0f0781128c63d9382ab06f72..c7ae7d372c62ef3aa6e87dda9462a35c2942bbc4 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_consensus_key.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_consensus_key.ml @@ -147,7 +147,8 @@ let test_consensus_key_storage () = let* () = let*! err = Consensus_key.register_update ctxt del1.pkh del2.pk in Assert.proto_error ~loc:__LOC__ err (function - | Delegate_consensus_key.Invalid_consensus_key_update_active pkh + | Delegate_consensus_key.Invalid_consensus_key_update_active + (pkh, Consensus) when Signature.Public_key_hash.equal del2.pkh pkh -> true | _ -> false) @@ -163,7 +164,8 @@ let test_consensus_key_storage () = let* () = let*! err = Consensus_key.register_update ctxt del2.pkh a1.pk in Assert.proto_error ~loc:__LOC__ err (function - | Delegate_consensus_key.Invalid_consensus_key_update_active pkh + | Delegate_consensus_key.Invalid_consensus_key_update_active + (pkh, Consensus) when Signature.Public_key_hash.equal a1.pkh pkh -> true | _ -> false) @@ -172,7 +174,7 @@ let test_consensus_key_storage () = let*! err = Consensus_key.register_update ctxt del2.pkh del1.pk in Assert.proto_error ~loc:__LOC__ err (function | Delegate_consensus_key.Invalid_consensus_key_update_another_delegate - pkh + (pkh, Consensus) when Signature.Public_key_hash.equal del1.pkh pkh -> true | _ -> false) diff --git a/src/proto_alpha/lib_protocol/validate.ml b/src/proto_alpha/lib_protocol/validate.ml index ad8b5fba90fd453dba3009d6fa4589307ad53913..14014e0eb697b5efeae6aceee985d836a8d1c74a 100644 --- a/src/proto_alpha/lib_protocol/validate.ml +++ b/src/proto_alpha/lib_protocol/validate.ml @@ -2915,7 +2915,7 @@ module Manager = struct {kind = Consensus; source; public_key}) | (Ed25519 _ | Secp256k1 _ | P256 _), None, Consensus -> return_unit else - let* () = Delegate.Consensus_key.check_not_tz4 public_key in + let* () = Delegate.Consensus_key.check_not_tz4 kind public_key in match kind with | Companion -> result_error