1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
6 #include "validationinterface.h"
9 #include "primitives/block.h"
10 #include "scheduler.h"
17 #include <boost/signals2/signal.hpp>
19 struct MainSignalsInstance
{
20 boost::signals2::signal
<void (const CBlockIndex
*, const CBlockIndex
*, bool fInitialDownload
)> UpdatedBlockTip
;
21 boost::signals2::signal
<void (const CTransactionRef
&)> TransactionAddedToMempool
;
22 boost::signals2::signal
<void (const std::shared_ptr
<const CBlock
> &, const CBlockIndex
*pindex
, const std::vector
<CTransactionRef
>&)> BlockConnected
;
23 boost::signals2::signal
<void (const std::shared_ptr
<const CBlock
> &)> BlockDisconnected
;
24 boost::signals2::signal
<void (const CBlockLocator
&)> SetBestChain
;
25 boost::signals2::signal
<void (const uint256
&)> Inventory
;
26 boost::signals2::signal
<void (int64_t nBestBlockTime
, CConnman
* connman
)> Broadcast
;
27 boost::signals2::signal
<void (const CBlock
&, const CValidationState
&)> BlockChecked
;
28 boost::signals2::signal
<void (const CBlockIndex
*, const std::shared_ptr
<const CBlock
>&)> NewPoWValidBlock
;
30 // We are not allowed to assume the scheduler only runs in one thread,
31 // but must ensure all callbacks happen in-order, so we end up creating
32 // our own queue here :(
33 SingleThreadedSchedulerClient m_schedulerClient
;
35 explicit MainSignalsInstance(CScheduler
*pscheduler
) : m_schedulerClient(pscheduler
) {}
38 static CMainSignals g_signals
;
40 void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler
& scheduler
) {
42 m_internals
.reset(new MainSignalsInstance(&scheduler
));
45 void CMainSignals::UnregisterBackgroundSignalScheduler() {
46 m_internals
.reset(nullptr);
49 void CMainSignals::FlushBackgroundCallbacks() {
50 m_internals
->m_schedulerClient
.EmptyQueue();
53 CMainSignals
& GetMainSignals()
58 void RegisterValidationInterface(CValidationInterface
* pwalletIn
) {
59 g_signals
.m_internals
->UpdatedBlockTip
.connect(boost::bind(&CValidationInterface::UpdatedBlockTip
, pwalletIn
, _1
, _2
, _3
));
60 g_signals
.m_internals
->TransactionAddedToMempool
.connect(boost::bind(&CValidationInterface::TransactionAddedToMempool
, pwalletIn
, _1
));
61 g_signals
.m_internals
->BlockConnected
.connect(boost::bind(&CValidationInterface::BlockConnected
, pwalletIn
, _1
, _2
, _3
));
62 g_signals
.m_internals
->BlockDisconnected
.connect(boost::bind(&CValidationInterface::BlockDisconnected
, pwalletIn
, _1
));
63 g_signals
.m_internals
->SetBestChain
.connect(boost::bind(&CValidationInterface::SetBestChain
, pwalletIn
, _1
));
64 g_signals
.m_internals
->Inventory
.connect(boost::bind(&CValidationInterface::Inventory
, pwalletIn
, _1
));
65 g_signals
.m_internals
->Broadcast
.connect(boost::bind(&CValidationInterface::ResendWalletTransactions
, pwalletIn
, _1
, _2
));
66 g_signals
.m_internals
->BlockChecked
.connect(boost::bind(&CValidationInterface::BlockChecked
, pwalletIn
, _1
, _2
));
67 g_signals
.m_internals
->NewPoWValidBlock
.connect(boost::bind(&CValidationInterface::NewPoWValidBlock
, pwalletIn
, _1
, _2
));
70 void UnregisterValidationInterface(CValidationInterface
* pwalletIn
) {
71 g_signals
.m_internals
->BlockChecked
.disconnect(boost::bind(&CValidationInterface::BlockChecked
, pwalletIn
, _1
, _2
));
72 g_signals
.m_internals
->Broadcast
.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions
, pwalletIn
, _1
, _2
));
73 g_signals
.m_internals
->Inventory
.disconnect(boost::bind(&CValidationInterface::Inventory
, pwalletIn
, _1
));
74 g_signals
.m_internals
->SetBestChain
.disconnect(boost::bind(&CValidationInterface::SetBestChain
, pwalletIn
, _1
));
75 g_signals
.m_internals
->TransactionAddedToMempool
.disconnect(boost::bind(&CValidationInterface::TransactionAddedToMempool
, pwalletIn
, _1
));
76 g_signals
.m_internals
->BlockConnected
.disconnect(boost::bind(&CValidationInterface::BlockConnected
, pwalletIn
, _1
, _2
, _3
));
77 g_signals
.m_internals
->BlockDisconnected
.disconnect(boost::bind(&CValidationInterface::BlockDisconnected
, pwalletIn
, _1
));
78 g_signals
.m_internals
->UpdatedBlockTip
.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip
, pwalletIn
, _1
, _2
, _3
));
79 g_signals
.m_internals
->NewPoWValidBlock
.disconnect(boost::bind(&CValidationInterface::NewPoWValidBlock
, pwalletIn
, _1
, _2
));
82 void UnregisterAllValidationInterfaces() {
83 g_signals
.m_internals
->BlockChecked
.disconnect_all_slots();
84 g_signals
.m_internals
->Broadcast
.disconnect_all_slots();
85 g_signals
.m_internals
->Inventory
.disconnect_all_slots();
86 g_signals
.m_internals
->SetBestChain
.disconnect_all_slots();
87 g_signals
.m_internals
->TransactionAddedToMempool
.disconnect_all_slots();
88 g_signals
.m_internals
->BlockConnected
.disconnect_all_slots();
89 g_signals
.m_internals
->BlockDisconnected
.disconnect_all_slots();
90 g_signals
.m_internals
->UpdatedBlockTip
.disconnect_all_slots();
91 g_signals
.m_internals
->NewPoWValidBlock
.disconnect_all_slots();
94 void CMainSignals::UpdatedBlockTip(const CBlockIndex
*pindexNew
, const CBlockIndex
*pindexFork
, bool fInitialDownload
) {
95 m_internals
->UpdatedBlockTip(pindexNew
, pindexFork
, fInitialDownload
);
98 void CMainSignals::TransactionAddedToMempool(const CTransactionRef
&ptx
) {
99 m_internals
->TransactionAddedToMempool(ptx
);
102 void CMainSignals::BlockConnected(const std::shared_ptr
<const CBlock
> &pblock
, const CBlockIndex
*pindex
, const std::vector
<CTransactionRef
>& vtxConflicted
) {
103 m_internals
->BlockConnected(pblock
, pindex
, vtxConflicted
);
106 void CMainSignals::BlockDisconnected(const std::shared_ptr
<const CBlock
> &pblock
) {
107 m_internals
->BlockDisconnected(pblock
);
110 void CMainSignals::SetBestChain(const CBlockLocator
&locator
) {
111 m_internals
->SetBestChain(locator
);
114 void CMainSignals::Inventory(const uint256
&hash
) {
115 m_internals
->Inventory(hash
);
118 void CMainSignals::Broadcast(int64_t nBestBlockTime
, CConnman
* connman
) {
119 m_internals
->Broadcast(nBestBlockTime
, connman
);
122 void CMainSignals::BlockChecked(const CBlock
& block
, const CValidationState
& state
) {
123 m_internals
->BlockChecked(block
, state
);
126 void CMainSignals::NewPoWValidBlock(const CBlockIndex
*pindex
, const std::shared_ptr
<const CBlock
> &block
) {
127 m_internals
->NewPoWValidBlock(pindex
, block
);