Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backport: merge bitcoin#21148, #21327, #23970, #24021, #24543, #26844, #25325, #28165, partial bitcoin#20524, #26036, #27981 (networking backports: part 7) #6067

Merged
merged 14 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ BITCOIN_CORE_H = \
streams.h \
statsd_client.h \
support/allocators/mt_pooled_secure.h \
support/allocators/pool.h \
support/allocators/pooled_secure.h \
support/allocators/secure.h \
support/allocators/zeroafterfree.h \
Expand All @@ -328,6 +329,7 @@ BITCOIN_CORE_H = \
torcontrol.h \
txdb.h \
txmempool.h \
txorphanage.h \
undo.h \
unordered_lru_cache.h \
util/bip32.h \
Expand Down Expand Up @@ -527,6 +529,7 @@ libbitcoin_server_a_SOURCES = \
torcontrol.cpp \
txdb.cpp \
txmempool.cpp \
txorphanage.cpp \
validation.cpp \
validationinterface.cpp \
versionbits.cpp \
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.bench.include
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ bench_bench_dash_SOURCES = \
bench/nanobench.h \
bench/nanobench.cpp \
bench/peer_eviction.cpp \
bench/pool.cpp \
bench/rpc_blockchain.cpp \
bench/rpc_mempool.cpp \
bench/util_time.cpp \
Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ BITCOIN_TESTS =\
test/netbase_tests.cpp \
test/pmt_tests.cpp \
test/policyestimator_tests.cpp \
test/pool_tests.cpp \
test/pow_tests.cpp \
test/prevector_tests.cpp \
test/raii_event_tests.cpp \
Expand Down Expand Up @@ -298,6 +299,7 @@ test_fuzz_fuzz_SOURCES = \
test/fuzz/parse_univalue.cpp \
test/fuzz/policy_estimator.cpp \
test/fuzz/policy_estimator_io.cpp \
test/fuzz/poolresource.cpp \
test/fuzz/pow.cpp \
test/fuzz/prevector.cpp \
test/fuzz/primitives_transaction.cpp \
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.test_util.include
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ TEST_UTIL_H = \
test/util/logging.h \
test/util/mining.h \
test/util/net.h \
test/util/poolresourcetester.h \
test/util/script.h \
test/util/setup_common.h \
test/util/str.h \
Expand Down
50 changes: 50 additions & 0 deletions src/bench/pool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>
#include <support/allocators/pool.h>

#include <unordered_map>

template <typename Map>
void BenchFillClearMap(benchmark::Bench& bench, Map& map)
{
size_t batch_size = 5000;

// make sure each iteration of the benchmark contains exactly 5000 inserts and one clear.
// do this at least 10 times so we get reasonable accurate results

bench.batch(batch_size).minEpochIterations(10).run([&] {
auto rng = ankerl::nanobench::Rng(1234);
for (size_t i = 0; i < batch_size; ++i) {
map[rng()];
}
map.clear();
});
}

static void PoolAllocator_StdUnorderedMap(benchmark::Bench& bench)
{
auto map = std::unordered_map<uint64_t, uint64_t>();
BenchFillClearMap(bench, map);
}

static void PoolAllocator_StdUnorderedMapWithPoolResource(benchmark::Bench& bench)
{
using Map = std::unordered_map<uint64_t,
uint64_t,
std::hash<uint64_t>,
std::equal_to<uint64_t>,
PoolAllocator<std::pair<const uint64_t, uint64_t>,
sizeof(std::pair<const uint64_t, uint64_t>) + 4 * sizeof(void*),
alignof(void*)>>;

// make sure the resource supports large enough pools to hold the node. We do this by adding the size of a few pointers to it.
auto pool_resource = Map::allocator_type::ResourceType();
auto map = Map{0, std::hash<uint64_t>{}, std::equal_to<uint64_t>{}, &pool_resource};
BenchFillClearMap(bench, map);
}

BENCHMARK(PoolAllocator_StdUnorderedMap);
BENCHMARK(PoolAllocator_StdUnorderedMapWithPoolResource);
15 changes: 10 additions & 5 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ size_t CCoinsViewBacked::EstimateSize() const { return base->EstimateSize(); }

