dash/src/masternode.h
2015-01-20 03:02:11 -07:00

275 lines
7.9 KiB
C++

// 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<CMasterNode> vecMasternodes;
extern CMasternodePayments masternodePayments;
extern std::vector<CTxIn> vecMasternodeAskedFor;
extern map<uint256, int> 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<unsigned char> 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<unsigned char> 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<unsigned char> 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<CMasternodePaymentWinner> 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<CMasternodePaymentWinner> 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