From 088064ca0325bf3dd023a0ffa6ed830487376fc5 Mon Sep 17 00:00:00 2001 From: Tarek Mohamed Abdalla Date: Fri, 22 Apr 2022 15:17:04 +0200 Subject: [PATCH] Add support for default domain. --- pallets/domains/src/benchmarking.rs | 8 +++ pallets/domains/src/lib.rs | 40 +++++++++++++- pallets/domains/src/tests.rs | 86 ++++++++++++++++++++++++++++- pallets/domains/src/weights.rs | 17 +++++- 4 files changed, 148 insertions(+), 3 deletions(-) diff --git a/pallets/domains/src/benchmarking.rs b/pallets/domains/src/benchmarking.rs index 834b29ef..353cc770 100644 --- a/pallets/domains/src/benchmarking.rs +++ b/pallets/domains/src/benchmarking.rs @@ -198,6 +198,14 @@ benchmarks! { assert_last_event::(Event::DomainMetaUpdated { who, domain }.into()); } + set_default_domain { + let who = account_with_balance::(); + let domain = add_domain::(&who)?; + }: _(RawOrigin::Signed(who.clone()), domain.clone()) + verify { + assert_last_event::(Event::DefaultDomainUpdated { who, domain }.into()); + } + reserve_words { let s in 1 .. T::DomainsInsertLimit::get() => (); let words = mock_bounded_string_array::(s as usize); diff --git a/pallets/domains/src/lib.rs b/pallets/domains/src/lib.rs index cc7671f7..6dd98e1b 100644 --- a/pallets/domains/src/lib.rs +++ b/pallets/domains/src/lib.rs @@ -101,7 +101,7 @@ pub mod pallet { StorageMap<_, Blake2_128Concat, DomainName, DomainMeta>; /// Domains owned per account. - /// + /// /// TWOX-NOTE: Safe as `AccountId`s are crypto hashes anyway. #[pallet::storage] #[pallet::getter(fn domains_by_owner)] @@ -113,6 +113,18 @@ pub mod pallet { ValueQuery, >; + /// The default [DomainName] set for each account. + /// + /// TWOX-NOTE: Safe as `AccountId`s are crypto hashes anyway. + #[pallet::storage] + pub(super) type DefaultDomain = + StorageMap<_, + Twox64Concat, + T::AccountId, + DomainName, + OptionQuery, + >; + /// TWOX-NOTE: Safe as `AccountId`s are crypto hashes anyway. #[pallet::storage] pub(super) type DomainByInnerValue = @@ -136,6 +148,8 @@ pub mod pallet { DomainRegistered { who: T::AccountId, domain: DomainName }, /// The domain meta was successfully updated. DomainMetaUpdated { who: T::AccountId, domain: DomainName }, + /// The default domain was successfully updated. + DefaultDomainUpdated { who: T::AccountId, domain: DomainName }, /// New words have been reserved. NewWordsReserved { count: u32 }, /// Added support for new TLDs (top-level domains). @@ -144,6 +158,8 @@ pub mod pallet { #[pallet::error] pub enum Error { + /// The default domain was not changed. + DefaultDomainNotChanged, /// The content stored in a domain metadata was not changed. DomainContentNotChanged, /// Cannot register more than `MaxDomainsPerAccount` domains. @@ -310,6 +326,28 @@ pub mod pallet { Ok(()) } + /// Sets the default domain of an account. + #[pallet::weight(::WeightInfo::set_default_domain())] + pub fn set_default_domain( + origin: OriginFor, + domain: DomainName, + ) -> DispatchResult { + let sender = ensure_signed(origin)?; + + let domain_lc = Self::lower_domain_then_bound(&domain); + let meta = Self::require_domain(domain_lc.clone())?; + + Self::ensure_allowed_to_update_domain(&meta, &sender)?; + + let old_default_domain = >::get(&sender); + ensure!(old_default_domain != Some(domain_lc.clone()), Error::::DefaultDomainNotChanged); + + >::insert(&sender, domain_lc); + + Self::deposit_event(Event::DefaultDomainUpdated { who: sender, domain }); + Ok(()) + } + /// Mark set of domains as not reservable by users. #[pallet::weight(( ::WeightInfo::reserve_words(T::DomainsInsertLimit::get()), diff --git a/pallets/domains/src/tests.rs b/pallets/domains/src/tests.rs index ee1bbd18..c24df8e5 100644 --- a/pallets/domains/src/tests.rs +++ b/pallets/domains/src/tests.rs @@ -5,8 +5,9 @@ use sp_std::convert::TryInto; use pallet_parachain_utils::mock_functions::{another_valid_content_ipfs, invalid_content_ipfs, valid_content_ipfs}; use pallet_parachain_utils::new_who_and_when; -use crate::{DomainByInnerValue, Event, mock::*}; +use crate::{DomainByInnerValue, Event, mock::*, Pallet}; use crate::Error; +use crate::Error::DefaultDomainNotChanged; use crate::types::*; // `register_domain` tests @@ -520,6 +521,89 @@ fn set_domain_content_should_fail_when_content_is_invalid() { }); } +// `set_default_domain` tests + +#[test] +fn set_default_domain_should_fail_when_domain_not_found() { + ExtBuilder::default().build_with_default_domain_registered().execute_with(|| { + assert_noop!( + Pallet::::set_default_domain( + Origin::signed(DOMAIN_OWNER), + b"test.fail".to_vec().try_into().unwrap(), + ), + Error::::DomainNotFound, + ); + }); +} + +#[test] +fn set_default_domain_should_fail_when_domain_expired() { + ExtBuilder::default().build_with_default_domain_registered().execute_with(|| { + System::set_block_number(ExtBuilder::default().reservation_period_limit + 1); + + assert_noop!( + Pallet::::set_default_domain( + Origin::signed(DOMAIN_OWNER), + default_domain(), + ), + Error::::DomainHasExpired, + ); + }); +} + +#[test] +fn set_default_domain_should_fail_when_not_domain_owner() { + ExtBuilder::default().build_with_default_domain_registered().execute_with(|| { + + assert_noop!( + Pallet::::set_default_domain( + Origin::signed(DUMMY_ACCOUNT), + default_domain(), + ), + Error::::NotDomainOwner, + ); + }); +} + +#[test] +fn set_default_domain_should_work() { + ExtBuilder::default().build_with_default_domain_registered().execute_with(|| { + + assert_ok!( + Pallet::::set_default_domain( + Origin::signed(DOMAIN_OWNER), + default_domain(), + ), + ); + + System::assert_last_event(Event::::DefaultDomainUpdated { + who: DOMAIN_OWNER, + domain: default_domain(), + }.into()); + }); +} + +#[test] +fn set_default_domain_should_fail_when_setting_the_same_value() { + ExtBuilder::default().build_with_default_domain_registered().execute_with(|| { + + assert_ok!( + Pallet::::set_default_domain( + Origin::signed(DOMAIN_OWNER), + default_domain(), + ), + ); + + assert_noop!( + Pallet::::set_default_domain( + Origin::signed(DOMAIN_OWNER), + default_domain(), + ), + Error::::DefaultDomainNotChanged, + ); + }); +} + // `reserve_domains` tests #[test] diff --git a/pallets/domains/src/weights.rs b/pallets/domains/src/weights.rs index 2424b847..809f5670 100644 --- a/pallets/domains/src/weights.rs +++ b/pallets/domains/src/weights.rs @@ -1,7 +1,7 @@ //! Autogenerated weights for pallet_domains //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-04-12, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2022-04-22, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: @@ -43,6 +43,7 @@ pub trait WeightInfo { fn force_set_inner_value() -> Weight; fn set_outer_value() -> Weight; fn set_domain_content() -> Weight; + fn set_default_domain() -> Weight; fn reserve_words(s: u32, ) -> Weight; fn support_tlds(s: u32, ) -> Weight; } @@ -94,6 +95,13 @@ pub struct SubstrateWeight(PhantomData); (21_323_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Domains RegisteredDomains (r:1 w:0) + // Storage: Domains DefaultDomain (r:1 w:1) + fn set_default_domain() -> Weight { + (34_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } // Storage: Domains ReservedWords (r:0 w:1) fn reserve_words(s: u32, ) -> Weight { @@ -159,6 +167,13 @@ pub struct SubstrateWeight(PhantomData); (21_323_000 as Weight) .saturating_add(RocksDbWeight::get().reads(1 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Domains RegisteredDomains (r:1 w:0) + // Storage: Domains DefaultDomain (r:1 w:1) + fn set_default_domain() -> Weight { + (34_000_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) } // Storage: Domains ReservedWords (r:0 w:1) fn reserve_words(s: u32, ) -> Weight {