Browse Source

Use CValidationInterface from chain logic to notify peer logic

This adds a new CValidationInterface subclass, defined in main.h,
to receive notifications of UpdatedBlockTip and use that to push
blocks to peers, instead of doing it directly from
ActivateBestChain.
0.14
Matt Corallo 8 years ago
parent
commit
fef1010199
  1. 5
      src/init.cpp
  2. 56
      src/main.cpp
  3. 11
      src/main.h

5
src/init.cpp

@ -72,6 +72,7 @@ static const bool DEFAULT_DISABLE_SAFEMODE = false;
static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
std::unique_ptr<CConnman> g_connman; std::unique_ptr<CConnman> g_connman;
std::unique_ptr<PeerLogicValidation> peerLogic;
#if ENABLE_ZMQ #if ENABLE_ZMQ
static CZMQNotificationInterface* pzmqNotificationInterface = NULL; static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
@ -200,6 +201,8 @@ void Shutdown()
pwalletMain->Flush(false); pwalletMain->Flush(false);
#endif #endif
MapPort(false); MapPort(false);
UnregisterValidationInterface(peerLogic.get());
peerLogic.reset();
g_connman.reset(); g_connman.reset();
StopTorControl(); StopTorControl();
@ -1102,6 +1105,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
g_connman = std::unique_ptr<CConnman>(new CConnman(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()))); g_connman = std::unique_ptr<CConnman>(new CConnman(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max())));
CConnman& connman = *g_connman; CConnman& connman = *g_connman;
peerLogic.reset(new PeerLogicValidation(&connman));
RegisterValidationInterface(peerLogic.get());
RegisterNodeSignals(GetNodeSignals()); RegisterNodeSignals(GetNodeSignals());
// sanitize comments per BIP-0014, format user agent and check total size // sanitize comments per BIP-0014, format user agent and check total size

56
src/main.cpp

@ -3073,30 +3073,6 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
if (pindexFork != pindexNewTip) { if (pindexFork != pindexNewTip) {
uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip); uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip);
if (!fInitialDownload) {
// Find the hashes of all blocks that weren't previously in the best chain.
std::vector<uint256> vHashes;
CBlockIndex *pindexToAnnounce = pindexNewTip;
while (pindexToAnnounce != pindexFork) {
vHashes.push_back(pindexToAnnounce->GetBlockHash());
pindexToAnnounce = pindexToAnnounce->pprev;
if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
// Limit announcements in case of a huge reorganization.
// Rely on the peer's synchronization mechanism in that case.
break;
}
}
// Relay inventory, but don't relay old inventory during initial block download.
if(connman) {
connman->ForEachNode([nNewHeight, &vHashes](CNode* pnode) {
if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 0)) {
BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) {
pnode->PushBlockHash(hash);
}
}
});
}
}
// Notify external listeners about the new tip. // Notify external listeners about the new tip.
GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload); GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
} }
@ -4682,6 +4658,38 @@ std::string GetWarnings(const std::string& strFor)
//////////////////////////////////////////////////////////////////////////////
//
// blockchain -> download logic notification
//
void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
const int nNewHeight = pindexNew->nHeight;
if (!fInitialDownload) {
// Find the hashes of all blocks that weren't previously in the best chain.
std::vector<uint256> vHashes;
const CBlockIndex *pindexToAnnounce = pindexNew;
while (pindexToAnnounce != pindexFork) {
vHashes.push_back(pindexToAnnounce->GetBlockHash());
pindexToAnnounce = pindexToAnnounce->pprev;
if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
// Limit announcements in case of a huge reorganization.
// Rely on the peer's synchronization mechanism in that case.
break;
}
}
// Relay inventory, but don't relay old inventory during initial block download.
connman->ForEachNode([nNewHeight, &vHashes](CNode* pnode) {
if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 0)) {
BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) {
pnode->PushBlockHash(hash);
}
}
});
}
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// Messages // Messages

11
src/main.h

@ -16,6 +16,7 @@
#include "net.h" #include "net.h"
#include "script/script_error.h" #include "script/script_error.h"
#include "sync.h" #include "sync.h"
#include "validationinterface.h"
#include "versionbits.h" #include "versionbits.h"
#include <algorithm> #include <algorithm>
@ -527,6 +528,16 @@ void RegisterNodeSignals(CNodeSignals& nodeSignals);
/** Unregister a network node */ /** Unregister a network node */
void UnregisterNodeSignals(CNodeSignals& nodeSignals); void UnregisterNodeSignals(CNodeSignals& nodeSignals);
class PeerLogicValidation : public CValidationInterface {
private:
CConnman* connman;
public:
PeerLogicValidation(CConnman* connmanIn) : connman(connmanIn) {}
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload);
};
struct CNodeStateStats { struct CNodeStateStats {
int nMisbehavior; int nMisbehavior;
int nSyncHeight; int nSyncHeight;

Loading…
Cancel
Save