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

[NET] Inv, mempool and validation improvements #2118

Merged
merged 32 commits into from
Jan 23, 2021

Conversation

furszy
Copy link

@furszy furszy commented Dec 31, 2020

Ending up 2020 with a large PR :).

Included a good number of performance and privacy improvements over the mempool and inv processing/sending areas + added mempool cache dump/load.
Almost finishing with #1726 work, getting closer to 9725, and getting closer to be able to decouple the message processing thread <-> wallet and the wallet <-> GUI locks dependencies (which will be another long story.. but well, step by step).

The final goal is clear, a much faster syncing process using pivx-qt (a good speed up for pivxd as well), smoother visual navigation when big wallets are syncing, less thread synchronization issues, among all of the improvements that will be coming with the backports adaptations.

Adapted the following PRs to our sources:

bitcoin#7062 —> only eb30666.
bitcoin#7174 —> complete.
bitcoin#7562 —> only c5d746a.
bitcoin#7594 —> complete.
bitcoin#7840 —> complete.
bitcoin#7997 —> complete.
bitcoin#8080 —> complete
bitcoin#8126 —> except e9b4780 (we don't have the mapRelay) and c2a4724 (we don't have the relay expiration vector).
bitcoin#8448 —> complete
bitcoin#8515 —> complete
bitcoin#9408 —> complete
bitcoin#9966 —> complete
bitcoin#10330 —> complete

furszy and others added 22 commits January 18, 2021 09:35
Coming from btc@7659438a63ef162b4a4f942f86683ae6785f8162
…ed non-recursively, so simplify the logic and eliminate an unnecessary parameter

Coming from btc@5de2baa138cda501038a4558bc169b2cfe5b7d6b
…prevent the descendant walking algorithm from doing too much work by marking the parent transaction as dirty. However to implement ancestor tracking, it's not possible to similarly mark those descendant transactions as dirty without having to calculate them to begin with. This commit removes the work limit altogether. With appropriate chain limits (-limitdescendantcount) the concern about doing too much work inside this function should be mitigated.

Coming from btc@76a76321d2f36992178ddaaf4d023c5e33c14fbf
Redo the feerate index to be based on mining score, rather than fee.

Update mempool_packages.py to test prioritisetransaction's effect on
package scores.

Coming from btc@eb306664e786ae43d539fde66f0fbe2a3e89d910
…state to each mempool entry, similar to descendant tracking, but also including caching sigops-with-ancestors (as that metric will be helpful to future code that implements better transaction selection in CreatenewBlock).

Coming from btc@72abd2ce3c5ad8157d3a993693df1919a6ad79c3
Coming from btc@ce019bf90fe89c1256a89c489795987ef0b8a18f
Previously Bitcoin would send 1/4 of transactions out to all peers
instantly. This causes high overhead because it makes >80% of
INVs size 1. Doing so harms privacy, because it limits the
amount of source obscurity a transaction can receive.

These randomized broadcasts also disobeyed transaction dependencies
and required use of the orphan pool. Because the orphan pool is
so small this leads to poor propagation for dependent transactions.

When the bypass wasn't in effect, transactions were sent in the
order they were received. This avoided creating orphans but
undermines privacy fairly significantly.

This commit:
Eliminates the bypass. The bypass is replaced by halving the
 average delay for outbound peers.

Sorts candidate transactions for INV by their topological
 depth then by their feerate (then hash); removing the
 information leakage and providing priority service to
 higher fee transactions.

Limits the amount of transactions sent in a single INV to
 7tx/sec (and twice that for outbound); this limits the
 harm of low fee transaction floods, gives faster relay
 service to higher fee transactions. The 7 sounds lower
 than it really is because received advertisements need
 not be sent, and because the aggregate rate is multipled
 by the number of peers.

 Coming from btc@f2d3ba73860e875972738d1da1507124d0971ae5
