2021-04-20 21:33:02 +02:00
|
|
|
// Copyright (c) 2014-2021 The Dash Core developers
|
2019-01-03 21:08:34 +01:00
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2021-10-01 21:19:08 +02:00
|
|
|
#ifndef BITCOIN_MASTERNODE_META_H
|
|
|
|
#define BITCOIN_MASTERNODE_META_H
|
2019-01-03 21:08:34 +01:00
|
|
|
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <serialize.h>
|
2019-01-03 21:08:34 +01:00
|
|
|
|
2020-03-26 16:47:48 +01:00
|
|
|
#include <univalue.h>
|
2020-03-19 15:23:00 +01:00
|
|
|
|
2021-09-30 23:00:52 +02:00
|
|
|
#include <atomic>
|
2021-04-16 05:41:16 +02:00
|
|
|
#include <uint256.h>
|
|
|
|
#include <sync.h>
|
2019-01-03 21:08:34 +01:00
|
|
|
|
|
|
|
class CConnman;
|
|
|
|
|
|
|
|
static const int MASTERNODE_MAX_MIXING_TXES = 5;
|
|
|
|
|
|
|
|
// Holds extra (non-deterministic) information about masternodes
|
|
|
|
// This is mostly local information, e.g. about mixing and governance
|
|
|
|
class CMasternodeMetaInfo
|
|
|
|
{
|
|
|
|
friend class CMasternodeMetaMan;
|
|
|
|
|
|
|
|
private:
|
|
|
|
mutable CCriticalSection cs;
|
|
|
|
|
2021-09-30 23:00:52 +02:00
|
|
|
uint256 proTxHash GUARDED_BY(cs);
|
2019-01-03 21:08:34 +01:00
|
|
|
|
|
|
|
//the dsq count from the last dsq broadcast of this node
|
2021-09-30 23:00:52 +02:00
|
|
|
std::atomic<int64_t> nLastDsq{0};
|
|
|
|
std::atomic<int> nMixingTxCount{0};
|
2019-01-03 21:08:34 +01:00
|
|
|
|
|
|
|
// KEEP TRACK OF GOVERNANCE ITEMS EACH MASTERNODE HAS VOTE UPON FOR RECALCULATION
|
2021-09-30 23:00:52 +02:00
|
|
|
std::map<uint256, int> mapGovernanceObjectsVotedOn GUARDED_BY(cs);
|
2019-01-03 21:08:34 +01:00
|
|
|
|
2021-09-30 23:00:52 +02:00
|
|
|
std::atomic<int64_t> lastOutboundAttempt{0};
|
|
|
|
std::atomic<int64_t> lastOutboundSuccess{0};
|
2020-03-19 13:51:25 +01:00
|
|
|
|
2019-01-03 21:08:34 +01:00
|
|
|
public:
|
2020-08-09 23:35:42 +02:00
|
|
|
CMasternodeMetaInfo() = default;
|
2020-01-05 01:55:41 +01:00
|
|
|
explicit CMasternodeMetaInfo(const uint256& _proTxHash) : proTxHash(_proTxHash) {}
|
2019-01-03 21:08:34 +01:00
|
|
|
CMasternodeMetaInfo(const CMasternodeMetaInfo& ref) :
|
|
|
|
proTxHash(ref.proTxHash),
|
2021-09-30 23:00:52 +02:00
|
|
|
nLastDsq(ref.nLastDsq.load()),
|
|
|
|
nMixingTxCount(ref.nMixingTxCount.load()),
|
2020-03-19 13:51:25 +01:00
|
|
|
mapGovernanceObjectsVotedOn(ref.mapGovernanceObjectsVotedOn),
|
2021-09-30 23:00:52 +02:00
|
|
|
lastOutboundAttempt(ref.lastOutboundAttempt.load()),
|
|
|
|
lastOutboundSuccess(ref.lastOutboundSuccess.load())
|
2019-01-03 21:08:34 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-05-27 17:17:29 +02:00
|
|
|
SERIALIZE_METHODS(CMasternodeMetaInfo, obj)
|
2019-01-03 21:08:34 +01:00
|
|
|
{
|
2021-05-27 17:17:29 +02:00
|
|
|
LOCK(obj.cs);
|
|
|
|
READWRITE(
|
|
|
|
obj.proTxHash,
|
|
|
|
obj.nLastDsq,
|
|
|
|
obj.nMixingTxCount,
|
|
|
|
obj.mapGovernanceObjectsVotedOn,
|
|
|
|
obj.lastOutboundAttempt,
|
|
|
|
obj.lastOutboundSuccess
|
|
|
|
);
|
2019-01-03 21:08:34 +01:00
|
|
|
}
|
|
|
|
|
2020-03-19 15:23:00 +01:00
|
|
|
UniValue ToJson() const;
|
|
|
|
|
2019-01-03 21:08:34 +01:00
|
|
|
public:
|
|
|
|
const uint256& GetProTxHash() const { LOCK(cs); return proTxHash; }
|
2021-09-30 23:00:52 +02:00
|
|
|
int64_t GetLastDsq() const { return nLastDsq; }
|
|
|
|
int GetMixingTxCount() const { return nMixingTxCount; }
|
2019-01-03 21:08:34 +01:00
|
|
|
|
|
|
|
bool IsValidForMixingTxes() const { return GetMixingTxCount() <= MASTERNODE_MAX_MIXING_TXES; }
|
|
|
|
|
2020-08-09 23:35:42 +02:00
|
|
|
// KEEP TRACK OF EACH GOVERNANCE ITEM IN CASE THIS NODE GOES OFFLINE, SO WE CAN RECALCULATE THEIR STATUS
|
2019-01-03 21:08:34 +01:00
|
|
|
void AddGovernanceVote(const uint256& nGovernanceObjectHash);
|
|
|
|
|
|
|
|
void RemoveGovernanceObject(const uint256& nGovernanceObjectHash);
|
2020-03-19 13:51:25 +01:00
|
|
|
|
2021-09-30 23:00:52 +02:00
|
|
|
void SetLastOutboundAttempt(int64_t t) { lastOutboundAttempt = t; }
|
|
|
|
int64_t GetLastOutboundAttempt() const { return lastOutboundAttempt; }
|
|
|
|
void SetLastOutboundSuccess(int64_t t) { lastOutboundSuccess = t; }
|
|
|
|
int64_t GetLastOutboundSuccess() const { return lastOutboundSuccess; }
|
2019-01-03 21:08:34 +01:00
|
|
|
};
|
2021-10-05 23:26:29 +02:00
|
|
|
using CMasternodeMetaInfoPtr = std::shared_ptr<CMasternodeMetaInfo>;
|
2019-01-03 21:08:34 +01:00
|
|
|
|
|
|
|
class CMasternodeMetaMan
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
static const std::string SERIALIZATION_VERSION_STRING;
|
|
|
|
|
2021-05-27 17:17:29 +02:00
|
|
|
mutable CCriticalSection cs;
|
2019-01-03 21:08:34 +01:00
|
|
|
|
2021-09-30 23:00:52 +02:00
|
|
|
std::map<uint256, CMasternodeMetaInfoPtr> metaInfos GUARDED_BY(cs);
|
|
|
|
std::vector<uint256> vecDirtyGovernanceObjectHashes GUARDED_BY(cs);
|
2019-01-03 21:08:34 +01:00
|
|
|
|
2021-03-17 23:36:11 +01:00
|
|
|
// keep track of dsq count to prevent masternodes from gaming coinjoin queue
|
2021-09-30 23:00:52 +02:00
|
|
|
std::atomic<int64_t> nDsqCount{0};
|
2019-01-03 21:08:34 +01:00
|
|
|
|
|
|
|
public:
|
2021-05-27 17:17:29 +02:00
|
|
|
template<typename Stream>
|
|
|
|
void Serialize(Stream &s) const
|
2019-01-03 21:08:34 +01:00
|
|
|
{
|
|
|
|
LOCK(cs);
|
2021-05-27 17:17:29 +02:00
|
|
|
std::vector<CMasternodeMetaInfo> tmpMetaInfo;
|
|
|
|
for (auto& p : metaInfos) {
|
|
|
|
tmpMetaInfo.emplace_back(*p.second);
|
|
|
|
}
|
|
|
|
s << SERIALIZATION_VERSION_STRING << tmpMetaInfo << nDsqCount;
|
|
|
|
}
|
2019-01-03 21:08:34 +01:00
|
|
|
|
2021-05-27 17:17:29 +02:00
|
|
|
template<typename Stream>
|
|
|
|
void Unserialize(Stream &s)
|
|
|
|
{
|
|
|
|
LOCK(cs);
|
|
|
|
Clear();
|
2019-01-03 21:08:34 +01:00
|
|
|
std::string strVersion;
|
2021-05-27 17:17:29 +02:00
|
|
|
s >> strVersion;
|
|
|
|
if (strVersion != SERIALIZATION_VERSION_STRING) {
|
|
|
|
return;
|
2019-01-03 21:08:34 +01:00
|
|
|
}
|
|
|
|
std::vector<CMasternodeMetaInfo> tmpMetaInfo;
|
2021-05-27 17:17:29 +02:00
|
|
|
s >> tmpMetaInfo >> nDsqCount;
|
|
|
|
metaInfos.clear();
|
|
|
|
for (auto& mm : tmpMetaInfo) {
|
|
|
|
metaInfos.emplace(mm.GetProTxHash(), std::make_shared<CMasternodeMetaInfo>(std::move(mm)));
|
2019-01-03 21:08:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
CMasternodeMetaInfoPtr GetMetaInfo(const uint256& proTxHash, bool fCreate = true);
|
|
|
|
|
2021-09-30 23:00:52 +02:00
|
|
|
int64_t GetDsqCount() const { return nDsqCount; }
|
2020-05-02 17:50:03 +02:00
|
|
|
int64_t GetDsqThreshold(const uint256& proTxHash, int nMnCount);
|
2019-01-03 21:08:34 +01:00
|
|
|
|
|
|
|
void AllowMixing(const uint256& proTxHash);
|
|
|
|
void DisallowMixing(const uint256& proTxHash);
|
|
|
|
|
|
|
|
bool AddGovernanceVote(const uint256& proTxHash, const uint256& nGovernanceObjectHash);
|
|
|
|
void RemoveGovernanceObject(const uint256& nGovernanceObjectHash);
|
|
|
|
|
|
|
|
std::vector<uint256> GetAndClearDirtyGovernanceObjectHashes();
|
|
|
|
|
|
|
|
void Clear();
|
2021-09-30 20:59:42 +02:00
|
|
|
// Needed to avoid errors in flat-database.h
|
|
|
|
void CheckAndRemove() const {};
|
2019-01-03 21:08:34 +01:00
|
|
|
|
|
|
|
std::string ToString() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern CMasternodeMetaMan mmetaman;
|
|
|
|
|
2021-10-01 21:19:08 +02:00
|
|
|
#endif // BITCOIN_MASTERNODE_META_H
|