Commit 0a7d7796 authored by Ashot Khachatryan's avatar Ashot Khachatryan
Browse files

Added servicenode-sync class

parent a752bdc2
Showing with 594 additions and 14 deletions
+594 -14
......@@ -140,6 +140,7 @@ BITCOIN_CORE_H = \
throneman.h \
throneconfig.h \
servicenode.h \
servicenode-sync.h \
servicenodeman.h \
servicenodeconfig.h \
threadsafety.h \
......@@ -229,6 +230,7 @@ libbitcoin_wallet_a_SOURCES = \
throne-sync.cpp \
throneconfig.cpp \
throneman.cpp \
servicenode-sync.cpp \
servicenode.cpp \
servicenodeconfig.cpp \
servicenodeman.cpp \
......
......@@ -15,6 +15,7 @@
#include "util.h"
#include "spork.h"
#include "throne-sync.h"
#include "servicenode-sync.h"
#ifdef ENABLE_WALLET
#include "wallet.h"
#include "walletdb.h"
......@@ -150,6 +151,44 @@ Value mnsync(const Array& params, bool fHelp)
Value snsync(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
"snsync [status|reset]\n"
"Returns the sync status or resets sync.\n"
);
std::string strMode = params[0].get_str();
if(strMode == "status") {
Object obj;
obj.push_back(Pair("IsBlockchainSynced", servicenodeSync.IsBlockchainSynced()));
obj.push_back(Pair("lastServicenodeList", servicenodeSync.lastServicenodeList));
obj.push_back(Pair("lastServicenodeWinner", servicenodeSync.lastServicenodeWinner));
obj.push_back(Pair("lastBudgetItem", servicenodeSync.lastBudgetItem));
obj.push_back(Pair("lastFailure", servicenodeSync.lastFailure));
obj.push_back(Pair("nCountFailures", servicenodeSync.nCountFailures));
obj.push_back(Pair("sumServicenodeList", servicenodeSync.sumServicenodeList));
obj.push_back(Pair("sumServicenodeWinner", servicenodeSync.sumServicenodeWinner));
obj.push_back(Pair("sumBudgetItemProp", servicenodeSync.sumBudgetItemProp));
obj.push_back(Pair("sumBudgetItemFin", servicenodeSync.sumBudgetItemFin));
obj.push_back(Pair("countServicenodeList", servicenodeSync.countServicenodeList));
obj.push_back(Pair("countServicenodeWinner", servicenodeSync.countServicenodeWinner));
obj.push_back(Pair("countBudgetItemProp", servicenodeSync.countBudgetItemProp));
obj.push_back(Pair("countBudgetItemFin", servicenodeSync.countBudgetItemFin));
obj.push_back(Pair("RequestedServicenodeAssets", servicenodeSync.RequestedServicenodeAssets));
obj.push_back(Pair("RequestedServicenodeAttempt", servicenodeSync.RequestedServicenodeAttempt));
return obj;
}
if(strMode == "reset")
{
servicenodeSync.Reset();
return "success";
}
return "failure";
}
#ifdef ENABLE_WALLET
......
// Copyright (c) 2014-2015 The Crown developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "main.h"
//#include "activeservicenode.h"
#include "servicenode-sync.h"
//#include "servicenode-payments.h"
//#include "servicenode-budget.h"
#include "servicenode.h"
#include "servicenodeman.h"
#include "spork.h"
#include "util.h"
#include "addrman.h"
class CServicenodeSync;
CServicenodeSync servicenodeSync;
CServicenodeSync::CServicenodeSync()
{
Reset();
}
bool CServicenodeSync::IsSynced()
{
return RequestedServicenodeAssets == SERVICENODE_SYNC_FINISHED;
}
bool CServicenodeSync::IsBlockchainSynced()
{
static bool fBlockchainSynced = false;
static int64_t lastProcess = GetTime();
// if the last call to this function was more than 60 minutes ago (client was in sleep mode) reset the sync process
if(GetTime() - lastProcess > 60*60) {
Reset();
fBlockchainSynced = false;
}
lastProcess = GetTime();
if(fBlockchainSynced) return true;
if (fImporting || fReindex) return false;
TRY_LOCK(cs_main, lockMain);
if(!lockMain) return false;
CBlockIndex* pindex = chainActive.Tip();
if(pindex == NULL) return false;
if(pindex->nTime + 60*60 < GetTime())
return false;
fBlockchainSynced = true;
return true;
}
void CServicenodeSync::Reset()
{
lastServicenodeList = 0;
lastServicenodeWinner = 0;
lastBudgetItem = 0;
mapSeenSyncMNB.clear();
mapSeenSyncMNW.clear();
mapSeenSyncBudget.clear();
lastFailure = 0;
nCountFailures = 0;
sumServicenodeList = 0;
sumServicenodeWinner = 0;
sumBudgetItemProp = 0;
sumBudgetItemFin = 0;
countServicenodeList = 0;
countServicenodeWinner = 0;
countBudgetItemProp = 0;
countBudgetItemFin = 0;
RequestedServicenodeAssets = SERVICENODE_SYNC_INITIAL;
RequestedServicenodeAttempt = 0;
nAssetSyncStarted = GetTime();
}
void CServicenodeSync::AddedServicenodeList(uint256 hash)
{
if(snodeman.mapSeenServicenodeBroadcast.count(hash)) {
if(mapSeenSyncMNB[hash] < SERVICENODE_SYNC_THRESHOLD) {
lastServicenodeList = GetTime();
mapSeenSyncMNB[hash]++;
}
} else {
lastServicenodeList = GetTime();
mapSeenSyncMNB.insert(make_pair(hash, 1));
}
}
void CServicenodeSync::AddedServicenodeWinner(uint256 hash)
{
//if(servicenodePayments.mapServicenodePayeeVotes.count(hash)) {
// if(mapSeenSyncMNW[hash] < SERVICENODE_SYNC_THRESHOLD) {
// lastServicenodeWinner = GetTime();
// mapSeenSyncMNW[hash]++;
// }
//} else {
// lastServicenodeWinner = GetTime();
// mapSeenSyncMNW.insert(make_pair(hash, 1));
//}
}
void CServicenodeSync::AddedBudgetItem(uint256 hash)
{
//if(budget.mapSeenServicenodeBudgetProposals.count(hash) || budget.mapSeenServicenodeBudgetVotes.count(hash) ||
// budget.mapSeenFinalizedBudgets.count(hash) || budget.mapSeenFinalizedBudgetVotes.count(hash)) {
// if(mapSeenSyncBudget[hash] < SERVICENODE_SYNC_THRESHOLD) {
// lastBudgetItem = GetTime();
// mapSeenSyncBudget[hash]++;
// }
//} else {
// lastBudgetItem = GetTime();
// mapSeenSyncBudget.insert(make_pair(hash, 1));
//}
}
bool CServicenodeSync::IsBudgetPropEmpty()
{
return sumBudgetItemProp==0 && countBudgetItemProp>0;
}
bool CServicenodeSync::IsBudgetFinEmpty()
{
return sumBudgetItemFin==0 && countBudgetItemFin>0;
}
void CServicenodeSync::GetNextAsset()
{
switch(RequestedServicenodeAssets)
{
case(SERVICENODE_SYNC_INITIAL):
case(SERVICENODE_SYNC_FAILED): // should never be used here actually, use Reset() instead
ClearFulfilledRequest();
RequestedServicenodeAssets = SERVICENODE_SYNC_SPORKS;
break;
case(SERVICENODE_SYNC_SPORKS):
RequestedServicenodeAssets = SERVICENODE_SYNC_LIST;
break;
case(SERVICENODE_SYNC_LIST):
RequestedServicenodeAssets = SERVICENODE_SYNC_MNW;
break;
case(SERVICENODE_SYNC_MNW):
RequestedServicenodeAssets = SERVICENODE_SYNC_BUDGET;
break;
case(SERVICENODE_SYNC_BUDGET):
LogPrintf("CServicenodeSync::GetNextAsset - Sync has finished\n");
RequestedServicenodeAssets = SERVICENODE_SYNC_FINISHED;
break;
}
RequestedServicenodeAttempt = 0;
nAssetSyncStarted = GetTime();
}
std::string CServicenodeSync::GetSyncStatus()
{
switch (servicenodeSync.RequestedServicenodeAssets) {
case SERVICENODE_SYNC_INITIAL: return _("Synchronization pending...");
case SERVICENODE_SYNC_SPORKS: return _("Synchronizing sporks...");
case SERVICENODE_SYNC_LIST: return _("Synchronizing servicenodes...");
case SERVICENODE_SYNC_MNW: return _("Synchronizing servicenode winners...");
case SERVICENODE_SYNC_BUDGET: return _("Synchronizing budgets...");
case SERVICENODE_SYNC_FAILED: return _("Synchronization failed");
case SERVICENODE_SYNC_FINISHED: return _("Synchronization finished");
}
return "";
}
void CServicenodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
if (strCommand == "ssc") { //Sync status count
int nItemID;
int nCount;
vRecv >> nItemID >> nCount;
if(RequestedServicenodeAssets >= SERVICENODE_SYNC_FINISHED) return;
//this means we will receive no further communication
switch(nItemID)
{
case(SERVICENODE_SYNC_LIST):
if(nItemID != RequestedServicenodeAssets) return;
sumServicenodeList += nCount;
countServicenodeList++;
break;
case(SERVICENODE_SYNC_MNW):
if(nItemID != RequestedServicenodeAssets) return;
sumServicenodeWinner += nCount;
countServicenodeWinner++;
break;
case(SERVICENODE_SYNC_BUDGET_PROP):
if(RequestedServicenodeAssets != SERVICENODE_SYNC_BUDGET) return;
sumBudgetItemProp += nCount;
countBudgetItemProp++;
break;
case(SERVICENODE_SYNC_BUDGET_FIN):
if(RequestedServicenodeAssets != SERVICENODE_SYNC_BUDGET) return;
sumBudgetItemFin += nCount;
countBudgetItemFin++;
break;
}
LogPrintf("CServicenodeSync:ProcessMessage - ssc - got inventory count %d %d\n", nItemID, nCount);
}
}
void CServicenodeSync::ClearFulfilledRequest()
{
TRY_LOCK(cs_vNodes, lockRecv);
if(!lockRecv) return;
BOOST_FOREACH(CNode* pnode, vNodes)
{
pnode->ClearFulfilledRequest("getspork");
pnode->ClearFulfilledRequest("mnsync");
pnode->ClearFulfilledRequest("mnwsync");
pnode->ClearFulfilledRequest("busync");
}
}
void CServicenodeSync::Process()
{
static int tick = 0;
if(tick++ % SERVICENODE_SYNC_TIMEOUT != 0) return;
if(IsSynced()) {
/*
Resync if we lose all servicenodes from sleep/wake or failure to sync originally
*/
if(snodeman.CountEnabled() == 0) {
Reset();
} else
return;
}
//try syncing again
if(RequestedServicenodeAssets == SERVICENODE_SYNC_FAILED && lastFailure + (1*60) < GetTime()) {
Reset();
} else if (RequestedServicenodeAssets == SERVICENODE_SYNC_FAILED) {
return;
}
if(fDebug) LogPrintf("CServicenodeSync::Process() - tick %d RequestedServicenodeAssets %d\n", tick, RequestedServicenodeAssets);
if(RequestedServicenodeAssets == SERVICENODE_SYNC_INITIAL) GetNextAsset();
// sporks synced but blockchain is not, wait until we're almost at a recent block to continue
if(Params().NetworkID() != CBaseChainParams::REGTEST &&
!IsBlockchainSynced() && RequestedServicenodeAssets > SERVICENODE_SYNC_SPORKS) return;
TRY_LOCK(cs_vNodes, lockRecv);
if(!lockRecv) return;
BOOST_FOREACH(CNode* pnode, vNodes)
{
if(Params().NetworkID() == CBaseChainParams::REGTEST){
if(RequestedServicenodeAttempt <= 2) {
pnode->PushMessage("getsporks"); //get current network sporks
} else if(RequestedServicenodeAttempt < 4) {
snodeman.DsegUpdate(pnode);
} else if(RequestedServicenodeAttempt < 6) {
int nMnCount = snodeman.CountEnabled();
pnode->PushMessage("mnget", nMnCount); //sync payees
uint256 n = uint256();
pnode->PushMessage("mnvs", n); //sync servicenode votes
} else {
RequestedServicenodeAssets = SERVICENODE_SYNC_FINISHED;
}
RequestedServicenodeAttempt++;
return;
}
//set to synced
if(RequestedServicenodeAssets == SERVICENODE_SYNC_SPORKS){
if(pnode->HasFulfilledRequest("getspork")) continue;
pnode->FulfilledRequest("getspork");
pnode->PushMessage("getsporks"); //get current network sporks
if(RequestedServicenodeAttempt >= 2) GetNextAsset();
RequestedServicenodeAttempt++;
return;
}
//if (pnode->nVersion >= servicenodePayments.GetMinServicenodePaymentsProto()) {
// if(RequestedServicenodeAssets == SERVICENODE_SYNC_LIST) {
// if(fDebug) LogPrintf("CServicenodeSync::Process() - lastServicenodeList %lld (GetTime() - SERVICENODE_SYNC_TIMEOUT) %lld\n", lastServicenodeList, GetTime() - SERVICENODE_SYNC_TIMEOUT);
// if(lastServicenodeList > 0 && lastServicenodeList < GetTime() - SERVICENODE_SYNC_TIMEOUT*2 && RequestedServicenodeAttempt >= SERVICENODE_SYNC_THRESHOLD){ //hasn't received a new item in the last five seconds, so we'll move to the
// GetNextAsset();
// return;
// }
// if(pnode->HasFulfilledRequest("mnsync")) continue;
// pnode->FulfilledRequest("mnsync");
// // timeout
// if(lastServicenodeList == 0 &&
// (RequestedServicenodeAttempt >= SERVICENODE_SYNC_THRESHOLD*3 || GetTime() - nAssetSyncStarted > SERVICENODE_SYNC_TIMEOUT*5)) {
// if(IsSporkActive(SPORK_8_SERVICENODE_PAYMENT_ENFORCEMENT)) {
// LogPrintf("CServicenodeSync::Process - ERROR - Sync has failed, will retry later\n");
// RequestedServicenodeAssets = SERVICENODE_SYNC_FAILED;
// RequestedServicenodeAttempt = 0;
// lastFailure = GetTime();
// nCountFailures++;
// } else {
// GetNextAsset();
// }
// return;
// }
// if(RequestedServicenodeAttempt >= SERVICENODE_SYNC_THRESHOLD*3) return;
// snodeman.DsegUpdate(pnode);
// RequestedServicenodeAttempt++;
// return;
// }
// if(RequestedServicenodeAssets == SERVICENODE_SYNC_MNW) {
// if(lastServicenodeWinner > 0 && lastServicenodeWinner < GetTime() - SERVICENODE_SYNC_TIMEOUT*2 && RequestedServicenodeAttempt >= SERVICENODE_SYNC_THRESHOLD){ //hasn't received a new item in the last five seconds, so we'll move to the
// GetNextAsset();
// return;
// }
// if(pnode->HasFulfilledRequest("mnwsync")) continue;
// pnode->FulfilledRequest("mnwsync");
// // timeout
// if(lastServicenodeWinner == 0 &&
// (RequestedServicenodeAttempt >= SERVICENODE_SYNC_THRESHOLD*3 || GetTime() - nAssetSyncStarted > SERVICENODE_SYNC_TIMEOUT*5)) {
// if(IsSporkActive(SPORK_8_SERVICENODE_PAYMENT_ENFORCEMENT)) {
// LogPrintf("CServicenodeSync::Process - ERROR - Sync has failed, will retry later\n");
// RequestedServicenodeAssets = SERVICENODE_SYNC_FAILED;
// RequestedServicenodeAttempt = 0;
// lastFailure = GetTime();
// nCountFailures++;
// } else {
// GetNextAsset();
// }
// return;
// }
// if(RequestedServicenodeAttempt >= SERVICENODE_SYNC_THRESHOLD*3) return;
// CBlockIndex* pindexPrev = chainActive.Tip();
// if(pindexPrev == NULL) return;
// int nMnCount = snodeman.CountEnabled();
// pnode->PushMessage("mnget", nMnCount); //sync payees
// RequestedServicenodeAttempt++;
// return;
// }
//}
if (pnode->nVersion >= MIN_BUDGET_PEER_PROTO_VERSION) {
if(RequestedServicenodeAssets == SERVICENODE_SYNC_BUDGET){
//we'll start rejecting votes if we accidentally get set as synced too soon
if(lastBudgetItem > 0 && lastBudgetItem < GetTime() - SERVICENODE_SYNC_TIMEOUT*2 && RequestedServicenodeAttempt >= SERVICENODE_SYNC_THRESHOLD){ //hasn't received a new item in the last five seconds, so we'll move to the
//LogPrintf("CServicenodeSync::Process - HasNextFinalizedBudget %d nCountFailures %d IsBudgetPropEmpty %d\n", budget.HasNextFinalizedBudget(), nCountFailures, IsBudgetPropEmpty());
//if(budget.HasNextFinalizedBudget() || nCountFailures >= 2 || IsBudgetPropEmpty()) {
GetNextAsset();
//try to activate our servicenode if possible
// TODO uncomment later
//activeServicenode.ManageStatus();
// } else { //we've failed to sync, this state will reject the next budget block
// LogPrintf("CServicenodeSync::Process - ERROR - Sync has failed, will retry later\n");
// RequestedServicenodeAssets = SERVICENODE_SYNC_FAILED;
// RequestedServicenodeAttempt = 0;
// lastFailure = GetTime();
// nCountFailures++;
// }
return;
}
// timeout
if(lastBudgetItem == 0 &&
(RequestedServicenodeAttempt >= SERVICENODE_SYNC_THRESHOLD*3 || GetTime() - nAssetSyncStarted > SERVICENODE_SYNC_TIMEOUT*5)) {
// maybe there is no budgets at all, so just finish syncing
GetNextAsset();
//activeServicenode.ManageStatus();
return;
}
if(pnode->HasFulfilledRequest("busync")) continue;
pnode->FulfilledRequest("busync");
if(RequestedServicenodeAttempt >= SERVICENODE_SYNC_THRESHOLD*3) return;
uint256 n = uint256();
pnode->PushMessage("mnvs", n); //sync servicenode votes
RequestedServicenodeAttempt++;
return;
}
}
}
}
// Copyright (c) 2014-2015 The Crown developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef SERVICENODE_SYNC_H
#define SERVICENODE_SYNC_H
#define SERVICENODE_SYNC_INITIAL 0
#define SERVICENODE_SYNC_SPORKS 1
#define SERVICENODE_SYNC_LIST 2
#define SERVICENODE_SYNC_MNW 3
#define SERVICENODE_SYNC_BUDGET 4
#define SERVICENODE_SYNC_BUDGET_PROP 10
#define SERVICENODE_SYNC_BUDGET_FIN 11
#define SERVICENODE_SYNC_FAILED 998
#define SERVICENODE_SYNC_FINISHED 999
#define SERVICENODE_SYNC_TIMEOUT 5
#define SERVICENODE_SYNC_THRESHOLD 2
class CServicenodeSync;
extern CServicenodeSync servicenodeSync;
//
// CServicenodeSync : Sync servicenode assets in stages
//
class CServicenodeSync
{
public:
std::map<uint256, int> mapSeenSyncMNB;
std::map<uint256, int> mapSeenSyncMNW;
std::map<uint256, int> mapSeenSyncBudget;
int64_t lastServicenodeList;
int64_t lastServicenodeWinner;
int64_t lastBudgetItem;
int64_t lastFailure;
int nCountFailures;
// sum of all counts
int sumServicenodeList;
int sumServicenodeWinner;
int sumBudgetItemProp;
int sumBudgetItemFin;
// peers that reported counts
int countServicenodeList;
int countServicenodeWinner;
int countBudgetItemProp;
int countBudgetItemFin;
// Count peers we've requested the list from
int RequestedServicenodeAssets;
int RequestedServicenodeAttempt;
// Time when current servicenode asset sync started
int64_t nAssetSyncStarted;
CServicenodeSync();
void AddedServicenodeList(uint256 hash);
void AddedServicenodeWinner(uint256 hash);
void AddedBudgetItem(uint256 hash);
void GetNextAsset();
std::string GetSyncStatus();
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
bool IsBudgetFinEmpty();
bool IsBudgetPropEmpty();
void Reset();
void Process();
bool IsSynced();
bool IsBlockchainSynced();
void ClearFulfilledRequest();
};
#endif
......@@ -4,6 +4,7 @@
#include "servicenode.h"
#include "servicenodeman.h"
#include "servicenode-sync.h"
#include "darksend.h"
#include "util.h"
#include "sync.h"
......@@ -291,7 +292,7 @@ bool CServicenodeBroadcast::CheckAndUpdate(int& nDos)
pmn->Check();
if(pmn->IsEnabled()) Relay();
}
// servicenodeSync.AddedServicenodeList(GetHash());
servicenodeSync.AddedServicenodeList(GetHash());
}
return true;
......@@ -330,7 +331,7 @@ bool CServicenodeBroadcast::CheckInputsAndAdd(int& nDoS)
if(!lockMain) {
// not snb fault, let it to be checked again later
snodeman.mapSeenServicenodeBroadcast.erase(GetHash());
// servicenodeSync.mapSeenSyncMNB.erase(GetHash());
servicenodeSync.mapSeenSyncMNB.erase(GetHash());
return false;
}
......@@ -347,7 +348,7 @@ bool CServicenodeBroadcast::CheckInputsAndAdd(int& nDoS)
LogPrintf("snb - Input must have at least %d confirmations\n", SERVICENODE_MIN_CONFIRMATIONS);
// maybe we miss few blocks, let this snb to be checked again later
snodeman.mapSeenServicenodeBroadcast.erase(GetHash());
//servicenodeSync.mapSeenSyncMNB.erase(GetHash());
servicenodeSync.mapSeenSyncMNB.erase(GetHash());
return false;
}
......@@ -444,11 +445,11 @@ bool CServicenodeBroadcast::Create(std::string strService, std::string strKeySer
CKey keyServicenodeNew;
//need correct blocks to send ping
//if(!fOffline && !servicenodeSync.IsBlockchainSynced()) {
// strErrorMessage = "Sync in progress. Must wait until sync is complete to start Servicenode";
// LogPrintf("CServicenodeBroadcast::Create -- %s\n", strErrorMessage);
// return false;
//}
if(!fOffline && !servicenodeSync.IsBlockchainSynced()) {
strErrorMessage = "Sync in progress. Must wait until sync is complete to start Servicenode";
LogPrintf("CServicenodeBroadcast::Create -- %s\n", strErrorMessage);
return false;
}
if(!darkSendSigner.SetKey(strKeyServicenode, strErrorMessage, keyServicenodeNew, pubKeyServicenodeNew))
{
......
......@@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "servicenodeman.h"
#include "servicenode-sync.h"
#include "darksend.h"
#include "util.h"
#include "addrman.h"
......@@ -16,7 +17,7 @@ CServicenodeMan snodeman;
void CServicenodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
if(fLiteMode) return; //disable all Darksend/Servicenode related functionality
//if(!servicenodeSync.IsBlockchainSynced()) return;
if(!servicenodeSync.IsBlockchainSynced()) return;
LOCK(cs_process_message);
......@@ -41,7 +42,7 @@ bool CServicenodeMan::CheckSnbAndUpdateServicenodeList(CServicenodeBroadcast snb
LogPrint("servicenode", "CServicenodeMan::CheckSnbAndUpdateServicenodeList - Servicenode broadcast, vin: %s\n", snb.vin.ToString());
if(mapSeenServicenodeBroadcast.count(snb.GetHash())) { //seen
// servicenodeSync.AddedServicenodeList(snb.GetHash());
servicenodeSync.AddedServicenodeList(snb.GetHash());
return true;
}
mapSeenServicenodeBroadcast.insert(make_pair(snb.GetHash(), snb));
......@@ -70,7 +71,7 @@ bool CServicenodeMan::CheckSnbAndUpdateServicenodeList(CServicenodeBroadcast snb
// make sure it's still unspent
// - this is checked later by .check() in many places and by ThreadCheckDarkSendPool()
if(snb.CheckInputsAndAdd(nDos)) {
// servicenodeSync.AddedServicenodeList(snb.GetHash());
servicenodeSync.AddedServicenodeList(snb.GetHash());
} else {
LogPrintf("CServicenodeMan::CheckSnbAndUpdateServicenodeList - Rejected Servicenode entry %s\n", snb.addr.ToString());
return false;
......@@ -112,7 +113,7 @@ bool CServicenodeMan::Add(CServicenode &sn)
void CServicenodeMan::UpdateServicenodeList(CServicenodeBroadcast snb) {
mapSeenServicenodePing.insert(make_pair(snb.lastPing.GetHash(), snb.lastPing));
mapSeenServicenodeBroadcast.insert(make_pair(snb.GetHash(), snb));
//servicenodeSync.AddedServicenodeList(snb.GetHash());
servicenodeSync.AddedServicenodeList(snb.GetHash());
LogPrintf("CServicenodeMan::UpdateServicenodeList() - addr: %s\n vin: %s\n", snb.addr.ToString(), snb.vin.ToString());
......@@ -141,3 +142,47 @@ void CServicenodeMan::Remove(CTxIn vin)
}
}
// TODO remove this later
int GetMinServicenodePaymentsProto() {
return IsSporkActive(SPORK_10_THRONE_PAY_UPDATED_NODES)
? MIN_THRONE_PAYMENT_PROTO_VERSION_2
: MIN_THRONE_PAYMENT_PROTO_VERSION_1;
}
int CServicenodeMan::CountEnabled(int protocolVersion)
{
int i = 0;
protocolVersion = protocolVersion == -1 ? GetMinServicenodePaymentsProto() : protocolVersion;
BOOST_FOREACH(CServicenode& sn, vServicenodes) {
sn.Check();
if(sn.protocolVersion < protocolVersion || !sn.IsEnabled()) continue;
i++;
}
return i;
}
void CServicenodeMan::DsegUpdate(CNode* pnode)
{
LOCK(cs);
if(Params().NetworkID() == CBaseChainParams::MAIN) {
if(!(pnode->addr.IsRFC1918() || pnode->addr.IsLocal())){
std::map<CNetAddr, int64_t>::iterator it = mWeAskedForServicenodeList.find(pnode->addr);
if (it != mWeAskedForServicenodeList.end())
{
if (GetTime() < (*it).second) {
LogPrintf("dseg - we already asked %s for the list; skipping...\n", pnode->addr.ToString());
return;
}
}
}
}
pnode->PushMessage("dseg", CTxIn());
int64_t askAgain = GetTime() + THRONES_DSEG_SECONDS;
mWeAskedForServicenodeList[pnode->addr] = askAgain;
}
......@@ -34,9 +34,16 @@ private:
// critical section to protect the inner data structures specifically on messaging
mutable CCriticalSection cs_process_message;
public:
// map to hold all SNs
std::vector<CServicenode> vServicenodes;
// who's asked for the Servicenode list and the last time
std::map<CNetAddr, int64_t> mAskedUsForServicenodeList;
// who we asked for the Servicenode list and the last time
std::map<CNetAddr, int64_t> mWeAskedForServicenodeList;
// which Servicenodes we've asked for
std::map<COutPoint, int64_t> mWeAskedForServicenodeListEntry;
public:
// Keep track of all broadcasts I've seen
map<uint256, CServicenodeBroadcast> mapSeenServicenodeBroadcast;
// Keep track of all pings I've seen
......@@ -46,13 +53,15 @@ public:
/// Perform complete check and only then update list and maps
bool CheckSnbAndUpdateServicenodeList(CServicenodeBroadcast snb, int& nDos);
void DsegUpdate(CNode* pnode);
/// Find an entry
CServicenode* Find(const CTxIn& vin);
void Remove(CTxIn vin);
int CountEnabled(int protocolVersion = -1);
/// Add an entry
bool Add(CServicenode &mn);
/// Return the number of (unique) Thrones
/// Return the number of (unique) Servicenodes
int size() { return vServicenodes.size(); }
void UpdateServicenodeList(CServicenodeBroadcast snb);
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment