๐ญValidation
Maintaining agreement over the growing history of the system.
Last updated
Maintaining agreement over the growing history of the system.
Last updated
The Nominated Proof of Stake (NPoS) employed in the Joystream ecosystem is an advanced consensus mechanism that relies on the collaborative efforts of validators and nominators to ensure network security. Validators, pivotal in this framework, are tasked with block production and transaction validation. To qualify as validators, participants must bond a specified quantity of tokens, a process which symbolizes their commitment and aligns their interests with the network's stability. Once tokens are bonded, they can then be staked for engaging in block validation and acquiring rewards. Meanwhile, nominators, after initially bonding their tokens, play a crucial role by selecting reliable validators and allocating their bonded tokens to them, thus bolstering the network's overall security and efficiency. In Joystream, an 'era' denotes a set period during which staking rewards are determined and allocated in accordance with the contributions of validators and nominators. These rewards serve dual purposes: they incentivize participation and offset the inflationary impact of new token generation. To safeguard network integrity, Joystream incorporates a 'slashing' mechanism. This punitive measure targets validators engaging in harmful activities or exhibiting incompetence, penalizing them by destroying a portion of their staked tokens.
Tokens are minted as part of the inflationary mechanism to compensate validators and nominators for their participation and contribution to network security. This minting process is automated and governed by the network's consensus rules. The newly minted tokens are distributed as rewards at the end of each era. The mathematical expression used in reward computation is referred as reward curve and it's graph is as follows
The minimum and maximum inflation for stakers reward values of 0.705%
and 3%
are highlighted in the y axis and the ideal staking percentage of 50%
is highlighted in the x axis. The reward curve is such that stakers are incentivised if the the current staking percentage is below the ideal rate and disincentivized if it's above the ideal rate.
The current percentage of supply staked can be inspected in Joystream the subscan dashboard
Below is an illustrative example on how validator can determined their profit margin given their initial operational cost of setting up a server. Let's start with the following assumptions:
Total Supply of Tokens: 1,000,000,000 tokens.
Annual Inflation Rate for NPoS Rewards: 1.3%.
Percentage of Tokens Staked: 12%.
Era Length: 6 hours.
Validator 1 (v1): 40M JOY, 20% commission (20M validators, 20M nominators).
Validator 2 (v2): 40M JOY, 40% commission (20M validators, 20M nominators).
Validator 3 (v3): 30,000,000 JOY, 10% commission (15M validators, 15M nominators).
Validator 4 (v4): 10M JOY, 0% commission (2M validator, 8M nominators).
Total Staked Tokens: 12% of 1,000,000,000 = 120,000,000 JOY.
Annual Reward Pool: 1,000,000,000 * 1.3% = 13,000,000 JOY.
Reward Pool per Era: 13,000,000 JOY / (24 * 365 / 6) = 8910.96 JOY (approx).
Era points are a measure of a validator's contribution to the network during an era. These points are awarded for various actions like validating blocks, producing blocks, and other network-supportive actions. The specific allocation of era points can vary based on the network's rules and validators' performance. They are not predictable and they add a probabilistic component to the validator payout scheme.
Validator era point are used to computed the share of each validator for the total reward pool, using the formula validatorPoints / totalPoints
: where totalPoints
is the total number of points earned by all validators in the era, and validatorPoints
is the number of points awarded to each unique validator during the same era. Suppose for the sake of simplicity that the share is proportional to the validator stake percentage over the total staked amount in the network:
Validator 1's share v1s
: 40,000,000 / 120,000,000.
Validator 2's share v2s
: 40,000,000 / 120,000,000.
Validator 3's share v3s
: 30,000,000 / 120,000,000.
Validator 4's share v4s
: 10,000,000 / 120,000,000.
However, in practice, era points are not strictly proportional to stake but depend on actual performance and contributions, which can vary.
Validator 1's Total Reward:
Era Points Share: v1s
* 8910.96 JOY = 2970.32 JOY.
Commission: 20% of 2970.32 JOY = 594.06 JOY (goes to validator 1)
Validator Share: (80% of 2970.32) * 20M/40M = 1188.12 JOY
Nominators Share: (80% of 2970.32) * 20M/40M = 1188.12 JOY
Validator 2's Total Reward:
Era Points Share: v2s
* 8910.96 JOY = 2970.32 JOY.
Commission: 40% of 2970.32 JOY = 1188.12 JOY (goes to validator 2)
Validator Share: (60% of 2970.32) * 20M/40M = 950.4 JOY
Nominators Share: (60% of 2970.32) * 20M/40M = 950.4 JOY
Validator 3's Total Reward:
Era Points Share: v3s
* 8910.96 JOY = 2227.74 JOY.
Commission: 10% of 2227.74 JOY = 222.77 JOY (goes to validator 3)
Validator Share: (90% of 2227.74) * 15M/30M = 1002.48 JOY
Nominators Share: (90% of 2227.74) * 15M/30M = 1002.48 JOY,
Validator 4's Total Reward:
Era Points Share: v4s
* 8910.96 JOY = 742.58 JOY.
Commission: 0% of 2227.74 JOY = 0 JOY (goes to validator 4)
Validator' Share: (100% of 742.58) * 2M/10M = 148.51 JOY.
Nominators Share: (100% of 742.58) * 8M/10M = 593.94 JOY.
Single nominators reward are distributed according to share of staked JOY, so for example if in the Validator 1 case there are two nominators staking 10M JOY each then every one of them gets:
Nominator Share * 50% = 950.4 * 50% = 475.2 JOY
From the numbers above validators can compute the respective USD revenue per era, which can then be used for budgeting
bonding duration
The amount of eras
before a bonded
account that unbonds has to wait until their tokens can be unlocked by the staking
lock.
This will allow the tokens to be staked for "rivalrous" purposes, and, if no other locks are applied, be spent freely.
Set to 112 eras
, eg ~403200 blocks, or 28 days.
commission
candidates
Validators and nominators get paid from block production on the network, where validators can set a variable commission rate, which is initially subtracted from the total rewards that validator is entitled to (for that period), where the commission determines the rate of distribution for the remaining rewards set out for the nominators that are backing that validator.
Set by the validator as a percentage of the reward for each era
.
election
An operation performed automatically on-chain, by the runtime, to elect a new set of validators for the upcoming era
. Who gets elected depends on a variety of factors, such as the amount of candidates
, the number of slots
and the total active stake
for each validator.
era
A (whole) number of sessions
, which is the period that the validator set (and each validator's active nominator set) is recalculated and where rewards are paid out.
Target is 6 sessions
, eg ~3600 blocks, or 6h.
era points
Every time a specific validator produces a block, they earn points. The rewards for the individual validator for that era
are proportional to their era points, which are reset when a new era
begins.
nominator
Accounts that select a set of validators to nominate by bonding their tokens. Nominators receive some of the validators' rewards, but are also liable for slashing if their nominated validators misbehave.
rewards
The shared rewards earned by the entire validator set for each era
. For the individual validator
, they are proportional to the era points
earned.
Note that the total active stake
does not impact the era points
or rewards directly, but of course, unless the validator gets a slot, they will not earn any rewards.
session
A session is a Joystream implementation term for a period that has a constant set of validators. Validators can only join or exit the validator set at a session change.
Target is ~600 blocks, or 1h.
session keys
Hot (must be online) keys that are used for performing network operations by validators, for example, signing GRANDPA commit messages.
slashing
The removal of a percentage of an account's JOY as a punishment for a validator acting maliciously or incompetently (e.g., equivocating or remaining offline for an extended period).
Will apply equally to nominators of a validator that gets slashed.
slots
Total amount of spots in the validator set at any given time. Can be adjusted up or down through a proposal.
staking
The act of bonding JOY tokens by putting them up as "collateral" for a chance to produce a valid block (and thus obtain a block reward). Validators and nominators stake their JOY in order to secure the network.
total active stake
The sum of stake put up by the validator itself, plus the amount each of the (potential) nominators
backs the validator with. Used to the determine whether the validator gets a slot
in the validator set or not in the election
for the upcoming era.
Experienced with how to setup and maintain high performance IT infrastructure
Access to highly performant and reliable IT infrastructure, with high storage, (up & down) bandwidth and processing capacity
Able to securely store keys
Hold sufficient amount of the native platform token to put at stake
currently at least JOY 41.667k in a single account, which is the minimum to sign up โ actually getting a validator slot likely requires more
The Joystream blockchain, and therefore the joystream-node
is built on the substrate framework, developed for the Polkadot ecosystem. As Joystream is still in infancy on mainnet, we refer to the their expertise for the technical specification and recommendations:
CPU
x86-64 compatible;
Intel Ice Lake, or newer (Xeon or Core series); AMD Zen3, or newer (EPYC or Ryzen);
4 physical cores @ 3.4GHz;
Simultaneous multithreading disabled (Hyper-Threading on Intel, SMT on AMD);
Prefer single-threaded performance over higher cores count. A comparison of single-threaded performance can be found here.
Storage
An NVMe SSD of 1 TB (As it should be reasonably sized to deal with blockchain growth). An estimation of current chain snapshot sizes can be found here. In general, the latency is more important than the throughput.
Memory
16GB DDR4 ECC.
System
Linux Kernel 5.16 or newer.
Network
The minimum symmetric networking speed is set to 500 Mbit/s (= 62.5 MB/s). This is required to support a large number of parachains and allow for proper congestion control in busy network situations.
It should be obvious that given the life span and size โ thus state and transaction activity โ of Polkadot relative to Joystream at this stage, it is certainly fine to scale down on things like storage...
The instructions below cover Linux binaries only. If you want to build from source, clone the repo and follow the build steps there.
Every time something is written in <brackets>
, this means you have to replace this with your input, without the <>
.
When something is written in "double_quotes"
, it means the number/data will vary depending on your node or the current state of the blockchain.
For terminal commands:
$
means you must type what comes afterwards
#
means it's just a comment/explanation for the readers convenience
For the purposes of simplicity, we will assume:
You are user joystream
, with sudo priveliges.
You want to save everything in /home/joystream/bin/
Find the latest release here or get the tag from the command line with:
At the time of writing, the latest release is v12.1001.0
, whereas the last node binary is from version v12.1000.0
(mainnet)
Assuming it starts syncing, you can stop it right away with ctrl+c
The node lets you set a variety of option flags. You can display them all with ./joystream-node --help
Some basic options
you should enable or consider:
--chain <CHAIN_SPEC>
Specify the chain specification. It can be one of the predefined ones (dev, local, or staging) or it can be a path to a file with the chainspec (such as one exported by the
build-spec
subcommand).
Required
Without this flag, you will not connect the chain.
--pruning <PRUNING_MODE>
Specify the state pruning mode, a number of blocks to keep or 'archive'. Default is to keep all block states if the node is running as a validator (i.e. 'archive'), otherwise state is only kept for the last 256 blocks.
Required for validators
If you want to be a validator, the node must run with --pruning archive
If you start syncing without that flag enabled, you will have to wipe your node and sync again if you change your mind.
--validator
Enable validator mode. The node will be started with the authority role and actively participate in any consensus task that it can (e.g. depending on availability of local keys).
Required for validators
Unlike with --pruning
, it only has to be set when you are actually in the validator set to have an effect, so you don't have to re-sync if you forget while syncing.
--name
The human-readable name for this node. The node name will be reported to the telemetry server, if enabled.
Optional
May serve some benefits if you want someone to nominate you, but may make it easier to identity you.
As a validator, you should (as a bare minimum) be very restrictive in terms of RPC access to your node. Go through the options, and double check that the defaults are in line with your preferences and risk tolerance.
Running as a service means that the node will continue running as a daemon, and you can enable it to restart in case of crashes and on reboot.
It requires sudo privileges. If you are not user root
, add sudo
before commands.
Example file below, with essentials only:
With your validator node up and running, you are now ready to set up keys and announce your intentions on chain.
In the terminal on your node (will only work if you are on running the chain on the same machine!):
Where 0xabc...123
(a much longer string in reality) is a concatenation of four public keys hex-encoded. The private keys should have been injected in your base-path
. Make sure you copy this string over somewhere, as you need it later.
Assuming you only did this once (while running this this chain), and you didn't set a different --base-path
flag:
Warning:
It's both bad practice, and a possible slashing risk, to keep multiple set of session keys on one node. If you wanted to try the command, made a mistake, or for whatever reason want to switch them, delete them. If you have had set them on chain (see next steps), you can change them before you get into the validator set.
Keeping the same set of keys, on multiple nodes, all running with the --validator
enabled, will cause a slash. A good backup system could include backup nodes, but be careful. It's better to get "booted" for an era than to double sign blocks. It will be treated as an attack even if just by accident.
For the time being, we will only show how to do this with Polkadot{.js} apps, a web based UI, and the Polkadot{.js} extension, a that works with both the aforementioned UI and Joystreams own Pioneer.
As the polkadot-js UI serves lots of projects in the substrate ecosystem, you have to make sure to set the correct endpoint, meaning which network (and node) you connect to. The link above does Joystream automatically, and sets it as default in local storage (until another is set).
The network endpoint can also be set manually by clicking the top left corner, and selecting "Live Networks" -> "Joystream" (hosted by Jsgenesis) before clicking "Switch", from the meny that appears.
This will display the logo, network name, node version and latest block height of the chain you are currently connected to as shown below.
With Polkadot-js
You need two keys for this, one to be the controller
and one as the stash
. The latter holds the stake and must sign at least once to "delegate" to the controller
which is running the "day to day" operations.
Assuming you are fully synched, your node is running, and you have
Steps:
Go to the "staking actions" tab - "Network" -> "Staking" -> "Accounts", and click the "+ Validator" button in the top right corner.
Select a stash
and controller
account from the dropdown, set the "value bonded" as the amount you want to stake, and choose a "payment destination", then hit "next".
Paste in the public session keys (0xabc...123
), choose a "reward commission percentage" and whether you want to allow nominations or not, then click "Bond & Validate".
If you are preparing this for later, click the "+ Stash" button instead. This allows you to wait for your session keys and/or synching your node.
Assuming the transaction went through, you will now appear under the "waiting" tab here. That means you are in the queue for joining the validator set, but when (and whether) you actually join depends on the competition for getting a slot.
At all times, there is a limit to how many can become validators. What that number is set by the council. The current value can be found in the chain state -> "staking" -> "validatorCount".
Suppose that number is n
, and that there are m
validators that, towards the end of each era
were already validating or joined the queue:
If n >= m
, all will be elected
If n<m
, the n
validators with the highest total active stake will be elected for the upcoming era
Notes:
An era
lasts ~6h.
total active stake refers to the active stake for the validator itself, plus all of their nominators.
Transaction Rejected
There is a minimum threshold of funds required to stake as a validator. As you can get slashed, that means you can not "re-use" tokens that are staked for other "slashable" purposes, such as role stake.
That number can be found in the chain state -> "staking" -> "minValidatorBond". (In base value HAPI
, meaning 1*10^-10 JOY
)
Another reason the transaction can be rejected is if the maximum number of bonded
accounts have declared as validators. That number can be found in the chain state -> "staking" -> "maxValidatorsCount". How many there are currently can be found in the chain state -> "staking" -> "counterForValidators".
There are of course a limitless amount of other reasons the transaction could be rejected if you constructed it yourself in the cli.
TODO