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

Commit

Permalink
Add tests for Polkadot runtime weights and fees (#1090)
Browse files Browse the repository at this point in the history
* Add tests for Balance module weights

* Add tests for some of the Staking functions

* Add tests for system Pallet weights

* Add weight tests for Session pallet

* Add tests for Democracy Pallet weights

* Add tests for Phragment weights

* Add tests for Treasury weights

* Use consistent naming for tests

* Split tests into separate weight and fee suites

* Move weight constant checks into one test

* Use formulas instead of hardcoded weights

* Slim down number of tests

Mainly removing ones that are either root calls that aren't "important",
or others which will likely change if another test (which we kept) also
changes.

* Update timestamp set() weight

* Update Staking Pallet weights

* Update Democracy Pallet weights

* Update copyright year

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
  • Loading branch information
HCastano and kianenigma authored May 27, 2020
1 parent cfd1e09 commit fc839a0
Show file tree
Hide file tree
Showing 2 changed files with 278 additions and 3 deletions.
6 changes: 3 additions & 3 deletions runtime/polkadot/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ pub mod currency {
use primitives::Balance;

pub const DOTS: Balance = 1_000_000_000_000;
pub const DOLLARS: Balance = DOTS / 100;
pub const CENTS: Balance = DOLLARS / 100;
pub const MILLICENTS: Balance = CENTS / 1_000;
pub const DOLLARS: Balance = DOTS / 100; // 10_000_000_000
pub const CENTS: Balance = DOLLARS / 100; // 100_000_000
pub const MILLICENTS: Balance = CENTS / 1_000; // 100_000
}

/// Time and blocks.
Expand Down
275 changes: 275 additions & 0 deletions runtime/polkadot/tests/weights.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot 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.

// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! Tests to make sure that Polkadot's weights and fees match what we
//! expect from Substrate.
//!
//! These test are not meant to be exhaustive, as it is inevitable that
//! weights in Substrate will change. Instead they are supposed to provide
//! some sort of indicator that calls we consider important (e.g Balances::transfer)
//! have not suddenly changed from under us.

use frame_support::{
traits::ContainsLengthBound,
weights::{constants::*, GetDispatchInfo, Weight},
};
use keyring::AccountKeyring;
use polkadot_runtime::constants::currency::*;
use polkadot_runtime::{self, Runtime};
use primitives::AccountId;
use runtime_common::MaximumBlockWeight;

use democracy::Call as DemocracyCall;
use elections_phragmen::Call as PhragmenCall;
use session::Call as SessionCall;
use staking::Call as StakingCall;
use system::Call as SystemCall;
use treasury::Call as TreasuryCall;

type DbWeight = <Runtime as system::Trait>::DbWeight;

#[test]
fn sanity_check_weight_per_time_constants_are_as_expected() {
// These values comes from Substrate, we want to make sure that if it
// ever changes we don't accidently break Polkadot
assert_eq!(WEIGHT_PER_SECOND, 1_000_000_000_000);
assert_eq!(WEIGHT_PER_MILLIS, WEIGHT_PER_SECOND / 1000);
assert_eq!(WEIGHT_PER_MICROS, WEIGHT_PER_MILLIS / 1000);
assert_eq!(WEIGHT_PER_NANOS, WEIGHT_PER_MICROS / 1000);
}

#[test]
fn weight_of_balances_transfer_is_correct() {
// #[weight = T::DbWeight::get().reads_writes(1, 1) + 70_000_000]
let expected_weight = DbWeight::get().read + DbWeight::get().write + 70_000_000;

let weight = polkadot_runtime::BalancesCall::transfer::<Runtime>(Default::default(), Default::default())
.get_dispatch_info()
.weight;
assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_balances_transfer_keep_alive_is_correct() {
// #[weight = T::DbWeight::get().reads_writes(1, 1) + 50_000_000]
let expected_weight = DbWeight::get().read + DbWeight::get().write + 50_000_000;

let weight = polkadot_runtime::BalancesCall::transfer_keep_alive::<Runtime>(Default::default(), Default::default())
.get_dispatch_info()
.weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_timestamp_set_is_correct() {
// #[weight = T::DbWeight::get().reads_writes(2, 1) + 8_000_000]
let expected_weight = (2 * DbWeight::get().read) + DbWeight::get().write + 8_000_000;
let weight = polkadot_runtime::TimestampCall::set::<Runtime>(Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_staking_bond_is_correct() {
let controller: AccountId = AccountKeyring::Alice.into();

// #[weight = 67 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(5, 4)]
let expected_weight = 67 * WEIGHT_PER_MICROS + (DbWeight::get().read * 5) + (DbWeight::get().write * 4);
let weight = StakingCall::bond::<Runtime>(controller, 1 * DOLLARS, Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_staking_validate_is_correct() {
// #[weight = 17 * WEIGHT_PER_MICROS + T::DbWeight::get().reads_writes(2, 2)]
let expected_weight = 17 * WEIGHT_PER_MICROS + (DbWeight::get().read * 2) + (DbWeight::get().write * 2);
let weight = StakingCall::validate::<Runtime>(Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_staking_nominate_is_correct() {
let targets: Vec<AccountId> = vec![Default::default(), Default::default(), Default::default()];

// #[weight = T::DbWeight::get().reads_writes(3, 2)
// .saturating_add(22 * WEIGHT_PER_MICROS)
// .saturating_add((360 * WEIGHT_PER_NANOS).saturating_mul(targets.len() as Weight))
// ]
let db_weight = (DbWeight::get().read * 3) + (DbWeight::get().write * 2);
let targets_weight = (360 * WEIGHT_PER_NANOS).saturating_mul(targets.len() as Weight);

let expected_weight = db_weight.saturating_add(22 * WEIGHT_PER_MICROS).saturating_add(targets_weight);
let weight = StakingCall::nominate::<Runtime>(targets).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_system_set_code_is_correct() {
// #[weight = (T::MaximumBlockWeight::get(), DispatchClass::Operational)]
let expected_weight = MaximumBlockWeight::get();
let weight = SystemCall::set_code::<Runtime>(vec![]).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_system_set_storage_is_correct() {
let storage_items = vec![(vec![12], vec![34]), (vec![45], vec![83])];
let len = storage_items.len() as Weight;

// #[weight = FunctionOf(
// |(items,): (&Vec<KeyValue>,)| {
// T::DbWeight::get().writes(items.len() as Weight)
// .saturating_add((items.len() as Weight).saturating_mul(600_000))
// },
// DispatchClass::Operational,
// Pays::Yes,
// )]
let expected_weight = (DbWeight::get().write * len).saturating_add(len.saturating_mul(600_000));
let weight = SystemCall::set_storage::<Runtime>(storage_items).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_system_remark_is_correct() {
// #[weight = 700_000]
let expected_weight = 700_000;
let weight = SystemCall::remark::<Runtime>(vec![]).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_session_set_keys_is_correct() {
// #[weight = 200_000_000
// + T::DbWeight::get().reads(2 + T::Keys::key_ids().len() as Weight)
// + T::DbWeight::get().writes(1 + T::Keys::key_ids().len() as Weight)]
//
// Polkadot has five possible session keys, so we default to key_ids.len() = 5
let expected_weight = 200_000_000 + (DbWeight::get().read * (2 + 5)) + (DbWeight::get().write * (1 + 5));
let weight = SessionCall::set_keys::<Runtime>(Default::default(), Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_session_purge_keys_is_correct() {
// #[weight = 120_000_000
// + T::DbWeight::get().reads_writes(2, 1 + T::Keys::key_ids().len() as Weight)]
//
// Polkadot has five possible session keys, so we default to key_ids.len() = 5
let expected_weight = 120_000_000 + (DbWeight::get().read * 2) + (DbWeight::get().write * (1 + 5));
let weight = SessionCall::purge_keys::<Runtime>().get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_democracy_propose_is_correct() {
// #[weight = 50_000_000 + T::DbWeight::get().reads_writes(2, 3)]
let expected_weight = 50_000_000 + (DbWeight::get().read * 2) + (DbWeight::get().write * 3);
let weight = DemocracyCall::propose::<Runtime>(Default::default(), Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_democracy_vote_is_correct() {
use democracy::AccountVote;
let vote = AccountVote::Standard { vote: Default::default(), balance: Default::default() };

// #[weight = 50_000_000 + 350_000 * Weight::from(T::MaxVotes::get()) + T::DbWeight::get().reads_writes(3, 3)]
let expected_weight = 50_000_000
+ 350_000 * (Weight::from(polkadot_runtime::MaxVotes::get()))
+ (DbWeight::get().read * 3)
+ (DbWeight::get().write * 3);
let weight = DemocracyCall::vote::<Runtime>(Default::default(), vote).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_democracy_enact_proposal_is_correct() {
// #[weight = T::MaximumBlockWeight::get()]
let expected_weight = MaximumBlockWeight::get();
let weight =
DemocracyCall::enact_proposal::<Runtime>(Default::default(), Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_phragmen_vote_is_correct() {
// #[weight = 100_000_000]
let expected_weight = 100_000_000;
let weight = PhragmenCall::vote::<Runtime>(Default::default(), Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_phragmen_submit_candidacy_is_correct() {
// #[weight = 500_000_000]
let expected_weight = 500_000_000;
let weight = PhragmenCall::submit_candidacy::<Runtime>().get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_phragmen_renounce_candidacy_is_correct() {
// #[weight = (2_000_000_000, DispatchClass::Operational)]
let expected_weight = 2_000_000_000;
let weight = PhragmenCall::renounce_candidacy::<Runtime>().get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_treasury_propose_spend_is_correct() {
// #[weight = 120_000_000 + T::DbWeight::get().reads_writes(1, 2)]
let expected_weight = 120_000_000 + DbWeight::get().read + 2 * DbWeight::get().write;
let weight =
TreasuryCall::propose_spend::<Runtime>(Default::default(), Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_treasury_approve_proposal_is_correct() {
// #[weight = (34_000_000 + T::DbWeight::get().reads_writes(2, 1), DispatchClass::Operational)]
let expected_weight = 34_000_000 + 2 * DbWeight::get().read + DbWeight::get().write;
let weight = TreasuryCall::approve_proposal::<Runtime>(Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

#[test]
fn weight_of_treasury_tip_is_correct() {
let max_len: Weight = <Runtime as treasury::Trait>::Tippers::max_len() as Weight;

// #[weight = 68_000_000 + 2_000_000 * T::Tippers::max_len() as Weight
// + T::DbWeight::get().reads_writes(2, 1)]
let expected_weight = 68_000_000 + 2_000_000 * max_len + 2 * DbWeight::get().read + DbWeight::get().write;
let weight = TreasuryCall::tip::<Runtime>(Default::default(), Default::default()).get_dispatch_info().weight;

assert_eq!(weight, expected_weight);
}

0 comments on commit fc839a0

Please sign in to comment.