# Consensus

Consensus uses a similar consensus mechanism to most PoS blockchains geared towards decentralized subnets. Consensus mimics the concept of routing tables in a P2P network, where each node can recognize all other nodes or have access to the knowledge of all other nodes. Meaning, consensus requires that each node gets a score regardless of its in-subnet roles or tasks. The validator must submit scores on each node, and every other node attests to them. Subnets should be designed in such a way that scores are deterministic and attesting requires 100% accuracy.

## 66% Consensus

To receive rewards, the subnet must pass the required attestation rate of 66%.

***

## Elected Subnet Validator Node

On each epoch, a Validator [classified](https://docs.hypertensor.org/subnet-node#classifications) subnet node is randomly elected to be the validator to submit consensus data from each subnet. This elected subnet validator node submits a score on each node in its subnet. Subnets can optionally pass through miscellaneous data that the subnet can utilize.

#### Note

The election happens in the subnet slot.

#### The elected validator calls `validate` to submit consensus data

```rust
pub fn propose_attestation(
    origin: OriginFor<T>,
    subnet_id: u32,
    data: Vec<SubnetNodeConsensusData>,
    prioritize_queue_node_id: Option<u32>,
    remove_queue_node_id: Option<u32>,
    args: Option<BoundedVec<u8, DefaultValidatorArgsLimit>>,
    attest_data: Option<BoundedVec<u8, DefaultValidatorArgsLimit>>,
)
```

```rust
pub struct SubnetNodeConsensusData {
    pub subnet_node_id: u32,
    pub score: u128,
}
```

### Parameters

* `data`: The scores of each node
* `prioritized_queue_node_id`: Optional parameter that can represent a node ID in the queue that the subnet wants to place first in the queue.
* `remove_queue_node_id`: Optional parameter that can represent a node ID in the queue that the subnet wants to remove from the queue. To remove a node from the queue, the node must be passed the `QueueImmunityEpochs`.
* `args`: Optional miscellaneous data the subnet can utilize in-subnet (this is not used on-chain anywhere)
* `attest_data`: Optional miscellaneous data that the attestors can submit with their attestation (validators that submit data auto-attest) can utilize in-subnet (this is not used on-chain anywhere).

## Attestors

Each other Validator [classified](https://docs.hypertensor.org/subnet-node#classifications) subnet nodes can attest to the validator's consensus submission.

#### Attestors call `attest` to attest to the elected validators' consensus data

```rust
pub fn attest(
    origin: OriginFor<T>, 
    subnet_id: u32,
    attest_data: Option<BoundedVec<u8, DefaultValidatorArgsLimit>>,
)
```

### Parameters

* `attest_data`: Optional miscellaneous data that the attestors can submit with their attestation (validators that submit data auto-attest) can utilize in-subnet (this is not used on-chain anywhere).

***

## Penalties

### Slashing

The elected validator is slashed for not achieving a 66% attestation ratio or for not submitting consensus data.

Validators are slashed 3.125% of their total staked balance, up to the maximum slash value of 1 TENSOR.

#### **Given:**

* `S` = **Validator's subnet stake** (node's stake balance in subnet)
* `B` = **BaseSlashPercentage** (as a percentage, e.g., 3.125%)
* `A` = **Attestation Percentage** (actual %)
* `M` = **Minimum attestation percentage** (minimum required %)
* `Max` = **MaxSlashAmount**

#### **Formula**

$$
slash\text{\_}amount=min((S×B)×(1− MA),Max)
$$

<p align="center">and</p>

$$
𝑆new=𝑆−slash\text{\_}amount
$$

#### **Where**

1. **Base Slash**

   $$base\text{\_}slash=S×B$$
2. **Attestation Delta**
   * Attestation ratio:

     $$r=MA​$$
   * Delta (difference from 1.0):

     $$\delta = 1 - r = 1 - \frac{A}{M}$$
3. **Adjusted Slash**

   $$slash\text{*}amount=base\text{*}slash×δ$$
4. **Max Cap**

   $$slash\text{*}amount=min⁡(slash\text{*}amount,Max)$$
5. **Final Stake Update**\
   $$If slash\text{*} amount>0: \ \quad 𝑆new ​  =𝑆−slash\text{*}amount$$

<figure><img src="https://743092870-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FaoXQsAR3UWLLhndOMfU7%2Fuploads%2FzjvIhfb0JRVzEgDxfd1h%2FFrame%2012.svg?alt=media&#x26;token=4e60574f-2b4a-4de0-a665-51a3d15f701e" alt="" width="375"><figcaption></figcaption></figure>

### Elected Validator Penalties

The elected validator can decrease its reputation by not achieving a 66% attestation ratio or by not submitting its consensus data.

{% hint style="info" %}
Elected validators have penalties decreased for every successfully attested epoch.
{% endhint %}

### Node Penalties

Nodes can decrease their reputation if the validator doesn't submit them in its consensus data, and the epochs' attestation rate is at least 66%. Meaning, if the subnet comes to a consensus that a node is not in consensus, that node decreases its reputation until it reaches the minimum reputation and is removed.

{% hint style="info" %}
Nodes have their reputations increased for every successfully attested epoch they are included in the consensus.
{% endhint %}

Each node's score is used as a percentage of the sum of scores for its portion of emissions. See [Incentives](https://docs.hypertensor.org/network/incentives) for more information.
