2021-04-20 21:33:02 +02:00
|
|
|
// Copyright (c) 2018-2021 The Dash Core developers
|
2018-02-14 14:43:03 +01:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2018-04-02 00:30:17 +02:00
|
|
|
#ifndef BITCOIN_EVO_DETERMINISTICMNS_H
|
|
|
|
#define BITCOIN_EVO_DETERMINISTICMNS_H
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2022-02-26 19:50:35 +01:00
|
|
|
#include <evo/dmnstate.h>
|
|
|
|
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <arith_uint256.h>
|
2018-11-30 18:21:03 +01:00
|
|
|
#include <crypto/common.h>
|
2022-03-30 03:13:33 +02:00
|
|
|
#include <consensus/params.h>
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <evo/evodb.h>
|
|
|
|
#include <evo/providertx.h>
|
2020-06-09 06:43:34 +02:00
|
|
|
#include <saltedhasher.h>
|
2022-03-30 03:13:33 +02:00
|
|
|
#include <scheduler.h>
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <sync.h>
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2020-03-19 23:46:56 +01:00
|
|
|
#include <immer/map.hpp>
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2020-06-09 06:43:34 +02:00
|
|
|
#include <unordered_map>
|
2021-07-31 20:29:12 +02:00
|
|
|
#include <utility>
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2022-04-07 17:32:40 +02:00
|
|
|
class CConnman;
|
2018-02-14 14:43:03 +01:00
|
|
|
class CBlock;
|
|
|
|
class CBlockIndex;
|
|
|
|
class CValidationState;
|
2021-04-16 05:41:16 +02:00
|
|
|
class CSimplifiedMNListDiff;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2021-09-28 23:23:34 +02:00
|
|
|
extern CCriticalSection cs_main;
|
|
|
|
|
2018-11-25 14:27:18 +01:00
|
|
|
namespace llmq
|
|
|
|
{
|
|
|
|
class CFinalCommitment;
|
2019-07-15 20:55:01 +02:00
|
|
|
} // namespace llmq
|
2018-11-25 14:27:18 +01:00
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
class CDeterministicMN
|
|
|
|
{
|
2020-06-09 05:53:42 +02:00
|
|
|
private:
|
|
|
|
uint64_t internalId{std::numeric_limits<uint64_t>::max()};
|
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
public:
|
2020-06-09 05:53:42 +02:00
|
|
|
CDeterministicMN() = delete; // no default constructor, must specify internalId
|
2020-08-09 23:34:26 +02:00
|
|
|
explicit CDeterministicMN(uint64_t _internalId) : internalId(_internalId)
|
2020-06-09 05:53:42 +02:00
|
|
|
{
|
|
|
|
// only non-initial values
|
|
|
|
assert(_internalId != std::numeric_limits<uint64_t>::max());
|
|
|
|
}
|
|
|
|
// TODO: can be removed in a future version
|
2021-07-31 20:29:12 +02:00
|
|
|
CDeterministicMN(CDeterministicMN mn, uint64_t _internalId) : CDeterministicMN(std::move(mn)) {
|
2020-06-09 05:53:42 +02:00
|
|
|
// only non-initial values
|
|
|
|
assert(_internalId != std::numeric_limits<uint64_t>::max());
|
|
|
|
internalId = _internalId;
|
|
|
|
}
|
|
|
|
|
2018-11-06 09:54:23 +01:00
|
|
|
template <typename Stream>
|
|
|
|
CDeterministicMN(deserialize_type, Stream& s)
|
|
|
|
{
|
|
|
|
s >> *this;
|
|
|
|
}
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
uint256 proTxHash;
|
2018-10-25 16:29:50 +02:00
|
|
|
COutPoint collateralOutpoint;
|
2021-12-28 22:54:50 +01:00
|
|
|
uint16_t nOperatorReward{0};
|
2022-03-11 20:40:31 +01:00
|
|
|
std::shared_ptr<const CDeterministicMNState> pdmnState;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2019-07-09 07:59:57 +02:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action, bool oldFormat)
|
2018-02-14 14:43:03 +01:00
|
|
|
{
|
|
|
|
READWRITE(proTxHash);
|
2019-07-09 07:59:57 +02:00
|
|
|
if (!oldFormat) {
|
|
|
|
READWRITE(VARINT(internalId));
|
|
|
|
}
|
2018-10-25 16:29:50 +02:00
|
|
|
READWRITE(collateralOutpoint);
|
2018-02-14 14:43:03 +01:00
|
|
|
READWRITE(nOperatorReward);
|
|
|
|
READWRITE(pdmnState);
|
|
|
|
}
|
|
|
|
|
2019-07-09 07:59:57 +02:00
|
|
|
template<typename Stream>
|
|
|
|
void Serialize(Stream& s) const
|
|
|
|
{
|
2021-05-27 17:17:29 +02:00
|
|
|
const_cast<CDeterministicMN*>(this)->SerializationOp(s, CSerActionSerialize(), false);
|
2019-07-09 07:59:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Stream>
|
|
|
|
void Unserialize(Stream& s, bool oldFormat = false)
|
|
|
|
{
|
|
|
|
SerializationOp(s, CSerActionUnserialize(), oldFormat);
|
|
|
|
}
|
|
|
|
|
2020-06-09 05:53:42 +02:00
|
|
|
uint64_t GetInternalId() const;
|
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
std::string ToString() const;
|
|
|
|
void ToJson(UniValue& obj) const;
|
|
|
|
};
|
2021-10-05 23:26:29 +02:00
|
|
|
using CDeterministicMNCPtr = std::shared_ptr<const CDeterministicMN>;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
class CDeterministicMNListDiff;
|
|
|
|
|
2018-11-06 09:54:23 +01:00
|
|
|
template <typename Stream, typename K, typename T, typename Hash, typename Equal>
|
2018-02-14 14:43:03 +01:00
|
|
|
void SerializeImmerMap(Stream& os, const immer::map<K, T, Hash, Equal>& m)
|
|
|
|
{
|
|
|
|
WriteCompactSize(os, m.size());
|
|
|
|
for (typename immer::map<K, T, Hash, Equal>::const_iterator mi = m.begin(); mi != m.end(); ++mi)
|
|
|
|
Serialize(os, (*mi));
|
|
|
|
}
|
|
|
|
|
2018-11-06 09:54:23 +01:00
|
|
|
template <typename Stream, typename K, typename T, typename Hash, typename Equal>
|
2018-02-14 14:43:03 +01:00
|
|
|
void UnserializeImmerMap(Stream& is, immer::map<K, T, Hash, Equal>& m)
|
|
|
|
{
|
|
|
|
m = immer::map<K, T, Hash, Equal>();
|
|
|
|
unsigned int nSize = ReadCompactSize(is);
|
2018-11-06 09:54:23 +01:00
|
|
|
for (unsigned int i = 0; i < nSize; i++) {
|
2018-02-14 14:43:03 +01:00
|
|
|
std::pair<K, T> item;
|
|
|
|
Unserialize(is, item);
|
|
|
|
m = m.set(item.first, item.second);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-02 06:16:27 +02:00
|
|
|
// For some reason the compiler is not able to choose the correct Serialize/Deserialize methods without a specialized
|
|
|
|
// version of SerReadWrite. It otherwise always chooses the version that calls a.Serialize()
|
|
|
|
template<typename Stream, typename K, typename T, typename Hash, typename Equal>
|
|
|
|
inline void SerReadWrite(Stream& s, const immer::map<K, T, Hash, Equal>& m, CSerActionSerialize ser_action)
|
|
|
|
{
|
|
|
|
::SerializeImmerMap(s, m);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Stream, typename K, typename T, typename Hash, typename Equal>
|
|
|
|
inline void SerReadWrite(Stream& s, immer::map<K, T, Hash, Equal>& obj, CSerActionUnserialize ser_action)
|
|
|
|
{
|
|
|
|
::UnserializeImmerMap(s, obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
class CDeterministicMNList
|
|
|
|
{
|
2018-11-30 18:21:03 +01:00
|
|
|
private:
|
|
|
|
struct ImmerHasher
|
|
|
|
{
|
|
|
|
size_t operator()(const uint256& hash) const { return ReadLE64(hash.begin()); }
|
|
|
|
};
|
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
public:
|
2018-11-30 18:21:03 +01:00
|
|
|
using MnMap = immer::map<uint256, CDeterministicMNCPtr, ImmerHasher>;
|
2021-10-05 23:26:29 +02:00
|
|
|
using MnInternalIdMap = immer::map<uint64_t, uint256>;
|
2018-11-30 18:21:03 +01:00
|
|
|
using MnUniquePropertyMap = immer::map<uint256, std::pair<uint256, uint32_t>, ImmerHasher>;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
uint256 blockHash;
|
|
|
|
int nHeight{-1};
|
2019-07-09 07:59:57 +02:00
|
|
|
uint32_t nTotalRegisteredCount{0};
|
2018-02-14 14:43:03 +01:00
|
|
|
MnMap mnMap;
|
2019-07-09 07:59:57 +02:00
|
|
|
MnInternalIdMap mnInternalIdMap;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
// map of unique properties like address and keys
|
|
|
|
// we keep track of this as checking for duplicates would otherwise be painfully slow
|
|
|
|
MnUniquePropertyMap mnUniquePropertyMap;
|
|
|
|
|
|
|
|
public:
|
2020-08-09 23:34:26 +02:00
|
|
|
CDeterministicMNList() = default;
|
2019-07-09 07:59:57 +02:00
|
|
|
explicit CDeterministicMNList(const uint256& _blockHash, int _height, uint32_t _totalRegisteredCount) :
|
2018-11-06 09:54:23 +01:00
|
|
|
blockHash(_blockHash),
|
2019-07-09 07:59:57 +02:00
|
|
|
nHeight(_height),
|
|
|
|
nTotalRegisteredCount(_totalRegisteredCount)
|
2018-11-06 09:54:23 +01:00
|
|
|
{
|
|
|
|
}
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2019-07-09 07:59:57 +02:00
|
|
|
inline void SerializationOpBase(Stream& s, Operation ser_action)
|
2018-02-14 14:43:03 +01:00
|
|
|
{
|
|
|
|
READWRITE(blockHash);
|
|
|
|
READWRITE(nHeight);
|
2019-07-09 07:59:57 +02:00
|
|
|
READWRITE(nTotalRegisteredCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Stream>
|
|
|
|
void Serialize(Stream& s) const
|
|
|
|
{
|
2021-05-27 17:17:29 +02:00
|
|
|
const_cast<CDeterministicMNList*>(this)->SerializationOpBase(s, CSerActionSerialize());
|
2019-07-09 07:59:57 +02:00
|
|
|
// Serialize the map as a vector
|
|
|
|
WriteCompactSize(s, mnMap.size());
|
|
|
|
for (const auto& p : mnMap) {
|
|
|
|
s << *p.second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Stream>
|
|
|
|
void Unserialize(Stream& s) {
|
|
|
|
mnMap = MnMap();
|
|
|
|
mnUniquePropertyMap = MnUniquePropertyMap();
|
|
|
|
mnInternalIdMap = MnInternalIdMap();
|
|
|
|
|
|
|
|
SerializationOpBase(s, CSerActionUnserialize());
|
|
|
|
|
|
|
|
size_t cnt = ReadCompactSize(s);
|
|
|
|
for (size_t i = 0; i < cnt; i++) {
|
2020-06-08 04:57:57 +02:00
|
|
|
AddMN(std::make_shared<CDeterministicMN>(deserialize, s), false);
|
2019-07-09 07:59:57 +02:00
|
|
|
}
|
2018-02-14 14:43:03 +01:00
|
|
|
}
|
|
|
|
|
2018-10-02 11:03:05 +02:00
|
|
|
size_t GetAllMNsCount() const
|
2018-02-14 14:43:03 +01:00
|
|
|
{
|
|
|
|
return mnMap.size();
|
|
|
|
}
|
|
|
|
|
2018-10-23 13:15:38 +02:00
|
|
|
size_t GetValidMNsCount() const
|
|
|
|
{
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
return ranges::count_if(mnMap, [](const auto& p){ return IsMNValid(*p.second); });
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute a callback on all masternodes in the mnList. This will pass a reference
|
2022-04-25 21:13:24 +02:00
|
|
|
* of each masternode to the callback function. This should be preferred over ForEachMNShared.
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
* @param onlyValid Run on all masternodes, or only "valid" (not banned) masternodes
|
|
|
|
* @param cb callback to execute
|
|
|
|
*/
|
|
|
|
template <typename Callback>
|
|
|
|
void ForEachMN(bool onlyValid, Callback&& cb) const
|
|
|
|
{
|
2018-10-23 13:15:38 +02:00
|
|
|
for (const auto& p : mnMap) {
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
if (!onlyValid || IsMNValid(*p.second)) {
|
|
|
|
cb(*p.second);
|
2018-10-23 13:15:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
/**
|
|
|
|
* Prefer ForEachMN. Execute a callback on all masternodes in the mnList.
|
|
|
|
* This will pass a non-null shared_ptr of each masternode to the callback function.
|
|
|
|
* Use this function only when a shared_ptr is needed in order to take shared ownership.
|
|
|
|
* @param onlyValid Run on all masternodes, or only "valid" (not banned) masternodes
|
|
|
|
* @param cb callback to execute
|
|
|
|
*/
|
2018-11-06 09:54:23 +01:00
|
|
|
template <typename Callback>
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
void ForEachMNShared(bool onlyValid, Callback&& cb) const
|
2018-11-06 09:54:23 +01:00
|
|
|
{
|
2018-02-14 14:43:03 +01:00
|
|
|
for (const auto& p : mnMap) {
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
if (!onlyValid || IsMNValid(*p.second)) {
|
2018-10-02 11:03:05 +02:00
|
|
|
cb(p.second);
|
2018-02-14 14:43:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const uint256& GetBlockHash() const
|
|
|
|
{
|
|
|
|
return blockHash;
|
|
|
|
}
|
|
|
|
void SetBlockHash(const uint256& _blockHash)
|
|
|
|
{
|
|
|
|
blockHash = _blockHash;
|
|
|
|
}
|
|
|
|
int GetHeight() const
|
|
|
|
{
|
|
|
|
return nHeight;
|
|
|
|
}
|
|
|
|
void SetHeight(int _height)
|
|
|
|
{
|
|
|
|
nHeight = _height;
|
|
|
|
}
|
2019-07-09 07:59:57 +02:00
|
|
|
uint32_t GetTotalRegisteredCount() const
|
|
|
|
{
|
|
|
|
return nTotalRegisteredCount;
|
|
|
|
}
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
bool IsMNValid(const uint256& proTxHash) const;
|
|
|
|
bool IsMNPoSeBanned(const uint256& proTxHash) const;
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
static bool IsMNValid(const CDeterministicMN& dmn);
|
|
|
|
static bool IsMNPoSeBanned(const CDeterministicMN& dmn);
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2018-11-06 09:54:23 +01:00
|
|
|
bool HasMN(const uint256& proTxHash) const
|
|
|
|
{
|
2018-02-14 14:43:03 +01:00
|
|
|
return GetMN(proTxHash) != nullptr;
|
|
|
|
}
|
2018-12-17 14:24:48 +01:00
|
|
|
bool HasMNByCollateral(const COutPoint& collateralOutpoint) const
|
|
|
|
{
|
|
|
|
return GetMNByCollateral(collateralOutpoint) != nullptr;
|
|
|
|
}
|
|
|
|
bool HasValidMNByCollateral(const COutPoint& collateralOutpoint) const
|
|
|
|
{
|
|
|
|
return GetValidMNByCollateral(collateralOutpoint) != nullptr;
|
|
|
|
}
|
2018-02-14 14:43:03 +01:00
|
|
|
CDeterministicMNCPtr GetMN(const uint256& proTxHash) const;
|
|
|
|
CDeterministicMNCPtr GetValidMN(const uint256& proTxHash) const;
|
2021-07-31 20:29:12 +02:00
|
|
|
CDeterministicMNCPtr GetMNByOperatorKey(const CBLSPublicKey& pubKey) const;
|
2018-10-25 16:29:50 +02:00
|
|
|
CDeterministicMNCPtr GetMNByCollateral(const COutPoint& collateralOutpoint) const;
|
2018-12-17 14:24:48 +01:00
|
|
|
CDeterministicMNCPtr GetValidMNByCollateral(const COutPoint& collateralOutpoint) const;
|
2019-06-13 11:03:20 +02:00
|
|
|
CDeterministicMNCPtr GetMNByService(const CService& service) const;
|
2019-07-09 07:59:57 +02:00
|
|
|
CDeterministicMNCPtr GetMNByInternalId(uint64_t internalId) const;
|
2018-02-14 14:43:03 +01:00
|
|
|
CDeterministicMNCPtr GetMNPayee() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates the projected MN payees for the next *count* blocks. The result is not guaranteed to be correct
|
|
|
|
* as PoSe banning might occur later
|
|
|
|
* @param count
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
std::vector<CDeterministicMNCPtr> GetProjectedMNPayees(int nCount) const;
|
|
|
|
|
2018-11-13 13:24:14 +01:00
|
|
|
/**
|
|
|
|
* Calculate a quorum based on the modifier. The resulting list is deterministically sorted by score
|
|
|
|
* @param maxSize
|
|
|
|
* @param modifier
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
std::vector<CDeterministicMNCPtr> CalculateQuorum(size_t maxSize, const uint256& modifier) const;
|
|
|
|
std::vector<std::pair<arith_uint256, CDeterministicMNCPtr>> CalculateScores(const uint256& modifier) const;
|
|
|
|
|
2018-11-25 14:27:18 +01:00
|
|
|
/**
|
|
|
|
* Calculates the maximum penalty which is allowed at the height of this MN list. It is dynamic and might change
|
|
|
|
* for every block.
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
int CalcMaxPoSePenalty() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a the given percentage from the max penalty for this MN list. Always use this method to calculate the
|
|
|
|
* value later passed to PoSePunish. The percentage should be high enough to take per-block penalty decreasing for MNs
|
|
|
|
* into account. This means, if you want to accept 2 failures per payment cycle, you should choose a percentage that
|
|
|
|
* is higher then 50%, e.g. 66%.
|
|
|
|
* @param percent
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
int CalcPenalty(int percent) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Punishes a MN for misbehavior. If the resulting penalty score of the MN reaches the max penalty, it is banned.
|
|
|
|
* Penalty scores are only increased when the MN is not already banned, which means that after banning the penalty
|
|
|
|
* might appear lower then the current max penalty, while the MN is still banned.
|
|
|
|
* @param proTxHash
|
|
|
|
* @param penalty
|
|
|
|
*/
|
2018-12-06 08:06:37 +01:00
|
|
|
void PoSePunish(const uint256& proTxHash, int penalty, bool debugLogs);
|
2018-11-25 14:27:18 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Decrease penalty score of MN by 1.
|
|
|
|
* Only allowed on non-banned MNs.
|
|
|
|
* @param proTxHash
|
|
|
|
*/
|
|
|
|
void PoSeDecrease(const uint256& proTxHash);
|
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
CDeterministicMNListDiff BuildDiff(const CDeterministicMNList& to) const;
|
2018-11-15 10:42:39 +01:00
|
|
|
CSimplifiedMNListDiff BuildSimplifiedDiff(const CDeterministicMNList& to) const;
|
2019-07-09 07:59:57 +02:00
|
|
|
CDeterministicMNList ApplyDiff(const CBlockIndex* pindex, const CDeterministicMNListDiff& diff) const;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2020-06-08 04:57:57 +02:00
|
|
|
void AddMN(const CDeterministicMNCPtr& dmn, bool fBumpTotalCount = true);
|
2022-03-11 20:40:31 +01:00
|
|
|
void UpdateMN(const CDeterministicMN& oldDmn, const std::shared_ptr<const CDeterministicMNState>& pdmnState);
|
|
|
|
void UpdateMN(const uint256& proTxHash, const std::shared_ptr<const CDeterministicMNState>& pdmnState);
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
void UpdateMN(const CDeterministicMN& oldDmn, const CDeterministicMNStateDiff& stateDiff);
|
2018-02-14 14:43:03 +01:00
|
|
|
void RemoveMN(const uint256& proTxHash);
|
|
|
|
|
2018-11-06 09:54:23 +01:00
|
|
|
template <typename T>
|
2018-02-14 14:43:03 +01:00
|
|
|
bool HasUniqueProperty(const T& v) const
|
|
|
|
{
|
|
|
|
return mnUniquePropertyMap.count(::SerializeHash(v)) != 0;
|
|
|
|
}
|
2018-11-06 09:54:23 +01:00
|
|
|
template <typename T>
|
2018-02-14 14:43:03 +01:00
|
|
|
CDeterministicMNCPtr GetUniquePropertyMN(const T& v) const
|
|
|
|
{
|
|
|
|
auto p = mnUniquePropertyMap.find(::SerializeHash(v));
|
|
|
|
if (!p) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return GetMN(p->first);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-11-06 09:54:23 +01:00
|
|
|
template <typename T>
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
[[nodiscard]] bool AddUniqueProperty(const CDeterministicMN& dmn, const T& v)
|
2018-02-14 14:43:03 +01:00
|
|
|
{
|
2018-12-10 08:31:09 +01:00
|
|
|
static const T nullValue;
|
2021-05-06 05:40:45 +02:00
|
|
|
if (v == nullValue) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-12-10 08:31:09 +01:00
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
auto hash = ::SerializeHash(v);
|
|
|
|
auto oldEntry = mnUniquePropertyMap.find(hash);
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
if (oldEntry != nullptr && oldEntry->first != dmn.proTxHash) {
|
2021-05-06 05:40:45 +02:00
|
|
|
return false;
|
|
|
|
}
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
std::pair<uint256, uint32_t> newEntry(dmn.proTxHash, 1);
|
2021-05-06 05:40:45 +02:00
|
|
|
if (oldEntry != nullptr) {
|
2018-02-14 14:43:03 +01:00
|
|
|
newEntry.second = oldEntry->second + 1;
|
|
|
|
}
|
|
|
|
mnUniquePropertyMap = mnUniquePropertyMap.set(hash, newEntry);
|
2021-05-06 05:40:45 +02:00
|
|
|
return true;
|
2018-02-14 14:43:03 +01:00
|
|
|
}
|
2018-11-06 09:54:23 +01:00
|
|
|
template <typename T>
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
[[nodiscard]] bool DeleteUniqueProperty(const CDeterministicMN& dmn, const T& oldValue)
|
2018-02-14 14:43:03 +01:00
|
|
|
{
|
2018-12-10 08:31:09 +01:00
|
|
|
static const T nullValue;
|
2021-05-06 05:40:45 +02:00
|
|
|
if (oldValue == nullValue) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-12-10 08:31:09 +01:00
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
auto oldHash = ::SerializeHash(oldValue);
|
|
|
|
auto p = mnUniquePropertyMap.find(oldHash);
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
if (p == nullptr || p->first != dmn.proTxHash) {
|
2021-05-06 05:40:45 +02:00
|
|
|
return false;
|
|
|
|
}
|
2018-02-14 14:43:03 +01:00
|
|
|
if (p->second == 1) {
|
|
|
|
mnUniquePropertyMap = mnUniquePropertyMap.erase(oldHash);
|
|
|
|
} else {
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
mnUniquePropertyMap = mnUniquePropertyMap.set(oldHash, std::make_pair(dmn.proTxHash, p->second - 1));
|
2018-02-14 14:43:03 +01:00
|
|
|
}
|
2021-05-06 05:40:45 +02:00
|
|
|
return true;
|
2018-02-14 14:43:03 +01:00
|
|
|
}
|
2018-11-06 09:54:23 +01:00
|
|
|
template <typename T>
|
refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed. (#4653)
* refactor: numerous changes to avoid passing around a const ref to shared_ptr of CDeterministicMNC when not needed.
Introduces ForEachMNShared, a version of ForEachMN that uses a shared_ptr, and may extend the lifetime of the underlying shared_ptr. This is not preferred, should prefer ForEachMN. See docs.
Adjusts ForEachMN to pass a reference. This is preferred for use over ForEachMNShared. See docs. A reference should be used since in usage we assume it's non-null anyway. Additionally, it allows us to know that the lifespan of the dmn is not being being extended (if lifespan needs to be extended, should use ForEachMNShared.
IsMNValid, IsMNPoSeBanned, UpdateMN, UpdateMN, AddUniqueProperty, DeleteUniqueProperty, UpdateUniqueProperty now take a const reference to CDeterministicMN instead of a const reference to shared_ptr<CDeterministicMN>. All of these functions previously assumed (or would've crashed) a non-null ptr, and non extended lifetime, as such converting to ref is appropriate.
CompareByLastPaid ptr overload now takes raw ptr instead of a const ref to shared. Since we simply dereference them, a raw ptr makes the most sense. This also avoids a potential expensive and implicit raw ptr -> shared ptr conversion if the function was called with raw ptrs.
rpcevo BuildDMNListEntry now takes a const ref for reasons as stated above
Signed-off-by: Pasta <pasta@dashboost.org>
* make stuff const
Signed-off-by: Pasta <pasta@dashboost.org>
* refactor/llmq: use ranges count_if
Signed-off-by: Pasta <pasta@dashboost.org>
2022-01-04 17:13:38 +01:00
|
|
|
[[nodiscard]] bool UpdateUniqueProperty(const CDeterministicMN& dmn, const T& oldValue, const T& newValue)
|
2018-02-14 14:43:03 +01:00
|
|
|
{
|
|
|
|
if (oldValue == newValue) {
|
2021-05-06 05:40:45 +02:00
|
|
|
return true;
|
2018-02-14 14:43:03 +01:00
|
|
|
}
|
2018-12-10 08:31:09 +01:00
|
|
|
static const T nullValue;
|
|
|
|
|
2021-05-06 05:40:45 +02:00
|
|
|
if (oldValue != nullValue && !DeleteUniqueProperty(dmn, oldValue)) {
|
|
|
|
return false;
|
2018-12-10 08:31:09 +01:00
|
|
|
}
|
|
|
|
|
2021-05-06 05:40:45 +02:00
|
|
|
if (newValue != nullValue && !AddUniqueProperty(dmn, newValue)) {
|
|
|
|
return false;
|
2018-12-10 08:31:09 +01:00
|
|
|
}
|
2021-05-06 05:40:45 +02:00
|
|
|
return true;
|
2018-02-14 14:43:03 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class CDeterministicMNListDiff
|
|
|
|
{
|
|
|
|
public:
|
2020-06-09 06:43:34 +02:00
|
|
|
int nHeight{-1}; //memory only
|
|
|
|
|
2019-07-09 07:59:57 +02:00
|
|
|
std::vector<CDeterministicMNCPtr> addedMNs;
|
|
|
|
// keys are all relating to the internalId of MNs
|
|
|
|
std::map<uint64_t, CDeterministicMNStateDiff> updatedMNs;
|
|
|
|
std::set<uint64_t> removedMns;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2019-07-09 07:59:57 +02:00
|
|
|
template<typename Stream>
|
|
|
|
void Serialize(Stream& s) const
|
|
|
|
{
|
|
|
|
s << addedMNs;
|
|
|
|
WriteCompactSize(s, updatedMNs.size());
|
|
|
|
for (const auto& p : updatedMNs) {
|
2020-12-17 13:20:31 +01:00
|
|
|
WriteVarInt<Stream, VarIntMode::DEFAULT, uint64_t>(s, p.first);
|
2019-07-09 07:59:57 +02:00
|
|
|
s << p.second;
|
|
|
|
}
|
|
|
|
WriteCompactSize(s, removedMns.size());
|
|
|
|
for (const auto& p : removedMns) {
|
2020-12-17 13:20:31 +01:00
|
|
|
WriteVarInt<Stream, VarIntMode::DEFAULT, uint64_t>(s, p);
|
2019-07-09 07:59:57 +02:00
|
|
|
}
|
|
|
|
}
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2019-07-09 07:59:57 +02:00
|
|
|
template<typename Stream>
|
|
|
|
void Unserialize(Stream& s)
|
2018-02-14 14:43:03 +01:00
|
|
|
{
|
2019-07-09 07:59:57 +02:00
|
|
|
updatedMNs.clear();
|
|
|
|
removedMns.clear();
|
|
|
|
|
|
|
|
size_t tmp;
|
|
|
|
uint64_t tmp2;
|
|
|
|
s >> addedMNs;
|
|
|
|
tmp = ReadCompactSize(s);
|
|
|
|
for (size_t i = 0; i < tmp; i++) {
|
|
|
|
CDeterministicMNStateDiff diff;
|
2020-12-17 13:20:31 +01:00
|
|
|
tmp2 = ReadVarInt<Stream, VarIntMode::DEFAULT, uint64_t>(s);
|
2019-07-09 07:59:57 +02:00
|
|
|
s >> diff;
|
|
|
|
updatedMNs.emplace(tmp2, std::move(diff));
|
|
|
|
}
|
|
|
|
tmp = ReadCompactSize(s);
|
|
|
|
for (size_t i = 0; i < tmp; i++) {
|
2020-12-17 13:20:31 +01:00
|
|
|
tmp2 = ReadVarInt<Stream, VarIntMode::DEFAULT, uint64_t>(s);
|
2019-07-09 07:59:57 +02:00
|
|
|
removedMns.emplace(tmp2);
|
|
|
|
}
|
2018-02-14 14:43:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool HasChanges() const
|
|
|
|
{
|
|
|
|
return !addedMNs.empty() || !updatedMNs.empty() || !removedMns.empty();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-09 07:59:57 +02:00
|
|
|
// TODO can be removed in a future version
|
|
|
|
class CDeterministicMNListDiff_OldFormat
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
uint256 prevBlockHash;
|
|
|
|
uint256 blockHash;
|
|
|
|
int nHeight{-1};
|
|
|
|
std::map<uint256, CDeterministicMNCPtr> addedMNs;
|
2022-03-11 20:40:31 +01:00
|
|
|
std::map<uint256, std::shared_ptr<const CDeterministicMNState>> updatedMNs;
|
2019-07-09 07:59:57 +02:00
|
|
|
std::set<uint256> removedMns;
|
|
|
|
|
|
|
|
template<typename Stream>
|
|
|
|
void Unserialize(Stream& s) {
|
|
|
|
addedMNs.clear();
|
|
|
|
s >> prevBlockHash;
|
|
|
|
s >> blockHash;
|
|
|
|
s >> nHeight;
|
|
|
|
size_t cnt = ReadCompactSize(s);
|
|
|
|
for (size_t i = 0; i < cnt; i++) {
|
|
|
|
uint256 proTxHash;
|
2020-06-09 05:53:42 +02:00
|
|
|
// NOTE: This is a hack and "0" is just a dummy id. The actual internalId is assigned to a copy
|
|
|
|
// of this dmn via corresponding ctor when we convert the diff format to a new one in UpgradeDiff
|
|
|
|
// thus the logic that we must set internalId before dmn is used in any meaningful way is preserved.
|
|
|
|
auto dmn = std::make_shared<CDeterministicMN>(0);
|
2019-07-09 07:59:57 +02:00
|
|
|
s >> proTxHash;
|
|
|
|
dmn->Unserialize(s, true);
|
|
|
|
addedMNs.emplace(proTxHash, dmn);
|
|
|
|
}
|
|
|
|
s >> updatedMNs;
|
|
|
|
s >> removedMns;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
class CDeterministicMNManager
|
|
|
|
{
|
2021-10-10 23:41:53 +02:00
|
|
|
static constexpr int DISK_SNAPSHOT_PERIOD = 576; // once per day
|
|
|
|
static constexpr int DISK_SNAPSHOTS = 3; // keep cache for 3 disk snapshots to have 2 full days covered
|
|
|
|
static constexpr int LIST_DIFFS_CACHE_SIZE = DISK_SNAPSHOT_PERIOD * DISK_SNAPSHOTS;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
CCriticalSection cs;
|
|
|
|
|
|
|
|
private:
|
2022-03-30 03:13:33 +02:00
|
|
|
Mutex cs_cleanup;
|
|
|
|
// We have performed CleanupCache() on this height.
|
|
|
|
int did_cleanup GUARDED_BY(cs_cleanup) {0};
|
|
|
|
|
|
|
|
// Main thread has indicated we should perform cleanup up to this height
|
|
|
|
std::atomic<int> to_cleanup {0};
|
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
CEvoDB& evoDb;
|
2022-04-07 17:32:40 +02:00
|
|
|
CConnman& connman;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2021-09-28 23:23:34 +02:00
|
|
|
std::unordered_map<uint256, CDeterministicMNList, StaticSaltedHasher> mnListsCache GUARDED_BY(cs);
|
|
|
|
std::unordered_map<uint256, CDeterministicMNListDiff, StaticSaltedHasher> mnListDiffsCache GUARDED_BY(cs);
|
|
|
|
const CBlockIndex* tipIndex GUARDED_BY(cs) {nullptr};
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
public:
|
2022-04-07 17:32:40 +02:00
|
|
|
explicit CDeterministicMNManager(CEvoDB& _evoDb, CConnman& _connman) : evoDb(_evoDb), connman(_connman) {}
|
2022-03-30 03:13:33 +02:00
|
|
|
~CDeterministicMNManager() = default;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2021-09-28 23:23:34 +02:00
|
|
|
bool ProcessBlock(const CBlock& block, const CBlockIndex* pindex, CValidationState& state,
|
|
|
|
const CCoinsViewCache& view, bool fJustCheck) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
2018-02-14 14:43:03 +01:00
|
|
|
bool UndoBlock(const CBlock& block, const CBlockIndex* pindex);
|
|
|
|
|
2018-11-06 09:54:23 +01:00
|
|
|
void UpdatedBlockTip(const CBlockIndex* pindex);
|
2018-02-14 14:43:03 +01:00
|
|
|
|
|
|
|
// the returned list will not contain the correct block hash (we can't know it yet as the coinbase TX is not updated yet)
|
2021-09-28 23:23:34 +02:00
|
|
|
bool BuildNewListFromBlock(const CBlock& block, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view,
|
|
|
|
CDeterministicMNList& mnListRet, bool debugLogs) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
2021-10-26 18:08:38 +02:00
|
|
|
static void HandleQuorumCommitment(const llmq::CFinalCommitment& qc, const CBlockIndex* pQuorumBaseBlockIndex, CDeterministicMNList& mnList, bool debugLogs);
|
2020-08-09 23:34:26 +02:00
|
|
|
static void DecreasePoSePenalties(CDeterministicMNList& mnList);
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2019-07-09 07:59:57 +02:00
|
|
|
CDeterministicMNList GetListForBlock(const CBlockIndex* pindex);
|
2018-02-14 14:43:03 +01:00
|
|
|
CDeterministicMNList GetListAtChainTip();
|
|
|
|
|
2018-10-25 16:29:50 +02:00
|
|
|
// Test if given TX is a ProRegTx which also contains the collateral at index n
|
2020-08-09 23:34:26 +02:00
|
|
|
static bool IsProTxWithCollateral(const CTransactionRef& tx, uint32_t n);
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2019-01-29 15:54:38 +01:00
|
|
|
bool IsDIP3Enforced(int nHeight = -1);
|
2018-02-15 13:57:18 +01:00
|
|
|
|
2019-07-09 07:59:57 +02:00
|
|
|
// TODO these can all be removed in a future version
|
2020-06-11 19:52:58 +02:00
|
|
|
void UpgradeDiff(CDBBatch& batch, const CBlockIndex* pindexNext, const CDeterministicMNList& curMNList, CDeterministicMNList& newMNList);
|
|
|
|
bool UpgradeDBIfNeeded();
|
2019-07-09 07:59:57 +02:00
|
|
|
|
2022-03-30 03:13:33 +02:00
|
|
|
void DoMaintenance();
|
|
|
|
|
2018-02-14 14:43:03 +01:00
|
|
|
private:
|
2021-09-28 23:23:34 +02:00
|
|
|
void CleanupCache(int nHeight) EXCLUSIVE_LOCKS_REQUIRED(cs);
|
2018-02-14 14:43:03 +01:00
|
|
|
};
|
|
|
|
|
2022-03-30 03:13:33 +02:00
|
|
|
bool CheckProRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view, bool check_sigs);
|
|
|
|
bool CheckProUpServTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, bool check_sigs);
|
|
|
|
bool CheckProUpRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, const CCoinsViewCache& view, bool check_sigs);
|
|
|
|
bool CheckProUpRevTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValidationState& state, bool check_sigs);
|
2022-02-26 19:50:35 +01:00
|
|
|
|
2017-11-09 21:22:08 +01:00
|
|
|
extern std::unique_ptr<CDeterministicMNManager> deterministicMNManager;
|
2018-02-14 14:43:03 +01:00
|
|
|
|
2018-04-02 00:30:17 +02:00
|
|
|
#endif // BITCOIN_EVO_DETERMINISTICMNS_H
|