From e59bb71e192ecfd555a278e2938770c7d9a521d0 Mon Sep 17 00:00:00 2001 From: mvmt-ninja Date: Thu, 14 Dec 2023 17:14:37 +0100 Subject: [PATCH 1/3] feat: resolve issue91 to add get_max_paralletl_group --- .../types/sui-helper-types/src/block/block.rs | 65 ++++++++++++++++++- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/movement-sdk/types/sui-helper-types/src/block/block.rs b/movement-sdk/types/sui-helper-types/src/block/block.rs index 3a9c74a0..78abfd58 100644 --- a/movement-sdk/types/sui-helper-types/src/block/block.rs +++ b/movement-sdk/types/sui-helper-types/src/block/block.rs @@ -1,8 +1,13 @@ +use sui_types::base_types::ObjectID; +use sui_types::digests::SenderSignedDataDigest; +use sui_types::message_envelope::VerifiedEnvelope; use sui_types::{ transaction::SenderSignedData, executable_transaction::VerifiedExecutableTransaction }; +use sui_types::transaction::{TransactionDataAPI, TransactionData}; + /// A SuiBlock is a block as we would most often expect it to be constructed. /// It contains only user signed data. #[derive(Debug, Clone)] @@ -32,8 +37,62 @@ impl VerifiedExecutableBlock { } pub fn get_max_parallel_groups(&self) -> VerifiedExecutableExecutionGroups { - // todo: see readme - unimplemented!(); + let mut groups: Vec> = vec![]; + let mut group_id = 0; + let mut processed_cnt = 0; + // (objectId, is_mutable) + let mut objects_in_groups: Vec> = vec![]; + let mut processed_digests: Vec = vec![]; + + let tx_cnt = self.clone().into_iter().len(); + loop { + for executable_transaction in self.clone().into_iter() { + let sender_signed_data = executable_transaction.clone().into_message(); + + // check if transaction is already pushed in groups + if let Some(_found) = processed_digests.iter().find(|&&tx_digest| tx_digest == sender_signed_data.full_message_digest()) { + break; + } + + let transaction_data = sender_signed_data.transaction_data(); + let TransactionData::V1(tx_data_v1) = transaction_data; + let shared_objects = tx_data_v1.shared_input_objects(); + + // check out if any shared objects are conflicted in the group + let mut mut_obj_duplicated = false; + for obj in shared_objects.iter() { + if let Some (_found) = objects_in_groups[group_id].iter().find(|&obj_in_group| obj_in_group.0 == obj.id && obj_in_group.1 && obj.mutable) { + mut_obj_duplicated = true; + break + } + } + + // if no object conflicts, then the transaction can go in the group + if !mut_obj_duplicated { + for obj in shared_objects.iter() { + objects_in_groups[group_id].push((obj.id, obj.mutable)); + } + + // add a tx into group + groups[group_id].push(executable_transaction.clone()); + + // set transaction as processed + processed_digests.push(sender_signed_data.full_message_digest()); + + // increase processed_count + processed_cnt += 1; + } + } + // start new group + group_id += 1; + + // if all transactions are included in groups, then exit from the loop + if processed_cnt == tx_cnt { + break + } + } + + VerifiedExecutableExecutionGroups(groups) } @@ -46,4 +105,4 @@ impl IntoIterator for VerifiedExecutableBlock { fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } -} \ No newline at end of file +} From d30c4623330699f9be35e59cd3ba822de509c208 Mon Sep 17 00:00:00 2001 From: mvmt-ninja Date: Fri, 15 Dec 2023 13:49:54 +0100 Subject: [PATCH 2/3] fix: update the logic of max parallel gropu --- .../types/sui-helper-types/src/block/block.rs | 82 ++++++++----------- 1 file changed, 35 insertions(+), 47 deletions(-) diff --git a/movement-sdk/types/sui-helper-types/src/block/block.rs b/movement-sdk/types/sui-helper-types/src/block/block.rs index 78abfd58..e0bca3b4 100644 --- a/movement-sdk/types/sui-helper-types/src/block/block.rs +++ b/movement-sdk/types/sui-helper-types/src/block/block.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use sui_types::base_types::ObjectID; use sui_types::digests::SenderSignedDataDigest; use sui_types::message_envelope::VerifiedEnvelope; @@ -37,63 +39,49 @@ impl VerifiedExecutableBlock { } pub fn get_max_parallel_groups(&self) -> VerifiedExecutableExecutionGroups { - let mut groups: Vec> = vec![]; - let mut group_id = 0; - let mut processed_cnt = 0; - // (objectId, is_mutable) - let mut objects_in_groups: Vec> = vec![]; - let mut processed_digests: Vec = vec![]; - - let tx_cnt = self.clone().into_iter().len(); - loop { - for executable_transaction in self.clone().into_iter() { - let sender_signed_data = executable_transaction.clone().into_message(); - - // check if transaction is already pushed in groups - if let Some(_found) = processed_digests.iter().find(|&&tx_digest| tx_digest == sender_signed_data.full_message_digest()) { - break; - } - - let transaction_data = sender_signed_data.transaction_data(); - let TransactionData::V1(tx_data_v1) = transaction_data; - let shared_objects = tx_data_v1.shared_input_objects(); - - // check out if any shared objects are conflicted in the group - let mut mut_obj_duplicated = false; - for obj in shared_objects.iter() { - if let Some (_found) = objects_in_groups[group_id].iter().find(|&obj_in_group| obj_in_group.0 == obj.id && obj_in_group.1 && obj.mutable) { - mut_obj_duplicated = true; - break - } - } + let mut groups: Vec> = Vec::new(); + let mut objects_in_groups: Vec> = Vec::new(); + let mut processed_digests: HashSet = HashSet::new(); + for executable_transaction in self.clone().into_iter() { + let sender_signed_data = executable_transaction.clone().into_message(); + + // Skip if transaction is already processed + if processed_digests.contains(&sender_signed_data.full_message_digest()) { + continue; + } - // if no object conflicts, then the transaction can go in the group - if !mut_obj_duplicated { - for obj in shared_objects.iter() { - objects_in_groups[group_id].push((obj.id, obj.mutable)); - } - - // add a tx into group - groups[group_id].push(executable_transaction.clone()); + let TransactionData::V1(tx_data_v1) = sender_signed_data.transaction_data(); + let shared_objects = tx_data_v1.shared_input_objects(); - // set transaction as processed - processed_digests.push(sender_signed_data.full_message_digest()); + // Find a group where the transaction can be added without conflict + let mut group_id = 0; + while group_id < objects_in_groups.len() { + let is_conflict = shared_objects.iter().any(|obj| { + objects_in_groups[group_id].contains(&(obj.id, true)) && obj.mutable + }); - // increase processed_count - processed_cnt += 1; + if !is_conflict { + break; } + group_id += 1; } - // start new group - group_id += 1; - // if all transactions are included in groups, then exit from the loop - if processed_cnt == tx_cnt { - break + // If no suitable group, create a new one + if group_id == objects_in_groups.len() { + groups.push(Vec::new()); + objects_in_groups.push(HashSet::new()); } - } + // Add the transaction to the group + for obj in shared_objects { + objects_in_groups[group_id].insert((obj.id, obj.mutable)); + } + groups[group_id].push(executable_transaction.clone()); + processed_digests.insert(sender_signed_data.full_message_digest()); + } VerifiedExecutableExecutionGroups(groups) } + } From adde5f2f4591343ecc8e84d606ed29fe6e8ef854 Mon Sep 17 00:00:00 2001 From: mvmt-ninja Date: Mon, 18 Dec 2023 13:09:45 +0100 Subject: [PATCH 3/3] update: change shared objects to input objects --- .../types/sui-helper-types/src/block/block.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/movement-sdk/types/sui-helper-types/src/block/block.rs b/movement-sdk/types/sui-helper-types/src/block/block.rs index e0bca3b4..4b9816c0 100644 --- a/movement-sdk/types/sui-helper-types/src/block/block.rs +++ b/movement-sdk/types/sui-helper-types/src/block/block.rs @@ -51,13 +51,19 @@ impl VerifiedExecutableBlock { } let TransactionData::V1(tx_data_v1) = sender_signed_data.transaction_data(); - let shared_objects = tx_data_v1.shared_input_objects(); + //let shared_objects = tx_data_v1.shared_input_objects(); + let input_objects = tx_data_v1.input_objects(); + if input_objects.is_err() { + continue; + } + + let input_objects = input_objects.unwrap(); // Find a group where the transaction can be added without conflict let mut group_id = 0; while group_id < objects_in_groups.len() { - let is_conflict = shared_objects.iter().any(|obj| { - objects_in_groups[group_id].contains(&(obj.id, true)) && obj.mutable + let is_conflict = input_objects.iter().any(|obj| { + objects_in_groups[group_id].contains(&(obj.object_id(), true)) && obj.is_mutable() }); if !is_conflict { @@ -73,8 +79,8 @@ impl VerifiedExecutableBlock { } // Add the transaction to the group - for obj in shared_objects { - objects_in_groups[group_id].insert((obj.id, obj.mutable)); + for obj in input_objects { + objects_in_groups[group_id].insert((obj.object_id(), obj.is_mutable())); } groups[group_id].push(executable_transaction.clone()); processed_digests.insert(sender_signed_data.full_message_digest());