dash/src/dsnotificationinterface.cpp
pasta 7a9e475c26
Merge #6231: backport: merge bitcoin#19572, #20953, #20523, #21008, #21310, #22079, #23471, #24218 (zmq backports)
b75e83b298 merge bitcoin#24218: Fix implicit-integer-sign-change (Kittywhiskers Van Gogh)
8ecc22f51f merge bitcoin#23471: Improve ZMQ documentation (Kittywhiskers Van Gogh)
2965093c4a merge bitcoin#22079: Add support to listen on IPv6 addresses (Kittywhiskers Van Gogh)
3ac3714957 merge bitcoin#21310: fix sync-up by matching notification to generated block (Kittywhiskers Van Gogh)
7b0c725c59 merge bitcoin#21008: fix zmq test flakiness, improve speed (Kittywhiskers Van Gogh)
5e87efd04b merge bitcoin#20523: deduplicate 'sequence' publisher message creation/sending (Kittywhiskers Van Gogh)
99c730f0f3 merge bitcoin#20953: dedup zmq test setup code (node restart, topics subscription) (Kittywhiskers Van Gogh)
982c1f03d4 merge bitcoin#19572: Create "sequence" notifier, enabling client-side mempool tracking (Kittywhiskers Van Gogh)
b0b4e0fa7f zmq: Make `g_zmq_notification_interface` a smart pointer (Kittywhiskers Van Gogh)
0a1ffd30b9 zmq: extend appending address to log msg for Dash-specific notifications (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * [bitcoin#19572](https://github.com/bitcoin/bitcoin/pull/19572) introduces tests in `interface_zmq.py` that validate newly introduced "sequence" reporting of all message types (`C`, `D`, `R` and `A`). The `R` message type (removed from mempool) is tested by leveraging the RBF mechanism, which isn't present in Dash.

    In order to allow the tests to successfully pass, all fee bumping and RBF-specific code had to be removed from the tests. This test also involves creating a new block to test the `C` message (connected block) that would return a `time-too-new` error and fail unless mocktime has been disabled (which has been done in this test).

  * When backporting [bitcoin#18309](https://github.com/bitcoin/bitcoin/pull/18309) ([dash#5728](https://github.com/dashpay/dash/pull/5728)), Dash-specific ZMQ notifications did not have those changes applied to them and that particular backport was merged upstream *after* [bitcoin#19572](https://github.com/bitcoin/bitcoin/pull/19572), meaning, for completion, the changes from [bitcoin#18309](https://github.com/bitcoin/bitcoin/pull/18309) have been integrated into [bitcoin#19572](https://github.com/bitcoin/bitcoin/pull/19572)'s backport.

    As for the Dash-specific notifications, they have been covered to ensure uniformity in a separate commit.

  * The ZMQ notification interface has been converted to a smart pointer in the interest of safety (this change is eventually done upstream in 8ed4ff8e05d61a8e954d72cebdc2e1d1ab24fb84 ([bitcoin#27125](https://github.com/bitcoin/bitcoin/pull/27125)))

  ## Breaking Changes

  None expected.

  ## Checklist:

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK b75e83b298
  PastaPastaPasta:
    utACK b75e83b298
  knst:
    utACK b75e83b298

Tree-SHA512: 9f860d1203bebe0914a5102f101f646873d14754830d651fb91ed0d1285a6c1a58ffc492b07d4768324d94f53171c9a4da974cf4a0b1e5c665979eace289f6f0
2024-08-30 22:18:37 -05:00

156 lines
5.8 KiB
C++

// Copyright (c) 2014-2024 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <chainparams.h>
#include <coinjoin/coinjoin.h>
#ifdef ENABLE_WALLET
#include <coinjoin/client.h>
#endif // ENABLE_WALLET
#include <coinjoin/context.h>
#include <dsnotificationinterface.h>
#include <governance/governance.h>
#include <masternode/sync.h>
#include <net_processing.h>
#include <validation.h>
#include <evo/deterministicmns.h>
#include <evo/mnauth.h>
#include <llmq/chainlocks.h>
#include <llmq/context.h>
#include <llmq/dkgsessionmgr.h>
#include <llmq/ehf_signals.h>
#include <llmq/instantsend.h>
#include <llmq/quorums.h>
CDSNotificationInterface::CDSNotificationInterface(CConnman& connman,
CMasternodeSync& mn_sync,
CGovernanceManager& govman,
PeerManager& peerman,
const ChainstateManager& chainman,
const CActiveMasternodeManager* const mn_activeman,
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),
m_peerman(peerman),
m_chainman(chainman),
m_mn_activeman(mn_activeman),
m_dmnman(dmnman),
m_llmq_ctx(llmq_ctx),
m_cj_ctx(cj_ctx) {}
void CDSNotificationInterface::InitializeCurrentBlockTip()
{
SynchronousUpdatedBlockTip(m_chainman.ActiveChain().Tip(), nullptr, m_chainman.ActiveChainstate().IsInitialBlockDownload());
UpdatedBlockTip(m_chainman.ActiveChain().Tip(), nullptr, m_chainman.ActiveChainstate().IsInitialBlockDownload());
}
void CDSNotificationInterface::AcceptedBlockHeader(const CBlockIndex *pindexNew)
{
assert(m_llmq_ctx);
m_llmq_ctx->clhandler->AcceptedBlockHeader(pindexNew);
m_mn_sync.AcceptedBlockHeader(pindexNew);
}
void CDSNotificationInterface::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload)
{
m_mn_sync.NotifyHeaderTip(pindexNew, fInitialDownload);
}
void CDSNotificationInterface::SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
{
assert(m_dmnman);
if (pindexNew == pindexFork) // blocks were disconnected without any new ones
return;
m_dmnman->UpdatedBlockTip(pindexNew);
}
void CDSNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
{
assert(m_cj_ctx && m_llmq_ctx);
if (pindexNew == pindexFork) // blocks were disconnected without any new ones
return;
m_mn_sync.UpdatedBlockTip(WITH_LOCK(::cs_main, return m_chainman.m_best_header), pindexNew, fInitialDownload);
if (fInitialDownload)
return;
m_cj_ctx->dstxman->UpdatedBlockTip(pindexNew, *m_llmq_ctx->clhandler, m_mn_sync);
#ifdef ENABLE_WALLET
m_cj_ctx->walletman->ForEachCJClientMan(
[&pindexNew](std::unique_ptr<CCoinJoinClientManager>& clientman) { clientman->UpdatedBlockTip(pindexNew); });
#endif // ENABLE_WALLET
m_llmq_ctx->isman->UpdatedBlockTip(pindexNew);
m_llmq_ctx->clhandler->UpdatedBlockTip();
m_llmq_ctx->qman->UpdatedBlockTip(pindexNew, fInitialDownload);
m_llmq_ctx->qdkgsman->UpdatedBlockTip(pindexNew, fInitialDownload);
m_llmq_ctx->ehfSignalsHandler->UpdatedBlockTip(pindexNew, /* is_masternode = */ m_mn_activeman != nullptr);
if (m_govman.IsValid()) {
m_govman.UpdatedBlockTip(pindexNew, m_connman, m_peerman, m_mn_activeman);
}
}
void CDSNotificationInterface::TransactionAddedToMempool(const CTransactionRef& ptx, int64_t nAcceptTime,
uint64_t mempool_sequence)
{
assert(m_cj_ctx && m_llmq_ctx);
m_llmq_ctx->isman->TransactionAddedToMempool(ptx);
m_llmq_ctx->clhandler->TransactionAddedToMempool(ptx, nAcceptTime);
m_cj_ctx->dstxman->TransactionAddedToMempool(ptx);
}
void CDSNotificationInterface::TransactionRemovedFromMempool(const CTransactionRef& ptx, MemPoolRemovalReason reason,
uint64_t mempool_sequence)
{
assert(m_llmq_ctx);
m_llmq_ctx->isman->TransactionRemovedFromMempool(ptx);
}
void CDSNotificationInterface::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
{
assert(m_cj_ctx && m_llmq_ctx);
m_llmq_ctx->isman->BlockConnected(pblock, pindex);
m_llmq_ctx->clhandler->BlockConnected(pblock, pindex);
m_cj_ctx->dstxman->BlockConnected(pblock, pindex);
}
void CDSNotificationInterface::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected)
{
assert(m_cj_ctx && m_llmq_ctx);
m_llmq_ctx->isman->BlockDisconnected(pblock, pindexDisconnected);
m_llmq_ctx->clhandler->BlockDisconnected(pblock, pindexDisconnected);
m_cj_ctx->dstxman->BlockDisconnected(pblock, pindexDisconnected);
}
void CDSNotificationInterface::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff)
{
CMNAuth::NotifyMasternodeListChanged(undo, oldMNList, diff, m_connman);
if (m_govman.IsValid()) {
m_govman.CheckAndRemove();
}
}
void CDSNotificationInterface::NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const llmq::CChainLockSig>& clsig)
{
assert(m_cj_ctx && m_llmq_ctx);
m_llmq_ctx->isman->NotifyChainLock(pindex);
m_cj_ctx->dstxman->NotifyChainLock(pindex, *m_llmq_ctx->clhandler, m_mn_sync);
}