Skip to content

Commit

Permalink
Enrich staking metadata exports (#786)
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Tinker <michael.tinker@swirldslabs.com>
Co-authored-by: Michael Garber <michael.garber@swirldslabs.com>
  • Loading branch information
tinker-michaelj and mgarbs authored Aug 14, 2023
1 parent ef0eec7 commit f89b8d3
Showing 1 changed file with 185 additions and 0 deletions.
185 changes: 185 additions & 0 deletions HIP/hip-786.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---
hip: 786
title: Enriched staking metadata exports
author: Michael Tinker <michael.tinker@swirldslabs.com>
working-group: Leemon Baird <leemon@swirldslabs.com>, Alex Popowycz <a@hedera.com>
type: Standards Track
category: Core
needs-council-approval: Yes
status: Review
created: 2023-08-10
discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/discussions/785
updated: 2023-08-11
---

## Abstract

The Hedera network pays staking rewards using an opportunistic mechanism defined by [HIP-406](https://hips.hedera.com/hip/hip-406).
When an account is involved in a transaction that changes its staked amount or staking metadata, it automatically receives
any rewards it has earned from the `0.0.800` account.

This means we cannot interpret the `0.0.800` balance as the amount of staking rewards that could still be earned in the
future. We have to recognize that part of this balance is **reserved** for staking rewards that are already earned,
but not yet paid. Furthermore, only the **unreserved** part of the `0.0.800` balance at the end of a staking period
affects the reward rate that will be paid for that period; c.f. [HIP-782](https://hips.hedera.com/hip/hip-782).

In principle, anyone can compute the reserved rewards by iterating through each account's staking metadata and computing
its pending rewards. By tracking the end-of-period `0.0.800` balance and current network properties, they can then compute
the unreserved `0.0.800` balance and the HIP-782 reward rate for that period. But this is an exorbitant amount of work,
and consensus nodes could just as easily expose all this information directly to mirror nodes via the end-of-period
`NodeStakeUpdateTransactionBody` transaction.

Hence we propose adding four fields to the `NodeStakeUpdateTransactionBody` transaction:
1. `reserved_staking_rewards` - the total staking rewards earned but not collected at the close of the previous staking period.
2. `unreserved_staking_reward_balance` - the funds available for future staking rewards at the close of the previous period.
3. `reward_balance_threshold` - as defined in [HIP-782](https://hips.hedera.com/hip/hip-782).
4. `max_stake_rewarded` - as defined in [HIP-782](https://hips.hedera.com/hip/hip-782).

We also propose deprecating the [`staking_reward_rate`](https://github.com/hashgraph/hedera-protobufs/blob/main/services/node_stake_update.proto#L82)
field, and replacing it with a new field `total_reward`. This replacement field will have the same information---that is, the total
number of tinybars to be paid as staking rewards for the just-ended period. But its new name will avoid confusing readers who are
not familiar with the revision history of HIP-406. (The legacy `staking_reward_rate` field will continue to be populated for an
appropriate time.)

We recommend that relevant mirror node APIs (such as the Hedera public mirror node endpoint `/api/v1/network/stake`) expand to
include these new fields.

## Motivation

Stakers and other interested parties might like to know the reserved rewards, `0.0.800` unreserved balance, and HIP-782 properties
for any number of reasons; for example, to estimate the rewards they might receive from staking, or to confirm the observed reward
rate matches the formula in HIP-782.

## Rationale

Since we already export many other important staking values in the end-of-period synthetic
[`NodeStakeTransactionBody`](https://github.com/hashgraph/hedera-protobufs/blob/main/services/node_stake_update.proto#L35),
it is hard to find a reason to put these related values anywhere else.

## User stories

As an HBAR staker, I want to follow along from home as the network applies the HIP-782 reward rate formulas.

As a mirror node operator, I want to give my API clients an up-to-date view on the amount of reserved rewards.

As a Hedera council member, I want to make decisions about network staking parameters based on the unreserved `0.0.800` balance.

## Specification

### Consensus nodes

Update the [`NodeStakeTransactionBody`](https://github.com/hashgraph/hedera-protobufs/blob/main/services/node_stake_update.proto#L35)
with fields the consensus nodes will use to export all the staking values in HIP-782 formulas, as below:
```
message NodeStakeUpdateTransactionBody {
...
/**
* (DEPRECATED) The total number of tinybars to be distributed as staking rewards each period.
* Please consult the total_reward field instead.
*/
int64 staking_reward_rate = 9 [deprecated = true];
/**
* The amount of the staking reward funds (account 0.0.800) reserved to pay pending rewards that
* have been earned but not collected.
*/
int64 reserved_staking_rewards = 10;
/**
* The unreserved balance of account 0.0.800 at the close of the just-ending period; this value is
* used to compute the HIP-782 balance ratio.
*/
int64 unreserved_staking_reward_balance = 11;
/**
* The unreserved tinybar balance of account 0.0.800 required to achieve the maximum per-hbar reward
* rate; please see HIP-782 for details.
*/
int64 reward_balance_threshold = 12;
/**
* The maximum amount of tinybar that can be staked for reward while still achieving the maximum
* per-hbar reward rate; please see HIP-782 for details.
*/
int64 max_stake_rewarded = 13;
/**
* The total tinybars to be paid as staking rewards in the ending period, after applying
* the settings for the 0.0.800 balance threshold and the maximum stake rewarded.
*/
int64 total_reward = 14;
}
```

### Mirror nodes

If a mirror node API exposes network staking properties, it _should_ expand to include this new information
and _should_ replace the `staking_reward_rate` field with `total_reward`. For example,
the Hedera public mirror node currently exposes a `/api/v1/network/stake` endpoint with sample response,
```
{
"max_staking_reward_rate_per_hbar": 17808,
"node_reward_fee_fraction": 0,
"stake_total": 3420441313766831000,
"staking_period": {
"from": "1691625600.000000000",
"to": "1691712000.000000000"
},
"staking_period_duration": 1440,
"staking_periods_stored": 365,
"staking_reward_fee_fraction": 0,
"staking_reward_rate": 273972602739726,
"staking_start_threshold": 25000000000000000
}
```

This response should remove the `staking_reward_rate` mapping and expand to include,
```
{
...
"reserved_staking_rewards": 111111111,
"unreserved_staking_reward_balance": 222222222,
"reward_balance_threshold": 333333333,
"max_stake_rewarded": 444444444,
"total_reward": 273972602739726
}
```


## Backwards Compatibility

This HIP primarily adds new information that mirror node operators and other record stream consumers can simply ignore if
they do not need it. However, consumers of the `staking_reward_rate` field should migrate to use `total_reward` within
an appropriate time interval.

## Security Implications

There are no security implications for this HIP. It simply provides a much more convenient, aggregated view of
information that is already publicly available.

## How to Teach This

Mirror node operators can use newly exported fields to easily give a full picture of the HIP-782 staking formulas.

## Reference Implementation

Please follow [this issue](https://github.com/hashgraph/hedera-services/issues/7946) for progress on the reference implementation.

## Rejected Ideas

We briefly considered adding a consensus node query to give a real-time view into the reserved rewards and unreserved
`0.0.800` balance. But since these values are only _used_ once per staking period, there seemed very little value in doing so.

## Open Issues

No known open issues exist.

## References

1. [HIP-406](https://hips.hedera.com/hip/hip-406)
2. [HIP-782](https://hips.hedera.com/hip/hip-782)
3. [`NodeStakeTransactionBody`](https://github.com/hashgraph/hedera-protobufs/blob/main/services/node_stake_update.proto#L35)

## Copyright/license

This document is licensed under the Apache License, Version 2.0 -- see [LICENSE](../LICENSE) or (https://www.apache.org/licenses/LICENSE-2.0)

0 comments on commit f89b8d3

Please sign in to comment.