From 1a02498af23c21a6cbcf5e6091e021c6f6b24174 Mon Sep 17 00:00:00 2001 From: Diane Gallois-Wong Date: Tue, 14 Jan 2025 16:52:20 +0100 Subject: [PATCH] Q plugin: remove problematic cycle from ghostnet context --- .../registered_protocol.mli | 1 + .../lib_plugin/ghostnet_fix.ml | 55 +++++++++++++++++++ .../lib_plugin/plugin_registerer.ml | 9 +++ 3 files changed, 65 insertions(+) create mode 100644 src/proto_021_PsQuebec/lib_plugin/ghostnet_fix.ml diff --git a/src/lib_protocol_updater/registered_protocol.mli b/src/lib_protocol_updater/registered_protocol.mli index c3a96a52c5f9..f0ef7c16c31b 100644 --- a/src/lib_protocol_updater/registered_protocol.mli +++ b/src/lib_protocol_updater/registered_protocol.mli @@ -257,3 +257,4 @@ 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 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 000000000000..59b3ceda3713 --- /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 096a5f55d284..366c85d6c1a8 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 -- GitLab