Skip to content

Commit

Permalink
Merge pull request #2160 from shamil-gadelshin/withdraw_funds_from_bo…
Browse files Browse the repository at this point in the history
…unty

Withdraw funds from bounty.
  • Loading branch information
bedeho authored Feb 17, 2021
2 parents d18cc3a + 121d870 commit 83cbaec
Show file tree
Hide file tree
Showing 7 changed files with 1,829 additions and 129 deletions.
202 changes: 184 additions & 18 deletions runtime-modules/bounty/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,39 @@
use frame_benchmarking::{account, benchmarks};
use frame_support::sp_runtime::traits::Bounded;
use frame_support::storage::StorageMap;
use frame_support::traits::Currency;
use frame_system::Module as System;
use frame_support::traits::{Currency, OnFinalize, OnInitialize};
use frame_system::{EventRecord, RawOrigin};
use sp_arithmetic::traits::One;
use sp_runtime::traits::SaturatedConversion;
use sp_std::boxed::Box;
use sp_std::vec;
use sp_std::vec::Vec;

use crate::Module as Bounty;
use balances::Module as Balances;
use common::council::CouncilBudgetManager;
use frame_system::Module as System;
use membership::Module as Membership;

use crate::{
BalanceOf, Bounties, BountyCreationParameters, BountyCreator, BountyMilestone, Call, Event,
Module, Trait,
BalanceOf, Bounties, BountyCreationParameters, BountyCreator, BountyMilestone, BountyStage,
Call, Event, Module, Trait,
};

pub fn run_to_block<T: Trait>(target_block: T::BlockNumber) {
let mut current_block = System::<T>::block_number();
while current_block < target_block {
System::<T>::on_finalize(current_block);
Bounty::<T>::on_finalize(current_block);

current_block += One::one();
System::<T>::set_block_number(current_block);

System::<T>::on_initialize(current_block);
Bounty::<T>::on_initialize(current_block);
}
}

