2015-02-04 16:11:44 -08:00
|
|
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
|
|
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2019-07-18 07:16:09 -07:00
|
|
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
2015-02-04 16:11:44 -08:00
|
|
|
|
|
|
|
#include "validationinterface.h"
|
|
|
|
|
2019-11-20 06:16:58 -08:00
|
|
|
#include "chainparams.h"
|
2019-11-20 04:52:58 -08:00
|
|
|
#include "txmempool.h"
|
|
|
|
|
|
|
|
#include <boost/thread.hpp>
|
|
|
|
|
|
|
|
#include <chrono>
|
|
|
|
#include <thread>
|
|
|
|
|
2015-02-04 16:11:44 -08:00
|
|
|
static CMainSignals g_signals;
|
|
|
|
|
|
|
|
CMainSignals& GetMainSignals()
|
|
|
|
{
|
|
|
|
return g_signals;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RegisterValidationInterface(CValidationInterface* pwalletIn) {
|
2015-05-07 07:49:00 -07:00
|
|
|
g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1));
|
2015-02-04 16:11:44 -08:00
|
|
|
g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
|
|
|
|
g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
|
|
|
|
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
2019-11-21 09:00:22 -08:00
|
|
|
g_signals.ChainTip.connect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3));
|
2015-02-04 16:11:44 -08:00
|
|
|
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
|
|
|
|
g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
|
2015-03-23 10:47:18 -07:00
|
|
|
g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
|
2015-02-04 16:11:44 -08:00
|
|
|
g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
|
2015-04-10 03:49:01 -07:00
|
|
|
g_signals.ScriptForMining.connect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1));
|
2015-07-01 07:06:49 -07:00
|
|
|
g_signals.BlockFound.connect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1));
|
2015-02-04 16:11:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
|
2015-07-01 07:06:49 -07:00
|
|
|
g_signals.BlockFound.disconnect(boost::bind(&CValidationInterface::ResetRequestCount, pwalletIn, _1));
|
2015-04-10 03:49:01 -07:00
|
|
|
g_signals.ScriptForMining.disconnect(boost::bind(&CValidationInterface::GetScriptForMining, pwalletIn, _1));
|
2015-02-04 16:11:44 -08:00
|
|
|
g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
|
2015-03-23 10:47:18 -07:00
|
|
|
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1));
|
2015-02-04 16:11:44 -08:00
|
|
|
g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
|
2019-11-21 09:00:22 -08:00
|
|
|
g_signals.ChainTip.disconnect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3));
|
2015-02-04 16:11:44 -08:00
|
|
|
g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
|
|
|
|
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
|
|
|
g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
|
|
|
|
g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
|
2015-05-07 07:49:00 -07:00
|
|
|
g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1));
|
2015-02-04 16:11:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void UnregisterAllValidationInterfaces() {
|
2015-04-10 03:49:01 -07:00
|
|
|
g_signals.BlockFound.disconnect_all_slots();
|
|
|
|
g_signals.ScriptForMining.disconnect_all_slots();
|
2015-02-04 16:11:44 -08:00
|
|
|
g_signals.BlockChecked.disconnect_all_slots();
|
|
|
|
g_signals.Broadcast.disconnect_all_slots();
|
|
|
|
g_signals.Inventory.disconnect_all_slots();
|
2016-08-23 20:52:43 -07:00
|
|
|
g_signals.ChainTip.disconnect_all_slots();
|
2015-02-04 16:11:44 -08:00
|
|
|
g_signals.SetBestChain.disconnect_all_slots();
|
|
|
|
g_signals.UpdatedTransaction.disconnect_all_slots();
|
|
|
|
g_signals.EraseTransaction.disconnect_all_slots();
|
|
|
|
g_signals.SyncTransaction.disconnect_all_slots();
|
2015-05-07 07:49:00 -07:00
|
|
|
g_signals.UpdatedBlockTip.disconnect_all_slots();
|
2015-02-04 16:11:44 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) {
|
|
|
|
g_signals.SyncTransaction(tx, pblock);
|
|
|
|
}
|
2019-11-20 04:52:58 -08:00
|
|
|
|
|
|
|
extern CTxMemPool mempool;
|
|
|
|
|
|
|
|
void ThreadNotifyWallets()
|
|
|
|
{
|
|
|
|
while (true) {
|
|
|
|
// Run the notifier on an integer second in the steady clock.
|
|
|
|
auto now = std::chrono::steady_clock::now().time_since_epoch();
|
|
|
|
auto nextFire = std::chrono::duration_cast<std::chrono::seconds>(
|
|
|
|
now + std::chrono::seconds(1));
|
|
|
|
std::this_thread::sleep_until(
|
|
|
|
std::chrono::time_point<std::chrono::steady_clock>(nextFire));
|
|
|
|
|
|
|
|
boost::this_thread::interruption_point();
|
|
|
|
|
2019-11-20 06:16:58 -08:00
|
|
|
// Collect all the state we require
|
|
|
|
|
|
|
|
auto recentlyAdded = mempool.DrainRecentlyAdded();
|
|
|
|
|
|
|
|
// Execute wallet logic based on the collected state. We MUST NOT take
|
|
|
|
// the cs_main or mempool.cs locks again until after the next sleep.
|
|
|
|
|
|
|
|
// A race condition can occur here between these SyncWithWallets calls, and
|
|
|
|
// the ones triggered by block logic (in ConnectTip and DisconnectTip). It
|
|
|
|
// is harmless because calling SyncWithWallets(_, NULL) does not alter the
|
|
|
|
// wallet transaction's block information.
|
|
|
|
for (auto tx : recentlyAdded.first) {
|
|
|
|
try {
|
|
|
|
SyncWithWallets(tx, NULL);
|
|
|
|
} catch (const boost::thread_interrupted&) {
|
|
|
|
throw;
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
PrintExceptionContinue(&e, "ThreadNotifyWallets()");
|
|
|
|
} catch (...) {
|
|
|
|
PrintExceptionContinue(NULL, "ThreadNotifyWallets()");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update the notified sequence number. We only need this in regtest mode,
|
|
|
|
// and should not lock on cs between calls to DrainRecentlyAdded otherwise.
|
|
|
|
if (Params().NetworkIDString() == "regtest") {
|
|
|
|
mempool.SetNotifiedSequence(recentlyAdded.second);
|
|
|
|
}
|
2019-11-20 04:52:58 -08:00
|
|
|
}
|
|
|
|
}
|