2018-09-28 09:56:17 +02:00
// Copyright (c) 2014-2018 The Dash Core developers
2016-11-24 19:12:05 +01:00
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# ifndef GOVERNANCE_OBJECT_H
# define GOVERNANCE_OBJECT_H
//#define ENABLE_DASH_DEBUG
2016-12-20 14:27:59 +01:00
# include "cachemultimap.h"
2016-11-24 19:12:05 +01:00
# include "governance-exceptions.h"
# include "governance-vote.h"
# include "governance-votedb.h"
2016-12-20 14:27:59 +01:00
# include "key.h"
# include "net.h"
# include "sync.h"
# include "util.h"
2018-02-15 15:43:17 +01:00
# include "utilstrencodings.h"
2018-10-21 21:45:16 +02:00
# include "bls/bls.h"
2016-11-24 19:12:05 +01:00
2016-12-20 14:27:59 +01:00
# include <univalue.h>
2016-11-24 19:12:05 +01:00
class CGovernanceManager ;
class CGovernanceTriggerManager ;
class CGovernanceObject ;
class CGovernanceVote ;
2018-09-05 18:34:56 +02:00
static const int MIN_GOVERNANCE_PEER_PROTO_VERSION = 70210 ;
2017-02-02 09:50:44 +01:00
static const int GOVERNANCE_FILTER_PROTO_VERSION = 70206 ;
static const double GOVERNANCE_FILTER_FP_RATE = 0.001 ;
2016-11-24 19:12:05 +01:00
static const int GOVERNANCE_OBJECT_UNKNOWN = 0 ;
static const int GOVERNANCE_OBJECT_PROPOSAL = 1 ;
static const int GOVERNANCE_OBJECT_TRIGGER = 2 ;
static const int GOVERNANCE_OBJECT_WATCHDOG = 3 ;
2018-09-28 09:56:17 +02:00
static const CAmount GOVERNANCE_PROPOSAL_FEE_TX = ( 5.0 * COIN ) ;
2016-11-24 19:12:05 +01:00
static const int64_t GOVERNANCE_FEE_CONFIRMATIONS = 6 ;
2017-07-05 02:31:50 +02:00
static const int64_t GOVERNANCE_MIN_RELAY_FEE_CONFIRMATIONS = 1 ;
2018-09-28 09:56:17 +02:00
static const int64_t GOVERNANCE_UPDATE_MIN = 60 * 60 ;
static const int64_t GOVERNANCE_DELETION_DELAY = 10 * 60 ;
static const int64_t GOVERNANCE_ORPHAN_EXPIRATION_TIME = 10 * 60 ;
2016-11-24 19:12:05 +01:00
// FOR SEEN MAP ARRAYS - GOVERNANCE OBJECTS AND VOTES
static const int SEEN_OBJECT_IS_VALID = 0 ;
static const int SEEN_OBJECT_ERROR_INVALID = 1 ;
static const int SEEN_OBJECT_ERROR_IMMATURE = 2 ;
static const int SEEN_OBJECT_EXECUTED = 3 ; //used for triggers
2018-09-28 09:56:17 +02:00
static const int SEEN_OBJECT_UNKNOWN = 4 ; // the default
2016-11-24 19:12:05 +01:00
typedef std : : pair < CGovernanceVote , int64_t > vote_time_pair_t ;
inline bool operator < ( const vote_time_pair_t & p1 , const vote_time_pair_t & p2 )
{
return ( p1 . first < p2 . first ) ;
}
struct vote_instance_t {
vote_outcome_enum_t eOutcome ;
int64_t nTime ;
2017-02-23 13:29:00 +01:00
int64_t nCreationTime ;
2016-11-24 19:12:05 +01:00
2018-09-28 09:56:17 +02:00
vote_instance_t ( vote_outcome_enum_t eOutcomeIn = VOTE_OUTCOME_NONE , int64_t nTimeIn = 0 , int64_t nCreationTimeIn = 0 ) :
eOutcome ( eOutcomeIn ) ,
nTime ( nTimeIn ) ,
nCreationTime ( nCreationTimeIn )
{
}
2016-11-24 19:12:05 +01:00
ADD_SERIALIZE_METHODS ;
template < typename Stream , typename Operation >
2017-09-19 21:36:55 +02:00
inline void SerializationOp ( Stream & s , Operation ser_action )
2016-11-24 19:12:05 +01:00
{
int nOutcome = int ( eOutcome ) ;
READWRITE ( nOutcome ) ;
READWRITE ( nTime ) ;
2017-02-23 13:29:00 +01:00
READWRITE ( nCreationTime ) ;
2018-09-28 09:56:17 +02:00
if ( ser_action . ForRead ( ) ) {
2016-11-24 19:12:05 +01:00
eOutcome = vote_outcome_enum_t ( nOutcome ) ;
}
}
} ;
2018-09-28 09:56:17 +02:00
typedef std : : map < int , vote_instance_t > vote_instance_m_t ;
2016-11-24 19:12:05 +01:00
typedef vote_instance_m_t : : iterator vote_instance_m_it ;
typedef vote_instance_m_t : : const_iterator vote_instance_m_cit ;
struct vote_rec_t {
vote_instance_m_t mapInstances ;
ADD_SERIALIZE_METHODS ;
2018-09-28 09:56:17 +02:00
template < typename Stream , typename Operation >
inline void SerializationOp ( Stream & s , Operation ser_action )
{
READWRITE ( mapInstances ) ;
}
2016-11-24 19:12:05 +01:00
} ;
/**
* Governance Object
*
*/
class CGovernanceObject
{
friend class CGovernanceManager ;
friend class CGovernanceTriggerManager ;
2018-02-12 19:35:10 +01:00
friend class CSuperblock ;
2016-11-24 19:12:05 +01:00
public : // Types
2017-09-11 16:13:48 +02:00
typedef std : : map < COutPoint , vote_rec_t > vote_m_t ;
2016-11-24 19:12:05 +01:00
typedef vote_m_t : : iterator vote_m_it ;
typedef vote_m_t : : const_iterator vote_m_cit ;
2018-02-06 12:08:43 +01:00
typedef CacheMultiMap < COutPoint , vote_time_pair_t > vote_cmm_t ;
2016-11-24 19:12:05 +01:00
private :
/// critical section to protect the inner data structures
mutable CCriticalSection cs ;
/// Object typecode
int nObjectType ;
/// parent object, 0 is root
uint256 nHashParent ;
/// object revision in the system
int nRevision ;
/// time this object was created
int64_t nTime ;
/// time this object was marked for deletion
int64_t nDeletionTime ;
/// fee-tx
uint256 nCollateralHash ;
/// Data field - can be used for anything
2018-02-15 15:43:17 +01:00
std : : vector < unsigned char > vchData ;
2016-11-24 19:12:05 +01:00
/// Masternode info for signed objects
2018-02-15 08:29:44 +01:00
COutPoint masternodeOutpoint ;
2016-11-24 19:12:05 +01:00
std : : vector < unsigned char > vchSig ;
/// is valid by blockchain
bool fCachedLocalValidity ;
std : : string strLocalValidityError ;
// VARIOUS FLAGS FOR OBJECT / SET VIA MASTERNODE VOTING
/// true == minimum network support has been reached for this object to be funded (doesn't mean it will for sure though)
bool fCachedFunding ;
2017-12-05 23:17:45 +01:00
/// true == minimum network has been reached flagging this object as a valid and understood governance object (e.g, the serialized data is correct format, etc)
2016-11-24 19:12:05 +01:00
bool fCachedValid ;
/// true == minimum network support has been reached saying this object should be deleted from the system entirely
bool fCachedDelete ;
/** true == minimum network support has been reached flagging this object as endorsed by an elected representative body
* ( e . g . business review board / technecial review board / etc )
*/
bool fCachedEndorsed ;
/// object was updated and cached values should be updated soon
bool fDirtyCache ;
/// Object is no longer of interest
bool fExpired ;
/// Failed to parse object data
bool fUnparsable ;
vote_m_t mapCurrentMNVotes ;
/// Limited map of votes orphaned by MN
2018-02-06 12:08:43 +01:00
vote_cmm_t cmmapOrphanVotes ;
2016-11-24 19:12:05 +01:00
CGovernanceObjectVoteFile fileVotes ;
public :
CGovernanceObject ( ) ;
2018-02-15 15:43:17 +01:00
CGovernanceObject ( const uint256 & nHashParentIn , int nRevisionIn , int64_t nTime , const uint256 & nCollateralHashIn , const std : : string & strDataHexIn ) ;
2016-11-24 19:12:05 +01:00
CGovernanceObject ( const CGovernanceObject & other ) ;
// Public Getter methods
2018-09-28 09:56:17 +02:00
int64_t GetCreationTime ( ) const
{
2016-11-24 19:12:05 +01:00
return nTime ;
}
2018-09-28 09:56:17 +02:00
int64_t GetDeletionTime ( ) const
{
2016-11-24 19:12:05 +01:00
return nDeletionTime ;
}
2018-09-28 09:56:17 +02:00
int GetObjectType ( ) const
{
2016-11-24 19:12:05 +01:00
return nObjectType ;
}
2018-09-28 09:56:17 +02:00
const uint256 & GetCollateralHash ( ) const
{
2016-11-24 19:12:05 +01:00
return nCollateralHash ;
}
2018-09-28 09:56:17 +02:00
const COutPoint & GetMasternodeOutpoint ( ) const
{
2018-02-15 08:29:44 +01:00
return masternodeOutpoint ;
2016-11-24 19:12:05 +01:00
}
2018-09-28 09:56:17 +02:00
bool IsSetCachedFunding ( ) const
{
2016-11-24 19:12:05 +01:00
return fCachedFunding ;
}
2018-09-28 09:56:17 +02:00
bool IsSetCachedValid ( ) const
{
2016-11-24 19:12:05 +01:00
return fCachedValid ;
}
2018-09-28 09:56:17 +02:00
bool IsSetCachedDelete ( ) const
{
2016-11-24 19:12:05 +01:00
return fCachedDelete ;
}
2018-09-28 09:56:17 +02:00
bool IsSetCachedEndorsed ( ) const
{
2016-11-24 19:12:05 +01:00
return fCachedEndorsed ;
}
2018-09-28 09:56:17 +02:00
bool IsSetDirtyCache ( ) const
{
2016-11-24 19:12:05 +01:00
return fDirtyCache ;
}
2018-09-28 09:56:17 +02:00
bool IsSetExpired ( ) const
{
2016-11-24 19:12:05 +01:00
return fExpired ;
}
2018-09-28 09:56:17 +02:00
const CGovernanceObjectVoteFile & GetVoteFile ( ) const
{
2016-11-24 19:12:05 +01:00
return fileVotes ;
}
// Signature related functions
2018-02-15 08:29:44 +01:00
void SetMasternodeOutpoint ( const COutPoint & outpoint ) ;
2018-08-31 15:31:59 +02:00
bool Sign ( const CKey & key , const CKeyID & keyID ) ;
bool CheckSignature ( const CKeyID & keyID ) const ;
2018-10-21 21:45:16 +02:00
bool Sign ( const CBLSSecretKey & key ) ;
bool CheckSignature ( const CBLSPublicKey & pubKey ) const ;
2016-11-24 19:12:05 +01:00
2016-12-20 04:25:20 +01:00
std : : string GetSignatureMessage ( ) const ;
2018-02-16 15:54:53 +01:00
uint256 GetSignatureHash ( ) const ;
2016-12-20 04:25:20 +01:00
2016-11-24 19:12:05 +01:00
// CORE OBJECT FUNCTIONS
2018-03-20 12:04:59 +01:00
bool IsValidLocally ( std : : string & strError , bool fCheckCollateral ) const ;
2016-11-24 19:12:05 +01:00
2018-03-20 12:04:59 +01:00
bool IsValidLocally ( std : : string & strError , bool & fMissingMasternode , bool & fMissingConfirmations , bool fCheckCollateral ) const ;
2016-11-24 19:12:05 +01:00
/// Check the collateral transaction for the budget proposal/finalized budget
2018-03-20 12:04:59 +01:00
bool IsCollateralValid ( std : : string & strError , bool & fMissingConfirmations ) const ;
2016-11-24 19:12:05 +01:00
2017-01-03 19:32:52 +01:00
void UpdateLocalValidity ( ) ;
2016-11-24 19:12:05 +01:00
2016-12-11 07:17:38 +01:00
void UpdateSentinelVariables ( ) ;
2016-11-24 19:12:05 +01:00
2018-03-20 12:04:59 +01:00
CAmount GetMinCollateralFee ( ) const ;
2016-11-24 19:12:05 +01:00
UniValue GetJSONObject ( ) ;
2017-09-19 16:51:38 +02:00
void Relay ( CConnman & connman ) ;
2016-11-24 19:12:05 +01:00
2016-12-11 07:17:38 +01:00
uint256 GetHash ( ) const ;
2016-11-24 19:12:05 +01:00
// GET VOTE COUNT FOR SIGNAL
int CountMatchingVotes ( vote_signal_enum_t eVoteSignalIn , vote_outcome_enum_t eVoteOutcomeIn ) const ;
int GetAbsoluteYesCount ( vote_signal_enum_t eVoteSignalIn ) const ;
int GetAbsoluteNoCount ( vote_signal_enum_t eVoteSignalIn ) const ;
int GetYesCount ( vote_signal_enum_t eVoteSignalIn ) const ;
int GetNoCount ( vote_signal_enum_t eVoteSignalIn ) const ;
int GetAbstainCount ( vote_signal_enum_t eVoteSignalIn ) const ;
2018-03-20 12:04:59 +01:00
bool GetCurrentMNVotes ( const COutPoint & mnCollateralOutpoint , vote_rec_t & voteRecord ) const ;
2016-11-24 19:12:05 +01:00
// FUNCTIONS FOR DEALING WITH DATA STRING
2018-02-15 15:43:17 +01:00
std : : string GetDataAsHexString ( ) const ;
std : : string GetDataAsPlainString ( ) const ;
2016-11-24 19:12:05 +01:00
// SERIALIZER
ADD_SERIALIZE_METHODS ;
template < typename Stream , typename Operation >
2017-09-19 21:36:55 +02:00
inline void SerializationOp ( Stream & s , Operation ser_action )
2016-11-24 19:12:05 +01:00
{
// SERIALIZE DATA FOR SAVING/LOADING OR NETWORK FUNCTIONS
READWRITE ( nHashParent ) ;
READWRITE ( nRevision ) ;
READWRITE ( nTime ) ;
READWRITE ( nCollateralHash ) ;
2018-09-15 12:19:31 +02:00
READWRITE ( vchData ) ;
2016-11-24 19:12:05 +01:00
READWRITE ( nObjectType ) ;
2018-09-15 12:19:31 +02:00
READWRITE ( masternodeOutpoint ) ;
2018-02-16 15:54:53 +01:00
if ( ! ( s . GetType ( ) & SER_GETHASH ) ) {
READWRITE ( vchSig ) ;
}
2018-09-28 09:56:17 +02:00
if ( s . GetType ( ) & SER_DISK ) {
2016-11-24 19:12:05 +01:00
// Only include these for the disk file format
LogPrint ( " gobject " , " CGovernanceObject::SerializationOp Reading/writing votes from/to disk \n " ) ;
2017-02-17 01:48:42 +01:00
READWRITE ( nDeletionTime ) ;
READWRITE ( fExpired ) ;
2016-11-24 19:12:05 +01:00
READWRITE ( mapCurrentMNVotes ) ;
READWRITE ( fileVotes ) ;
LogPrint ( " gobject " , " CGovernanceObject::SerializationOp hash = %s, vote count = %d \n " , GetHash ( ) . ToString ( ) , fileVotes . GetVoteCount ( ) ) ;
}
// AFTER DESERIALIZATION OCCURS, CACHED VARIABLES MUST BE CALCULATED MANUALLY
}
private :
// FUNCTIONS FOR DEALING WITH DATA STRING
void LoadData ( ) ;
void GetData ( UniValue & objResult ) ;
bool ProcessVote ( CNode * pfrom ,
2018-09-28 09:56:17 +02:00
const CGovernanceVote & vote ,
CGovernanceException & exception ,
CConnman & connman ) ;
2016-11-24 19:12:05 +01:00
/// Called when MN's which have voted on this object have been removed
void ClearMasternodeVotes ( ) ;
2017-09-19 16:51:38 +02:00
void CheckOrphanVotes ( CConnman & connman ) ;
2018-11-29 19:51:53 +01:00
// TODO can be removed after DIP3 is fully deployed
std : : vector < uint256 > RemoveOldVotes ( unsigned int nMinTime ) ;
2016-11-24 19:12:05 +01:00
} ;
# endif