80-char lines
This commit is contained in:
parent
ae903f190e
commit
546c92751b
|
@ -8,14 +8,11 @@
|
|||
.---------. | | Fetch | | SigVerify | | Banking | | Ledger | | | Broadcast |
|
||||
| Clients |--->| Stage |->| Stage |->| Stage |-->| Write +---->| Service |
|
||||
`---------` | | | | | | | | Stage | | | |
|
||||
| `-------` `-----------` `----+----` `---+----` | `------------`
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
`---------------------------------|------------|-------`
|
||||
| |
|
||||
v v
|
||||
.------. .--------.
|
||||
| Bank | | Ledger |
|
||||
`------` `--------`
|
||||
| `-------` `-----------` `----+----` `--------` | `------------`
|
||||
| | |
|
||||
`---------------------------------|--------------------`
|
||||
|
|
||||
v
|
||||
.------.
|
||||
| Bank |
|
||||
`------`
|
||||
|
|
|
@ -1,35 +1,58 @@
|
|||
# Signing using Secure Enclave
|
||||
|
||||
This document defines the security mechanism of signing keys used by the network nodes. Every node contains an asymmetric key that's used for signing and verifying the votes. The node signs the vote transactions using its private key. Other entities can verify the signature using the node's public key.
|
||||
This document defines the security mechanism of signing keys used by the
|
||||
network nodes. Every node contains an asymmetric key that's used for signing
|
||||
and verifying the votes. The node signs the vote transactions using its private
|
||||
key. Other entities can verify the signature using the node's public key.
|
||||
|
||||
The node's stake or its resources could be compromised if its private key is used to sign incorrect data (e.g. voting on multiple forks of the ledger). So, it's important to safeguard the private key.
|
||||
The node's stake or its resources could be compromised if its private key is
|
||||
used to sign incorrect data (e.g. voting on multiple forks of the ledger). So,
|
||||
it's important to safeguard the private key.
|
||||
|
||||
Secure Enclaves (such as SGX) provide a layer of memory and computation protection. An enclave can be used to generate an asymmetric key and keep the private key in its protected memory. It can expose an API that user (untrusted) code can use for signing the transactions.
|
||||
Secure Enclaves (such as SGX) provide a layer of memory and computation
|
||||
protection. An enclave can be used to generate an asymmetric key and keep the
|
||||
private key in its protected memory. It can expose an API that user (untrusted)
|
||||
code can use for signing the transactions.
|
||||
|
||||
## Message Flow
|
||||
|
||||
1. The node initializes the enclave at startup
|
||||
* The enclave generates an asymmetric key and returns the public key to the node
|
||||
* The keypair is ephemeral. A new keypair is generated on node bootup. A new keypair might also be generated at runtime based on some TBD criteria.
|
||||
* The enclave generates an asymmetric key and returns the public key to the
|
||||
node
|
||||
* The keypair is ephemeral. A new keypair is generated on node bootup. A
|
||||
new keypair might also be generated at runtime based on some TBD
|
||||
criteria.
|
||||
* The enclave returns its attestation report to the node
|
||||
2. The node performs attestation of the enclave (e.g using Intel's IAS APIs)
|
||||
* The node ensures that the Secure Enclave is running on a TPM and is signed by a trusted party
|
||||
3. The owner of the node grants ephemeral key permission to use its stake. This process is TBD.
|
||||
4. The node's untrusted, non-enclave software calls trusted enclave software using its interface to sign transactions and other data.
|
||||
* In case of vote signing, the node needs to verify the PoH. The PoH verification is an integral part of signing. The enclave would be presented with some verifiable data that it'll check before signing the vote.
|
||||
* The node ensures that the Secure Enclave is running on a TPM and is
|
||||
signed by a trusted party
|
||||
3. The owner of the node grants ephemeral key permission to use its stake. This
|
||||
process is TBD.
|
||||
4. The node's untrusted, non-enclave software calls trusted enclave software
|
||||
using its interface to sign transactions and other data.
|
||||
* In case of vote signing, the node needs to verify the PoH. The PoH
|
||||
verification is an integral part of signing. The enclave would be
|
||||
presented with some verifiable data that it'll check before signing the vote.
|
||||
* The process of generating the verifiable data in untrusted space is TBD
|
||||
|
||||
## PoH Verification
|
||||
|
||||
1. When the node votes on an en entry `X`, there's a lockout period `N`, for which it cannot vote on a fork that does not contain `X` in its history.
|
||||
2. Every time the node votes on the derivative of `X`, say `X+y`, the lockout period for `X` increases by a factor `F` (i.e. the duration node cannot vote on a fork that does not contain `X` increases).
|
||||
1. When the node votes on an en entry `X`, there's a lockout period `N`, for
|
||||
which it cannot vote on a fork that does not contain `X` in its history.
|
||||
2. Every time the node votes on the derivative of `X`, say `X+y`, the lockout
|
||||
period for `X` increases by a factor `F` (i.e. the duration node cannot vote on
|
||||
a fork that does not contain `X` increases).
|
||||
* The lockout period for `X+y` is still `N` until the node votes again.
|
||||
3. The lockout period increment is capped (e.g. factor `F` applies maximum 32 times).
|
||||
4. The signing enclave must not sign a vote that violates this policy. This means
|
||||
3. The lockout period increment is capped (e.g. factor `F` applies maximum 32
|
||||
times).
|
||||
4. The signing enclave must not sign a vote that violates this policy. This
|
||||
means
|
||||
* Enclave is initialized with `N`, `F` and `Factor cap`
|
||||
* Enclave stores `Factor cap` number of entry IDs on which the node had previously voted
|
||||
* Enclave stores `Factor cap` number of entry IDs on which the node had
|
||||
previously voted
|
||||
* The sign request contains the entry ID for the new vote
|
||||
* Enclave verifies that new vote's entry ID is on the correct fork (following the rules #1 and #2 above)
|
||||
* Enclave verifies that new vote's entry ID is on the correct fork
|
||||
(following the rules #1 and #2 above)
|
||||
|
||||
## Ancestor Verification
|
||||
|
||||
|
@ -38,66 +61,121 @@ This is alternate, albeit, less certain approach to verifying voting fork.
|
|||
2. It observes the votes from the active set in the last voting period
|
||||
3. It stores the ancestor/last_tick at which each node voted
|
||||
4. It sends new vote request to vote-signing service
|
||||
* It includes previous votes from nodes in the active set, and their corresponding ancestors
|
||||
5. The signer checks if the previous votes contains a vote from the validator, and the vote ancestor matches with majority of the nodes
|
||||
* It includes previous votes from nodes in the active set, and their
|
||||
corresponding ancestors
|
||||
5. The signer checks if the previous votes contains a vote from the validator,
|
||||
and the vote ancestor matches with majority of the nodes
|
||||
* It signs the new vote if the check is successful
|
||||
* It asserts (raises an alarm of some sort) if the check is unsuccessful
|
||||
|
||||
The premise is that the validator can be spoofed at most once to vote on incorrect data. If someone hijacks the validator and submits a vote request for bogus data, that vote will not be included in the PoH (as it'll be rejected by the network). The next time the validator sends a request to sign the vote, the signing service will detect that validator's last vote is missing (as part of #5 above).
|
||||
The premise is that the validator can be spoofed at most once to vote on
|
||||
incorrect data. If someone hijacks the validator and submits a vote request for
|
||||
bogus data, that vote will not be included in the PoH (as it'll be rejected by
|
||||
the network). The next time the validator sends a request to sign the vote, the
|
||||
signing service will detect that validator's last vote is missing (as part of
|
||||
#5 above).
|
||||
|
||||
## Fork determination
|
||||
|
||||
Due to the fact that the enclave cannot process PoH, it has no direct knowledge of fork history of a submitted validator vote. Each enclave should be initiated with the current *active set* of public keys. A validator should submit its current vote along with the votes of the active set (including itself) that it observed in the slot of its previous vote. In this way, the enclave can surmise the votes accompanying the validator's previous vote and thus the fork being voted on. This is not possible for the validator's initial submitted vote, as it will not have a 'previous' slot to reference. To account for this, a short voting freeze should apply until the second vote is submitted containing the votes within the active set, along with it's own vote, at the height of the initial vote.
|
||||
Due to the fact that the enclave cannot process PoH, it has no direct knowledge
|
||||
of fork history of a submitted validator vote. Each enclave should be initiated
|
||||
with the current *active set* of public keys. A validator should submit its
|
||||
current vote along with the votes of the active set (including itself) that it
|
||||
observed in the slot of its previous vote. In this way, the enclave can surmise
|
||||
the votes accompanying the validator's previous vote and thus the fork being
|
||||
voted on. This is not possible for the validator's initial submitted vote, as
|
||||
it will not have a 'previous' slot to reference. To account for this, a short
|
||||
voting freeze should apply until the second vote is submitted containing the
|
||||
votes within the active set, along with it's own vote, at the height of the
|
||||
initial vote.
|
||||
|
||||
## Enclave configuration
|
||||
|
||||
A staking client should be configurable to prevent voting on inactive forks. This mechanism should use the client's known active set `N_active` along with a threshold vote `N_vote` and a threshold depth `N_depth` to determine whether or not to continue voting on a submitted fork. This configuration should take the form of a rule such that the client will only vote on a fork if it observes more than `N_vote` at `N_depth`. Practically, this represents the client from confirming that it has observed some probability of economic finality of the submitted fork at a depth where an additional vote would create a lockout for an undesirable amount of time if that fork turns out not to be live.
|
||||
A staking client should be configurable to prevent voting on inactive forks.
|
||||
This mechanism should use the client's known active set `N_active` along with a
|
||||
threshold vote `N_vote` and a threshold depth `N_depth` to determine whether or
|
||||
not to continue voting on a submitted fork. This configuration should take the
|
||||
form of a rule such that the client will only vote on a fork if it observes
|
||||
more than `N_vote` at `N_depth`. Practically, this represents the client from
|
||||
confirming that it has observed some probability of economic finality of the
|
||||
submitted fork at a depth where an additional vote would create a lockout for
|
||||
an undesirable amount of time if that fork turns out not to be live.
|
||||
|
||||
## Signing service
|
||||
|
||||
The signing service consists of a a JSON RPC server, and a request processor. At startup, it starts the RPC server at a configured port and waits for client/validator requests. It expects the following type of requests.
|
||||
The signing service consists of a a JSON RPC server, and a request processor.
|
||||
At startup, it starts the RPC server at a configured port and waits for
|
||||
client/validator requests. It expects the following type of requests.
|
||||
1. Register a new validator node
|
||||
* The request contains validator's identity (public key)
|
||||
* The request is signed with validator's private key
|
||||
* The service will drop the request if signature of the request cannot be verified
|
||||
* The service will create a new voting asymmetric key for the validator, and return the public key as a response
|
||||
* If a validator retries to register, it'll return the public key from the pre-existing keypair
|
||||
* The service will drop the request if signature of the request cannot be
|
||||
verified
|
||||
* The service will create a new voting asymmetric key for the validator,
|
||||
and return the public key as a response
|
||||
* If a validator retries to register, it'll return the public key from the
|
||||
pre-existing keypair
|
||||
2. Sign a vote
|
||||
* The request contains voting transaction, and all verification data (as described in Ancestor Verification)
|
||||
* The request contains voting transaction, and all verification data (as
|
||||
described in Ancestor Verification)
|
||||
* The request is signed with validator's private key
|
||||
* The service will drop the request if signature of the request cannot be verified
|
||||
* The service will drop the request if signature of the request cannot be
|
||||
verified
|
||||
* The service will verify the voting data
|
||||
* The service will return a signed transaction (or signature for the transaction)
|
||||
* The service will return a signed transaction (or signature for the
|
||||
transaction)
|
||||
|
||||
The service could potentially have different variations, depending on the hardware platform capabilities. For example, if the hardware supports a secure enclave, the service can offload asymmetric key generation, and private key protection to the enclave. A less secure implementation of the service could simply carry the keypair in the process memory.
|
||||
The service could potentially have different variations, depending on the
|
||||
hardware platform capabilities. For example, if the hardware supports a secure
|
||||
enclave, the service can offload asymmetric key generation, and private key
|
||||
protection to the enclave. A less secure implementation of the service could
|
||||
simply carry the keypair in the process memory.
|
||||
|
||||
## Validator voting
|
||||
|
||||
A validator node, at startup, creates a new vote account and registers it with the network. This is done by submitting a new "vote register" transaction. The transaction contains validator's keypair, it's vote signing public key, and some additional information. The other nodes on the network process this transaction and include the new validator in the active set.
|
||||
A validator node, at startup, creates a new vote account and registers it with
|
||||
the network. This is done by submitting a new "vote register" transaction. The
|
||||
transaction contains validator's keypair, it's vote signing public key, and
|
||||
some additional information. The other nodes on the network process this
|
||||
transaction and include the new validator in the active set.
|
||||
|
||||
Subsequently, the validator submits a "new vote" transaction on a voting event. This vote is signed with validator's voting private key.
|
||||
Subsequently, the validator submits a "new vote" transaction on a voting event.
|
||||
This vote is signed with validator's voting private key.
|
||||
|
||||
The validator code will change to interface with Signing service for "vote register" and "new vote" use cases.
|
||||
The validator code will change to interface with Signing service for "vote
|
||||
register" and "new vote" use cases.
|
||||
|
||||
### Configuration
|
||||
|
||||
The validator node will be configured with Signing service's network endpoint (IP/Port).
|
||||
The validator node will be configured with Signing service's network endpoint
|
||||
(IP/Port).
|
||||
|
||||
### Register
|
||||
|
||||
At startup, the validator will call Signing service using JSON RPC to register itself. The RPC call will return the voting public key for the validator node. The validator will create a new "vote register" transaction including this public key in it, and submit it to the network.
|
||||
At startup, the validator will call Signing service using JSON RPC to register
|
||||
itself. The RPC call will return the voting public key for the validator node.
|
||||
The validator will create a new "vote register" transaction including this
|
||||
public key in it, and submit it to the network.
|
||||
|
||||
### Collect votes for last period
|
||||
|
||||
The validator will look up the votes submitted by all the nodes in the network for the last voting period. This information will be submitted to signing service with new vote signing request.
|
||||
The validator will look up the votes submitted by all the nodes in the network
|
||||
for the last voting period. This information will be submitted to signing
|
||||
service with new vote signing request.
|
||||
|
||||
### New Vote Signing
|
||||
|
||||
The validator will create a "new vote" transaction and send it to the signing service using JSON RPC. The RPC request will also include the vote verification data. On success, RPC call will return the signature for the vote. On failure, RPC call will return the failure code.
|
||||
The validator will create a "new vote" transaction and send it to the signing
|
||||
service using JSON RPC. The RPC request will also include the vote verification
|
||||
data. On success, RPC call will return the signature for the vote. On failure,
|
||||
RPC call will return the failure code.
|
||||
|
||||
## Challenges
|
||||
|
||||
1. The nodes are currently being configured with asymmetric keys that are generated and stored in PKCS8 files.
|
||||
2. The genesis block contains an entry that's signed with leader's private key. This entry is used to identify the primordial leader.
|
||||
3. Generation of verifiable data in untrusted space for PoH verification in the enclave.
|
||||
1. The nodes are currently being configured with asymmetric keys that are
|
||||
generated and stored in PKCS8 files.
|
||||
2. The genesis block contains an entry that's signed with leader's private key.
|
||||
This entry is used to identify the primordial leader.
|
||||
3. Generation of verifiable data in untrusted space for PoH verification in the
|
||||
enclave.
|
||||
4. Need infrastructure for granting stake to an ephemeral key.
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
# Fork Generation
|
||||
|
||||
The chapter describes how forks naturally occur as a consequence of [leader rotation](leader-rotation.md).
|
||||
The chapter describes how forks naturally occur as a consequence of [leader
|
||||
rotation](leader-rotation.md).
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
Nodes take turns being leader and generating the PoH that encodes state changes. The network can tolerate loss of connection to any leader by synthesizing what the leader ***would*** have generated had it been connected but not ingesting any state changes. The possible number of forks is thereby limited to a "there/not-there" skip list of forks that may arise on leader rotation slot boundaries. At any given slot, only a single leader's transactions will be accepted.
|
||||
Nodes take turns being leader and generating the PoH that encodes state
|
||||
changes. The network can tolerate loss of connection to any leader by
|
||||
synthesizing what the leader ***would*** have generated had it been connected
|
||||
but not ingesting any state changes. The possible number of forks is thereby
|
||||
limited to a "there/not-there" skip list of forks that may arise on leader
|
||||
rotation slot boundaries. At any given slot, only a single leader's
|
||||
transactions will be accepted.
|
||||
|
||||
## Message Flow
|
||||
|
||||
|
@ -14,50 +21,82 @@ Nodes take turns being leader and generating the PoH that encodes state changes.
|
|||
3. Leader executes valid transactions updating its state.
|
||||
4. Leader packages transactions into entries based off its current PoH slot.
|
||||
5. Leader transmits the entries to validator nodes (in signed blobs)
|
||||
1. The PoH stream includes ticks; empty entries that indicate liveness of the leader and the passage of time on the network.
|
||||
2. A leader's stream begins with the tick entries necessary complete the PoH back to the leaders most recently observed prior leader slot.
|
||||
6. Validators retransmit entries to peers in their set and to further downstream nodes.
|
||||
1. The PoH stream includes ticks; empty entries that indicate liveness of
|
||||
the leader and the passage of time on the network.
|
||||
2. A leader's stream begins with the tick entries necessary complete the PoH
|
||||
back to the leaders most recently observed prior leader slot.
|
||||
6. Validators retransmit entries to peers in their set and to further
|
||||
downstream nodes.
|
||||
7. Validators validate the transactions and execute them on their state.
|
||||
8. Validators compute the hash of the state.
|
||||
9. At specific times, i.e. specific PoH tick counts, validators transmit votes to the leader.
|
||||
1. Votes are signatures of the hash of the computed state at that PoH tick count
|
||||
9. At specific times, i.e. specific PoH tick counts, validators transmit votes
|
||||
to the leader.
|
||||
1. Votes are signatures of the hash of the computed state at that PoH tick
|
||||
count
|
||||
2. Votes are also propagated via gossip
|
||||
10. Leader executes the votes as any other transaction and broadcasts them to the network
|
||||
10. Leader executes the votes as any other transaction and broadcasts them to
|
||||
the network
|
||||
11. Validators observe their votes and all the votes from the network.
|
||||
|
||||
## Partitions, Forks
|
||||
|
||||
Forks can arise at PoH tick counts that correspond to a vote. The next leader may not have observed the last vote slot and may start their slot with generated virtual PoH entries. These empty ticks are generated by all nodes in the network at a network-specified rate for hashes/per/tick `Z`.
|
||||
Forks can arise at PoH tick counts that correspond to a vote. The next leader
|
||||
may not have observed the last vote slot and may start their slot with
|
||||
generated virtual PoH entries. These empty ticks are generated by all nodes in
|
||||
the network at a network-specified rate for hashes/per/tick `Z`.
|
||||
|
||||
There are only two possible versions of the PoH during a voting slot: PoH with `T` ticks and entries generated by the current leader, or PoH with just ticks. The "just ticks" version of the PoH can be thought of as a virtual ledger, one that all nodes in the network can derive from the last tick in the previous slot.
|
||||
There are only two possible versions of the PoH during a voting slot: PoH with
|
||||
`T` ticks and entries generated by the current leader, or PoH with just ticks.
|
||||
The "just ticks" version of the PoH can be thought of as a virtual ledger, one
|
||||
that all nodes in the network can derive from the last tick in the previous
|
||||
slot.
|
||||
|
||||
Validators can ignore forks at other points (e.g. from the wrong leader), or slash the leader responsible for the fork.
|
||||
Validators can ignore forks at other points (e.g. from the wrong leader), or
|
||||
slash the leader responsible for the fork.
|
||||
|
||||
Validators vote based on a greedy choice to maximize their reward described in [forks selection](fork-selection.md).
|
||||
Validators vote based on a greedy choice to maximize their reward described in
|
||||
[forks selection](fork-selection.md).
|
||||
|
||||
### Validator's View
|
||||
|
||||
#### Time Progression
|
||||
The diagram below represents a validator's view of the PoH stream with possible forks over time. L1, L2, etc. are leader slot, and `E`s represent entries from that leader during that leader's slot. The 'x's represent ticks only, and time flows downwards in the diagram.
|
||||
#### Time Progression The diagram below represents a validator's view of the
|
||||
PoH stream with possible forks over time. L1, L2, etc. are leader slot, and
|
||||
`E`s represent entries from that leader during that leader's slot. The 'x's
|
||||
represent ticks only, and time flows downwards in the diagram.
|
||||
|
||||
|
||||
<img alt="Fork generation" src="img/fork-generation.svg" class="center"/>
|
||||
|
||||
Note that an `E` appearing on 2 forks at the same slot is a slashable condition, so a validator observing `E3` and `E3'` can slash L3 and safely choose `x` for that slot. Once a validator commits to a forks, other forks can be discarded below that tick count. For any slot, validators need only consider a single "has entries" chain or a "ticks only" chain to be proposed by a leader. But multiple virtual entries may overlap as they link back to the a previous slot.
|
||||
Note that an `E` appearing on 2 forks at the same slot is a slashable
|
||||
condition, so a validator observing `E3` and `E3'` can slash L3 and safely
|
||||
choose `x` for that slot. Once a validator commits to a forks, other forks can
|
||||
be discarded below that tick count. For any slot, validators need only
|
||||
consider a single "has entries" chain or a "ticks only" chain to be proposed by
|
||||
a leader. But multiple virtual entries may overlap as they link back to the a
|
||||
previous slot.
|
||||
|
||||
#### Time Division
|
||||
|
||||
It's useful to consider leader rotation over PoH tick count as time division of the job of encoding state for the network. The following table presents the above tree of forks as a time-divided ledger.
|
||||
It's useful to consider leader rotation over PoH tick count as time division of
|
||||
the job of encoding state for the network. The following table presents the
|
||||
above tree of forks as a time-divided ledger.
|
||||
|
||||
leader slot | L1 | L2 | L3 | L4 | L5
|
||||
-------|----|----|----|----|----
|
||||
data | E1| E2 | E3 | E4 | E5
|
||||
ticks since prev | | | | x | xx
|
||||
|
||||
Note that only data from leader L3 will be accepted during leader slot L3. Data from L3 may include "catchup" ticks back to a slot other than L2 if L3 did not observe L2's data. L4 and L5's transmissions include the "ticks to prev" PoH entries.
|
||||
Note that only data from leader L3 will be accepted during leader slot L3.
|
||||
Data from L3 may include "catchup" ticks back to a slot other than L2 if L3 did
|
||||
not observe L2's data. L4 and L5's transmissions include the "ticks to prev"
|
||||
PoH entries.
|
||||
|
||||
This arrangement of the network data streams permits nodes to save exactly this to the ledger for replay, restart, and checkpoints.
|
||||
This arrangement of the network data streams permits nodes to save exactly this
|
||||
to the ledger for replay, restart, and checkpoints.
|
||||
|
||||
### Leader's View
|
||||
|
||||
When a new leader begins a slot, it must first transmit any PoH (ticks) required to link the new slot with the most recently observed and voted slot. The fork the leader proposes would link the current slot to a previous fork that the leader has voted on with virtual ticks.
|
||||
When a new leader begins a slot, it must first transmit any PoH (ticks)
|
||||
required to link the new slot with the most recently observed and voted slot.
|
||||
The fork the leader proposes would link the current slot to a previous fork
|
||||
that the leader has voted on with virtual ticks.
|
||||
|
|
|
@ -1,72 +1,165 @@
|
|||
Initial Proof of Stake (PoS) (i.e. using in-protocol asset, SOL, to provide secure consensus) design ideas outlined here. Solana will implement a proof of stake reward/security scheme for node validators on the network. The purpose is threefold:
|
||||
# Staking Rewards
|
||||
|
||||
- Align validator incentives with that of the greater network through skin-in-the-game deposits at risk
|
||||
- Avoid 'nothing at stake' fork voting issues by implementing slashing rules aimed at promoting fork convergence
|
||||
- Provide an avenue for validator rewards provided as a function of validator participation in the network.
|
||||
Initial Proof of Stake (PoS) (i.e. using in-protocol asset, SOL, to provide
|
||||
secure consensus) design ideas outlined here. Solana will implement a proof of
|
||||
stake reward/security scheme for node validators on the network. The purpose is
|
||||
threefold:
|
||||
|
||||
While many of the details of the specific implementation are currently under consideration and are expected to come into focus through specific modeling studies and parameter exploration on the Solana testnet, we outline here our current thinking on the main components of the PoS system. Much of this thinking is based on the current status of Casper FFG, with optimizations and specific attributes to be modified as is allowed by Solana's Proof of History (PoH) blockchain data structure.
|
||||
- Align validator incentives with that of the greater network through
|
||||
skin-in-the-game deposits at risk
|
||||
- Avoid 'nothing at stake' fork voting issues by implementing slashing rules
|
||||
aimed at promoting fork convergence
|
||||
- Provide an avenue for validator rewards provided as a function of validator
|
||||
participation in the network.
|
||||
|
||||
While many of the details of the specific implementation are currently under
|
||||
consideration and are expected to come into focus through specific modeling
|
||||
studies and parameter exploration on the Solana testnet, we outline here our
|
||||
current thinking on the main components of the PoS system. Much of this
|
||||
thinking is based on the current status of Casper FFG, with optimizations and
|
||||
specific attributes to be modified as is allowed by Solana's Proof of History
|
||||
(PoH) blockchain data structure.
|
||||
|
||||
### General Overview
|
||||
|
||||
Solana's validation network design is based on a rotating, stake-weighted randomly selected leader broadcasting network transactions in a PoH data structure to validating nodes. These nodes, upon receiving the leader's broadcast, have the opportunity to vote on the current state and PoH height by signing a transaction into the PoH stream.
|
||||
Solana's validation network design is based on a rotating, stake-weighted
|
||||
randomly selected leader broadcasting network transactions in a PoH data
|
||||
structure to validating nodes. These nodes, upon receiving the leader's
|
||||
broadcast, have the opportunity to vote on the current state and PoH height by
|
||||
signing a transaction into the PoH stream.
|
||||
|
||||
To become a Solana validator, a network node must deposit/lock-up some amount of SOL in a contract. This SOL will not be accessible for a specific time period. The precise duration of the staking lockup period has not been determined. However we can consider three phases of this time for which specific parameters will be necessary:
|
||||
To become a Solana validator, a network node must deposit/lock-up some amount
|
||||
of SOL in a contract. This SOL will not be accessible for a specific time
|
||||
period. The precise duration of the staking lockup period has not been
|
||||
determined. However we can consider three phases of this time for which
|
||||
specific parameters will be necessary:
|
||||
|
||||
- *Warm-up period*: which SOL is deposited and inaccessible to the node, however PoH transaction validation has not begun. Most likely on the order of days to weeks
|
||||
- *Validation period*: a minimum duration for which the deposited SOL will be inaccessible, at risk of slashing (see slashing rules below) and earning network rewards for the validator participation. Likely duration of months to a year.
|
||||
- *Cool-down period*: a duration of time following the submission of a 'withdrawal' transaction. During this period validation responsibilities have been removed and the funds continue to be inaccessible. Accumulated rewards should be delivered at the end of this period, along with the return of the initial deposit.
|
||||
- *Warm-up period*: which SOL is deposited and inaccessible to the node,
|
||||
however PoH transaction validation has not begun. Most likely on the order of
|
||||
days to weeks
|
||||
- *Validation period*: a minimum duration for which the deposited SOL will be
|
||||
inaccessible, at risk of slashing (see slashing rules below) and earning
|
||||
network rewards for the validator participation. Likely duration of months to a
|
||||
year.
|
||||
- *Cool-down period*: a duration of time following the submission of a
|
||||
'withdrawal' transaction. During this period validation responsibilities have
|
||||
been removed and the funds continue to be inaccessible. Accumulated rewards
|
||||
should be delivered at the end of this period, along with the return of the
|
||||
initial deposit.
|
||||
|
||||
Solana's trustless sense of time and ordering provided by its PoH data structure, along with its [avalanche](https://www.youtube.com/watch?v=qt_gDRXHrHQ&t=1s) data broadcast and transmission design, should provide subsecond confirmation times that scale with the log of the number of nodes in the network. This means we shouldn't have to restrict the number of validating nodes with a prohibitive 'minimum deposits' and expect nodes to be able to become validators with nominal amounts of SOL staked. This should also render validation pools, a proposed solution for economic censorship imposed by minimum staking amounts currently described in Casper, unnecessary and remove the concern for needing to put slashable stake at risk while relying on others to play by the rules.
|
||||
Solana's trustless sense of time and ordering provided by its PoH data
|
||||
structure, along with its
|
||||
[avalanche](https://www.youtube.com/watch?v=qt_gDRXHrHQ&t=1s) data broadcast
|
||||
and transmission design, should provide subsecond confirmation times that scale
|
||||
with the log of the number of nodes in the network. This means we shouldn't
|
||||
have to restrict the number of validating nodes with a prohibitive 'minimum
|
||||
deposits' and expect nodes to be able to become validators with nominal amounts
|
||||
of SOL staked. This should also render validation pools, a proposed solution
|
||||
for economic censorship imposed by minimum staking amounts currently described
|
||||
in Casper, unnecessary and remove the concern for needing to put slashable
|
||||
stake at risk while relying on others to play by the rules.
|
||||
|
||||
### Stake-weighted Rewards
|
||||
|
||||
Rewards are expected to be paid out to active validators as a function of validator activity and as a proportion of the percentage of SOL they have at stake out of the entirety of the staking pool.
|
||||
Rewards are expected to be paid out to active validators as a function of
|
||||
validator activity and as a proportion of the percentage of SOL they have at
|
||||
stake out of the entirety of the staking pool.
|
||||
|
||||
We expect to define a baseline annual validator payout/inflation rate based on the total SOL deposited. E.g. 10% annual interest on SOL deposited with X total SOL deposited as slashable on network. This is the same design as currently proposed in Casper FFG which has additionally specifies how inflation rates adjust as a function of total ETH deposited. Specifically, Casper validator returns are proportional to the inverse square root of the total deposits and initial annual rates are estimated as:
|
||||
We expect to define a baseline annual validator payout/inflation rate based on
|
||||
the total SOL deposited. E.g. 10% annual interest on SOL deposited with X total
|
||||
SOL deposited as slashable on network. This is the same design as currently
|
||||
proposed in Casper FFG which has additionally specifies how inflation rates
|
||||
adjust as a function of total ETH deposited. Specifically, Casper validator
|
||||
returns are proportional to the inverse square root of the total deposits and
|
||||
initial annual rates are estimated as:
|
||||
|
||||
| Deposit Size | Annual Validator Interest |
|
||||
|--------------|---------------------------|
|
||||
|-------------=|--------------------------=|
|
||||
| 2.5M ETH | 10.12% |
|
||||
| 10M ETH | 5.00% |
|
||||
| 20M ETH | 3.52% |
|
||||
| 40M ETH | 2.48% |
|
||||
|
||||
This has the nice property of potentially incentivizing participation around a target deposit size. Incentivisation of specific participation rates more directly (rather than deposit size) may something also worth exploring.
|
||||
This has the nice property of potentially incentivizing participation around a
|
||||
target deposit size. Incentivisation of specific participation rates more
|
||||
directly (rather than deposit size) may something also worth exploring.
|
||||
|
||||
The specifics of the Solana validator reward scheme are to be worked out in parallel with a design for transaction fee assignment as well as our storage mining reward scheme.
|
||||
The specifics of the Solana validator reward scheme are to be worked out in
|
||||
parallel with a design for transaction fee assignment as well as our storage
|
||||
mining reward scheme.
|
||||
|
||||
### Slashing rules
|
||||
|
||||
Unlike Proof of Work (PoW) where off-chain capital expenses are already deployed at the time of block construction/voting, PoS systems require capital-at-risk to prevent a logical/optimal strategy of multiple chain voting. We intend to implement slashing rules which, if broken, result some amount of the offending validator's deposited stake to be removed from circulation. Given the ordering properties of the PoH data structure, we believe we can simplify our slashing rules to the level of a voting lockout time assigned per vote.
|
||||
Unlike Proof of Work (PoW) where off-chain capital expenses are already
|
||||
deployed at the time of block construction/voting, PoS systems require
|
||||
capital-at-risk to prevent a logical/optimal strategy of multiple chain voting.
|
||||
We intend to implement slashing rules which, if broken, result some amount of
|
||||
the offending validator's deposited stake to be removed from circulation. Given
|
||||
the ordering properties of the PoH data structure, we believe we can simplify
|
||||
our slashing rules to the level of a voting lockout time assigned per vote.
|
||||
|
||||
I.e. Each vote has an associated lockout time (PoH duration) that represents a duration by any additional vote from that validator must be in a PoH that contains the original vote, or a portion of that validator's stake is slashable. This duration time is a function of the initial vote PoH count and all additional vote PoH counts. It will likely take the form:
|
||||
I.e. Each vote has an associated lockout time (PoH duration) that represents a
|
||||
duration by any additional vote from that validator must be in a PoH that
|
||||
contains the original vote, or a portion of that validator's stake is
|
||||
slashable. This duration time is a function of the initial vote PoH count and
|
||||
all additional vote PoH counts. It will likely take the form:
|
||||
|
||||
Lockout<sub>i</sub>(PoH<sub>i</sub>, PoH<sub>j</sub>) = PoH<sub>j</sub> + K * exp((PoH<sub>j</sub> - PoH<sub>i</sub>) / K)
|
||||
Lockout<sub>i</sub>(PoH<sub>i</sub>, PoH<sub>j</sub>) = PoH<sub>j</sub> + K *
|
||||
exp((PoH<sub>j</sub> - PoH<sub>i</sub>) / K)
|
||||
|
||||
Where PoH<sub>i</sub> is the height of the vote that the lockout is to be applied to and PoH<sub>j</sub> is the height of the current vote on the same fork. If the validator submits a vote on a different PoH fork on any PoH<sub>k</sub> where k > j > i and PoH<sub>k</sub> < Lockout(PoH<sub>i</sub>, PoH<sub>j</sub>), then a portion of that validator's stake is at risk of being slashed.
|
||||
Where PoH<sub>i</sub> is the height of the vote that the lockout is to be
|
||||
applied to and PoH<sub>j</sub> is the height of the current vote on the same
|
||||
fork. If the validator submits a vote on a different PoH fork on any
|
||||
PoH<sub>k</sub> where k > j > i and PoH<sub>k</sub> < Lockout(PoH<sub>i</sub>,
|
||||
PoH<sub>j</sub>), then a portion of that validator's stake is at risk of being
|
||||
slashed.
|
||||
|
||||
In addition to the functional form lockout described above, early implementation may be a numerical approximation based on a First In, First Out (FIFO) data structure and the following logic:
|
||||
In addition to the functional form lockout described above, early
|
||||
implementation may be a numerical approximation based on a First In, First Out
|
||||
(FIFO) data structure and the following logic:
|
||||
- FIFO queue holding 32 votes per active validator
|
||||
- new votes are pushed on top of queue (`push_front`)
|
||||
- expired votes are popped off top (`pop_front`)
|
||||
- as votes are pushed into the queue, the lockout of each queued vote doubles
|
||||
- votes are removed from back of queue if `queue.len() > 32`
|
||||
- the earliest and latest height that has been removed from the back of the queue should be stored
|
||||
- the earliest and latest height that has been removed from the back of the
|
||||
queue should be stored
|
||||
|
||||
It is likely that a reward will be offered as a % of the slashed amount to any node that submits proof of this slashing condition being violated to the PoH.
|
||||
It is likely that a reward will be offered as a % of the slashed amount to any
|
||||
node that submits proof of this slashing condition being violated to the PoH.
|
||||
|
||||
#### Partial Slashing
|
||||
In the schema described so far, when a validator votes on a given PoH stream, they are committing themselves to that fork for a time determined by the vote lockout. An open question is whether validators will be hesitant to begin voting on an available fork if the penalties are perceived too harsh for an honest mistake or flipped bit.
|
||||
#### Partial Slashing In the schema described so far, when a validator votes on
|
||||
a given PoH stream, they are committing themselves to that fork for a time
|
||||
determined by the vote lockout. An open question is whether validators will be
|
||||
hesitant to begin voting on an available fork if the penalties are perceived
|
||||
too harsh for an honest mistake or flipped bit.
|
||||
|
||||
One way to address this concern would be a partial slashing design that results in a slashable amount as a function of either:
|
||||
One way to address this concern would be a partial slashing design that results
|
||||
in a slashable amount as a function of either:
|
||||
|
||||
1) the fraction of validators, out of the total validator pool, that were also slashed during the same time period (ala Casper),
|
||||
2) the amount of time since the vote was cast (e.g. a linearly increasing % of total deposited as slashable amount over time), or both.
|
||||
1) the fraction of validators, out of the total validator pool, that were also
|
||||
slashed during the same time period (ala Casper), 2) the amount of time since
|
||||
the vote was cast (e.g. a linearly increasing % of total deposited as slashable
|
||||
amount over time), or both.
|
||||
|
||||
This is an area currently under exploration
|
||||
|
||||
|
||||
### Penalties
|
||||
As previously discussed, annual validator reward rates are to be specified as a function of total amount staked. The network rewards validators who are online and actively participating in the validation process throughout the entirety of their *validation period*. For validators that go offline/fail to validate transactions during this period, their annual reward is effectively reduced.
|
||||
### Penalties As previously discussed, annual validator reward rates are to be
|
||||
specified as a function of total amount staked. The network rewards validators
|
||||
who are online and actively participating in the validation process throughout
|
||||
the entirety of their *validation period*. For validators that go offline/fail
|
||||
to validate transactions during this period, their annual reward is effectively
|
||||
reduced.
|
||||
|
||||
Similarly, we may consider an algorithmic reduction in a validator's active amount staked amount in the case that they are offline. I.e. if a validator is inactive for some amount of time, either due to a partition or otherwise, the amount of their stake that is considered ‘active’ (eligible to earn rewards) may be reduced. This design would be structured to help long-lived partitions to eventually reach finality on their respective chains as the % of non-voting total stake is reduced over time until a super-majority can be achieved by the active validators in each partition. Similarly, upon re-engaging, the ‘active’ amount staked will come back online at some defined rate. Different rates of stake reduction may be considered depending on the size of the partition/active set.
|
||||
Similarly, we may consider an algorithmic reduction in a validator's active
|
||||
amount staked amount in the case that they are offline. I.e. if a validator is
|
||||
inactive for some amount of time, either due to a partition or otherwise, the
|
||||
amount of their stake that is considered ‘active’ (eligible to earn rewards)
|
||||
may be reduced. This design would be structured to help long-lived partitions
|
||||
to eventually reach finality on their respective chains as the % of non-voting
|
||||
total stake is reduced over time until a super-majority can be achieved by the
|
||||
active validators in each partition. Similarly, upon re-engaging, the ‘active’
|
||||
amount staked will come back online at some defined rate. Different rates of
|
||||
stake reduction may be considered depending on the size of the partition/active
|
||||
set.
|
||||
|
|
|
@ -19,8 +19,8 @@ A fraction of a [block](#block); the smallest unit sent between
|
|||
#### block
|
||||
|
||||
A contiguous set of [entries](#entry) on the ledger covered by a [vote](#ledger-vote).
|
||||
The length of a block is network hyper parameter, specified in [ticks](#tick).
|
||||
Also called [voting period](#voting-period).
|
||||
The duration of a block is some number of [ticks](#tick), configured via the
|
||||
[control plane](#control-plane). Also called [voting period](#voting-period).
|
||||
|
||||
#### bootstrap leader
|
||||
|
||||
|
@ -226,9 +226,9 @@ The role of a [fullnode](#fullnode) when it is validating the
|
|||
|
||||
#### vote
|
||||
|
||||
See [ledger vote](#ledger-vote)
|
||||
See [ledger vote](#ledger-vote).
|
||||
|
||||
#### voting period
|
||||
|
||||
See [block](#block)
|
||||
The duration of a [block](#block).
|
||||
|
||||
|
|
Loading…
Reference in New Issue