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/block.h \
|
||||||
primitives/transaction.h \
|
primitives/transaction.h \
|
||||||
core_io.h \
|
core_io.h \
|
||||||
coinbase-payee.h \
|
|
||||||
crypter.h \
|
crypter.h \
|
||||||
darksend.h \
|
darksend.h \
|
||||||
darksend-relay.h \
|
darksend-relay.h \
|
||||||
@ -178,7 +177,6 @@ libbitcoin_server_a_SOURCES = \
|
|||||||
addrman.cpp \
|
addrman.cpp \
|
||||||
alert.cpp \
|
alert.cpp \
|
||||||
bloom.cpp \
|
bloom.cpp \
|
||||||
coinbase-payee.cpp \
|
|
||||||
chain.cpp \
|
chain.cpp \
|
||||||
checkpoints.cpp \
|
checkpoints.cpp \
|
||||||
init.cpp \
|
init.cpp \
|
||||||
@ -279,7 +277,6 @@ libbitcoin_common_a_SOURCES = \
|
|||||||
allocators.cpp \
|
allocators.cpp \
|
||||||
amount.cpp \
|
amount.cpp \
|
||||||
base58.cpp \
|
base58.cpp \
|
||||||
coinbase-payee.cpp \
|
|
||||||
chainparams.cpp \
|
chainparams.cpp \
|
||||||
darksend.cpp \
|
darksend.cpp \
|
||||||
darksend-relay.cpp \
|
darksend-relay.cpp \
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "chain.h"
|
#include "chain.h"
|
||||||
#include "coinbase-payee.h"
|
|
||||||
|
|
||||||
using namespace std;
|
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 "addrman.h"
|
||||||
#include "amount.h"
|
#include "amount.h"
|
||||||
#include "checkpoints.h"
|
#include "checkpoints.h"
|
||||||
#include "coinbase-payee.h"
|
|
||||||
#include "compat/sanity.h"
|
#include "compat/sanity.h"
|
||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
@ -172,7 +171,6 @@ void PrepareShutdown()
|
|||||||
StopNode();
|
StopNode();
|
||||||
DumpMasternodes();
|
DumpMasternodes();
|
||||||
DumpBudgets();
|
DumpBudgets();
|
||||||
DumpCoinbasePayees();
|
|
||||||
UnregisterNodeSignals(GetNodeSignals());
|
UnregisterNodeSignals(GetNodeSignals());
|
||||||
|
|
||||||
if (fFeeEstimatesInitialized)
|
if (fFeeEstimatesInitialized)
|
||||||
@ -1437,22 +1435,6 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||||||
LogPrintf("file format is unknown or invalid, please fix it manually\n");
|
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);
|
fMasterNode = GetBoolArg("-masternode", false);
|
||||||
|
|
||||||
if((fMasterNode || masternodeConfig.getCount() > -1) && fTxIndex == false) {
|
if((fMasterNode || masternodeConfig.getCount() > -1) && fTxIndex == false) {
|
||||||
@ -1564,8 +1546,6 @@ bool AppInit2(boost::thread_group& threadGroup)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
darkSendPool.InitCollateralAddress();
|
darkSendPool.InitCollateralAddress();
|
||||||
coinbasePayee.BuildIndex(true);
|
|
||||||
coinbasePayee.ReprocessChain();
|
|
||||||
|
|
||||||
threadGroup.create_thread(boost::bind(&ThreadCheckDarkSendPool));
|
threadGroup.create_thread(boost::bind(&ThreadCheckDarkSendPool));
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ class CConsensusVote;
|
|||||||
class CTransaction;
|
class CTransaction;
|
||||||
class CTransactionLock;
|
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> mapTxLockReq;
|
||||||
extern map<uint256, CTransaction> mapTxLockReqRejected;
|
extern map<uint256, CTransaction> mapTxLockReqRejected;
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "chainparams.h"
|
#include "chainparams.h"
|
||||||
#include "checkpoints.h"
|
#include "checkpoints.h"
|
||||||
#include "checkqueue.h"
|
#include "checkqueue.h"
|
||||||
#include "coinbase-payee.h"
|
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "instantx.h"
|
#include "instantx.h"
|
||||||
#include "darksend.h"
|
#include "darksend.h"
|
||||||
@ -3264,7 +3263,6 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis
|
|||||||
if (masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_LIST) {
|
if (masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_LIST) {
|
||||||
CScript payee;
|
CScript payee;
|
||||||
CTxIn vin;
|
CTxIn vin;
|
||||||
coinbasePayee.ReprocessChain();
|
|
||||||
darkSendPool.NewBlock();
|
darkSendPool.NewBlock();
|
||||||
masternodePayments.ProcessBlock(GetHeight()+10);
|
masternodePayments.ProcessBlock(GetHeight()+10);
|
||||||
if (masternodeSync.RequestedMasternodeAssets > MASTERNODE_SYNC_BUDGET)
|
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 (strCommand == "mnget") { //Masternode Payments Request Sync
|
||||||
if(fLiteMode) return; //disable all Darksend/Masternode related functionality
|
if(fLiteMode) return; //disable all Darksend/Masternode related functionality
|
||||||
|
|
||||||
|
int nCountNeeded;
|
||||||
|
vRecv >> nCountNeeded;
|
||||||
|
|
||||||
if(pfrom->HasFulfilledRequest("mnget")) {
|
if(pfrom->HasFulfilledRequest("mnget")) {
|
||||||
LogPrintf("mnget - peer already asked me for the list\n");
|
LogPrintf("mnget - peer already asked me for the list\n");
|
||||||
Misbehaving(pfrom->GetId(), 20);
|
Misbehaving(pfrom->GetId(), 20);
|
||||||
@ -183,7 +186,7 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
|
|||||||
}
|
}
|
||||||
|
|
||||||
pfrom->FulfilledRequest("mnget");
|
pfrom->FulfilledRequest("mnget");
|
||||||
masternodePayments.Sync(pfrom);
|
masternodePayments.Sync(pfrom, nCountNeeded);
|
||||||
LogPrintf("mnget - Sent Masternode winners to %s\n", pfrom->addr.ToString().c_str());
|
LogPrintf("mnget - Sent Masternode winners to %s\n", pfrom->addr.ToString().c_str());
|
||||||
}
|
}
|
||||||
else if (strCommand == "mnw") { //Masternode Payments Declare Winner
|
else if (strCommand == "mnw") { //Masternode Payments Declare Winner
|
||||||
@ -200,8 +203,9 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(winner.nBlockHeight < chainActive.Tip()->nHeight - 10 || winner.nBlockHeight > chainActive.Tip()->nHeight+20){
|
int nFirstBlock = (masternodeSync.IsSynced() ? (chainActive.Tip()->nHeight - (mnodeman.CountEnabled()*1.1)) : chainActive.Tip()->nHeight - 10);
|
||||||
LogPrintf("mnw - winner out of range - Height %d bestHeight %d\n", winner.nBlockHeight, chainActive.Tip()->nHeight);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +274,7 @@ bool CMasternodePayments::IsScheduled(CMasternode& mn, int nNotBlockHeight)
|
|||||||
mnpayee = GetScriptForDestination(mn.pubkey.GetID());
|
mnpayee = GetScriptForDestination(mn.pubkey.GetID());
|
||||||
|
|
||||||
CScript payee;
|
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(h == nNotBlockHeight) continue;
|
||||||
if(mapMasternodeBlocks.count(h)){
|
if(mapMasternodeBlocks.count(h)){
|
||||||
if(mapMasternodeBlocks[h].GetPayee(payee)){
|
if(mapMasternodeBlocks[h].GetPayee(payee)){
|
||||||
@ -548,7 +552,6 @@ bool CMasternodePaymentWinner::SignatureValid()
|
|||||||
boost::lexical_cast<std::string>(nBlockHeight) +
|
boost::lexical_cast<std::string>(nBlockHeight) +
|
||||||
payee.ToString();
|
payee.ToString();
|
||||||
|
|
||||||
|
|
||||||
std::string errorMessage = "";
|
std::string errorMessage = "";
|
||||||
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)){
|
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)){
|
||||||
return error("CMasternodePaymentWinner::SignatureValid() - Got bad Masternode address signature %s \n", vinMasternode.ToString().c_str());
|
return error("CMasternodePaymentWinner::SignatureValid() - Got bad Masternode address signature %s \n", vinMasternode.ToString().c_str());
|
||||||
@ -560,16 +563,19 @@ bool CMasternodePaymentWinner::SignatureValid()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMasternodePayments::Sync(CNode* node)
|
void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
|
||||||
{
|
{
|
||||||
LOCK(cs_masternodepayments);
|
LOCK(cs_masternodepayments);
|
||||||
|
|
||||||
if(chainActive.Tip() == NULL) return;
|
if(chainActive.Tip() == NULL) return;
|
||||||
|
|
||||||
|
int nCount = (mnodeman.CountEnabled()*1.1);
|
||||||
|
if(nCountNeeded > nCount) nCountNeeded = nCount;
|
||||||
|
|
||||||
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
|
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
|
||||||
while(it != mapMasternodePayeeVotes.end()) {
|
while(it != mapMasternodePayeeVotes.end()) {
|
||||||
CMasternodePaymentWinner winner = (*it).second;
|
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);
|
node->PushMessage("mnw", winner);
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
@ -97,6 +97,15 @@ public:
|
|||||||
return (nVotes > -1);
|
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);
|
bool IsTransactionValid(const CTransaction& txNew);
|
||||||
std::string GetRequiredPaymentsString();
|
std::string GetRequiredPaymentsString();
|
||||||
|
|
||||||
@ -191,7 +200,7 @@ public:
|
|||||||
bool AddWinningMasternode(CMasternodePaymentWinner& winner);
|
bool AddWinningMasternode(CMasternodePaymentWinner& winner);
|
||||||
bool ProcessBlock(int nBlockHeight);
|
bool ProcessBlock(int nBlockHeight);
|
||||||
|
|
||||||
void Sync(CNode* node);
|
void Sync(CNode* node, int nCountNeeded);
|
||||||
void CleanPaymentList();
|
void CleanPaymentList();
|
||||||
int LastPayment(CMasternode& mn);
|
int LastPayment(CMasternode& mn);
|
||||||
|
|
||||||
|
@ -153,7 +153,8 @@ void CMasternodeSync::Process()
|
|||||||
|
|
||||||
if((lastMasternodeWinner == 0 || lastMasternodeWinner > GetTime() - MASTERNODE_SYNC_TIMEOUT)
|
if((lastMasternodeWinner == 0 || lastMasternodeWinner > GetTime() - MASTERNODE_SYNC_TIMEOUT)
|
||||||
&& RequestedMasternodeAttempt <= 2){
|
&& RequestedMasternodeAttempt <= 2){
|
||||||
pnode->PushMessage("mnget"); //sync payees
|
int nCountNeeded = (mnodeman.CountEnabled()*1.1);
|
||||||
|
pnode->PushMessage("mnget", nCountNeeded); //sync payees
|
||||||
RequestedMasternodeAttempt++;
|
RequestedMasternodeAttempt++;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include "masternode.h"
|
#include "masternode.h"
|
||||||
#include "masternodeman.h"
|
#include "masternodeman.h"
|
||||||
#include "coinbase-payee.h"
|
|
||||||
#include "darksend.h"
|
#include "darksend.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
@ -210,7 +209,7 @@ int64_t CMasternode::SecondsSincePayment() {
|
|||||||
CScript pubkeyScript;
|
CScript pubkeyScript;
|
||||||
pubkeyScript = GetScriptForDestination(pubkey.GetID());
|
pubkeyScript = GetScriptForDestination(pubkey.GetID());
|
||||||
|
|
||||||
int64_t sec = (GetAdjustedTime() - coinbasePayee.GetLastPaid(pubkeyScript));
|
int64_t sec = (GetAdjustedTime() - GetLastPaid());
|
||||||
int64_t month = 60*60*24*30;
|
int64_t month = 60*60*24*30;
|
||||||
if(sec < month) return sec; //if it's less than 30 days, give seconds
|
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() {
|
int64_t CMasternode::GetLastPaid() {
|
||||||
CScript pubkeyScript;
|
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||||
pubkeyScript = GetScriptForDestination(pubkey.GetID());
|
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()
|
CMasternodeBroadcast::CMasternodeBroadcast()
|
||||||
|
@ -450,9 +450,15 @@ Value masternode(const Array& params, bool fHelp)
|
|||||||
|
|
||||||
if (strCommand == "winners")
|
if (strCommand == "winners")
|
||||||
{
|
{
|
||||||
|
int nLast = 10;
|
||||||
|
|
||||||
|
if (params.size() >= 2){
|
||||||
|
nLast = params[1].get_int();
|
||||||
|
}
|
||||||
|
|
||||||
Object obj;
|
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)));
|
obj.push_back(Pair(strprintf("%d", nHeight), GetRequiredPaymentsString(nHeight)));
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* network protocol versioning
|
* 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
|
//! initial proto version, to be increased after version/verack negotiation
|
||||||
static const int INIT_PROTO_VERSION = 209;
|
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;
|
static const int MIN_PEER_PROTO_VERSION = 70066;
|
||||||
|
|
||||||
//! minimum peer version accepted by DarksendPool
|
//! 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
|
//! 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
|
//! minimum peer version that can receive masternode payments
|
||||||
// V1 - Last protocol version before update
|
// V1 - Last protocol version before update
|
||||||
// V2 - Newest protocol version
|
// V2 - Newest protocol version
|
||||||
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70066;
|
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;
|
//! nTime field added to CAddress, starting with this version;
|
||||||
//! if possible, avoid requesting addresses nodes older than this
|
//! if possible, avoid requesting addresses nodes older than this
|
||||||
|
Loading…
Reference in New Issue
Block a user