Skip to content

Commit

Permalink
offchain migration confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed Jun 28, 2024
1 parent 8e8c998 commit fe1cb20
Show file tree
Hide file tree
Showing 17 changed files with 520 additions and 173 deletions.
142 changes: 135 additions & 7 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 itertools::Itertools;
use pallet_funding::{assert_close_enough, types::*, ProjectId};
use polimec_common::migration_types::{MigrationStatus, Migrations};
use polimec_runtime::Funding;
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_configure_receiver_pallet_migration(&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,13 +60,23 @@ 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();
let MigrationType::ParachainReceiverPallet(receiver_pallet_info) = project_details.migration_type else {
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())
});
}

fn assert_migration_not_ready(project_id: u32) {
PolimecNet::execute_with(|| {
let project_details = pallet_funding::ProjectsDetails::<PolimecRuntime>::get(project_id).unwrap();
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())
});
}

fn get_migrations_for_participants(
project_id: ProjectId,
participants: Vec<AccountId>,
Expand All @@ -69,7 +85,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 Down Expand Up @@ -181,15 +197,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 @@ -200,3 +218,113 @@ 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
);
});
}
}
4 changes: 2 additions & 2 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_configure_receiver_pallet_migration(
assert_ok!(PolimecFunding::do_start_pallet_migration(
&ISSUER.into(),
project_id,
ParaId::from(6969u32),
Expand All @@ -509,7 +509,7 @@ fn ct_migrated() {
// Migration is ready
PolimecNet::execute_with(|| {
let project_details = pallet_funding::ProjectsDetails::<PolimecRuntime>::get(project_id).unwrap();
let MigrationType::ParachainReceiverPallet(migration_info) = project_details.migration_type else {
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())
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
2 changes: 1 addition & 1 deletion pallets/funding/src/functions/1_application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<T: Config> Pallet<T> {
},
usd_bid_on_oversubscription: None,
funding_end_block: None,
migration_type: MigrationType::Offchain,
migration_type: None,
};

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

0 comments on commit fe1cb20

Please sign in to comment.