Skip to content

Commit

Permalink
Merge pull request #53 from logion-network/feature/invited-contributor
Browse files Browse the repository at this point in the history
Invited contributor
  • Loading branch information
benoitdevos authored Jan 11, 2024
2 parents bab6aa7 + c7844cb commit 26cbca2
Show file tree
Hide file tree
Showing 7 changed files with 393 additions and 109 deletions.
9 changes: 9 additions & 0 deletions pallet-block-reward/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{self as pallet_block_reward, NegativeImbalanceOf};
use frame_support::{
construct_runtime, parameter_types, traits::Currency,
};
use frame_support::dispatch::RawOrigin;
use frame_support::traits::EnsureOrigin;
use frame_system as system;

Expand Down Expand Up @@ -123,13 +124,21 @@ parameter_types! {
};
}

#[cfg(feature = "runtime-benchmarks")]
pub type OuterOrigin<T> = <T as frame_system::Config>::RuntimeOrigin;

pub struct LoAuthorityListMock;
impl EnsureOrigin<RuntimeOrigin> for LoAuthorityListMock {
type Success = <Test as system::Config>::AccountId;

fn try_origin(o: <Test as system::Config>::RuntimeOrigin) -> Result<Self::Success, <Test as system::Config>::RuntimeOrigin> {
<Self as IsLegalOfficer<<Test as system::Config>::AccountId, <Test as system::Config>::RuntimeOrigin>>::try_origin(o)
}

#[cfg(feature = "runtime-benchmarks")]
fn try_successful_origin() -> Result<RuntimeOrigin, ()> {
Ok(OuterOrigin::<Test>::from(RawOrigin::Signed(LEGAL_OFFICER_ACCOUNT_1)))
}
}

impl IsLegalOfficer<<Test as system::Config>::AccountId, RuntimeOrigin> for LoAuthorityListMock {
Expand Down
81 changes: 81 additions & 0 deletions pallet-logion-loc/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ mod benchmarks {
fn create_polkadot_identity_loc() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);
let items = many_items::<T>(&requester);
let next_loc_id: T::LocId = T::LocIdFactory::loc_id(NEXT_LOC_ID);
Expand Down Expand Up @@ -128,6 +129,7 @@ mod benchmarks {
fn create_polkadot_transaction_loc() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);
let items = many_items::<T>(&requester);
let next_loc_id: T::LocId = T::LocIdFactory::loc_id(NEXT_LOC_ID);
Expand Down Expand Up @@ -183,6 +185,7 @@ mod benchmarks {
fn create_collection_loc() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);
let items = many_items::<T>(&requester);
let next_loc_id: T::LocId = T::LocIdFactory::loc_id(NEXT_LOC_ID);
Expand Down Expand Up @@ -253,6 +256,7 @@ mod benchmarks {
fn add_link() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);
create_locs_to_link_to::<T>(&requester); // Targets of the many links
create_loc::<T>(T::LocIdFactory::loc_id(MANY_ITEMS), &legal_officer_id, &requester); // New target
Expand Down Expand Up @@ -312,6 +316,7 @@ mod benchmarks {
fn add_collection_item() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);

let loc_id: T::LocId = T::LocIdFactory::loc_id(0);
Expand Down Expand Up @@ -481,6 +486,7 @@ mod benchmarks {
fn add_tokens_record() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);

let loc_id: T::LocId = T::LocIdFactory::loc_id(0);
Expand Down Expand Up @@ -602,6 +608,7 @@ mod benchmarks {
fn acknowledge_metadata() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);

let loc_id: T::LocId = T::LocIdFactory::loc_id(0);
Expand Down Expand Up @@ -637,6 +644,7 @@ mod benchmarks {
fn acknowledge_file() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);

let loc_id: T::LocId = T::LocIdFactory::loc_id(0);
Expand Down Expand Up @@ -672,6 +680,7 @@ mod benchmarks {
fn acknowledge_link() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);
create_locs_to_link_to::<T>(&requester); // Targets of the many links

Expand Down Expand Up @@ -708,6 +717,7 @@ mod benchmarks {
fn close() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);
let items = many_items::<T>(&requester);
let next_loc_id: T::LocId = T::LocIdFactory::loc_id(NEXT_LOC_ID);
Expand All @@ -731,6 +741,54 @@ mod benchmarks {
Ok(())
}

// Benchmark `set_invited_contributor_selection` extrinsic.
#[benchmark]
fn set_invited_contributor_selection() -> Result<(), BenchmarkError> {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);

ensure_enough_funds::<T>(&requester);

let invited_contributor: T::AccountId = account("invited_contributor", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(INVITED_CONTRIBUTOR_IDENTITY_LOC_ID), &legal_officer_id, &invited_contributor);

let loc_id: T::LocId = T::LocIdFactory::loc_id(0);
assert_ok!(LogionLoc::<T>::create_collection_loc(
<T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(requester.clone())),
loc_id,
legal_officer_id.clone(),
None,
Some(100),
true,
0u32.into(),
0u32.into(),
0u32.into(),
0u32.into(),
ItemsParams {
metadata: Vec::new(),
files: Vec::new(),
links: Vec::new(),
},
));
assert_ok!(LogionLoc::<T>::close(
<T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(legal_officer_id.clone())),
loc_id,
None,
false,
));

