GitHub Logo HIP-786: Enriched staking metadata exports

Author Michael Tinker
Working Group Leemon Baird, Alex Popowycz
Requested By Hedera
Discussions-To https://github.com/hashgraph/hedera-improvement-proposal/discussions/785
Status Final
Needs Council Approval Yes
Review period ends Wed, 30 Aug 2023 07:00:00 +0000
Type Standards Track
Category Core
Created 2023-08-10
Updated 2023-09-13
Release v0.43.0

Abstract

The Hedera network pays staking rewards using an opportunistic mechanism defined by 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.

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.
  4. max_stake_rewarded - as defined in HIP-782.

We also propose deprecating the staking_reward_rate field, and replacing it with a new field max_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, 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 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 max_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 max_total_reward = 14;
}

Mirror nodes

If a mirror node API exposes network staking properties, it should expand to include this new information and should retain the now deprecated staking_reward_rate field. 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 retain all existing mappings, including staking_reward_rate, and expand to include,

{
  ...
  "reserved_staking_rewards": 111111111,
  "unreserved_staking_reward_balance": 222222222,
  "reward_balance_threshold": 333333333,
  "max_stake_rewarded": 444444444,
  "max_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 max_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 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
  2. HIP-782
  3. NodeStakeTransactionBody

Copyright/license

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

Citation

Please cite this document as: