Skip to content

Commit

Permalink
schedule merge runtime api
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed Sep 3, 2024
1 parent bedd4b9 commit 8b89be8
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 3 deletions.
3 changes: 2 additions & 1 deletion pallets/funding/src/instantiator/chain_interactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,8 @@ impl<
ProjectStatus::CommunityRound(..) =>
for cont in contributions {
let did = generate_did_from_account(cont.contributor.clone());
let investor_type = InvestorType::Retail;
// We use institutional to be able to test most multipliers.
let investor_type = InvestorType::Institutional;
let params = DoContributeParams::<T> {
contributor: cont.contributor,
project_id,
Expand Down
3 changes: 2 additions & 1 deletion pallets/funding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ pub type ContributionInfoOf<T> =
pub type BucketOf<T> = Bucket<PriceOf<T>>;
pub type WeightInfoOf<T> = <T as Config>::WeightInfo;
pub type VestingOf<T> = pallet_linear_release::Pallet<T>;
pub type BlockNumberToBalanceOf<T> = <T as pallet_linear_release::Config>::BlockNumberToBalance;

pub const PLMC_FOREIGN_ID: u32 = 3344;
pub const PLMC_DECIMALS: u8 = 10;
Expand Down Expand Up @@ -329,7 +330,7 @@ pub mod pallet {
+ Member;

/// The hold reason enum constructed by the construct_runtime macro
type RuntimeHoldReason: From<HoldReason>;
type RuntimeHoldReason: From<HoldReason> + Parameter + MaxEncodedLen + Copy;

/// The origin enum constructed by the construct_runtime macro
type RuntimeOrigin: IsType<<Self as frame_system::Config>::RuntimeOrigin>
Expand Down
5 changes: 5 additions & 0 deletions pallets/funding/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,5 +552,10 @@ sp_api::mock_impl_runtime_apis! {
fn funding_asset_to_ct_amount(project_id: ProjectId, asset: AcceptedFundingAsset, asset_amount: Balance) -> Balance {
PolimecFunding::funding_asset_to_ct_amount(project_id, asset, asset_amount)
}
fn get_next_vesting_schedule_merge_candidates(account: AccountId, hold_reason: RuntimeHoldReason, end_max_delta: Balance) -> Option<(u32, u32)> {
PolimecFunding::get_next_vesting_schedule_merge_candidates(account, hold_reason, end_max_delta)
}


}
}
36 changes: 35 additions & 1 deletion pallets/funding/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,15 @@ sp_api::decl_runtime_apis! {
fn projects_by_did(did: Did) -> Vec<ProjectId>;
}

#[api_version(1)]
#[api_version(2)]
pub trait ExtrinsicHelpers<T: Config> {
/// Get the current price of a contribution token (either current bucket in the auction, or WAP in contribution phase),
/// and calculate the amount of tokens that can be bought with the given amount USDT/USDC/DOT.
fn funding_asset_to_ct_amount(project_id: ProjectId, asset: AcceptedFundingAsset, asset_amount: Balance) -> Balance;

/// Get the indexes of vesting schedules that are good candidates to be merged.
/// Schedules that have not yet started are de-facto bad candidates.
fn get_next_vesting_schedule_merge_candidates(account_id: AccountIdOf<T>, hold_reason: <T as Config>::RuntimeHoldReason, end_max_delta: Balance) -> Option<(u32, u32)>;
}
}

Expand Down Expand Up @@ -169,6 +173,36 @@ impl<T: Config> Pallet<T> {
ct_amount
}

pub fn get_next_vesting_schedule_merge_candidates(
account_id: AccountIdOf<T>,
hold_reason: <T as Config>::RuntimeHoldReason,
end_max_delta: Balance,
) -> Option<(u32, u32)> {
let schedules = pallet_linear_release::Vesting::<T>::get(account_id, hold_reason)
.expect("No vesting schedules found")
.to_vec();

let mut inspected_schedules: Vec<(usize, &pallet_linear_release::VestingInfoOf<T>)> = Vec::new();
let now = <frame_system::Pallet<T>>::block_number();
for (i, schedule) in schedules.iter().enumerate() {
if schedule.starting_block > now {
continue;
}

let schedule_end = schedule.ending_block_as_balance::<BlockNumberToBalanceOf<T>>();

for (j, other_schedule) in inspected_schedules.iter() {
let other_end = other_schedule.ending_block_as_balance::<BlockNumberToBalanceOf<T>>();
let end_delta = schedule_end.abs_diff(other_end);
if end_delta <= end_max_delta {
return Some((i as u32, *j as u32));
}
}
inspected_schedules.push((i, schedule));
}
None
}

pub fn all_project_participations_by_did(project_id: ProjectId, did: Did) -> Vec<ProjectParticipationIds<T>> {
let evaluations = Evaluations::<T>::iter_prefix((project_id,))
.filter(|((_account_id, _evaluation_id), evaluation)| evaluation.did == did)
Expand Down
59 changes: 59 additions & 0 deletions pallets/funding/src/tests/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,65 @@ fn funding_asset_to_ct_amount() {
});
}

