Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduces: Delegated Staking Pallet #3904

Merged
merged 114 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from 84 commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
dda12d4
add ability to super bond to staking
Ank4n Mar 29, 2024
802784c
some comments
Ank4n Mar 29, 2024
d2b680e
fix tests
Ank4n Mar 29, 2024
646c7f4
tests
Ank4n Mar 31, 2024
bc92a19
fix naming
Ank4n Mar 31, 2024
2528da7
fmt
Ank4n Mar 31, 2024
4ddcb77
Merge branch 'master' into ankan/01-prep-staking-for-delegation
Ank4n Mar 31, 2024
0cbec7d
delegated staking without pool tests
Ank4n Mar 30, 2024
e6152ed
fix clippy errors
Ank4n Mar 30, 2024
a91a417
remove pool dependency
Ank4n Mar 30, 2024
d6069a4
fix imports
Ank4n Mar 30, 2024
3e37916
taplo fmt toml files
Ank4n Mar 30, 2024
79c4a86
taplo refmt
Ank4n Mar 30, 2024
35c5e80
remove calls
Ank4n Mar 31, 2024
c5a5d32
fix docs
Ank4n Mar 31, 2024
f82b349
rename storage Delegatees to Agents
Ank4n Mar 31, 2024
b550031
rename all delegatee to agent
Ank4n Mar 31, 2024
b87fc08
remove fixme
Ank4n Apr 1, 2024
bfd3434
Make delegation interface independent
Ank4n Apr 2, 2024
7104faf
move reward account check to caller
Ank4n Apr 3, 2024
aed693c
virtual staker cannot bond again
Ank4n Apr 3, 2024
989bc50
release all becomes migrate_to_virtual_staker
Ank4n Apr 3, 2024
731f5a1
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 3, 2024
4226b9b
fix function call
Ank4n Apr 3, 2024
6f05a52
add test
Ank4n Apr 3, 2024
3d0e0ba
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 3, 2024
4d00b04
remove benchmarking file
Ank4n Apr 3, 2024
264f71a
small refactors
Ank4n Apr 3, 2024
f9a52f1
fmt
Ank4n Apr 3, 2024
1d58711
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 3, 2024
7bf4d34
remove mod bench
Ank4n Apr 3, 2024
40a5132
add pool migration function to Delegation Interface
Ank4n Apr 3, 2024
e8e498c
add migrate delegation to delegation interface
Ank4n Apr 3, 2024
5ece9c7
dec provider if agent is killed
Ank4n Apr 3, 2024
23c65c4
doc updates
Ank4n Apr 4, 2024
4f441d5
doc updates
Ank4n Apr 4, 2024
58b50c9
test for bonders cannot virtual bond
Ank4n Apr 4, 2024
b946c4a
virtual nominators receive rewards
Ank4n Apr 4, 2024
0aa9006
virtual nominator slashing test
Ank4n Apr 4, 2024
d242356
fmt
Ank4n Apr 4, 2024
4fcafd0
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 4, 2024
6bd5e2c
fmt
Ank4n Apr 4, 2024
2fb04c5
found a bug while unbonding
Ank4n Apr 4, 2024
7962aac
test for unclaimed withdrawals
Ank4n Apr 4, 2024
8bd3bc3
fix clippy error
Ank4n Apr 4, 2024
11da089
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 4, 2024
15a9fc6
fix clippy
Ank4n Apr 4, 2024
1a34d28
fix compile
Ank4n Apr 4, 2024
2a75dc5
fix defensive trigger
Ank4n Apr 4, 2024
0bf4dba
pool does not have to transfer ed to proxy delegator
Ank4n Apr 4, 2024
7800446
don't check for min balance when delegating to agent. pool should che…
Ank4n Apr 9, 2024
84fb918
don't check for min balance
Ank4n Apr 9, 2024
e55cea3
fix imports
Ank4n Apr 9, 2024
fbccd0f
Merge branch 'master' into ankan/01-prep-staking-for-delegation
Ank4n Apr 9, 2024
0c83496
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 9, 2024
765278a
prdoc
Ank4n Apr 9, 2024
e46b01b
prdoc
Ank4n Apr 9, 2024
0e41b01
Merge branch 'master' into ankan/01-prep-staking-for-delegation
Ank4n Apr 10, 2024
67a541c
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 10, 2024
444dc76
add migrate to direct staker for testing
Ank4n Apr 11, 2024
9e5bdfa
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 11, 2024
b1312d7
minor refactor
Ank4n Apr 11, 2024
9079d82
add migrate to direct staker for testing
Ank4n Apr 11, 2024
616dfa7
doc comment
Ank4n Apr 11, 2024
6bcf0ab
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 11, 2024
afe8c87
pr feedback
Ank4n Apr 11, 2024
e7d65e2
add try state checks for virtual ledger
Ank4n Apr 11, 2024
474c1de
fmt
Ank4n Apr 11, 2024
6a019d6
Update substrate/frame/delegated-staking/src/lib.rs
kianenigma Apr 12, 2024
8d481a6
Apply suggestions from code review
Ank4n Apr 16, 2024
6940f88
Merge branch 'master' into ankan/01-prep-staking-for-delegation
Ank4n Apr 17, 2024
a884846
safe maths
Ank4n Apr 17, 2024
d4633c2
fix docs based on feedback
Ank4n Apr 17, 2024
c013cde
rename StakingUnsafe to StakingUnchecked
Ank4n Apr 17, 2024
b2588a5
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 17, 2024
ac3cadf
use static mutate
Ank4n Apr 17, 2024
8cee25c
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 17, 2024
0537e9c
Rename StakingUnsafe to StakingUnchecked
Ank4n Apr 17, 2024
fb5d64c
pr feedbacks
Ank4n Apr 17, 2024
bb93c8c
pr feedbacks
Ank4n Apr 17, 2024
cba250e
feedbacks
Ank4n Apr 17, 2024
9897437
feedback
Ank4n Apr 17, 2024
09d3359
Merge branch 'master' into ankan/01-prep-staking-for-delegation
Ank4n Apr 18, 2024
e75c2e6
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 18, 2024
e31866e
inline locking
Ank4n Apr 19, 2024
078cf5f
optimize stash kill
Ank4n Apr 19, 2024
3790a40
Merge branch 'master' into ankan/01-prep-staking-for-delegation
Ank4n Apr 19, 2024
796c848
Merge branch 'ankan/01-prep-staking-for-delegation' into ankan/02-pal…
Ank4n Apr 19, 2024
666be52
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n Apr 20, 2024
be76a6b
pr feedbacks
Ank4n Apr 22, 2024
c6070d8
check stash is killed before cleaning up agent
Ank4n Apr 22, 2024
886a1a7
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n Apr 22, 2024
a69d620
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n Apr 24, 2024
4b2daa2
withdraw delegation requires num slashing spans
Ank4n Apr 24, 2024
0e17037
separate trait for migration
Ank4n Apr 24, 2024
4e3b8cd
add a separate slash reward fraction for agent slashing
Ank4n Apr 24, 2024
b1b1e1d
better docs pr feedback
Ank4n Apr 25, 2024
1e6cdad
rename claim delegation to migrate delegation
Ank4n Apr 25, 2024
3cef018
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n Apr 25, 2024
24d05ad
fix docs
Ank4n Apr 25, 2024
bd56eb3
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n May 2, 2024
d4ef271
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n May 7, 2024
fe0b657
fix migration, move free funds as well when migrating a nominator to …
Ank4n May 7, 2024
464cea0
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n May 13, 2024
7782cab
pr feedbacks
Ank4n May 13, 2024
6e3045f
use system events for pallet
Ank4n May 13, 2024
159d1bf
run try state for staking
Ank4n May 13, 2024
52ae957
fmt
Ank4n May 13, 2024
77eb34c
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n May 13, 2024
9e035ba
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n May 14, 2024
78fac9e
initial release version for delegate staking pallet
Ank4n May 15, 2024
3264782
initial version set to 1.0.0 and bump as patch
Ank4n May 15, 2024
cd5eb94
add other pallets affected in prdoc
Ank4n May 15, 2024
8314177
Merge branch 'master' into ankan/02-pallet-delegated-staking
Ank4n May 15, 2024
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
22 changes: 22 additions & 0 deletions 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 @@ -328,6 +328,7 @@ members = [
"substrate/frame/contracts/uapi",
"substrate/frame/conviction-voting",
"substrate/frame/core-fellowship",
"substrate/frame/delegated-staking",
"substrate/frame/democracy",
"substrate/frame/election-provider-multi-phase",
"substrate/frame/election-provider-multi-phase/test-staking-e2e",
Expand Down
14 changes: 14 additions & 0 deletions prdoc/pr_3889.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json

title: Allow privileged virtual bond into pallet Staking

doc:
- audience: Runtime Dev
description: |
Introduces a new low level API to allow privileged virtual bond into pallet Staking. This allows other pallets
to stake funds into staking pallet while managing the fund lock and unlocking process themselves.

crates:
- name: pallet-staking

15 changes: 15 additions & 0 deletions prdoc/pr_3904.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json

title: Introduce pallet-delegated-staking

doc:
- audience: Runtime Dev
description: |
Adds a new pallet `delegated-staking` that allows delegators to delegate their funds to agents who can stake
these funds on behalf of them. This would be used by Nomination Pools to migrate into a delegation staking based
pool.

crates:
- name: pallet-delegated-staking

69 changes: 69 additions & 0 deletions substrate/frame/delegated-staking/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
[package]
name = "pallet-delegated-staking"
version = "4.0.0-dev"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
homepage = "https://substrate.io"
repository.workspace = true
description = "FRAME delegated staking pallet"

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

[dependencies]
codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] }
frame-support = { path = "../support", default-features = false }
frame-system = { path = "../system", default-features = false }
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
sp-std = { path = "../../primitives/std", default-features = false }
sp-runtime = { path = "../../primitives/runtime", default-features = false }
sp-staking = { path = "../../primitives/staking", default-features = false }