Saves about 10% of application memory usage once the mempool warms up. Since the
mempool is DynamicUsage-regulated, this will translate to a larger mempool in
the same amount of space.

Map value type: eliminate the vin index; no users of the map need to know which
input of the transaction is spending the prevout.

Map key type: replace the COutPoint with a pointer to a COutPoint. A COutPoint
is 36 bytes, but each COutPoint is accessible from the same map entry's value.
A trivial DereferencingComparator functor allows indirect map keys, but the
resulting syntax is misleading: `map.find(&outpoint)`. Implement an indirectmap
that acts as a wrapper to a map that uses a DereferencingComparator, supporting
a syntax that accurately reflect the container's semantics: inserts and
iterators use pointers since they store pointers and need them to remain
constant and dereferenceable, but lookup functions take const references.

 Coming from btc@9805f4af7ecb6becf8a146bd845fb131ffa625c9
 Coming from btc@96918a2f0990a8207d7631b8de73af8ae5d24aeb
An adaptation of btc@dc13dcd2bec2613a1cd5e0395b09b449d176146f with a tier two INV vector.
Handle mempool requests in send loop, subject to trickle  By eliminating queued entries from the mempool response and responding only at trickle time, this makes the mempool no longer leak transaction arrival order information (as the mempool itself is also sorted)-- at least no more than relay itself leaks it.
Move bloom and feerate filtering to just prior to tx sending.

This will avoid sending more pointless INVs around updates, and
prevents using filter updates to timetag transactions.

Also adds locking for fRelayTxes.
…f and introduced the timeLastMempoolReq coming from btc#8080.
Coming from btc@288d85ddf2e0a0c9d25a23db56052883170466d0
sipa and others added 9 commits January 18, 2021 09:36
zapwallettxes previously did not interact well with persistent mempool.
zapwallettxes would cause wallet transactions to be zapped, but they
would then be reloaded from the mempool on startup. This commit softsets
persistmempool to false if zapwallettxes is enabled so transactions are
actually zapped.
@furszy furszy force-pushed the 2020_mempool_and_inv_improvements branch from c4fb8d9 to d6d0ad9 Compare January 18, 2021 13:02
@furszy
Copy link
Author

furszy commented Jan 18, 2021

Rebased on master after merging #2082.

And.. surprise surprise, couldn't resist myself and have gone much deeper over this area, fulfilling my own #1726 goal. Fixing issues with zapwallettxs, adding mempool cache dump/load capabilities and improving mempool prioritization and removal performance.

Added the following back port adaptations plus some fixes that found on the way as well:

bitcoin#8448
bitcoin#8515
bitcoin#9408
bitcoin#9966
bitcoin#10330

This is ready for review.

Copy link

@random-zebra random-zebra left a comment

Choose a reason for hiding this comment

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

wow. Awesome job 🥃
code review ACK. Going to do some testing...

Copy link

@random-zebra random-zebra left a comment

Choose a reason for hiding this comment

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

ACK 9b9c616

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 9b9c616

@furszy furszy merged commit 1f010c0 into PIVX-Project:master Jan 23, 2021
furszy added a commit that referenced this pull request Feb 26, 2021
…ead (without cs_main)

3d11027 wallet:CreateCoinStake, solving IsSpent() missing cs_main lock. (furszy)
046386b IsNoteSaplingChange: Add missing cs_wallet lock. (furszy)
ded2e8e feature_dbcrash.py using blockmaxsize instead of blockmaxweight that we currently don't support. (furszy)
00cc6ec dumpwallet: Add missing BlockUntilSyncedToCurrentChain (furszy)
bfd9a15 test: sapling_fillblock.py sync mempool every 200 transactions instead of only at the end. (furszy)
53497f0 Validation: DisconnectTip doesn't need to force a flush to disk. (furszy)
f8cd371 [Miner] Sync wallet state before try to solve proof of stake. (furszy)
3ace13b qa: Fix some tests to work on native windows (furszy)
65cf7e1 don't attempt mempool entry for wallet transactions on startup if already in mempool (instagibbs)
756d0fa Handle rename failure in DumpMempool(...) by using RenameOver(...) return value (practicalswift)
1423dba [bugfix] save feeDelta instead of priorityDelta in DumpMempool (Alex Morcos)
d97ace9 [Test] notes_double_spend: sync wallet before check balances. (furszy)
1ed753f Fix wallet_tests.cpp, missing fInMempool flag set. (furszy)
815667d unit test framework: missing scheduler service loop start added. (furszy)
de3c7ae fix wallet_upgrade.py test, wasn't counting the coinbase script. (furszy)
e6770c8 fixing invalid wallet_dump.py, generated PoW blocks use a P2PKH coinbase script that now is properly marked as used inside the wallet. (furszy)
4ed7024 fix invalid numbers in wallet_labels.py (furszy)
b9249c5 Miner: generate RPC, fix coinbase script key not marked as used (furszy)
296c956 wallet: guard null m_last_block_processed (furszy)
0dfebf4 sapling_rpc_wallet_tests: remove unneeded cs_main and cs_wallet locks. (furszy)
c3a281c fix mempool_persist.py dump issue, missing sync with validation interface. (furszy)
67c754a qa: Sync with validationinterface queue in sync_mempools (MarcoFalke)
596056c [validation] Do not check for double spent zerocoins. (furszy)
0c4642c Add helper to wait for validation interface queue to catch up (Matt Corallo)
cc91d44 Block ActivateBestChain to empty validationinterface queue (Matt Corallo)
0c68e2f Add an interface to get the queue depth out of CValidationInterface (Matt Corallo)
31c7974 Decouple block processing cs_main lock from the rest of inv get data requests (furszy)
da7c0f7 Refactor ProcessGetData avoiding to lock cs_main for its entire time. (furszy)
10efbe5 net_processing: making PushTierTwoGetDataRequest return a bool in case of pushing the message. (furszy)
51dea23 net_processing move-only: decouple tier two get data request into its own function. (furszy)
1c9fe10 RPC: listunspent remove redundant wallet check (furszy)
4d927b0 Add a dev notes document describing the new wallet RPC blocking (Matt Corallo)
5f521fd Give ZMQ consistent order with UpdatedBlockTip on scheduler thread (Matt Corallo)
7d05997 Fix wallet RPC race by waiting for callbacks in sendrawtransaction (Matt Corallo)
c7ab490 Also call other wallet notify callbacks in scheduler thread (Matt Corallo)
31a8790 Use callbacks to cache whether wallet transactions are in mempool (Matt Corallo)
f6df6e4 Add calls to CWallet::BlockUntilSyncedToCurrentChain() in RPCs (furszy)
24a3ce4 Add CWallet::BlockUntilSyncedToCurrentChain() (Matt Corallo)
40ed4c4 Add CallFunctionInQueue to wait on validation interface queue drain (Matt Corallo)
268be9c Call TransactionRemovedFromMempool in the CScheduler thread (Matt Corallo)
1fa0d70 Add a CValidationInterface::TransactionRemovedFromMempool (Matt Corallo)

Pull request description:

  Concluding with the validation <--> wallet asynchronous signal processing work started in #2082, #2118, #2150, #2192, #2195.

  Effectively moving every validation interface callback to a background thread without locking `cs_main` for its entire process (each handler can now request `cs_main` lock only when/if they need it).

  This has a direct performance improvement on the synchronization time (which i haven't measured yet because there is one/two more PRs over the wallet and GUI areas, probably large as well, on top of this one and #2201 that should boost the sync time a lot more).

  Containing the following changes:

  * Adaptations coming from bitcoin#10286.
  * Adaptations coming from bitcoin#11824 (this one is different for us, take the base idea when you review it). Essentially solves a severe memory leak introduced previously in 10286 and improves `cs_main` lock acquisitions as well.
  * net_processing: decouple and refactor tier two inv data request processing.
  * bitcoin#12206

ACKs for top commit:
  random-zebra:
    Great job! 🍻 ACK 3d11027
  Fuzzbawls:
    ACK 3d11027

Tree-SHA512: 60a25604fb8a3ad0553ccb074aed99c1b3c6f8a765b40c1b43f25412373cbd2a9e4f0f413d45cf694bd62e48512c936099ffb7a0d23a1b97576cb33283ca05ac
random-zebra added a commit that referenced this pull request Mar 12, 2021
ca3edc5 GUI: Update worker type if task already exist. (furszy)
a1390c3 wallet balances, cache total delegated balance and calculate it only once. (furszy)
02eb781 GUI: settings information, do not update block num and block hash if the screen is not visible. (furszy)
cbc5021 Masternode-sync read only function to get the "IsBlockchainSynced" state. (furszy)
ef77fdf GUI: topbar, removing not used block source. (furszy)
e9c160a wallet: single loop to calculate the currently required balances. (furszy)
32538ae wallet: Disallow abandon of conflicted txes (furszy)
62cd35f GUI: MN model, remove now unneeded cs_main locks. (furszy)
5658844 wallet: removing unnecessary `mempool.cs` lock from ReacceptWalletTransactions() (furszy)
63f3fa7 GUI: add missing qt metatype declarations. (furszy)
bc76186 wallet model: update delay increased to 5 seconds. (furszy)
3fb3f34 GUI dashboard: do not update the staking filter if it's not needed. (furszy)
7cb8276 init: move "Done loading" message and rpc warm up finished after the wallet post initialization process (furszy)
8762e81 Refactoring with QString::toNSString (Hennadii Stepanov)
69b3330 GUI: txmodel, do not lock cs_wallet if no wtx status update is needed. (furszy)
b4ab286 GUI: dashboard, charts update delay time increased for IBD. (furszy)
0f197ca Wallet interface: do not load not used cold staking balances. (furszy)
dee4224 Wallet:GetLockedCoins() loop only over the locked coins, not over the entire wallet txes map. (furszy)
0a61f7f GUI: cold staking, do not refresh delegations if the screen is not visible. (furszy)
c2d66d0 GUI: cold staking screen, do not initialize coin control dialog at startup. (furszy)
44d9cbe GUI: dashboard screen, remove stakes filter source model if chart is not being presented. (furszy)
6e49a11 GUI: send screen, initialize coinControlDialog view only when it's being called. (furszy)
379e5f2 GUI: send screen, move refresh amounts calculation to a background worker thread. (furszy)
76bc08b GUI: balance polling update moved to a background worker thread. (furszy)
b73500a wallet:BlockConnected do not lock cs_wallet for its entire process. (furszy)
208a292 wallet: remove last cs_main locks from every signal handler function :) . (furszy)
9720579 SSPKM: remove redundant ReadBlockFromDisk from IncrementNoteWitnesses. (furszy)
4ccec74 wallet: Add IsSpent() cs_wallet lock assertion. (furszy)
e0a0d2d sapling_wallet_tests: locking order refactor, solving inconsistent orders for cs_main and cs_wallet. (furszy)
c69e7e8 Adapt sapling_wallet_listreceived.py to the new wtx confirmation structure. (furszy)
c4952a2 Wallet::CreateWalletFromFile guard direct chainActive access (furszy)
f889dcb test : updating wallet's last block processed manually. (furszy)
45c9471 wallet: split CheckTXAvailability in two. (furszy)
5109c8d Wallet: remove cs_main from IsSaplingSpent() and GetFilteredNotes() (furszy)
a7f6ab1 Wallet: remove cs_main requirement from RelayWalletTransaction and FundTransaction. (furszy)
1e7ffc2 Wallet: remove cs_main requirement from CreateCoinStake (furszy)
2e7cdb2 Wallet: added max value out filter for AvailableCoins. (furszy)
b9220f4 Wallet: Do not add P2CS utxo to autocombine flow and discard them later. (furszy)
59ed47d Wallet: remove cs_main lock from AutoCombineDust plus a redundant maturity check. (furszy)
fcc4c83 Move AutoCombineDust functionality to the wallet background thread (furszy)
fcb20c2 GUI: remove cs_main lock dependency from CWalletModel::isSpent, CWalletModel::isLockedCoin, CWalletModel::lockCoin, CWalletModel::unlockCoin (furszy)
65fbad1 GUI: remove cs_main lock dependency from transaction model update. (furszy)
0b61857 GUI: fix coinstake tx ordering. (furszy)
33588fe GUI: Remove cs_main lock and chain dependency from transaction update status (furszy)
3dede64 GUI: Remove cs_main lock from balance polling timer (furszy)
5e06330 Removed IsFinalTx() cs_main lock requirement. (furszy)
1bd97ca wallet::MarkConflicted remove blockIndex and there by cs_main lock dependency. (furszy)
239d6a2 wallet: remove the now unneeded cs_main locks (furszy)
1386ab7 Use CWallet::m_last_block_processed_height in GetDepthInMainChain (furszy)
9adeb61 Only return early from BlockUntilSyncedToCurrentChain if current tip is exact match (furszy)
8aa2d31 Add block_height field in struct Confirmation (furszy)
4405ac0 Replace CWalletTx::SetConf by Confirmation initialization list (furszy)
6320efb Update wallet last processed index in every unit test that needs it (furszy)
4957051 wallet: cache block hash, height and time inside the wallet. (furszy)
33f4788 wallet: refactor GetDepthInMainChain to not return the block index. (furszy)
e7c8ca6 wallet: remove unused IsInMainChain method (furszy)
9e51a48 Add a test wallet_reorgsrestore (Antoine Riard)
370c200 wallet: simplifying pindexRescan set + added an AssertLockHeld on FindForkInGlobalIndex (furszy)
46f0e30 Fixing reindex problem, use mapBlockIndex.find() and not mapBlockIndex[] (furszy)
da78039 [Wallet] Adapting TransactionAddedToMempool and BlockDisconnected to the new wtx confirmation status (furszy)
ff04fa6 Modify wallet tx status if has been reorged out (furszy)
f7baeaf Remove SyncTransaction for conflicted txn in CWallet::BlockConnected (Antoine Riard)
8d8928e Encapsulate tx status in a Confirmation struct (Antoine Riard)

Pull request description:

  This is the conclusion of a deep deep rabbit hole: #1726, #2150, #2082, #2118, #2150, #2179, #2191, #2192, #2195, #2201, #2203..

  Effectively removing every `cs_main` lock from the wallet and GUI processing threads. Completely decoupling the wallet state and the visual interface update procedures from the main message and validation handler thread.

  Meaning that the messages & validation handler thread will be largely more active, accepting and verifying way more data in less time, not being affected by several other threads accessing to the main critical section. And, at the same time, the wallet and GUI worker threads will be able to perform and process their tasks concurrently, without waiting for the `cs_main` mutex acquisition.
  Improving the overall software performance, the GUI responsiveness and decreasing the synchronization time.

  To make this possible, the wallet is maintaining in memory a view of the chain and updating it only via the validation interface signals. Using the view to perform all of the chain related calculations.

ACKs for top commit:
  Fuzzbawls:
    All good now, ACK ca3edc5
  random-zebra:
    ACK ca3edc5 and merging...

Tree-SHA512: 6d4268730941822942b0df0aab200683a1fabaf6801618cf34955b43b29bc2beb694567635f731a724abf7b73cec3edfe506e0428de6710c0fcf603613f5614a
@furszy furszy deleted the 2020_mempool_and_inv_improvements branch November 29, 2022 14:23
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.

8 participants