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] Per-txout model for chainstate database #1801

Merged
merged 25 commits into from
Sep 5, 2020

Conversation

random-zebra
Copy link

@random-zebra random-zebra commented Aug 11, 2020

The chainstate database, and its cache, rely on a per-tx model (i.e. it is a map from txids to lists of unspent outputs).
This PR chages it to a per-txout model (i.e. a map from outpoints to single unspent outputs).

Pros:

  • Simpler code.
  • Avoiding the CPU overhead of deserializing and serializing the unused outputs.
  • More predictable memory usage.
  • More easily adaptable to various cache flushing strategies.

Cons:

  • Slightly larger on-disk representation, and sometimes larger in-memory representation (when there are multiple outputs for the same txid in the cache, which becomes optional).

Adapted from bitcoin#10195 (adding a fCoinStake boolean memeber to the Coin class and considering BIP34 always in effect as per #1775)

Based on top of:

The actual PR starts with "Introduce Coin, a single unspent output" (171bf0b)

⚠️ Note for testers: Do a backup of the chainstate before testing. With this PR, at startup, the database is automatically upgraded to the new format (so a reindex is not needed).

@random-zebra random-zebra added this to the 5.0.0 milestone Aug 11, 2020
@random-zebra random-zebra added this to In Progress in perpetual updating PIVX Core to BTC Core via automation Aug 11, 2020
@random-zebra random-zebra self-assigned this Aug 11, 2020
@random-zebra random-zebra force-pushed the 202007_pertxoutcache_2 branch 2 times, most recently from 903ca50 to 54e98d8 Compare August 12, 2020 11:19
@random-zebra random-zebra force-pushed the 202007_pertxoutcache_2 branch 2 times, most recently from 9c7e104 to 02b804b Compare August 19, 2020 15:04
@random-zebra
Copy link
Author

Rebased on master. Ready for review.

random-zebra and others added 19 commits August 23, 2020 18:00
change the serialization/unserialization code, mirroring CTxInUndo class
(which will be removed in next commit, and replaced with a serialization
adapter for Coin)
>>> backports bitcoin/bitcoin@cb2c7fd

The earlier CTxInUndo class now holds the same information as the Coin
class. Instead of duplicating functionality, replace CTxInUndo with a
serialization adapter for Coin.
>>> backports bitcoin/bitcoin@bd83111

This avoids a prevector copy in ApplyTxInUndo.
>>> backports bitcoin/bitcoin@0003911

The new functions are:
* CCoinsViewCache::AddCoin: Add a single COutPoint/Coin pair.
* CCoinsViewCache::SpendCoin: Remove a single COutPoint.
* AddCoins: utility function that invokes CCoinsViewCache::AddCoin for
  each output in a CTransaction.
* AccessByTxid: utility function that searches for any output with
  a given txid.
* CCoinsViewCache::AccessCoin: retrieve the Coin for a COutPoint.
* CCoinsViewCache::HaveCoins: check whether a non-empty Coin exists
  for a given COutPoint.

The AddCoin and SpendCoin methods will eventually replace ModifyCoins
and ModifyNewCoins, AddCoins will replace CCoins::FromTx, and the new
AccessCoins and HaveCoins functions will replace their per-txid
counterparts.

Note that AccessCoin for now returns a copy of the Coin object. In a
later commit it will be change to returning a const reference (which
keeps working in all call sites).
>>> backports bitcoin/bitcoin@c87b957

This clarifies a bit more the ways in which the new script execution
cache could break consensus in the future if additional data from
the CCoins object were to be used as a part of script execution.

After this change, any such consensus breaks should be very visible
to reviewers, hopefully ensuring no such changes can be made.
>>> backports bitcoin/bitcoin@5083079

This patch makes several related changes:
* Changes the CCoinsView virtual methods (GetCoins, HaveCoins, ...)
  to be COutPoint/Coin-based rather than txid/CCoins-based.
* Changes the chainstate db to a new incompatible format that is also
  COutPoint/Coin based.
* Implements reconstruction code for hash_serialized_2.
* Adapts the coins_tests unit tests (thanks to Russell Yanofsky).

A side effect of the new CCoinsView model is that we can no longer
use the (unreliable) test for transaction outputs in the UTXO set
to determine whether we already have a particular transaction.
random-zebra and others added 6 commits August 23, 2020 18:01
>>> backports bitcoin/bitcoin@b2af357

As the maximum amount of data that can be pulled into the cache due to
a block validation is much lower now (at most one CCoin entry per input
and per output), reduce the conservative estimate used to determine
flushing time.
>>> backports bitcoin/bitcoin@580b023

It's only used for upgrading from the old database anymore.
>>> backports bitcoin/bitcoin@5898279

Thanks to John Newberry for pointing these out.

