Skip to content

Commit

Permalink
chore: emergency version upgrade to v1.3 Protocol Version 2. (#2138)
Browse files Browse the repository at this point in the history
  • Loading branch information
QuantumExplorer authored Sep 18, 2024
1 parent f2ded52 commit 48a0332
Show file tree
Hide file tree
Showing 15 changed files with 192 additions and 27 deletions.
8 changes: 4 additions & 4 deletions packages/rs-drive-abci/src/abci/handler/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::abci::AbciError;
use crate::error::Error;
use crate::platform_types::platform_state::v0::PlatformStateV0Methods;
use crate::rpc::core::CoreRPCLike;
use dpp::version::PlatformVersion;
use dpp::version::DESIRED_PLATFORM_VERSION;
use tenderdash_abci::proto::abci as proto;

pub fn info<A, C>(app: &A, request: proto::RequestInfo) -> Result<proto::ResponseInfo, Error>
Expand All @@ -26,18 +26,18 @@ where
.map(|app_hash| app_hash.to_vec())
.unwrap_or_default();

let latest_supported_protocol_version = PlatformVersion::latest().protocol_version;
let desired_protocol_version = DESIRED_PLATFORM_VERSION.protocol_version;

let response = proto::ResponseInfo {
data: "".to_string(),
app_version: latest_supported_protocol_version as u64,
app_version: desired_protocol_version as u64,
last_block_height: platform_state.last_committed_block_height() as i64,
version: env!("CARGO_PKG_VERSION").to_string(),
last_block_app_hash: state_app_hash.clone(),
};

tracing::debug!(
latest_supported_protocol_version,
desired_protocol_version,
software_version = env!("CARGO_PKG_VERSION"),
block_version = request.block_version,
p2p_version = request.p2p_version,
Expand Down
11 changes: 8 additions & 3 deletions packages/rs-drive-abci/src/abci/handler/prepare_proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use crate::abci::app::{BlockExecutionApplication, PlatformApplication, Transacti
use crate::abci::AbciError;
use crate::error::Error;
use crate::execution::engine::consensus_params_update::consensus_params_update;
use crate::execution::types::block_execution_context::v0::BlockExecutionContextV0Setters;
use crate::execution::types::block_execution_context::v0::{
BlockExecutionContextV0Getters, BlockExecutionContextV0Setters,
};
use crate::platform_types::block_execution_outcome;
use crate::platform_types::block_proposal::v0::BlockProposal;
use crate::platform_types::platform::Platform;
use crate::platform_types::platform_state::v0::PlatformStateV0Methods;
use crate::platform_types::state_transitions_processing_result::StateTransitionExecutionResult;
use crate::rpc::core::CoreRPCLike;
Expand All @@ -15,7 +16,7 @@ use drive::grovedb_storage::Error::RocksDBError;
use tenderdash_abci::proto::abci as proto;
use tenderdash_abci::proto::abci::tx_record::TxAction;
use tenderdash_abci::proto::abci::{ExecTxResult, TxRecord};
use tenderdash_abci::proto::types::{ConsensusParams, CoreChainLock};
use tenderdash_abci::proto::types::CoreChainLock;

pub fn prepare_proposal<'a, A, C>(
app: &A,
Expand Down Expand Up @@ -133,6 +134,8 @@ where
mut block_execution_context,
} = run_result.into_data().map_err(Error::Protocol)?;

let epoch_info = block_execution_context.epoch_info();

// We need to let Tenderdash know about the transactions we should remove from execution
let valid_tx_count = state_transitions_result.valid_count();
let failed_tx_count = state_transitions_result.failed_count();
Expand Down Expand Up @@ -204,8 +207,10 @@ where
}),
validator_set_update,
consensus_param_updates: consensus_params_update(
app.platform().config.network,
starting_platform_version,
platform_version,
epoch_info,
)?,
app_version: platform_version.protocol_version as u64,
};
Expand Down
5 changes: 4 additions & 1 deletion packages/rs-drive-abci/src/abci/handler/process_proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use crate::execution::types::block_state_info::v0::{
BlockStateInfoV0Getters, BlockStateInfoV0Setters,
};
use crate::platform_types::block_execution_outcome;
use crate::platform_types::platform::Platform;
use crate::platform_types::platform_state::v0::PlatformStateV0Methods;
use crate::platform_types::state_transitions_processing_result::StateTransitionExecutionResult;
use crate::rpc::core::CoreRPCLike;
Expand Down Expand Up @@ -217,6 +216,8 @@ where
block_execution_context,
} = run_result.into_data().map_err(Error::Protocol)?;

let epoch_info = *block_execution_context.epoch_info();

