Skip to content

Commit adcd3b8

Browse files
fix!: emergency hard fork to fix masternode voting (#2397)
1 parent 21ec393 commit adcd3b8

File tree

7 files changed

+254
-7
lines changed
  • packages
    • rs-drive-abci/src/execution/validation/state_transition/state_transitions/masternode_vote/nonce
    • rs-platform-version/src/version

7 files changed

+254
-7
lines changed

packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/masternode_vote/nonce/mod.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::error::execution::ExecutionError;
22
use crate::error::Error;
33
use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext;
44
use crate::execution::validation::state_transition::masternode_vote::nonce::v0::MasternodeVoteTransitionIdentityNonceV0;
5+
use crate::execution::validation::state_transition::masternode_vote::nonce::v1::MasternodeVoteTransitionIdentityNonceV1;
56
use crate::execution::validation::state_transition::processor::v0::StateTransitionNonceValidationV0;
67
use crate::platform_types::platform::PlatformStateRef;
78
use dpp::block::block_info::BlockInfo;
@@ -11,6 +12,8 @@ use dpp::version::PlatformVersion;
1112
use drive::grovedb::TransactionArg;
1213

1314
pub(crate) mod v0;
15+
pub(crate) mod v1;
16+
1417
impl StateTransitionNonceValidationV0 for MasternodeVoteTransition {
1518
fn validate_nonces(
1619
&self,
@@ -34,14 +37,21 @@ impl StateTransitionNonceValidationV0 for MasternodeVoteTransition {
3437
execution_context,
3538
platform_version,
3639
),
40+
Some(1) => self.validate_nonce_v1(
41+
platform,
42+
block_info,
43+
tx,
44+
execution_context,
45+
platform_version,
46+
),
3747
Some(version) => Err(Error::Execution(ExecutionError::UnknownVersionMismatch {
3848
method: "masternode vote transition: validate_nonces".to_string(),
39-
known_versions: vec![0],
49+
known_versions: vec![0, 1],
4050
received: version,
4151
})),
4252
None => Err(Error::Execution(ExecutionError::VersionNotActive {
4353
method: "masternode vote transition: validate_nonces".to_string(),
44-
known_versions: vec![0],
54+
known_versions: vec![0, 1],
4555
})),
4656
}
4757
}

packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/masternode_vote/nonce/v0/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::execution::types::execution_operation::ValidationOperation;
1414
use crate::execution::types::state_transition_execution_context::{
1515
StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0,
1616
};
17+
use crate::execution::validation::state_transition::masternode_vote::nonce::v1::MasternodeVoteTransitionIdentityNonceV1;
1718
use crate::platform_types::platform::PlatformStateRef;
1819
use dpp::version::PlatformVersion;
1920
use drive::grovedb::TransactionArg;
@@ -39,6 +40,17 @@ impl MasternodeVoteTransitionIdentityNonceV0 for MasternodeVoteTransition {
3940
execution_context: &mut StateTransitionExecutionContext,
4041
platform_version: &PlatformVersion,
4142
) -> Result<SimpleConsensusValidationResult, Error> {
43+
// We are introducing this as an emergency hard fork activating at epoch 13.
44+
if block_info.epoch.index >= 13 {
45+
return self.validate_nonce_v1(
46+
platform,
47+
block_info,
48+
tx,
49+
execution_context,
50+
platform_version,
51+
);
52+
}
53+
4254
let revision_nonce = self.nonce();
4355

4456
if revision_nonce & MISSING_IDENTITY_REVISIONS_FILTER > 0 {
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use crate::error::Error;
2+
use dpp::block::block_info::BlockInfo;
3+
use dpp::consensus::basic::document::NonceOutOfBoundsError;
4+
use dpp::consensus::basic::BasicError;
5+
use dpp::identity::identity_nonce::{
6+
validate_identity_nonce_update, validate_new_identity_nonce, MISSING_IDENTITY_REVISIONS_FILTER,
7+
};
8+
use dpp::state_transition::masternode_vote_transition::accessors::MasternodeVoteTransitionAccessorsV0;
9+
use dpp::state_transition::masternode_vote_transition::MasternodeVoteTransition;
10+
11+
use dpp::validation::SimpleConsensusValidationResult;
12+
13+
use crate::execution::types::execution_operation::ValidationOperation;
14+
use crate::execution::types::state_transition_execution_context::{
15+
StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0,
16+
};
17+
use crate::platform_types::platform::PlatformStateRef;
18+
use dpp::version::PlatformVersion;
19+
use drive::grovedb::TransactionArg;
20+
21+
pub(in crate::execution::validation::state_transition::state_transitions) trait MasternodeVoteTransitionIdentityNonceV1
22+
{
23+
fn validate_nonce_v1(
24+
&self,
25+
platform: &PlatformStateRef,
26+
block_info: &BlockInfo,
27+
tx: TransactionArg,
28+
execution_context: &mut StateTransitionExecutionContext,
29+
platform_version: &PlatformVersion,
30+
) -> Result<SimpleConsensusValidationResult, Error>;
31+
}
32+
33+
impl MasternodeVoteTransitionIdentityNonceV1 for MasternodeVoteTransition {
34+
fn validate_nonce_v1(
35+
&self,
36+
platform: &PlatformStateRef,
37+
block_info: &BlockInfo,
38+
tx: TransactionArg,
39+
execution_context: &mut StateTransitionExecutionContext,
40+
platform_version: &PlatformVersion,
41+
) -> Result<SimpleConsensusValidationResult, Error> {
42+
let revision_nonce = self.nonce();
43+
44+
if revision_nonce & MISSING_IDENTITY_REVISIONS_FILTER > 0 {
45+
return Ok(SimpleConsensusValidationResult::new_with_error(
46+
BasicError::NonceOutOfBoundsError(NonceOutOfBoundsError::new(revision_nonce))
47+
.into(),
48+
));
49+
}
50+
51+
let voter_identity_id = self.voter_identity_id();
52+
53+
let (existing_nonce, fee) = platform.drive.fetch_identity_nonce_with_fees(
54+
voter_identity_id.to_buffer(),
55+
block_info,
56+
true,
57+
tx,
58+
platform_version,
59+
)?;
60+
61+
execution_context.add_operation(ValidationOperation::PrecalculatedOperation(fee));
62+
63+
let result = if let Some(existing_nonce) = existing_nonce {
64+
validate_identity_nonce_update(existing_nonce, revision_nonce, voter_identity_id)
65+
} else {
66+
validate_new_identity_nonce(revision_nonce, voter_identity_id)
67+
};
68+
69+
Ok(result)
70+
}
71+
}

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub mod v1;
22
pub mod v2;
33
pub mod v3;
44
pub mod v4;
5+
pub mod v5;
56

67
use versioned_feature_core::{FeatureVersion, OptionalFeatureVersion};
78

packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ use crate::version::drive_abci_versions::drive_abci_validation_versions::{
66
DriveAbciValidationVersions, PenaltyAmounts,
77
};
88

9+
// We introduced nonce validation for masternode voting in this version, and changed the call
10+
// for nonce validation, however the actual validation for masternode voting was faulty, which is
11+
// why we introduced V5. (We also are making an emergency hard fork).
912
pub const DRIVE_ABCI_VALIDATION_VERSIONS_V4: DriveAbciValidationVersions =
1013
DriveAbciValidationVersions {
1114
state_transitions: DriveAbciStateTransitionValidationVersions {
@@ -131,7 +134,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V4: DriveAbciValidationVersions =
131134
document_update_price_transition_state_validation: 0,
132135
},
133136
},
134-
has_nonce_validation: 1,
137+
has_nonce_validation: 1, // <---- changed this
135138
process_state_transition: 0,
136139
state_transition_to_execution_event_for_check_tx: 0,
137140
penalties: PenaltyAmounts {
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
use crate::version::drive_abci_versions::drive_abci_validation_versions::{
2+
DriveAbciAssetLockValidationVersions, DriveAbciDocumentsStateTransitionValidationVersions,
3+
DriveAbciStateTransitionCommonValidationVersions, DriveAbciStateTransitionValidationVersion,
4+
DriveAbciStateTransitionValidationVersions, DriveAbciValidationConstants,
5+
DriveAbciValidationDataTriggerAndBindingVersions, DriveAbciValidationDataTriggerVersions,
6+
DriveAbciValidationVersions, PenaltyAmounts,
7+
};
8+
9+
// In this version we change the nonce validation of masternode voting.
10+
// There was a bug before this where the nonce validation would validate using the owner identity
11+
// instead of the voting identity.
12+
// This is not the same issue as before when we didn't validate nonces on masternode votes at all.
13+
pub const DRIVE_ABCI_VALIDATION_VERSIONS_V5: DriveAbciValidationVersions =
14+
DriveAbciValidationVersions {
15+
state_transitions: DriveAbciStateTransitionValidationVersions {
16+
common_validation_methods: DriveAbciStateTransitionCommonValidationVersions {
17+
asset_locks: DriveAbciAssetLockValidationVersions {
18+
fetch_asset_lock_transaction_output_sync: 0,
19+
verify_asset_lock_is_not_spent_and_has_enough_balance: 0,
20+
},
21+
validate_identity_public_key_contract_bounds: 0,
22+
validate_identity_public_key_ids_dont_exist_in_state: 0,
23+
validate_identity_public_key_ids_exist_in_state: 0,
24+
validate_state_transition_identity_signed: 0,
25+
validate_unique_identity_public_key_hashes_in_state: 0,
26+
validate_master_key_uniqueness: 0,
27+
validate_simple_pre_check_balance: 0,
28+
},
29+
max_asset_lock_usage_attempts: 16,
30+
identity_create_state_transition: DriveAbciStateTransitionValidationVersion {
31+
basic_structure: Some(0),
32+
advanced_structure: Some(0),
33+
identity_signatures: Some(0),
34+
advanced_minimum_balance_pre_check: None,
35+
nonce: None,
36+
state: 0,
37+
transform_into_action: 0,
38+
},
39+
identity_update_state_transition: DriveAbciStateTransitionValidationVersion {
40+
basic_structure: Some(0),
41+
advanced_structure: Some(0),
42+
identity_signatures: Some(0),
43+
advanced_minimum_balance_pre_check: None,
44+
nonce: Some(0),
45+
state: 0,
46+
transform_into_action: 0,
47+
},
48+
identity_top_up_state_transition: DriveAbciStateTransitionValidationVersion {
49+
basic_structure: Some(0),
50+
advanced_structure: None,
51+
identity_signatures: None,
52+
advanced_minimum_balance_pre_check: None,
53+
nonce: None,
54+
state: 0,
55+
transform_into_action: 0,
56+
},
57+
identity_credit_withdrawal_state_transition:
58+
DriveAbciStateTransitionValidationVersion {
59+
basic_structure: Some(1),
60+
advanced_structure: None,
61+
identity_signatures: None,
62+
advanced_minimum_balance_pre_check: Some(0),
63+
nonce: Some(0),
64+
state: 0,
65+
transform_into_action: 0,
66+
},
67+
identity_credit_withdrawal_state_transition_purpose_matches_requirements: 0,
68+
identity_credit_transfer_state_transition: DriveAbciStateTransitionValidationVersion {
69+
basic_structure: Some(0),
70+
advanced_structure: None,
71+
identity_signatures: None,
72+
advanced_minimum_balance_pre_check: Some(0),
73+
nonce: Some(0),
74+
state: 0,
75+
transform_into_action: 0,
76+
},
77+
masternode_vote_state_transition: DriveAbciStateTransitionValidationVersion {
78+
basic_structure: None,
79+
advanced_structure: Some(0),
80+
identity_signatures: None,
81+
advanced_minimum_balance_pre_check: Some(0),
82+
nonce: Some(1), // <---- Changed this here
83+
state: 0,
84+
transform_into_action: 0,
85+
},
86+
contract_create_state_transition: DriveAbciStateTransitionValidationVersion {
87+
basic_structure: Some(0),
88+
advanced_structure: None,
89+
identity_signatures: None,
90+
advanced_minimum_balance_pre_check: None,
91+
nonce: Some(0),
92+
state: 0,
93+
transform_into_action: 0,
94+
},
95+
contract_update_state_transition: DriveAbciStateTransitionValidationVersion {
96+
basic_structure: None,
97+
advanced_structure: None,
98+
identity_signatures: None,
99+
advanced_minimum_balance_pre_check: None,
100+
nonce: Some(0),
101+
state: 0,
102+
transform_into_action: 0,
103+
},
104+
documents_batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions {
105+
balance_pre_check: 0,
106+
basic_structure: 0,
107+
advanced_structure: 0,
108+
state: 0,
109+
revision: 0,
110+
transform_into_action: 0,
111+
data_triggers: DriveAbciValidationDataTriggerAndBindingVersions {
112+
bindings: 0,
113+
triggers: DriveAbciValidationDataTriggerVersions {
114+
create_contact_request_data_trigger: 0,
115+
create_domain_data_trigger: 0,
116+
create_identity_data_trigger: 0,
117+
create_feature_flag_data_trigger: 0,
118+
create_masternode_reward_shares_data_trigger: 0,
119+
delete_withdrawal_data_trigger: 0,
120+
reject_data_trigger: 0,
121+
},
122+
},
123+
is_allowed: 0,
124+
document_create_transition_structure_validation: 0,
125+
document_delete_transition_structure_validation: 0,
126+
document_replace_transition_structure_validation: 0,
127+
document_transfer_transition_structure_validation: 0,
128+
document_purchase_transition_structure_validation: 0,
129+
document_update_price_transition_structure_validation: 0,
130+
document_create_transition_state_validation: 1,
131+
document_delete_transition_state_validation: 0,
132+
document_replace_transition_state_validation: 0,
133+
document_transfer_transition_state_validation: 0,
134+
document_purchase_transition_state_validation: 0,
135+
document_update_price_transition_state_validation: 0,
136+
},
137+
},
138+
has_nonce_validation: 1,
139+
process_state_transition: 0,
140+
state_transition_to_execution_event_for_check_tx: 0,
141+
penalties: PenaltyAmounts {
142+
identity_id_not_correct: 50000000,
143+
unique_key_already_present: 10000000,
144+
validation_of_added_keys_structure_failure: 10000000,
145+
validation_of_added_keys_proof_of_possession_failure: 50000000,
146+
},
147+
event_constants: DriveAbciValidationConstants {
148+
maximum_vote_polls_to_process: 2,
149+
maximum_contenders_to_consider: 100,
150+
},
151+
};

packages/rs-platform-version/src/version/v7.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::version::dpp_versions::DPPVersion;
1616
use crate::version::drive_abci_versions::drive_abci_method_versions::v4::DRIVE_ABCI_METHOD_VERSIONS_V4;
1717
use crate::version::drive_abci_versions::drive_abci_query_versions::v1::DRIVE_ABCI_QUERY_VERSIONS_V1;
1818
use crate::version::drive_abci_versions::drive_abci_structure_versions::v1::DRIVE_ABCI_STRUCTURE_VERSIONS_V1;
19-
use crate::version::drive_abci_versions::drive_abci_validation_versions::v4::DRIVE_ABCI_VALIDATION_VERSIONS_V4;
19+
use crate::version::drive_abci_versions::drive_abci_validation_versions::v5::DRIVE_ABCI_VALIDATION_VERSIONS_V5;
2020
use crate::version::drive_abci_versions::drive_abci_withdrawal_constants::v2::DRIVE_ABCI_WITHDRAWAL_CONSTANTS_V2;
2121
use crate::version::drive_abci_versions::DriveAbciVersion;
2222
use crate::version::drive_versions::v2::DRIVE_VERSION_V2;
@@ -28,15 +28,14 @@ use crate::version::ProtocolVersion;
2828

2929
pub const PROTOCOL_VERSION_7: ProtocolVersion = 7;
3030

31-
/// This version adds token support.
32-
//todo: make changes
31+
/// This version fixes masternode voting nonce issue.
3332
pub const PLATFORM_V7: PlatformVersion = PlatformVersion {
3433
protocol_version: PROTOCOL_VERSION_7,
3534
drive: DRIVE_VERSION_V2,
3635
drive_abci: DriveAbciVersion {
3736
structs: DRIVE_ABCI_STRUCTURE_VERSIONS_V1,
3837
methods: DRIVE_ABCI_METHOD_VERSIONS_V4,
39-
validation_and_processing: DRIVE_ABCI_VALIDATION_VERSIONS_V4,
38+
validation_and_processing: DRIVE_ABCI_VALIDATION_VERSIONS_V5, // <--- changed to V5
4039
withdrawal_constants: DRIVE_ABCI_WITHDRAWAL_CONSTANTS_V2,
4140
query: DRIVE_ABCI_QUERY_VERSIONS_V1,
4241
},

0 commit comments

Comments
 (0)