From 3b7ca92feb544519a4f326bdc689ede277dbe6f9 Mon Sep 17 00:00:00 2001 From: QuantumExplorer Date: Sun, 10 Nov 2024 00:25:48 +0100 Subject: [PATCH] feat: hardcoded identity transfers in strategy tests (#2322) Authored-by: pauldelucia --- .../tests/strategy_tests/main.rs | 7 +- .../tests/strategy_tests/strategy.rs | 16 +++- .../tests/strategy_tests/voting_tests.rs | 90 +++++++++++-------- packages/strategy-tests/src/lib.rs | 70 ++++++++++----- packages/strategy-tests/src/operations.rs | 19 +++- packages/strategy-tests/src/transitions.rs | 2 +- 6 files changed, 138 insertions(+), 66 deletions(-) diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 2312241cc6..03bb92bc1a 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -2602,7 +2602,10 @@ mod tests { &simple_signer, &mut rng, platform_version, - ); + ) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) + .collect(); let strategy = NetworkStrategy { strategy: Strategy { @@ -3910,7 +3913,7 @@ mod tests { strategy: Strategy { start_contracts: vec![], operations: vec![Operation { - op_type: OperationType::IdentityTransfer, + op_type: OperationType::IdentityTransfer(None), frequency: Frequency { times_per_block_range: 1..3, chance_per_block: None, diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index 667b846868..bf3235ea78 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -41,7 +41,7 @@ use drive_abci::rpc::core::MockCoreRPCLike; use rand::prelude::{IteratorRandom, SliceRandom, StdRng}; use rand::Rng; use strategy_tests::Strategy; -use strategy_tests::transitions::{create_state_transitions_for_identities, create_state_transitions_for_identities_and_proofs, instant_asset_lock_proof_fixture, instant_asset_lock_proof_fixture_with_dynamic_range}; +use strategy_tests::transitions::{create_state_transitions_for_identities, create_state_transitions_for_identities_and_proofs, instant_asset_lock_proof_fixture_with_dynamic_range}; use std::borrow::Cow; use std::collections::{BTreeMap, HashMap, HashSet}; use std::ops::RangeInclusive; @@ -404,8 +404,18 @@ impl NetworkStrategy { ); state_transitions.append(&mut new_transitions); } + // Extend the state transitions with the strategy's hard coded start identities + // Filtering out the ones that have no create transition if !self.strategy.start_identities.hard_coded.is_empty() { - state_transitions.extend(self.strategy.start_identities.hard_coded.clone()); + state_transitions.extend( + self.strategy.start_identities.hard_coded.iter().filter_map( + |(identity, transition)| { + transition.as_ref().map(|create_transition| { + (identity.clone(), create_transition.clone()) + }) + }, + ), + ); } } let frequency = &self.strategy.identity_inserts.frequency; @@ -1196,7 +1206,7 @@ impl NetworkStrategy { operations.push(state_transition); } } - OperationType::IdentityTransfer if current_identities.len() > 1 => { + OperationType::IdentityTransfer(_) if current_identities.len() > 1 => { let identities_clone = current_identities.clone(); // Sender is the first in the list, which should be loaded_identity diff --git a/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs index e14f8d7b1b..83834520c0 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs @@ -79,13 +79,17 @@ mod tests { simple_signer.add_keys(keys1); - let start_identities = create_state_transitions_for_identities( - vec![identity1], - &(dash_to_duffs!(1)..=dash_to_duffs!(1)), - &simple_signer, - &mut rng, - platform_version, - ); + let start_identities: Vec<(Identity, Option)> = + create_state_transitions_for_identities( + vec![identity1], + &(dash_to_duffs!(1)..=dash_to_duffs!(1)), + &simple_signer, + &mut rng, + platform_version, + ) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) + .collect(); let dpns_contract = platform .drive @@ -363,13 +367,17 @@ mod tests { simple_signer.add_keys(keys2); - let start_identities = create_state_transitions_for_identities( - vec![identity1, identity2], - &(dash_to_duffs!(1)..=dash_to_duffs!(1)), - &simple_signer, - &mut rng, - platform_version, - ); + let start_identities: Vec<(Identity, Option)> = + create_state_transitions_for_identities( + vec![identity1, identity2], + &(dash_to_duffs!(1)..=dash_to_duffs!(1)), + &simple_signer, + &mut rng, + platform_version, + ) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) + .collect(); let dpns_contract = platform .drive @@ -635,13 +643,17 @@ mod tests { simple_signer.add_keys(keys2); - let start_identities = create_state_transitions_for_identities( - vec![identity1, identity2], - &(dash_to_duffs!(1)..=dash_to_duffs!(1)), - &simple_signer, - &mut rng, - platform_version, - ); + let start_identities: Vec<(Identity, Option)> = + create_state_transitions_for_identities( + vec![identity1, identity2], + &(dash_to_duffs!(1)..=dash_to_duffs!(1)), + &simple_signer, + &mut rng, + platform_version, + ) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) + .collect(); let dpns_contract = platform .drive @@ -988,13 +1000,17 @@ mod tests { simple_signer.add_keys(keys2); - let start_identities = create_state_transitions_for_identities( - vec![identity1, identity2], - &(dash_to_duffs!(1)..=dash_to_duffs!(1)), - &simple_signer, - &mut rng, - platform_version, - ); + let start_identities: Vec<(Identity, Option)> = + create_state_transitions_for_identities( + vec![identity1, identity2], + &(dash_to_duffs!(1)..=dash_to_duffs!(1)), + &simple_signer, + &mut rng, + platform_version, + ) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) + .collect(); let dpns_contract = platform .drive @@ -1353,13 +1369,17 @@ mod tests { simple_signer.add_keys(keys2); - let start_identities = create_state_transitions_for_identities( - vec![identity1, identity2], - &(dash_to_duffs!(1)..=dash_to_duffs!(1)), - &simple_signer, - &mut rng, - platform_version, - ); + let start_identities: Vec<(Identity, Option)> = + create_state_transitions_for_identities( + vec![identity1, identity2], + &(dash_to_duffs!(1)..=dash_to_duffs!(1)), + &simple_signer, + &mut rng, + platform_version, + ) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) + .collect(); let dpns_contract = platform .drive diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index 61395d99f2..efdb702a48 100644 --- a/packages/strategy-tests/src/lib.rs +++ b/packages/strategy-tests/src/lib.rs @@ -44,6 +44,7 @@ use platform_version::TryFromPlatformVersioned; use rand::prelude::StdRng; use rand::seq::{IteratorRandom, SliceRandom}; use rand::Rng; +use transitions::create_identity_credit_transfer_transition; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::ops::RangeInclusive; use bincode::{Decode, Encode}; @@ -146,7 +147,7 @@ pub struct StartIdentities { pub keys_per_identity: u8, pub starting_balances: u64, // starting balance in duffs pub extra_keys: KeyMaps, - pub hard_coded: Vec<(Identity, StateTransition)>, + pub hard_coded: Vec<(Identity, Option)>, } /// Identities to register on the first block of the strategy @@ -1287,38 +1288,65 @@ impl Strategy { } // Generate state transition for identity transfer operation - OperationType::IdentityTransfer if current_identities.len() > 1 => { + OperationType::IdentityTransfer(identity_transfer_info) => { for _ in 0..count { - let identities_count = current_identities.len(); - if identities_count == 0 { - break; - } + // Handle the case where specific sender, recipient, and amount are provided + if let Some(transfer_info) = identity_transfer_info { + let sender = current_identities + .iter() + .find(|identity| identity.id() == transfer_info.from) + .expect( + "Expected to find sender identity in hardcoded start identities", + ); + let recipient = current_identities + .iter() + .find(|identity| identity.id() == transfer_info.to) + .expect( + "Expected to find recipient identity in hardcoded start identities", + ); - // Select a random identity from the current_identities for the sender - let random_index_sender = rng.gen_range(0..identities_count); + let state_transition = create_identity_credit_transfer_transition( + &sender, + &recipient, + identity_nonce_counter, + signer, // This means in the TUI, the loaded identity must always be the sender since we're always signing with it for now + transfer_info.amount, + ); + operations.push(state_transition); + } else if current_identities.len() > 1 { + // Handle the case where no sender, recipient, and amount are provided - // Clone current_identities to a Vec for manipulation - let mut unused_identities: Vec<_> = - current_identities.iter().cloned().collect(); - unused_identities.remove(random_index_sender); // Remove the sender - let unused_identities_count = unused_identities.len(); + let identities_count = current_identities.len(); + if identities_count == 0 { + break; + } - // Select a random identity from the remaining ones for the recipient - let random_index_recipient = rng.gen_range(0..unused_identities_count); - let recipient = &unused_identities[random_index_recipient]; + // Select a random identity from the current_identities for the sender + let random_index_sender = rng.gen_range(0..identities_count); - // Use the sender index on the original slice - let sender = &mut current_identities[random_index_sender]; + // Clone current_identities to a Vec for manipulation + let mut unused_identities: Vec<_> = + current_identities.iter().cloned().collect(); + unused_identities.remove(random_index_sender); // Remove the sender + let unused_identities_count = unused_identities.len(); - let state_transition = - crate::transitions::create_identity_credit_transfer_transition( + // Select a random identity from the remaining ones for the recipient + let random_index_recipient = + rng.gen_range(0..unused_identities_count); + let recipient = &unused_identities[random_index_recipient]; + + // Use the sender index on the original slice + let sender = &mut current_identities[random_index_sender]; + + let state_transition = create_identity_credit_transfer_transition( sender, recipient, identity_nonce_counter, signer, 300000, ); - operations.push(state_transition); + operations.push(state_transition); + } } } diff --git a/packages/strategy-tests/src/operations.rs b/packages/strategy-tests/src/operations.rs index 675e996843..d35fc9f503 100644 --- a/packages/strategy-tests/src/operations.rs +++ b/packages/strategy-tests/src/operations.rs @@ -497,6 +497,13 @@ impl VoteAction { pub type AmountRange = RangeInclusive; +#[derive(Clone, Debug, PartialEq, Encode, Decode)] +pub struct IdentityTransferInfo { + pub from: Identifier, + pub to: Identifier, + pub amount: Credits, +} + #[derive(Clone, Debug, PartialEq)] pub enum OperationType { Document(DocumentOp), @@ -505,7 +512,7 @@ pub enum OperationType { IdentityWithdrawal(AmountRange), ContractCreate(RandomDocumentTypeParameters, DocumentTypeCount), ContractUpdate(DataContractUpdateOp), - IdentityTransfer, + IdentityTransfer(Option), ResourceVote(ResourceVoteOp), } @@ -517,7 +524,7 @@ enum OperationTypeInSerializationFormat { IdentityWithdrawal(AmountRange), ContractCreate(RandomDocumentTypeParameters, DocumentTypeCount), ContractUpdate(Vec), - IdentityTransfer, + IdentityTransfer(Option), ResourceVote(ResourceVoteOpSerializable), } @@ -563,7 +570,9 @@ impl PlatformSerializableWithPlatformVersion for OperationType { contract_op_in_serialization_format, ) } - OperationType::IdentityTransfer => OperationTypeInSerializationFormat::IdentityTransfer, + OperationType::IdentityTransfer(identity_transfer_info) => { + OperationTypeInSerializationFormat::IdentityTransfer(identity_transfer_info) + } OperationType::ResourceVote(resource_vote_op) => { let vote_op_in_serialization_format = resource_vote_op.try_into_platform_versioned(platform_version)?; @@ -626,7 +635,9 @@ impl PlatformDeserializableWithPotentialValidationFromVersionedStructure for Ope )?; OperationType::ContractUpdate(update_op) } - OperationTypeInSerializationFormat::IdentityTransfer => OperationType::IdentityTransfer, + OperationTypeInSerializationFormat::IdentityTransfer(identity_transfer_info) => { + OperationType::IdentityTransfer(identity_transfer_info) + } OperationTypeInSerializationFormat::ResourceVote(resource_vote_op) => { let vote_op = resource_vote_op.try_into_platform_versioned(platform_version)?; OperationType::ResourceVote(vote_op) diff --git a/packages/strategy-tests/src/transitions.rs b/packages/strategy-tests/src/transitions.rs index 85d03eb333..c77b51e290 100644 --- a/packages/strategy-tests/src/transitions.rs +++ b/packages/strategy-tests/src/transitions.rs @@ -802,7 +802,7 @@ pub fn create_identity_withdrawal_transition_with_output_address( /// - If the sender's identity does not have a suitable authentication key available for signing. /// - If there's an error during the signing process. pub fn create_identity_credit_transfer_transition( - identity: &mut Identity, + identity: &Identity, recipient: &Identity, identity_nonce_counter: &mut BTreeMap, signer: &mut SimpleSigner,