-BEGIN VERIFY SCRIPT-
sed -i 's/\<GetCoins\>/GetCoin/g' src/*.cpp src/*.h src/*/*.cpp
src/*/*.h
sed -i 's/\<HaveCoins\>/HaveCoin/g' src/*.cpp src/*.h src/*/*.cpp
src/*/*.h
sed -i 's/\<HaveCoinsInCache\>/HaveCoinInCache/g' src/*.cpp src/*.h
src/*/*.cpp src/*/*.h
sed -i 's/\<IsPruned\>/IsSpent/g' src/*.cpp src/*.h src/*/*.cpp
src/*/*.h
sed -i 's/\<FetchCoins\>/FetchCoin/g' src/*.cpp src/*.h src/*/*.cpp
src/*/*.h
sed -i 's/\<CoinsEntry\>/CoinEntry/g' src/*.cpp src/*.h src/*/*.cpp
src/*/*.h
sed -i 's/\<vHashTxnToUncache\>/coins_to_uncache/g' src/*.cpp src/*.h
src/*/*.cpp src/*/*.h
sed -i 's/\<vHashTxToUncache\>/coins_to_uncache/g' src/*.cpp src/*.h
src/*/*.cpp src/*/*.h
sed -i 's/\<fHadTxInCache\>/had_coin_in_cache/g' src/*.cpp src/*.h
src/*/*.cpp src/*/*.h
sed -i 's/\<coinbaseids\>/coinbase_coins/g' src/*.cpp src/*.h
src/*/*.cpp src/*/*.h
sed -i 's/\<disconnectedids\>/disconnected_coins/g' src/*.cpp src/*.h
src/*/*.cpp src/*/*.h
sed -i 's/\<duplicateids\>/duplicate_coins/g' src/*.cpp src/*.h
src/*/*.cpp src/*/*.h
sed -i 's/\<oldcoins\>/old_coin/g' src/test/coins_tests.cpp
sed -i 's/\<origcoins\>/orig_coin/g' src/*.cpp src/*.h src/*/*.cpp
src/*/*.h
-END VERIFY SCRIPT-
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.

Nice work!
Code review ACK 535d8e4. Need some live testing now.

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.

ACK 535d8e4

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 535d8e4

@random-zebra random-zebra merged commit 30d353e into PIVX-Project:master Sep 5, 2020
perpetual updating PIVX Core to BTC Core automation moved this from Ready to Done Sep 5, 2020
furszy added a commit that referenced this pull request Sep 7, 2020
cf7003b [Cleanup] Remove cacheInputAge nonsense from CMasternode (random-zebra)
7cebb9b [Refactor] Get rid of GetInputAge static function (random-zebra)
ae2af54 [Refactoring] Add GetCoinDepth utility function to CCoinsViewCache (random-zebra)

Pull request description:

  Introduce a `GetCoinDepth()` utility function in CCoinsViewCache and use that instead (with `pcoinsTip`... no need to lock/load the mempool too in the  backend).
  This should fix the invalid lock order:
  ```
  2020-09-02 10:23:17 POTENTIAL DEADLOCK DETECTED
  2020-09-02 10:23:17 Previous lock order was:
  2020-09-02 10:23:17  cs_process_message /src/masternodeman.cpp:690 (in thread pivx-msghand)
  2020-09-02 10:23:17  (1) mempool.cs /src/main.cpp:777 (in thread pivx-msghand)
  2020-09-02 10:23:17  (2) cs_main /src/main.cpp:785 (in thread pivx-msghand)
  2020-09-02 10:23:17 Current lock order is:
  2020-09-02 10:23:17  (2) cs_main /src/main.cpp:4571 (in thread )
  2020-09-02 10:23:17  (1) cs /src/txmempool.cpp:590 (in thread )
  ```

  To be able to use the new per-txout interface, this is based on top of:
  - [x] #1801

  The present PR starts with `[Refactoring] Add GetCoinDepth utility function to CCoinsViewCache` (294e177)

  BONUS: remove the cached "ages" saved/serialized in CMasternode class... no comment.

ACKs for top commit:
  furszy:
    utACK cf7003b

Tree-SHA512: 8eb73ff32d542a97aacd53ca4e0743a7facdf9055a45feea80e47822befc4ee499d4d943160e3926bd62ad287ccff546fdc3e868a0c6d15eb9e3e8b34e367c20
@random-zebra random-zebra modified the milestones: 5.0.0, 4.3.0 Sep 10, 2020
furszy added a commit that referenced this pull request Sep 23, 2020
979cb74 [Trivial][UI] Fix init messages (random-zebra)

Pull request description:

  After #1801 the coins database is updated to the new format.
  During this time (which could take a minute or so), QT wallet reports "Loading block index..."

  <img src="https://user-images.githubusercontent.com/18186894/93999833-9bdb8c80-fd96-11ea-9c40-d58417a122a0.png" width="60%">

  which is wrong: even without the coins DB upgrade, it loads first the sporks DB, before the block index.

  So:
  - remove the misplaced init message for BlockIndex load (there's another one in the right place).
  - add a new init message for the coins DB upgrade (if the DB is already upgraded, the function returns immediately so this is shown only for a fraction of a second before "Loading sporks...").

  Note: As 4.3 is the first release including the new DB, we should probably backport this trivial PR.

ACKs for top commit:
  furszy:
    utACK 979cb74
  Fuzzbawls:
    ACK 979cb74

Tree-SHA512: e85a3e128907430391d47b28ed66473e2be16ec83683362ccdc8e1d4ce62d24f8a39de9ce049dce339cb575616194ee5cfb8c8f033fc0dde8f154c18a0b01a99
@Fuzzbawls Fuzzbawls added Needs Release Notes Placeholder tag for anything needing mention in the "Notable Changes" section of release notes and removed Needs Release Notes Placeholder tag for anything needing mention in the "Notable Changes" section of release notes labels Sep 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

4 participants