// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef MASTERNODE_H #define MASTERNODE_H #include "bignum.h" #include "sync.h" #include "net.h" #include "key.h" #include "core.h" #include "util.h" #include "script.h" #include "base58.h" #include "main.h" class CMasterNode; class CMasternodePayments; #define MASTERNODE_NOT_PROCESSED 0 // initial state #define MASTERNODE_IS_CAPABLE 1 #define MASTERNODE_NOT_CAPABLE 2 #define MASTERNODE_STOPPED 3 #define MASTERNODE_INPUT_TOO_NEW 4 #define MASTERNODE_PORT_NOT_OPEN 6 #define MASTERNODE_PORT_OPEN 7 #define MASTERNODE_SYNC_IN_PROCESS 8 #define MASTERNODE_REMOTELY_ENABLED 9 #define MASTERNODE_MIN_CONFIRMATIONS 15 #define MASTERNODE_MIN_DSEEP_SECONDS (30*60) #define MASTERNODE_MIN_DSEE_SECONDS (5*60) #define MASTERNODE_PING_SECONDS (1*60) #define MASTERNODE_EXPIRATION_SECONDS (65*60) #define MASTERNODE_REMOVAL_SECONDS (70*60) using namespace std; extern std::vector vecMasternodes; extern CMasternodePayments masternodePayments; extern std::vector vecMasternodeAskedFor; extern map mapSeenMasternodeVotes; // manage the masternode connections void ProcessMasternodeConnections(); int CountMasternodesAboveProtocol(int protocolVersion); // Get the current winner for this block int GetCurrentMasterNode(int mod=1, int64_t nBlockHeight=0, int minProtocol=0); int GetMasternodeByVin(CTxIn& vin); int GetMasternodeRank(CTxIn& vin, int64_t nBlockHeight=0, int minProtocol=0); int GetMasternodeByRank(int findRank, int64_t nBlockHeight=0, int minProtocol=0); void ProcessMessageMasternode(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); // // The Masternode Class. For managing the darksend process. It contains the input of the 1000DRK, signature to prove // it's the one who own that ip address and code for calculating the payment election. // class CMasterNode { public: CService addr; CTxIn vin; int64_t lastTimeSeen; CPubKey pubkey; CPubKey pubkey2; std::vector sig; int64_t now; //dsee message times int64_t lastDseep; int cacheInputAge; int cacheInputAgeBlock; int enabled; bool unitTest; bool allowFreeTx; int protocolVersion; //the dsq count from the last dsq broadcast of this node int64_t nLastDsq; CMasterNode(CService newAddr, CTxIn newVin, CPubKey newPubkey, std::vector newSig, int64_t newNow, CPubKey newPubkey2, int protocolVersionIn) { addr = newAddr; vin = newVin; pubkey = newPubkey; pubkey2 = newPubkey2; sig = newSig; now = newNow; enabled = 1; lastTimeSeen = 0; unitTest = false; cacheInputAge = 0; cacheInputAgeBlock = 0; nLastDsq = 0; lastDseep = 0; allowFreeTx = true; protocolVersion = protocolVersionIn; } uint256 CalculateScore(int mod=1, int64_t nBlockHeight=0); void UpdateLastSeen(int64_t override=0) { if(override == 0){ lastTimeSeen = GetAdjustedTime(); } else { lastTimeSeen = override; } } inline uint64_t SliceHash(uint256& hash, int slice) { uint64_t n = 0; memcpy(&n, &hash+slice*64, 64); return n; } void Check(); bool UpdatedWithin(int seconds) { // LogPrintf("UpdatedWithin %d, %d -- %d \n", GetAdjustedTime() , lastTimeSeen, (GetAdjustedTime() - lastTimeSeen) < seconds); return (GetAdjustedTime() - lastTimeSeen) < seconds; } void Disable() { lastTimeSeen = 0; } bool IsEnabled() { return enabled == 1; } int GetMasternodeInputAge() { if(chainActive.Tip() == NULL) return 0; if(cacheInputAge == 0){ cacheInputAge = GetInputAge(vin); cacheInputAgeBlock = chainActive.Tip()->nHeight; } return cacheInputAge+(chainActive.Tip()->nHeight-cacheInputAgeBlock); } }; // for storing the winning payments class CMasternodePaymentWinner { public: int nBlockHeight; CTxIn vin; std::vector vchSig; uint64_t score; CMasternodePaymentWinner() { nBlockHeight = 0; score = 0; vin = CTxIn(); } uint256 GetHash(){ uint256 n2 = HashX11(BEGIN(nBlockHeight), END(nBlockHeight)); uint256 n3 = vin.prevout.hash > n2 ? (vin.prevout.hash - n2) : (n2 - vin.prevout.hash); return n3; } IMPLEMENT_SERIALIZE( READWRITE(nBlockHeight); READWRITE(score); READWRITE(vin); READWRITE(vchSig); ) }; // // Masternode Payments Class // Keeps track of who should get paid for which blocks // class CMasternodePayments { private: std::vector vWinning; int nSyncedFromPeer; std::string strMasterPrivKey; std::string strTestPubKey; std::string strMainPubKey; bool enabled; public: CMasternodePayments() { strMainPubKey = "04549ac134f694c0243f503e8c8a9a986f5de6610049c40b07816809b0d1d06a21b07be27b9bb555931773f62ba6cf35a25fd52f694d4e1106ccd237a7bb899fdd"; strTestPubKey = "046f78dcf911fbd61910136f7f0f8d90578f68d0b3ac973b5040fb7afb501b5939f39b108b0569dca71488f5bbf498d92e4d1194f6f941307ffd95f75e76869f0e"; enabled = false; } bool SetPrivKey(std::string strPrivKey); bool CheckSignature(CMasternodePaymentWinner& winner); bool Sign(CMasternodePaymentWinner& winner); // Deterministically calculate a given "score" for a masternode depending on how close it's hash is // to the blockHeight. The further away they are the better, the furthest will win the election // and get paid this block // uint64_t CalculateScore(uint256 blockHash, CTxIn& vin); bool GetWinningMasternode(int nBlockHeight, CTxIn& vinOut); bool AddWinningMasternode(CMasternodePaymentWinner& winner); bool ProcessBlock(int nBlockHeight); void Relay(CMasternodePaymentWinner& winner); void Sync(CNode* node); void CleanPaymentList(); int LastPayment(CMasterNode& mn); //slow bool GetBlockPayee(int nBlockHeight, CScript& payee); }; /*// // Masternode Scanning Error // Enforces proof-of-service by scanning the masternode network // class CMasternodePayments { private: std::vector vWinning; int nSyncedFromPeer; std::string strMasterPrivKey; std::string strTestPubKey; std::string strMainPubKey; public: CMasternodePayments() { strMainPubKey = "04549ac134f694c0243f503e8c8a9a986f5de6610049c40b07816809b0d1d06a21b07be27b9bb555931773f62ba6cf35a25fd52f694d4e1106ccd237a7bb899fdd"; strTestPubKey = "046f78dcf911fbd61910136f7f0f8d90578f68d0b3ac973b5040fb7afb501b5939f39b108b0569dca71488f5bbf498d92e4d1194f6f941307ffd95f75e76869f0e"; } bool SetPrivKey(std::string strPrivKey); bool CheckSignature(CMasternodePaymentWinner& winner); bool Sign(CMasternodePaymentWinner& winner); // Deterministically calculate a given "score" for a masternode depending on how close it's hash is // to the blockHeight. The further away they are the better, the furthest will win the election // and get paid this block // uint64_t CalculateScore(uint256 blockHash, CTxIn& vin); bool GetWinningMasternode(int nBlockHeight, CTxIn& vinOut); bool AddWinningMasternode(CMasternodePaymentWinner& winner); bool ProcessBlock(int nBlockHeight); void Relay(CMasternodePaymentWinner& winner); void Sync(CNode* node); void CleanPaymentList(); int LastPayment(CMasterNode& mn); //slow bool GetBlockPayee(int nBlockHeight, CScript& payee); };*/ #endif