Refactored masternode payments system
- Replaced coinbase cache in favor of using the masternode payments voting system only - Syncing masternode payments now supports up to the syncing the entire payment list
This commit is contained in:
parent
d193cc2d91
commit
37f55a3181
@ -91,7 +91,6 @@ BITCOIN_CORE_H = \
|
||||
primitives/block.h \
|
||||
primitives/transaction.h \
|
||||
core_io.h \
|
||||
coinbase-payee.h \
|
||||
crypter.h \
|
||||
darksend.h \
|
||||
darksend-relay.h \
|
||||
@ -178,7 +177,6 @@ libbitcoin_server_a_SOURCES = \
|
||||
addrman.cpp \
|
||||
alert.cpp \
|
||||
bloom.cpp \
|
||||
coinbase-payee.cpp \
|
||||
chain.cpp \
|
||||
checkpoints.cpp \
|
||||
init.cpp \
|
||||
@ -279,7 +277,6 @@ libbitcoin_common_a_SOURCES = \
|
||||
allocators.cpp \
|
||||
amount.cpp \
|
||||
base58.cpp \
|
||||
coinbase-payee.cpp \
|
||||
chainparams.cpp \
|
||||
darksend.cpp \
|
||||
darksend-relay.cpp \
|
||||
|
@ -4,7 +4,6 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "chain.h"
|
||||
#include "coinbase-payee.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -1,273 +0,0 @@
|
||||
// Copyright (c) 2014-2015 The Dash developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "coinbase-payee.h"
|
||||
#include "util.h"
|
||||
#include "addrman.h"
|
||||
#include "masternode.h"
|
||||
#include "darksend.h"
|
||||
#include "masternodeman.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
CCoinbasePayee coinbasePayee;
|
||||
|
||||
//
|
||||
// CCoinbasePayeeDB
|
||||
//
|
||||
|
||||
CCoinbasePayeeDB::CCoinbasePayeeDB()
|
||||
{
|
||||
pathDB = GetDataDir() / "coinbase-payee.dat";
|
||||
strMagicMessage = "CoinbasePayeeDB";
|
||||
}
|
||||
|
||||
bool CCoinbasePayeeDB::Write(const CCoinbasePayee& objToSave)
|
||||
{
|
||||
int64_t nStart = GetTimeMillis();
|
||||
|
||||
// serialize, checksum data up to that point, then append checksum
|
||||
CDataStream ssObj(SER_DISK, CLIENT_VERSION);
|
||||
ssObj << strMagicMessage; // coinbase payee cache file specific magic message
|
||||
ssObj << FLATDATA(Params().MessageStart()); // network specific magic number
|
||||
ssObj << objToSave;
|
||||
uint256 hash = Hash(ssObj.begin(), ssObj.end());
|
||||
ssObj << hash;
|
||||
|
||||
// open output file, and associate with CAutoFile
|
||||
FILE *file = fopen(pathDB.string().c_str(), "wb");
|
||||
CAutoFile fileout(file, SER_DISK, CLIENT_VERSION);
|
||||
if (fileout.IsNull())
|
||||
return error("%s : Failed to open file %s", __func__, pathDB.string());
|
||||
|
||||
// Write and commit header, data
|
||||
try {
|
||||
fileout << ssObj;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
return error("%s : Serialize or I/O error - %s", __func__, e.what());
|
||||
}
|
||||
fileout.fclose();
|
||||
|
||||
LogPrintf("Written info to coinbase-payee.dat %dms\n", GetTimeMillis() - nStart);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CCoinbasePayeeDB::ReadResult CCoinbasePayeeDB::Read(CCoinbasePayee& objToLoad)
|
||||
{
|
||||
|
||||
int64_t nStart = GetTimeMillis();
|
||||
// open input file, and associate with CAutoFile
|
||||
FILE *file = fopen(pathDB.string().c_str(), "rb");
|
||||
CAutoFile filein(file, SER_DISK, CLIENT_VERSION);
|
||||
if (filein.IsNull())
|
||||
{
|
||||
error("%s : Failed to open file %s", __func__, pathDB.string());
|
||||
return FileError;
|
||||
}
|
||||
|
||||
// use file size to size memory buffer
|
||||
int fileSize = boost::filesystem::file_size(pathDB);
|
||||
int dataSize = fileSize - sizeof(uint256);
|
||||
// Don't try to resize to a negative number if file is small
|
||||
if (dataSize < 0)
|
||||
dataSize = 0;
|
||||
vector<unsigned char> vchData;
|
||||
vchData.resize(dataSize);
|
||||
uint256 hashIn;
|
||||
|
||||
// read data and checksum from file
|
||||
try {
|
||||
filein.read((char *)&vchData[0], dataSize);
|
||||
filein >> hashIn;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
error("%s : Deserialize or I/O error - %s", __func__, e.what());
|
||||
return HashReadError;
|
||||
}
|
||||
filein.fclose();
|
||||
|
||||
CDataStream ssObj(vchData, SER_DISK, CLIENT_VERSION);
|
||||
|
||||
// verify stored checksum matches input data
|
||||
uint256 hashTmp = Hash(ssObj.begin(), ssObj.end());
|
||||
if (hashIn != hashTmp)
|
||||
{
|
||||
error("%s : Checksum mismatch, data corrupted", __func__);
|
||||
return IncorrectHash;
|
||||
}
|
||||
|
||||
|
||||
unsigned char pchMsgTmp[4];
|
||||
std::string strMagicMessageTmp;
|
||||
try {
|
||||
// de-serialize file header (coinbase payee cache file specific magic message) and ..
|
||||
ssObj >> strMagicMessageTmp;
|
||||
|
||||
// ... verify the message matches predefined one
|
||||
if (strMagicMessage != strMagicMessageTmp)
|
||||
{
|
||||
error("%s : Invalid coinbase payee cache magic message", __func__);
|
||||
return IncorrectMagicMessage;
|
||||
}
|
||||
|
||||
|
||||
// de-serialize file header (network specific magic number) and ..
|
||||
ssObj >> FLATDATA(pchMsgTmp);
|
||||
|
||||
// ... verify the network matches ours
|
||||
if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp)))
|
||||
{
|
||||
error("%s : Invalid network magic number", __func__);
|
||||
return IncorrectMagicNumber;
|
||||
}
|
||||
|
||||
// de-serialize data into CCoinbasePayee object
|
||||
ssObj >> objToLoad;
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
objToLoad.Clear();
|
||||
error("%s : Deserialize or I/O error - %s", __func__, e.what());
|
||||
return IncorrectFormat;
|
||||
}
|
||||
|
||||
|
||||
objToLoad.CleanUp(); // clean out expired
|
||||
LogPrintf("Loaded info from coinbase-payee.dat %dms\n", GetTimeMillis() - nStart);
|
||||
LogPrintf(" %s\n", objToLoad.ToString());
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
void DumpCoinbasePayees()
|
||||
{
|
||||
return; //disable the cache
|
||||
|
||||
int64_t nStart = GetTimeMillis();
|
||||
|
||||
CCoinbasePayeeDB mndb;
|
||||
CCoinbasePayee temp;
|
||||
|
||||
LogPrintf("Verifying coinbase-payee.dat format...\n");
|
||||
CCoinbasePayeeDB::ReadResult readResult = mndb.Read(temp);
|
||||
// there was an error and it was not an error on file openning => do not proceed
|
||||
if (readResult == CCoinbasePayeeDB::FileError)
|
||||
LogPrintf("Missing payees cache file - coinbase-payee.dat, will try to recreate\n");
|
||||
else if (readResult != CCoinbasePayeeDB::Ok)
|
||||
{
|
||||
LogPrintf("Error reading coinbase-payee.dat: ");
|
||||
if(readResult == CCoinbasePayeeDB::IncorrectFormat)
|
||||
LogPrintf("magic is ok but data has invalid format, will try to recreate\n");
|
||||
else
|
||||
{
|
||||
LogPrintf("file format is unknown or invalid, please fix it manually\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
LogPrintf("Writting info to coinbase-payee.dat...\n");
|
||||
mndb.Write(coinbasePayee);
|
||||
|
||||
LogPrintf("Coinbase payee dump finished %dms\n", GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
void CCoinbasePayee::BuildIndex(bool bForced)
|
||||
{
|
||||
if(mapPaidTime.size() > 0 && !bForced) {
|
||||
LogPrintf("CCoinbasePayee::BuildIndex - coinbase cache exists, skipping BuildIndex\n");
|
||||
return;
|
||||
} else if(bForced) {
|
||||
if(fDebug) LogPrintf("CCoinbasePayee::BuildIndex - Rebuilding coinbase cache\n");
|
||||
mapPaidTime.clear();
|
||||
}
|
||||
|
||||
//scan last 30 days worth of blocks, run processBlockCoinbaseTX for each
|
||||
|
||||
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||
int count = 0;
|
||||
|
||||
for (unsigned int i = 1; pindexPrev && pindexPrev->nHeight > 0; i++) {
|
||||
count++;
|
||||
if(count > 18000) return;
|
||||
|
||||
CBlock block;
|
||||
if (ReadBlockFromDisk(block, pindexPrev)) {
|
||||
ProcessBlockCoinbaseTX(block.vtx[0], block.nTime);
|
||||
}
|
||||
|
||||
if (pindexPrev->pprev == NULL) { assert(pindexPrev); break; }
|
||||
pindexPrev = pindexPrev->pprev;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Reprocess the last 120 blocks and overwrite the lastpaid times (incase we switch chains)
|
||||
// TODO : Keep track of the block hashes and reprocess until we find one we've processed
|
||||
void CCoinbasePayee::ReprocessChain()
|
||||
{
|
||||
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||
int count = 0;
|
||||
|
||||
for (unsigned int i = 1; pindexPrev && pindexPrev->nHeight > 0; i++) {
|
||||
count++;
|
||||
if(count > 120) return;
|
||||
|
||||
CBlock block;
|
||||
if (ReadBlockFromDisk(block, pindexPrev)) {
|
||||
ProcessBlockCoinbaseTX(block.vtx[0], block.nTime, true);
|
||||
}
|
||||
|
||||
if (pindexPrev->pprev == NULL) { assert(pindexPrev); break; }
|
||||
pindexPrev = pindexPrev->pprev;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void CCoinbasePayee::ProcessBlockCoinbaseTX(CTransaction& txCoinbase, int64_t nTime, bool fOverwrite)
|
||||
{
|
||||
if (!txCoinbase.IsCoinBase()){
|
||||
LogPrintf("ERROR: CCoinbasePayee::ProcessBlockCoinbaseTX - tx is not coinbase\n");
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(CTxOut out, txCoinbase.vout){
|
||||
uint256 h = GetScriptHash(out.scriptPubKey);
|
||||
if(fDebug) LogPrintf("CCoinbasePayee::ProcessBlockCoinbaseTX - %s - %d\n", h.ToString(), nTime);
|
||||
if(mapPaidTime.count(h)){
|
||||
if(mapPaidTime[h] < nTime || fOverwrite) {
|
||||
mapPaidTime[h] = nTime;
|
||||
} else {
|
||||
if(fDebug) LogPrintf("CCoinbasePayee::ProcessBlockCoinbaseTX - not updated -- %s - %d\n", h.ToString(), nTime);
|
||||
}
|
||||
} else {
|
||||
mapPaidTime[h] = nTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t CCoinbasePayee::GetLastPaid(CScript& pubkey)
|
||||
{
|
||||
uint256 h = GetScriptHash(pubkey);
|
||||
|
||||
if(mapPaidTime.count(h)){
|
||||
return mapPaidTime[h];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CCoinbasePayee::CleanUp()
|
||||
{
|
||||
// std::map<uint256, int64_t>::iterator it = mapPaidTime.begin();
|
||||
// while(it != mapPaidTime.end())
|
||||
// {
|
||||
// //keep 30 days of history
|
||||
// if((*it).second < GetAdjustedTime() - (60*60*24*30)) {
|
||||
// mapPaidTime.erase(it++);
|
||||
// } else {
|
||||
// ++it;
|
||||
// }
|
||||
// }
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
// Copyright (c) 2014-2015 The Dash developers
|
||||
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#ifndef MASTERNODE_LASTPAID_H
|
||||
#define MASTERNODE_LASTPAID_H
|
||||
|
||||
#include "main.h"
|
||||
#include "sync.h"
|
||||
#include "net.h"
|
||||
#include "key.h"
|
||||
#include "util.h"
|
||||
#include "base58.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class CCoinbasePayee;
|
||||
|
||||
extern CCoinbasePayee coinbasePayee;
|
||||
|
||||
void DumpCoinbasePayees();
|
||||
|
||||
/** Save Budget Manager (coinbase-payee.dat)
|
||||
*/
|
||||
class CCoinbasePayeeDB
|
||||
{
|
||||
private:
|
||||
boost::filesystem::path pathDB;
|
||||
std::string strMagicMessage;
|
||||
public:
|
||||
enum ReadResult {
|
||||
Ok,
|
||||
FileError,
|
||||
HashReadError,
|
||||
IncorrectHash,
|
||||
IncorrectMagicMessage,
|
||||
IncorrectMagicNumber,
|
||||
IncorrectFormat
|
||||
};
|
||||
|
||||
CCoinbasePayeeDB();
|
||||
bool Write(const CCoinbasePayee &objToSave);
|
||||
ReadResult Read(CCoinbasePayee& objToLoad);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Coinbase Payee : Keep track of the last time addresses were paid up to a few weeks (used for masternode payments)
|
||||
//
|
||||
class CCoinbasePayee
|
||||
{
|
||||
private:
|
||||
// critical section to protect the inner data structures
|
||||
mutable CCriticalSection cs;
|
||||
|
||||
uint256 GetScriptHash(CScript& pubkey){
|
||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||
ss << pubkey;
|
||||
uint256 h1 = ss.GetHash();
|
||||
return h1;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
map<uint256, int64_t> mapPaidTime;
|
||||
|
||||
CCoinbasePayee() {
|
||||
mapPaidTime.clear();
|
||||
}
|
||||
|
||||
void BuildIndex(bool bForced=false);
|
||||
void ReprocessChain();
|
||||
void ProcessBlockCoinbaseTX(CTransaction& txCoinbase, int64_t nTime, bool fOverwrite=false);
|
||||
int64_t GetLastPaid(CScript& pubkey);
|
||||
void CleanUp();
|
||||
|
||||
void Clear(){
|
||||
LogPrintf("CoinbasePayee object cleared\n");
|
||||
mapPaidTime.clear();
|
||||
}
|
||||
std::string ToString() {
|
||||
std::string strMessage = boost::lexical_cast<std::string>((int)mapPaidTime.size()) + " objects";
|
||||
|
||||
return strMessage;
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
//for saving to the serialized db
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
READWRITE(mapPaidTime);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
20
src/init.cpp
20
src/init.cpp
@ -13,7 +13,6 @@
|
||||
#include "addrman.h"
|
||||
#include "amount.h"
|
||||
#include "checkpoints.h"
|
||||
#include "coinbase-payee.h"
|
||||
#include "compat/sanity.h"
|
||||
#include "key.h"
|
||||
#include "main.h"
|
||||
@ -172,7 +171,6 @@ void PrepareShutdown()
|
||||
StopNode();
|
||||
DumpMasternodes();
|
||||
DumpBudgets();
|
||||
DumpCoinbasePayees();
|
||||
UnregisterNodeSignals(GetNodeSignals());
|
||||
|
||||
if (fFeeEstimatesInitialized)
|
||||
@ -1437,22 +1435,6 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
LogPrintf("file format is unknown or invalid, please fix it manually\n");
|
||||
}
|
||||
|
||||
// Disable loading the coinbase cache
|
||||
// CCoinbasePayeeDB payeedb;
|
||||
// CCoinbasePayeeDB::ReadResult readResult3 = payeedb.Read(coinbasePayee);
|
||||
|
||||
// if (readResult3 == CCoinbasePayeeDB::FileError)
|
||||
// LogPrintf("Missing payee cache - coinbase-payee.dat, will try to recreate\n");
|
||||
// else if (readResult3 != CCoinbasePayeeDB::Ok)
|
||||
// {
|
||||
// LogPrintf("Error reading coinbase-payee.dat: ");
|
||||
// if(readResult3 == CCoinbasePayeeDB::IncorrectFormat)
|
||||
// LogPrintf("magic is ok but data has invalid format, will try to recreate\n");
|
||||
// else
|
||||
// LogPrintf("file format is unknown or invalid, please fix it manually\n");
|
||||
// }
|
||||
|
||||
|
||||
fMasterNode = GetBoolArg("-masternode", false);
|
||||
|
||||
if((fMasterNode || masternodeConfig.getCount() > -1) && fTxIndex == false) {
|
||||
@ -1564,8 +1546,6 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
*/
|
||||
|
||||
darkSendPool.InitCollateralAddress();
|
||||
coinbasePayee.BuildIndex(true);
|
||||
coinbasePayee.ReprocessChain();
|
||||
|
||||
threadGroup.create_thread(boost::bind(&ThreadCheckDarkSendPool));
|
||||
|
||||
|
@ -27,7 +27,7 @@ class CConsensusVote;
|
||||
class CTransaction;
|
||||
class CTransactionLock;
|
||||
|
||||
static const int MIN_INSTANTX_PROTO_VERSION = 70092;
|
||||
static const int MIN_INSTANTX_PROTO_VERSION = 70093;
|
||||
|
||||
extern map<uint256, CTransaction> mapTxLockReq;
|
||||
extern map<uint256, CTransaction> mapTxLockReqRejected;
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "chainparams.h"
|
||||
#include "checkpoints.h"
|
||||
#include "checkqueue.h"
|
||||
#include "coinbase-payee.h"
|
||||
#include "init.h"
|
||||
#include "instantx.h"
|
||||
#include "darksend.h"
|
||||
@ -3264,7 +3263,6 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
|
||||
if (masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_LIST) {
|
||||
CScript payee;
|
||||
CTxIn vin;
|
||||
coinbasePayee.ReprocessChain();
|
||||
darkSendPool.NewBlock();
|
||||
masternodePayments.ProcessBlock(GetHeight()+10);
|
||||
if (masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_BUDGET)
|
||||
|
@ -176,6 +176,9 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
|
||||
if (strCommand == "mnget") { //Masternode Payments Request Sync
|
||||
if(fLiteMode) return; //disable all Darksend/Masternode related functionality
|
||||
|
||||
int nCountNeeded;
|
||||
vRecv >> nCountNeeded;
|
||||
|
||||
if(pfrom->HasFulfilledRequest("mnget")) {
|
||||
LogPrintf("mnget - peer already asked me for the list\n");
|
||||
Misbehaving(pfrom->GetId(), 20);
|
||||
@ -183,7 +186,7 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
|
||||
}
|
||||
|
||||
pfrom->FulfilledRequest("mnget");
|
||||
masternodePayments.Sync(pfrom);
|
||||
masternodePayments.Sync(pfrom, nCountNeeded);
|
||||
LogPrintf("mnget - Sent Masternode winners to %s\n", pfrom->addr.ToString().c_str());
|
||||
}
|
||||
else if (strCommand == "mnw") { //Masternode Payments Declare Winner
|
||||
@ -200,8 +203,9 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
|
||||
return;
|
||||
}
|
||||
|
||||
if(winner.nBlockHeight < chainActive.Tip()->nHeight - 10 || winner.nBlockHeight > chainActive.Tip()->nHeight+20){
|
||||
LogPrintf("mnw - winner out of range - Height %d bestHeight %d\n", winner.nBlockHeight, chainActive.Tip()->nHeight);
|
||||
int nFirstBlock = (masternodeSync.IsSynced() ? (chainActive.Tip()->nHeight - (mnodeman.CountEnabled()*1.1)) : chainActive.Tip()->nHeight - 10);
|
||||
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > chainActive.Tip()->nHeight+20){
|
||||
LogPrintf("mnw - winner out of range - FirstBlock %d Height %d bestHeight %d\n", nFirstBlock, winner.nBlockHeight, chainActive.Tip()->nHeight);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -270,7 +274,7 @@ bool CMasternodePayments::IsScheduled(CMasternode& mn, int nNotBlockHeight)
|
||||
mnpayee = GetScriptForDestination(mn.pubkey.GetID());
|
||||
|
||||
CScript payee;
|
||||
for(int64_t h = pindexPrev->nHeight; h <= pindexPrev->nHeight+10; h++){
|
||||
for(int64_t h = pindexPrev->nHeight-1; h <= pindexPrev->nHeight+11; h++){
|
||||
if(h == nNotBlockHeight) continue;
|
||||
if(mapMasternodeBlocks.count(h)){
|
||||
if(mapMasternodeBlocks[h].GetPayee(payee)){
|
||||
@ -548,7 +552,6 @@ bool CMasternodePaymentWinner::SignatureValid()
|
||||
boost::lexical_cast<std::string>(nBlockHeight) +
|
||||
payee.ToString();
|
||||
|
||||
|
||||
std::string errorMessage = "";
|
||||
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)){
|
||||
return error("CMasternodePaymentWinner::SignatureValid() - Got bad Masternode address signature %s \n", vinMasternode.ToString().c_str());
|
||||
@ -560,16 +563,19 @@ bool CMasternodePaymentWinner::SignatureValid()
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMasternodePayments::Sync(CNode* node)
|
||||
void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
|
||||
{
|
||||
LOCK(cs_masternodepayments);
|
||||
|
||||
if(chainActive.Tip() == NULL) return;
|
||||
|
||||
int nCount = (mnodeman.CountEnabled()*1.1);
|
||||
if(nCountNeeded > nCount) nCountNeeded = nCount;
|
||||
|
||||
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
|
||||
while(it != mapMasternodePayeeVotes.end()) {
|
||||
CMasternodePaymentWinner winner = (*it).second;
|
||||
if(winner.nBlockHeight >= chainActive.Tip()->nHeight-10 && winner.nBlockHeight <= chainActive.Tip()->nHeight + 20)
|
||||
if(winner.nBlockHeight >= chainActive.Tip()->nHeight-nCountNeeded && winner.nBlockHeight <= chainActive.Tip()->nHeight + 20)
|
||||
node->PushMessage("mnw", winner);
|
||||
++it;
|
||||
}
|
||||
|
@ -97,6 +97,15 @@ public:
|
||||
return (nVotes > -1);
|
||||
}
|
||||
|
||||
bool HasPayeeWithVotes(CScript payee, int nVotesReq)
|
||||
{
|
||||
BOOST_FOREACH(CMasternodePayee& p, vecPayments){
|
||||
if(p.nVotes > nVotesReq && p.scriptPubKey == payee) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsTransactionValid(const CTransaction& txNew);
|
||||
std::string GetRequiredPaymentsString();
|
||||
|
||||
@ -191,7 +200,7 @@ public:
|
||||
bool AddWinningMasternode(CMasternodePaymentWinner& winner);
|
||||
bool ProcessBlock(int nBlockHeight);
|
||||
|
||||
void Sync(CNode* node);
|
||||
void Sync(CNode* node, int nCountNeeded);
|
||||
void CleanPaymentList();
|
||||
int LastPayment(CMasternode& mn);
|
||||
|
||||
|
@ -153,7 +153,8 @@ void CMasternodeSync::Process()
|
||||
|
||||
if((lastMasternodeWinner == 0 || lastMasternodeWinner > GetTime() - MASTERNODE_SYNC_TIMEOUT)
|
||||
&& RequestedMasternodeAttempt <= 2){
|
||||
pnode->PushMessage("mnget"); //sync payees
|
||||
int nCountNeeded = (mnodeman.CountEnabled()*1.1);
|
||||
pnode->PushMessage("mnget", nCountNeeded); //sync payees
|
||||
RequestedMasternodeAttempt++;
|
||||
}
|
||||
return;
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "masternode.h"
|
||||
#include "masternodeman.h"
|
||||
#include "coinbase-payee.h"
|
||||
#include "darksend.h"
|
||||
#include "util.h"
|
||||
#include "sync.h"
|
||||
@ -210,7 +209,7 @@ int64_t CMasternode::SecondsSincePayment() {
|
||||
CScript pubkeyScript;
|
||||
pubkeyScript = GetScriptForDestination(pubkey.GetID());
|
||||
|
||||
int64_t sec = (GetAdjustedTime() - coinbasePayee.GetLastPaid(pubkeyScript));
|
||||
int64_t sec = (GetAdjustedTime() - GetLastPaid());
|
||||
int64_t month = 60*60*24*30;
|
||||
if(sec < month) return sec; //if it's less than 30 days, give seconds
|
||||
|
||||
@ -224,10 +223,26 @@ int64_t CMasternode::SecondsSincePayment() {
|
||||
}
|
||||
|
||||
int64_t CMasternode::GetLastPaid() {
|
||||
CScript pubkeyScript;
|
||||
pubkeyScript = GetScriptForDestination(pubkey.GetID());
|
||||
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||
if(pindexPrev == NULL) return false;
|
||||
|
||||
return coinbasePayee.GetLastPaid(pubkeyScript);
|
||||
CScript mnpayee;
|
||||
mnpayee = GetScriptForDestination(pubkey.GetID());
|
||||
|
||||
for(int64_t h = pindexPrev->nHeight-mnodeman.CountEnabled()*0.95; h <= pindexPrev->nHeight+10; h++){
|
||||
if(mapMasternodeBlocks.count(h)){
|
||||
/*
|
||||
Search for this payee, with at least 2 votes. This will aid in consensus allowing the network
|
||||
to converge on the same payees quickly, then keep the same schedule.
|
||||
*/
|
||||
if(mapMasternodeBlocks[h].HasPayeeWithVotes(mnpayee, 2)){
|
||||
int64_t nTimeEstimate = pindexPrev->nTime - (pindexPrev->nHeight - h)*2.6;
|
||||
return nTimeEstimate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMasternodeBroadcast::CMasternodeBroadcast()
|
||||
|
@ -450,9 +450,15 @@ Value masternode(const Array& params, bool fHelp)
|
||||
|
||||
if (strCommand == "winners")
|
||||
{
|
||||
int nLast = 10;
|
||||
|
||||
if (params.size() >= 2){
|
||||
nLast = params[1].get_int();
|
||||
}
|
||||
|
||||
Object obj;
|
||||
|
||||
for(int nHeight = chainActive.Tip()->nHeight-10; nHeight < chainActive.Tip()->nHeight+20; nHeight++)
|
||||
for(int nHeight = chainActive.Tip()->nHeight-nLast; nHeight < chainActive.Tip()->nHeight+20; nHeight++)
|
||||
{
|
||||
obj.push_back(Pair(strprintf("%d", nHeight), GetRequiredPaymentsString(nHeight)));
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
* network protocol versioning
|
||||
*/
|
||||
|
||||
static const int PROTOCOL_VERSION = 70092;
|
||||
static const int PROTOCOL_VERSION = 70093;
|
||||
|
||||
//! initial proto version, to be increased after version/verack negotiation
|
||||
static const int INIT_PROTO_VERSION = 209;
|
||||
@ -22,16 +22,16 @@ static const int GETHEADERS_VERSION = 70077;
|
||||
static const int MIN_PEER_PROTO_VERSION = 70066;
|
||||
|
||||
//! minimum peer version accepted by DarksendPool
|
||||
static const int MIN_POOL_PEER_PROTO_VERSION = 70092;
|
||||
static const int MIN_POOL_PEER_PROTO_VERSION = 70093;
|
||||
|
||||
//! minimum peer version for masternode budgets
|
||||
static const int MIN_BUDGET_PEER_PROTO_VERSION = 70092;
|
||||
static const int MIN_BUDGET_PEER_PROTO_VERSION = 70093;
|
||||
|
||||
//! minimum peer version that can receive masternode payments
|
||||
// V1 - Last protocol version before update
|
||||
// V2 - Newest protocol version
|
||||
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70066;
|
||||
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70092;
|
||||
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70093;
|
||||
|
||||
//! nTime field added to CAddress, starting with this version;
|
||||
//! if possible, avoid requesting addresses nodes older than this
|
||||
|
Loading…
Reference in New Issue
Block a user