Skip to content

Commit 3a0ef57

Browse files
gpestanamelekeskianenigmaarkparmuharem
authored andcommitted
Staking and nomination pools runtime API improvements (paritytech#13119)
* Adds StakingAPI_nominations_quota and NominationPoolsApi_balanceToPoint and NominationPoolsApi_pointsToBalance runtime APIs * Adds balance param to api_nominations_quota * Update frame/nomination-pools/src/lib.rs Co-authored-by: Anton <anton.kalyaev@gmail.com> * Update frame/nomination-pools/src/lib.rs Co-authored-by: Anton <anton.kalyaev@gmail.com> * Addresses comments - returns zero instead of error in runtime api * Update frame/staking/runtime-api/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/staking/runtime-api/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Addresses PR comments * Update frame/nomination-pools/runtime-api/Cargo.toml Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Fixes points_to_balance logic; adds tests * test comment fix * Update frame/nomination-pools/runtime-api/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/nomination-pools/runtime-api/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Fix block pruning (paritytech#13323) * Referendum proposal's metadata (paritytech#12568) * referenda metadata * todo comment * remove TODO, update rustdocs * referenda clear_metadata origin signed or root * referenda metadata unit tests * drop schema type for referenda metadata * remove metadata type * referenda metadata benches * note different preimages * metadata for democracy pallet * metadata democracy pallet tests and benches * fix cargo clippy * update docs * ".git/.scripts/bench-bot.sh" pallet dev pallet_democracy * ".git/.scripts/bench-bot.sh" pallet dev pallet_referenda * Update the doc frame/democracy/src/lib.rs Co-authored-by: Roman Useinov <roman.useinov@gmail.com> * Update the doc frame/democracy/src/lib.rs Co-authored-by: Anthony Alaribe <anthonyalaribe@gmail.com> * reference instead clone for take Co-authored-by: Anthony Alaribe <anthonyalaribe@gmail.com> * error rename BadMetadata to PreimageNotExist * clear metadata within internal_cancel_referendum fn * remove redundant clone * collapse metadata api into one set_metadata method * fmt * review fixes * not request preimage on set_metadata * rename events and update docs * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_democracy * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_referenda * rename reset_metadata to transfer_metadata --------- Co-authored-by: command-bot <> Co-authored-by: Roman Useinov <roman.useinov@gmail.com> Co-authored-by: Anthony Alaribe <anthonyalaribe@gmail.com> * Improve test coverage of the `Notifications` protocol (paritytech#13033) * Add handler and upgrade tests * Add tests for `behaviour.rs` * Apply review comments * Update dependencies * Apply suggestions from code review Co-authored-by: Dmitry Markin <dmitry@markin.tech> * Apply review comments * Fix clippy * Update mockall * Apply review comment --------- Co-authored-by: Dmitry Markin <dmitry@markin.tech> * refactors runtime API logic to own pallet impl block * removes unrelated changes * Fixes cargo doc comments lint * fixes node cargo * fixes comment * restart ci * restart ci * restart ci --------- Co-authored-by: Anton <anton.kalyaev@gmail.com> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: parity-processbot <> Co-authored-by: Arkadiy Paronyan <arkady.paronyan@gmail.com> Co-authored-by: Muharem Ismailov <ismailov.m.h@gmail.com> Co-authored-by: Roman Useinov <roman.useinov@gmail.com> Co-authored-by: Anthony Alaribe <anthonyalaribe@gmail.com> Co-authored-by: Aaro Altonen <48052676+altonen@users.noreply.github.com> Co-authored-by: Dmitry Markin <dmitry@markin.tech>
1 parent 3e75d66 commit 3a0ef57

File tree

12 files changed

+222
-45
lines changed

12 files changed

+222
-45
lines changed

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ members = [
141141
"frame/staking",
142142
"frame/staking/reward-curve",
143143
"frame/staking/reward-fn",
144+
"frame/staking/runtime-api",
144145
"frame/state-trie-migration",
145146
"frame/sudo",
146147
"frame/root-offences",

bin/node/runtime/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pallet-session = { version = "4.0.0-dev", features = [ "historical" ], path = ".
9797
pallet-session-benchmarking = { version = "4.0.0-dev", path = "../../../frame/session/benchmarking", default-features = false, optional = true }
9898
pallet-staking = { version = "4.0.0-dev", default-features = false, path = "../../../frame/staking" }
9999
pallet-staking-reward-curve = { version = "4.0.0-dev", default-features = false, path = "../../../frame/staking/reward-curve" }
100+
pallet-staking-runtime-api = { version = "4.0.0-dev", default-features = false, path = "../../../frame/staking/runtime-api" }
100101
pallet-state-trie-migration = { version = "4.0.0-dev", default-features = false, path = "../../../frame/state-trie-migration" }
101102
pallet-scheduler = { version = "4.0.0-dev", default-features = false, path = "../../../frame/scheduler" }
102103
pallet-society = { version = "4.0.0-dev", default-features = false, path = "../../../frame/society" }
@@ -175,6 +176,7 @@ std = [
175176
"sp-runtime/std",
176177
"sp-staking/std",
177178
"pallet-staking/std",
179+
"pallet-staking-runtime-api/std",
178180
"pallet-state-trie-migration/std",
179181
"sp-session/std",
180182
"pallet-sudo/std",

bin/node/runtime/src/lib.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,8 +1986,22 @@ impl_runtime_apis! {
19861986
}
19871987

19881988
impl pallet_nomination_pools_runtime_api::NominationPoolsApi<Block, AccountId, Balance> for Runtime {
1989-
fn pending_rewards(member_account: AccountId) -> Balance {
1990-
NominationPools::pending_rewards(member_account).unwrap_or_default()
1989+
fn pending_rewards(who: AccountId) -> Balance {
1990+
NominationPools::api_pending_rewards(who).unwrap_or_default()
1991+
}
1992+
1993+
fn points_to_balance(pool_id: pallet_nomination_pools::PoolId, points: Balance) -> Balance {
1994+
NominationPools::api_points_to_balance(pool_id, points)
1995+
}
1996+
1997+
fn balance_to_points(pool_id: pallet_nomination_pools::PoolId, new_funds: Balance) -> Balance {
1998+
NominationPools::api_balance_to_points(pool_id, new_funds)
1999+
}
2000+
}
2001+
2002+
impl pallet_staking_runtime_api::StakingApi<Block, Balance> for Runtime {
2003+
fn nominations_quota(balance: Balance) -> u32 {
2004+
Staking::api_nominations_quota(balance)
19912005
}
19922006
}
19932007

frame/nomination-pools/runtime-api/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ targets = ["x86_64-unknown-linux-gnu"]
1616
codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] }
1717
sp-api = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/api" }
1818
sp-std = { version = "5.0.0", default-features = false, path = "../../../primitives/std" }
19+
pallet-nomination-pools = { version = "1.0.0", default-features = false, path = "../" }
1920

2021
[features]
2122
default = ["std"]
2223
std = [
2324
"codec/std",
2425
"sp-api/std",
2526
"sp-std/std",
27+
"pallet-nomination-pools/std",
2628
]

frame/nomination-pools/runtime-api/src/lib.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,22 @@
2121
#![cfg_attr(not(feature = "std"), no_std)]
2222

2323
use codec::Codec;
24+
use pallet_nomination_pools::PoolId;
2425

2526
sp_api::decl_runtime_apis! {
2627
/// Runtime api for accessing information about nomination pools.
2728
pub trait NominationPoolsApi<AccountId, Balance>
28-
where AccountId: Codec, Balance: Codec
29+
where
30+
AccountId: Codec,
31+
Balance: Codec,
2932
{
3033
/// Returns the pending rewards for the member that the AccountId was given for.
31-
fn pending_rewards(member: AccountId) -> Balance;
34+
fn pending_rewards(who: AccountId) -> Balance;
35+
36+
/// Returns the equivalent balance of `points` for a given pool.
37+
fn points_to_balance(pool_id: PoolId, points: Balance) -> Balance;
38+
39+
/// Returns the equivalent points of `new_funds` for a given pool.
40+
fn balance_to_points(pool_id: PoolId, new_funds: Balance) -> Balance;
3241
}
3342
}

frame/nomination-pools/src/lib.rs

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,24 +2142,6 @@ pub mod pallet {
21422142
}
21432143

21442144
impl<T: Config> Pallet<T> {
2145-
/// Returns the pending rewards for the specified `member_account`.
2146-
///
2147-
/// In the case of error, `None` is returned.
2148-
pub fn pending_rewards(member_account: T::AccountId) -> Option<BalanceOf<T>> {
2149-
if let Some(pool_member) = PoolMembers::<T>::get(member_account) {
2150-
if let Some((reward_pool, bonded_pool)) = RewardPools::<T>::get(pool_member.pool_id)
2151-
.zip(BondedPools::<T>::get(pool_member.pool_id))
2152-
{
2153-
let current_reward_counter = reward_pool
2154-
.current_reward_counter(pool_member.pool_id, bonded_pool.points)
2155-
.ok()?;
2156-
return pool_member.pending_rewards(current_reward_counter).ok()
2157-
}
2158-
}
2159-
2160-
None
2161-
}
2162-
21632145
/// The amount of bond that MUST REMAIN IN BONDED in ALL POOLS.
21642146
///
21652147
/// It is the responsibility of the depositor to put these funds into the pool initially. Upon
@@ -2579,6 +2561,50 @@ impl<T: Config> Pallet<T> {
25792561
}
25802562
}
25812563

2564+
impl<T: Config> Pallet<T> {
2565+
/// Returns the pending rewards for the specified `who` account.
2566+
///
2567+
/// In the case of error, `None` is returned. Used by runtime API.
2568+
pub fn api_pending_rewards(who: T::AccountId) -> Option<BalanceOf<T>> {
2569+
if let Some(pool_member) = PoolMembers::<T>::get(who) {
2570+
if let Some((reward_pool, bonded_pool)) = RewardPools::<T>::get(pool_member.pool_id)
2571+
.zip(BondedPools::<T>::get(pool_member.pool_id))
2572+
{
2573+
let current_reward_counter = reward_pool
2574+
.current_reward_counter(pool_member.pool_id, bonded_pool.points)
2575+
.ok()?;
2576+
return pool_member.pending_rewards(current_reward_counter).ok()
2577+
}
2578+
}
2579+
2580+
None
2581+
}
2582+
2583+
/// Returns the points to balance conversion for a specified pool.
2584+
///
2585+
/// If the pool ID does not exist, it returns 0 ratio points to balance. Used by runtime API.
2586+
pub fn api_points_to_balance(pool_id: PoolId, points: BalanceOf<T>) -> BalanceOf<T> {
2587+
if let Some(pool) = BondedPool::<T>::get(pool_id) {
2588+
pool.points_to_balance(points)
2589+
} else {
2590+
Zero::zero()
2591+
}
2592+
}
2593+
2594+
/// Returns the equivalent `new_funds` balance to point conversion for a specified pool.
2595+
///
2596+
/// If the pool ID does not exist, returns 0 ratio balance to points. Used by runtime API.
2597+
pub fn api_balance_to_points(pool_id: PoolId, new_funds: BalanceOf<T>) -> BalanceOf<T> {
2598+
if let Some(pool) = BondedPool::<T>::get(pool_id) {
2599+
let bonded_balance =
2600+
T::Staking::active_stake(&pool.bonded_account()).unwrap_or(Zero::zero());
2601+
Pallet::<T>::balance_to_point(bonded_balance, pool.points, new_funds)
2602+
} else {
2603+
Zero::zero()
2604+
}
2605+
}
2606+
}
2607+
25822608
impl<T: Config> OnStakerSlash<T::AccountId, BalanceOf<T>> for Pallet<T> {
25832609
fn on_slash(
25842610
pool_account: &T::AccountId,

frame/nomination-pools/src/tests.rs

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,46 @@ mod bonded_pool {
195195
})
196196
}
197197

198+
#[test]
199+
fn api_points_to_balance_works() {
200+
ExtBuilder::default().build_and_execute(|| {
201+
assert!(BondedPool::<Runtime>::get(1).is_some());
202+
assert_eq!(Pallet::<Runtime>::api_points_to_balance(1, 10), 10);
203+
204+
// slash half of the pool's balance. expected result of `fn api_points_to_balance`
205+
// to be 1/2 of the pool's balance.
206+
StakingMock::set_bonded_balance(
207+
default_bonded_account(),
208+
Pools::depositor_min_bond() / 2,
209+
);
210+
assert_eq!(Pallet::<Runtime>::api_points_to_balance(1, 10), 5);
211+
212+
// if pool does not exist, points to balance ratio is 0.
213+
assert_eq!(BondedPool::<Runtime>::get(2), None);
214+
assert_eq!(Pallet::<Runtime>::api_points_to_balance(2, 10), 0);
215+
})
216+
}
217+
218+
#[test]
219+
fn api_balance_to_points_works() {
220+
ExtBuilder::default().build_and_execute(|| {
221+
assert_eq!(Pallet::<Runtime>::api_balance_to_points(1, 0), 0);
222+
assert_eq!(Pallet::<Runtime>::api_balance_to_points(1, 10), 10);
223+
224+
// slash half of the pool's balance. expect result of `fn api_balance_to_points`
225+
// to be 2 * of the balance to add to the pool.
226+
StakingMock::set_bonded_balance(
227+
default_bonded_account(),
228+
Pools::depositor_min_bond() / 2,
229+
);
230+
assert_eq!(Pallet::<Runtime>::api_balance_to_points(1, 10), 20);
231+
232+
// if pool does not exist, balance to points ratio is 0.
233+
assert_eq!(BondedPool::<Runtime>::get(2), None);
234+
assert_eq!(Pallet::<Runtime>::api_points_to_balance(2, 10), 0);
235+
})
236+
}
237+
198238
#[test]
199239
fn ok_to_join_with_works() {
200240
ExtBuilder::default().build_and_execute(|| {
@@ -1305,51 +1345,51 @@ mod claim_payout {
13051345
ExtBuilder::default().build_and_execute(|| {
13061346
let ed = Balances::minimum_balance();
13071347

1308-
assert_eq!(Pools::pending_rewards(10), Some(0));
1348+
assert_eq!(Pools::api_pending_rewards(10), Some(0));
13091349
Balances::mutate_account(&default_reward_account(), |f| f.free += 30).unwrap();
1310-
assert_eq!(Pools::pending_rewards(10), Some(30));
1311-
assert_eq!(Pools::pending_rewards(20), None);
1350+
assert_eq!(Pools::api_pending_rewards(10), Some(30));
1351+
assert_eq!(Pools::api_pending_rewards(20), None);
13121352

13131353
Balances::make_free_balance_be(&20, ed + 10);
13141354
assert_ok!(Pools::join(RuntimeOrigin::signed(20), 10, 1));
13151355

1316-
assert_eq!(Pools::pending_rewards(10), Some(30));
1317-
assert_eq!(Pools::pending_rewards(20), Some(0));
1356+
assert_eq!(Pools::api_pending_rewards(10), Some(30));
1357+
assert_eq!(Pools::api_pending_rewards(20), Some(0));
13181358

13191359
Balances::mutate_account(&default_reward_account(), |f| f.free += 100).unwrap();
13201360

1321-
assert_eq!(Pools::pending_rewards(10), Some(30 + 50));
1322-
assert_eq!(Pools::pending_rewards(20), Some(50));
1323-
assert_eq!(Pools::pending_rewards(30), None);
1361+
assert_eq!(Pools::api_pending_rewards(10), Some(30 + 50));
1362+
assert_eq!(Pools::api_pending_rewards(20), Some(50));
1363+
assert_eq!(Pools::api_pending_rewards(30), None);
13241364

13251365
Balances::make_free_balance_be(&30, ed + 10);
13261366
assert_ok!(Pools::join(RuntimeOrigin::signed(30), 10, 1));
13271367

1328-
assert_eq!(Pools::pending_rewards(10), Some(30 + 50));
1329-
assert_eq!(Pools::pending_rewards(20), Some(50));
1330-
assert_eq!(Pools::pending_rewards(30), Some(0));
1368+
assert_eq!(Pools::api_pending_rewards(10), Some(30 + 50));
1369+
assert_eq!(Pools::api_pending_rewards(20), Some(50));
1370+
assert_eq!(Pools::api_pending_rewards(30), Some(0));
13311371

13321372
Balances::mutate_account(&default_reward_account(), |f| f.free += 60).unwrap();
13331373

1334-
assert_eq!(Pools::pending_rewards(10), Some(30 + 50 + 20));
1335-
assert_eq!(Pools::pending_rewards(20), Some(50 + 20));
1336-
assert_eq!(Pools::pending_rewards(30), Some(20));
1374+
assert_eq!(Pools::api_pending_rewards(10), Some(30 + 50 + 20));
1375+
assert_eq!(Pools::api_pending_rewards(20), Some(50 + 20));
1376+
assert_eq!(Pools::api_pending_rewards(30), Some(20));
13371377

13381378
// 10 should claim 10, 20 should claim nothing.
13391379
assert_ok!(Pools::claim_payout(RuntimeOrigin::signed(10)));
1340-
assert_eq!(Pools::pending_rewards(10), Some(0));
1341-
assert_eq!(Pools::pending_rewards(20), Some(50 + 20));
1342-
assert_eq!(Pools::pending_rewards(30), Some(20));
1380+
assert_eq!(Pools::api_pending_rewards(10), Some(0));
1381+
assert_eq!(Pools::api_pending_rewards(20), Some(50 + 20));
1382+
assert_eq!(Pools::api_pending_rewards(30), Some(20));
13431383

13441384
assert_ok!(Pools::claim_payout(RuntimeOrigin::signed(20)));
1345-
assert_eq!(Pools::pending_rewards(10), Some(0));
1346-
assert_eq!(Pools::pending_rewards(20), Some(0));
1347-
assert_eq!(Pools::pending_rewards(30), Some(20));
1385+
assert_eq!(Pools::api_pending_rewards(10), Some(0));
1386+
assert_eq!(Pools::api_pending_rewards(20), Some(0));
1387+
assert_eq!(Pools::api_pending_rewards(30), Some(20));
13481388

13491389
assert_ok!(Pools::claim_payout(RuntimeOrigin::signed(30)));
1350-
assert_eq!(Pools::pending_rewards(10), Some(0));
1351-
assert_eq!(Pools::pending_rewards(20), Some(0));
1352-
assert_eq!(Pools::pending_rewards(30), Some(0));
1390+
assert_eq!(Pools::api_pending_rewards(10), Some(0));
1391+
assert_eq!(Pools::api_pending_rewards(20), Some(0));
1392+
assert_eq!(Pools::api_pending_rewards(30), Some(0));
13531393
});
13541394
}
13551395

frame/staking/runtime-api/Cargo.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
name = "pallet-staking-runtime-api"
3+
version = "4.0.0-dev"
4+
authors = ["Parity Technologies <admin@parity.io>"]
5+
edition = "2021"
6+
license = "Apache-2.0"
7+
homepage = "https://substrate.io"
8+
repository = "https://github.com/paritytech/substrate/"
9+
description = "RPC runtime API for transaction payment FRAME pallet"
10+
readme = "README.md"
11+
12+
[package.metadata.docs.rs]
13+
targets = ["x86_64-unknown-linux-gnu"]
14+
15+
[dependencies]
16+
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
17+
sp-api = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/api" }
18+
19+
[features]
20+
default = ["std"]
21+
std = [
22+
"codec/std",
23+
"sp-api/std",
24+
]

frame/staking/runtime-api/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Runtime API definition for the staking pallet.
2+
3+
License: Apache-2.0

0 commit comments

Comments
 (0)