Skip to content

Commit a0409a1

Browse files
more work
1 parent 31a2d68 commit a0409a1

File tree

26 files changed

+744
-29
lines changed

26 files changed

+744
-29
lines changed

packages/rs-dpp/src/core_types/validator/v0/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use dashcore::{ProTxHash, PubkeyHash};
2-
use std::fmt;
3-
use std::fmt::{Debug, Display, Formatter};
2+
use std::fmt::{Debug, Formatter};
43

54
use crate::bls_signatures::PublicKey as BlsPublicKey;
65
#[cfg(feature = "core-types-serde-conversion")]

packages/rs-dpp/src/errors/consensus/basic/basic_error.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use crate::consensus::basic::identity::{
5252
InvalidIdentityUpdateTransitionDisableKeysError, InvalidIdentityUpdateTransitionEmptyError,
5353
InvalidInstantAssetLockProofError, InvalidInstantAssetLockProofSignatureError,
5454
MissingMasterPublicKeyError, NotImplementedIdentityCreditWithdrawalTransitionPoolingError,
55-
TooManyMasterPublicKeyError,
55+
TooManyMasterPublicKeyError, WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError,
5656
};
5757
use crate::consensus::basic::invalid_identifier_error::InvalidIdentifierError;
5858
use crate::consensus::basic::state_transition::{
@@ -335,6 +335,11 @@ pub enum BasicError {
335335
InvalidIdentityCreditWithdrawalTransitionOutputScriptError,
336336
),
337337

338+
#[error(transparent)]
339+
WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError(
340+
WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError,
341+
),
342+
338343
#[error(transparent)]
339344
InvalidIdentityCreditWithdrawalTransitionCoreFeeError(
340345
InvalidIdentityCreditWithdrawalTransitionCoreFeeError,

packages/rs-dpp/src/errors/consensus/basic/identity/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub use invalid_instant_asset_lock_proof_signature_error::*;
2929
pub use missing_master_public_key_error::*;
3030
pub use not_implemented_identity_credit_withdrawal_transition_pooling_error::*;
3131
pub use too_many_master_public_key_error::*;
32+
pub use withdrawal_output_script_not_allowed_when_signing_with_owner_key::*;
3233

3334
mod data_contract_bounds_not_present_error;
3435
mod disabling_key_id_also_being_added_in_same_transition_error;
@@ -62,3 +63,4 @@ mod invalid_instant_asset_lock_proof_signature_error;
6263
mod missing_master_public_key_error;
6364
mod not_implemented_identity_credit_withdrawal_transition_pooling_error;
6465
mod too_many_master_public_key_error;
66+
mod withdrawal_output_script_not_allowed_when_signing_with_owner_key;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use crate::errors::ProtocolError;
2+
use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
3+
use thiserror::Error;
4+
5+
use crate::consensus::basic::BasicError;
6+
use crate::consensus::ConsensusError;
7+
use crate::identity::core_script::CoreScript;
8+
9+
use crate::identity::KeyID;
10+
use bincode::{Decode, Encode};
11+
12+
#[derive(
13+
Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize,
14+
)]
15+
#[error("Withdrawal output script not allowed when signing with owner key {key_id}")]
16+
#[platform_serialize(unversioned)]
17+
pub struct WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError {
18+
output_script: CoreScript,
19+
key_id: KeyID,
20+
}
21+
22+
/*
23+
24+
DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION
25+
26+
*/
27+
28+
impl WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError {
29+
pub fn new(output_script: CoreScript, key_id: KeyID) -> Self {
30+
Self {
31+
output_script,
32+
key_id,
33+
}
34+
}
35+
36+
pub fn output_script(&self) -> &CoreScript {
37+
&self.output_script
38+
}
39+
40+
pub fn key_id(&self) -> KeyID {
41+
self.key_id
42+
}
43+
}
44+
impl From<WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError> for ConsensusError {
45+
fn from(err: WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError) -> Self {
46+
Self::BasicError(
47+
BasicError::WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError(err),
48+
)
49+
}
50+
}

packages/rs-dpp/src/errors/consensus/codes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ impl ErrorWithCode for BasicError {
153153
Self::MasterPublicKeyUpdateError(_) => 10529,
154154
Self::IdentityAssetLockTransactionOutPointNotEnoughBalanceError(_) => 10530,
155155
Self::IdentityAssetLockStateTransitionReplayError(_) => 10531,
156+
Self::WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError(_) => 10532,
156157

157158
// State Transition Errors: 10600-10699
158159
Self::InvalidStateTransitionTypeError { .. } => 10600,

packages/rs-dpp/src/identity/identity_public_key/random.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,149 @@ impl IdentityPublicKey {
467467
}
468468
}
469469

