diff --git a/CHANGES.rst b/CHANGES.rst index 2275993d71f84cfb806e030658adfd05096aa76d..4d366f3716fc7e865d03811899dfd1ad75b6dc16 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -293,3 +293,9 @@ Baker Miscellaneous ------------- + +- Fixed a ghostnet issue related to the lowering of + ``consensus_rights_delay`` from 3 in Paris to 2 in Quebec on + ghostnet. This issue does not affect mainnet, where + ``consensus_rights_delay`` was already 2 in Paris and remains + unchanged in Quebec. (MR :gl:`!16219`) diff --git a/src/lib_protocol_updater/registered_protocol.mli b/src/lib_protocol_updater/registered_protocol.mli index a651b6e079bf1b46445f909aa6407a6d09c46fa5..5afdf69ea92cd12164a216e2da45bd52524731bf 100644 --- a/src/lib_protocol_updater/registered_protocol.mli +++ b/src/lib_protocol_updater/registered_protocol.mli @@ -257,6 +257,7 @@ module Register_embedded_V13 and type operation = Proto.operation and type operation_receipt = Proto.operation_receipt and type validation_state = Proto.validation_state + and type application_state = Proto.application_state module Register_embedded_V14 (Env : Tezos_protocol_environment.V14.T) diff --git a/src/proto_021_PsQuebec/lib_plugin/ghostnet_fix.ml b/src/proto_021_PsQuebec/lib_plugin/ghostnet_fix.ml new file mode 100644 index 0000000000000000000000000000000000000000..59b3ceda37138ee682c0f8d279118be9af2921db --- /dev/null +++ b/src/proto_021_PsQuebec/lib_plugin/ghostnet_fix.ml @@ -0,0 +1,55 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(* /!\ This file must not be removed when protocol Q gets frozen. *) + +open Protocol +open Protocol.Alpha_context + +let ghostnet_id = Chain_id.of_b58check_exn "NetXnHfVqm9iesp" + +let ghostnet_fix_level = Raw_level.of_int32_exn 10_062_848l + +(* The issue is that on ghostnet, consensus_rights_delay was still 3 + in Paris, then gets lowered to 2 in Quebec without properly + stitching the context. This issue doesn't affect mainnet, where + consensus_rights_delay was already 2 in Paris and is still 2 in + Quebec. + + Denote n the first cycle of Q on ghostnet. At the end of cycle n, + we compute the rights for cycle n + 1 + consensus_rights_delay = n + + 3. But at the end of cycle n-1, the Paris protocol has already + computed the rights for this cycle since its consensus_rights_delay + was higher. And for instance in lib_protocol/stake_storage.ml we + call Storage.Stake.Selected_distribution_for_cycle.init on a cycle + that already has an entry in the storage, which fails. + + To fix this, we overwrite finalize_application in + plugin_register.ml to call this function, which clears the + problematic tables during level 10_062_848 which is the last level + of cycle n. + + /!\ This function must always leave [application_state] unchanged + on mainnet. *) +let fix_ghostnet_state (application_state : Apply.application_state) = + let open Lwt_syntax in + if + Chain_id.(application_state.chain_id = ghostnet_id) + && Raw_level.( + (Level.current application_state.ctxt).level = ghostnet_fix_level) + then + let (ctxt : Raw_context.t) = Obj.magic (application_state.ctxt : context) in + let current_cycle = (Raw_context.current_level ctxt).cycle in + let cycle_to_clear = Cycle_repr.add current_cycle 3 in + let* ctxt = + Storage.Stake.Selected_distribution_for_cycle.remove ctxt cycle_to_clear + in + let* ctxt = Storage.Stake.Total_active_stake.remove ctxt cycle_to_clear in + let* ctxt = Storage.Delegate_sampler_state.remove ctxt cycle_to_clear in + let (ctxt : context) = Obj.magic (ctxt : Raw_context.t) in + return {application_state with ctxt} + else return application_state diff --git a/src/proto_021_PsQuebec/lib_plugin/plugin_registerer.ml b/src/proto_021_PsQuebec/lib_plugin/plugin_registerer.ml index 096a5f55d284741e6acc783b191388dc5782f565..366c85d6c1a8f1e39d73c492876d0b8f0207bf60 100644 --- a/src/proto_021_PsQuebec/lib_plugin/plugin_registerer.ml +++ b/src/proto_021_PsQuebec/lib_plugin/plugin_registerer.ml @@ -9,6 +9,15 @@ module Validation = struct include Registerer.Registered module Plugin = Plugin.Mempool + + (* /!\ This overwrite must not be removed when protocol Q gets + frozen. See {!Ghostnet_fix}. *) + let finalize_application application_state shell_header = + let open Lwt_syntax in + let* application_state = + Ghostnet_fix.fix_ghostnet_state application_state + in + finalize_application application_state shell_header end module RPC = struct