update book with stake stuff (#4893)
This commit is contained in:
		@@ -20,7 +20,7 @@ stakes delegated to it and has no staking weight.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
A separate Stake account (created by a staker) names a Vote account to which the
 | 
					A separate Stake account (created by a staker) names a Vote account to which the
 | 
				
			||||||
stake is delegated.  Rewards generated are proportional to the amount of
 | 
					stake is delegated.  Rewards generated are proportional to the amount of
 | 
				
			||||||
lamports staked.  The Stake account is owned by the staker only.  Lamports
 | 
					lamports staked.  The Stake account is owned by the staker only.  Some portion of the lamports
 | 
				
			||||||
stored in this account are the stake.
 | 
					stored in this account are the stake.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Passive Delegation
 | 
					## Passive Delegation
 | 
				
			||||||
@@ -31,7 +31,7 @@ the Vote account or submitting votes to the account.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
The total stake allocated to a Vote account can be calculated by the sum of
 | 
					The total stake allocated to a Vote account can be calculated by the sum of
 | 
				
			||||||
all the Stake accounts that have the Vote account pubkey as the
 | 
					all the Stake accounts that have the Vote account pubkey as the
 | 
				
			||||||
`StakeState::Delegate::voter_pubkey`.
 | 
					`StakeState::Stake::voter_pubkey`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Vote and Stake accounts
 | 
					## Vote and Stake accounts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -46,15 +46,15 @@ program that its delegate has participated in validating the ledger.
 | 
				
			|||||||
VoteState is the current state of all the votes the validator has submitted to
 | 
					VoteState is the current state of all the votes the validator has submitted to
 | 
				
			||||||
the network. VoteState contains the following state information:
 | 
					the network. VoteState contains the following state information:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* votes - The submitted votes data structure.
 | 
					* `votes` - The submitted votes data structure.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* credits - The total number of rewards this vote program has generated over its
 | 
					* `credits` - The total number of rewards this vote program has generated over its
 | 
				
			||||||
lifetime.
 | 
					lifetime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* root\_slot - The last slot to reach the full lockout commitment necessary for
 | 
					* `root_slot` - The last slot to reach the full lockout commitment necessary for
 | 
				
			||||||
rewards.
 | 
					rewards.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* commission - The commission taken by this VoteState for any rewards claimed by
 | 
					* `commission` - The commission taken by this VoteState for any rewards claimed by
 | 
				
			||||||
staker's Stake accounts.  This is the percentage ceiling of the reward.
 | 
					staker's Stake accounts.  This is the percentage ceiling of the reward.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Account::lamports - The accumulated lamports from the commission.  These do not
 | 
					* Account::lamports - The accumulated lamports from the commission.  These do not
 | 
				
			||||||
@@ -71,8 +71,12 @@ count as stakes.
 | 
				
			|||||||
### VoteInstruction::AuthorizeVoteSigner(Pubkey)
 | 
					### VoteInstruction::AuthorizeVoteSigner(Pubkey)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `account[0]` - RW - The VoteState
 | 
					* `account[0]` - RW - The VoteState
 | 
				
			||||||
  `VoteState::authorized_vote_signer` is set to to `Pubkey`, instruction must by
 | 
					  `VoteState::authorized_vote_signer` is set to to `Pubkey`, the transaction must by
 | 
				
			||||||
   signed by Pubkey
 | 
					   signed by the Vote account's current `authorized_vote_signer`.  <br>
 | 
				
			||||||
 | 
					   `VoteInstruction::AuthorizeVoter` allows a staker to choose a signing service
 | 
				
			||||||
 | 
					for its votes. That service is responsible for ensuring the vote won't cause
 | 
				
			||||||
 | 
					the staker to be slashed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### VoteInstruction::Vote(Vec<Vote>)
 | 
					### VoteInstruction::Vote(Vec<Vote>)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -85,14 +89,16 @@ count as stakes.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
### StakeState
 | 
					### StakeState
 | 
				
			||||||
 | 
					
 | 
				
			||||||
A StakeState takes one of two forms, StakeState::Delegate and StakeState::MiningPool.
 | 
					A StakeState takes one of three forms, StakeState::Uninitialized, StakeState::Stake and StakeState::RewardsPool.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### StakeState::Delegate
 | 
					### StakeState::Stake
 | 
				
			||||||
 | 
					
 | 
				
			||||||
StakeState is the current delegation preference of the **staker**. StakeState
 | 
					StakeState::Stake is the current delegation preference of the **staker** and
 | 
				
			||||||
contains the following state information:
 | 
					contains the following state information:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Account::lamports - The staked lamports.
 | 
					* Account::lamports - The lamports available for staking.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `stake` - the staked amount (subject to warm up and cool down) for generating rewards, always less than or equal to Account::lamports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `voter_pubkey` - The pubkey of the VoteState instance the lamports are
 | 
					* `voter_pubkey` - The pubkey of the VoteState instance the lamports are
 | 
				
			||||||
delegated to.
 | 
					delegated to.
 | 
				
			||||||
@@ -100,56 +106,53 @@ delegated to.
 | 
				
			|||||||
* `credits_observed` - The total credits claimed over the lifetime of the
 | 
					* `credits_observed` - The total credits claimed over the lifetime of the
 | 
				
			||||||
program.
 | 
					program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### StakeState::MiningPool
 | 
					* `activated` - the epoch at which this stake was activated/delegated. The full stake will be counted after warm up.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
There are two approaches to the mining pool.  The bank could allow the
 | 
					* `deactivated` - the epoch at which this stake will be completely de-activated, which is `cool down` epochs after StakeInstruction::Deactivate is issued.
 | 
				
			||||||
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
 | 
					 | 
				
			||||||
StakeState::MiningPool instances as the cluster wide mining pools.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
* 256 StakeState::MiningPool are initialized, each with 1/256 number of mining pool
 | 
					### StakeState::RewardsPool
 | 
				
			||||||
tokens stored as `Account::lamports`.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The stakes and the MiningPool are accounts that are owned by the same `Stake`
 | 
					To avoid a single network wide lock or contention in redemption, 256 RewardsPools are part of genesis under pre-determined keys, each with std::u64::MAX credits to be able to satisfy redemptions according to point value.
 | 
				
			||||||
program.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### StakeInstruction::Initialize
 | 
					The Stakes and the RewardsPool are accounts that are owned by the same `Stake` program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `account[0]` - RW - The StakeState::Delegate instance.
 | 
					### StakeInstruction::DelegateStake(u64)
 | 
				
			||||||
  `StakeState::Delegate::credits_observed` is initialized to `VoteState::credits`.
 | 
					
 | 
				
			||||||
  `StakeState::Delegate::voter_pubkey` is initialized to `account[1]`
 | 
					The Stake account is moved from Unitialized to StakeState::Stake form.  This is
 | 
				
			||||||
 | 
					how stakers choose their initial delegate validator node and activate their
 | 
				
			||||||
 | 
					stake account lamports.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `account[0]` - RW - The StakeState::Stake instance. <br>
 | 
				
			||||||
 | 
					      `StakeState::Stake::credits_observed` is initialized to `VoteState::credits`,<br>
 | 
				
			||||||
 | 
					      `StakeState::Stake::voter_pubkey` is initialized to `account[1]`,<br>
 | 
				
			||||||
 | 
					      `StakeState::Stake::stake` is initialized to the u64 passed as an argument above,<br>
 | 
				
			||||||
 | 
					      `StakeState::Stake::activated` is initialized to current Bank epoch, and<br>
 | 
				
			||||||
 | 
					      `StakeState::Stake::deactivated` is initialized to std::u64::MAX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `account[1]` - R - The VoteState instance.
 | 
					* `account[1]` - R - The VoteState instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `account[2]` - R - syscall::current account, carries information about current Bank epoch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### StakeInstruction::RedeemVoteCredits
 | 
					### StakeInstruction::RedeemVoteCredits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The Staker or the owner of the Stake account sends a transaction with this
 | 
					The staker or the owner of the Stake account sends a transaction with this
 | 
				
			||||||
instruction to claim rewards.
 | 
					instruction to claim rewards.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The Vote account and the Stake account pair maintain a lifetime counter
 | 
					The Vote account and the Stake account pair maintain a lifetime counter of total
 | 
				
			||||||
of total rewards generated and claimed.  When claiming rewards, the total lamports
 | 
					rewards generated and claimed.  Rewards are paid according to a point value
 | 
				
			||||||
deposited into the Stake account and as validator commission is proportional to
 | 
					supplied by the Bank from inflation.  A `point` is one credit * one staked
 | 
				
			||||||
`VoteState::credits - StakeState::credits_observed`.
 | 
					lamport, rewards paid are proportional to the number of lamports staked.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `account[0]` - RW - The StakeState::Stake instance that is redeeming rewards.
 | 
				
			||||||
* `account[0]` - RW - The StakeState::MiningPool instance that will fulfill the
 | 
					* `account[1]` - R - The VoteState instance, must be the same as `StakeState::voter_pubkey`
 | 
				
			||||||
reward.
 | 
					* `account[2]` - RW - The StakeState::RewardsPool instance that will fulfill the request (picked at random).
 | 
				
			||||||
* `account[1]` - RW - The StakeState::Delegate instance that is redeeming votes
 | 
					* `account[3]` - R - syscall::rewards account from the Bank that carries point value.
 | 
				
			||||||
credits.
 | 
					 | 
				
			||||||
* `account[2]` - R - The VoteState instance, must be the same as
 | 
					 | 
				
			||||||
`StakeState::voter_pubkey`
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Reward is paid out for the difference between `VoteState::credits` to
 | 
					Reward is paid out for the difference between `VoteState::credits` to
 | 
				
			||||||
`StakeState::Delgate.credits_observed`, and `credits_observed` is updated to
 | 
					`StakeState::Stake::credits_observed`, multiplied by `syscall::rewards::Rewards::validator_point_value`.
 | 
				
			||||||
`VoteState::credits`.  The commission is deposited into the Vote account token
 | 
					`StakeState::Stake::credits_observed` is updated to`VoteState::credits`.  The commission is deposited into the Vote account token
 | 
				
			||||||
balance, and the reward is deposited to the Stake account token balance.
 | 
					balance, and the reward is deposited to the Stake account token balance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The total lamports paid is a percentage-rate of the lamports staked muiltplied by
 | 
					 | 
				
			||||||
the ratio of rewards being redeemed to rewards that could have been generated
 | 
					 | 
				
			||||||
during the rate period.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Any random MiningPool can be used to redeem the credits.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
```rust,ignore
 | 
					```rust,ignore
 | 
				
			||||||
let credits_to_claim = vote_state.credits - stake_state.credits_observed;
 | 
					let credits_to_claim = vote_state.credits - stake_state.credits_observed;
 | 
				
			||||||
@@ -157,24 +160,26 @@ stake_state.credits_observed = vote_state.credits;
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`credits_to_claim` is used to compute the reward and commission, and
 | 
					`credits_to_claim` is used to compute the reward and commission, and
 | 
				
			||||||
`StakeState::Delegate::credits_observed` is updated to the latest
 | 
					`StakeState::Stake::credits_observed` is updated to the latest
 | 
				
			||||||
`VoteState::credits` value.
 | 
					`VoteState::credits` value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Collecting network fees into the MiningPool
 | 
					### StakeInstruction::Deactivate
 | 
				
			||||||
 | 
					A staker may wish to withdraw from the network.  To do so he must first deactivate his stake, and wait for cool down.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
At the end of the block, before the bank is frozen, but after it processed all
 | 
					* `account[0]` - RW - The StakeState::Stake instance that is deactivating, the transaction must be signed by this key.
 | 
				
			||||||
the transactions for the block, a virtual instruction is executed to collect
 | 
					* `account[1]` - R - syscall::current account from the Bank that carries current epoch
 | 
				
			||||||
the transaction fees.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
* A portion of the fees are deposited into the leader's account.
 | 
					StakeState::Stake::deactivated is set to the current epoch + cool down.  The account's stake will ramp down to zero by
 | 
				
			||||||
* A portion of the fees are deposited into the smallest StakeState::MiningPool
 | 
					that epoch, and Account::lamports will be available for withdrawal.
 | 
				
			||||||
account.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Authorizing a Vote Signer
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
`VoteInstruction::AuthorizeVoter` allows a staker to choose a signing service
 | 
					### StakeInstruction::Withdraw(u64)
 | 
				
			||||||
for its votes. That service is responsible for ensuring the vote won't cause
 | 
					Lamports build up over time in a Stake account and any excess over activated stake can be withdrawn.
 | 
				
			||||||
the staker to be slashed.
 | 
					
 | 
				
			||||||
 | 
					* `account[0]` - RW - The StakeState::Stake from which to withdraw, the transaction must be signed by this key.
 | 
				
			||||||
 | 
					* `account[1]` - RW - Account that should be credited with the withdrawn lamports.
 | 
				
			||||||
 | 
					* `account[2]` - R - syscall::current account from the Bank that carries current epoch, to calculate stake.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Benefits of the design
 | 
					## Benefits of the design
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -187,9 +192,6 @@ the staker to be slashed.
 | 
				
			|||||||
* Commission for the work is deposited when a reward is claimed by the delegated
 | 
					* Commission for the work is deposited when a reward is claimed by the delegated
 | 
				
			||||||
stake.
 | 
					stake.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This proposal would benefit from the `read-only` accounts proposal to allow for
 | 
					 | 
				
			||||||
many rewards to be claimed concurrently.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Example Callflow
 | 
					## Example Callflow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<img alt="Passive Staking Callflow" src="img/passive-staking-callflow.svg" class="center"/>
 | 
					<img alt="Passive Staking Callflow" src="img/passive-staking-callflow.svg" class="center"/>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user