s/voter/validator
This commit is contained in:
committed by
Greg Fitzgerald
parent
3cbbceec78
commit
5b8e7bfcf2
@ -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
|
||||||
|
Reference in New Issue
Block a user