Remove old accepted design proposals (#5951)
* remove passive-stake-delegation-and-rewards from summary * Delete passive-stake-delegation-and-rewards.md
This commit is contained in:
parent
31a276b628
commit
64f23ab26a
|
@ -84,7 +84,6 @@
|
|||
- [Tower BFT](tower-bft.md)
|
||||
- [Leader-to-Leader Transition](leader-leader-transition.md)
|
||||
- [Leader-to-Validator Transition](leader-validator-transition.md)
|
||||
- [Passive Stake Delegation and Rewards](passive-stake-delegation-and-rewards.md)
|
||||
- [Persistent Account Storage](persistent-account-storage.md)
|
||||
- [Reliable Vote Transmission](reliable-vote-transmission.md)
|
||||
- [Repair Service](repair-service.md)
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
# Stake Delegation and Reward
|
||||
|
||||
This design proposal focuses on the software architecture for the on-chain
|
||||
voting and staking programs. Incentives for staking is covered in [staking
|
||||
rewards](staking-rewards.md).
|
||||
|
||||
The current architecture requires a vote for each delegated stake from the
|
||||
validator, and therefore does not scale to allow replicator clients to
|
||||
automatically delegate their rewards.
|
||||
|
||||
The design proposes a new set of programs for voting and stake delegation, The
|
||||
proposed programs allow many stake accounts to passively earn rewards with a
|
||||
single validator vote without permission or active involvement from the
|
||||
validator.
|
||||
|
||||
## Current Design Problems
|
||||
|
||||
In the current design each staker creates their own VoteState, and assigns a
|
||||
**delegate** in the VoteState that can submit votes. Since the validator has to
|
||||
actively vote for each stake delegated to it, validators can censor stakes by
|
||||
not voting for them.
|
||||
|
||||
The number of votes is equal to the number of stakers, and not the number of
|
||||
validators. Replicator clients are expected to delegate their replication
|
||||
rewards as they are earned, and therefore the number of stakes is expected to be
|
||||
large compared to the number of validators in a long running cluster.
|
||||
|
||||
## Proposed changes to the current design.
|
||||
|
||||
The general idea is that instead of the staker, the validator will own the
|
||||
VoteState program. In this proposal the VoteState program is there to track
|
||||
validator votes, count validator generated credits and to provide any
|
||||
additional validator specific state. The VoteState program is not aware of any
|
||||
stakes delegated to it, and has no staking weight.
|
||||
|
||||
The rewards generated are proportional to the amount of lamports staked. In
|
||||
this proposal stake state is stored as part of the StakeState program. This
|
||||
program is owned by the staker only. Lamports stored in this program are the
|
||||
stake. Unlike the current design, this program contains a new field to indicate
|
||||
which VoteState program the stake is delegated to.
|
||||
|
||||
### VoteState
|
||||
|
||||
VoteState is the current state of all the votes the **delegate** has submitted
|
||||
to the bank. VoteState contains the following state information:
|
||||
|
||||
* votes - The submitted votes data structure.
|
||||
|
||||
* credits - The total number of rewards this vote program has generated over its
|
||||
lifetime.
|
||||
|
||||
* root\_slot - The last slot to reach the full lockout commitment necessary for
|
||||
rewards.
|
||||
|
||||
* commission - The commission taken by this VoteState for any rewards claimed by
|
||||
staker's StakeState accounts. This is the percentage ceiling of the reward.
|
||||
|
||||
* Account::lamports - The accumulated lamports from the commission. These do not
|
||||
count as stakes.
|
||||
|
||||
* `authorized_vote_signer` - Only this identity is authorized to submit votes, and
|
||||
this field can only modified by this entity
|
||||
|
||||
### VoteInstruction::Initialize
|
||||
|
||||
* `account[0]` - RW - The VoteState
|
||||
`VoteState::authorized_vote_signer` is initialized to `account[0]`
|
||||
other VoteState members defaulted
|
||||
|
||||
### VoteInstruction::AuthorizeVoteSigner(Pubkey)
|
||||
|
||||
* `account[0]` - RW - The VoteState
|
||||
`VoteState::authorized_vote_signer` is set to to `Pubkey`, instruction must by
|
||||
signed by Pubkey
|
||||
|
||||
|
||||
### StakeState
|
||||
|
||||
A StakeState takes one of two forms, StakeState::Stake and StakeState::MiningPool.
|
||||
|
||||
### StakeState::Stake
|
||||
|
||||
Stake is the current delegation preference of the **staker**. Stake
|
||||
contains the following state information:
|
||||
|
||||
* `voter_pubkey` - The pubkey of the VoteState instance the lamports are
|
||||
delegated to.
|
||||
|
||||
* `credits_observed` - The total credits claimed over the lifetime of the
|
||||
program.
|
||||
|
||||
* `stake` - The actual activated stake.
|
||||
|
||||
* Account::lamports - Lamports available for staking, including any earned as rewards.
|
||||
|
||||
|
||||
### StakeState::MiningPool
|
||||
|
||||
There are two approaches to the mining pool. The bank could allow the
|
||||
StakeState program to bypass the token balance check, or a program representing
|
||||
the mining pool could run on the network. To avoid a single network wide lock,
|
||||
the pool can be split into several mining pools. This design focuses on using a
|
||||
StakeState::MiningPool as the cluster wide mining pools.
|
||||
|
||||
* 256 StakeState::MiningPool are initialized, each with 1/256 number of mining pool
|
||||
tokens stored as `Account::lamports`.
|
||||
|
||||
The stakes and the MiningPool are accounts that are owned by the same `Stake`
|
||||
program.
|
||||
|
||||
### StakeInstruction::DelegateStake(stake)
|
||||
|
||||
* `account[0]` - RW - The StakeState::Stake instance.
|
||||
`StakeState::Stake::credits_observed` is initialized to `VoteState::credits`.
|
||||
`StakeState::Stake::voter_pubkey` is initialized to `account[1]`
|
||||
`StakeState::Stake::stake` is initialized to `stake`, as long as it's less than account[0].lamports
|
||||
|
||||
* `account[1]` - R - The VoteState instance.
|
||||
|
||||
### StakeInstruction::RedeemVoteCredits
|
||||
|
||||
The VoteState program and the StakeState programs maintain a lifetime counter
|
||||
of total rewards generated and claimed. Therefore an explicit `Clear`
|
||||
instruction is not necessary. When claiming rewards, the total lamports
|
||||
deposited into the StakeState and as validator commission is proportional to
|
||||
`VoteState::credits - StakeState::credits_observed`.
|
||||
|
||||
|
||||
* `account[0]` - RW - The StakeState::MiningPool instance that will fulfill the
|
||||
reward.
|
||||
* `account[1]` - RW - The StakeState::Stake instance that is redeeming votes
|
||||
credits.
|
||||
* `account[2]` - R - The VoteState instance, must be the same as
|
||||
`StakeState::voter_pubkey`
|
||||
|
||||
Reward is payed out for the difference between `VoteState::credits` to
|
||||
`StakeState::Delgate.credits_observed`, and `credits_observed` is updated to
|
||||
`VoteState::credits`. The commission is deposited into the `VoteState` token
|
||||
balance, and the reward is deposited to the `StakeState::Stake` token balance. The
|
||||
reward and the commission is weighted by the `StakeState::lamports` divided by total lamports staked.
|
||||
|
||||
The Staker or the owner of the Stake program sends a transaction with this
|
||||
instruction to claim the reward.
|
||||
|
||||
Any random MiningPool can be used to redeem the credits.
|
||||
|
||||
```rust,ignore
|
||||
let credits_to_claim = vote_state.credits - stake_state.credits_observed;
|
||||
stake_state.credits_observed = vote_state.credits;
|
||||
```
|
||||
|
||||
`credits_to_claim` is used to compute the reward and commission, and
|
||||
`StakeState::Stake::credits_observed` is updated to the latest
|
||||
`VoteState::credits` value.
|
||||
|
||||
### Collecting network fees into the MiningPool
|
||||
|
||||
At the end of the block, before the bank is frozen, but after it processed all
|
||||
the transactions for the block, a virtual instruction is executed to collect
|
||||
the transaction fees.
|
||||
|
||||
* A portion of the fees are deposited into the leader's account.
|
||||
* A portion of the fees are deposited into the smallest StakeState::MiningPool
|
||||
account.
|
||||
|
||||
### Benefits
|
||||
|
||||
* Single vote for all the stakers.
|
||||
|
||||
* Clearing of the credit variable is not necessary for claiming rewards.
|
||||
|
||||
* Each delegated stake can claim its rewards independently.
|
||||
|
||||
* Commission for the work is deposited when a reward is claimed by the delegated
|
||||
stake.
|
||||
|
||||
This proposal would benefit from the `read-only` accounts proposal to allow for
|
||||
many rewards to be claimed concurrently.
|
||||
|
||||
## Passive Delegation
|
||||
|
||||
Any number of instances of StakeState::Stake programs can delegate to a single
|
||||
VoteState program without an interactive action from the identity controlling
|
||||
the VoteState program or submitting votes to the program.
|
||||
|
||||
The total stake allocated to a VoteState program can be calculated by the sum of
|
||||
all the StakeState programs that have the VoteState pubkey as the
|
||||
`StakeState::Stake::voter_pubkey`.
|
||||
|
||||
## Example Callflow
|
||||
|
||||
<img alt="Passive Staking Callflow" src="img/passive-staking-callflow.svg" class="center"/>
|
||||
|
||||
## Future work
|
||||
|
||||
Validators may want to split the stake delegated to them amongst many validator
|
||||
nodes since stake is used as weight in the network control and data planes. One
|
||||
way to implement this would be for the StakeState to delegate to a pool of
|
||||
validators instead of a single one.
|
||||
|
||||
Instead of a single `vote_pubkey` and `credits_observed` entry in the StakeState
|
||||
program, the program can be initialized with a vector of tuples.
|
||||
|
||||
```rust,ignore
|
||||
Voter {
|
||||
voter_pubkey: Pubkey,
|
||||
credits_observed: u64,
|
||||
weight: u8,
|
||||
}
|
||||
```
|
||||
|
||||
* voters: Vec<Voter> - Array of VoteState accounts that are voting rewards with
|
||||
this stake.
|
||||
|
||||
A StakeState program would claim a fraction of the reward from each voter in
|
||||
the `voters` array, and each voter would be delegated a fraction of the stake.
|
Loading…
Reference in New Issue