app.block_execution_context()
.write()
.unwrap()
Expand Down Expand Up @@ -280,8 +281,10 @@ where
status: proto::response_process_proposal::ProposalStatus::Accept.into(),
validator_set_update,
consensus_param_updates: consensus_params_update(
app.platform().config.network,
starting_platform_version,
platform_version,
&epoch_info,
)?,
events: Vec::new(),
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
use crate::error::execution::ExecutionError;
use crate::error::Error;
use crate::execution::engine::consensus_params_update::v0::consensus_params_update_v0;
use crate::platform_types::epoch_info::EpochInfo;
use dpp::dashcore::Network;
use dpp::version::PlatformVersion;
use tenderdash_abci::proto::types::ConsensusParams;

mod v0;
pub(crate) fn consensus_params_update(
network: Network,
original_platform_version: &PlatformVersion,
new_platform_version: &PlatformVersion,
epoch_info: &EpochInfo,
) -> Result<Option<ConsensusParams>, Error> {
match new_platform_version
.drive_abci
Expand All @@ -15,8 +20,10 @@ pub(crate) fn consensus_params_update(
.consensus_params_update
{
0 => Ok(consensus_params_update_v0(
network,
original_platform_version,
new_platform_version,
epoch_info,
)),
version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch {
method: "consensus_params_update".to_string(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,54 @@
use crate::platform_types::epoch_info::v0::EpochInfoV0Methods;
use crate::platform_types::epoch_info::EpochInfo;
use dpp::dashcore::Network;
use dpp::version::PlatformVersion;
use tenderdash_abci::proto::types::{ConsensusParams, VersionParams};

#[inline(always)]
pub(super) fn consensus_params_update_v0(
network: Network,
original_platform_version: &PlatformVersion,
new_platform_version: &PlatformVersion,
epoch_info: &EpochInfo,
) -> Option<ConsensusParams> {
// These are emergency consensus updates
match network {
Network::Dash => {
if epoch_info.is_first_block_of_epoch(3) {
return Some(ConsensusParams {
block: None,
evidence: None,
validator: None,
version: Some(VersionParams {
app_version: new_platform_version.protocol_version as u64,
consensus_version: 1,
}),
synchrony: None,
timeout: None,
abci: None,
});
}
}
Network::Testnet => {
if epoch_info.is_first_block_of_epoch(1475) {
return Some(ConsensusParams {
block: None,
evidence: None,
validator: None,
version: Some(VersionParams {
app_version: new_platform_version.protocol_version as u64,
consensus_version: 1,
}),
synchrony: None,
timeout: None,
abci: None,
});
}
}
_ => {}
}

// These are normal consensus updates
if original_platform_version
.consensus
.tenderdash_consensus_version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ use dpp::util::deserializer::ProtocolVersion;
use dpp::version::PlatformVersion;

mod v0;
mod v1;

impl<C> Platform<C> {
/// Checks for a network upgrade and resets activation window.
/// This method should only be called when a new epoch starts.
///
/// # Arguments
///
/// * `total_hpmns` - The total number of high priority masternodes.
/// * `active_hpmns` - The total number of evonodes that are not banned.
///
/// # Returns
///
Expand All @@ -29,7 +30,7 @@ impl<C> Platform<C> {
/// * More than one version pass the threshold to upgrade.
pub fn check_for_desired_protocol_upgrade(
&self,
total_hpmns: u32,
active_hpmns: u32,
platform_version: &PlatformVersion,
) -> Result<Option<ProtocolVersion>, Error> {
match platform_version
Expand All @@ -38,10 +39,11 @@ impl<C> Platform<C> {
.protocol_upgrade
.check_for_desired_protocol_upgrade
{
0 => self.check_for_desired_protocol_upgrade_v0(total_hpmns, platform_version),
0 => self.check_for_desired_protocol_upgrade_v0(active_hpmns, platform_version),
1 => self.check_for_desired_protocol_upgrade_v1(active_hpmns, platform_version),
version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch {
method: "check_for_desired_protocol_upgrade".to_string(),
known_versions: vec![0],
known_versions: vec![0, 1],
received: version,
})),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::error::execution::ExecutionError;
use crate::error::Error;
use crate::platform_types::platform::Platform;
use dpp::dashcore::Network;

use dpp::version::PlatformVersion;
use drive::dpp::util::deserializer::ProtocolVersion;
Expand All @@ -10,17 +11,26 @@ impl<C> Platform<C> {
/// this should only be called on epoch change
pub(super) fn check_for_desired_protocol_upgrade_v0(
&self,
total_hpmns: u32,
active_hpmns: u32,
platform_version: &PlatformVersion,
) -> Result<Option<ProtocolVersion>, Error> {
let upgrade_percentage_needed = platform_version
.drive_abci
.methods
.protocol_upgrade
.protocol_version_upgrade_percentage_needed;
let upgrade_percentage_needed = if (self.config.network == Network::Dash
&& platform_version.protocol_version == 1)
|| (self.config.network == Network::Testnet && platform_version.protocol_version == 2)
{
// This is a solution for the emergency update to version 3
// We clean this up immediately though as we transition to check_for_desired_protocol_upgrade_v1
51
} else {
platform_version
.drive_abci
.methods
.protocol_upgrade
.protocol_version_upgrade_percentage_needed
};

let required_upgraded_hpmns = 1
+ (total_hpmns as u64)
+ (active_hpmns as u64)
.checked_mul(upgrade_percentage_needed)
.and_then(|product| product.checked_div(100))
.ok_or(Error::Execution(ExecutionError::Overflow(
Expand All @@ -43,7 +53,7 @@ impl<C> Platform<C> {
}

tracing::debug!(
total_hpmns,
active_hpmns,
required_upgraded_hpmns,
all_votes = ?protocol_versions_counter.global_cache,
?versions_passing_threshold,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::error::execution::ExecutionError;
use crate::error::Error;
use crate::platform_types::platform::Platform;

use dpp::version::PlatformVersion;
use drive::dpp::util::deserializer::ProtocolVersion;

impl<C> Platform<C> {
/// checks for a network upgrade and resets activation window
/// this should only be called on epoch change
pub(super) fn check_for_desired_protocol_upgrade_v1(
&self,
active_hpmns: u32,
platform_version: &PlatformVersion,
) -> Result<Option<ProtocolVersion>, Error> {
let upgrade_percentage_needed = platform_version
.drive_abci
.methods
.protocol_upgrade
.protocol_version_upgrade_percentage_needed;

let required_upgraded_hpmns = 1
+ (active_hpmns as u64)
.checked_mul(upgrade_percentage_needed)
.and_then(|product| product.checked_div(100))
.ok_or(Error::Execution(ExecutionError::Overflow(
"overflow for required block count",
)))?;

// if we are at an epoch change, check to see if over 75% of blocks of previous epoch
// were on the future version
let protocol_versions_counter = self.drive.cache.protocol_versions_counter.read();

let mut versions_passing_threshold =
protocol_versions_counter.versions_passing_threshold(required_upgraded_hpmns);

if versions_passing_threshold.len() > 1 {
return Err(Error::Execution(
ExecutionError::ProtocolUpgradeIncoherence(
"only at most 1 version should be able to pass the threshold to upgrade",
),
));
}

tracing::debug!(
active_hpmns,
required_upgraded_hpmns,
all_votes = ?protocol_versions_counter.global_cache,
?versions_passing_threshold,
"Protocol version voting is finished. we require {} upgraded, {} versions passing the threshold: {:?}",
required_upgraded_hpmns,
versions_passing_threshold.len(),
versions_passing_threshold
);

if !versions_passing_threshold.is_empty() {
// same as equals 1
let next_version = versions_passing_threshold.remove(0);
Ok(Some(next_version))
} else {
Ok(None)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ use dpp::state_transition::documents_batch_transition::document_create_transitio
use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition;
use dpp::validation::ConsensusValidationResult;

pub const TARGET_EPOCH_INDEX: EpochIndex = 3;
// TARGET_EPOCH_INDEX was introduced without versioning.
// All Evonodes that have not upgraded to version 1.3 by Epoch 3 will chain stall.
//
// This value was previously 3 before version 1.3
pub const TARGET_EPOCH_INDEX: EpochIndex = 4;

#[inline(always)]
pub fn validate_is_allowed_v0<C>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub mod v0;
/// This means that if we ever want to update EpochInfo, we will need to do so on a release
/// where the new fields of epoch info are not being used. Then make another version once
/// that one is activated.
#[derive(Clone, Serialize, Deserialize, Debug, From, Eq, PartialEq)]
#[derive(Clone, Copy, Serialize, Deserialize, Debug, From, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub enum EpochInfo {
/// Version 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};

/// Info pertinent to the current epoch.
#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq)]
#[derive(Clone, Copy, Serialize, Deserialize, Debug, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct EpochInfoV0 {
/// Current epoch index
Expand Down
1 change: 0 additions & 1 deletion packages/rs-drive/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use dpp::dashcore::Network;
use dpp::fee::epoch::DEFAULT_EPOCHS_PER_ERA;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::str::FromStr;

/// Boolean if GroveDB batching consistency verification is enabled by default
pub const DEFAULT_GROVE_BATCHING_CONSISTENCY_VERIFICATION_ENABLED: bool = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::drive::votes::paths::{
vote_contested_resource_end_date_queries_at_time_tree_path_vec,
vote_end_date_queries_tree_path, vote_end_date_queries_tree_path_vec,
vote_end_date_queries_tree_path_vec,
};
use crate::drive::votes::resolved::vote_polls::contested_document_resource_vote_poll::ContestedDocumentResourceVotePollWithContractInfo;
use crate::drive::Drive;
Expand Down
Loading

0 comments on commit 48a0332

Please sign in to comment.