470+
/// Generates a random ECDSA critical-level authentication key for a masternode owner.
471+
///
472+
/// This function generates a random key that can be used for owner authentication in a masternode context.
473+
/// The function accepts an optional seed for deterministic key generation, or uses entropy-based randomness if no seed is provided.
474+
///
475+
/// # Parameters
476+
///
477+
/// * `id`: The identifier (`KeyID`) for the masternode owner key.
478+
/// * `seed`: An optional `u64` value used to seed the random number generator. If `None`, the RNG will be seeded from entropy.
479+
/// * `platform_version`: A reference to the `PlatformVersion` struct, which is used to determine the correct key structure version.
480+
///
481+
/// # Returns
482+
///
483+
/// Returns a tuple containing the generated `IdentityPublicKey` for the masternode owner and the corresponding private key as a byte vector.
484+
///
485+
/// # Errors
486+
///
487+
/// Returns a `ProtocolError` if the platform version is not supported.
488+
pub fn random_masternode_owner_key(
489+
id: KeyID,
490+
seed: Option<u64>,
491+
platform_version: &PlatformVersion,
492+
) -> Result<(Self, Vec<u8>), ProtocolError> {
493+
let mut rng = match seed {
494+
None => StdRng::from_entropy(),
495+
Some(seed_value) => StdRng::seed_from_u64(seed_value),
496+
};
497+
Self::random_masternode_owner_key_with_rng(id, &mut rng, platform_version)
498+
}
499+
500+
/// Generates a random ECDSA critical-level authentication key for a masternode owner using a custom RNG.
501+
///
502+
/// This function generates a random key using a given random number generator (RNG). This is useful when specific control over the randomness is needed.
503+
///
504+
/// # Parameters
505+
///
506+
/// * `id`: The identifier (`KeyID`) for the masternode owner key.
507+
/// * `rng`: A mutable reference to a `StdRng` instance used to generate randomness.
508+
/// * `platform_version`: A reference to the `PlatformVersion` struct, which is used to determine the correct key structure version.
509+
///
510+
/// # Returns
511+
///
512+
/// Returns a tuple containing the generated `IdentityPublicKey` for the masternode owner and the corresponding private key as a byte vector.
513+
///
514+
/// # Errors
515+
///
516+
/// Returns a `ProtocolError` if the platform version is not supported.
517+
pub fn random_masternode_owner_key_with_rng(
518+
id: KeyID,
519+
rng: &mut StdRng,
520+
platform_version: &PlatformVersion,
521+
) -> Result<(Self, Vec<u8>), ProtocolError> {
522+
match platform_version
523+
.dpp
524+
.identity_versions
525+
.identity_key_structure_version
526+
{
527+
0 => {
528+
let (key, private_key) =
529+
IdentityPublicKeyV0::random_owner_key_with_rng(id, rng, platform_version)?;
530+
Ok((key.into(), private_key))
531+
}
532+
version => Err(ProtocolError::UnknownVersionMismatch {
533+
method: "IdentityPublicKey::random_masternode_owner_key_with_rng".to_string(),
534+
known_versions: vec![0],
535+
received: version,
536+
}),
537+
}
538+
}
539+
540+
/// Generates a random ECDSA critical-level transfer key for a masternode.
541+
///
542+
/// This function generates a random key for use in transferring ownership of a masternode. An optional seed can be provided for deterministic key generation, or entropy-based randomness is used if no seed is given.
543+
///
544+
/// # Parameters
545+
///
546+
/// * `id`: The identifier (`KeyID`) for the masternode transfer key.
547+
/// * `seed`: An optional `u64` value used to seed the random number generator. If `None`, the RNG will be seeded from entropy.
548+
/// * `platform_version`: A reference to the `PlatformVersion` struct, which is used to determine the correct key structure version.
549+
///
550+
/// # Returns
551+
///
552+
/// Returns a tuple containing the generated `IdentityPublicKey` for the masternode transfer key and the corresponding private key as a byte vector.
553+
///
554+
/// # Errors
555+
///
556+
/// Returns a `ProtocolError` if the platform version is not supported.
557+
pub fn random_masternode_transfer_key(
558+
id: KeyID,
559+
seed: Option<u64>,
560+
platform_version: &PlatformVersion,
561+
) -> Result<(Self, Vec<u8>), ProtocolError> {
562+
let mut rng = match seed {
563+
None => StdRng::from_entropy(),
564+
Some(seed_value) => StdRng::seed_from_u64(seed_value),
565+
};
566+
Self::random_masternode_transfer_key_with_rng(id, &mut rng, platform_version)
567+
}
568+
569+
/// Generates a random ECDSA critical-level transfer key for a masternode using a custom RNG.
570+
///
571+
/// This function generates a random key for masternode transfers using a given random number generator (RNG).
572+
///
573+
/// # Parameters
574+
///
575+
/// * `id`: The identifier (`KeyID`) for the masternode transfer key.
576+
/// * `rng`: A mutable reference to a `StdRng` instance used to generate randomness.
577+
/// * `platform_version`: A reference to the `PlatformVersion` struct, which is used to determine the correct key structure version.
578+
///
579+
/// # Returns
580+
///
581+
/// Returns a tuple containing the generated `IdentityPublicKey` for the masternode transfer key and the corresponding private key as a byte vector.
582+
///
583+
/// # Errors
584+
///
585+
/// Returns a `ProtocolError` if the platform version is not supported.
586+
pub fn random_masternode_transfer_key_with_rng(
587+
id: KeyID,
588+
rng: &mut StdRng,
589+
platform_version: &PlatformVersion,
590+
) -> Result<(Self, Vec<u8>), ProtocolError> {
591+
match platform_version
592+
.dpp
593+
.identity_versions
594+
.identity_key_structure_version
595+
{
596+
0 => {
597+
let (key, private_key) =
598+
IdentityPublicKeyV0::random_masternode_transfer_key_with_rng(
599+
id,
600+
rng,
601+
platform_version,
602+
)?;
603+
Ok((key.into(), private_key))
604+
}
605+
version => Err(ProtocolError::UnknownVersionMismatch {
606+
method: "IdentityPublicKey::random_masternode_transfer_key_with_rng".to_string(),
607+
known_versions: vec![0],
608+
received: version,
609+
}),
610+
}
611+
}
612+
470613
/// Generates a random ECDSA high-level authentication public key along with its corresponding private key.
471614
///
472615
/// This method constructs a random ECDSA (using the secp256k1 curve) high-level authentication public key

