Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Substrate Name Service Pallet #7197

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
fb53e61
Initial Design
shawntabrizi Sep 24, 2020
5373c40
Name assignments
shawntabrizi Sep 25, 2020
a94e901
rename expiration -> bid end
shawntabrizi Sep 25, 2020
71c5115
Hashed names
shawntabrizi Sep 25, 2020
7c3e76d
Update name to PaymentDestination
shawntabrizi Sep 25, 2020
a4f085a
attempt at multiaddress
shawntabrizi Sep 25, 2020
d59c8da
`extend_ownership` + `ExtensionConfig`
shawntabrizi Sep 25, 2020
3aa692a
Basic end to end test
shawntabrizi Oct 8, 2020
af5eca2
Merge branch 'master' into shawntabrizi-name-service
shawntabrizi Oct 8, 2020
cdb64fb
Update frame/name-service/src/mock.rs
shawntabrizi Oct 23, 2020
a329e32
More extensible multiaddress format
shawntabrizi Oct 23, 2020
b81b08d
update name
shawntabrizi Oct 23, 2020
7009e91
Don't depend on indices to define multiaddress type
shawntabrizi Oct 23, 2020
36fdb7b
Use MultiAddress in Node Template too!
shawntabrizi Oct 23, 2020
3fc64d1
reduce traits, fix build
shawntabrizi Oct 23, 2020
e450ded
Merge remote-tracking branch 'origin/shawntabrizi-multiaddress' into …
shawntabrizi Oct 23, 2020
08de670
fix merge
shawntabrizi Oct 23, 2020
b7c120d
compiles... kinda a hack
shawntabrizi Oct 23, 2020
20d1a70
Simple implementation of `TwoStaticLookup`
shawntabrizi Oct 23, 2020
64afc14
better impl of multiple lookup sources
shawntabrizi Oct 24, 2020
535a512
support multiple `StaticLookup`
shawntabrizi Oct 24, 2020
98bfef6
bump tx version
shawntabrizi Oct 26, 2020
3a8c1c2
Merge branch 'master' into shawntabrizi-multiaddress
shawntabrizi Oct 26, 2020
41e3c24
Merge branch 'master' into shawntabrizi-multiaddress
shawntabrizi Oct 31, 2020
0e5ffa3
feedback
shawntabrizi Oct 31, 2020
65c701b
Merge branch 'shawntabrizi-multiaddress' into shawntabrizi-name-service
shawntabrizi Oct 31, 2020
04b0e8d
Update lib.rs
shawntabrizi Oct 31, 2020
474c2ea
Pallet-name-service tests (#7676)
stanly-johnson Dec 9, 2020
db31a2d
Merge branch 'master' into shawntabrizi-name-service
shawntabrizi Dec 9, 2020
b159137
update to latest substrate
shawntabrizi Dec 9, 2020
ba33ee6
Merge branch 'master' into shawntabrizi-name-service
shawntabrizi Dec 9, 2020
0526e3d
integrate benchmarks
shawntabrizi Dec 9, 2020
c729951
Benchmarks for name service pallet (#7723)
stanly-johnson Apr 10, 2021
6141b79
Merge branch 'master' into shawntabrizi-name-service
shawntabrizi Feb 23, 2022
d8ad107
migrate to FRAME v2
shawntabrizi Feb 23, 2022
db4a1be
fix static lookup
shawntabrizi Feb 23, 2022
939d2db
fix imports
shawntabrizi Feb 23, 2022
ec3ce2a
Merge branch 'master' into shawntabrizi-name-service
shawntabrizi Feb 27, 2022
da9aad5
fix deps
shawntabrizi Feb 27, 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
19 changes: 18 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ members = [
"frame/merkle-mountain-range/primitives",
"frame/merkle-mountain-range/rpc",
"frame/multisig",
"frame/name-service",
"frame/nicks",
"frame/node-authorization",
"frame/offences",
Expand Down
3 changes: 3 additions & 0 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pallet-lottery = { version = "4.0.0-dev", default-features = false, path = "../.
pallet-membership = { version = "4.0.0-dev", default-features = false, path = "../../../frame/membership" }
pallet-mmr = { version = "4.0.0-dev", default-features = false, path = "../../../frame/merkle-mountain-range" }
pallet-multisig = { version = "4.0.0-dev", default-features = false, path = "../../../frame/multisig" }
pallet-name-service = { version = "4.0.0-dev", default-features = false, path = "../../../frame/name-service" }
pallet-offences = { version = "4.0.0-dev", default-features = false, path = "../../../frame/offences" }
pallet-offences-benchmarking = { version = "4.0.0-dev", path = "../../../frame/offences/benchmarking", default-features = false, optional = true }
pallet-preimage = { version = "4.0.0-dev", default-features = false, path = "../../../frame/preimage" }
Expand Down Expand Up @@ -137,6 +138,7 @@ std = [
"pallet-membership/std",
"pallet-mmr/std",
"pallet-multisig/std",
"pallet-name-service/std",
"pallet-identity/std",
"pallet-scheduler/std",
"node-primitives/std",
Expand Down Expand Up @@ -205,6 +207,7 @@ runtime-benchmarks = [
"pallet-membership/runtime-benchmarks",
"pallet-mmr/runtime-benchmarks",
"pallet-multisig/runtime-benchmarks",
"pallet-name-service/runtime-benchmarks",
"pallet-offences-benchmarking",
"pallet-preimage/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
Expand Down
27 changes: 26 additions & 1 deletion bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ impl frame_system::Config for Runtime {
type Hash = Hash;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = Indices;
type Lookup = (Indices, NameService);
type Header = generic::Header<BlockNumber, BlakeTwo256>;
type Event = Event;
type BlockHashCount = BlockHashCount;
Expand Down Expand Up @@ -1252,6 +1252,29 @@ impl pallet_mmr::Config for Runtime {
type WeightInfo = ();
}

parameter_types! {
pub const BiddingPeriod: BlockNumber = 1 * DAYS;
pub const ClaimPeriod: BlockNumber = 1 * DAYS;
pub const OwnershipPeriod: BlockNumber = 365 * DAYS;
pub const MinBid: Balance = 10 * DOLLARS;
}

impl pallet_name_service::Config for Runtime {
type AccountIndex = AccountIndex;
type Currency = Balances;
type Event = Event;
type ManagerOrigin = EnsureRoot<AccountId>;
type PermanenceOrigin = EnsureRoot<AccountId>;
type BiddingPeriod = BiddingPeriod;
type ClaimPeriod = ClaimPeriod;
type OwnershipPeriod = OwnershipPeriod;
type PaymentDestination = Treasury;
type MinBid = MinBid;
// Extensions off
type ExtensionConfig = ();
type WeightInfo = ();
}

parameter_types! {
pub const LotteryPalletId: PalletId = PalletId(*b"py/lotto");
pub const MaxCalls: u32 = 10;
Expand Down Expand Up @@ -1411,6 +1434,7 @@ construct_runtime!(
ChildBounties: pallet_child_bounties,
Referenda: pallet_referenda,
ConvictionVoting: pallet_conviction_voting,
NameService: pallet_name_service,
}
);

Expand Down Expand Up @@ -1494,6 +1518,7 @@ mod benches {
[pallet_membership, TechnicalMembership]
[pallet_mmr, Mmr]
[pallet_multisig, Multisig]
[pallet_name_service, NameService]
[pallet_offences, OffencesBench::<Runtime>]
[pallet_preimage, Preimage]
[pallet_proxy, Proxy]
Expand Down
47 changes: 47 additions & 0 deletions frame/name-service/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[package]
name = "pallet-name-service"
version = "4.0.0-dev"
authors = ["Parity Technologies <[email protected]>"]
edition = "2018"
license = "Apache-2.0"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/substrate/"
description = "FRAME name service for Substrate"
readme = "README.md"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
sp-std = { version = "4.0.0-dev", default-features = false, path = "../../primitives/std" }
sp-runtime = { version = "5.0.0", default-features = false, path = "../../primitives/runtime" }
sp-core = { version = "5.0.0", default-features = false, path = "../../primitives/core" }
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
scale-info = { version = "2.0.0", default-features = false, features = ["derive"] }

# Benchmarking dependencies
frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true }
sp-io = { version = "5.0.0", default-features = false, path = "../../primitives/io", optional = true }

[dev-dependencies]
pallet-balances = { version = "4.0.0-dev", path = "../balances" }
sp-io = { version = "5.0.0", path = "../../primitives/io" }

[features]
default = ["std"]
std = [
"codec/std",
"sp-core/std",
"sp-std/std",
"frame-support/std",
"sp-runtime/std",
"frame-system/std",
]
runtime-benchmarks = [
"sp-io",
"frame-benchmarking",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
]
3 changes: 3 additions & 0 deletions frame/name-service/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A simple name service that can be used to give accounts friendly names.

License: Apache-2.0
174 changes: 174 additions & 0 deletions frame/name-service/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// This file is part of Substrate.

// Copyright (C) 2019-2020 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Benchmarks for Name Service Pallet

#![cfg(feature = "runtime-benchmarks")]

use super::*;
use frame_benchmarking::{account, benchmarks, whitelisted_caller};
use frame_support::traits::{Currency, Get, OnFinalize, OnInitialize};
use frame_system::{Pallet as System, RawOrigin};
use sp_runtime::traits::{One, Saturating};
use sp_io::hashing::blake2_256;

use crate::Pallet as NameService;
const SEED: u32 = 1;

fn run_to_block<T: Config>(n: T::BlockNumber) {
while System::<T>::block_number() < n {
NameService::<T>::on_finalize(System::<T>::block_number());
System::<T>::set_block_number(System::<T>::block_number() + One::one());
NameService::<T>::on_initialize(System::<T>::block_number());
}
}

benchmarks! {
// Benchmark bid with the worst possible scenario
// ie. When the bid is ongoing and new_bidder != current_bidder
bid {
// Test data
let name_hash = blake2_256(b"shawntabrizi");
let current_bidder : T::AccountId = account("current_bidder", 0, SEED);
let new_bidder : T::AccountId = whitelisted_caller();
let balance = T::Currency::minimum_balance().max(T::MinBid::get()).saturating_mul(100u32.into());
T::Currency::make_free_balance_be(&current_bidder, balance);
T::Currency::make_free_balance_be(&new_bidder, balance);
// create first bid
NameService::<T>::bid(RawOrigin::Signed(current_bidder.clone()).into(), name_hash, T::MinBid::get())?;
let new_bid_amount = T::MinBid::get().saturating_mul(2u32.into());
}: _(RawOrigin::Signed(new_bidder.clone()), name_hash, new_bid_amount)
verify {
let stored_data = Registration::<T>::get(&name_hash);
assert_eq!(stored_data, NameStatus::Bidding {
who: new_bidder.clone(),
bid_end: T::BiddingPeriod::get().saturating_add(1u32.into()),
amount: new_bid_amount
});
assert_eq!(T::Currency::total_balance(&current_bidder), balance);
assert_eq!(T::Currency::free_balance(&new_bidder), balance.saturating_sub(new_bid_amount));
}

// Benchmark claim with the worst possible scenario
// ie. When a claim is valid and for (min+1) periods
claim {
// Test data
let name_hash = blake2_256(b"shawntabrizi");
let current_bidder : T::AccountId = whitelisted_caller();
let balance = T::Currency::minimum_balance().max(T::MinBid::get()).saturating_mul(100u32.into());
T::Currency::make_free_balance_be(&current_bidder, balance);
// create winning bid
NameService::<T>::bid(RawOrigin::Signed(
current_bidder.clone()).into(),
name_hash,
T::MinBid::get())?;
run_to_block::<T>(T::BiddingPeriod::get());
}: _(RawOrigin::Signed(current_bidder.clone()), name_hash, 2 as u32)
verify {
let stored_data = Registration::<T>::get(&name_hash);
let expected_expiry = T::BiddingPeriod::get()
.saturating_add(T::OwnershipPeriod::get()
.saturating_mul(2u32.into()));
assert_eq!(stored_data, NameStatus::Owned {
who: current_bidder.clone(),
expiration : Some(expected_expiry)
});
assert_eq!(T::Currency::free_balance(&current_bidder),
balance.saturating_sub(T::MinBid::get().saturating_mul(4u32.into())));
}

// Benchmark free with the worst possible scenario
// ie. When a bid has expired and not claimed
free {
// Test data
let name_hash = blake2_256(b"shawntabrizi");
let current_bidder : T::AccountId = whitelisted_caller();
let balance = T::Currency::minimum_balance().max(T::MinBid::get()).saturating_mul(100u32.into());
T::Currency::make_free_balance_be(&current_bidder, balance);
// bid for the name
NameService::<T>::bid(RawOrigin::Signed(current_bidder.clone()).into(), name_hash, T::MinBid::get())?;
// expiry+bid+claim time
let block_to_free = T::BiddingPeriod::get()
.saturating_mul(2u32.into())
.saturating_add(T::ClaimPeriod::get());
run_to_block::<T>(block_to_free.saturating_add(1u32.into()));
}: _(RawOrigin::Signed(current_bidder.clone()), name_hash)
verify {
let stored_data = Registration::<T>::get(&name_hash);
assert_eq!(stored_data, NameStatus::default());
assert_eq!(T::Currency::total_balance(&current_bidder), balance.saturating_sub(T::MinBid::get()));
}

// Benchmark assign with the worst possible scenario
// ie. When a name is Owned and target is being set
assign {
// Test data
let name_hash = blake2_256(b"shawntabrizi");
let caller : T::AccountId = whitelisted_caller();
// set caller as the owner of name
let state = NameStatus::<T::AccountId, T::BlockNumber, BalanceOf<T>>::Owned{
who : caller.clone(),
expiration : None
};
Registration::<T>::insert(&name_hash, state);
}: _(RawOrigin::Signed(caller.clone()), name_hash, Some(caller.clone()))
verify {
assert_eq!(Lookup::<T>::get(&name_hash), Some(caller.clone()));
}

// Benchmark unassign with the worst possible scenario
// ie. When the caller is the target and can unassign
unassign {
// Test data
let name_hash = blake2_256(b"shawntabrizi");
let caller : T::AccountId = whitelisted_caller();
// set caller as the target of name
Lookup::<T>::insert(&name_hash, caller.clone());
}: _(RawOrigin::Signed(caller.clone()), name_hash)
verify {
assert_eq!(Lookup::<T>::get(&name_hash), None);
}

// Benchmark extend_ownership with the worst possible scenario
// ie. When the name is Owned, has an expiration date and extension is enabled
extend_ownership {
// Test data
let name_hash = blake2_256(b"shawntabrizi");
let caller : T::AccountId = whitelisted_caller();
let balance = T::Currency::minimum_balance()
.max(T::MinBid::get())
.saturating_mul(100u32.into());
T::Currency::make_free_balance_be(&caller, balance);
// set caller as the owner of name
let state = NameStatus::<T::AccountId, T::BlockNumber, BalanceOf<T>>::Owned{
who : caller.clone(),
expiration : Some(0u32.into())
};
Registration::<T>::insert(&name_hash, state);
}: _(RawOrigin::Signed(caller.clone()), name_hash)
verify {
let stored_data = Registration::<T>::get(&name_hash);
assert_eq!(stored_data, NameStatus::Owned {
who: caller.clone(),
expiration : Some(100u32.into())
});
assert_eq!(T::Currency::free_balance(&caller),
balance.saturating_sub(T::ExtensionConfig::get().extension_fee));
}

impl_benchmark_test_suite!(NameService, crate::mock::new_test_ext(), crate::mock::Test);
}
Loading