diff --git a/pallets/proposals/src/impls/pallet_impls.rs b/pallets/proposals/src/impls/pallet_impls.rs index d368c307..277d8ab3 100644 --- a/pallets/proposals/src/impls/pallet_impls.rs +++ b/pallets/proposals/src/impls/pallet_impls.rs @@ -176,6 +176,11 @@ impl Pallet { Projects::::mutate_exists(project_key, |project| -> DispatchResult { if let Some(p) = project { p.withdrawn_funds = p.withdrawn_funds.saturating_add(withdrawable); + for (_,ms) in &mut p.milestones { + if ms.is_approved { + ms.withdrawn = true; + } + } if p.withdrawn_funds == p.raised_funds { ::DepositHandler::return_deposit(p.deposit_id)?; CompletedProjects::::try_mutate( diff --git a/pallets/proposals/src/lib.rs b/pallets/proposals/src/lib.rs index 922628f7..63c6ea76 100644 --- a/pallets/proposals/src/lib.rs +++ b/pallets/proposals/src/lib.rs @@ -509,6 +509,7 @@ pub mod pallet { milestone_key, percentage_to_unlock: milestone.percentage_to_unlock, is_approved: false, + withdrawn: false, }; milestones .try_insert(milestone_key, milestone) @@ -540,6 +541,7 @@ pub mod pallet { agreement_hash: brief_hash, funding_type, deposit_id, + payment_address: [0; 20], }; Projects::::insert(project_key, project); @@ -582,6 +584,7 @@ pub struct Milestone { pub milestone_key: MilestoneKey, pub percentage_to_unlock: Percent, pub is_approved: bool, + pub withdrawn: bool, } /// The vote struct is used to @@ -617,6 +620,7 @@ pub struct Project { pub cancelled: bool, pub funding_type: FundingType, pub deposit_id: DepositIdOf, + pub payment_address: [u8; 20], } /// The contribution users made to a proposal project. diff --git a/pallets/proposals/src/migration.rs b/pallets/proposals/src/migration.rs index 8d2012af..fb391734 100644 --- a/pallets/proposals/src/migration.rs +++ b/pallets/proposals/src/migration.rs @@ -4,6 +4,7 @@ use frame_support::*; use frame_system::pallet_prelude::BlockNumberFor; pub use pallet::*; +use sp_runtime::traits::AccountIdConversion; pub type TimestampOf = ::Moment; @@ -273,6 +274,8 @@ pub mod v3 { milestone.percentage_to_unlock as u8, ), is_approved: milestone.is_approved, + + withdrawn: milestone.is_approved, }, ); }); @@ -296,6 +299,7 @@ pub mod v3 { funding_type: FundingType::Proposal, // A deposit_id of u32::MAX is ignored. deposit_id: u32::MAX.into(), + payment_address: Default::default(), }; Some(migrated_project) } else { @@ -556,7 +560,7 @@ pub mod v5 { pub mod v6 { use super::*; - + pub type ProjectV6Of = ProjectV6, BalanceOf, BlockNumberFor>; #[storage_alias] pub(super) type MilestoneVotes = StorageDoubleMap< Pallet, @@ -568,11 +572,37 @@ pub mod v6 { OptionQuery, >; + #[derive(Encode, Clone, Decode, Debug)] + pub struct MilestoneV6 { + pub project_key: u32, + pub milestone_key: u32, + pub percentage_to_unlock: Percent, + pub is_approved: bool, + } + + #[derive(Encode, Decode, Clone)] + pub struct ProjectV6 { + pub agreement_hash: H256, + pub milestones: BTreeMap, + pub contributions: BTreeMap>, + pub currency_id: common_types::CurrencyId, + pub withdrawn_funds: Balance, + pub required_funds: Balance, + pub raised_funds: Balance, + pub initiator: AccountId, + pub created_on: BlockNumber, + pub cancelled: bool, + pub funding_type: FundingType, + } + + #[storage_alias] + pub type Projects = StorageMap, Identity, ProjectKey, ProjectV6Of, OptionQuery>; + // Since we are keeping the depricated vote of no confidence for the meantime // only migrate the voting rounds awaiting the migration to remove no confidence rounds. // User votes is now handled by IndividualVoteStore:: fn migrate_user_has_voted(weight: &mut Weight) { - Projects::::iter().for_each(|(project_key, project)| { + v6::Projects::::iter().for_each(|(project_key, project)| { *weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); project.milestones.keys().for_each(|milestone_key| { *weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); @@ -676,10 +706,58 @@ pub mod v6 { Ok(()) } } + + +} + +pub mod v7{ + use super::*; + + pub fn migrate_milestones_and_payment_address() -> Weight + { + let mut weight = T::DbWeight::get().reads_writes(1, 1); + let mut migrated_milestones: BoundedBTreeMilestones = BoundedBTreeMilestones::new(); + Projects::::translate(|_project_key, project: v6::ProjectV6Of| { + let _ = project + .milestones + .into_values() + .map(|milestone| { + let migrated_milestone = Milestone { + project_key: milestone.project_key, + milestone_key: milestone.milestone_key, + percentage_to_unlock: milestone.percentage_to_unlock, + is_approved: milestone.is_approved, + withdrawn: true, + }; + migrated_milestones.insert(milestone.milestone_key, migrated_milestone) + }) + .collect::>(); + + weight += T::DbWeight::get().reads_writes(1, 1); + let migrated_project: Project = Project { + milestones: migrated_milestones.clone(), + contributions: project.contributions, + currency_id: project.currency_id, + withdrawn_funds: project.withdrawn_funds, + initiator: project.initiator, + created_on: project.created_on, + agreement_hash: Default::default(), + cancelled: project.cancelled, + raised_funds: project.raised_funds, + funding_type: FundingType::Proposal, + deposit_id: u32::MAX.into(), + payment_address: Default::default(), + }; + Some(migrated_project) + }); + weight + } + } #[cfg(test)] mod test { + use std::io::Read; use super::*; use mock::*; use test_utils::*; diff --git a/pallets/proposals/src/test_utils.rs b/pallets/proposals/src/test_utils.rs index 2d9da68b..167ae27d 100644 --- a/pallets/proposals/src/test_utils.rs +++ b/pallets/proposals/src/test_utils.rs @@ -87,6 +87,7 @@ pub fn create_project( milestone_key, percentage_to_unlock: ms.percentage_to_unlock, is_approved: false, + withdrawn: false, }; milestones.insert(milestone_key, milestone); let _ = bounded_milestone_keys.try_push(milestone_key); @@ -108,6 +109,7 @@ pub fn create_project( agreement_hash, funding_type: FundingType::Brief, deposit_id, + payment_address: [0;20], }; crate::Projects::::insert(project_key, project); diff --git a/pallets/proposals/src/tests/pallet.rs b/pallets/proposals/src/tests/pallet.rs index 1be8674f..eae47a70 100644 --- a/pallets/proposals/src/tests/pallet.rs +++ b/pallets/proposals/src/tests/pallet.rs @@ -621,6 +621,9 @@ fn withdraw_only_transfers_approved_milestones() { RuntimeOrigin::signed(ALICE), project_key )); + //validating the withdrawn flag set to true once the fund for the milestone is being withdrawn + assert_eq!(Projects::::get(project_key).unwrap().milestones.get(&milestone_key).unwrap().withdrawn,true); + let alice_after = ::MultiCurrency::free_balance(CurrencyId::Native, &ALICE); let expected_fee = ::ImbueFee::get().mul_floor(per_contribution * 2 / 10); // total_contribution / number of milestones - fee