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

Commit

Permalink
Basic end to end test
Browse files Browse the repository at this point in the history
  • Loading branch information
shawntabrizi committed Oct 8, 2020
1 parent d59c8da commit 3aa692a
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 12 deletions.
2 changes: 0 additions & 2 deletions Cargo.lock

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

8 changes: 2 additions & 6 deletions frame/name-service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,26 @@ readme = "README.md"
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
serde = { version = "1.0.101", optional = true }
codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] }
sp-keyring = { version = "2.0.0", optional = true, path = "../../primitives/keyring" }
sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" }
sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" }
sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" }
sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" }
frame-support = { version = "2.0.0", default-features = false, path = "../support" }
frame-system = { version = "2.0.0", default-features = false, path = "../system" }

# Benchmarking dependencies
frame-benchmarking = { version = "2.0.0", default-features = false, path = "../benchmarking", optional = true }

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

[features]
default = ["std"]
std = [
"serde",
"sp-keyring",
"codec/std",
"sp-core/std",
"sp-std/std",
"sp-io/std",
"frame-support/std",
"sp-runtime/std",
"frame-system/std",
Expand Down
14 changes: 10 additions & 4 deletions frame/name-service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ use frame_support::traits::{
use frame_system::ensure_signed;
use codec::{Encode, Decode};

mod mock;
mod tests;

type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
type NegativeImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance;

pub trait WeightInfo {}
impl WeightInfo for () {}

/// The module's config trait.
pub trait Trait: frame_system::Trait {
Expand Down Expand Up @@ -185,7 +189,7 @@ decl_module! {
#[weight = 0]
fn bid(origin, name: Name, new_bid: BalanceOf<T>) {
let new_bidder = ensure_signed(origin)?;
ensure!(new_bid > T::MinBid::get(), Error::<T>::InvalidBid);
ensure!(new_bid >= T::MinBid::get(), Error::<T>::InvalidBid);

let block_number = frame_system::Module::<T>::block_number();
let new_bid_end = block_number.saturating_add(T::BiddingPeriod::get());
Expand Down Expand Up @@ -247,7 +251,7 @@ decl_module! {
NameStatus::Available | NameStatus::Owned { .. } => Err(Error::<T>::InvalidClaim)?,
NameStatus::Bidding { who: current_bidder, bid_end, amount } => {
ensure!(caller == *current_bidder, Error::<T>::NotBidder);
ensure!(*bid_end < block_number, Error::<T>::NotExpired);
ensure!(*bid_end <= block_number, Error::<T>::NotExpired);
// If user only wants 1 period, just slash the reserve we already have.
let mut credit = if num_of_periods == 1 {
NegativeImbalanceOf::<T>::zero()
Expand All @@ -268,7 +272,9 @@ decl_module! {
credit.subsume(T::Currency::slash_reserved(current_bidder, *amount).0);
T::PaymentDestination::on_unbalanced(credit);
// Grant ownership
let ownership_expiration = T::OwnershipPeriod::get().saturating_mul(num_of_periods.into());
let ownership_expiration = block_number.saturating_add(
T::OwnershipPeriod::get().saturating_mul(num_of_periods.into())
);
*state = NameStatus::Owned {
who: current_bidder.clone(),
expiration: Some(ownership_expiration),
Expand Down Expand Up @@ -307,7 +313,7 @@ decl_module! {
NameStatus::Owned { who: current_owner, expiration: maybe_expiration } => {
if let Some(expiration) = maybe_expiration {
if caller != *current_owner {
ensure!(*expiration < block_number, Error::<T>::NotExpired);
ensure!(*expiration <= block_number, Error::<T>::NotExpired);
}
*state = NameStatus::Available;
Ok(())
Expand Down
138 changes: 138 additions & 0 deletions frame/name-service/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// This file is part of Substrate.

// Copyright (C) 2018-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.

//! Test utilities

#![cfg(test)]

use sp_runtime::testing::Header;
use sp_runtime::Perbill;
use sp_core::H256;
use frame_support::{impl_outer_origin, impl_outer_event, parameter_types, ord_parameter_types, weights::Weight};
use crate::{self as pallet_name_service, Module, Trait, ExtensionConfig};
use frame_system::EnsureSignedBy;

impl_outer_origin!{
pub enum Origin for Test where system = frame_system {}
}
impl_outer_event!{
pub enum Event for Test {
frame_system<T>,
pallet_balances<T>,
pallet_name_service<T>,
}
}

// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Test;

parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const MaximumBlockWeight: Weight = 1024;
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::one();
}

type BlockNumber = u64;
type Balance = u64;

impl frame_system::Trait for Test {
type BaseCallFilter = ();
type Origin = Origin;
type Call = ();
type Index = u64;
type BlockNumber = BlockNumber;
type Hash = H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
type AccountId = u64;
type Lookup = NameService;
type Header = Header;
type Event = Event;
type BlockHashCount = BlockHashCount;
type MaximumBlockWeight = MaximumBlockWeight;
type DbWeight = ();
type BlockExecutionWeight = ();
type ExtrinsicBaseWeight = ();
type MaximumExtrinsicWeight = MaximumBlockWeight;
type MaximumBlockLength = MaximumBlockLength;
type AvailableBlockRatio = AvailableBlockRatio;
type Version = ();
type PalletInfo = ();
type AccountData = pallet_balances::AccountData<u64>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
}

parameter_types! {
pub const ExistentialDeposit: u64 = 1;
}

impl pallet_balances::Trait for Test {
type MaxLocks = ();
type Balance = Balance;
type DustRemoval = ();
type Event = Event;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
}


parameter_types! {
pub const BiddingPeriod: BlockNumber = 10;
pub const ClaimPeriod: BlockNumber = 5;
pub const OwnershipPeriod: BlockNumber = 100;
pub const MinBid: Balance = 5;
pub ExtensionsOn: ExtensionConfig<Balance, BlockNumber> = ExtensionConfig {
enabled: true,
extension_period: 100,
extension_fee: 5,
};
}

ord_parameter_types! {
pub const Manager: u64 = 100;
pub const Permanence: u64 = 200;
}

impl Trait for Test {
type Currency = Balances;
type Event = Event;
type ManagerOrigin = EnsureSignedBy<Manager, u64>;
type PermanenceOrigin = EnsureSignedBy<Permanence, u64>;
type BiddingPeriod = BiddingPeriod;
type ClaimPeriod = ClaimPeriod;
type OwnershipPeriod = OwnershipPeriod;
type PaymentDestination = ();
type MinBid = MinBid;
type ExtensionConfig = ExtensionsOn;
type WeightInfo = ();
}

pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
pallet_balances::GenesisConfig::<Test>{
balances: vec![(1, 100), (2, 200), (3, 300), (4, 400), (5, 500), (6, 600)],
}.assimilate_storage(&mut t).unwrap();
t.into()
}

pub type System = frame_system::Module<Test>;
pub type Balances = pallet_balances::Module<Test>;
pub type NameService = Module<Test>;
94 changes: 94 additions & 0 deletions frame/name-service/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// This file is part of Substrate.

// Copyright (C) 2017-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.

//! Tests for the module.

#![cfg(test)]

use super::*;
use super::mock::*;
use sp_core::blake2_256;
use frame_support::{
assert_ok, assert_noop,
traits::{OnInitialize, OnFinalize}
};
use pallet_balances::Error as BalancesError;

fn run_to_block(n: u64) {
while System::block_number() < n {
NameService::on_finalize(System::block_number());
System::set_block_number(System::block_number() + 1);
NameService::on_initialize(System::block_number());
}
}

#[test]
fn basic_setup_works() {
new_test_ext().execute_with(|| {
assert_eq!(Balances::free_balance(&1), 100);
assert_eq!(Balances::free_balance(&2), 200);
});
}

#[test]
fn end_to_end_should_work() {
new_test_ext().execute_with(|| {
// This is the name we will bid on.
let name = b"shawntabrizi";
let name_hash = blake2_256(name);

// Name is totally available.
assert!(!Registration::<Test>::contains_key(name_hash));
assert!(!Lookup::<Test>::contains_key(name_hash));

// User 1 can make an initial bid.
assert_ok!(NameService::bid(Origin::signed(1), name_hash, 5));
assert_eq!(Balances::free_balance(&1), 95);

// User 2 can be outbid.
run_to_block(9);
assert_ok!(NameService::bid(Origin::signed(2), name_hash, 10));
assert_eq!(Balances::free_balance(&1), 100);
assert_eq!(Balances::free_balance(&2), 190);

// User 2 can win bid. (others cant bid anymore)
run_to_block(19);
assert_noop!(NameService::bid(Origin::signed(1), name_hash, 15), Error::<Test>::InvalidBid);

// User 2 can claim bid. 2 ^ 2 = 4 * 10 = 40 total cost
assert_ok!(NameService::claim(Origin::signed(2), name_hash, 2));
assert_eq!(Balances::free_balance(&2), 160);

// User 2 can assign their name
assert_ok!(NameService::assign(Origin::signed(2), name_hash, Some(2)));

// Name is totally taken.
assert!(Registration::<Test>::contains_key(name_hash));
assert_eq!(Lookup::<Test>::get(name_hash), Some(2));

// Name can be used instead of AccountId
assert_ok!(Balances::transfer(Origin::signed(1), MultiAddress::Hash256(name_hash), 40));
assert_eq!(Balances::free_balance(&2), 200);

// Name can expire
run_to_block(219);
assert_ok!(NameService::free(Origin::signed(1), name_hash));

// Name can be bid for again.
assert_ok!(NameService::bid(Origin::signed(1), name_hash, 5));
});
}

0 comments on commit 3aa692a

Please sign in to comment.