packages/rs-dpp/src/identity/identity_public_key/v0/random.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::identity::contract_bounds::ContractBounds;
22
use crate::identity::identity_public_key::v0::IdentityPublicKeyV0;
33
use crate::identity::KeyType::{ECDSA_HASH160, ECDSA_SECP256K1};
4-
use crate::identity::Purpose::{AUTHENTICATION, VOTING};
4+
use crate::identity::Purpose::{AUTHENTICATION, OWNER, TRANSFER, VOTING};
55
use crate::identity::SecurityLevel::{CRITICAL, HIGH, MASTER, MEDIUM};
66
use crate::identity::{KeyCount, KeyID, KeyType, Purpose, SecurityLevel};
77
use crate::version::PlatformVersion;
@@ -245,6 +245,58 @@ impl IdentityPublicKeyV0 {
245245
))
246246
}
247247

248+
pub fn random_owner_key_with_rng(
249+
id: KeyID,
250+
rng: &mut StdRng,
251+
platform_version: &PlatformVersion,
252+
) -> Result<(Self, Vec<u8>), ProtocolError> {
253+
let key_type = ECDSA_HASH160;
254+
let purpose = OWNER;
255+
let security_level = CRITICAL;
256+
let read_only = true;
257+
let (data, private_data) =
258+
key_type.random_public_and_private_key_data(rng, platform_version)?;
259+
Ok((
260+
IdentityPublicKeyV0 {
261+
id,
262+
key_type,
263+
purpose,
264+
security_level,
265+
read_only,
266+
disabled_at: None,
267+
data: data.into(),
268+
contract_bounds: None,
269+
},
270+
private_data,
271+
))
272+
}
273+
274+
pub fn random_masternode_transfer_key_with_rng(
275+
id: KeyID,
276+
rng: &mut StdRng,
277+
platform_version: &PlatformVersion,
278+
) -> Result<(Self, Vec<u8>), ProtocolError> {
279+
let key_type = ECDSA_HASH160;
280+
let purpose = TRANSFER;
281+
let security_level = CRITICAL;
282+
let read_only = true;
283+
let (data, private_data) =
284+
key_type.random_public_and_private_key_data(rng, platform_version)?;
285+
Ok((
286+
IdentityPublicKeyV0 {
287+
id,
288+
key_type,
289+
purpose,
290+
security_level,
291+
read_only,
292+
disabled_at: None,
293+
data: data.into(),
294+
contract_bounds: None,
295+
},
296+
private_data,
297+
))
298+
}
299+
248300
pub fn random_ecdsa_critical_level_authentication_key_with_rng(
249301
id: KeyID,
250302
rng: &mut StdRng,

packages/rs-dpp/src/state_transition/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ macro_rules! call_getter_method_identity_signed {
152152
StateTransition::DataContractCreate(st) => Some(st.$method($args)),
153153
StateTransition::DataContractUpdate(st) => Some(st.$method($args)),
154154
StateTransition::DocumentsBatch(st) => Some(st.$method($args)),
155-
StateTransition::IdentityCreate(st) => None,
156-
StateTransition::IdentityTopUp(st) => None,
155+
StateTransition::IdentityCreate(_) => None,
156+
StateTransition::IdentityTopUp(_) => None,
157157
StateTransition::IdentityCreditWithdrawal(st) => Some(st.$method($args)),
158158
StateTransition::IdentityUpdate(st) => Some(st.$method($args)),
159159
StateTransition::IdentityCreditTransfer(st) => Some(st.$method($args)),
@@ -165,8 +165,8 @@ macro_rules! call_getter_method_identity_signed {
165165
StateTransition::DataContractCreate(st) => Some(st.$method()),
166166
StateTransition::DataContractUpdate(st) => Some(st.$method()),
167167
StateTransition::DocumentsBatch(st) => Some(st.$method()),
168-
StateTransition::IdentityCreate(_st) => None,
169-
StateTransition::IdentityTopUp(_st) => None,
168+
StateTransition::IdentityCreate(_) => None,
169+
StateTransition::IdentityTopUp(_) => None,
170170
StateTransition::IdentityCreditWithdrawal(st) => Some(st.$method()),
171171
StateTransition::IdentityUpdate(st) => Some(st.$method()),
172172
StateTransition::IdentityCreditTransfer(st) => Some(st.$method()),

packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/methods/v0/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ use platform_version::version::{FeatureVersion, PlatformVersion};
1616
pub enum PreferredKeyPurposeForSigningWithdrawal {
1717
/// Use any key
1818
Any,
19-
/// Use the master key, then the transfer key
20-
MasterPreferred,
21-
/// Use the transfer key, then the master key
19+
/// Use the owner key, then the transfer key
20+
OwnerPreferred,
21+
/// Use the transfer key, then the owner key
2222
TransferPreferred,
23-
/// Only use the master key
24-
MasterOnly,
23+
/// Only use the owner key
24+
OwnerOnly,
2525
/// Only use the transfer key
2626
TransferOnly,
2727
}

packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v1/v0_methods.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ impl IdentityCreditWithdrawalTransitionMethodsV0 for IdentityCreditWithdrawalTra
6565
let mut key: Option<&IdentityPublicKey>;
6666

6767
match preferred_key_purpose_for_signing_withdrawal {
68-
PreferredKeyPurposeForSigningWithdrawal::MasterPreferred => {
68+
PreferredKeyPurposeForSigningWithdrawal::OwnerPreferred => {
6969
key = identity.get_first_public_key_matching(
70-
Purpose::AUTHENTICATION,
70+
Purpose::OWNER,
7171
SecurityLevel::full_range().into(),
7272
KeyType::all_key_types().into(),
7373
true,
@@ -93,16 +93,16 @@ impl IdentityCreditWithdrawalTransitionMethodsV0 for IdentityCreditWithdrawalTra
9393

9494
if key.is_none() || !signer.can_sign_with(key.unwrap()) {
9595
key = identity.get_first_public_key_matching(
96-
Purpose::AUTHENTICATION,
96+
Purpose::OWNER,
9797
SecurityLevel::full_range().into(),
9898
KeyType::all_key_types().into(),
9999
true,
100100
);
101101
}
102102
}
103-
PreferredKeyPurposeForSigningWithdrawal::MasterOnly => {
103+
PreferredKeyPurposeForSigningWithdrawal::OwnerOnly => {
104104
key = identity.get_first_public_key_matching(
105-
Purpose::AUTHENTICATION,
105+
Purpose::OWNER,
106106
SecurityLevel::full_range().into(),
107107
KeyType::all_key_types().into(),
108108
true,

0 commit comments

Comments
 (0)