Skip to content

Commit

Permalink
offchain migration confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed Jul 1, 2024
1 parent 091c477 commit d3d71ec
Show file tree
Hide file tree
Showing 19 changed files with 826 additions and 462 deletions.
143 changes: 134 additions & 9 deletions integration-tests/src/tests/ct_migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@

use crate::*;
use frame_support::traits::{fungible::Mutate, fungibles::Inspect};
use pallet_funding::{assert_close_enough, ProjectId};
use polimec_common::migration_types::{MigrationStatus, Migrations};
use polimec_runtime::Funding;
use itertools::Itertools;
use pallet_funding::{assert_close_enough, types::*, ProjectId};
use polimec_common::migration_types::{MigrationStatus, Migrations, ParticipationType};
use polimec_runtime::{Funding, RuntimeOrigin};
use polkadot_service::chain_spec::get_account_id_from_seed;
use sp_runtime::Perquintill;
use std::collections::HashMap;
use tests::defaults::*;

fn alice() -> AccountId {
get_account_id_from_seed::<sr25519::Public>(ALICE)
}

fn mock_hrmp_establishment(project_id: u32) {
let ct_issued = PolimecNet::execute_with(|| {
<PolimecRuntime as pallet_funding::Config>::ContributionTokenCurrency::total_issuance(project_id)
Expand All @@ -34,7 +40,7 @@ fn mock_hrmp_establishment(project_id: u32) {
});

PolimecNet::execute_with(|| {
assert_ok!(Funding::do_set_para_id_for_project(&ISSUER.into(), project_id, ParaId::from(6969u32)));
assert_ok!(Funding::do_start_pallet_migration(&ISSUER.into(), project_id, ParaId::from(6969u32)));

let open_channel_message = xcm::v3::opaque::Instruction::HrmpNewChannelOpenRequest {
sender: 6969,
Expand All @@ -54,7 +60,10 @@ fn mock_hrmp_establishment(project_id: u32) {
fn assert_migration_is_ready(project_id: u32) {
PolimecNet::execute_with(|| {
let project_details = pallet_funding::ProjectsDetails::<PolimecRuntime>::get(project_id).unwrap();
assert!(project_details.migration_readiness_check.unwrap().is_ready())
let Some(MigrationType::Pallet(receiver_pallet_info)) = project_details.migration_type else {
panic!("Migration type is not ParachainReceiverPallet");
};
assert!(receiver_pallet_info.migration_readiness_check.unwrap().is_ready())
});
}

Expand All @@ -66,7 +75,7 @@ fn get_migrations_for_participants(
PolimecNet::execute_with(|| {
for participant in participants {
let (status, migrations) =
pallet_funding::UserMigrations::<PolimecRuntime>::get(project_id, participant.clone()).unwrap();
pallet_funding::UserMigrations::<PolimecRuntime>::get((project_id, participant.clone())).unwrap();
user_migrations.insert(participant, (status, Migrations::from(migrations.into())));
}
});
Expand All @@ -76,7 +85,11 @@ fn get_migrations_for_participants(
fn send_migrations(project_id: ProjectId, accounts: Vec<AccountId>) {
for user in accounts.into_iter() {
PolimecNet::execute_with(|| {
assert_ok!(Funding::migrate_one_participant(PolimecOrigin::signed(user.clone()), project_id, user.clone()));
assert_ok!(Funding::send_pallet_migration_for(
PolimecOrigin::signed(user.clone()),
project_id,
user.clone()
));
});
}
}
Expand Down Expand Up @@ -114,6 +127,10 @@ fn migrations_are_confirmed(project_id: u32, accounts: Vec<AccountId>) {
let (current_status, _) = user_migrations.get(user).unwrap();
assert_eq!(current_status, &MigrationStatus::Confirmed);
}

PolimecFunding::do_mark_project_ct_migration_as_finished(project_id).unwrap();
let project_details = pallet_funding::ProjectsDetails::<PolimecRuntime>::get(project_id).unwrap();
assert_eq!(project_details.status, pallet_funding::ProjectStatus::CTMigrationFinished)
});
}

Expand Down Expand Up @@ -174,15 +191,17 @@ fn create_settled_project() -> (ProjectId, Vec<AccountId>) {
}

#[test]
fn full_migration_test() {
fn full_pallet_migration_test() {
polimec::set_prices();
let (project_id, participants) = create_settled_project();
let project_status =
PolimecNet::execute_with(|| pallet_funding::ProjectsDetails::<PolimecRuntime>::get(project_id).unwrap().status);
dbg!(project_status);

mock_hrmp_establishment(project_id);

assert_migration_is_ready(project_id);

// Migrate is sent
send_migrations(project_id, participants.clone());

migrations_are_executed(project_id, participants.clone());
Expand All @@ -193,3 +212,109 @@ fn full_migration_test() {

migrations_are_vested(project_id, participants.clone());
}

/// Creates a project with all participations settled except for one.
fn create_project_with_unsettled_participation(participation_type: ParticipationType) -> (ProjectId, Vec<AccountId>) {
let mut inst = IntegrationInstantiator::new(None);
PolimecNet::execute_with(|| {
let project_id = inst.create_finished_project(
default_project_metadata(ISSUER.into()),
ISSUER.into(),
default_evaluations(),
default_bids(),
default_community_contributions(),
default_remainder_contributions(),
);

inst.advance_time(<PolimecRuntime as pallet_funding::Config>::SuccessToSettlementTime::get()).unwrap();
let evaluations_to_settle =
pallet_funding::Evaluations::<PolimecRuntime>::iter_prefix_values((project_id,)).collect_vec();
let bids_to_settle = pallet_funding::Bids::<PolimecRuntime>::iter_prefix_values((project_id,)).collect_vec();
let contributions_to_settle =
pallet_funding::Contributions::<PolimecRuntime>::iter_prefix_values((project_id,)).collect_vec();

let mut participants: Vec<AccountId> = evaluations_to_settle
.iter()
.map(|eval| eval.evaluator.clone())
.chain(bids_to_settle.iter().map(|bid| bid.bidder.clone()))
.chain(contributions_to_settle.iter().map(|contribution| contribution.contributor.clone()))
.collect();
participants.sort();
participants.dedup();

let start = if participation_type == ParticipationType::Evaluation { 1 } else { 0 };
for evaluation in evaluations_to_settle[start..].iter() {
PolimecFunding::settle_successful_evaluation(
RuntimeOrigin::signed(alice()),
project_id,
evaluation.evaluator.clone(),
evaluation.id,
)
.unwrap()
}

let start = if participation_type == ParticipationType::Bid { 1 } else { 0 };
for bid in bids_to_settle[start..].iter() {
PolimecFunding::settle_successful_bid(
RuntimeOrigin::signed(alice()),
project_id,
bid.bidder.clone(),
bid.id,
)
.unwrap()
}

let start = if participation_type == ParticipationType::Contribution { 1 } else { 0 };
for contribution in contributions_to_settle[start..].iter() {
PolimecFunding::settle_successful_contribution(
RuntimeOrigin::signed(alice()),
project_id,
contribution.contributor.clone(),
contribution.id,
)
.unwrap()
}

let evaluations =
pallet_funding::Evaluations::<PolimecRuntime>::iter_prefix_values((project_id,)).collect_vec();
let bids = pallet_funding::Bids::<PolimecRuntime>::iter_prefix_values((project_id,)).collect_vec();
let contributions =
pallet_funding::Contributions::<PolimecRuntime>::iter_prefix_values((project_id,)).collect_vec();

if participation_type == ParticipationType::Evaluation {
assert_eq!(evaluations.len(), 1);
assert_eq!(bids.len(), 0);
assert_eq!(contributions.len(), 0);
} else if participation_type == ParticipationType::Bid {
assert_eq!(evaluations.len(), 0);
assert_eq!(bids.len(), 1);
assert_eq!(contributions.len(), 0);
} else {
assert_eq!(evaluations.len(), 0);
assert_eq!(bids.len(), 0);
assert_eq!(contributions.len(), 1);
}

(project_id, participants)
})
}

#[test]
fn cannot_start_pallet_migration_with_unsettled_participations() {
polimec::set_prices();

let tup_1 = create_project_with_unsettled_participation(ParticipationType::Evaluation);
let tup_2 = create_project_with_unsettled_participation(ParticipationType::Bid);
let tup_3 = create_project_with_unsettled_participation(ParticipationType::Contribution);

let tups = vec![tup_1, tup_2, tup_3];

for (project_id, participants) in tups.into_iter() {
PolimecNet::execute_with(|| {
assert_noop!(
PolimecFunding::do_start_pallet_migration(&ISSUER.into(), project_id, ParaId::from(6969u32)),
pallet_funding::Error::<PolimecRuntime>::SettlementNotComplete
);
});
}
}
9 changes: 6 additions & 3 deletions integration-tests/src/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ fn ct_migrated() {
// Mock HRMP establishment
PolimecNet::execute_with(|| {
let _account_id: PolimecAccountId = ISSUER.into();
assert_ok!(PolimecFunding::do_set_para_id_for_project(&ISSUER.into(), project_id, ParaId::from(6969u32),));
assert_ok!(PolimecFunding::do_start_pallet_migration(&ISSUER.into(), project_id, ParaId::from(6969u32),));
let open_channel_message = xcm::v3::opaque::Instruction::HrmpNewChannelOpenRequest {
sender: 6969,
max_message_size: 102_300,
Expand All @@ -505,7 +505,10 @@ fn ct_migrated() {
// Migration is ready
PolimecNet::execute_with(|| {
let project_details = pallet_funding::ProjectsDetails::<PolimecRuntime>::get(project_id).unwrap();
assert!(project_details.migration_readiness_check.unwrap().is_ready())
let Some(MigrationType::Pallet(migration_info)) = project_details.migration_type else {
panic!("Migration type should be ParachainReceiverPallet");
};
assert!(migration_info.migration_readiness_check.unwrap().is_ready())
});

excel_ct_amounts().iter().map(|tup| tup.0.clone()).unique().for_each(|account| {
Expand All @@ -525,7 +528,7 @@ fn ct_migrated() {

for account in accounts {
PolimecNet::execute_with(|| {
assert_ok!(PolimecFunding::migrate_one_participant(
assert_ok!(PolimecFunding::send_pallet_migration_for(
PolimecOrigin::signed(account.clone()),
project_id,
account.clone()
Expand Down
29 changes: 22 additions & 7 deletions pallets/funding/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1535,7 +1535,10 @@ mod benchmarks {
inst.create_finished_project(project_metadata, issuer, evaluations, bids, contributions, vec![]);

inst.advance_time(One::one()).unwrap();
assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::FundingFailed);
assert_eq!(
inst.get_project_details(project_id).status,
ProjectStatus::SettlementStarted(FundingOutcome::FundingFailed)
);

let evaluation_to_settle =
inst.execute(|| Evaluations::<T>::iter_prefix_values((project_id, evaluator.clone())).next().unwrap());
Expand Down Expand Up @@ -1606,7 +1609,10 @@ mod benchmarks {

run_blocks_to_execute_next_transition(project_id, UpdateType::StartSettlement, &mut inst);

assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::FundingSuccessful);
assert_eq!(
inst.get_project_details(project_id).status,
ProjectStatus::SettlementStarted(FundingOutcome::FundingSuccessful)
);

let bid_to_settle =
inst.execute(|| Bids::<T>::iter_prefix_values((project_id, bidder.clone())).next().unwrap());
Expand Down Expand Up @@ -1665,7 +1671,10 @@ mod benchmarks {
inst.create_finished_project(project_metadata, issuer.clone(), evaluations, bids, contributions, vec![]);

inst.advance_time(One::one()).unwrap();
assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::FundingFailed);
assert_eq!(
inst.get_project_details(project_id).status,
ProjectStatus::SettlementStarted(FundingOutcome::FundingFailed)
);

let bid_to_settle =
inst.execute(|| Bids::<T>::iter_prefix_values((project_id, bidder.clone())).next().unwrap());
Expand Down Expand Up @@ -1713,7 +1722,10 @@ mod benchmarks {

run_blocks_to_execute_next_transition(project_id, UpdateType::StartSettlement, &mut inst);

assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::FundingSuccessful);
assert_eq!(
inst.get_project_details(project_id).status,
ProjectStatus::SettlementStarted(FundingOutcome::FundingSuccessful)
);

let contribution_to_settle =
inst.execute(|| Contributions::<T>::iter_prefix_values((project_id, contributor.clone())).next().unwrap());
Expand Down Expand Up @@ -1783,7 +1795,10 @@ mod benchmarks {
inst.create_finished_project(project_metadata, issuer, evaluations, bids, contributions, vec![]);

inst.advance_time(One::one()).unwrap();
assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::FundingFailed);
assert_eq!(
inst.get_project_details(project_id).status,
ProjectStatus::SettlementStarted(FundingOutcome::FundingFailed)
);

let contribution_to_settle =
inst.execute(|| Contributions::<T>::iter_prefix_values((project_id, contributor.clone())).next().unwrap());
Expand Down Expand Up @@ -2618,7 +2633,7 @@ mod benchmarks {

// * validity checks *
let project_details = inst.get_project_details(project_id);
assert_eq!(project_details.status, ProjectStatus::FundingSuccessful);
assert_eq!(project_details.status, ProjectStatus::SettlementStarted(FundingOutcome::FundingSuccessful));
}

#[benchmark]
Expand Down Expand Up @@ -2667,7 +2682,7 @@ mod benchmarks {

// * validity checks *
let project_details = inst.get_project_details(project_id);
assert_eq!(project_details.status, ProjectStatus::FundingFailed);
assert_eq!(project_details.status, ProjectStatus::SettlementStarted(FundingOutcome::FundingFailed));
}

#[cfg(test)]
Expand Down
7 changes: 1 addition & 6 deletions pallets/funding/src/functions/1_application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,7 @@ impl<T: Config> Pallet<T> {
},
usd_bid_on_oversubscription: None,
funding_end_block: None,
parachain_id: None,
migration_readiness_check: None,
hrmp_channel_status: HRMPChannelStatus {
project_to_polimec: ChannelStatus::Closed,
polimec_to_project: ChannelStatus::Closed,
},
migration_type: None,
};

let bucket: BucketOf<T> = Self::create_bucket_from_metadata(&project_metadata)?;
Expand Down
Loading

0 comments on commit d3d71ec

Please sign in to comment.