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

backport: Call wallet notify callbacks in scheduler thread (without cs_main) (bitcoin #10286) #1168

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from

Conversation

fdoving
Copy link
Contributor

@fdoving fdoving commented Dec 19, 2021

Backport of bitcoin/bitcoin#10286

This is currently unused, but will by used by wallet to cache when
transactions are in the mempool, obviating the need for calls to
mempool from CWalletTx::InMempool()
This is both good practice (we want to move all such callbacks
into a background thread eventually) and prevents a lock inversion
when we go to use this in wallet (mempool.cs->cs_wallet and
cs_wallet->mempool.cs would otherwise both be used).
This blocks until the wallet has synced up to the current height.
This prevents the wallet-RPCs-return-stale-info issue from being
re-introduced when new-block callbacks no longer happen in the
block-connection cs_main lock

conflict:
We have disabled bumpfee
This avoid calling out to mempool state during coin selection,
balance calculation, etc. In the next commit we ensure all wallet
callbacks from CValidationInterface happen in the same queue,
serialized with each other. This helps to avoid re-introducing one
of the issues described in #9584 [1] by further disconnecting
wallet from current chain/mempool state.

Thanks to @morcos for the suggestion to do this.

Note that there are several race conditions introduced here:

 * If a user calls sendrawtransaction from RPC, adding a
   transaction which is "trusted" (ie from them) and pays them
   change, it may not be immediately used by coin selection until
   the notification callbacks finish running. No such race is
   introduced in normal transaction-sending RPCs as this case is
   explicitly handled.

 * Until Block{Connected,Disconnected} and
   TransactionAddedToMempool calls also run in the CSceduler
   background thread, there is a race where
   TransactionAddedToMempool might be called after a
   Block{Connected,Disconnected} call happens.

 * Wallet will write a new best chain from the SetBestChain
   callback prior to having processed the transaction from that
   block.

[1] "you could go to select coins, need to use 0-conf change, but
such 0-conf change may have been included in a block who's
callbacks have not yet been processed - resulting in thinking they
are not in mempool and, thus, not selectable."

Conflicts:

Already backported beef7ec4be725beea870a2da510d2817487601ec
This runs Block{Connected,Disconnected}, SetBestChain, Inventory,
and TransactionAddedToMempool on the background scheduler thread.

Of those, only BlockConnected is used outside of Wallet/ZMQ, and
is used only for orphan transaction removal in net_processing,
something which does not need to be synchronous with anything
else.

This partially reverts #9583, re-enabling some of the gains from
 #7946. This does not, however, re-enable the gains achieved by
repeatedly releasing cs_main between each transaction processed.

Conflicts:
Already backported beef7ec4be725beea870a2da510d2817487601ec
Copy link
Contributor

@hans-schmidt hans-schmidt left a comment

Choose a reason for hiding this comment

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

Please correct the following error:
In src/validationinterface.h this PR incorrectly deleted Line 42 "~CValidationInterface() = default;"
-that destructor was added into Ravencoin by Mark Ney 2019-11-11 to remove build warnings
-that desctructor is also in the current version of bitcoin (added into bitcoin 2018-03-14 in commit 2b3ea39d)

The only other two changes relative to the bitcoin PR which I saw are correct:
1) src/validationinterface.cpp is different:
The last few line changes are ommitted in RVN because RVN doesn't have a "void CMainSignals::Inventory" function
2) src/wallet/rpcwallet.cpp is different:
The last 3-lines added in the bitcoin PR are ommitted on the RVN PR because bumpfee has been deprecated on the RVN Wallet

Note that UpdatedBlockTip is also used in net_processing to
announce new blocks to peers. As this may need additional review,
this change is included in its own commit.
@fdoving
Copy link
Contributor Author

fdoving commented Jan 21, 2022

Changes pushed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants