Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Total issuance discrepancy #563

Open
orriin opened this issue Jun 24, 2024 · 5 comments
Open

Total issuance discrepancy #563

orriin opened this issue Jun 24, 2024 · 5 comments
Assignees
Labels
bug Something isn't working

Comments

@orriin
Copy link
Contributor

orriin commented Jun 24, 2024

balance.totalIssuance: 1,195,894,993,084,044 (which should be effectively the number of coins in circulation)
subtensorModule.totalissuance: 7,010,451,064,912,511
subtensorModule.totalstake: 5,780,329,269,388,411

@orriin orriin added the bug Something isn't working label Jun 24, 2024
@orriin orriin self-assigned this Jun 24, 2024
@mogmachine
Copy link

I think this stems from the way burned and recycled tokens are or are not counted in the various totals, but this is critical we get right as exchanges are relying on us for the truth and we are showing discrepancies in our data.

@orriin
Copy link
Contributor Author

orriin commented Jun 25, 2024

Initial analysis

Screenshot 2024-06-25 at 16 44 51

Good news:

  • Balances TotalIssuance amount is consistent with all free + reserved tokens in existence
  • Subtensor TotalStaked amount is consistent with sum of staked amounts across all accounts
  • TAOStats reports the correct TI (6.97M)

Inconsistency:

  • Subtensor TotalIssuance is 35651447307410 (approximately 35k TAO or 0.5%) higher than it should be.

Next Steps

  1. Identify which code path/s decrease the stake or account balance without making a corresponding change to Subtensor TI. Will collab with @mogmachine on that, it sounds like he already has an idea.
  2. Fix the issue, so TI changes no longer deviate from stake or acc balance changes
  3. Adjust the TI back to its correct value
  4. Add a try-state invariant to immediately notify us if state becomes inconsistent again

Long Term

We should migrate our staking system to use Holds instead of the current Stake storage, this can be achieved as a lazy migration. Once migrated to Holds, we can remove all the "double accounting" that we currently do to track total issuance.

@orriin
Copy link
Contributor Author

orriin commented Jun 26, 2024

Confirmed the cause is with subnet registration fees and tx fees.

Subnet registration makes up for the overwhelming majority of the 35k discrepancy, only ~7.5 TAO comes from tx fees.

Causes

Subnet registration

When a user registers a new network here:

/// User register a new subnetwork
#[pallet::call_index(59)]
#[pallet::weight((Weight::from_parts(157_000_000, 0)
.saturating_add(T::DbWeight::get().reads(16))
.saturating_add(T::DbWeight::get().writes(30)), DispatchClass::Operational, Pays::No))]
pub fn register_network(origin: OriginFor<T>) -> DispatchResult {
Self::user_add_network(origin)
}

balance is "burnt" from the registrar without a corresponding update to the subtensor total issuance:

let actual_lock_amount = Self::remove_balance_from_coldkey_account(&coldkey, lock_amount)?;

Tx fees

Tx fees are burnt using the default pallet_transaction CurrencyAdapter:

type OnChargeTransaction = CurrencyAdapter<Balances, ()>;

This default behavior is to just drop (burn) the fee amount, and this updates the Balances pallet TI but not the subtensor pallet TI.

Immediate remedies

Subnet registration

If we wish to consider TAO locked as part of TI, then we should create a TotalSubnetRegistrationLock or similar storage (like we have for TotalStake) and document the subtensor TI storage to explicitly state it is made up of account balances + total stake + total registration lock.

Tx fee

We should write an OnUnbalanced handler for the CurrencyAdapter that will decrease the Subtensor TI when tx fees are paid.

"Syncing" the correct total issuance

Once the above is in place, we can use sudo to initialise the TotalSubnetRegistrationLock value.

Then, we can call a simple admin function that sets the subtensor pallet TI to Balances pallet TI + total stake + total subnet registration lock. This will result in the subtensor pallet TI becoming perfectly balanced.

try-state

A try-state invariant should be written to notify us if TI ever deviates again.

Long term

As mentioned, we should migrate to using Holds for Staking and Subnet Registration which will massively simplify our accounting. However this is a large size lift, and I am not sure how high priority it will be once we fix the current issue.

@surcyf123
Copy link

but tao locked is part of total issuance, so it seems like only the trx fees need to be fixed. And Balances TI should include locked tao

@orriin
Copy link
Contributor Author

orriin commented Jun 27, 2024

but tao locked is part of total issuance, so it seems like only the trx fees need to be fixed

I think it's still prudent to add a TotalSubnetLocked storage entry, similar to how we have TotalStake.

And Balances TI should include locked tao

This will happen when we migrate to Holds. In the mean time, I think it's prudent to avoid changing the idiomatic definition, or otherwise messing with the Balances pallet TI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants