Skip to content
This repository was archived by the owner on Jul 4, 2022. It is now read-only.
14 changes: 13 additions & 1 deletion prml/consortium-permission/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ mod mock;
#[cfg(test)]
mod tests;

use frame_support::{decl_error, decl_event, decl_module, decl_storage, ensure, traits::Get};
use frame_support::{
decl_error, decl_event, decl_module, decl_storage, ensure, traits::Get,
storage::{StorageMap, IterableStorageMap}
};
use frame_system::{ensure_root, ensure_signed};
use sp_runtime::DispatchResult;
use sp_std::prelude::*;
Expand Down Expand Up @@ -302,6 +305,15 @@ impl<T: Trait> Module<T> {
}
}

/// Counts the number of accounts that have been granted a specific permission.
/// Takes a topic and value, iterate through all existing claims, and count the
/// numbers of claims with matching topic and value.
pub fn granted_permission_count(topic: &Topic, value: &Value) -> u32 {
Claim::<T>::iter().filter(
|((_holder, t), (_issuer, v))| t == topic && v == value
).count() as u32
}

/// Performs all storage changes to make a claim by an issuer on a topic about a holder.
pub fn do_make_claim(
issuer: &T::AccountId,
Expand Down
12 changes: 6 additions & 6 deletions prml/consortium-permission/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,18 +164,18 @@ impl ExtBuilder {
.unwrap()
.into();
t.execute_with(|| {
for i in self.issuers.into_iter() {
<crate::Issuers<Test>>::insert(i.0, i.1);
if !self.genesis_topics.is_empty() {
ConsortiumPermission::initialise_topics(&self.genesis_topics)
}
<crate::Topics>::put(&self.topics.0);
for i in 0..self.topics.0.len() {
<crate::TopicEnabled>::insert(&self.topics.0[i], self.topics.1[i]);
let _ = ConsortiumPermission::insert_topic(&self.topics.0[i]);
let _ = ConsortiumPermission::update_topic(&self.topics.0[i], self.topics.1[i]);
}
if !self.genesis_issuers.is_empty() {
ConsortiumPermission::initialise_issuers(&self.genesis_issuers)
}
if !self.genesis_topics.is_empty() {
ConsortiumPermission::initialise_topics(&self.genesis_topics)
for i in self.issuers.into_iter() {
<crate::Issuers<Test>>::insert(i.0, i.1);
}
});
t
Expand Down
94 changes: 78 additions & 16 deletions prml/consortium-permission/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const ALICE: AccountId = 0;
const BOB: AccountId = 1;
const CHARLIE: AccountId = 2;

const PERMISSION_GRANTED: u8 = 0x01;

// Issuers

#[test]
Expand Down Expand Up @@ -410,7 +412,7 @@ fn claim_extrinsics_must_be_signed() {
.execute_with(|| {
let topic = String::from("access").into_bytes();
assert_noop!(
ConsortiumPermission::make_claim(Origin::NONE, CHARLIE, topic.clone(), vec![0x1]),
ConsortiumPermission::make_claim(Origin::NONE, CHARLIE, topic.clone(), vec![PERMISSION_GRANTED]),
BadOrigin
);
assert_noop!(
Expand All @@ -432,7 +434,7 @@ fn claim_cannot_be_made_by_unauthorized_issuer() {
Origin::signed(BOB),
CHARLIE,
ACCESS_TOPIC.to_vec(),
vec![0x1]
vec![PERMISSION_GRANTED]
),
Error::<Test>::IssuerNotAuthorizedOnTopic
);
Expand All @@ -441,7 +443,7 @@ fn claim_cannot_be_made_by_unauthorized_issuer() {
Origin::signed(ALICE),
CHARLIE,
vec![1, 2, 3, 4, 5],
vec![0x1]
vec![PERMISSION_GRANTED]
),
Error::<Test>::IssuerNotAuthorizedOnTopic
);
Expand All @@ -456,7 +458,7 @@ fn claim_cannot_be_made_by_non_existent_topics() {
Origin::signed(ALICE),
CHARLIE,
String::from("fake-topic").into_bytes(),
vec![0x1]
vec![PERMISSION_GRANTED]
),
Error::<Test>::IssuerNotAuthorizedOnTopic
);
Expand All @@ -475,7 +477,7 @@ fn claim_cannot_be_made_by_disabled_topics() {
Origin::signed(ALICE),
CHARLIE,
String::from("disabled-topic").into_bytes(),
vec![0x1]
vec![PERMISSION_GRANTED]
),
Error::<Test>::DisabledTopic
);
Expand All @@ -494,11 +496,11 @@ fn make_simple_claim() {
Origin::signed(ALICE),
CHARLIE,
topic.clone(),
vec![0x1]
vec![PERMISSION_GRANTED]
));
assert_eq!(
ConsortiumPermission::claim((CHARLIE, &topic)),
(ALICE, vec![0x1])
(ALICE, vec![PERMISSION_GRANTED])
);
assert_eq!(
ConsortiumPermission::issuer_claims(ALICE),
Expand All @@ -515,7 +517,7 @@ fn make_simple_claim() {
ALICE,
CHARLIE,
topic,
vec![0x1]
vec![PERMISSION_GRANTED]
))
);
});
Expand All @@ -536,7 +538,7 @@ fn reissue_simple_claim() {
Origin::signed(ALICE),
CHARLIE,
topic.clone(),
vec![0x1]
vec![PERMISSION_GRANTED]
));
// Reissue
assert_ok!(ConsortiumPermission::make_claim(
Expand Down Expand Up @@ -583,7 +585,7 @@ fn claim_value_is_too_damn_long() {
Origin::signed(ALICE),
CHARLIE,
String::from("access").into_bytes(),
vec![0x1; <mock::Test as Trait>::MaximumValueSize::get() + 1]
vec![PERMISSION_GRANTED; <mock::Test as Trait>::MaximumValueSize::get() + 1]
),
Error::<Test>::ValueExceedsAllowableSize
);
Expand All @@ -601,7 +603,7 @@ fn claim_value_is_just_right() {
Origin::signed(ALICE),
CHARLIE,
String::from("access").into_bytes(),
vec![0x1; <mock::Test as Trait>::MaximumValueSize::get()]
vec![PERMISSION_GRANTED; <mock::Test as Trait>::MaximumValueSize::get()]
));
});
}
Expand Down Expand Up @@ -635,7 +637,7 @@ fn claim_revocation_fails_with_unauthorized_issuer() {
Origin::signed(ALICE),
CHARLIE,
String::from("access").into_bytes(),
vec![0x1]
vec![PERMISSION_GRANTED]
));
assert_noop!(
ConsortiumPermission::revoke_claim(
Expand All @@ -660,7 +662,7 @@ fn revoke_simple_claim() {
Origin::signed(ALICE),
CHARLIE,
topic.clone(),
vec![0x1]
vec![PERMISSION_GRANTED]
));
assert_ok!(ConsortiumPermission::revoke_claim(
Origin::signed(ALICE),
Expand Down Expand Up @@ -700,7 +702,7 @@ fn revoke_someone_elses_claim() {
Origin::signed(ALICE),
CHARLIE,
topic.clone(),
vec![0x1]
vec![PERMISSION_GRANTED]
));
assert_ok!(ConsortiumPermission::revoke_claim(
Origin::signed(BOB),
Expand Down Expand Up @@ -737,7 +739,7 @@ fn sudo_claim_revocation_fails_without_sudo() {
Origin::signed(ALICE),
CHARLIE,
String::from("access").into_bytes(),
vec![0x1]
vec![PERMISSION_GRANTED]
));
assert_noop!(
ConsortiumPermission::sudo_revoke_claim(
Expand Down Expand Up @@ -780,7 +782,7 @@ fn sudo_revoke_a_claim() {
Origin::signed(ALICE),
CHARLIE,
topic.clone(),
vec![0x1]
vec![PERMISSION_GRANTED]
));
assert_ok!(ConsortiumPermission::sudo_revoke_claim(
Origin::ROOT,
Expand Down Expand Up @@ -1000,3 +1002,63 @@ fn disable_topic_emits_events() {
);
});
}


#[test]
fn can_count_permissioned_accounts() {
ExtBuilder::default()
.topic(b"access", true)
.topic(b"can_mint_burn", true)
.build()
.execute_with(|| {
let topic = String::from("can_mint_burn").into_bytes();
assert_ok!(ConsortiumPermission::add_issuer_with_topic(Origin::ROOT, ALICE, ACCESS_TOPIC.to_vec()));
assert_ok!(ConsortiumPermission::add_issuer_with_topic(Origin::ROOT, BOB, ACCESS_TOPIC.to_vec()));
assert_ok!(ConsortiumPermission::add_issuer_with_topic(Origin::ROOT, CHARLIE, ACCESS_TOPIC.to_vec()));
assert_ok!(ConsortiumPermission::add_issuer_with_topic(Origin::ROOT, ALICE, topic.clone()));
assert_ok!(ConsortiumPermission::add_issuer_with_topic(Origin::ROOT, BOB, topic.clone()));

// Since "access" is automatically granted to its issuers,
// 3 people should have the "access" permission
assert_eq!(
ConsortiumPermission::granted_permission_count(
&ACCESS_TOPIC.to_vec(),
&vec![PERMISSION_GRANTED]
), 3);


assert_ok!(ConsortiumPermission::make_claim(
Origin::signed(ALICE),
ALICE,
topic.clone(),
vec![PERMISSION_GRANTED]
));
assert_ok!(ConsortiumPermission::make_claim(
Origin::signed(ALICE),
CHARLIE,
topic.clone(),
vec![PERMISSION_GRANTED]
));

assert_eq!(
ConsortiumPermission::granted_permission_count(
&topic.clone(),
&vec![PERMISSION_GRANTED]
), 2);

// This should replace the claim with a different issuer, the total count should
// stay unchanged.
assert_ok!(ConsortiumPermission::make_claim(
Origin::signed(BOB),
CHARLIE,
topic.clone(),
vec![PERMISSION_GRANTED]
));
assert_eq!(
ConsortiumPermission::granted_permission_count(
&topic.clone(),
&vec![PERMISSION_GRANTED]
), 2);
});
}