Skip to content

Commit

Permalink
feat: Add heartbeats and additional rewards
Browse files Browse the repository at this point in the history
Copied from #2026 with the base as the `palazzo` branch.

close #1993 .
  • Loading branch information
gordsport committed Feb 22, 2024
1 parent 092f3ff commit 1707f97
Showing 1 changed file with 62 additions and 1 deletion.
63 changes: 62 additions & 1 deletion protocol/0064-VALP-validator_performance_based_rewards.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Validator performance based rewards

## Network Parameters

1. `ethereum_heartbeat_period`: This parameter defines how many ethereum events need to pass (in average) for a validator to have to forward a heartbeat event. If it is set to 0, heartbeats are deactivated.

Valid range is any integer >= 0
The initial value is 128.

1. `ethereum_read_heartbeat_period`: This parameter defines how many ethereum events need to pass (in average) for a validator to have to forward a heartbeat event. If it is set to 0, heartbeats are deactivated.
Valid range is any integer >= 0
The initial value is 128.

1. `performance_weights` is a vector containing four integer values w0,w1,w2,w3; this parameter defines the weights of the different performance measurements that impact the reward. The weight formula (given performance values p1, p2 and p3) is w0*p1*p2*p3 + w1*p1+w2*p2+w3*p3).
If more performance measurements are added later, this vector is expanded correspondingly.

Legal values are all floats that sum up to 1. The initial value is (0,1,0,0)

## Adjusting Validator Rewards Based on Performance

The Vega chain is a delegated proof-of-stake based chain where validators are rewarded from fees generated or from on-chain treasury.
Expand All @@ -13,7 +29,7 @@ The purpose of the specification is to define how the validator rewards will be

### Tendermint validators

Goal: Detect how long a validator is offline and punish them
Goal 1: Detect how long a validator is offline and punish them
Detection: Validator does not act as a leader

For each block tendermint provides information about who is the proposer. The selection of the proposer is deterministic and is proportional roughly to the voting power of the validator. Therefore we can calculate the performance of a validator in the following way:
Expand All @@ -36,6 +52,50 @@ be modified and set to neutral defaults (i.e., 0)

Then `validator_performance = max(0.05, min((p'/expected, 1))`

Goal 2: Detect unforwarded Ethereum events and lack or read access and punish the validator that does not forward them
Detection: Events forwarded by some validators are not forwarded by others.

#### Ethereum Heartbeat

For the Ethereum Heartbeat, we use the network parameter `ethereum_heartbeat_period`. This parameter should be either 0 or a value bigger than the number of validators; the recommended initial value is 128, which would create a hearbeat per validator about every 20 minutes (i.e., about 120 heartbeats per validator per epoch). Legal values are all integers larger or equal to 0.

For every Ethereum block, if the hash of this block mod `ethereum_heartbeat_period` equals the identity of the a validator (taken mod ethereum_heartbeat_period)+1, then this validator has to forward this as an Ethereum event. This event is confirmed by other validators just like any other Ethereum event, but then ignored. If that block also contains a valid Vega event that requires an action, this is forwarded independently by the normal event forwarding mechanisms. The heartbeat also does contain the Ethereum hash of the corresponding block.
If the parameter is set to 0, the heartbeats are effectively turned off.

If a validator forwards a heartbeat, all other validators have to validate its correctness by checking if the hashes work out.

#### Ethereum Read Access Heartbeat

For every Ethereum block, if the hash of [The balance of the key that initiated the first transaction on the block / the random value of that block] mod `ethereum_read_heartbeat_period` equals the identity of the a validator (taken mod ethereum_read_heartbeat_period)+1, then this validator has to forward this as an Ethereum event. This event is confirmed by other validators just like any other Ethereum event, but otherwise ignored. If that block also contains a valid Vega event that requires an action, this is forwarded independently by the normal event forwarding mechanisms.

#### Performance Measurements

t the end of each epoch, it is counted how many Ethereum events have been forwarded by each validator; this is (number_of_ethereum_blocks_per_epoch)/`ethereum_heartbeat_period`)+number_of_ethereum_events_per_validator

Let `expected_f` be the maximum number of Ethereum events forwarded by any Validator given above conditions (i.e. the best validator defines the expectation), and `f` be the number of blocks a given validator has forwarded. If `expected_f` equals zero, then all scores are set to 1.
Let `low_volume_correction` be `abs(3-expected_f)`.

[Comment: expected_f is not calculated using statistics, as that would mean that an issue with the Ethereum chain would cause punishment for the validators. A more precise estiimate (all validators coiunting what all others should forward) is also possilbe, but unnecessarily complex).


Else, validator_ethereum_performance = `(min((f+low_volume_correction)/(expected_f)*1.1, 1)))`,

The exact same calculation is used to compute validator_ethereum_read_performance.

Explanation: low_volume_correction handle the case that the number of events is very low, and a validator might just by bad luck never get anything to forward (which also would only happen if the heartbeat is deactivated). Thus, if a validator is expected to forward 2 or less events, it is not penalised if it didn't forward any.
The multiplication with 1.1 is adding preventing a validator to get penalised if they got slightly less than others (which always can happen due to the random distribution). Thus, a validator that forwards 95% of the events that others do is not penalised. We could get more precision here (differentiating between the heartbeat and the expected real events etc), but that'd be overthinking.
In the end, we make sure no score is bigger than 1 (which might happen due to the multiplicative bonus).

### Total Performance

As we have several performance measurements, they need to be combined to a total score. To this end, we have a system variable `performance_weights`,
which has n+1 parameters (weight_0,.. weight_n) for n measurements (currently 2, the tendermint-performance and the ethereum-performance. Weights are normalised, so the sum of all weights needs to be 1. Also, all individual performance measurements are normalised to be between 0 and 1.

The total performance then is
`weight_0*(validator_ethereum_performance*validator_tendermint_performance)+weight_1*(validator_tendermint_performance)+weight_2*(validator_ethereum_performance)+weight_3*validator_ethereum_read_performance`

The initial values for the weights are {0,1,0,0}.

### Ersatz and pending validators

For validators who [have submitted a transaction to become validators](./0069-VCBS-validators_chosen_by_stake.md) the `performance_score` is defined as follows: during each epoch
Expand Down Expand Up @@ -87,6 +147,7 @@ The performance score should be available on all the same API endpoints as the `
- Verify that, at the beginning of the next epoch, all performance scores are 0 and voting power for all is 1 but the network keeps producing blocks and no nodes were removed from Tendermint.
1. Scores are restored after a snapshot restart (<a name="0064-VALP-006" href="#0064-VALP-006">0064-VALP-006</a>):
- With a snapshot that was taken at a block-height that falls in the middle of an epoch, restart a node from that snapshot. Ensure that at the end of the epoch the node remains in consensus and has produced the correct performance scores.
1. Setting the performance weights to (0,0,1,0) and (0,0,0,1) penalises validators only based on missed ethereum events and missed read access, respectively (<a name="0064-VALP-007" href="#0064-VALP-007">0064-VALP-007</a>)

## Future Stuff (in here for discussion purposes, not yet to be implemented)

Expand Down

0 comments on commit 1707f97

Please sign in to comment.