2022-06-08 01:36:46 +02:00
// Copyright (c) 2018-2022 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>
2022-03-30 03:13:33 +02:00
# include <consensus/params.h>
2023-02-14 19:48:33 +01:00
# include <crypto/common.h>
# include <evo/dmn_types.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 :
2023-02-14 19:48:33 +01:00
static constexpr uint16_t CURRENT_MN_FORMAT = 0 ;
static constexpr uint16_t MN_TYPE_FORMAT = 1 ;
2020-06-09 05:53:42 +02:00
CDeterministicMN ( ) = delete ; // no default constructor, must specify internalId
2023-02-14 19:48:33 +01:00
explicit CDeterministicMN ( uint64_t _internalId , bool highPerformanceMasternode = false ) :
internalId ( _internalId ) ,
nType ( highPerformanceMasternode ? MnType : : HighPerformance . index : MnType : : Regular . index )
2020-06-09 05:53:42 +02:00
{
// only non-initial values
assert ( _internalId ! = std : : numeric_limits < uint64_t > : : max ( ) ) ;
}
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 } ;
2023-02-14 19:48:33 +01:00
uint16_t nType { MnType : : Regular . index } ;
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 >
2023-02-14 19:48:33 +01:00
inline void SerializationOp ( Stream & s , Operation ser_action , const uint8_t format_version )
2018-02-14 14:43:03 +01:00
{
READWRITE ( proTxHash ) ;
2023-02-14 19:48:33 +01:00
READWRITE ( VARINT ( internalId ) ) ;
2018-10-25 16:29:50 +02:00
READWRITE ( collateralOutpoint ) ;
2018-02-14 14:43:03 +01:00
READWRITE ( nOperatorReward ) ;
2023-02-14 19:48:33 +01:00
// We need to read CDeterministicMNState using the old format only when called with CURRENT_MN_FORMAT on Unserialize()
// Serialisation (writing) will be done always using new format
if ( ser_action . ForRead ( ) & & format_version = = CURRENT_MN_FORMAT ) {
CDeterministicMNState_Oldformat old_state ;
READWRITE ( old_state ) ;
pdmnState = std : : make_shared < const CDeterministicMNState > ( old_state ) ;
} else {
READWRITE ( pdmnState ) ;
}
// We need to read/write nType if:
// format_version is set to MN_TYPE_FORMAT (For writing (serialisation) it is always the case) Needed for the MNLISTDIFF Migration in evoDB
// We can't know if we are serialising for the Disk or for the Network here (s.GetType() is not accessible)
// Therefore if s.GetVersion() == CLIENT_VERSION -> Then we know we are serialising for the Disk
// Otherwise, we can safely check with protocol versioning logic so we won't break old clients
if ( format_version > = MN_TYPE_FORMAT & & ( s . GetVersion ( ) = = CLIENT_VERSION | | s . GetVersion ( ) > = DMN_TYPE_PROTO_VERSION ) ) {
READWRITE ( nType ) ;
} else {
nType = MnType : : Regular . index ;
}
2018-02-14 14:43:03 +01:00
}
2019-07-09 07:59:57 +02:00
template < typename Stream >
void Serialize ( Stream & s ) const
{
2023-02-14 19:48:33 +01:00
const_cast < CDeterministicMN * > ( this ) - > SerializationOp ( s , CSerActionSerialize ( ) , MN_TYPE_FORMAT ) ;
2019-07-09 07:59:57 +02:00
}
2023-02-14 19:48:33 +01:00
template < typename Stream >
void Unserialize ( Stream & s , const uint8_t format_version = MN_TYPE_FORMAT )
2019-07-09 07:59:57 +02:00
{
2023-02-14 19:48:33 +01:00
SerializationOp ( s , CSerActionUnserialize ( ) , format_version ) ;
2019-07-09 07:59:57 +02:00
}
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] uint64_t GetInternalId ( ) const ;
2020-06-09 05:53:42 +02:00
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] std : : string ToString ( ) const ;
2018-02-14 14:43:03 +01:00
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
}
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] size_t GetAllMNsCount ( ) const
2018-02-14 14:43:03 +01:00
{
return mnMap . size ( ) ;
}
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] size_t GetValidMNsCount ( ) const
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
return ranges : : count_if ( mnMap , [ ] ( const auto & p ) { return IsMNValid ( * p . second ) ; } ) ;
}
2023-02-14 19:48:33 +01:00
[ [ nodiscard ] ] size_t GetAllHPMNsCount ( ) const
{
return ranges : : count_if ( mnMap , [ ] ( const auto & p ) { return p . second - > nType = = MnType : : HighPerformance . index ; } ) ;
}
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
/**
* 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
}
}
}
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] const uint256 & GetBlockHash ( ) const
2018-02-14 14:43:03 +01:00
{
return blockHash ;
}
void SetBlockHash ( const uint256 & _blockHash )
{
blockHash = _blockHash ;
}
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] int GetHeight ( ) const
2018-02-14 14:43:03 +01:00
{
return nHeight ;
}
void SetHeight ( int _height )
{
nHeight = _height ;
}
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] uint32_t GetTotalRegisteredCount ( ) const
2019-07-09 07:59:57 +02:00
{
return nTotalRegisteredCount ;
}
2018-02-14 14:43:03 +01:00
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] bool IsMNValid ( const uint256 & proTxHash ) const ;
[ [ nodiscard ] ] 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
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] bool HasMN ( const uint256 & proTxHash ) const
2018-11-06 09:54:23 +01:00
{
2018-02-14 14:43:03 +01:00
return GetMN ( proTxHash ) ! = nullptr ;
}
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] bool HasMNByCollateral ( const COutPoint & collateralOutpoint ) const
2018-12-17 14:24:48 +01:00
{
return GetMNByCollateral ( collateralOutpoint ) ! = nullptr ;
}
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] bool HasValidMNByCollateral ( const COutPoint & collateralOutpoint ) const
2018-12-17 14:24:48 +01:00
{
return GetValidMNByCollateral ( collateralOutpoint ) ! = nullptr ;
}
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] CDeterministicMNCPtr GetMN ( const uint256 & proTxHash ) const ;
[ [ nodiscard ] ] CDeterministicMNCPtr GetValidMN ( const uint256 & proTxHash ) const ;
[ [ nodiscard ] ] CDeterministicMNCPtr GetMNByOperatorKey ( const CBLSPublicKey & pubKey ) const ;
[ [ nodiscard ] ] CDeterministicMNCPtr GetMNByCollateral ( const COutPoint & collateralOutpoint ) const ;
[ [ nodiscard ] ] CDeterministicMNCPtr GetValidMNByCollateral ( const COutPoint & collateralOutpoint ) const ;
[ [ nodiscard ] ] CDeterministicMNCPtr GetMNByService ( const CService & service ) const ;
[ [ nodiscard ] ] CDeterministicMNCPtr GetMNByInternalId ( uint64_t internalId ) const ;
2023-02-14 19:48:33 +01:00
[ [ nodiscard ] ] CDeterministicMNCPtr GetMNPayee ( const CBlockIndex * pIndex ) const ;
2018-02-14 14:43:03 +01:00
/**
* 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
*/
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] std : : vector < CDeterministicMNCPtr > GetProjectedMNPayees ( int nCount ) const ;
2018-02-14 14:43:03 +01:00
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
*/
2023-02-14 19:48:33 +01:00
[ [ nodiscard ] ] std : : vector < CDeterministicMNCPtr > CalculateQuorum ( size_t maxSize , const uint256 & modifier , const bool onlyHighPerformanceMasternodes = false ) const ;
[ [ nodiscard ] ] std : : vector < std : : pair < arith_uint256 , CDeterministicMNCPtr > > CalculateScores ( const uint256 & modifier , const bool onlyHighPerformanceMasternodes ) const ;
2018-11-13 13:24:14 +01:00
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
*/
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] int CalcMaxPoSePenalty ( ) const ;
2018-11-25 14:27:18 +01:00
/**
* 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
*/
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] int CalcPenalty ( int percent ) const ;
2018-11-25 14:27:18 +01:00
/**
* 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 ) ;
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] CDeterministicMNListDiff BuildDiff ( const CDeterministicMNList & to ) const ;
[ [ nodiscard ] ] CSimplifiedMNListDiff BuildSimplifiedDiff ( const CDeterministicMNList & to , bool extended ) const ;
[ [ nodiscard ] ] 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 >
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] bool HasUniqueProperty ( const T & v ) const
2018-02-14 14:43:03 +01:00
{
return mnUniquePropertyMap . count ( : : SerializeHash ( v ) ) ! = 0 ;
}
2018-11-06 09:54:23 +01:00
template < typename T >
2022-09-03 12:20:06 +02:00
[ [ nodiscard ] ] CDeterministicMNCPtr GetUniquePropertyMN ( const T & v ) const
2018-02-14 14:43:03 +01:00
{
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
2023-02-14 19:48:33 +01:00
template < typename Stream >
void Unserialize ( Stream & s , const uint8_t format_version = CDeterministicMN : : MN_TYPE_FORMAT )
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 ;
2023-02-14 19:48:33 +01:00
tmp = ReadCompactSize ( s ) ;
for ( size_t i = 0 ; i < tmp ; i + + ) {
CDeterministicMN mn ( 0 ) ;
// Unserialise CDeterministicMN using CURRENT_MN_FORMAT and set it's type to the default value TYPE_REGULAR_MASTERNODE
// It will be later written with format MN_TYPE_FORMAT which includes the type field.
mn . Unserialize ( s , format_version ) ;
auto dmn = std : : make_shared < CDeterministicMN > ( mn ) ;
addedMNs . push_back ( dmn ) ;
}
2019-07-09 07:59:57 +02:00
tmp = ReadCompactSize ( s ) ;
for ( size_t i = 0 ; i < tmp ; i + + ) {
CDeterministicMNStateDiff diff ;
2023-02-14 19:48:33 +01:00
// CDeterministicMNState hold new fields {nConsecutivePayments, platformNodeID, platformP2PPort, platformHTTPPort} but no migration is needed here since:
// CDeterministicMNStateDiff is always serialised using a bitmask.
// Because the new field have a new bit guide value then we are good to continue
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
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 } ;
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have added or updated relevant unit/integration/functional/e2e
tests
- [ ] I have made corresponding changes to the documentation
**For repository code-owners and collaborators only**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
CEvoDB & m_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 :
refactor: remove the g_evoDb global; use NodeContext and locals (#5058)
<!--
*** Please remove the following help text before submitting: ***
Provide a general summary of your changes in the Title above
Pull requests without a rationale and clear improvement may be closed
immediately.
Please provide clear motivation for your patch and explain how it
improves
Dash Core user experience or Dash Core developer experience
significantly:
* Any test improvements or new tests that improve coverage are always
welcome.
* All other changes should have accompanying unit tests (see
`src/test/`) or
functional tests (see `test/`). Contributors should note which tests
cover
modified code. If no tests exist for a region of modified code, new
tests
should accompany the change.
* Bug fixes are most welcome when they come with steps to reproduce or
an
explanation of the potential issue as well as reasoning for the way the
bug
was fixed.
* Features are welcome, but might be rejected due to design or scope
issues.
If a feature is based on a lot of dependencies, contributors should
first
consider building the system outside of Dash Core, if possible.
-->
## Issue being fixed or feature implemented
<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->
globals should be avoided to avoid annoying lifetime / nullptr /
initialization issues
## What was done?
<!--- Describe your changes in detail -->
removed a global, g_evoDB
## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran
to -->
<!--- see how your change affects other areas of the code, etc. -->
make check
## Breaking Changes
<!--- Please describe any breaking changes your code introduces -->
none
## Checklist:
<!--- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have added or updated relevant unit/integration/functional/e2e
tests
- [ ] I have made corresponding changes to the documentation
**For repository code-owners and collaborators only**
- [ ] I have assigned this pull request to a milestone
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
Co-authored-by: Kittywhiskers Van Gogh <63189531+kittywhiskers@users.noreply.github.com>
2022-12-10 18:58:17 +01:00
explicit CDeterministicMNManager ( CEvoDB & evoDb , CConnman & _connman ) :
m_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
2023-02-14 19:48:33 +01:00
void MigrateDiff ( CDBBatch & batch , const CBlockIndex * pindexNext , const CDeterministicMNList & curMNList , CDeterministicMNList & newMNList ) ;
bool MigrateDBIfNeeded ( ) ;
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