#[test]
fn get_next_vesting_schedule_merge_candidates() {
let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext())));
let evaluations = vec![
UserToUSDBalance::new(EVALUATOR_1, 500_000 * USD_UNIT),
UserToUSDBalance::new(EVALUATOR_2, 250_000 * USD_UNIT),
UserToUSDBalance::new(BIDDER_1, 320_000 * USD_UNIT),
];
let bids = vec![
BidParams::new(BIDDER_1, 50_000 * CT_UNIT, 10u8, AcceptedFundingAsset::USDT),
BidParams::new(BIDDER_1, 400_000 * CT_UNIT, 5u8, AcceptedFundingAsset::USDT),
BidParams::new(BIDDER_2, 50_000 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT),
];
let remaining_contributions = vec![
ContributionParams::new(BIDDER_1, 15_000 * CT_UNIT, 10u8, AcceptedFundingAsset::USDT),
ContributionParams::new(BIDDER_1, 1_000 * CT_UNIT, 5u8, AcceptedFundingAsset::USDT),

];

let _project_id_1 = inst.create_settled_project(
default_project_metadata(ISSUER_1),
ISSUER_1,
None,
evaluations.clone(),
bids.clone(),
default_community_contributions(),
remaining_contributions.clone(),
true,
);
inst.advance_time(1000);
let _project_id_2 = inst.create_settled_project(
default_project_metadata(ISSUER_2),
ISSUER_2,
None,
evaluations,
bids,
default_community_contributions(),
remaining_contributions,
true,
);
let hold_reason: mock::RuntimeHoldReason = HoldReason::Participation.into();
let bidder_1_schedules = inst.execute(|| pallet_linear_release::Vesting::<TestRuntime>::get(BIDDER_1, hold_reason).unwrap().to_vec());
// Evaluations didn't get a vesting schedule
assert_eq!(bidder_1_schedules.len(), 4);

// inst.execute(|| {
// let block_hash = System::block_hash(System::block_number());
// let (idx_1, idx_2) = TestRuntime::get_next_vesting_schedule_merge_candidates(
// &TestRuntime,
// block_hash,
// BIDDER_1,
// HoldReason::Participation.into(),
// // within 1000 blocks
// 1000u128
// )
// .unwrap();
// });
}

#[test]
fn all_project_participations_by_did() {
let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext())));
Expand Down
3 changes: 3 additions & 0 deletions runtimes/polimec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,9 @@ impl_runtime_apis! {
fn funding_asset_to_ct_amount(project_id: ProjectId, asset: AcceptedFundingAsset, asset_amount: Balance) -> Balance {
Funding::funding_asset_to_ct_amount(project_id, asset, asset_amount)
}
fn get_next_vesting_schedule_merge_candidates(account: AccountId, hold_reason: RuntimeHoldReason, end_max_delta: Balance) -> Option<(u32, u32)> {
Funding::get_next_vesting_schedule_merge_candidates(account, hold_reason, end_max_delta)
}
}

#[cfg(feature = "try-runtime")]
Expand Down

0 comments on commit 8b89be8

Please sign in to comment.