2023-12-31 01:00:00 +01:00
|
|
|
// Copyright (c) 2014-2024 The Dash Core developers
|
2016-03-02 22:20:04 +01:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <chainparams.h>
|
2021-03-17 23:36:11 +01:00
|
|
|
#include <coinjoin/coinjoin.h>
|
|
|
|
#ifdef ENABLE_WALLET
|
2021-10-01 21:19:08 +02:00
|
|
|
#include <coinjoin/client.h>
|
2021-03-17 23:36:11 +01:00
|
|
|
#endif // ENABLE_WALLET
|
refactor: subsume CoinJoin objects under CJContext, deglobalize coinJoin{ClientQueueManager,Server} (#5337)
## Motivation
CoinJoin's subsystems are initialized by variables and managers that
occupy the global context. The _extent_ to which these subsystems
entrench themselves into the codebase is difficult to assess and moving
them out of the global context forces us to enumerate the subsystems in
the codebase that rely on CoinJoin logic and enumerate the order in
which components are initialized and destroyed.
Keeping this in mind, the scope of this pull request aims to:
* Reduce the amount of CoinJoin-specific entities present in the global
scope
* Make the remaining usage of these entities in the global scope
explicit and easily searchable
## Additional Information
* The initialization of `CCoinJoinClientQueueManager` is dependent on
blocks-only mode being disabled (which can be alternatively interpreted
as enabling the relay of transactions). The same applies to
`CBlockPolicyEstimator`, which `CCoinJoinClientQueueManager` depends.
Therefore, `CCoinJoinClientQueueManager` is only initialized if
transaction relaying is enabled and so is its scheduled maintenance
task. This can be found by looking at `init.cpp`
[here](https://github.com/dashpay/dash/blob/93f8df1c31fdce6a14f149acfdff22678c3f22ca/src/init.cpp#L1681-L1683),
[here](https://github.com/dashpay/dash/blob/93f8df1c31fdce6a14f149acfdff22678c3f22ca/src/init.cpp#L2253-L2255)
and
[here](https://github.com/dashpay/dash/blob/93f8df1c31fdce6a14f149acfdff22678c3f22ca/src/init.cpp#L2326-L2327).
For this reason, `CBlockPolicyEstimator` is not a member of `CJContext`
and its usage is fulfilled by passing it as a reference when
initializing the scheduling task.
* `CJClientManager` has not used `CConnman` or `CTxMemPool` as `const`
as existing code that is outside the scope of this PR would cast away
constness, which would be unacceptable. Furthermore, some logical paths
are taken that will grind to a halt if they are stored as `const`.
Examples of such a call chains would be:
* `CJClientManager::DoMaintenance >
CCoinJoinClientManager::DoMaintenance > DoAutomaticDenominating >
CCoinJoinClientSession::DoAutomaticDenominating >
CCoinJoinClientSession::StartNewQueue > CConnman::AddPendingMasternode`
which modifies `CConnman::vPendingMasternodes`, which is non-const
behaviour
* `CJClientManager::DoMaintenance >
CCoinJoinClientManager::DoMaintenance > DoAutomaticDenominating >
CCoinJoin::IsCollateralValid > AcceptToMemoryPool` which adds a
transaction to the memory pool, which is non-const behaviour
* There were cppcheck [linter
failures](https://github.com/dashpay/dash/pull/5337#issuecomment-1685084688)
that seemed to be caused by the usage of `Assert` in
`coinjoin/client.h`. This seems to be resolved by backporting
[bitcoin#24714](https://github.com/bitcoin/bitcoin/pull/24714). (Thanks
@knst!)
* Depends on #5546
---------
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
Co-authored-by: PastaPastaPasta <6443210+PastaPastaPasta@users.noreply.github.com>
2023-09-13 19:52:38 +02:00
|
|
|
#include <coinjoin/context.h>
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <dsnotificationinterface.h>
|
|
|
|
#include <governance/governance.h>
|
2021-10-01 21:19:08 +02:00
|
|
|
#include <masternode/sync.h>
|
2024-04-09 21:51:13 +02:00
|
|
|
#include <net_processing.h>
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <validation.h>
|
2016-03-02 22:20:04 +01:00
|
|
|
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <evo/deterministicmns.h>
|
|
|
|
#include <evo/mnauth.h>
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2021-10-02 19:32:24 +02:00
|
|
|
#include <llmq/chainlocks.h>
|
2022-11-07 19:09:44 +01:00
|
|
|
#include <llmq/context.h>
|
2021-10-02 19:32:24 +02:00
|
|
|
#include <llmq/dkgsessionmgr.h>
|
2023-10-18 05:31:40 +02:00
|
|
|
#include <llmq/ehf_signals.h>
|
2022-11-07 19:09:44 +01:00
|
|
|
#include <llmq/instantsend.h>
|
|
|
|
#include <llmq/quorums.h>
|
2019-01-22 14:20:32 +01:00
|
|
|
|
2024-02-28 13:53:56 +01:00
|
|
|
CDSNotificationInterface::CDSNotificationInterface(CConnman& connman,
|
|
|
|
CMasternodeSync& mn_sync,
|
|
|
|
CGovernanceManager& govman,
|
2024-04-09 21:51:13 +02:00
|
|
|
PeerManager& peerman,
|
2024-06-25 11:44:28 +02:00
|
|
|
const ChainstateManager& chainman,
|
2024-03-30 01:16:48 +01:00
|
|
|
const CActiveMasternodeManager* const mn_activeman,
|
2024-02-28 13:53:56 +01:00
|
|
|
const std::unique_ptr<CDeterministicMNManager>& dmnman,
|
|
|
|
const std::unique_ptr<LLMQContext>& llmq_ctx,
|
|
|
|
const std::unique_ptr<CJContext>& cj_ctx)
|
|
|
|
: m_connman(connman),
|
|
|
|
m_mn_sync(mn_sync),
|
|
|
|
m_govman(govman),
|
2024-04-09 21:51:13 +02:00
|
|
|
m_peerman(peerman),
|
2024-06-25 11:44:28 +02:00
|
|
|
m_chainman(chainman),
|
2024-03-30 01:16:48 +01:00
|
|
|
m_mn_activeman(mn_activeman),
|
2024-02-28 13:53:56 +01:00
|
|
|
m_dmnman(dmnman),
|
|
|
|
m_llmq_ctx(llmq_ctx),
|
|
|
|
m_cj_ctx(cj_ctx) {}
|
2022-09-22 13:14:48 +02:00
|
|
|
|
2017-08-29 01:51:33 +02:00
|
|
|
void CDSNotificationInterface::InitializeCurrentBlockTip()
|
2016-03-02 22:20:04 +01:00
|
|
|
{
|
2024-06-25 11:44:28 +02:00
|
|
|
SynchronousUpdatedBlockTip(m_chainman.ActiveChain().Tip(), nullptr, m_chainman.ActiveChainstate().IsInitialBlockDownload());
|
|
|
|
UpdatedBlockTip(m_chainman.ActiveChain().Tip(), nullptr, m_chainman.ActiveChainstate().IsInitialBlockDownload());
|
2016-03-02 22:20:04 +01:00
|
|
|
}
|
|
|
|
|
2017-09-03 15:30:08 +02:00
|
|
|
void CDSNotificationInterface::AcceptedBlockHeader(const CBlockIndex *pindexNew)
|
|
|
|
{
|
2024-02-28 13:53:56 +01:00
|
|
|
assert(m_llmq_ctx);
|
|
|
|
|
|
|
|
m_llmq_ctx->clhandler->AcceptedBlockHeader(pindexNew);
|
2023-06-04 22:26:23 +02:00
|
|
|
m_mn_sync.AcceptedBlockHeader(pindexNew);
|
2017-09-03 15:30:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CDSNotificationInterface::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload)
|
|
|
|
{
|
2023-06-04 22:26:23 +02:00
|
|
|
m_mn_sync.NotifyHeaderTip(pindexNew, fInitialDownload);
|
2017-09-03 15:30:08 +02:00
|
|
|
}
|
|
|
|
|
2020-03-20 17:11:54 +01:00
|
|
|
void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
|
2016-03-02 22:20:04 +01:00
|
|
|
{
|
2024-02-28 13:53:56 +01:00
|
|
|
assert(m_dmnman);
|
|
|
|
|
2017-09-20 22:30:56 +02:00
|
|
|
if (pindexNew == pindexFork) // blocks were disconnected without any new ones
|
|
|
|
return;
|
|
|
|
|
2024-02-28 13:53:56 +01:00
|
|
|
m_dmnman->UpdatedBlockTip(pindexNew);
|
2020-03-20 17:11:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
|
|
|
|
{
|
2024-02-28 13:26:42 +01:00
|
|
|
assert(m_cj_ctx && m_llmq_ctx);
|
2024-02-28 13:53:56 +01:00
|
|
|
|
2020-03-20 17:11:54 +01:00
|
|
|
if (pindexNew == pindexFork) // blocks were disconnected without any new ones
|
|
|
|
return;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
fix: lock `::cs_main` before accessing `ChainstateManager::m_best_header`
Avoid TSan-reported data race
```
WARNING: ThreadSanitizer: data race (pid=360336)
Write of size 8 at 0x7b5000002db8 by thread T15 (mutexes: write M0):
#0 BlockManager::AddToBlockIndex(CBlockHeader const&, uint256 const&, CBlockIndex*&, BlockStatus) /src/dash/src/node/blockstorage.cpp:117:25 (dashd+0x44df7a) (BuildId: e27186c7ba08e897d376eb5779db9809baf7ad37)
#1 ChainstateManager::AcceptBlockHeader(CBlockHeader const&, BlockValidationState&, CChainParams const&, CBlockIndex**) /src/dash/src/validation.cpp:3758:36 (dashd+0x83e45d) (BuildId: e27186c7ba08e897d376eb5779db9809baf7ad37)
#2 CChainState::AcceptBlock(std::shared_ptr<CBlock const> const&, BlockValidationState&, CBlockIndex**, bool, FlatFilePos const*, bool*) /src/dash/src/validation.cpp:3812:37 (dashd+0x842848) (BuildId: e27186c7ba08e897d376eb5779db9809baf7ad37)
[...]
Previous read of size 8 at 0x7b5000002db8 by thread T12:
#0 CDSNotificationInterface::UpdatedBlockTip(CBlockIndex const*, CBlockIndex const*, bool) /src/dash/src/dsnotificationinterface.cpp:82:42 (dashd+0x91e87e) (BuildId: e27186c7ba08e897d376eb5779db9809baf7ad37)
#1 operator() /src/dash/src/validationinterface.cpp:199:79 (dashd+0x889f1e) (BuildId: e27186c7ba08e897d376eb5779db9809baf7ad37)
#2 Iterate<(lambda at validationinterface.cpp:199:30)> /src/dash/src/validationinterface.cpp:88:17 (dashd+0x889f1e)
[...]
[...]
SUMMARY: ThreadSanitizer: data race [...]
```
2024-08-10 18:35:27 +02:00
|
|
|
m_mn_sync.UpdatedBlockTip(WITH_LOCK(::cs_main, return m_chainman.m_best_header), pindexNew, fInitialDownload);
|
2017-09-20 22:30:56 +02:00
|
|
|
|
2017-10-09 20:25:24 +02:00
|
|
|
if (fInitialDownload)
|
2017-09-22 03:54:14 +02:00
|
|
|
return;
|
|
|
|
|
2024-02-28 13:26:42 +01:00
|
|
|
m_cj_ctx->dstxman->UpdatedBlockTip(pindexNew, *m_llmq_ctx->clhandler, m_mn_sync);
|
2019-06-27 22:24:43 +02:00
|
|
|
#ifdef ENABLE_WALLET
|
2024-08-26 17:55:37 +02:00
|
|
|
m_cj_ctx->walletman->ForEachCJClientMan(
|
|
|
|
[&pindexNew](std::unique_ptr<CCoinJoinClientManager>& clientman) { clientman->UpdatedBlockTip(pindexNew); });
|
2019-06-27 22:24:43 +02:00
|
|
|
#endif // ENABLE_WALLET
|
|
|
|
|
2024-02-28 13:53:56 +01:00
|
|
|
m_llmq_ctx->isman->UpdatedBlockTip(pindexNew);
|
|
|
|
m_llmq_ctx->clhandler->UpdatedBlockTip();
|
2019-01-22 14:20:32 +01:00
|
|
|
|
2024-02-28 13:53:56 +01:00
|
|
|
m_llmq_ctx->qman->UpdatedBlockTip(pindexNew, fInitialDownload);
|
|
|
|
m_llmq_ctx->qdkgsman->UpdatedBlockTip(pindexNew, fInitialDownload);
|
2024-04-18 19:40:07 +02:00
|
|
|
m_llmq_ctx->ehfSignalsHandler->UpdatedBlockTip(pindexNew, /* is_masternode = */ m_mn_activeman != nullptr);
|
2020-06-13 20:18:31 +02:00
|
|
|
|
2024-04-25 12:04:44 +02:00
|
|
|
if (m_govman.IsValid()) {
|
|
|
|
m_govman.UpdatedBlockTip(pindexNew, m_connman, m_peerman, m_mn_activeman);
|
|
|
|
}
|
2016-03-02 22:20:04 +01:00
|
|
|
}
|
2017-01-29 09:22:14 +01:00
|
|
|
|
2024-08-26 17:35:12 +02:00
|
|
|
void CDSNotificationInterface::TransactionAddedToMempool(const CTransactionRef& ptx, int64_t nAcceptTime,
|
|
|
|
uint64_t mempool_sequence)
|
2019-05-23 18:22:37 +02:00
|
|
|
{
|
2024-02-28 13:26:42 +01:00
|
|
|
assert(m_cj_ctx && m_llmq_ctx);
|
2024-02-28 13:53:56 +01:00
|
|
|
|
|
|
|
m_llmq_ctx->isman->TransactionAddedToMempool(ptx);
|
|
|
|
m_llmq_ctx->clhandler->TransactionAddedToMempool(ptx, nAcceptTime);
|
2024-02-28 13:26:42 +01:00
|
|
|
m_cj_ctx->dstxman->TransactionAddedToMempool(ptx);
|
2019-05-23 18:22:37 +02:00
|
|
|
}
|
|
|
|
|
2024-08-26 17:35:12 +02:00
|
|
|
void CDSNotificationInterface::TransactionRemovedFromMempool(const CTransactionRef& ptx, MemPoolRemovalReason reason,
|
|
|
|
uint64_t mempool_sequence)
|
2021-05-15 02:17:16 +02:00
|
|
|
{
|
2024-02-28 13:53:56 +01:00
|
|
|
assert(m_llmq_ctx);
|
|
|
|
|
|
|
|
m_llmq_ctx->isman->TransactionRemovedFromMempool(ptx);
|
2021-05-15 02:17:16 +02:00
|
|
|
}
|
|
|
|
|
2020-03-19 17:09:15 +01:00
|
|
|
void CDSNotificationInterface::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
|
2019-05-23 18:22:37 +02:00
|
|
|
{
|
2024-02-28 13:26:42 +01:00
|
|
|
assert(m_cj_ctx && m_llmq_ctx);
|
2024-02-28 13:53:56 +01:00
|
|
|
|
|
|
|
m_llmq_ctx->isman->BlockConnected(pblock, pindex);
|
|
|
|
m_llmq_ctx->clhandler->BlockConnected(pblock, pindex);
|
2024-02-28 13:26:42 +01:00
|
|
|
m_cj_ctx->dstxman->BlockConnected(pblock, pindex);
|
2019-05-23 18:22:37 +02:00
|
|
|
}
|
|
|
|
|
2019-05-27 14:55:29 +02:00
|
|
|
void CDSNotificationInterface::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected)
|
2019-05-23 18:22:37 +02:00
|
|
|
{
|
2024-02-28 13:26:42 +01:00
|
|
|
assert(m_cj_ctx && m_llmq_ctx);
|
2024-02-28 13:53:56 +01:00
|
|
|
|
|
|
|
m_llmq_ctx->isman->BlockDisconnected(pblock, pindexDisconnected);
|
|
|
|
m_llmq_ctx->clhandler->BlockDisconnected(pblock, pindexDisconnected);
|
2024-02-28 13:26:42 +01:00
|
|
|
m_cj_ctx->dstxman->BlockDisconnected(pblock, pindexDisconnected);
|
2019-05-23 18:22:37 +02:00
|
|
|
}
|
|
|
|
|
2023-11-16 19:36:46 +01:00
|
|
|
void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff)
|
2019-01-03 10:17:43 +01:00
|
|
|
{
|
2024-02-28 13:53:56 +01:00
|
|
|
CMNAuth::NotifyMasternodeListChanged(undo, oldMNList, diff, m_connman);
|
2024-04-09 22:38:27 +02:00
|
|
|
if (m_govman.IsValid()) {
|
|
|
|
m_govman.CheckAndRemove();
|
|
|
|
}
|
2019-01-03 10:17:43 +01:00
|
|
|
}
|
2018-09-21 16:01:04 +02:00
|
|
|
|
2021-01-22 05:32:15 +01:00
|
|
|
void CDSNotificationInterface::NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
|
2018-09-21 16:01:04 +02:00
|
|
|
{
|
2024-02-28 13:26:42 +01:00
|
|
|
assert(m_cj_ctx && m_llmq_ctx);
|
2024-02-28 13:53:56 +01:00
|
|
|
|
|
|
|
m_llmq_ctx->isman->NotifyChainLock(pindex);
|
2024-02-28 13:26:42 +01:00
|
|
|
m_cj_ctx->dstxman->NotifyChainLock(pindex, *m_llmq_ctx->clhandler, m_mn_sync);
|
2018-09-21 16:01:04 +02:00
|
|
|
}
|
2024-07-04 15:26:27 +02:00
|
|
|
|
|
|
|
std::unique_ptr<CDSNotificationInterface> g_ds_notification_interface;
|