Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e791b72
fix: add did lookup pallet to DID authorization logic
ntn-x2 Mar 18, 2022
7f0c05b
test: add unit tests for spiritnet and peregrine runtimes for correct…
ntn-x2 Mar 18, 2022
de6e2e5
chore: clippy
ntn-x2 Mar 18, 2022
80e9a4e
feat: add additional map for reverse index
ntn-x2 Mar 18, 2022
9bea6cf
test: add unit tests
ntn-x2 Mar 18, 2022
5377124
chore: update benchmarks checks
ntn-x2 Mar 18, 2022
8fd08dd
wip: runtime upgrade scripts
ntn-x2 Mar 18, 2022
edc254f
wip: lookup pallet migration
ntn-x2 Mar 18, 2022
ce70247
chore: update toolchain version to nightly 1.59 (#339)
ntn-x2 Mar 16, 2022
53f4170
wip: benchmarks
ntn-x2 Mar 21, 2022
9cd44d2
bench: benchmark compiling
ntn-x2 Mar 21, 2022
a73b61f
chore: try-runtime complete
ntn-x2 Mar 21, 2022
4077251
chore: update deps
ntn-x2 Mar 21, 2022
12b6f33
chore: add migrations to Spiritnet runtime
ntn-x2 Mar 22, 2022
b8e2f24
chore: add comment in lookup migration
ntn-x2 Mar 22, 2022
52365eb
chore: move migration into lookup pallet
ntn-x2 Mar 22, 2022
6a4445f
fix: add try-runtime feature to did lookup crate
ntn-x2 Mar 22, 2022
08fc0c8
chore: fixes after rebase
ntn-x2 Mar 22, 2022
ae0275c
chore: fmt
ntn-x2 Mar 22, 2022
0421c85
chore: ConnectedAccounts map comment
ntn-x2 Mar 23, 2022
bb00c5d
cargo run --quiet --release -p kilt-parachain --features=runtime-benc…
Mar 24, 2022
c459a6b
cargo run --quiet --release -p kilt-parachain --features=runtime-benc…
Mar 24, 2022
f2d766a
cargo run --quiet --release -p kilt-parachain --features=runtime-benc…
Mar 24, 2022
8297e36
bench: update benchmarks to include account replacement as worst case
ntn-x2 Mar 24, 2022
54daad1
bench: fix InsufficientFunds error in benchmarks
ntn-x2 Mar 24, 2022
2732dd3
chore: fmt
ntn-x2 Mar 24, 2022
ef0ed69
cargo run --quiet --release -p kilt-parachain --features=runtime-benc…
Mar 24, 2022
1f41720
chore: update comments
ntn-x2 Mar 24, 2022
05ceed4
cargo run --quiet --release -p kilt-parachain --features=runtime-benc…
Mar 24, 2022
7cd84a0
cargo run --quiet --release -p kilt-parachain --features=runtime-benc…
Mar 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
274 changes: 147 additions & 127 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions pallets/pallet-did-lookup/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ sp-keystore = {branch = "polkadot-v0.9.17", default-features = false, git = "htt

[dependencies]
codec = {default-features = false, features = ["derive"], package = "parity-scale-codec", version = "2.3.1"}
log = "0.4"
scale-info = {version = "1.0", default-features = false, features = ["derive"]}

# KILT
Expand Down Expand Up @@ -49,7 +50,13 @@ std = [
"frame-benchmarking/std",
"frame-support/std",
"frame-system/std",
"log/std",
"scale-info/std",
"sp-runtime/std",
"sp-std/std",
]

try-runtime = [
"frame-support/try-runtime",
"kilt-support/try-runtime",
]
23 changes: 14 additions & 9 deletions pallets/pallet-did-lookup/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

//! Benchmarking

use crate::{AccountIdOf, Call, Config, ConnectedDids, CurrencyOf, Pallet};
use crate::{AccountIdOf, Call, Config, ConnectedAccounts, ConnectedDids, CurrencyOf, Pallet};

use codec::Encode;
use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite};
Expand Down Expand Up @@ -57,34 +57,37 @@ benchmarks! {
.into();

make_free_for_did::<T>(&caller);
let origin = T::EnsureOrigin::generate_origin(caller, did);
let origin = T::EnsureOrigin::generate_origin(caller, did.clone());
}: _<T::Origin>(origin, connected_acc_id, bn, sig)
verify {
assert!(ConnectedDids::<T>::get(T::AccountId::from(connected_acc)).is_some());
assert!(ConnectedAccounts::<T>::get(did, T::AccountId::from(connected_acc)).is_some());
}

associate_sender {
let caller: T::AccountId = account("caller", 0, SEED);
let did: T::DidIdentifier = account("did", 0, SEED);

make_free_for_did::<T>(&caller);
let origin = T::EnsureOrigin::generate_origin(caller.clone(), did);
let origin = T::EnsureOrigin::generate_origin(caller.clone(), did.clone());
}: _<T::Origin>(origin)
verify {
assert!(ConnectedDids::<T>::get(caller).is_some());
assert!(ConnectedDids::<T>::get(&caller).is_some());
assert!(ConnectedAccounts::<T>::get(did, caller).is_some());
}

remove_sender_association {
let caller: T::AccountId = account("caller", 0, SEED);
let did: T::DidIdentifier = account("did", 0, SEED);

make_free_for_did::<T>(&caller);
Pallet::<T>::add_association(caller.clone(), did, caller.clone()).expect("should create association");
Pallet::<T>::add_association(caller.clone(), did.clone(), caller.clone()).expect("should create association");

let origin = RawOrigin::Signed(caller.clone());
}: _(origin)
verify {
assert!(ConnectedDids::<T>::get(caller).is_none());
assert!(ConnectedDids::<T>::get(&caller).is_none());
assert!(ConnectedAccounts::<T>::get(did, caller).is_none());
}

remove_account_association {
Expand All @@ -94,10 +97,12 @@ benchmarks! {

Pallet::<T>::add_association(caller.clone(), did.clone(), caller.clone()).expect("should create association");

let origin = T::EnsureOrigin::generate_origin(caller.clone(), did);
}: _<T::Origin>(origin, caller.clone())
let origin = T::EnsureOrigin::generate_origin(caller.clone(), did.clone());
let caller_clone = caller.clone();
}: _<T::Origin>(origin, caller_clone)
verify {
assert!(ConnectedDids::<T>::get(caller).is_none());
assert!(ConnectedDids::<T>::get(&caller).is_none());
assert!(ConnectedAccounts::<T>::get(did, caller).is_none());
}
}

