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

[Core][RPC][BUG] Use sum of utxo values as money supply #1878

Merged
merged 12 commits into from
Oct 10, 2020

Conversation

random-zebra
Copy link

@random-zebra random-zebra commented Sep 27, 2020

Instead of updating and databasing independently nMoneySupply, just use the sum of all unspent tx outputs, returned by the coins cache.

This has the following advantages:

  • Cleaner code: we don't need to add special cases for exceptional one-time events, such as wrapped serials, accumulator recalculation, etc.
  • More robust: with the old code, nMoneySupply is databased at every block and does not follow the chainstate flushing strategy, so it's very easy to get an inconsistent state (see [Bug] getinfo returns wrong moneysupply amount #1873).
    Even more so, considering the absence of any consistency check between the actual chain height and the height at which the supply was updated.
  • More accurate number: this returns only the spendable supply, so it excludes all unspendable outputs (OP_RETURN), such as proposals / finalized budgets collaterals, that were originally counted in.
    Those outputs, in fact, are effectively "burnt" coins and should not be part of the total supply calculation.

Disadvantage:

  • Calculating the supply from the coins DB is a bit slow, but the only place where this is done is in the RPC getinfo.

This PR removes the global variable nMoneySupply and all related code (Closes #1873) and gets rid of the startup flag --reindexmoneysupply no longer needed (#1864 introduces reindex-chainstate).

⚠️ This also fixes the following bug with zerocoin txes:
Currently, on master, gettxoutsetinfo reports a total amount of about 811 million PIV!
This is due to improper handling of zerocoin-related "utxos".
Basically mints are added to the coins cache (AddCoin only skips OP_RETURN coins, not mints) and never pruned/spent (as they are skipped inside UpdateCoins), except in DisconnectBlock.

Here we completely remove zerocoin mint outputs from the coins DB.
This makes sense, as originally they were not meant to be linked when spending, so should have been considered unspendable outputs, and not included in the first place. With the introduction of Public Spends, mint outputs are now referenced when spending, but we don't need to keep them in the cache either, as double spending is checked only via the zerocoin serial (and, as said, the coins aren't even spent in UpdateCoins).
We also remove all those utxos flagged as invalid.

Removing zerocoin mints from the unspent coins DB also gives a nice reduction to the utxoset size on disk (about 37%, from 428 Mb to 270 Mb).

@random-zebra random-zebra added RPC Bug Needs Release Notes Placeholder tag for anything needing mention in the "Notable Changes" section of release notes UTXO DBs and Indexes labels Sep 27, 2020
@random-zebra random-zebra added this to the 5.0.0 milestone Sep 27, 2020
@random-zebra random-zebra self-assigned this Sep 27, 2020
@random-zebra
Copy link
Author

Rebased.

@Fuzzbawls
Copy link
Collaborator

looking good so far. With this, can't we also get rid of the ZC_WrappedSerialsSupply consensus param since it is no longer used anywhere?

@random-zebra
Copy link
Author

Oh yep, the ability to remove these special cases was, in fact, one of the pros.
Nice catch. Added in the last commit.

Copy link
Collaborator

@Fuzzbawls Fuzzbawls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK dcc032c

Copy link

@furszy furszy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code review ACK 0e7921e , nice finding 👌 .

@random-zebra random-zebra merged commit 7bba394 into PIVX-Project:master Oct 10, 2020
furszy added a commit that referenced this pull request Oct 13, 2020
ae4069e [Core] Skip MoneySupply update during IBD (random-zebra)
5fc1f30 [Tests] Use new rpc getsupplyinfo in mining_pos_reorg.py (random-zebra)
244c608 [RPC] Use getsupplyinfo from within getinfo (random-zebra)
31d26c7 [RPC] Introduce getsupplyinfo RPC function (random-zebra)
8c6e4c7 [Validation] Update money supply when the chainstate is flushed (random-zebra)
809e580 [Init] Initialize global MoneySupply at startup (random-zebra)
ed591d6 [Core] Introduce CMoneySupply class (random-zebra)

Pull request description:

  With #1878 the RPC call `getinfo` becomes awfully slow (it triggers a flush of the chainstate to disk and recalculates the amount).

  In this PR we introduce a in-memory global object (instance of a dumb storage class) to cache the money supply, as well as the height of the chain when it was last updated.
  The cache is updated in 3 cases:
  - at startup
  - after periodic full flushes to disk (blocks and chainstate), except during shutdown or IBD
  - on-demand via RPC (see below)

  A new RPC `getsupplyinfo` is introduced. It returns the contents of the cached object, after an optional flush/recalculation (if the `forceupdate` argument is set to true).

  The money supply is still part of `getinfo` output, for backward compatibility, but the fetching is redirected to the new `getsupplyinfo` (with default value, false, for the `forceupdate` argument, thus without flush/recalculation).

  Examples:
  ```
  > getblockcount
  2542258

  > getsupplyinfo
  {
    "updateheight": 2542240,
    "supply": 64090963.91257160
  }

  > getinfo
  {
    ...
    "moneysupply": 64090963.91257160
    ...
  }

  > getmoneysupplyinfo true
  {
    "updateheight": 2542258,
    "supply": 64091053.91230406
  }

  > getinfo
  {
    ...
    "moneysupply": 64091053.91230406
    ...
  }
  ```

  Based on top of
  - [x] #1878

  Starts with `[Core] Introduce CMoneySupply class` (6554757)

ACKs for top commit:
  furszy:
    The new RPC command will need to be added to the release notes, other than that ACK ae4069e. Nice improvement
  Fuzzbawls:
    ACK ae4069e

Tree-SHA512: d88d78a21d23ce63228bf1eb27e02453007dc401cb250dcc7b0a2cc412db7604b555cb915ed1e6d7ea1d333cbe860c5d5857c176b9db19e73be17146a04ae690
@random-zebra random-zebra removed the Needs Release Notes Placeholder tag for anything needing mention in the "Notable Changes" section of release notes label Jan 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] getinfo returns wrong moneysupply amount
3 participants