Backport Bitcoin PR#8865: Decouple peer-processing-logic from block-connection-logic (#1556)
* Make validationinterface.UpdatedBlockTip more verbose In anticipation of making all the callbacks out of block processing flow through it. Note that vHashes will always have something in it since pindexFork != pindexNewTip. * Remove duplicate nBlocksEstimate cmp (we already checked IsIBD()) * Remove CConnman parameter from ProcessNewBlock/ActivateBestChain * Remove SyncWithWallets wrapper function * Move net-processing logic definitions together in main.h * 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. * Always call UpdatedBlockTip, even if blocks were only disconnected * Use BlockChecked signal to send reject messages from mapBlockSource
This commit is contained in:
parent
cc4db34f4d
commit
a3c8cb20df
@ -99,6 +99,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;
|
||||||
@ -228,6 +229,8 @@ void PrepareShutdown()
|
|||||||
#endif
|
#endif
|
||||||
GenerateBitcoins(false, 0, Params(), *g_connman);
|
GenerateBitcoins(false, 0, Params(), *g_connman);
|
||||||
MapPort(false);
|
MapPort(false);
|
||||||
|
UnregisterValidationInterface(peerLogic.get());
|
||||||
|
peerLogic.reset();
|
||||||
g_connman.reset();
|
g_connman.reset();
|
||||||
|
|
||||||
// STORE DATA CACHES INTO SERIALIZED DAT FILES
|
// STORE DATA CACHES INTO SERIALIZED DAT FILES
|
||||||
@ -1316,6 +1319,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||||||
g_connman = std::unique_ptr<CConnman>(new CConnman());
|
g_connman = std::unique_ptr<CConnman>(new CConnman());
|
||||||
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
|
||||||
|
121
src/main.cpp
121
src/main.cpp
@ -1540,7 +1540,8 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!fDryRun) SyncWithWallets(tx, NULL);
|
if(!fDryRun)
|
||||||
|
GetMainSignals().SyncTransaction(tx, NULL);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1966,17 +1967,6 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
|
void static InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state) {
|
||||||
int nDoS = 0;
|
|
||||||
if (state.IsInvalid(nDoS)) {
|
|
||||||
std::map<uint256, NodeId>::iterator it = mapBlockSource.find(pindex->GetBlockHash());
|
|
||||||
if (it != mapBlockSource.end() && State(it->second)) {
|
|
||||||
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
|
|
||||||
CBlockReject reject = {(unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), pindex->GetBlockHash()};
|
|
||||||
State(it->second)->rejects.push_back(reject);
|
|
||||||
if (nDoS > 0)
|
|
||||||
Misbehaving(it->second, nDoS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!state.CorruptionPossible()) {
|
if (!state.CorruptionPossible()) {
|
||||||
pindex->nStatus |= BLOCK_FAILED_VALID;
|
pindex->nStatus |= BLOCK_FAILED_VALID;
|
||||||
setDirtyBlockIndex.insert(pindex);
|
setDirtyBlockIndex.insert(pindex);
|
||||||
@ -3047,7 +3037,7 @@ bool static DisconnectTip(CValidationState& state, const Consensus::Params& cons
|
|||||||
// Let wallets know transactions went from 1-confirmed to
|
// Let wallets know transactions went from 1-confirmed to
|
||||||
// 0-confirmed or conflicted:
|
// 0-confirmed or conflicted:
|
||||||
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
|
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
|
||||||
SyncWithWallets(tx, NULL);
|
GetMainSignals().SyncTransaction(tx, NULL);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3086,7 +3076,6 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
|
|||||||
InvalidBlockFound(pindexNew, state);
|
InvalidBlockFound(pindexNew, state);
|
||||||
return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
|
return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
|
||||||
}
|
}
|
||||||
mapBlockSource.erase(pindexNew->GetBlockHash());
|
|
||||||
nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
|
nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
|
||||||
LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
|
LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
|
||||||
assert(view.Flush());
|
assert(view.Flush());
|
||||||
@ -3106,11 +3095,11 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
|
|||||||
// Tell wallet about transactions that went from mempool
|
// Tell wallet about transactions that went from mempool
|
||||||
// to conflicted:
|
// to conflicted:
|
||||||
BOOST_FOREACH(const CTransaction &tx, txConflicted) {
|
BOOST_FOREACH(const CTransaction &tx, txConflicted) {
|
||||||
SyncWithWallets(tx, NULL);
|
GetMainSignals().SyncTransaction(tx, NULL);
|
||||||
}
|
}
|
||||||
// ... and about transactions that got confirmed:
|
// ... and about transactions that got confirmed:
|
||||||
BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
|
BOOST_FOREACH(const CTransaction &tx, pblock->vtx) {
|
||||||
SyncWithWallets(tx, pblock);
|
GetMainSignals().SyncTransaction(tx, pblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
|
int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
|
||||||
@ -3336,7 +3325,7 @@ static void NotifyHeaderTip() {
|
|||||||
* or an activated best chain. pblock is either NULL or a pointer to a block
|
* or an activated best chain. pblock is either NULL or a pointer to a block
|
||||||
* that is already loaded (to avoid loading it again from disk).
|
* that is already loaded (to avoid loading it again from disk).
|
||||||
*/
|
*/
|
||||||
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock, CConnman* connman) {
|
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) {
|
||||||
CBlockIndex *pindexMostWork = NULL;
|
CBlockIndex *pindexMostWork = NULL;
|
||||||
CBlockIndex *pindexNewTip = NULL;
|
CBlockIndex *pindexNewTip = NULL;
|
||||||
do {
|
do {
|
||||||
@ -3346,7 +3335,6 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
|
|||||||
|
|
||||||
const CBlockIndex *pindexFork;
|
const CBlockIndex *pindexFork;
|
||||||
bool fInitialDownload;
|
bool fInitialDownload;
|
||||||
int nNewHeight;
|
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CBlockIndex *pindexOldTip = chainActive.Tip();
|
CBlockIndex *pindexOldTip = chainActive.Tip();
|
||||||
@ -3369,49 +3357,17 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
|
|||||||
pindexNewTip = chainActive.Tip();
|
pindexNewTip = chainActive.Tip();
|
||||||
pindexFork = chainActive.FindFork(pindexOldTip);
|
pindexFork = chainActive.FindFork(pindexOldTip);
|
||||||
fInitialDownload = IsInitialBlockDownload();
|
fInitialDownload = IsInitialBlockDownload();
|
||||||
nNewHeight = chainActive.Height();
|
|
||||||
}
|
}
|
||||||
// When we reach this point, we switched to a new tip (stored in pindexNewTip).
|
// When we reach this point, we switched to a new tip (stored in pindexNewTip).
|
||||||
|
|
||||||
// Notifications/callbacks that can run without cs_main
|
// Notifications/callbacks that can run without cs_main
|
||||||
if(connman)
|
|
||||||
connman->SetBestHeight(chainActive.Height());
|
// Notify external listeners about the new tip.
|
||||||
|
GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
|
||||||
|
|
||||||
// Always notify the UI if a new block tip was connected
|
// Always notify the UI if a new block tip was connected
|
||||||
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.
|
|
||||||
int nBlockEstimate = 0;
|
|
||||||
if (fCheckpointsEnabled)
|
|
||||||
nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints());
|
|
||||||
if(connman) {
|
|
||||||
connman->ForEachNode([nNewHeight, nBlockEstimate, &vHashes](CNode* pnode) {
|
|
||||||
if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) {
|
|
||||||
BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) {
|
|
||||||
pnode->PushBlockHash(hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Notify external listeners about the new tip.
|
|
||||||
if (!vHashes.empty()) {
|
|
||||||
GetMainSignals().UpdatedBlockTip(pindexNewTip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (pindexNewTip != pindexMostWork);
|
} while (pindexNewTip != pindexMostWork);
|
||||||
CheckBlockIndex(chainparams.GetConsensus());
|
CheckBlockIndex(chainparams.GetConsensus());
|
||||||
@ -4003,7 +3959,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, CConnman* connman)
|
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
@ -4025,7 +3981,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, C
|
|||||||
|
|
||||||
NotifyHeaderTip();
|
NotifyHeaderTip();
|
||||||
|
|
||||||
if (!ActivateBestChain(state, chainparams, pblock, connman))
|
if (!ActivateBestChain(state, chainparams, pblock))
|
||||||
return error("%s: ActivateBestChain failed", __func__);
|
return error("%s: ActivateBestChain failed", __func__);
|
||||||
|
|
||||||
masternodeSync.IsBlockchainSynced(true);
|
masternodeSync.IsBlockchainSynced(true);
|
||||||
@ -4909,6 +4865,59 @@ 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;
|
||||||
|
connman->SetBestHeight(nNewHeight);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationState& state) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
|
||||||
|
const uint256 hash(block.GetHash());
|
||||||
|
std::map<uint256, NodeId>::iterator it = mapBlockSource.find(hash);
|
||||||
|
|
||||||
|
int nDoS = 0;
|
||||||
|
if (state.IsInvalid(nDoS)) {
|
||||||
|
if (it != mapBlockSource.end() && State(it->second)) {
|
||||||
|
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
|
||||||
|
CBlockReject reject = {(unsigned char)state.GetRejectCode(), state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), hash};
|
||||||
|
State(it->second)->rejects.push_back(reject);
|
||||||
|
if (nDoS > 0)
|
||||||
|
Misbehaving(it->second, nDoS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (it != mapBlockSource.end())
|
||||||
|
mapBlockSource.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Messages
|
// Messages
|
||||||
@ -6107,7 +6116,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||||||
// Such an unrequested block may still be processed, subject to the
|
// Such an unrequested block may still be processed, subject to the
|
||||||
// conditions in AcceptBlock().
|
// conditions in AcceptBlock().
|
||||||
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
|
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
|
||||||
ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL, &connman);
|
ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL);
|
||||||
int nDoS;
|
int nDoS;
|
||||||
if (state.IsInvalid(nDoS)) {
|
if (state.IsInvalid(nDoS)) {
|
||||||
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
|
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
|
||||||
|
72
src/main.h
72
src/main.h
@ -17,6 +17,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 "spentindex.h"
|
#include "spentindex.h"
|
||||||
|
|
||||||
@ -42,7 +43,6 @@ class CTxMemPool;
|
|||||||
class CValidationInterface;
|
class CValidationInterface;
|
||||||
class CValidationState;
|
class CValidationState;
|
||||||
|
|
||||||
struct CNodeStateStats;
|
|
||||||
struct LockPoints;
|
struct LockPoints;
|
||||||
|
|
||||||
/** Default for accepting alerts from the P2P network. */
|
/** Default for accepting alerts from the P2P network. */
|
||||||
@ -189,11 +189,6 @@ static const unsigned int DEFAULT_CHECKLEVEL = 3;
|
|||||||
// Setting the target to > than 550MB will make it likely we can respect the target.
|
// Setting the target to > than 550MB will make it likely we can respect the target.
|
||||||
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
|
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES = 550 * 1024 * 1024;
|
||||||
|
|
||||||
/** Register with a network node to receive its signals */
|
|
||||||
void RegisterNodeSignals(CNodeSignals& nodeSignals);
|
|
||||||
/** Unregister a network node */
|
|
||||||
void UnregisterNodeSignals(CNodeSignals& nodeSignals);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process an incoming block. This only returns after the best known valid
|
* Process an incoming block. This only returns after the best known valid
|
||||||
* block is made active. Note that it does not, however, guarantee that the
|
* block is made active. Note that it does not, however, guarantee that the
|
||||||
@ -206,7 +201,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals);
|
|||||||
* @param[out] dbp The already known disk position of pblock, or NULL if not yet stored.
|
* @param[out] dbp The already known disk position of pblock, or NULL if not yet stored.
|
||||||
* @return True if state.IsValid()
|
* @return True if state.IsValid()
|
||||||
*/
|
*/
|
||||||
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, CConnman* connman);
|
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp);
|
||||||
/** Check whether enough disk space is available for an incoming block */
|
/** Check whether enough disk space is available for an incoming block */
|
||||||
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
|
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
|
||||||
/** Open a block file (blk?????.dat) */
|
/** Open a block file (blk?????.dat) */
|
||||||
@ -223,15 +218,6 @@ bool InitBlockIndex(const CChainParams& chainparams);
|
|||||||
bool LoadBlockIndex();
|
bool LoadBlockIndex();
|
||||||
/** Unload database information */
|
/** Unload database information */
|
||||||
void UnloadBlockIndex();
|
void UnloadBlockIndex();
|
||||||
/** Process protocol messages received from a given node */
|
|
||||||
bool ProcessMessages(CNode* pfrom, CConnman& connman);
|
|
||||||
/**
|
|
||||||
* Send queued protocol messages to be sent to a give node.
|
|
||||||
*
|
|
||||||
* @param[in] pto The node which we are sending messages to.
|
|
||||||
* @param[in] connman The connection manager for that node.
|
|
||||||
*/
|
|
||||||
bool SendMessages(CNode* pto, CConnman& connman);
|
|
||||||
/** Run an instance of the script checking thread */
|
/** Run an instance of the script checking thread */
|
||||||
void ThreadScriptCheck();
|
void ThreadScriptCheck();
|
||||||
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
||||||
@ -247,7 +233,7 @@ std::string GetWarnings(const std::string& strFor);
|
|||||||
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
|
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
|
||||||
bool GetTransaction(const uint256 &hash, CTransaction &tx, const Consensus::Params& params, uint256 &hashBlock, bool fAllowSlow = false);
|
bool GetTransaction(const uint256 &hash, CTransaction &tx, const Consensus::Params& params, uint256 &hashBlock, bool fAllowSlow = false);
|
||||||
/** Find the best known block, and make it the tip of the block chain */
|
/** Find the best known block, and make it the tip of the block chain */
|
||||||
bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, const CBlock* pblock = NULL, CConnman* connman = NULL);
|
bool ActivateBestChain(CValidationState& state, const CChainParams& chainparams, const CBlock* pblock = NULL);
|
||||||
|
|
||||||
double ConvertBitsToDouble(unsigned int nBits);
|
double ConvertBitsToDouble(unsigned int nBits);
|
||||||
CAmount GetBlockSubsidy(int nBits, int nHeight, const Consensus::Params& consensusParams, bool fSuperblockPartOnly = false);
|
CAmount GetBlockSubsidy(int nBits, int nHeight, const Consensus::Params& consensusParams, bool fSuperblockPartOnly = false);
|
||||||
@ -277,10 +263,6 @@ void UnlinkPrunedFiles(std::set<int>& setFilesToPrune);
|
|||||||
|
|
||||||
/** Create a new block index entry for a given block hash */
|
/** Create a new block index entry for a given block hash */
|
||||||
CBlockIndex * InsertBlockIndex(uint256 hash);
|
CBlockIndex * InsertBlockIndex(uint256 hash);
|
||||||
/** Get statistics from node state */
|
|
||||||
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
|
|
||||||
/** Increase a node's misbehavior score. */
|
|
||||||
void Misbehaving(NodeId nodeid, int howmuch);
|
|
||||||
/** Flush all state, indexes and buffers to disk. */
|
/** Flush all state, indexes and buffers to disk. */
|
||||||
void FlushStateToDisk();
|
void FlushStateToDisk();
|
||||||
/** Prune block files and flush state to disk. */
|
/** Prune block files and flush state to disk. */
|
||||||
@ -301,13 +283,6 @@ std::string FormatStateMessage(const CValidationState &state);
|
|||||||
/** Get the BIP9 state for a given deployment at the current tip. */
|
/** Get the BIP9 state for a given deployment at the current tip. */
|
||||||
ThresholdState VersionBitsTipState(const Consensus::Params& params, Consensus::DeploymentPos pos);
|
ThresholdState VersionBitsTipState(const Consensus::Params& params, Consensus::DeploymentPos pos);
|
||||||
|
|
||||||
struct CNodeStateStats {
|
|
||||||
int nMisbehavior;
|
|
||||||
int nSyncHeight;
|
|
||||||
int nCommonHeight;
|
|
||||||
std::vector<int> vHeightInFlight;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CTimestampIndexIteratorKey {
|
struct CTimestampIndexIteratorKey {
|
||||||
unsigned int timestamp;
|
unsigned int timestamp;
|
||||||
|
|
||||||
@ -863,4 +838,45 @@ static const unsigned int REJECT_ALREADY_KNOWN = 0x101;
|
|||||||
/** Transaction conflicts with a transaction already known */
|
/** Transaction conflicts with a transaction already known */
|
||||||
static const unsigned int REJECT_CONFLICT = 0x102;
|
static const unsigned int REJECT_CONFLICT = 0x102;
|
||||||
|
|
||||||
|
// The following things handle network-processing logic
|
||||||
|
// (and should be moved to a separate file)
|
||||||
|
|
||||||
|
/** Register with a network node to receive its signals */
|
||||||
|
void RegisterNodeSignals(CNodeSignals& nodeSignals);
|
||||||
|
/** Unregister a network node */
|
||||||
|
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);
|
||||||
|
virtual void BlockChecked(const CBlock& block, const CValidationState& state);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CNodeStateStats {
|
||||||
|
int nMisbehavior;
|
||||||
|
int nSyncHeight;
|
||||||
|
int nCommonHeight;
|
||||||
|
std::vector<int> vHeightInFlight;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Get statistics from node state */
|
||||||
|
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
|
||||||
|
/** Increase a node's misbehavior score. */
|
||||||
|
void Misbehaving(NodeId nodeid, int howmuch);
|
||||||
|
|
||||||
|
/** Process protocol messages received from a given node */
|
||||||
|
bool ProcessMessages(CNode* pfrom, CConnman& connman);
|
||||||
|
/**
|
||||||
|
* Send queued protocol messages to be sent to a give node.
|
||||||
|
*
|
||||||
|
* @param[in] pto The node which we are sending messages to.
|
||||||
|
* @param[in] connman The connection manager for that node.
|
||||||
|
*/
|
||||||
|
bool SendMessages(CNode* pto, CConnman& connman);
|
||||||
|
|
||||||
#endif // BITCOIN_MAIN_H
|
#endif // BITCOIN_MAIN_H
|
||||||
|
@ -376,7 +376,7 @@ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainparams, CConnman* connman)
|
static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainparams)
|
||||||
{
|
{
|
||||||
LogPrintf("%s\n", pblock->ToString());
|
LogPrintf("%s\n", pblock->ToString());
|
||||||
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
|
LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
|
||||||
@ -393,7 +393,7 @@ static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainpar
|
|||||||
|
|
||||||
// Process this block the same as if we had received it from another node
|
// Process this block the same as if we had received it from another node
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL, connman))
|
if (!ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL))
|
||||||
return error("ProcessBlockFound -- ProcessNewBlock() failed, block not accepted");
|
return error("ProcessBlockFound -- ProcessNewBlock() failed, block not accepted");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -468,7 +468,7 @@ void static BitcoinMiner(const CChainParams& chainparams, CConnman& connman)
|
|||||||
// Found a solution
|
// Found a solution
|
||||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||||
LogPrintf("DashMiner:\n proof-of-work found\n hash: %s\n target: %s\n", hash.GetHex(), hashTarget.GetHex());
|
LogPrintf("DashMiner:\n proof-of-work found\n hash: %s\n target: %s\n", hash.GetHex(), hashTarget.GetHex());
|
||||||
ProcessBlockFound(pblock, chainparams, &connman);
|
ProcessBlockFound(pblock, chainparams);
|
||||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||||
coinbaseScript->KeepScript();
|
coinbaseScript->KeepScript();
|
||||||
|
|
||||||
|
@ -1007,7 +1007,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state.IsValid()) {
|
if (state.IsValid()) {
|
||||||
ActivateBestChain(state, Params(), NULL, g_connman.get());
|
ActivateBestChain(state, Params(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.IsValid()) {
|
if (!state.IsValid()) {
|
||||||
@ -1046,7 +1046,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state.IsValid()) {
|
if (state.IsValid()) {
|
||||||
ActivateBestChain(state, Params(), NULL, g_connman.get());
|
ActivateBestChain(state, Params(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.IsValid()) {
|
if (!state.IsValid()) {
|
||||||
|
@ -178,7 +178,7 @@ UniValue generate(const UniValue& params, bool fHelp)
|
|||||||
++pblock->nNonce;
|
++pblock->nNonce;
|
||||||
}
|
}
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL, g_connman.get()))
|
if (!ProcessNewBlock(state, Params(), NULL, pblock, true, NULL))
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted");
|
||||||
++nHeight;
|
++nHeight;
|
||||||
blockHashes.push_back(pblock->GetHash().GetHex());
|
blockHashes.push_back(pblock->GetHash().GetHex());
|
||||||
@ -797,7 +797,7 @@ UniValue submitblock(const UniValue& params, bool fHelp)
|
|||||||
CValidationState state;
|
CValidationState state;
|
||||||
submitblock_StateCatcher sc(block.GetHash());
|
submitblock_StateCatcher sc(block.GetHash());
|
||||||
RegisterValidationInterface(&sc);
|
RegisterValidationInterface(&sc);
|
||||||
bool fAccepted = ProcessNewBlock(state, Params(), NULL, &block, true, NULL, g_connman.get());
|
bool fAccepted = ProcessNewBlock(state, Params(), NULL, &block, true, NULL);
|
||||||
UnregisterValidationInterface(&sc);
|
UnregisterValidationInterface(&sc);
|
||||||
if (fBlockPresent)
|
if (fBlockPresent)
|
||||||
{
|
{
|
||||||
|
@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||||||
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
||||||
pblock->nNonce = blockinfo[i].nonce;
|
pblock->nNonce = blockinfo[i].nonce;
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL, connman));
|
BOOST_CHECK(ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL));
|
||||||
BOOST_CHECK(state.IsValid());
|
BOOST_CHECK(state.IsValid());
|
||||||
pblock->hashPrevBlock = pblock->GetHash();
|
pblock->hashPrevBlock = pblock->GetHash();
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>&
|
|||||||
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
|
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
|
||||||
|
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
ProcessNewBlock(state, chainparams, NULL, &block, true, NULL, connman);
|
ProcessNewBlock(state, chainparams, NULL, &block, true, NULL);
|
||||||
|
|
||||||
CBlock result = block;
|
CBlock result = block;
|
||||||
delete pblocktemplate;
|
delete pblocktemplate;
|
||||||
|
@ -13,7 +13,7 @@ CMainSignals& GetMainSignals()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegisterValidationInterface(CValidationInterface* pwalletIn) {
|
void RegisterValidationInterface(CValidationInterface* pwalletIn) {
|
||||||
g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1));
|
g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
|
||||||
g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
|
g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
|
||||||
g_signals.NotifyTransactionLock.connect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, _1));
|
g_signals.NotifyTransactionLock.connect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, _1));
|
||||||
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
||||||
@ -35,7 +35,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
|
|||||||
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
||||||
g_signals.NotifyTransactionLock.disconnect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, _1));
|
g_signals.NotifyTransactionLock.disconnect(boost::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, _1));
|
||||||
g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
|
g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
|
||||||
g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1));
|
g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnregisterAllValidationInterfaces() {
|
void UnregisterAllValidationInterfaces() {
|
||||||
@ -50,7 +50,3 @@ void UnregisterAllValidationInterfaces() {
|
|||||||
g_signals.SyncTransaction.disconnect_all_slots();
|
g_signals.SyncTransaction.disconnect_all_slots();
|
||||||
g_signals.UpdatedBlockTip.disconnect_all_slots();
|
g_signals.UpdatedBlockTip.disconnect_all_slots();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) {
|
|
||||||
g_signals.SyncTransaction(tx, pblock);
|
|
||||||
}
|
|
||||||
|
@ -27,12 +27,10 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn);
|
|||||||
void UnregisterValidationInterface(CValidationInterface* pwalletIn);
|
void UnregisterValidationInterface(CValidationInterface* pwalletIn);
|
||||||
/** Unregister all wallets from core */
|
/** Unregister all wallets from core */
|
||||||
void UnregisterAllValidationInterfaces();
|
void UnregisterAllValidationInterfaces();
|
||||||
/** Push an updated transaction to all registered wallets */
|
|
||||||
void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL);
|
|
||||||
|
|
||||||
class CValidationInterface {
|
class CValidationInterface {
|
||||||
protected:
|
protected:
|
||||||
virtual void UpdatedBlockTip(const CBlockIndex *pindex) {}
|
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {}
|
||||||
virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}
|
virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}
|
||||||
virtual void NotifyTransactionLock(const CTransaction &tx) {}
|
virtual void NotifyTransactionLock(const CTransaction &tx) {}
|
||||||
virtual void SetBestChain(const CBlockLocator &locator) {}
|
virtual void SetBestChain(const CBlockLocator &locator) {}
|
||||||
@ -49,7 +47,7 @@ protected:
|
|||||||
|
|
||||||
struct CMainSignals {
|
struct CMainSignals {
|
||||||
/** Notifies listeners of updated block chain tip */
|
/** Notifies listeners of updated block chain tip */
|
||||||
boost::signals2::signal<void (const CBlockIndex *)> UpdatedBlockTip;
|
boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip;
|
||||||
/** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
|
/** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
|
||||||
boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
|
boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
|
||||||
/** Notifies listeners of an updated transaction lock without new data. */
|
/** Notifies listeners of an updated transaction lock without new data. */
|
||||||
|
@ -126,12 +126,15 @@ void CZMQNotificationInterface::Shutdown()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindex)
|
void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
|
||||||
{
|
{
|
||||||
|
if (fInitialDownload || pindexNew == pindexFork) // In IBD or blocks were disconnected without any new ones
|
||||||
|
return;
|
||||||
|
|
||||||
for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
|
for (std::list<CZMQAbstractNotifier*>::iterator i = notifiers.begin(); i!=notifiers.end(); )
|
||||||
{
|
{
|
||||||
CZMQAbstractNotifier *notifier = *i;
|
CZMQAbstractNotifier *notifier = *i;
|
||||||
if (notifier->NotifyBlock(pindex))
|
if (notifier->NotifyBlock(pindexNew))
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ protected:
|
|||||||
|
|
||||||
// CValidationInterface
|
// CValidationInterface
|
||||||
void SyncTransaction(const CTransaction &tx, const CBlock *pblock);
|
void SyncTransaction(const CTransaction &tx, const CBlock *pblock);
|
||||||
void UpdatedBlockTip(const CBlockIndex *pindex);
|
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload);
|
||||||
void NotifyTransactionLock(const CTransaction &tx);
|
void NotifyTransactionLock(const CTransaction &tx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user