From f615eda39d50083756ac26e73c46846ff0d29af4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 3 Nov 2024 12:43:08 +0100 Subject: [PATCH] fix: trying to solve cache issue --- .../update_state_masternode_list/v0/mod.rs | 12 +++-- .../storage/fetch_platform_state/v0/mod.rs | 18 ++++++- .../src/platform_types/platform_state/mod.rs | 1 + .../patch_error_block_32326_commit_failure.rs | 48 +++++++++++++++++++ 4 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 packages/rs-drive-abci/src/platform_types/platform_state/patch_error_block_32326_commit_failure.rs diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs index b6c447fa75b..9ffd39d1331 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_list/update_state_masternode_list/v0/mod.rs @@ -12,10 +12,7 @@ use dashcore_rpc::dashcore_rpc_json::{DMNStateDiff, MasternodeListDiff, Masterno use indexmap::IndexMap; use std::collections::{BTreeMap, BTreeSet}; -impl Platform -where - C: CoreRPCLike, -{ +impl Platform { /// Remove a masternode from all validator sets based on its ProTxHash. /// /// This function iterates through all the validator sets and removes the given masternode @@ -27,7 +24,7 @@ where /// * `validator_sets` - A mutable reference to an IndexMap containing QuorumHash as key /// and ValidatorSet as value. /// - fn remove_masternode_in_validator_sets( + pub(crate) fn remove_masternode_in_validator_sets( pro_tx_hash: &ProTxHash, validator_sets: &mut IndexMap, ) { @@ -37,7 +34,12 @@ where validator_set.members_mut().remove(pro_tx_hash); }); } +} +impl Platform +where + C: CoreRPCLike, +{ /// Updates a masternode in the validator sets. /// /// This function updates the properties of the masternode that matches the given `pro_tx_hash`. diff --git a/packages/rs-drive-abci/src/execution/storage/fetch_platform_state/v0/mod.rs b/packages/rs-drive-abci/src/execution/storage/fetch_platform_state/v0/mod.rs index a815e0266a6..4e3bc098bed 100644 --- a/packages/rs-drive-abci/src/execution/storage/fetch_platform_state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/storage/fetch_platform_state/v0/mod.rs @@ -1,5 +1,6 @@ use crate::error::Error; use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::v0::PlatformStateV0Methods; use crate::platform_types::platform_state::PlatformState; use dpp::serialization::PlatformDeserializableFromVersionedStructure; use dpp::version::PlatformVersion; @@ -27,7 +28,22 @@ impl Platform { ); } - result + let mut platform_state = result?; + + if platform_state.last_committed_block_height() >= 32326 { + // Apply a corrective patch to handle the commit failure at block 32326 + // + // Due to a missed commit of block 32326, an Evonode deletion was not saved to disk. + // This discrepancy caused an inconsistency between the in-memory cache and the disk state, + // leading to potential issues in consensus. + // + // Calling `patch_error_block_32326_commit_failure` here replays the deletion event + // during state loading, ensuring that the in-memory state reflects the actual state + // on the network, allowing the chain to proceed correctly. + platform_state.patch_error_block_32326_commit_failure::(); + } + + Ok(platform_state) }) .transpose() } diff --git a/packages/rs-drive-abci/src/platform_types/platform_state/mod.rs b/packages/rs-drive-abci/src/platform_types/platform_state/mod.rs index d2236ef84cc..55769fd2357 100644 --- a/packages/rs-drive-abci/src/platform_types/platform_state/mod.rs +++ b/packages/rs-drive-abci/src/platform_types/platform_state/mod.rs @@ -1,3 +1,4 @@ +mod patch_error_block_32326_commit_failure; mod patch_platform_version; /// Version 0 pub mod v0; diff --git a/packages/rs-drive-abci/src/platform_types/platform_state/patch_error_block_32326_commit_failure.rs b/packages/rs-drive-abci/src/platform_types/platform_state/patch_error_block_32326_commit_failure.rs new file mode 100644 index 00000000000..c1b37e1d4e8 --- /dev/null +++ b/packages/rs-drive-abci/src/platform_types/platform_state/patch_error_block_32326_commit_failure.rs @@ -0,0 +1,48 @@ +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::v0::PlatformStateV0Methods; +use crate::platform_types::platform_state::PlatformState; +use dpp::dashcore::ProTxHash; + +impl PlatformState { + /// Patches the state to handle a commit failure at block 32326 where an Evonode deletion event was skipped. + /// + /// ### Background + /// At block 32326, a commit to storage failed due to a busy error from RocksDB. This caused the deletion + /// of an Evonode to not be saved to disk, even though the chain lock update included this deletion in + /// the in-memory cache. As a result, the in-memory state and disk state became inconsistent, with the + /// cache containing an Evonode that was no longer valid according to the chain lock. + /// + /// This inconsistency led the chain to continue with an incorrect state representation, causing issues + /// in achieving consensus when nodes would reload. + /// + /// ### Purpose + /// To resolve the inconsistency, this function replays the deletion event of the Evonode when the + /// state is loaded from disk, ensuring the cache and disk states are aligned. This enables the chain + /// to proceed without stalling. + /// + /// ### Implementation + /// - Identifies the Evonode removed at block 32326 by its ProTxHash. + /// - Removes the Evonode from the current validator sets, ensuring it is no longer part of + /// any active validator set. + /// - Updates both the full and HPMN (high-performance masternode) lists by removing the Evonode + /// entry, fully clearing it from the in-memory state. + /// + /// ### Usage + /// This function should be called during state loading to apply the corrective deletion event, + /// aligning the in-memory cache with the on-disk state for correct chain progression. + pub fn patch_error_block_32326_commit_failure(&mut self) { + // At block 32326 we only had 1 event which was the removal of an Evonode + let removed_evonode_hash = + ProTxHash::from_hex("fc2e4a2037610a2f90a0f26d3e8e0b9d84e35cb318dba8e3b9a8056922e09a93") + .expect("expected valid evonode hash"); + Platform::::remove_masternode_in_validator_sets( + &removed_evonode_hash, + self.validator_sets_mut(), + ); + + self.full_masternode_list_mut() + .remove(&removed_evonode_hash); + self.hpmn_masternode_list_mut() + .remove(&removed_evonode_hash); + } +}