Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

validationinterface.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <validationinterface.h>
7 
8 #include <init.h>
9 #include <primitives/block.h>
10 #include <scheduler.h>
11 #include <sync.h>
12 #include <txmempool.h>
13 #include <util.h>
14 #include <validation.h>
15 
16 #include <list>
17 #include <atomic>
18 #include <future>
19 
20 #include <boost/signals2/signal.hpp>
21 
23  boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip;
24  boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> SynchronousUpdatedBlockTip;
25  boost::signals2::signal<void (const CTransactionRef &, int64_t)> TransactionAddedToMempool;
26  boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef>&)> BlockConnected;
27  boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex* pindexDisconnected)> BlockDisconnected;
28  boost::signals2::signal<void (const CTransactionRef &)> TransactionRemovedFromMempool;
29  boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
30  boost::signals2::signal<void (int64_t nBestBlockTime, CConnman* connman)> Broadcast;
31  boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
32  boost::signals2::signal<void (const CBlockIndex *, const std::shared_ptr<const CBlock>&)> NewPoWValidBlock;
33  boost::signals2::signal<void (const CBlockIndex *)>AcceptedBlockHeader;
34  boost::signals2::signal<void (const CBlockIndex *, bool)>NotifyHeaderTip;
35  boost::signals2::signal<void (const CTransaction &tx, const llmq::CInstantSendLock& islock)>NotifyTransactionLock;
36  boost::signals2::signal<void (const CBlockIndex* pindex, const llmq::CChainLockSig& clsig)>NotifyChainLock;
37  boost::signals2::signal<void (const CGovernanceVote &vote)>NotifyGovernanceVote;
38  boost::signals2::signal<void (const CGovernanceObject &object)>NotifyGovernanceObject;
39  boost::signals2::signal<void (const CTransaction &currentTx, const CTransaction &previousTx)>NotifyInstantSendDoubleSpendAttempt;
40  boost::signals2::signal<void (bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff)>NotifyMasternodeListChanged;
41  // We are not allowed to assume the scheduler only runs in one thread,
42  // but must ensure all callbacks happen in-order, so we end up creating
43  // our own queue here :(
45 
46  explicit MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {}
47 };
48 
50 
52  assert(!m_internals);
54 }
55 
57  m_internals.reset(nullptr);
58 }
59 
61  if (m_internals) {
62  m_internals->m_schedulerClient.EmptyQueue();
63  }
64 }
65 
67  if (!m_internals) return 0;
68  return m_internals->m_schedulerClient.CallbacksPending();
69 }
70 
72  pool.NotifyEntryRemoved.connect(boost::bind(&CMainSignals::MempoolEntryRemoved, this, _1, _2));
73 }
74 
76  pool.NotifyEntryRemoved.disconnect(boost::bind(&CMainSignals::MempoolEntryRemoved, this, _1, _2));
77 }
78 
80 {
81  return g_signals;
82 }
83 
85  g_signals.m_internals->AcceptedBlockHeader.connect(boost::bind(&CValidationInterface::AcceptedBlockHeader, pwalletIn, _1));
86  g_signals.m_internals->NotifyHeaderTip.connect(boost::bind(&CValidationInterface::NotifyHeaderTip, pwalletIn, _1, _2));
87  g_signals.m_internals->UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
88  g_signals.m_internals->SynchronousUpdatedBlockTip.connect(boost::bind(&CValidationInterface::SynchronousUpdatedBlockTip, pwalletIn, _1, _2, _3));
89  g_signals.m_internals->TransactionAddedToMempool.connect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1, _2));
90  g_signals.m_internals->BlockConnected.connect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
91  g_signals.m_internals->BlockDisconnected.connect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1, _2));
92  g_signals.m_internals->NotifyTransactionLock.connect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, _1, _2));
93  g_signals.m_internals->NotifyChainLock.connect(boost::bind(&CValidationInterface::NotifyChainLock, pwalletIn, _1, _2));
94  g_signals.m_internals->TransactionRemovedFromMempool.connect(boost::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
95  g_signals.m_internals->SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
96  g_signals.m_internals->Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
97  g_signals.m_internals->BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
98  g_signals.m_internals->NewPoWValidBlock.connect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
99  g_signals.m_internals->NotifyGovernanceObject.connect(boost::bind(&CValidationInterface::NotifyGovernanceObject, pwalletIn, _1));
100  g_signals.m_internals->NotifyGovernanceVote.connect(boost::bind(&CValidationInterface::NotifyGovernanceVote, pwalletIn, _1));
101  g_signals.m_internals->NotifyInstantSendDoubleSpendAttempt.connect(boost::bind(&CValidationInterface::NotifyInstantSendDoubleSpendAttempt, pwalletIn, _1, _2));
102  g_signals.m_internals->NotifyMasternodeListChanged.connect(boost::bind(&CValidationInterface::NotifyMasternodeListChanged, pwalletIn, _1, _2, _3));
103 }
104 
106  g_signals.m_internals->BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
107  g_signals.m_internals->Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
108  g_signals.m_internals->SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
109  g_signals.m_internals->NotifyChainLock.disconnect(boost::bind(&CValidationInterface::NotifyChainLock, pwalletIn, _1, _2));
110  g_signals.m_internals->NotifyTransactionLock.disconnect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, _1, _2));
111  g_signals.m_internals->TransactionAddedToMempool.disconnect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1, _2));
112  g_signals.m_internals->BlockConnected.disconnect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
113  g_signals.m_internals->BlockDisconnected.disconnect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1, _2));
114  g_signals.m_internals->TransactionRemovedFromMempool.disconnect(boost::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
115  g_signals.m_internals->UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
116  g_signals.m_internals->SynchronousUpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::SynchronousUpdatedBlockTip, pwalletIn, _1, _2, _3));
117  g_signals.m_internals->NewPoWValidBlock.disconnect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
118  g_signals.m_internals->NotifyHeaderTip.disconnect(boost::bind(&CValidationInterface::NotifyHeaderTip, pwalletIn, _1, _2));
119  g_signals.m_internals->AcceptedBlockHeader.disconnect(boost::bind(&CValidationInterface::AcceptedBlockHeader, pwalletIn, _1));
120  g_signals.m_internals->NotifyGovernanceObject.disconnect(boost::bind(&CValidationInterface::NotifyGovernanceObject, pwalletIn, _1));
121  g_signals.m_internals->NotifyGovernanceVote.disconnect(boost::bind(&CValidationInterface::NotifyGovernanceVote, pwalletIn, _1));
122  g_signals.m_internals->NotifyInstantSendDoubleSpendAttempt.disconnect(boost::bind(&CValidationInterface::NotifyInstantSendDoubleSpendAttempt, pwalletIn, _1, _2));
123  g_signals.m_internals->NotifyMasternodeListChanged.disconnect(boost::bind(&CValidationInterface::NotifyMasternodeListChanged, pwalletIn, _1, _2, _3));
124 }
125 
127  if (!g_signals.m_internals) {
128  return;
129  }
130  g_signals.m_internals->BlockChecked.disconnect_all_slots();
131  g_signals.m_internals->Broadcast.disconnect_all_slots();
132  g_signals.m_internals->SetBestChain.disconnect_all_slots();
133  g_signals.m_internals->NotifyTransactionLock.disconnect_all_slots();
134  g_signals.m_internals->NotifyChainLock.disconnect_all_slots();
135  g_signals.m_internals->TransactionAddedToMempool.disconnect_all_slots();
136  g_signals.m_internals->BlockConnected.disconnect_all_slots();
137  g_signals.m_internals->BlockDisconnected.disconnect_all_slots();
138  g_signals.m_internals->TransactionRemovedFromMempool.disconnect_all_slots();
139  g_signals.m_internals->UpdatedBlockTip.disconnect_all_slots();
140  g_signals.m_internals->SynchronousUpdatedBlockTip.disconnect_all_slots();
141  g_signals.m_internals->NewPoWValidBlock.disconnect_all_slots();
142  g_signals.m_internals->NotifyHeaderTip.disconnect_all_slots();
143  g_signals.m_internals->AcceptedBlockHeader.disconnect_all_slots();
144  g_signals.m_internals->NotifyGovernanceObject.disconnect_all_slots();
145  g_signals.m_internals->NotifyGovernanceVote.disconnect_all_slots();
146  g_signals.m_internals->NotifyInstantSendDoubleSpendAttempt.disconnect_all_slots();
147  g_signals.m_internals->NotifyMasternodeListChanged.disconnect_all_slots();
148 }
149 
150 void CallFunctionInValidationInterfaceQueue(std::function<void ()> func) {
151  g_signals.m_internals->m_schedulerClient.AddToProcessQueue(std::move(func));
152 }
153 
156  // Block until the validation queue drains
157  std::promise<void> promise;
159  promise.set_value();
160  });
161  promise.get_future().wait();
162 }
163 
165  if (reason != MemPoolRemovalReason::BLOCK && reason != MemPoolRemovalReason::CONFLICT) {
166  m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] {
167  m_internals->TransactionRemovedFromMempool(ptx);
168  });
169  }
170 }
171 
172 void CMainSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
173  m_internals->m_schedulerClient.AddToProcessQueue([pindexNew, pindexFork, fInitialDownload, this] {
174  m_internals->UpdatedBlockTip(pindexNew, pindexFork, fInitialDownload);
175  });
176 }
177 
178 void CMainSignals::SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
179  m_internals->SynchronousUpdatedBlockTip(pindexNew, pindexFork, fInitialDownload);
180 }
181 
182 void CMainSignals::TransactionAddedToMempool(const CTransactionRef &ptx, int64_t nAcceptTime) {
183  m_internals->m_schedulerClient.AddToProcessQueue([ptx, nAcceptTime, this] {
184  m_internals->TransactionAddedToMempool(ptx, nAcceptTime);
185  });
186 }
187 
188 void CMainSignals::BlockConnected(const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>>& pvtxConflicted) {
189  m_internals->m_schedulerClient.AddToProcessQueue([pblock, pindex, pvtxConflicted, this] {
190  m_internals->BlockConnected(pblock, pindex, *pvtxConflicted);
191  });
192 }
193 
194 void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock> &pblock, const CBlockIndex* pindexDisconnected) {
195  m_internals->m_schedulerClient.AddToProcessQueue([pblock, pindexDisconnected, this] {
196  m_internals->BlockDisconnected(pblock, pindexDisconnected);
197  });
198 }
199 
201  m_internals->m_schedulerClient.AddToProcessQueue([locator, this] {
202  m_internals->SetBestChain(locator);
203  });
204 }
205 
206 void CMainSignals::Broadcast(int64_t nBestBlockTime, CConnman* connman) {
207  m_internals->Broadcast(nBestBlockTime, connman);
208 }
209 
210 void CMainSignals::BlockChecked(const CBlock& block, const CValidationState& state) {
211  m_internals->BlockChecked(block, state);
212 }
213 
214 void CMainSignals::NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock> &block) {
215  m_internals->NewPoWValidBlock(pindex, block);
216 }
217 
219  m_internals->AcceptedBlockHeader(pindexNew);
220 }
221 
222 void CMainSignals::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload) {
223  m_internals->NotifyHeaderTip(pindexNew, fInitialDownload);
224 }
225 
227  m_internals->NotifyTransactionLock(tx, islock);
228 }
229 
231  m_internals->NotifyChainLock(pindex, clsig);
232 }
233 
235  m_internals->NotifyGovernanceVote(vote);
236 }
237 
239  m_internals->NotifyGovernanceObject(object);
240 }
241 
243  m_internals->NotifyInstantSendDoubleSpendAttempt(currentTx, previousTx);
244 }
245 
247  m_internals->NotifyMasternodeListChanged(undo, oldMNList, diff);
248 }
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)
Class used by CScheduler clients which may schedule multiple jobs which are required to be run serial...
Definition: scheduler.h:93
std::unique_ptr< MainSignalsInstance > m_internals
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
virtual void BlockChecked(const CBlock &, const CValidationState &)
Notifies listeners of a block validation result.
virtual void TransactionAddedToMempool(const CTransactionRef &ptxn, int64_t nAcceptTime)
Notifies listeners of a transaction having been added to mempool.
virtual void AcceptedBlockHeader(const CBlockIndex *pindexNew)
Governance Object.
virtual void NotifyGovernanceVote(const CGovernanceVote &vote)
Describes a place in the block chain to another node such that if the other node doesn&#39;t have the sam...
Definition: block.h:127
void NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload)
void SynchronousUpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)
void BlockDisconnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindexDisconnected)
boost::signals2::signal< void(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex, const std::vector< CTransactionRef > &)> BlockConnected
Definition: block.h:72
void NotifyGovernanceVote(const CGovernanceVote &vote)
void TransactionAddedToMempool(const CTransactionRef &, int64_t)
virtual void ResendWalletTransactions(int64_t nBestBlockTime, CConnman *connman)
Tells listeners to broadcast their data.
virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr< const CBlock > &block)
Notifies listeners that a block which builds directly on our current tip has been received and connec...
boost::signals2::signal< void(const CBlock &, const CValidationState &)> BlockChecked
CCriticalSection cs_main
Definition: validation.cpp:213
void UnregisterBackgroundSignalScheduler()
Unregister a CScheduler to give callbacks which should run in the background - these callbacks will n...
void NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig &clsig)
boost::signals2::signal< void(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindexDisconnected)> BlockDisconnected
boost::signals2::signal< void(const CTransactionRef &, int64_t)> TransactionAddedToMempool
virtual void SetBestChain(const CBlockLocator &locator)
Notifies listeners of the new active block chain on-disk.
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
Definition: txmempool.h:349
void UnregisterAllValidationInterfaces()
Unregister all wallets from core.
void UnregisterValidationInterface(CValidationInterface *pwalletIn)
Unregister a wallet from core.
void Broadcast(int64_t nBestBlockTime, CConnman *connman)
static CScheduler scheduler
Definition: init.cpp:213
void BlockChecked(const CBlock &, const CValidationState &)
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:345
void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList &oldMNList, const CDeterministicMNListDiff &diff)
void NotifyGovernanceObject(const CGovernanceObject &object)
virtual void NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload)
virtual void NotifyChainLock(const CBlockIndex *pindex, const llmq::CChainLockSig &clsig)
boost::signals2::signal< void(const CBlockLocator &)> SetBestChain
static CMainSignals g_signals
virtual void NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx)
Removed for reorganization.
SingleThreadedSchedulerClient m_schedulerClient
MainSignalsInstance(CScheduler *pscheduler)
boost::signals2::signal< void(const CBlockIndex *, const std::shared_ptr< const CBlock > &)> NewPoWValidBlock
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
Notifies listeners of updated block chain tip.
void RegisterWithMempoolSignals(CTxMemPool &pool)
Register with mempool to call TransactionRemovedFromMempool callbacks.
virtual void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList &oldMNList, const CDeterministicMNListDiff &diff)
CMainSignals & GetMainSignals()
boost::signals2::signal< void(const CGovernanceObject &object)> NotifyGovernanceObject
void UnregisterWithMempoolSignals(CTxMemPool &pool)
Unregister with mempool.
Definition: net.h:136
void CallFunctionInValidationInterfaceQueue(std::function< void()> func)
Pushes a function to callback onto the notification queue, guaranteeing any callbacks generated prior...
void AcceptedBlockHeader(const CBlockIndex *pindexNew)
virtual void BlockDisconnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindexDisconnected)
Notifies listeners of a block being disconnected.
virtual void NotifyGovernanceObject(const CGovernanceObject &object)
boost::signals2::signal< void(const CTransaction &currentTx, const CTransaction &previousTx)> NotifyInstantSendDoubleSpendAttempt
void RegisterValidationInterface(CValidationInterface *pwalletIn)
Register a wallet to receive updates from core.
void RegisterBackgroundSignalScheduler(CScheduler &scheduler)
Register a CScheduler to give callbacks which should run in the background (may only be called once) ...
Capture information about block/transaction validation.
Definition: validation.h:22
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:442
virtual void NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock &islock)
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:170
void FlushBackgroundCallbacks()
Call any remaining callbacks on the calling thread.
boost::signals2::signal< void(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> SynchronousUpdatedBlockTip
void MempoolEntryRemoved(CTransactionRef tx, MemPoolRemovalReason reason)
boost::signals2::signal< void(const CBlockIndex *, bool)> NotifyHeaderTip
void NotifyInstantSendDoubleSpendAttempt(const CTransaction &currentTx, const CTransaction &previousTx)
virtual void TransactionRemovedFromMempool(const CTransactionRef &ptx)
Notifies listeners of a transaction leaving mempool.
#define AssertLockNotHeld(cs)
Definition: sync.h:88
virtual void SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
Same as UpdatedBlockTip, but called from the caller&#39;s thread.
boost::signals2::signal< void(bool undo, const CDeterministicMNList &oldMNList, const CDeterministicMNListDiff &diff)> NotifyMasternodeListChanged
virtual void BlockConnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex, const std::vector< CTransactionRef > &txnConflicted)
Notifies listeners of a block being connected.
boost::signals2::signal< void(const CTransaction &tx, const llmq::CInstantSendLock &islock)> NotifyTransactionLock
void SetBestChain(const CBlockLocator &)
boost::signals2::signal< void(const CBlockIndex *pindex, const llmq::CChainLockSig &clsig)> NotifyChainLock
boost::signals2::signal< void(CTransactionRef, MemPoolRemovalReason)> NotifyEntryRemoved
Definition: txmempool.h:687
boost::signals2::signal< void(const CGovernanceVote &vote)> NotifyGovernanceVote
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:198
boost::signals2::signal< void(const CBlockIndex *)> AcceptedBlockHeader
boost::signals2::signal< void(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr< const CBlock > &)
boost::signals2::signal< void(int64_t nBestBlockTime, CConnman *connman)> Broadcast
boost::signals2::signal< void(const CTransactionRef &)> TransactionRemovedFromMempool
void NotifyTransactionLock(const CTransaction &tx, const llmq::CInstantSendLock &islock)
void BlockConnected(const std::shared_ptr< const CBlock > &, const CBlockIndex *pindex, const std::shared_ptr< const std::vector< CTransactionRef >> &)
Released under the MIT license