s/voter/validator

This commit is contained in:
Anatoly Yakovenko
2019-01-30 10:49:54 -08:00
committed by Greg Fitzgerald
parent 3cbbceec78
commit 5b8e7bfcf2

View File

@ -1,7 +1,7 @@
# Fork Selection # Fork Selection
This article describes Solana's *Fork Selection* algorithm based on lockouts. It This design describes a *Fork Selection* algorithm. It addresses the following
attempts to solve the following problems: problems:
* Some forks may not end up accepted by the super-majority of the cluster, and * Some forks may not end up accepted by the super-majority of the cluster, and
voters need to recover from voting on such forks. voters need to recover from voting on such forks.
@ -23,6 +23,9 @@ History ASICS that are much faster than the rest of the cluster. Consensus
needs to be resistant to attacks that exploit the variability in Proof of needs to be resistant to attacks that exploit the variability in Proof of
History ASIC speed. History ASIC speed.
For brevity this design assumes that a single voter with a stake is deployed as
an individual validator in the cluster.
## Time ## Time
The Solana cluster generates a source of time via a Verifiable Delay Function we The Solana cluster generates a source of time via a Verifiable Delay Function we
@ -35,38 +38,38 @@ generation](fork-generation.md) and [leader rotation](leader-rotation.md).
## Lockouts ## Lockouts
The purpose of the lockout is to force a voter to commit opportunity cost to a The purpose of the lockout is to force a validator to commit opportunity cost to
specific fork. Lockouts are measured in slots, and therefor represent a a specific fork. Lockouts are measured in slots, and therefor represent a
real-time forced delay that a voter needs to wait before breaking the commitment real-time forced delay that a validator needs to wait before breaking the
to a fork. commitment to a fork.
Voters that violate the lockouts and vote for a diverging fork within the Validators that violate the lockouts and vote for a diverging fork within the
lockout should be punished. The proposed punishment is to slash the voters stake lockout should be punished. The proposed punishment is to slash the validator
if a concurrent vote within a lockout for a non-descendant fork can be proven to stake if a concurrent vote within a lockout for a non-descendant fork can be
the cluster. proven to the cluster.
## Algorithm ## Algorithm
The basic idea to this approach is to stack consensus votes and double lockouts. The basic idea to this approach is to stack consensus votes and double lockouts.
Each vote in the stack is a confirmation of a fork. Each confirmed fork is an Each vote in the stack is a confirmation of a fork. Each confirmed fork is an
ancestor of the fork above it. Each consensus vote has a `lockout` in units of ancestor of the fork above it. Each vote has a `lockout` in units of slots
slots before the validator can submit a vote that does not contain the confirmed before the validator can submit a vote that does not contain the confirmed fork
fork as an ancestor. as an ancestor.
When a vote is added to the stack, the lockouts of all the previous votes in the When a vote is added to the stack, the lockouts of all the previous votes in the
stack are doubled (more on this in [Rollback](#Rollback)). With each new vote, stack are doubled (more on this in [Rollback](#Rollback)). With each new vote,
a voter commits the previous votes to an ever-increasing lockout. At 32 votes a validator commits the previous votes to an ever-increasing lockout. At 32
we can consider the vote to be at `max lockout` any votes with a lockout equal votes we can consider the vote to be at `max lockout` any votes with a lockout
to or above `1<<32` are dequeued (FIFO). Dequeuing a vote is the trigger for a equal to or above `1<<32` are dequeued (FIFO). Dequeuing a vote is the trigger
reward. If a vote expires before it is dequeued, it and all the votes above it for a reward. If a vote expires before it is dequeued, it and all the votes
are popped (LIFO) from the vote stack. The voter needs to start rebuilding the above it are popped (LIFO) from the vote stack. The validator needs to start
stack from that point. rebuilding the stack from that point.
### Rollback ### Rollback
Before a vote is pushed to the stack, all the votes leading up to vote with a Before a vote is pushed to the stack, all the votes leading up to vote with a
lower lock time than the new vote are popped. After rollback lockouts are not lower lock time than the new vote are popped. After rollback lockouts are not
doubled until the voter catches up to the rollback height of votes. doubled until the validator catches up to the rollback height of votes.
For example, a vote stack with the following state: For example, a vote stack with the following state:
@ -108,67 +111,73 @@ votes.
### Slashing and Rewards ### Slashing and Rewards
Voters should be rewarded for selecting the fork that the rest of the cluster Validators should be rewarded for selecting the fork that the rest of the
selected as often as possible. This is well-aligned with generating a reward cluster selected as often as possible. This is well-aligned with generating a
when the vote stack is full and the oldest vote needs to be dequeued. Thus a reward when the vote stack is full and the oldest vote needs to be dequeued.
reward should be generated for each successful dequeue. Thus a reward should be generated for each successful dequeue.
### Cost of Rollback ### Cost of Rollback
Cost of rollback of *fork A* is defined as the cost in terms of lockout time to Cost of rollback of *fork A* is defined as the cost in terms of lockout time to
the validators to confirm any other fork that does not include *fork A* as an the validator to confirm any other fork that does not include *fork A* as an
ancestor. ancestor.
The **Economic Finality** of *fork A* can be calculated as the loss of all the The **Economic Finality** of *fork A* can be calculated as the loss of all the
rewards from rollback of *fork A* and its descendants, plus the opportunity rewards from rollback of *fork A* and its descendants, plus the opportunity cost
cost of reward due to the exponentially growing lockout of the votes that have of reward due to the exponentially growing lockout of the votes that have
confirmed *fork A*. confirmed *fork A*.
### Thresholds ### Thresholds
Each voter can independently set a threshold of cluster commitment to a fork Each validator can independently set a threshold of cluster commitment to a fork
before that voter commits to a fork. For example, at vote stack index 7, the before that validator commits to a fork. For example, at vote stack index 7,
lockout is 256 time units. A voter may withhold votes and let votes 0-7 expire the lockout is 256 time units. A validator may withhold votes and let votes 0-7
unless the vote at index 7 has at greater than 50% commitment in the cluster. expire unless the vote at index 7 has at greater than 50% commitment in the
This allows each voter to independently control how much risk to commit to a cluster. This allows each validator to independently control how much risk to
fork. Committing to forks at a higher frequency would allow the voter to earn commit to a fork. Committing to forks at a higher frequency would allow the
more rewards. validator to earn more rewards.
### Algorithm parameters ### Algorithm parameters
These parameters need to be tuned. The following parameters need to be tuned:
* Number of votes in the stack before dequeue occurs (32). * Number of votes in the stack before dequeue occurs (32).
* Rate of growth for lockouts in the stack (2x). * Rate of growth for lockouts in the stack (2x).
* Starting default lockout (2). * Starting default lockout (2).
* Threshold depth for minimum cluster commitment before committing to the fork * Threshold depth for minimum cluster commitment before committing to the fork
(8). (8).
* Minimum cluster commitment size at threshold depth (50%+). * Minimum cluster commitment size at threshold depth (50%+).
### Free Choice ### Free Choice
A "Free Choice" is an unenforcible voter action. A voter that maximizes A "Free Choice" is an unenforcible validator action. There is no way for the
self-reward over all possible futures should behave in such a way that the protocol to encode and enforce these actions since each validator can modify the
system is stable, and the local greedy choice should result in a greedy choice code and adjust the algorithm. A validator that maximizes self-reward over all
over all possible futures. A set of voter that are engaging in choices to possible futures should behave in such a way that the system is stable, and the
disrupt the protocol should be bound by their stake weight to the denial of local greedy choice should result in a greedy choice over all possible futures.
service. Two options exits for voter: A set of validator that are engaging in choices to disrupt the protocol should
be bound by their stake weight to the denial of service. Two options exits for
validator:
* a voter can outrun previous voters in virtual generation and submit a * a validator can outrun previous validator in virtual generation and submit a
concurrent fork concurrent fork
* a voter can withhold a vote to observe multiple forks before voting * a validator can withhold a vote to observe multiple forks before voting
In both cases, the voters in the cluster have several forks to pick from In both cases, the validator in the cluster have several forks to pick from
concurrently, even though each fork represents a different height. In both concurrently, even though each fork represents a different height. In both
cases it is impossible for the protocol to detect if the voter behavior is cases it is impossible for the protocol to detect if the validator behavior is
intentional or not. intentional or not.
### Greedy Choice for Concurrent Forks ### Greedy Choice for Concurrent Forks
When evaluating multiple forks, each voter should use the following rules: When evaluating multiple forks, each validator should use the following rules:
1. Forks must satisify the *Threshold* rule. 1. Forks must satisfy the *Threshold* rule.
2. Pick the fork that maximizes the total cluster lockout time for all the 2. Pick the fork that maximizes the total cluster lockout time for all the
ancestor forks. ancestor forks.
@ -192,8 +201,10 @@ effort to censor them. A fork proposed by this attacker will be available
concurrently with the next available leader. For nodes to pick this fork it concurrently with the next available leader. For nodes to pick this fork it
must satisfy the *Greedy Choice* rule. must satisfy the *Greedy Choice* rule.
1. Fork must have equal number of validator votes for the ancestor fork. 1. Fork must have equal number of votes for the ancestor fork.
2. Fork cannot be so far a head as to cause expired votes. 2. Fork cannot be so far a head as to cause expired votes.
3. Fork must have a greater amount of cluster transaction fees. 3. Fork must have a greater amount of cluster transaction fees.
This attack is then limited to censoring the previous leaders fees, and This attack is then limited to censoring the previous leaders fees, and