#[extrinsic_call]
_(
RawOrigin::Signed(requester.clone()),
loc_id,
requester.clone(),
true,
);

Ok(())
}

impl_benchmark_test_suite! {
LogionLoc,
crate::mock::new_test_ext(),
Expand Down Expand Up @@ -832,12 +890,35 @@ fn create_loc<T: pallet::Config>(loc_id: T::LocId, legal_officer_id: &T::Account
));
}

fn create_closed_polkadot_identity_loc<T: pallet::Config>(loc_id: T::LocId, legal_officer_id: &T::AccountId, requester: &T::AccountId) {
assert_ok!(LogionLoc::<T>::create_polkadot_identity_loc(
<T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(requester.clone())),
loc_id,
legal_officer_id.clone(),
0u32.into(),
ItemsParams {
metadata: Vec::new(),
files: Vec::new(),
links: Vec::new(),
},
));
assert_ok!(LogionLoc::<T>::close(
<T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(legal_officer_id.clone())),
loc_id,
None,
false,
));
}

const MANY_ITEMS: u32 = 10;
const NEXT_LOC_ID: u32 = MANY_ITEMS;
const REQUESTER_IDENTITY_LOC_ID: u32 = NEXT_LOC_ID + 2;
const INVITED_CONTRIBUTOR_IDENTITY_LOC_ID: u32 = NEXT_LOC_ID + 3;