[dev-dependencies]
sp-core = { path = "../../primitives/core" }
sp-io = { path = "../../primitives/io" }
substrate-test-utils = { path = "../../test-utils" }
sp-tracing = { path = "../../primitives/tracing" }
pallet-staking = { path = "../staking" }
pallet-balances = { path = "../balances" }
pallet-timestamp = { path = "../timestamp" }
pallet-staking-reward-curve = { path = "../staking/reward-curve" }
frame-election-provider-support = { path = "../election-provider-support", default-features = false }

[features]
default = ["std"]
std = [
"codec/std",
"frame-election-provider-support/std",
"frame-support/std",
"frame-system/std",
"pallet-balances/std",
"pallet-staking/std",
"pallet-timestamp/std",
"scale-info/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-staking/std",
"sp-std/std",
]
runtime-benchmarks = [
"frame-election-provider-support/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-staking/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"sp-staking/runtime-benchmarks",
]
try-runtime = [
"frame-election-provider-support/try-runtime",
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-balances/try-runtime",
"pallet-staking/try-runtime",
"pallet-timestamp/try-runtime",
"sp-runtime/try-runtime",
]
144 changes: 144 additions & 0 deletions substrate/frame/delegated-staking/src/impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program 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.

// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.

//! Implementations of public traits, namely [`DelegationInterface`] and [`OnStakingUpdate`].