CCoinsViewCache::CCoinsViewCache(CCoinsView* baseIn, bool deterministic) :
CCoinsViewBacked(baseIn), m_deterministic(deterministic),
cacheCoins(0, SaltedOutpointHasher(/*deterministic=*/deterministic))
cacheCoins(0, SaltedOutpointHasher(/*deterministic=*/deterministic), CCoinsMap::key_equal{}, &m_cache_coins_memory_resource)
{}

size_t CCoinsViewCache::DynamicMemoryUsage() const {
Expand Down Expand Up @@ -240,9 +240,12 @@ bool CCoinsViewCache::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlockIn

bool CCoinsViewCache::Flush() {
bool fOk = base->BatchWrite(cacheCoins, hashBlock, /*erase=*/true);
if (fOk && !cacheCoins.empty()) {
/* BatchWrite must erase all cacheCoins elements when erase=true. */
throw std::logic_error("Not all cached coins were erased");
if (fOk) {
if (!cacheCoins.empty()) {
/* BatchWrite must erase all cacheCoins elements when erase=true. */
throw std::logic_error("Not all cached coins were erased");
}
ReallocateCache();
}
cachedCoinsUsage = 0;
return fOk;
Expand Down Expand Up @@ -295,7 +298,9 @@ void CCoinsViewCache::ReallocateCache()
// Cache should be empty when we're calling this.
assert(cacheCoins.size() == 0);
cacheCoins.~CCoinsMap();
::new (&cacheCoins) CCoinsMap(0, SaltedOutpointHasher(/*deterministic=*/m_deterministic));
m_cache_coins_memory_resource.~CCoinsMapMemoryResource();
::new (&m_cache_coins_memory_resource) CCoinsMapMemoryResource{};
::new (&cacheCoins) CCoinsMap{0, SaltedOutpointHasher{/*deterministic=*/m_deterministic}, CCoinsMap::key_equal{}, &m_cache_coins_memory_resource};
}

void CCoinsViewCache::SanityCheck() const
Expand Down
20 changes: 19 additions & 1 deletion src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <memusage.h>
#include <primitives/transaction.h>
#include <serialize.h>
#include <support/allocators/pool.h>
#include <uint256.h>
#include <util/hasher.h>

Expand Down Expand Up @@ -131,7 +132,23 @@ struct CCoinsCacheEntry
CCoinsCacheEntry(Coin&& coin_, unsigned char flag) : coin(std::move(coin_)), flags(flag) {}
};

typedef std::unordered_map<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> CCoinsMap;
/**
* PoolAllocator's MAX_BLOCK_SIZE_BYTES parameter here uses sizeof the data, and adds the size
* of 4 pointers. We do not know the exact node size used in the std::unordered_node implementation
* because it is implementation defined. Most implementations have an overhead of 1 or 2 pointers,
* so nodes can be connected in a linked list, and in some cases the hash value is stored as well.
* Using an additional sizeof(void*)*4 for MAX_BLOCK_SIZE_BYTES should thus be sufficient so that
* all implementations can allocate the nodes from the PoolAllocator.
*/
using CCoinsMap = std::unordered_map<COutPoint,
CCoinsCacheEntry,
SaltedOutpointHasher,
std::equal_to<COutPoint>,
PoolAllocator<std::pair<const COutPoint, CCoinsCacheEntry>,
sizeof(std::pair<const COutPoint, CCoinsCacheEntry>) + sizeof(void*) * 4,
alignof(void*)>>;

using CCoinsMapMemoryResource = CCoinsMap::allocator_type::ResourceType;

/** Cursor for iterating over CoinsView state */
class CCoinsViewCursor
Expand Down Expand Up @@ -221,6 +238,7 @@ class CCoinsViewCache : public CCoinsViewBacked
* declared as "const".
*/
mutable uint256 hashBlock;
mutable CCoinsMapMemoryResource m_cache_coins_memory_resource{};
mutable CCoinsMap cacheCoins;

/* Cached dynamic memory usage for the inner Coin objects. */
Expand Down
20 changes: 7 additions & 13 deletions src/governance/governance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,7 @@ PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, Pe

uint256 nHash = govobj.GetHash();

{
LOCK(cs_main);
EraseObjectRequest(peer.GetId(), CInv(MSG_GOVERNANCE_OBJECT, nHash));
}
WITH_LOCK(::cs_main, peerman.EraseObjectRequest(peer.GetId(), CInv(MSG_GOVERNANCE_OBJECT, nHash)));

if (!m_mn_sync->IsBlockchainSynced()) {
LogPrint(BCLog::GOBJECT, "MNGOVERNANCEOBJECT -- masternode list not synced\n");
Expand Down Expand Up @@ -223,11 +220,7 @@ PeerMsgRet CGovernanceManager::ProcessMessage(CNode& peer, CConnman& connman, Pe
vRecv >> vote;

uint256 nHash = vote.GetHash();

{
LOCK(cs_main);
EraseObjectRequest(peer.GetId(), CInv(MSG_GOVERNANCE_OBJECT_VOTE, nHash));
}
WITH_LOCK(::cs_main, peerman.EraseObjectRequest(peer.GetId(), CInv(MSG_GOVERNANCE_OBJECT_VOTE, nHash)));

// Ignore such messages until masternode list is synced
if (!m_mn_sync->IsBlockchainSynced()) {
Expand Down Expand Up @@ -1222,13 +1215,14 @@ void CGovernanceManager::RequestGovernanceObject(CNode* pfrom, const uint256& nH
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MNGOVERNANCESYNC, nHash, filter));
}

int CGovernanceManager::RequestGovernanceObjectVotes(CNode& peer, CConnman& connman) const
int CGovernanceManager::RequestGovernanceObjectVotes(CNode& peer, CConnman& connman, const PeerManager& peerman) const
{
const std::vector<CNode*> vNodeCopy{&peer};
return RequestGovernanceObjectVotes(vNodeCopy, connman);
return RequestGovernanceObjectVotes(vNodeCopy, connman, peerman);
}

int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy, CConnman& connman) const
int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy, CConnman& connman,
const PeerManager& peerman) const
{
static std::map<uint256, std::map<CService, int64_t> > mapAskedRecently;

Expand Down Expand Up @@ -1304,7 +1298,7 @@ int CGovernanceManager::RequestGovernanceObjectVotes(const std::vector<CNode*>&
// stop early to prevent setAskFor overflow
{
LOCK(cs_main);
size_t nProjectedSize = GetRequestedObjectCount(pnode->GetId()) + nProjectedVotes;
size_t nProjectedSize = peerman.GetRequestedObjectCount(pnode->GetId()) + nProjectedVotes;
if (nProjectedSize > MAX_INV_SZ) continue;
// to early to ask the same node
if (mapAskedRecently[nHashGovobj].count(pnode->addr)) continue;
Expand Down
5 changes: 3 additions & 2 deletions src/governance/governance.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,9 @@ class CGovernanceManager : public GovernanceStore

void InitOnLoad();

int RequestGovernanceObjectVotes(CNode& peer, CConnman& connman) const;
int RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy, CConnman& connman) const;
int RequestGovernanceObjectVotes(CNode& peer, CConnman& connman, const PeerManager& peerman) const;
int RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy, CConnman& connman,
const PeerManager& peerman) const;

/*
* Trigger Management (formerly CGovernanceTriggerManager)
Expand Down
5 changes: 3 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include <torcontrol.h>
#include <txdb.h>
#include <txmempool.h>
#include <txorphanage.h>
#include <util/asmap.h>
#include <util/error.h>
#include <util/moneystr.h>
Expand Down Expand Up @@ -578,7 +579,7 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-listenonion", strprintf("Automatically create Tor onion service (default: %d)", DEFAULT_LISTEN_ONION), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxconnections=<n>", strprintf("Maintain at most <n> connections to peers (temporary service connections excluded) (default: %u). This limit does not apply to connections manually added via -addnode or the addnode RPC, which have a separate limit of %u.", DEFAULT_MAX_PEER_CONNECTIONS, MAX_ADDNODE_CONNECTIONS), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxreceivebuffer=<n>", strprintf("Maximum per-connection receive buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXRECEIVEBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxsendbuffer=<n>", strprintf("Maximum per-connection send buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxsendbuffer=<n>", strprintf("Maximum per-connection memory usage for the send buffer, <n>*1000 bytes (default: %u)", DEFAULT_MAXSENDBUFFER), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxtimeadjustment", strprintf("Maximum allowed median peer time offset adjustment. Local perspective of time may be influenced by peers forward or backward by this amount. (default: %u seconds)", DEFAULT_MAX_TIME_ADJUSTMENT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-maxuploadtarget=<n>", strprintf("Tries to keep outbound traffic under the given target (in MiB per 24h). Limit does not apply to peers with 'download' permission. 0 = no limit (default: %d)", DEFAULT_MAX_UPLOAD_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
argsman.AddArg("-onion=<ip:port>", "Use separate SOCKS5 proxy to reach peers via Tor onion services, set -noonion to disable (default: -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
Expand Down Expand Up @@ -2219,7 +2220,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ********************************************************* Step 10a: schedule Dash-specific tasks

node.scheduler->scheduleEvery(std::bind(&CNetFulfilledRequestManager::DoMaintenance, std::ref(*node.netfulfilledman)), std::chrono::minutes{1});
node.scheduler->scheduleEvery(std::bind(&CMasternodeSync::DoMaintenance, std::ref(*node.mn_sync)), std::chrono::seconds{1});
node.scheduler->scheduleEvery(std::bind(&CMasternodeSync::DoMaintenance, std::ref(*node.mn_sync), std::cref(*node.peerman)), std::chrono::seconds{1});
node.scheduler->scheduleEvery(std::bind(&CMasternodeUtils::DoMaintenance, std::ref(*node.connman), std::ref(*node.dmnman), std::ref(*node.mn_sync), std::ref(*node.cj_ctx)), std::chrono::minutes{1});
node.scheduler->scheduleEvery(std::bind(&CDeterministicMNManager::DoMaintenance, std::ref(*node.dmnman)), std::chrono::seconds{10});

Expand Down
3 changes: 2 additions & 1 deletion src/llmq/blockprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ PeerMsgRet CQuorumBlockProcessor::ProcessMessage(const CNode& peer, std::string_
CFinalCommitment qc;
vRecv >> qc;

WITH_LOCK(cs_main, EraseObjectRequest(peer.GetId(), CInv(MSG_QUORUM_FINAL_COMMITMENT, ::SerializeHash(qc))));
WITH_LOCK(::cs_main, Assert(m_peerman)->EraseObjectRequest(peer.GetId(),
CInv(MSG_QUORUM_FINAL_COMMITMENT, ::SerializeHash(qc))));

if (qc.IsNull()) {
LogPrint(BCLog::LLMQ, "CQuorumBlockProcessor::%s -- null commitment from peer=%d\n", __func__, peer.GetId());
Expand Down
3 changes: 1 addition & 2 deletions src/llmq/chainlocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ PeerMsgRet CChainLocksHandler::ProcessNewChainLock(const NodeId from, const llmq
CInv clsigInv(MSG_CLSIG, hash);

if (from != -1) {
LOCK(cs_main);
EraseObjectRequest(from, clsigInv);
WITH_LOCK(::cs_main, Assert(m_peerman)->EraseObjectRequest(from, clsigInv));
}

{
Expand Down
3 changes: 1 addition & 2 deletions src/llmq/dkgsessionhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ void CDKGPendingMessages::PushPendingMessage(NodeId from, PeerManager* peerman,
uint256 hash = hw.GetHash();

if (from != -1) {
LOCK(cs_main);
EraseObjectRequest(from, CInv(invType, hash));
WITH_LOCK(::cs_main, Assert(m_peerman.load())->EraseObjectRequest(from, CInv(invType, hash)));
}

LOCK(cs_messages);
Expand Down
8 changes: 5 additions & 3 deletions src/llmq/instantsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ PeerMsgRet CInstantSendManager::ProcessMessageInstantSendLock(const CNode& pfrom
{
auto hash = ::SerializeHash(*islock);

WITH_LOCK(cs_main, EraseObjectRequest(pfrom.GetId(), CInv(MSG_ISDLOCK, hash)));
WITH_LOCK(::cs_main, Assert(m_peerman)->EraseObjectRequest(pfrom.GetId(), CInv(MSG_ISDLOCK, hash)));

if (!islock->TriviallyValid()) {
return tl::unexpected{100};
Expand Down Expand Up @@ -1446,7 +1446,8 @@ void CInstantSendManager::RemoveConflictingLock(const uint256& islockHash, const
}
}

void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman, bool is_masternode)
void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnman& connman, PeerManager& peerman,
bool is_masternode)
{
std::vector<CNode*> nodesToAskFor;
nodesToAskFor.reserve(4);
Expand Down Expand Up @@ -1476,7 +1477,8 @@ void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnma
txid.ToString(), pnode->GetId());

CInv inv(MSG_TX, txid);
RequestObject(pnode->GetId(), inv, GetTime<std::chrono::microseconds>(), is_masternode, /* fForce = */ true);
peerman.RequestObject(pnode->GetId(), inv, GetTime<std::chrono::microseconds>(), is_masternode,
/* fForce = */ true);
}
}
for (CNode* pnode : nodesToAskFor) {
Expand Down
3 changes: 1 addition & 2 deletions src/llmq/instantsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,7 @@ class CInstantSendManager : public CRecoveredSigsListener
EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingRetry);
void ResolveBlockConflicts(const uint256& islockHash, const CInstantSendLock& islock)
EXCLUSIVE_LOCKS_REQUIRED(!cs_inputReqests, !cs_nonLocked, !cs_pendingLocks, !cs_pendingRetry);
static void AskNodesForLockedTx(const uint256& txid, const CConnman& connman, const PeerManager& peerman,
bool is_masternode);
static void AskNodesForLockedTx(const uint256& txid, const CConnman& connman, PeerManager& peerman, bool is_masternode);
void ProcessPendingRetryLockTxs()
EXCLUSIVE_LOCKS_REQUIRED(!cs_creating, !cs_inputReqests, !cs_nonLocked, !cs_pendingRetry);

