Skip to content

Commit

Permalink
Merge branch 'fix/TempStateCache' into v1.5.1-test
Browse files Browse the repository at this point in the history
  • Loading branch information
shumkov committed Nov 3, 2024
2 parents 2a3532b + f615eda commit 7ad1729
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ use dashcore_rpc::dashcore_rpc_json::{DMNStateDiff, MasternodeListDiff, Masterno
use indexmap::IndexMap;
use std::collections::{BTreeMap, BTreeSet};

impl<C> Platform<C>
where
C: CoreRPCLike,
{
impl<C> Platform<C> {
/// Remove a masternode from all validator sets based on its ProTxHash.
///
/// This function iterates through all the validator sets and removes the given masternode
Expand All @@ -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<QuorumHash, ValidatorSet>,
) {
Expand All @@ -37,7 +34,12 @@ where
validator_set.members_mut().remove(pro_tx_hash);
});
}
}

impl<C> Platform<C>
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`.
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -27,7 +28,22 @@ impl<C> Platform<C> {
);
}

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::<C>();
}

Ok(platform_state)
})
.transpose()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod patch_error_block_32326_commit_failure;
mod patch_platform_version;
/// Version 0
pub mod v0;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<C>(&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::<C>::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);
}
}

0 comments on commit 7ad1729

Please sign in to comment.