From 24177fac262fd403cc198f107ac21ffb67b5d85e Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Mon, 4 Nov 2024 18:12:14 +0700 Subject: [PATCH 1/7] feat: hardcoded identity transfers in strategy tests --- .../tests/strategy_tests/main.rs | 7 +- .../tests/strategy_tests/strategy.rs | 14 ++- .../tests/strategy_tests/voting_tests.rs | 90 +++++++++++-------- packages/strategy-tests/src/lib.rs | 71 ++++++++++----- packages/strategy-tests/src/operations.rs | 19 +++- packages/strategy-tests/src/transitions.rs | 2 +- 6 files changed, 137 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 2312241cc64..f2122d627ef 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, - ); + ) + .iter() + .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .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 667b8468688..4d1a7ccb624 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; @@ -405,7 +405,15 @@ impl NetworkStrategy { state_transitions.append(&mut new_transitions); } 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 +1204,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 e14f8d7b1b0..2264a4cd5fb 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, + ) + .iter() + .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .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, + ) + .iter() + .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .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, + ) + .iter() + .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .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, + ) + .iter() + .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .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, + ) + .iter() + .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .collect(); let dpns_contract = platform .drive diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index 61395d99f2a..65e8a51f851 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,66 @@ 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; - } + if let Some(transfer_info) = identity_transfer_info { + let sender = self + .start_identities + .hard_coded + .iter() + .find(|(identity, _)| identity.id() == transfer_info.from) + .expect( + "Expected to find sender identity in hardcoded start identities", + ); + let recipient = self + .start_identities + .hard_coded + .iter() + .find(|(identity, _)| identity.id() == transfer_info.to) + .expect( + "Expected to find recipient identity in hardcoded start identities", + ); + + let state_transition = create_identity_credit_transfer_transition( + &sender.0, + &recipient.0, + identity_nonce_counter, + signer, // Does this mean the loaded identity must be the sender since we're signing with it? + transfer_info.amount, + ); + operations.push(state_transition); + } else if current_identities.len() > 1 { + let identities_count = current_identities.len(); + if identities_count == 0 { + break; + } - // Select a random identity from the current_identities for the sender - let random_index_sender = rng.gen_range(0..identities_count); + // Select a random identity from the current_identities for the sender + let random_index_sender = rng.gen_range(0..identities_count); - // 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(); + // 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(); - // 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 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]; + // Use the sender index on the original slice + let sender = &mut current_identities[random_index_sender]; - let state_transition = - crate::transitions::create_identity_credit_transfer_transition( + 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 675e9968433..d35fc9f5036 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 85d03eb333d..c77b51e2903 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, From 99fe5fa402ddcae329795bb29eaf73fd5044b4f2 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Mon, 4 Nov 2024 23:16:36 +0700 Subject: [PATCH 2/7] add comment --- packages/strategy-tests/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index 65e8a51f851..c2d81ea9905 100644 --- a/packages/strategy-tests/src/lib.rs +++ b/packages/strategy-tests/src/lib.rs @@ -1312,7 +1312,7 @@ impl Strategy { &sender.0, &recipient.0, identity_nonce_counter, - signer, // Does this mean the loaded identity must be the sender since we're signing with it? + signer, // This means the TUI loaded identity must always be the sender since we're always signing with it for now transfer_info.amount, ); operations.push(state_transition); From 0d3e091a5591fde03dbfd8e501864b5ffa2e3602 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 5 Nov 2024 13:07:49 +0700 Subject: [PATCH 3/7] comment --- packages/rs-drive-abci/tests/strategy_tests/strategy.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index 4d1a7ccb624..bf3235ea788 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -404,6 +404,8 @@ 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.iter().filter_map( From e4215145ad7889300810472c5a91f15ae987c1eb Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 5 Nov 2024 13:16:38 +0700 Subject: [PATCH 4/7] use into_iter instead of iter --- .../tests/strategy_tests/main.rs | 4 ++-- .../tests/strategy_tests/voting_tests.rs | 20 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index f2122d627ef..03bb92bc1ad 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -2603,8 +2603,8 @@ mod tests { &mut rng, platform_version, ) - .iter() - .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) .collect(); let strategy = NetworkStrategy { 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 2264a4cd5fb..83834520c0c 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs @@ -87,8 +87,8 @@ mod tests { &mut rng, platform_version, ) - .iter() - .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) .collect(); let dpns_contract = platform @@ -375,8 +375,8 @@ mod tests { &mut rng, platform_version, ) - .iter() - .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) .collect(); let dpns_contract = platform @@ -651,8 +651,8 @@ mod tests { &mut rng, platform_version, ) - .iter() - .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) .collect(); let dpns_contract = platform @@ -1008,8 +1008,8 @@ mod tests { &mut rng, platform_version, ) - .iter() - .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) .collect(); let dpns_contract = platform @@ -1377,8 +1377,8 @@ mod tests { &mut rng, platform_version, ) - .iter() - .map(|(identity, transition)| (identity.clone(), Some(transition.clone()))) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) .collect(); let dpns_contract = platform From 3d941ec5ab7f947e53d41c68eb5758ff2e0bd074 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 5 Nov 2024 13:31:07 +0700 Subject: [PATCH 5/7] use current identities instead of hardcoded start identities --- packages/strategy-tests/src/lib.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index c2d81ea9905..efdb702a482 100644 --- a/packages/strategy-tests/src/lib.rs +++ b/packages/strategy-tests/src/lib.rs @@ -1290,33 +1290,32 @@ impl Strategy { // Generate state transition for identity transfer operation OperationType::IdentityTransfer(identity_transfer_info) => { for _ in 0..count { + // Handle the case where specific sender, recipient, and amount are provided if let Some(transfer_info) = identity_transfer_info { - let sender = self - .start_identities - .hard_coded + let sender = current_identities .iter() - .find(|(identity, _)| identity.id() == transfer_info.from) + .find(|identity| identity.id() == transfer_info.from) .expect( "Expected to find sender identity in hardcoded start identities", ); - let recipient = self - .start_identities - .hard_coded + let recipient = current_identities .iter() - .find(|(identity, _)| identity.id() == transfer_info.to) + .find(|identity| identity.id() == transfer_info.to) .expect( "Expected to find recipient identity in hardcoded start identities", ); let state_transition = create_identity_credit_transfer_transition( - &sender.0, - &recipient.0, + &sender, + &recipient, identity_nonce_counter, - signer, // This means the TUI loaded identity must always be the sender since we're always signing with it for now + 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 + let identities_count = current_identities.len(); if identities_count == 0 { break; From 4bc0a653de328adacae4e8e85ab6971c42984786 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 5 Nov 2024 16:19:48 +0700 Subject: [PATCH 6/7] let transfer keys be any security level or key type --- packages/strategy-tests/src/transitions.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/strategy-tests/src/transitions.rs b/packages/strategy-tests/src/transitions.rs index c77b51e2903..a9cb113d83c 100644 --- a/packages/strategy-tests/src/transitions.rs +++ b/packages/strategy-tests/src/transitions.rs @@ -824,8 +824,8 @@ pub fn create_identity_credit_transfer_transition( let identity_public_key = identity .get_first_public_key_matching( Purpose::TRANSFER, - HashSet::from([SecurityLevel::CRITICAL]), - HashSet::from([KeyType::ECDSA_SECP256K1, KeyType::BLS12_381]), + SecurityLevel::full_range().into(), + KeyType::all_key_types().into(), false, ) .expect("expected to get a signing key"); From dc4882725f6ed6f7a6e4bc8835d84d95bd4ec41f Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 5 Nov 2024 17:44:37 +0700 Subject: [PATCH 7/7] fix --- packages/strategy-tests/src/transitions.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/strategy-tests/src/transitions.rs b/packages/strategy-tests/src/transitions.rs index a9cb113d83c..c77b51e2903 100644 --- a/packages/strategy-tests/src/transitions.rs +++ b/packages/strategy-tests/src/transitions.rs @@ -824,8 +824,8 @@ pub fn create_identity_credit_transfer_transition( let identity_public_key = identity .get_first_public_key_matching( Purpose::TRANSFER, - SecurityLevel::full_range().into(), - KeyType::all_key_types().into(), + HashSet::from([SecurityLevel::CRITICAL]), + HashSet::from([KeyType::ECDSA_SECP256K1, KeyType::BLS12_381]), false, ) .expect("expected to get a signing key");