Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(strategy-tests): create some identity transitions rather than none on error #2058

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
80 changes: 57 additions & 23 deletions packages/strategy-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,30 +484,38 @@ impl Strategy {
Vec<StateTransition>,
Vec<FinalizeBlockOperation>,
Vec<Identity>,
Vec<ProtocolError>,
) {
let mut finalize_block_operations = vec![];
let mut state_transitions = vec![];
let mut identities = vec![];
let mut errors = vec![];

// Get identity state transitions
// Start identities are done on the 1st block, identity inserts are done on 3rd+ blocks
let identity_state_transitions = match self.identity_state_transitions_for_block(
let identity_state_transition_results = self.identity_state_transitions_for_block(
block_info,
self.start_identities.starting_balances,
signer,
rng,
asset_lock_proofs,
config,
platform_version,
) {
Ok(transitions) => transitions,
Err(e) => {
tracing::error!("identity_state_transitions_for_block error: {}", e);
return (vec![], finalize_block_operations, vec![]);
}
};
);

// Create state_transitions vec and identities vec based on identity_state_transitions outcome
let (identities, mut state_transitions): (Vec<Identity>, Vec<StateTransition>) =
identity_state_transitions.into_iter().unzip();
// Process each result in the vector of results
for result in identity_state_transition_results {
match result {
Ok((identity, state_transition)) => {
identities.push(identity);
state_transitions.push(state_transition);
}
Err(e) => {
tracing::error!("Error in identity_state_transitions_for_block: {:?}", e);
errors.push(e);
}
}
}

// Add initial contracts for contracts_with_updates on 2nd block of strategy
if block_info.height == config.start_block_height + 1 {
Expand Down Expand Up @@ -552,7 +560,12 @@ impl Strategy {
state_transitions.append(&mut initial_contract_update_state_transitions);
}

(state_transitions, finalize_block_operations, identities)
(
state_transitions,
finalize_block_operations,
identities,
errors,
)
}

/// Processes strategy operations to generate state transitions specific to operations for a given block.
Expand Down Expand Up @@ -1521,27 +1534,44 @@ impl Strategy {
///
/// # Parameters
/// - `block_info`: Provides details about the current block, such as height, to guide the generation of state transitions.
/// - `amount`: The amount of funds to associate with each identity creation, influencing the identity state.
/// - `signer`: A mutable reference to a signer instance, used for signing the state transitions of identities.
/// - `rng`: A mutable reference to a random number generator, for creating randomized elements where necessary.
/// - `asset_lock_proofs`: A vector of asset lock proofs and associated private keys.
/// - `config`: Configuration details of the strategy, including the start block height.
/// - `platform_version`: Specifies the version of the Dash Platform, ensuring compatibility with its features and behaviors.
///
/// # Returns
/// A vector of tuples, each containing an `Identity` and its associated `StateTransition`, representing the actions taken by or on behalf of that identity within the block.
/// A vector of `Result` values, each either containing:
/// - `Ok((Identity, StateTransition))`: A tuple representing a successfully created identity and its corresponding state transition.
/// - `Err(ProtocolError)`: An error encountered during the creation of an identity or its state transition.
///
/// This return type allows for partial success; even if some state transitions fail, the successful ones will be included in the result.
///
/// # Examples
/// ```ignore
/// // Assuming `strategy` is an instance of `Strategy`, with `block_info`, `signer`, `rng`,
/// // `asset_lock_proofs`, `config`, and `platform_version` properly initialized:
/// let identity_transitions = strategy.identity_state_transitions_for_block(
/// &block_info,
/// amount,
/// &mut signer,
/// &mut rng,
/// &mut create_asset_lock,
/// &mut asset_lock_proofs,
/// &config,
/// &platform_version,
/// ).expect("Expected to generate identity state transitions without error");
/// );
///
/// for result in identity_transitions {
/// match result {
/// Ok((identity, state_transition)) => {
/// // Handle successful transition
/// }
/// Err(e) => {
/// // Handle error
/// }
/// }
/// }
/// ```
///
/// # Notes
Expand All @@ -1556,14 +1586,14 @@ impl Strategy {
asset_lock_proofs: &mut Vec<(AssetLockProof, PrivateKey)>,
config: &StrategyConfig,
platform_version: &PlatformVersion,
) -> Result<Vec<(Identity, StateTransition)>, ProtocolError> {
) -> Vec<Result<(Identity, StateTransition), ProtocolError>> {
let mut state_transitions = vec![];

// Add start_identities
if block_info.height == config.start_block_height
&& self.start_identities.number_of_identities > 0
{
let mut new_transitions = crate::transitions::create_identities_state_transitions(
let new_transitions = crate::transitions::create_identities_state_transitions(
self.start_identities.number_of_identities.into(),
self.start_identities.keys_per_identity.into(),
&self.start_identities.extra_keys,
Expand All @@ -1572,8 +1602,10 @@ impl Strategy {
rng,
asset_lock_proofs,
platform_version,
)?;
state_transitions.append(&mut new_transitions);
);

// Extend the state_transitions with the results
state_transitions.extend(new_transitions);
}

// Add identities_inserts
Expand All @@ -1583,7 +1615,7 @@ impl Strategy {
if frequency.check_hit(rng) {
let count = frequency.events(rng); // number of identities to create

let mut new_transitions = crate::transitions::create_identities_state_transitions(
let new_transitions = crate::transitions::create_identities_state_transitions(
count,
self.identity_inserts.start_keys as KeyID,
&self.identity_inserts.extra_keys,
Expand All @@ -1592,12 +1624,14 @@ impl Strategy {
rng,
asset_lock_proofs,
platform_version,
)?;
state_transitions.append(&mut new_transitions);
);

// Extend the state_transitions with the results
state_transitions.extend(new_transitions);
}
}

Ok(state_transitions)
state_transitions
}

/// Initializes contracts and generates their creation state transitions based on the `contracts_with_updates` field.
Expand Down
62 changes: 41 additions & 21 deletions packages/strategy-tests/src/transitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,9 +614,10 @@ pub fn create_identity_credit_transfer_transition(
/// platform version is used is crucial for compatibility and consistency in state transition creation.
///
/// # Returns
/// A vector of tuples, where each tuple contains:
/// 1. `Identity`: The generated random identity object.
/// 2. `StateTransition`: The generated state transition representing the creation of the identity.
/// A vector of results, where each result is either:
/// 1. `Ok((Identity, StateTransition))`: A tuple containing the generated random identity object and
/// the generated state transition representing the creation of the identity.
/// 2. `Err(ProtocolError)`: An error that occurred during the process.
///
/// # Examples
/// ```ignore
Expand All @@ -642,14 +643,18 @@ pub fn create_identities_state_transitions(
rng: &mut StdRng,
asset_lock_proofs: &mut Vec<(AssetLockProof, PrivateKey)>,
platform_version: &PlatformVersion,
) -> Result<Vec<(Identity, StateTransition)>, ProtocolError> {
) -> Vec<Result<(Identity, StateTransition), ProtocolError>> {
let (mut identities, mut keys) =
Identity::random_identities_with_private_keys_with_rng::<Vec<_>>(
count,
key_count,
rng,
platform_version,
)
.map_err(|e| {
tracing::error!("Failed to create identities and keys: {:?}", e);
ProtocolError::Generic("Failed to create identities and keys".to_string())
})
.expect("Expected to create identities and keys");

let starting_id_num = signer
Expand All @@ -663,18 +668,28 @@ pub fn create_identities_state_transitions(
for (_, (purpose, security_to_key_type_map)) in extra_keys.iter().enumerate() {
for (security_level, key_types) in security_to_key_type_map {
for key_type in key_types {
let (key, private_key) = IdentityPublicKey::random_key_with_known_attributes(
(identity.public_keys().len() + 1) as KeyID,
rng,
*purpose,
*security_level,
*key_type,
None,
platform_version,
)?;
identity.add_public_key(key.clone());
let key_num = key_count as usize * (i + 1) + i;
keys.insert(key_num, (key, private_key))
// Generate a key with known attributes, handle any potential error
if let Ok((key, private_key)) =
IdentityPublicKey::random_key_with_known_attributes(
(identity.public_keys().len() + 1) as KeyID,
rng,
*purpose,
*security_level,
*key_type,
None,
platform_version,
)
{
identity.add_public_key(key.clone());
let key_num = key_count as usize * (i + 1) + i;
keys.insert(key_num, (key, private_key));
} else {
tracing::error!(
"Failed to generate key with known attributes for identity index {}",
i
);
continue;
}
}
}
}
Expand Down Expand Up @@ -704,9 +719,10 @@ pub fn create_identities_state_transitions(
.values_mut()
.enumerate()
.for_each(|(key_index, public_key)| {
let IdentityPublicKey::V0(ref mut id_pub_key_v0) = public_key;
let new_id = identity_starting_id + key_index as u32;
id_pub_key_v0.set_id(new_id);
if let IdentityPublicKey::V0(ref mut id_pub_key_v0) = public_key {
let new_id = identity_starting_id + key_index as u32;
id_pub_key_v0.set_id(new_id);
}
});

if let Some(proof_and_pk) = asset_lock_proofs.pop() {
Expand All @@ -725,16 +741,20 @@ pub fn create_identities_state_transitions(
identity.set_id(identity_create_transition.owner_id());
Ok((identity, identity_create_transition))
}
Err(e) => Err(e),
Err(e) => {
tracing::error!("Error creating transition: {:?}", e);
Err(e)
}
}
} else {
tracing::error!("No asset lock proof to create transition");
Err(ProtocolError::Generic(
"No asset lock proofs available for create_identities_state_transitions"
.to_string(),
))
}
})
.collect::<Result<Vec<(Identity, StateTransition)>, ProtocolError>>()
.collect::<Vec<Result<(Identity, StateTransition), ProtocolError>>>()
}

/// Generates state transitions for the creation of new identities.
Expand Down
Loading