Initial validator sets pallet (#187)

* Initial work on a Validator Sets pallet

* Update Validator Set docs per current discussions

* Update validator-sets primitives and storage handling

* Add validator set pallets to deny.toml

* Remove Curve from primitives

Since we aren't reusing keys across coins, there's no reason for it to be
on-chain (as previously planned).

* Update documentation on Validator Sets

* Use Twox64Concat instead of Identity

Ensures an even distribution of keys. While xxhash is breakable, these keys
aren't manipulatable by users.

* Add math ops on Amount and define a coin as 1e8

* Add validator-sets to the runtime and remove contracts

Also removes the randomness pallet which was only required by the contracts
runtime.

Does not remove the contracts folder yet so they can still be referred to while
validator-sets is under development. Does remove them from Cargo.toml.

* Add vote function to validator-sets

* Remove contracts folder

* Create an event for the Validator Sets pallet

* Remove old contracts crates from deny.toml

* Remove line from staking branch

* Remove staking from runtime

* Correct VS Config in runtime

* cargo update

* Resolve a few PR comments on terminology

* Create a serai-primitives crate

Move types such as Amount/Coin out of validator-sets. Will be expanded in the
future.

* Fixes for last commit

* Don't reserve set 0

* Further fixes

* Add files meant for last commit

* Remove Staking transfer
This commit is contained in:
Luke Parker
2023-01-04 22:52:41 -05:00
committed by GitHub
parent 52913a6e8d
commit e979883f2d
26 changed files with 572 additions and 1151 deletions

View File

@@ -5,29 +5,10 @@ for various connected networks, offering secure decentralized custody of foreign
assets to applications built on it.
Serai is exemplified by Serai DEX, an automated-market-maker (AMM) decentralized
exchange, allowing swapping BTC, ETH, USDC, DAI, and XMR. It is the premier
exchange, allowing swapping Bitcoin, Ether, DAI, and Monero. It is the premier
application of Serai.
### Substrate
Serai is based on [Substrate](https://docs.substrate.io), a blockchain framework
offering a robust infrastructure.
### Smart Contracts
Serai offers WASM-based smart contracts. All applications are built over these
contracts, enabling composable interactions within a mutual layer. These
contracts are primarily written in [ink!](https://ink.substrate.io/), a
framework for building contracts in Rust.
Initially, smart contract deployment will not be enabled. Solely Serai DEX will
be available, due to the variety of economic considerations around securing the
multisig. Serai may expand in the future with more explicitly added
applications, each with tailored economic models, or may enable arbitrary
contract deployment. At this time, we solely plan for Serai DEX's availabiliy.
### Application Calls
Applications, such as Serai DEX, may be called via calling their relevant smart
contracts. At a low level, this is done via specifying the address of the
contract being interacted with, along with SCALE-encoded calldata.

View File

@@ -5,41 +5,30 @@
These are the list of types used to represent various properties within the
protocol.
| Alias | Shorthand | Type |
|-------------------------|-----------|----------|
| Amount | Amount | u64 |
| Curve | Curve | u16 |
| Coin | Coin | u32 |
| Global Validator Set ID | GVSID | u32 |
| Validator Set Index | VS | u8 |
| Key | Key | Vec\<u8> |
### Curves
Integer IDs for various curves. It should be noted some curves may be the same,
yet have distinct IDs due to having different basepoints, and accordingly
different keys. For such cases, the processor is expected to create one secret
per curve, and then use DLEq proofs to port keys to other basepoints as needed.
| Curve | ID |
|-----------|----|
| Secp256k1 | 0 |
| Ed25519 | 1 |
| Alias | Type |
|------------------------|--------------------------------|
| Amount | u64 |
| Coin | u32 |
| Session | u32 |
| Validator Set Index | u16 |
| Validator Set Instance | (Session, Validator Set Index) |
| Key | Vec\<u8> |
### Networks
Every network connected to Serai operates over a specific curve. While the
processor generates keys for curves, these keys are bound to specific networks
via an additive offset created by hashing the network's name (among other
things). The network's key is used for all coins on that network.
Every network connected to Serai operates over a specific curve. The processor
generates a distinct set of keys per network. Beyond the key-generation itself
being isolated, the generated keys are further bound to their respective
networks via an additive offset created by hashing the network's name (among
other properties). The network's key is used for all coins on that network.
Networks are not acknowledged by the Serai network, solely by the processor.
| Network | Curve |
|----------|-------|
| Bitcoin | 0 |
| Ethereum | 0 |
| Monero | 1 |
| Network | Curve |
|----------|-----------|
| Bitcoin | Secp256k1 |
| Ethereum | Secp256k1 |
| Monero | Ed25519 |
### Coins
@@ -48,7 +37,6 @@ Coins exist over a network and have a distinct integer ID.
| Coin | Network | ID |
|----------|----------|----|
| Bitcoin | Bitcoin | 0 |
| Ethereum | Ethereum | 1 |
| USDC | Ethereum | 2 |
| DAI | Ethereum | 3 |
| Monero | Monero | 4 |
| Ether | Ethereum | 1 |
| DAI | Ethereum | 2 |
| Monero | Monero | 3 |

View File

@@ -1,35 +0,0 @@
# Multisig
Multisigs are confirmed on-chain by the `Multisig` contract. While the processor
does create the multisig, and sign for it, making it irrelevant to the chain,
confirming it on-chain solves the question of if the multisig was successfully
created or not. If each processor simply asked all other processors for
confirmation, votes lost to the network would create an inconsistent view. This
is a form of the Byzantine Generals Problem, which can be resolved by placing
votes within a BFT system.
Confirmation requires all participants confirm the new set of keys. While this
isn't BFT, despite the voting process being BFT, it avoids the scenario where
only t (where t is the BFT threshold, as used in the t-of-n multisig)
successfully generated shares, actually creating a t-of-t multisig in practice,
which is not BFT. This does mean a single node can delay a churn, which is
expected to be handled via a combination of slashing, and if necessary, removal.
Validators are allowed to vote multiple times across sets of keys, with the
first set to be confirmed becoming the set of keys for that validator set. These
keys remain valid for the validator set until it is changed. If a validator set
remains consistent despite the global validator set updating, their keys carry.
If a validator set adds a new member, and then loses them, their historical keys
are not reused.
Once new keys are confirmed for a given validator set, they become tracked and
the recommended set of keys for incoming funds. The old keys are still eligible
to receive funds for a provided grace period, requiring the current validator
set to track both sets of keys. The old keys are also still used to handle all
outgoing payments as well, until the end of the grace period, at which point
they're no longer eligible to receive funds and they forward all of their funds
to the new set of keys.
### `vote(keys: Vec<Option<Key>>)`
Lets a validator vote on a set of keys for their validator set.

19
docs/protocol/Staking.md Normal file
View File

@@ -0,0 +1,19 @@
# Staking
Serai's staking pallet offers a DPoS system. All stake which enters the system
is delegated somewhere. Delegates can then bond their stake to different
validator sets, justifying their inclusion and providing financial security.
Delegators may transfer stake whenever, so long as that stake isn't actively
bonded. Delegators may also unstake whenever, so long as the prior condition
is still met.
### Stake (message)
- `delegate` (Address): Address to delegate the newly added stake to.
- `amount` (Amount): Amount to stake and delegate.
### Unstake (message)
- `delegate` (Address): Address the stake is currently delegated to.
- `amount` (Amount): Amount to unstake.

View File

@@ -2,29 +2,80 @@
Validator Sets are defined at the protocol level, with the following parameters:
- `index` (VS): Validator set index, a global key atomically increasing
from 0.
- `bond` (Amount): Amount of bond per key-share of this validator set.
- `coins` (Vec\<Coin>): Coins managed by this validator set.
- `bond` (Amount): Amount of bond per key-share.
- `coins` (Vec\<Coin>): List of coins within this set.
- `participants` (Vec\<Coin>): List of participants within this set.
At launch, there will solely be validator set 0, managing Bitcoin, Ethereum,
USDC, DAI, and Monero.
Validator Sets are referred to by `ValidatorSetIndex` yet have their data
accessible via `ValidatorSetInstance`.
### Multisig Management
Every validator set is expected to form a t-of-n multisig, where n is the amount
of key shares in the validator set and t is `n / 3 * 2 + 1`, per curve required
by its coins. This multisig is secure to hold funds up to 67% of the validator
set's bond value. If funds exceed that threshold, there's more value in the
multisig than in the supermajority of bond that must be put forth to control it.
At launch, there will solely be Validator Set 0, managing Bitcoin, Ether, DAI,
and Monero.
### Participation in the BFT process
All validator sets participate in the BFT process. Specifically, a block
containing `Oraclization`s for a coin must be approved by the BFT majority of
the validator set responsible for it, along with the BFT majority of the network
by bond.
All Validator Sets participate in the BFT process described under
[Consensus](./Consensus.md). Specifically, a block containing In Instructions
for a coin must be approved by the BFT majority of the Validator Set responsible
for it, along with the BFT majority of the network by bond.
At this time, `Oraclization`s for a coin are only expected to be included when a
validator from the validator set managing the coin is the producer of the block
At this time, In Instructions for a coin are only expected to be included when a
validator from the Validator Set managing the coin is the producer of the block
in question.
Since there is currently only one Validator Set, the aforementioned BFT
conditions collapse to simply the BFT majority by bond. Ensuring BFT majority
per responsible Validator Set is accordingly unimplemented for now.
### Multisig
Every Validator Set is expected to form a `t`-of-`n` multisig, where `n` is the
amount of key shares in the Validator Set and `t` is `n * 2 / 3 + 1`, for each
of its networks. This multisig is secure to hold coins up to 67% of the
Validator Set's bonded value. If the coins exceed that threshold, there's more
value in the multisig than in the supermajority of bond that must be put forth
to control it. Accordingly, it'd be no longer financially secure, and it MUST
reject newly added coins which would cross that threshold.
### Multisig Creation
Multisigs are created by processors, communicating via their Coordinators.
They're then confirmed on chain via the `validator-sets` pallet. This is done by
having 100% of participants agree on the resulting group key. While this isn't
fault tolerant, a malicious actor who forces a `t`-of-`n` multisig to be
`t`-of-`n-1` reduces the fault tolerance of the multisig which is a greater
issue. If a node does prevent multisig creation, other validators should issue
slashes for it/remove it from the Validator Set entirely.
Due to the fact multiple key generations may occur to account for
faulty/malicious nodes, voting on multiple keys for a single coin is allowed,
with the first key to be confirmed becoming the key for that coin.
Placing it on chain also solves the question of if the multisig was successfully
created or not. Processors cannot simply ask each other if they succeeded
without creating an instance of the Byzantine Generals Problem. Placing results
within a Byzantine Fault Tolerant system resolves this.
### Multisig Lifetime
The keys for a Validator Set remain valid until its participants change. If a
Validator Set adds a new member, and then they leave, the set's historical keys
are not reused.
### Multisig Handoffs
Once new keys are confirmed for a given Validator Set, they become tracked and
the recommended set of keys for incoming coins. The old keys are still eligible
to receive coins for a provided grace period, requiring the current Validator
Set to track both sets of keys. The old keys are also prioritized for handling
outbound transfers, until the end of the grace period, at which point they're
no longer eligible to receive coins and they forward all of their coins to the
new set of keys. It is only then that validators in the previous instance of the
set, yet not the current instance, may unbond their stake.
### Vote (message)
- `coin` (Coin): Coin whose key is being voted for.
- `key` (Key): Key being voted on.
Once a key is voted on by every member, it's adopted as detailed above.

View File

@@ -1,44 +0,0 @@
# Validators
### Register (message)
- `validator` (signer): Address which will be the validator on Substrate.
- `manager` (signer): Address which will manage this validator.
- `set` (VS): Validator set being joined.
Marks `validator` as a validator candidate for the specified validator set,
enabling delegation.
### Delegate (message)
- `delegator` (signer): Address delegating funds to `validator`.
- `validator` (address): Registered validator being delegated to.
- `amount` (Amount): Amount of funds being delegated to `validator`.
Delegated funds will be removed from `delegator`'s wallet and moved to
`validator`'s bond. `amount` must be a multiple of the validator set's bond, and
`delegator` must be `validator`'s manager.
### Undelegate (message)
- `delegator` (signer): Address removing delegated funds from `validator`.
- `validator` (address): Registered validator no longer being delegated to.
- `amount` (Amount): Amount of funds no longer being delegated to
`validator`.
`delegator` must be `validator`'s manager, and `amount` must be a multiple of
the validator set's bond. `validator` is scheduled to lose an according amount
of key shares at the next churn, and once they do, the specified amount will be
moved from `validator`'s bond to `delegator`'s wallet.
`validator`'s bond must be at least the validator set's bond after the
undelegation.
### Resign (message)
- `manager` (signer): Manager of `validator`.
- `validator` (address): Validator being removed from the pool/candidacy.
If `validator` is active, they will be removed at the next churn. If they are
solely a candidate, they will no longer be eligible for delegations. All bond is
refunded after their removal.