Expand Down
20 changes: 15 additions & 5 deletions pallets/pallet-did-lookup/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

mod connection_record;
pub mod default_weights;
pub mod migrations;

#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -70,7 +71,7 @@ pub mod pallet {
/// The connection record type.
pub(crate) type ConnectionRecordOf<T> = ConnectionRecord<DidIdentifierOf<T>, AccountIdOf<T>, BalanceOf<T>>;

pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);

#[pallet::config]
pub trait Config: frame_system::Config {
Expand Down Expand Up @@ -110,6 +111,12 @@ pub mod pallet {
#[pallet::getter(fn connected_dids)]
pub type ConnectedDids<T> = StorageMap<_, Blake2_128Concat, AccountIdOf<T>, ConnectionRecordOf<T>>;

/// Mapping from account identifiers to DIDs.
#[pallet::storage]
#[pallet::getter(fn connected_accounts)]
pub type ConnectedAccounts<T> =
StorageDoubleMap<_, Blake2_128Concat, DidIdentifierOf<T>, Blake2_128Concat, AccountIdOf<T>, ()>;
Comment thread
ntn-x2 marked this conversation as resolved.

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
Expand All @@ -129,7 +136,7 @@ pub mod pallet {
/// and the account ID.
NotAuthorized,

/// The supplied proof of ownership was outdated and will not
/// The supplied proof of ownership was outdated.
OutdatedProof,

/// The account has insufficient funds and can't pay the fees or reserve
Expand Down Expand Up @@ -293,18 +300,21 @@ pub mod pallet {
CurrencyOf::<T>::reserve(&record.deposit.owner, record.deposit.amount)?;

ConnectedDids::<T>::mutate(&account, |did_entry| {
if let Some(old_did) = did_entry.replace(record) {
Self::deposit_event(Event::<T>::AssociationRemoved(account.clone(), old_did.did));
kilt_support::free_deposit::<AccountIdOf<T>, CurrencyOf<T>>(&old_did.deposit);
if let Some(old_connection) = did_entry.replace(record) {
ConnectedAccounts::<T>::remove(&old_connection.did, &account);
Self::deposit_event(Event::<T>::AssociationRemoved(account.clone(), old_connection.did));
kilt_support::free_deposit::<AccountIdOf<T>, CurrencyOf<T>>(&old_connection.deposit);
}
});
ConnectedAccounts::<T>::insert(&did_identifier, &account, ());
Self::deposit_event(Event::AssociationEstablished(account, did_identifier));

Ok(())
}

pub(crate) fn remove_association(account: AccountIdOf<T>) -> DispatchResult {
if let Some(connection) = ConnectedDids::<T>::take(&account) {
ConnectedAccounts::<T>::remove(&connection.did, &account);
kilt_support::free_deposit::<AccountIdOf<T>, CurrencyOf<T>>(&connection.deposit);
Self::deposit_event(Event::AssociationRemoved(account, connection.did));

Expand Down
90 changes: 90 additions & 0 deletions pallets/pallet-did-lookup/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// KILT Blockchain – https://botlabs.org
// Copyright (C) 2019-2022 BOTLabs GmbH

// The KILT Blockchain is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The KILT Blockchain is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

// If you feel like getting in touch with us, you can do so at info@botlabs.org

use crate::{Config, ConnectedAccounts, ConnectedDids, Pallet};
use frame_support::{
dispatch::Weight,
traits::{Get, GetStorageVersion, OnRuntimeUpgrade},
};
use sp_std::marker::PhantomData;

pub struct LookupReverseIndexMigration<T>(PhantomData<T>);
Comment thread
ntn-x2 marked this conversation as resolved.

impl<T: Config> OnRuntimeUpgrade for LookupReverseIndexMigration<T> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<(), &'static str> {
assert!(Pallet::<T>::on_chain_storage_version() < Pallet::<T>::current_storage_version());
assert_eq!(ConnectedAccounts::<T>::iter().count(), 0);

log::info!(
"👥 DID lookup pallet to {:?} passes PRE migrate checks ✅",
Pallet::<T>::current_storage_version()
);

Ok(())
}

fn on_runtime_upgrade() -> frame_support::weights::Weight {
// Account for the new storage version written below.
let initial_weight = T::DbWeight::get().writes(1);

// Origin was disabled, so there cannot be any existing links. But we check just
// to be sure.
let total_weight: Weight =
ConnectedDids::<T>::iter().fold(initial_weight, |total_weight, (account, record)| {
ConnectedAccounts::<T>::insert(record.did, account, ());
// One read for the `ConnectedDids` entry, one write for the new
// `ConnectedAccounts` entry.
total_weight.saturating_add(T::DbWeight::get().reads_writes(1, 1))
});

Pallet::<T>::current_storage_version().put::<Pallet<T>>();

log::info!(
"👥 completed DID lookup pallet migration to {:?} ✅",
Pallet::<T>::current_storage_version()
);

total_weight
}

#[cfg(feature = "try-runtime")]
fn post_upgrade() -> Result<(), &'static str> {
assert_eq!(
Pallet::<T>::on_chain_storage_version(),
Pallet::<T>::current_storage_version()
);

// Verify DID -> Account integrity.
ConnectedDids::<T>::iter().for_each(|(account, record)| {
assert!(ConnectedAccounts::<T>::contains_key(record.did, account));
});
// Verify Account -> DID integrity.
ConnectedAccounts::<T>::iter().for_each(|(did, account, _)| {
let entry = ConnectedDids::<T>::get(account).expect("Should find a record for the given account.");
assert_eq!(entry.did, did);
});

log::info!(
"👥 DID lookup pallet to {:?} passes POST migrate checks ✅",
Pallet::<T>::current_storage_version()
);

Ok(())
}
}
12 changes: 11 additions & 1 deletion pallets/pallet-did-lookup/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use sp_runtime::{
MultiSignature, MultiSigner,
};

use crate::{mock::*, ConnectedDids, ConnectionRecord, Error};
use crate::{mock::*, ConnectedAccounts, ConnectedDids, ConnectionRecord, Error};

#[test]
fn test_add_association_sender() {
Expand All @@ -46,6 +46,7 @@ fn test_add_association_sender() {
}
})
);
assert!(ConnectedAccounts::<Test>::get(DID_00, ACCOUNT_00).is_some());
assert_eq!(
Balances::reserved_balance(ACCOUNT_00),
<Test as crate::Config>::Deposit::get()
Expand All @@ -63,6 +64,8 @@ fn test_add_association_sender() {
}
})
);
assert!(ConnectedAccounts::<Test>::get(DID_00, ACCOUNT_00).is_none());
assert!(ConnectedAccounts::<Test>::get(DID_01, ACCOUNT_00).is_some());
assert_eq!(
Balances::reserved_balance(ACCOUNT_00),
<Test as crate::Config>::Deposit::get()
Expand Down Expand Up @@ -100,6 +103,7 @@ fn test_add_association_account() {
}
})
);
assert!(ConnectedAccounts::<Test>::get(DID_00, &account_hash_alice).is_some());
assert_eq!(
Balances::reserved_balance(ACCOUNT_00),
<Test as crate::Config>::Deposit::get()
Expand All @@ -123,6 +127,8 @@ fn test_add_association_account() {
}
})
);
assert!(ConnectedAccounts::<Test>::get(DID_00, &account_hash_alice).is_none());
assert!(ConnectedAccounts::<Test>::get(DID_01, &account_hash_alice).is_some());
assert_eq!(
Balances::reserved_balance(ACCOUNT_00),
<Test as crate::Config>::Deposit::get()
Expand All @@ -146,6 +152,8 @@ fn test_add_association_account() {
}
})
);
assert!(ConnectedAccounts::<Test>::get(DID_00, &account_hash_alice).is_none());
assert!(ConnectedAccounts::<Test>::get(DID_01, &account_hash_alice).is_some());
assert_eq!(Balances::reserved_balance(ACCOUNT_00), 0);
assert_eq!(
Balances::reserved_balance(ACCOUNT_01),
Expand Down Expand Up @@ -211,6 +219,7 @@ fn test_remove_association_sender() {
// remove association
assert!(DidLookup::remove_sender_association(Origin::signed(ACCOUNT_00)).is_ok());
assert_eq!(ConnectedDids::<Test>::get(ACCOUNT_00), None);
assert!(ConnectedAccounts::<Test>::get(DID_01, ACCOUNT_00).is_none());
assert_eq!(Balances::reserved_balance(ACCOUNT_00), 0);
});
}
Expand Down Expand Up @@ -241,6 +250,7 @@ fn test_remove_association_account() {
)
.is_ok());
assert_eq!(ConnectedDids::<Test>::get(ACCOUNT_00), None);
assert!(ConnectedAccounts::<Test>::get(DID_01, ACCOUNT_00).is_none());
assert_eq!(Balances::reserved_balance(ACCOUNT_01), 0);
});
}
Expand Down
1 change: 1 addition & 0 deletions runtimes/peregrine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ try-runtime = [
"pallet-authorship/try-runtime",
"pallet-balances/try-runtime",
"pallet-collective/try-runtime",
"pallet-did-lookup/try-runtime",
"pallet-democracy/try-runtime",
"pallet-indices/try-runtime",
"pallet-membership/try-runtime",
Expand Down
36 changes: 3 additions & 33 deletions runtimes/peregrine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
construct_runtime, parameter_types,
traits::{EnsureOneOf, InstanceFilter, OnRuntimeUpgrade, PrivilegeCmp},
traits::{EnsureOneOf, InstanceFilter, PrivilegeCmp},
weights::{constants::RocksDbWeight, Weight},
};
use frame_system::EnsureRoot;
Expand Down Expand Up @@ -927,6 +927,7 @@ impl did::DeriveDidCallAuthorizationVerificationKeyRelationship for Call {
Call::Did(did::Call::create { .. }) => Err(did::RelationshipDeriveError::NotCallableByDid),
Call::Did { .. } => Ok(did::DidVerificationKeyRelationship::Authentication),
Call::Web3Names { .. } => Ok(did::DidVerificationKeyRelationship::Authentication),
Call::DidLookup { .. } => Ok(did::DidVerificationKeyRelationship::Authentication),
Call::Utility(pallet_utility::Call::batch { calls }) => single_key_relationship(&calls[..]),
Call::Utility(pallet_utility::Call::batch_all { calls }) => single_key_relationship(&calls[..]),
#[cfg(not(feature = "runtime-benchmarks"))]
Expand Down Expand Up @@ -976,40 +977,9 @@ pub type Executive = frame_executive::Executive<
// Executes pallet hooks in reverse order of definition in construct_runtime
// If we want to switch to AllPalletsWithSystem, we need to reorder the staking pallets
AllPalletsReversedWithSystemFirst,
(
SchedulerMigrationV3,
delegation::migrations::v3::DelegationMigrationV3<Runtime>,
did::migrations::v4::DidMigrationV4<Runtime>,
parachain_staking::migrations::v7::ParachainStakingMigrationV7<Runtime>,
),
pallet_did_lookup::migrations::LookupReverseIndexMigration<Runtime>,
>;

// Migration for scheduler pallet to move from a plain Call to a CallOrHash.
pub struct SchedulerMigrationV3;

impl OnRuntimeUpgrade for SchedulerMigrationV3 {
fn on_runtime_upgrade() -> frame_support::weights::Weight {
Scheduler::migrate_v1_to_v3()
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<(), &'static str> {
Scheduler::pre_migrate_to_v3()
}

#[cfg(feature = "try-runtime")]
fn post_upgrade() -> Result<(), &'static str> {
use frame_support::dispatch::GetStorageVersion;

Scheduler::post_migrate_to_v3()?;
log::info!(
"Scheduler migrated to version {:?}",
Scheduler::current_storage_version()
);
Ok(())
}
}

impl_runtime_apis! {
impl sp_api::Core<Block> for Runtime {
fn version() -> RuntimeVersion {
Expand Down
Loading