Version 26 / New masternode consensus system
- Consensus system selects 1/10 of the oldest masternodes by payment, then selects payee by score from those. This fixes various race conditions when blocks are close together or inconsistant historical winner lists. - Ask for up to 2 cycles of history - Keep up to 5 cycles of history locally
This commit is contained in:
parent
cbe2bae130
commit
388f22c576
@ -3,7 +3,7 @@ AC_PREREQ([2.60])
|
||||
define(_CLIENT_VERSION_MAJOR, 0)
|
||||
define(_CLIENT_VERSION_MINOR, 12)
|
||||
define(_CLIENT_VERSION_REVISION, 0)
|
||||
define(_CLIENT_VERSION_BUILD, 25)
|
||||
define(_CLIENT_VERSION_BUILD, 26)
|
||||
define(_CLIENT_VERSION_IS_RELEASE, true)
|
||||
define(_COPYRIGHT_YEAR, 2015)
|
||||
AC_INIT([Dash Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@dashpay.io],[dash])
|
||||
|
@ -17,7 +17,7 @@
|
||||
#define CLIENT_VERSION_MAJOR 0
|
||||
#define CLIENT_VERSION_MINOR 12
|
||||
#define CLIENT_VERSION_REVISION 0
|
||||
#define CLIENT_VERSION_BUILD 25
|
||||
#define CLIENT_VERSION_BUILD 26
|
||||
|
||||
//! Set to true for release, false for prerelease or test build
|
||||
#define CLIENT_VERSION_IS_RELEASE true
|
||||
|
@ -27,7 +27,7 @@ class CConsensusVote;
|
||||
class CTransaction;
|
||||
class CTransactionLock;
|
||||
|
||||
static const int MIN_INSTANTX_PROTO_VERSION = 70093;
|
||||
static const int MIN_INSTANTX_PROTO_VERSION = 70094;
|
||||
|
||||
extern map<uint256, CTransaction> mapTxLockReq;
|
||||
extern map<uint256, CTransaction> mapTxLockReqRejected;
|
||||
|
@ -365,7 +365,7 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
|
||||
return;
|
||||
}
|
||||
|
||||
int nFirstBlock = (masternodeSync.IsSynced() ? (chainActive.Tip()->nHeight - (mnodeman.CountEnabled()*1.1)) : chainActive.Tip()->nHeight - 10);
|
||||
int nFirstBlock = chainActive.Tip()->nHeight - (mnodeman.CountEnabled()*2);
|
||||
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;
|
||||
@ -427,6 +427,8 @@ bool CMasternodePayments::GetBlockPayee(int nBlockHeight, CScript& payee)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is this masternode scheduled to get paid soon?
|
||||
// -- Only look ahead up to 7 blocks to allow for propagation
|
||||
bool CMasternodePayments::IsScheduled(CMasternode& mn, int nNotBlockHeight)
|
||||
{
|
||||
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||
@ -436,7 +438,7 @@ bool CMasternodePayments::IsScheduled(CMasternode& mn, int nNotBlockHeight)
|
||||
mnpayee = GetScriptForDestination(mn.pubkey.GetID());
|
||||
|
||||
CScript payee;
|
||||
for(int64_t h = pindexPrev->nHeight-1; h <= pindexPrev->nHeight+11; h++){
|
||||
for(int64_t h = pindexPrev->nHeight; h <= pindexPrev->nHeight+7; h++){
|
||||
if(h == nNotBlockHeight) continue;
|
||||
if(mapMasternodeBlocks.count(h)){
|
||||
if(mapMasternodeBlocks[h].GetPayee(payee)){
|
||||
@ -564,7 +566,8 @@ void CMasternodePayments::CleanPaymentList()
|
||||
|
||||
if(chainActive.Tip() == NULL) return;
|
||||
|
||||
int nLimit = std::max(((int)mnodeman.size())*2, 1000);
|
||||
//keep up to five cycles for historical sake
|
||||
int nLimit = std::max(((int)mnodeman.size())*5, 1000);
|
||||
|
||||
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
|
||||
while(it != mapMasternodePayeeVotes.end()) {
|
||||
@ -742,7 +745,7 @@ void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
|
||||
|
||||
if(chainActive.Tip() == NULL) return;
|
||||
|
||||
int nCount = (mnodeman.CountEnabled()*1.1);
|
||||
int nCount = (mnodeman.CountEnabled()*2);
|
||||
if(nCountNeeded > nCount) nCountNeeded = nCount;
|
||||
|
||||
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
|
||||
|
@ -174,7 +174,7 @@ void CMasternodeSync::Process()
|
||||
CBlockIndex* pindexPrev = chainActive.Tip();
|
||||
if(pindexPrev == NULL) return;
|
||||
|
||||
int nMnCount = mnodeman.CountEnabled()*1.1;
|
||||
int nMnCount = mnodeman.CountEnabled()*2;
|
||||
int nCountNeeded = (pindexPrev->nHeight - masternodePayments.GetNewestBlock());
|
||||
int nHaveBlocks = (pindexPrev->nHeight - masternodePayments.GetOldestBlock());
|
||||
if(nHaveBlocks < nMnCount || nCountNeeded > nMnCount) {
|
||||
|
@ -241,7 +241,7 @@ int64_t CMasternode::GetLastPaid() {
|
||||
|
||||
const CBlockIndex *BlockReading = chainActive.Tip();
|
||||
|
||||
int nMnCount = mnodeman.CountEnabled()*1.1;
|
||||
int nMnCount = mnodeman.CountEnabled()*2;
|
||||
int n = 0;
|
||||
for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) {
|
||||
if(n >= nMnCount){
|
||||
|
@ -29,6 +29,7 @@ struct CompareValueOnly
|
||||
return t1.first < t2.first;
|
||||
}
|
||||
};
|
||||
|
||||
struct CompareValueOnlyMN
|
||||
{
|
||||
bool operator()(const pair<int64_t, CMasternode>& t1,
|
||||
@ -384,11 +385,19 @@ CMasternode *CMasternodeMan::Find(const CPubKey &pubKeyMasternode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Deterministically select the oldest/best masternode to pay on the network
|
||||
//
|
||||
CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
CMasternode *pOldestMasternode = NULL;
|
||||
CMasternode *pBestMasternode = NULL;
|
||||
std::vector<pair<int64_t, CTxIn> > vecMasternodeLastPaid;
|
||||
|
||||
/*
|
||||
Make a vector with all of the last paid times
|
||||
*/
|
||||
|
||||
BOOST_FOREACH(CMasternode &mn, vMasternodes)
|
||||
{
|
||||
@ -398,18 +407,37 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight
|
||||
// //check protocol version
|
||||
if(mn.protocolVersion < masternodePayments.GetMinMasternodePaymentsProto()) continue;
|
||||
|
||||
//it's in the list -- so let's skip it
|
||||
//it's in the list (up to 7 entries ahead of current block to allow propagation) -- so let's skip it
|
||||
if(masternodePayments.IsScheduled(mn, nBlockHeight)) continue;
|
||||
|
||||
//make sure it has as many confirmations as there are masternodes
|
||||
if(mn.GetMasternodeInputAge() < CountEnabled()) continue;
|
||||
|
||||
if(pOldestMasternode == NULL || pOldestMasternode->SecondsSincePayment() < mn.SecondsSincePayment()){
|
||||
pOldestMasternode = &mn;
|
||||
}
|
||||
vecMasternodeLastPaid.push_back(make_pair(mn.SecondsSincePayment(), mn.vin));
|
||||
}
|
||||
|
||||
return pOldestMasternode;
|
||||
// Sort them low to high
|
||||
sort(vecMasternodeLastPaid.rbegin(), vecMasternodeLastPaid.rend(), CompareValueOnly());
|
||||
|
||||
// Look at 1/10 of the oldest nodes (by last payment), calculate their scores and pay the best one
|
||||
// -- This doesn't look at who is being paid in the +7-10 blocks, allowing for double payments very rarely
|
||||
// -- 1/100 payments should be a double payment on mainnet - (1/(3000/10))*3 --(chance per block * chances before IsScheduled will fire)
|
||||
int nTenthNetwork = mnodeman.CountEnabled()/10;
|
||||
int nCount = 0;
|
||||
uint256 nHigh = 0;
|
||||
BOOST_FOREACH (PAIRTYPE(int64_t, CTxIn)& s, vecMasternodeLastPaid){
|
||||
CMasternode* pmn = mnodeman.Find(s.second);
|
||||
if(!pmn) break;
|
||||
|
||||
uint256 n = pmn->CalculateScore(1, nBlockHeight-100);
|
||||
if(n > nHigh){
|
||||
nHigh = n;
|
||||
pBestMasternode = pmn;
|
||||
}
|
||||
nCount++;
|
||||
if(nCount >= nTenthNetwork) break;
|
||||
}
|
||||
return pBestMasternode;
|
||||
}
|
||||
|
||||
CMasternode *CMasternodeMan::FindRandom()
|
||||
@ -682,7 +710,6 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
|
||||
}
|
||||
}
|
||||
int64_t askAgain = GetTime() + MASTERNODES_DSEG_SECONDS;
|
||||
|
||||
mAskedUsForMasternodeList[pfrom->addr] = askAgain;
|
||||
}
|
||||
} //else, asking for a specific node which is ok
|
||||
|
@ -10,7 +10,7 @@
|
||||
* network protocol versioning
|
||||
*/
|
||||
|
||||
static const int PROTOCOL_VERSION = 70093;
|
||||
static const int PROTOCOL_VERSION = 70094;
|
||||
|
||||
//! initial proto version, to be increased after version/verack negotiation
|
||||
static const int INIT_PROTO_VERSION = 209;
|
||||
@ -22,19 +22,19 @@ 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 = 70093;
|
||||
static const int MIN_POOL_PEER_PROTO_VERSION = 70094;
|
||||
|
||||
//! minimum peer version for masternode budgets
|
||||
static const int MIN_BUDGET_PEER_PROTO_VERSION = 70093;
|
||||
static const int MIN_BUDGET_PEER_PROTO_VERSION = 70094;
|
||||
|
||||
//! minimum peer version for masternode winner broadcasts
|
||||
static const int MIN_MNW_PEER_PROTO_VERSION = 70093;
|
||||
static const int MIN_MNW_PEER_PROTO_VERSION = 70094;
|
||||
|
||||
//! 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 = 70093;
|
||||
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70094;
|
||||
|
||||
//! 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