Merge #8865: Decouple peer-processing-logic from block-connection-logic
a9aec5c
Use BlockChecked signal to send reject messages from mapBlockSource (Matt Corallo)7565e03
Remove SyncWithWallets wrapper function (Matt Corallo)12ee1fe
Always call UpdatedBlockTip, even if blocks were only disconnected (Matt Corallo)f5efa28
Remove CConnman parameter from ProcessNewBlock/ActivateBestChain (Matt Corallo)fef1010
Use CValidationInterface from chain logic to notify peer logic (Matt Corallo)aefcb7b
Move net-processing logic definitions together in main.h (Matt Corallo)0278fb5
Remove duplicate nBlocksEstimate cmp (we already checked IsIBD()) (Matt Corallo)87e7d72
Make validationinterface.UpdatedBlockTip more verbose (Matt Corallo)
This commit is contained in:
commit
05998da5a7
11 changed files with 132 additions and 104 deletions
|
@ -72,6 +72,7 @@ static const bool DEFAULT_DISABLE_SAFEMODE = false;
|
|||
static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
|
||||
|
||||
std::unique_ptr<CConnman> g_connman;
|
||||
std::unique_ptr<PeerLogicValidation> peerLogic;
|
||||
|
||||
#if ENABLE_ZMQ
|
||||
static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
|
||||
|
@ -200,6 +201,8 @@ void Shutdown()
|
|||
pwalletMain->Flush(false);
|
||||
#endif
|
||||
MapPort(false);
|
||||
UnregisterValidationInterface(peerLogic.get());
|
||||
peerLogic.reset();
|
||||
g_connman.reset();
|
||||
|
||||
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())));
|
||||
CConnman& connman = *g_connman;
|
||||
|
||||
peerLogic.reset(new PeerLogicValidation(&connman));
|
||||
RegisterValidationInterface(peerLogic.get());
|
||||
RegisterNodeSignals(GetNodeSignals());
|
||||
|
||||
// sanitize comments per BIP-0014, format user agent and check total size
|
||||
|
|
122
src/main.cpp
122
src/main.cpp
|
@ -1567,7 +1567,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
|
|||
}
|
||||
}
|
||||
|
||||
SyncWithWallets(tx, NULL);
|
||||
GetMainSignals().SyncTransaction(tx, NULL, CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1882,17 +1882,6 @@ void static InvalidChainFound(CBlockIndex* pindexNew)
|
|||
}
|
||||
|
||||
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()) {
|
||||
pindex->nStatus |= BLOCK_FAILED_VALID;
|
||||
setDirtyBlockIndex.insert(pindex);
|
||||
|
@ -2800,7 +2789,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara
|
|||
// Let wallets know transactions went from 1-confirmed to
|
||||
// 0-confirmed or conflicted:
|
||||
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
|
||||
SyncWithWallets(tx, pindexDelete->pprev);
|
||||
GetMainSignals().SyncTransaction(tx, pindexDelete->pprev, CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2839,7 +2828,6 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams,
|
|||
InvalidBlockFound(pindexNew, state);
|
||||
return error("ConnectTip(): ConnectBlock %s failed", pindexNew->GetBlockHash().ToString());
|
||||
}
|
||||
mapBlockSource.erase(pindexNew->GetBlockHash());
|
||||
nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
|
||||
LogPrint("bench", " - Connect total: %.2fms [%.2fs]\n", (nTime3 - nTime2) * 0.001, nTimeConnectTotal * 0.000001);
|
||||
assert(view.Flush());
|
||||
|
@ -3038,7 +3026,7 @@ static void NotifyHeaderTip() {
|
|||
* 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).
|
||||
*/
|
||||
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 *pindexNewTip = NULL;
|
||||
std::vector<std::tuple<CTransaction,CBlockIndex*,int>> txChanged;
|
||||
|
@ -3053,7 +3041,6 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
|
|||
const CBlockIndex *pindexFork;
|
||||
std::list<CTransaction> txConflicted;
|
||||
bool fInitialDownload;
|
||||
int nNewHeight;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
CBlockIndex *pindexOldTip = chainActive.Tip();
|
||||
|
@ -3076,59 +3063,27 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
|
|||
pindexNewTip = chainActive.Tip();
|
||||
pindexFork = chainActive.FindFork(pindexOldTip);
|
||||
fInitialDownload = IsInitialBlockDownload();
|
||||
nNewHeight = chainActive.Height();
|
||||
}
|
||||
// When we reach this point, we switched to a new tip (stored in pindexNewTip).
|
||||
|
||||
// Notifications/callbacks that can run without cs_main
|
||||
if(connman)
|
||||
connman->SetBestHeight(nNewHeight);
|
||||
|
||||
// throw all transactions though the signal-interface
|
||||
// while _not_ holding the cs_main lock
|
||||
BOOST_FOREACH(const CTransaction &tx, txConflicted)
|
||||
{
|
||||
SyncWithWallets(tx, pindexNewTip);
|
||||
GetMainSignals().SyncTransaction(tx, pindexNewTip, CMainSignals::SYNC_TRANSACTION_NOT_IN_BLOCK);
|
||||
}
|
||||
// ... and about transactions that got confirmed:
|
||||
for(unsigned int i = 0; i < txChanged.size(); i++)
|
||||
SyncWithWallets(std::get<0>(txChanged[i]), std::get<1>(txChanged[i]), std::get<2>(txChanged[i]));
|
||||
GetMainSignals().SyncTransaction(std::get<0>(txChanged[i]), std::get<1>(txChanged[i]), std::get<2>(txChanged[i]));
|
||||
|
||||
// Notify external listeners about the new tip.
|
||||
GetMainSignals().UpdatedBlockTip(pindexNewTip, pindexFork, fInitialDownload);
|
||||
|
||||
// Always notify the UI if a new block tip was connected
|
||||
if (pindexFork != 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);
|
||||
CheckBlockIndex(chainparams.GetConsensus());
|
||||
|
@ -3787,7 +3742,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
|
|||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -3809,7 +3764,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, C
|
|||
|
||||
NotifyHeaderTip();
|
||||
|
||||
if (!ActivateBestChain(state, chainparams, pblock, connman))
|
||||
if (!ActivateBestChain(state, chainparams, pblock))
|
||||
return error("%s: ActivateBestChain failed", __func__);
|
||||
|
||||
return true;
|
||||
|
@ -4742,6 +4697,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
|
||||
|
@ -5845,7 +5853,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||
pfrom->PushMessage(NetMsgType::GETDATA, invs);
|
||||
} else {
|
||||
CValidationState state;
|
||||
ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL, &connman);
|
||||
ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL);
|
||||
int nDoS;
|
||||
if (state.IsInvalid(nDoS)) {
|
||||
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
|
||||
|
@ -6021,7 +6029,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
|||
// Such an unrequested block may still be processed, subject to the
|
||||
// conditions in AcceptBlock().
|
||||
bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload();
|
||||
ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL, &connman);
|
||||
ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL);
|
||||
int nDoS;
|
||||
if (state.IsInvalid(nDoS)) {
|
||||
assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
|
||||
|
|
72
src/main.h
72
src/main.h
|
@ -16,6 +16,7 @@
|
|||
#include "net.h"
|
||||
#include "script/script_error.h"
|
||||
#include "sync.h"
|
||||
#include "validationinterface.h"
|
||||
#include "versionbits.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -41,7 +42,6 @@ class CValidationInterface;
|
|||
class CValidationState;
|
||||
|
||||
struct PrecomputedTransactionData;
|
||||
struct CNodeStateStats;
|
||||
struct LockPoints;
|
||||
|
||||
/** Default for DEFAULT_WHITELISTRELAY. */
|
||||
|
@ -211,11 +211,6 @@ static const unsigned int DEFAULT_CHECKLEVEL = 3;
|
|||
// 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;
|
||||
|
||||
/** 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
|
||||
* block is made active. Note that it does not, however, guarantee that the
|
||||
|
@ -228,7 +223,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals);
|
|||
* @param[out] dbp The already known disk position of pblock, or NULL if not yet stored.
|
||||
* @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 */
|
||||
bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
|
||||
/** Open a block file (blk?????.dat) */
|
||||
|
@ -245,15 +240,6 @@ bool InitBlockIndex(const CChainParams& chainparams);
|
|||
bool LoadBlockIndex();
|
||||
/** Unload database information */
|
||||
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 */
|
||||
void ThreadScriptCheck();
|
||||
/** Check whether we are doing an initial block download (synchronizing from disk or network) */
|
||||
|
@ -269,7 +255,7 @@ std::string GetWarnings(const std::string& strFor);
|
|||
/** 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);
|
||||
/** 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);
|
||||
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams);
|
||||
|
||||
/**
|
||||
|
@ -296,10 +282,6 @@ void UnlinkPrunedFiles(std::set<int>& setFilesToPrune);
|
|||
|
||||
/** Create a new block index entry for a given block 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. */
|
||||
void FlushStateToDisk();
|
||||
/** Prune block files and flush state to disk. */
|
||||
|
@ -315,13 +297,6 @@ std::string FormatStateMessage(const CValidationState &state);
|
|||
/** Get the BIP9 state for a given deployment at the current tip. */
|
||||
ThresholdState VersionBitsTipState(const Consensus::Params& params, Consensus::DeploymentPos pos);
|
||||
|
||||
struct CNodeStateStats {
|
||||
int nMisbehavior;
|
||||
int nSyncHeight;
|
||||
int nCommonHeight;
|
||||
std::vector<int> vHeightInFlight;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -553,4 +528,45 @@ static const unsigned int REJECT_ALREADY_KNOWN = 0x101;
|
|||
/** Transaction conflicts with a transaction already known */
|
||||
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
|
||||
|
|
|
@ -1317,7 +1317,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp)
|
|||
}
|
||||
|
||||
if (state.IsValid()) {
|
||||
ActivateBestChain(state, Params(), NULL, g_connman.get());
|
||||
ActivateBestChain(state, Params(), NULL);
|
||||
}
|
||||
|
||||
if (!state.IsValid()) {
|
||||
|
@ -1355,7 +1355,7 @@ UniValue reconsiderblock(const UniValue& params, bool fHelp)
|
|||
}
|
||||
|
||||
CValidationState state;
|
||||
ActivateBestChain(state, Params(), NULL, g_connman.get());
|
||||
ActivateBestChain(state, Params(), NULL);
|
||||
|
||||
if (!state.IsValid()) {
|
||||
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
|
||||
|
|
|
@ -132,7 +132,7 @@ UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nG
|
|||
continue;
|
||||
}
|
||||
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");
|
||||
++nHeight;
|
||||
blockHashes.push_back(pblock->GetHash().GetHex());
|
||||
|
@ -751,7 +751,7 @@ UniValue submitblock(const UniValue& params, bool fHelp)
|
|||
CValidationState state;
|
||||
submitblock_StateCatcher sc(block.GetHash());
|
||||
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);
|
||||
if (fBlockPresent)
|
||||
{
|
||||
|
|
|
@ -224,7 +224,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
||||
pblock->nNonce = blockinfo[i].nonce;
|
||||
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());
|
||||
pblock->hashPrevBlock = pblock->GetHash();
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>&
|
|||
while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
|
||||
|
||||
CValidationState state;
|
||||
ProcessNewBlock(state, chainparams, NULL, &block, true, NULL, connman);
|
||||
ProcessNewBlock(state, chainparams, NULL, &block, true, NULL);
|
||||
|
||||
CBlock result = block;
|
||||
return result;
|
||||
|
|
|
@ -13,7 +13,7 @@ CMainSignals& GetMainSignals()
|
|||
}
|
||||
|
||||
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, _3));
|
||||
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
||||
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
|
||||
|
@ -33,7 +33,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
|
|||
g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
|
||||
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
|
||||
g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2, _3));
|
||||
g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1));
|
||||
g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
|
||||
}
|
||||
|
||||
void UnregisterAllValidationInterfaces() {
|
||||
|
@ -47,7 +47,3 @@ void UnregisterAllValidationInterfaces() {
|
|||
g_signals.SyncTransaction.disconnect_all_slots();
|
||||
g_signals.UpdatedBlockTip.disconnect_all_slots();
|
||||
}
|
||||
|
||||
void SyncWithWallets(const CTransaction &tx, const CBlockIndex *pindex, int posInBlock) {
|
||||
g_signals.SyncTransaction(tx, pindex, posInBlock);
|
||||
}
|
||||
|
|
|
@ -28,12 +28,10 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn);
|
|||
void UnregisterValidationInterface(CValidationInterface* pwalletIn);
|
||||
/** Unregister all wallets from core */
|
||||
void UnregisterAllValidationInterfaces();
|
||||
/** Push an updated transaction to all registered wallets */
|
||||
void SyncWithWallets(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock = -1);
|
||||
|
||||
class CValidationInterface {
|
||||
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 CBlockIndex *pindex, int posInBlock) {}
|
||||
virtual void SetBestChain(const CBlockLocator &locator) {}
|
||||
virtual void UpdatedTransaction(const uint256 &hash) {}
|
||||
|
@ -49,7 +47,9 @@ protected:
|
|||
|
||||
struct CMainSignals {
|
||||
/** 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;
|
||||
/** A posInBlock value for SyncTransaction which indicates the transaction was conflicted, disconnected, or not in a block */
|
||||
static const int SYNC_TRANSACTION_NOT_IN_BLOCK = -1;
|
||||
/** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
|
||||
boost::signals2::signal<void (const CTransaction &, const CBlockIndex *pindex, int posInBlock)> SyncTransaction;
|
||||
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
|
||||
|
|
|
@ -124,12 +124,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(); )
|
||||
{
|
||||
CZMQAbstractNotifier *notifier = *i;
|
||||
if (notifier->NotifyBlock(pindex))
|
||||
if (notifier->NotifyBlock(pindexNew))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ protected:
|
|||
|
||||
// CValidationInterface
|
||||
void SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock);
|
||||
void UpdatedBlockTip(const CBlockIndex *pindex);
|
||||
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload);
|
||||
|
||||
private:
|
||||
CZMQNotificationInterface();
|
||||
|
|
Loading…
Reference in a new issue