fn setup_empty_loc<T: pallet::Config>() -> (T::LocId, T::AccountId) {
let legal_officer_id = any_legal_officer::<T>();
let requester: T::AccountId = account("requester", 1, SEED);
create_closed_polkadot_identity_loc::<T>(T::LocIdFactory::loc_id(REQUESTER_IDENTITY_LOC_ID), &legal_officer_id, &requester);
ensure_enough_funds::<T>(&requester);
let loc_id: T::LocId = T::LocIdFactory::loc_id(0);
create_loc::<T>(loc_id, &legal_officer_id, &requester);
Expand Down
60 changes: 58 additions & 2 deletions pallet-logion-loc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,19 @@ pub mod pallet {
#[pallet::getter(fn sponsorship)]
pub type SponsorshipMap<T> = StorageMap<_, Blake2_128Concat, <T as Config>::SponsorshipId, SponsorshipOf<T>>;

#[pallet::event]
/// Invited Contributors by LOC
#[pallet::storage]
#[pallet::getter(fn selected_invited_contributors)]
pub type InvitedContributorsByLocMap<T> = StorageDoubleMap<
_,
Blake2_128Concat,
<T as Config>::LocId,
Blake2_128Concat,
<T as frame_system::Config>::AccountId, // invited contributor
()
>;

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Issued upon LOC creation. [locId]
Expand Down Expand Up @@ -836,6 +848,8 @@ pub mod pallet {
BadTokenIssuance,
/// There is still at least one Item (Metadata, Link or File) unacknowledged by verified issuer
CannotCloseUnacknowledgedByVerifiedIssuer,
/// The provided Polkadot account has no closed, non-void identity LOC
AccountNotIdentified,
}

#[pallet::hooks]
Expand Down Expand Up @@ -970,6 +984,8 @@ pub mod pallet {
Err(Error::<T>::Unauthorized)?
} else if <LocMap<T>>::contains_key(&loc_id) {
Err(Error::<T>::AlreadyExists)?
} else if !Self::has_closed_identity_loc(&requester_account_id, &legal_officer) {
Err(Error::<T>::AccountNotIdentified)?
} else {
let requester = RequesterOf::<T>::Account(requester_account_id.clone());
let mut loc = Self::build_open_loc(&legal_officer, &requester, LocType::Transaction, None, legal_fee);
Expand Down Expand Up @@ -1045,7 +1061,9 @@ pub mod pallet {
Err(Error::<T>::Unauthorized)?
} else if collection_last_block_submission.is_none() && collection_max_size.is_none() {
Err(Error::<T>::CollectionHasNoLimit)?
}
} else if !Self::has_closed_identity_loc(&requester_account_id, &legal_officer) {
Err(Error::<T>::AccountNotIdentified)?
}

if <LocMap<T>>::contains_key(&loc_id) {
Err(Error::<T>::AlreadyExists)?
Expand Down Expand Up @@ -1700,6 +1718,43 @@ pub mod pallet {
}
}
}

/// Select/unselect an invited contributor on a given LOC
#[pallet::call_index(25)]
#[pallet::weight(T::WeightInfo::set_invited_contributor_selection())]
pub fn set_invited_contributor_selection(
origin: OriginFor<T>,
#[pallet::compact] loc_id: T::LocId,
invited_contributor: T::AccountId,
selected: bool,
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
if !<LocMap<T>>::contains_key(&loc_id) {
Err(Error::<T>::NotFound)?
} else {
let loc = <LocMap<T>>::get(&loc_id).unwrap();
match &loc.requester {
Account(requester_account) =>
if requester_account.clone() != who {
Err(Error::<T>::Unauthorized)?
},
_ => Err(Error::<T>::Unauthorized)?
};
if loc.void_info.is_some() {
Err(Error::<T>::CannotMutateVoid)?
} else if !Self::has_closed_identity_loc(&invited_contributor, &loc.owner) {
Err(Error::<T>::AccountNotIdentified)?
} else {
let already_invited_contributor = Self::selected_invited_contributors(loc_id, &invited_contributor);
if already_invited_contributor.is_some() && !selected {
<InvitedContributorsByLocMap<T>>::remove(loc_id, &invited_contributor);
} else if already_invited_contributor.is_none() && selected {
<InvitedContributorsByLocMap<T>>::insert(loc_id, &invited_contributor, ());
}
Ok(().into())
}
}
}
}

impl<T: Config> LocQuery<T::LocId, <T as frame_system::Config>::AccountId> for Pallet<T> {
Expand Down Expand Up @@ -2076,6 +2131,7 @@ pub mod pallet {
match &collection_loc.requester { Account(requester) => requester == adder, _ => false }
|| *adder == collection_loc.owner
|| Self::selected_verified_issuers(loc_id, adder).is_some()
|| Self::selected_invited_contributors(loc_id, adder).is_some()
)
&& collection_loc.closed
&& collection_loc.void_info.is_none()
Expand Down
1 change: 1 addition & 0 deletions pallet-logion-loc/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub const ISSUER_ID2: u64 = 6;
pub const SPONSOR_ID: u64 = 7;
pub const LOGION_TREASURY_ACCOUNT_ID: u64 = 8;
pub const UNAUTHORIZED_CALLER: u64 = 9;
pub const INVITED_CONTRIBUTOR_ID: u64 = 10;

#[cfg(feature = "runtime-benchmarks")]
pub type OuterOrigin<T> = <T as frame_system::Config>::RuntimeOrigin;
Expand Down
Loading

0 comments on commit 26cbca2

Please sign in to comment.