fn assert_last_event<T: Trait>(generic_event: <T as Trait>::Event) {
let events = System::<T>::events();
let system_event: <T as frame_system::Trait>::Event = generic_event.into();
Expand Down Expand Up @@ -102,7 +117,7 @@ benchmarks! {
let bounty_id: T::BountyId = 1u32.into();

assert!(Bounties::<T>::contains_key(bounty_id));
assert_eq!(Module::<T>::bounty_count(), 1); // Bounty counter was updated.
assert_eq!(Bounty::<T>::bounty_count(), 1); // Bounty counter was updated.
assert_last_event::<T>(Event::<T>::BountyCreated(bounty_id, params).into());
}

Expand All @@ -128,12 +143,13 @@ benchmarks! {
let bounty_id: T::BountyId = 1u32.into();

assert!(Bounties::<T>::contains_key(bounty_id));
assert_eq!(Module::<T>::bounty_count(), 1); // Bounty counter was updated.
assert_eq!(Bounty::<T>::bounty_count(), 1); // Bounty counter was updated.
assert_last_event::<T>(Event::<T>::BountyCreated(bounty_id, params).into());
}

cancel_bounty_by_council {
let cherry: BalanceOf<T> = 100.into();
let max_amount: BalanceOf<T> = 1000.into();

T::CouncilBudgetManager::set_budget(cherry);

Expand All @@ -143,24 +159,26 @@ benchmarks! {
judging_period: One::one(),
cherry,
creator: creator.clone(),
max_amount,
..Default::default()
};

Module::<T>::create_bounty(RawOrigin::Root.into(), params, Vec::new()).unwrap();
Bounty::<T>::create_bounty(RawOrigin::Root.into(), params, Vec::new()).unwrap();

let bounty_id: T::BountyId = Module::<T>::bounty_count().into();
let bounty_id: T::BountyId = Bounty::<T>::bounty_count().into();

assert!(Bounties::<T>::contains_key(bounty_id));
}: cancel_bounty(RawOrigin::Root, creator.clone(), bounty_id)
verify {
let bounty = <crate::Bounties<T>>::get(bounty_id);
let bounty = Bounty::<T>::bounties(bounty_id);

assert!(matches!(bounty.milestone, BountyMilestone::Canceled));
assert_last_event::<T>(Event::<T>::BountyCanceled(bounty_id, creator).into());
}

cancel_bounty_by_member {
let cherry: BalanceOf<T> = 100.into();
let max_amount: BalanceOf<T> = 1000.into();
let (account_id, member_id) = member_funded_account::<T>("member1", 0);

T::CouncilBudgetManager::set_budget(cherry);
Expand All @@ -172,66 +190,193 @@ benchmarks! {
judging_period: One::one(),
cherry,
creator: creator.clone(),
max_amount,
..Default::default()
};

Module::<T>::create_bounty(
Bounty::<T>::create_bounty(
RawOrigin::Signed(account_id.clone()).into(),
params,
Vec::new()
).unwrap();

let bounty_id: T::BountyId = Module::<T>::bounty_count().into();
let bounty_id: T::BountyId = Bounty::<T>::bounty_count().into();

assert!(Bounties::<T>::contains_key(bounty_id));
}: cancel_bounty(RawOrigin::Signed(account_id), creator.clone(), bounty_id)
verify {
let bounty = <crate::Bounties<T>>::get(bounty_id);
let bounty = Bounty::<T>::bounties(bounty_id);

assert!(matches!(bounty.milestone, BountyMilestone::Canceled));
assert_last_event::<T>(Event::<T>::BountyCanceled(bounty_id, creator).into());
}

veto_bounty {
let max_amount: BalanceOf<T> = 1000.into();

let params = BountyCreationParameters::<T>{
work_period: One::one(),
judging_period: One::one(),
max_amount,
..Default::default()
};

Module::<T>::create_bounty(RawOrigin::Root.into(), params, Vec::new()).unwrap();
Bounty::<T>::create_bounty(RawOrigin::Root.into(), params, Vec::new()).unwrap();

let bounty_id: T::BountyId = Module::<T>::bounty_count().into();
let bounty_id: T::BountyId = Bounty::<T>::bounty_count().into();

assert!(Bounties::<T>::contains_key(bounty_id));
}: _ (RawOrigin::Root, bounty_id)
verify {
let bounty = <crate::Bounties<T>>::get(bounty_id);
let bounty = Bounty::<T>::bounties(bounty_id);

assert!(matches!(bounty.milestone, BountyMilestone::Canceled));
assert_last_event::<T>(Event::<T>::BountyVetoed(bounty_id).into());
}

fund_bounty {
let max_amount: BalanceOf<T> = 100.into();

let params = BountyCreationParameters::<T>{
work_period: One::one(),
judging_period: One::one(),
max_amount,
..Default::default()
};
// should reach default max bounty funding amount
let amount: BalanceOf<T> = 100.into();

let (account_id, member_id) = member_funded_account::<T>("member1", 0);

Module::<T>::create_bounty(RawOrigin::Root.into(), params, Vec::new()).unwrap();
Bounty::<T>::create_bounty(RawOrigin::Root.into(), params, Vec::new()).unwrap();

let bounty_id: T::BountyId = Module::<T>::bounty_count().into();
let bounty_id: T::BountyId = Bounty::<T>::bounty_count().into();

assert!(Bounties::<T>::contains_key(bounty_id));
}: _ (RawOrigin::Signed(account_id.clone()), member_id, bounty_id, amount)
verify {
assert_eq!(Balances::<T>::usable_balance(&account_id), T::Balance::max_value() - amount);
assert_last_event::<T>(Event::<T>::MaxFundingReached(bounty_id).into());
assert_last_event::<T>(Event::<T>::BountyMaxFundingReached(bounty_id).into());
}

withdraw_member_funding {
let funding_period = 1;
let bounty_amount = 200;

let params = BountyCreationParameters::<T>{
funding_period: Some(funding_period.into()),
work_period: One::one(),
judging_period: One::one(),
max_amount: bounty_amount.into(),
min_amount: bounty_amount.into(),
..Default::default()
};
// should reach default max bounty funding amount
let amount: BalanceOf<T> = 100.into();

let (account_id, member_id) = member_funded_account::<T>("member1", 0);

Bounty::<T>::create_bounty(RawOrigin::Root.into(), params, Vec::new()).unwrap();

let bounty_id: T::BountyId = Bounty::<T>::bounty_count().into();

assert!(Bounties::<T>::contains_key(bounty_id));

Bounty::<T>::fund_bounty(
RawOrigin::Signed(account_id.clone()).into(),
member_id,
bounty_id,
amount
).unwrap();

run_to_block::<T>((funding_period + 1).into());

}: _ (RawOrigin::Signed(account_id.clone()), member_id, bounty_id)
verify {
assert_eq!(Balances::<T>::usable_balance(&account_id), T::Balance::max_value());
assert_last_event::<T>(Event::<T>::BountyRemoved(bounty_id).into());
}

withdraw_creator_funding_by_council {
let max_amount: BalanceOf<T> = 1000.into();
let cherry: BalanceOf<T> = 100.into();

T::CouncilBudgetManager::set_budget(cherry);

let creator = BountyCreator::Council;
let params = BountyCreationParameters::<T>{
work_period: One::one(),
judging_period: One::one(),
cherry,
max_amount,
creator: creator.clone(),
..Default::default()
};

Bounty::<T>::create_bounty(RawOrigin::Root.into(), params, Vec::new()).unwrap();

let bounty_id: T::BountyId = Bounty::<T>::bounty_count().into();

assert!(Bounties::<T>::contains_key(bounty_id));

Bounty::<T>::cancel_bounty(RawOrigin::Root.into(), creator.clone(), bounty_id).unwrap();

let bounty = Bounty::<T>::bounties(bounty_id);
assert!(matches!(
Bounty::<T>::get_bounty_stage(&bounty),
BountyStage::Withdrawal {cherry_needs_withdrawal: true, ..}
));

}: withdraw_creator_funding(RawOrigin::Root, creator.clone(), bounty_id)
verify {
assert!(!Bounties::<T>::contains_key(bounty_id));
assert_last_event::<T>(Event::<T>::BountyRemoved(bounty_id).into());
}

withdraw_creator_funding_by_member {
let max_amount: BalanceOf<T> = 1000.into();
let cherry: BalanceOf<T> = 100.into();
let (account_id, member_id) = member_funded_account::<T>("member1", 0);

T::CouncilBudgetManager::set_budget(cherry);

let creator = BountyCreator::Member(member_id);

let params = BountyCreationParameters::<T>{
work_period: One::one(),
judging_period: One::one(),
cherry,
creator: creator.clone(),
max_amount,
..Default::default()
};

Bounty::<T>::create_bounty(
RawOrigin::Signed(account_id.clone()).into(),
params,
Vec::new()
).unwrap();

let bounty_id: T::BountyId = Bounty::<T>::bounty_count().into();

assert!(Bounties::<T>::contains_key(bounty_id));

Bounty::<T>::cancel_bounty(
RawOrigin::Signed(account_id.clone()).into(),
creator.clone(),
bounty_id
).unwrap();

let bounty = Bounty::<T>::bounties(bounty_id);
assert!(matches!(
Bounty::<T>::get_bounty_stage(&bounty),
BountyStage::Withdrawal {cherry_needs_withdrawal: true, ..}
));

}: withdraw_creator_funding(RawOrigin::Signed(account_id), creator.clone(), bounty_id)
verify {
assert!(!Bounties::<T>::contains_key(bounty_id));
assert_last_event::<T>(Event::<T>::BountyRemoved(bounty_id).into());
}
}

Expand Down Expand Up @@ -282,4 +427,25 @@ mod tests {
assert_ok!(test_benchmark_fund_bounty::<Test>());
});
}

#[test]
fn withdraw_member_funding() {
build_test_externalities().execute_with(|| {
assert_ok!(test_benchmark_withdraw_member_funding::<Test>());
});
}

#[test]
fn withdraw_creator_funding_by_council() {
build_test_externalities().execute_with(|| {
assert_ok!(test_benchmark_withdraw_creator_funding_by_council::<Test>());
});
}

#[test]
fn withdraw_creator_funding_by_member() {
build_test_externalities().execute_with(|| {
assert_ok!(test_benchmark_withdraw_creator_funding_by_member::<Test>());
});
}
}
Loading

0 comments on commit 83cbaec

Please sign in to comment.