Expand Down
6 changes: 2 additions & 4 deletions src/llmq/signing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,10 +604,8 @@ static bool PreVerifyRecoveredSig(const CQuorumManager& quorum_manager, const CR

PeerMsgRet CSigningManager::ProcessMessageRecoveredSig(const CNode& pfrom, const std::shared_ptr<const CRecoveredSig>& recoveredSig)
{
{
LOCK(cs_main);
EraseObjectRequest(pfrom.GetId(), CInv(MSG_QUORUM_RECOVERED_SIG, recoveredSig->GetHash()));
}
WITH_LOCK(::cs_main, Assert(m_peerman)->EraseObjectRequest(pfrom.GetId(),
CInv(MSG_QUORUM_RECOVERED_SIG, recoveredSig->GetHash())));

bool ban = false;
if (!PreVerifyRecoveredSig(qman, *recoveredSig, ban)) {
Expand Down
10 changes: 5 additions & 5 deletions src/masternode/sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void CMasternodeSync::ProcessMessage(const CNode& peer, std::string_view msg_typ
LogPrint(BCLog::MNSYNC, "SYNCSTATUSCOUNT -- got inventory count: nItemID=%d nCount=%d peer=%d\n", nItemID, nCount, peer.GetId());
}

void CMasternodeSync::ProcessTick()
void CMasternodeSync::ProcessTick(const PeerManager& peerman)
{
assert(m_netfulfilledman.IsValid());

Expand Down Expand Up @@ -144,7 +144,7 @@ void CMasternodeSync::ProcessTick()

// gradually request the rest of the votes after sync finished
if(IsSynced()) {
m_govman.RequestGovernanceObjectVotes(snap.Nodes(), connman);
m_govman.RequestGovernanceObjectVotes(snap.Nodes(), connman, peerman);
return;
}

Expand Down Expand Up @@ -264,7 +264,7 @@ void CMasternodeSync::ProcessTick()
if(!m_netfulfilledman.HasFulfilledRequest(pnode->addr, "governance-sync")) {
continue; // to early for this node
}
int nObjsLeftToAsk = m_govman.RequestGovernanceObjectVotes(*pnode, connman);
int nObjsLeftToAsk = m_govman.RequestGovernanceObjectVotes(*pnode, connman, peerman);
// check for data
if(nObjsLeftToAsk == 0) {
static int64_t nTimeNoObjectsLeft = 0;
Expand Down Expand Up @@ -368,9 +368,9 @@ void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexTip, const CBlock
pindexNew->nHeight, pindexTip->nHeight, fInitialDownload, fReachedBestHeader);
}

void CMasternodeSync::DoMaintenance()
void CMasternodeSync::DoMaintenance(const PeerManager& peerman)
{
if (ShutdownRequested()) return;

ProcessTick();
ProcessTick(peerman);
}
Loading
Loading