use super::*;
use sp_staking::{DelegationInterface, OnStakingUpdate};

impl<T: Config> DelegationInterface for Pallet<T> {
type Balance = BalanceOf<T>;
type AccountId = T::AccountId;

/// Effective balance of the `Agent` account.
fn agent_balance(who: &Self::AccountId) -> Self::Balance {
Agent::<T>::get(who)
.map(|agent| agent.ledger.effective_balance())
.unwrap_or_default()
}

fn delegator_balance(delegator: &Self::AccountId) -> Self::Balance {
Delegation::<T>::get(delegator).map(|d| d.amount).unwrap_or_default()
}

/// Delegate funds to an `Agent`.
fn delegate(
who: &Self::AccountId,
agent: &Self::AccountId,
reward_account: &Self::AccountId,
amount: Self::Balance,
) -> DispatchResult {
Pallet::<T>::register_agent(
RawOrigin::Signed(agent.clone()).into(),
reward_account.clone(),
)?;

// Delegate the funds from who to the `Agent` account.
Pallet::<T>::delegate_to_agent(RawOrigin::Signed(who.clone()).into(), agent.clone(), amount)
}

/// Add more delegation to the `Agent` account.
fn delegate_extra(
who: &Self::AccountId,
agent: &Self::AccountId,
amount: Self::Balance,
) -> DispatchResult {
Pallet::<T>::delegate_to_agent(RawOrigin::Signed(who.clone()).into(), agent.clone(), amount)
}

/// Withdraw delegation of `delegator` to `Agent`.
///
/// If there are funds in `Agent` account that can be withdrawn, then those funds would be
/// unlocked/released in the delegator's account.
fn withdraw_delegation(
delegator: &Self::AccountId,
agent: &Self::AccountId,
amount: Self::Balance,
) -> DispatchResult {
// fixme(ank4n): Can this not require slashing spans?
Pallet::<T>::release_delegation(
RawOrigin::Signed(agent.clone()).into(),
delegator.clone(),
amount,
0,
)
}

/// Returns true if the `Agent` have any slash pending to be applied.
fn has_pending_slash(agent: &Self::AccountId) -> bool {
Agent::<T>::get(agent)
.map(|d| !d.ledger.pending_slash.is_zero())
.unwrap_or(false)
}

fn delegator_slash(
agent: &Self::AccountId,
delegator: &Self::AccountId,
value: Self::Balance,
maybe_reporter: Option<Self::AccountId>,
) -> sp_runtime::DispatchResult {
Pallet::<T>::do_slash(agent.clone(), delegator.clone(), value, maybe_reporter)
}

fn migrate_nominator_to_agent(
agent: &Self::AccountId,
reward_account: &Self::AccountId,
) -> DispatchResult {
Pallet::<T>::migrate_to_agent(
RawOrigin::Signed(agent.clone()).into(),
reward_account.clone(),
)
}

fn migrate_delegation(
agent: &Self::AccountId,
delegator: &Self::AccountId,
value: Self::Balance,
) -> DispatchResult {
Pallet::<T>::claim_delegation(
RawOrigin::Signed(agent.clone()).into(),
delegator.clone(),
value,
)
}
}

impl<T: Config> OnStakingUpdate<T::AccountId, BalanceOf<T>> for Pallet<T> {
fn on_slash(
who: &T::AccountId,
_slashed_active: BalanceOf<T>,
_slashed_unlocking: &sp_std::collections::btree_map::BTreeMap<EraIndex, BalanceOf<T>>,
slashed_total: BalanceOf<T>,
) {
<Agents<T>>::mutate(who, |maybe_register| match maybe_register {
// if existing agent, register the slashed amount as pending slash.
Some(register) => register.pending_slash.saturating_accrue(slashed_total),
None => {
// nothing to do
},
});
}

fn on_withdraw(stash: &T::AccountId, amount: BalanceOf<T>) {
// if there is a withdraw to the agent, then add it to the unclaimed withdrawals.
let _ = Agent::<T>::get(stash)
// can't do anything if there is an overflow error. Just raise a defensive error.
.and_then(|agent| agent.add_unclaimed_withdraw(amount).defensive())
.map(|agent| agent.save());
}
}
Loading
Loading