Excessive CPU and RAM usage in crownd
Summary
Sometimes a crownd uses more CPU and memory than usual. The debug.log tends to show a LOT of CBudgetManager messages.
Steps to reproduce
Run a crownd. Wait for it to start using more CPU/RAM than usual.
Expected behavior
CPU/RAM usage should be fairly consistent over time.
Problematic behavior
Sometimes CPU and RAM usage are higher than usual and the RAM usage can creep up over a few days causing increased CPU usage by the swap daemon and eventually an OOM situation. The OOM may result in processes other than crownd being forcibly terminated.
Crown-core environment info
Ubuntu 16.04
Crown-core application info
Crown version v0.13.2.0-12a897ba
Relevant logs, dumps and/or screenshots
Uploaded 20190417_walkjivefly_MN01_excessive_cpu_ram.log to https://nextcloud.crown.tech/nextcloud/s/znd8HiiAsRX3C6B
Possible fixes
That log is for 21 hours and is 97061 records, 85460 of which are from CBudgetManager. It's hardly conclusive but I'd hazard a guess much of the normal CPU and RAM usage is related to that. But the log is not larger than usual so the excess usage may be happening elsewhere.
The BudgetManager sync happens more often than the comments in the code suggest it is designed to do, apparently due to the difference in block times between Dash and Crown. Consider
void CBudgetManager::NewBlock()
{
TRY_LOCK(cs, fBudgetNewBlock);
if(!fBudgetNewBlock)
return;
if (masternodeSync.RequestedMasternodeAssets <= MASTERNODE_SYNC_BUDGET)
return;
if (strBudgetMode == "suggest" || fMasterNode) //suggest the budget we see
SubmitBudgetDraft();
//this function should be called 1/6 blocks, allowing up to 100 votes per day on all proposals
if(chainActive.Height() % 6 != 0)
return;
// incremental sync with our peers
if(masternodeSync.IsSynced()){
LogPrintf("CBudgetManager::NewBlock - incremental sync started\n");
if(chainActive.Height() % 600 == rand() % 600) {
ClearSeen();
ResetSync();
}
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
if(pnode->nVersion >= MIN_BUDGET_PEER_PROTO_VERSION)
Sync(pnode, uint256(), true);
MarkSynced();
}
For a target 100 votes per day the function should be called 1 in 14 blocks, not 1 in 6; it's getting called about 2.5 times more often than designed, matching the difference in block times (Dash 2.5 minutes, Crown 1 minute)
/cc @artem