Merge branch 'v0.12.0.x'

This commit is contained in:
Evan Duffield 2015-08-29 19:25:38 -07:00
commit afa37a8442
10 changed files with 90 additions and 167 deletions

View File

@ -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, 50)
define(_CLIENT_VERSION_BUILD, 51)
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])

View File

@ -5,6 +5,7 @@ EXTRA_LIBRARIES += qt/libbitcoinqt.a
QT_TS = \
qt/locale/dash_bg.ts \
qt/locale/dash_de.ts \
qt/locale/dash_en.ts \
qt/locale/dash_es.ts \
qt/locale/dash_fi.ts \
qt/locale/dash_fr.ts \

View File

@ -17,7 +17,7 @@
#define CLIENT_VERSION_MAJOR 0
#define CLIENT_VERSION_MINOR 12
#define CLIENT_VERSION_REVISION 0
#define CLIENT_VERSION_BUILD 50
#define CLIENT_VERSION_BUILD 51
//! Set to true for release, false for prerelease or test build
#define CLIENT_VERSION_IS_RELEASE true

View File

@ -169,9 +169,9 @@ void PrepareShutdown()
GenerateBitcoins(false, NULL, 0);
#endif
StopNode();
//DumpMasternodes();
//DumpBudgets();
//DumpMasternodePayments();
DumpMasternodes();
DumpBudgets();
DumpMasternodePayments();
UnregisterNodeSignals(GetNodeSignals());
if (fFeeEstimatesInitialized)
@ -1409,67 +1409,57 @@ bool AppInit2(boost::thread_group& threadGroup)
// ********************************************************* Step 10: setup DarkSend
uiInterface.InitMessage(_("Loading masternode cache..."));
CMasternodeDB mndb;
CMasternodeDB::ReadResult readResult = mndb.Read(mnodeman);
if (readResult == CMasternodeDB::FileError)
LogPrintf("Missing masternode cache file - mncache.dat, will try to recreate\n");
else if (readResult != CMasternodeDB::Ok)
{
LogPrintf("Error reading mncache.dat: ");
if(readResult == CMasternodeDB::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");
}
uiInterface.InitMessage(_("Loading budget cache..."));
CBudgetDB budgetdb;
CBudgetDB::ReadResult readResult2 = budgetdb.Read(budget);
if (readResult2 == CBudgetDB::FileError)
LogPrintf("Missing budget cache - budget.dat, will try to recreate\n");
else if (readResult2 != CBudgetDB::Ok)
{
LogPrintf("Error reading budget.dat: ");
if(readResult2 == CBudgetDB::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");
}
//flag our cached items so we send them to our peers
budget.ResetSync();
budget.ClearSeen();
/*
uiInterface.InitMessage(_("Loading masternode payment cache..."));
We sync all of this information on boot anyway, as it's kept on the network so there's really no point.
Also, it seems it might be causing some edge cases where clients can get stuck. I think it's better to just
sync from the network instead.
uiInterface.InitMessage(_("Loading masternode cache..."));
CMasternodeDB mndb;
CMasternodeDB::ReadResult readResult = mndb.Read(mnodeman);
if (readResult == CMasternodeDB::FileError)
LogPrintf("Missing masternode cache file - mncache.dat, will try to recreate\n");
else if (readResult != CMasternodeDB::Ok)
{
LogPrintf("Error reading mncache.dat: ");
if(readResult == CMasternodeDB::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");
}
// ---------
// uiInterface.InitMessage(_("Loading budget cache..."));
// CBudgetDB budgetdb;
// CBudgetDB::ReadResult readResult2 = budgetdb.Read(budget);
// if (readResult2 == CBudgetDB::FileError)
// LogPrintf("Missing budget cache - budget.dat, will try to recreate\n");
// else if (readResult2 != CBudgetDB::Ok)
// {
// LogPrintf("Error reading budget.dat: ");
// if(readResult2 == CBudgetDB::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");
// }
// //flag our cached items so we send them to our peers
// budget.ResetSync();
// budget.ClearSeen();
// uiInterface.InitMessage(_("Loading masternode payment cache..."));
// CMasternodePaymentDB mnpayments;
// CMasternodePaymentDB::ReadResult readResult3 = mnpayments.Read(masternodePayments);
// if (readResult3 == CMasternodePaymentDB::FileError)
// LogPrintf("Missing masternode payment cache - mnpayments.dat, will try to recreate\n");
// else if (readResult3 != CMasternodePaymentDB::Ok)
// {
// LogPrintf("Error reading mnpayments.dat: ");
// if(readResult3 == CMasternodePaymentDB::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");
// }
*/
CMasternodePaymentDB mnpayments;
CMasternodePaymentDB::ReadResult readResult3 = mnpayments.Read(masternodePayments);
if (readResult3 == CMasternodePaymentDB::FileError)
LogPrintf("Missing masternode payment cache - mnpayments.dat, will try to recreate\n");
else if (readResult3 != CMasternodePaymentDB::Ok)
{
LogPrintf("Error reading mnpayments.dat: ");
if(readResult3 == CMasternodePaymentDB::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);

View File

@ -1379,16 +1379,6 @@ bool CBudgetProposal::AddOrUpdateVote(CBudgetVote& vote, std::string& strError)
}
}
//if we're synced, the vote should have been recent
if(masternodeSync.IsSynced()) {
//up to an hour ago
if(vote.nTime < GetTime() - (60*60)){
strError = strprintf("new vote is too old - %s - nTime %lli - Min Time %lli\n", vote.GetHash().ToString(), vote.nTime, GetTime() - (60*60));
LogPrint("mnbudget", "CBudgetProposal::AddOrUpdateVote - %s\n", strError);
return false;
}
}
if(vote.nTime > GetTime() + (60*60)){
strError = strprintf("new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", vote.GetHash().ToString(), vote.nTime, GetTime() + (60*60));
LogPrint("mnbudget", "CBudgetProposal::AddOrUpdateVote - %s\n", strError);
@ -1641,16 +1631,6 @@ bool CFinalizedBudget::AddOrUpdateVote(CFinalizedBudgetVote& vote, std::string&
}
}
//if we're synced, the vote should have been recent
if(masternodeSync.IsSynced()) {
//up to an hour ago
if(vote.nTime < GetTime() - (60*60)){
strError = strprintf("new vote is too old - %s - nTime %lli - Min Time %lli\n", vote.GetHash().ToString(), vote.nTime, GetTime() - (60*60));
LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);
return false;
}
}
if(vote.nTime > GetTime() + (60*60)){
strError = strprintf("new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", vote.GetHash().ToString(), vote.nTime, GetTime() + (60*60));
LogPrint("mnbudget", "CFinalizedBudget::AddOrUpdateVote - %s\n", strError);

View File

@ -382,8 +382,7 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
}
std::string strError = "";
int nRank = 99999;
if(!winner.IsValid(pfrom, strError, nRank)){
if(!winner.IsValid(pfrom, strError)){
if(strError != "") LogPrintf("mnw - invalid message - %s\n", strError);
return;
}
@ -407,7 +406,7 @@ void CMasternodePayments::ProcessMessageMasternodePayments(CNode* pfrom, std::st
LogPrint("mnpayments", "mnw - winning vote - Addr %s Height %d bestHeight %d - %s\n", address2.ToString().c_str(), winner.nBlockHeight, chainActive.Tip()->nHeight, winner.vinMasternode.prevout.ToStringShort());
if(masternodePayments.AddWinningMasternode(winner, nRank)){
if(masternodePayments.AddWinningMasternode(winner)){
winner.Relay();
masternodeSync.AddedMasternodeWinner(winner.GetHash());
}
@ -472,7 +471,7 @@ bool CMasternodePayments::IsScheduled(CMasternode& mn, int nNotBlockHeight)
return false;
}
bool CMasternodePayments::AddWinningMasternode(CMasternodePaymentWinner& winnerIn, int nRank)
bool CMasternodePayments::AddWinningMasternode(CMasternodePaymentWinner& winnerIn)
{
uint256 blockHash = 0;
if(!GetBlockHash(blockHash, winnerIn.nBlockHeight-100)) {
@ -496,7 +495,7 @@ bool CMasternodePayments::AddWinningMasternode(CMasternodePaymentWinner& winnerI
int n = 1;
if(IsReferenceNode(winnerIn.vinMasternode)) n = 100;
mapMasternodeBlocks[winnerIn.nBlockHeight].AddPayee(winnerIn.payee, n, winnerIn.GetHash(), nRank);
mapMasternodeBlocks[winnerIn.nBlockHeight].AddPayee(winnerIn.payee, n);
return true;
}
@ -626,7 +625,7 @@ bool IsReferenceNode(CTxIn& vin)
return false;
}
bool CMasternodePaymentWinner::IsValid(CNode* pnode, std::string& strError, int& nRank)
bool CMasternodePaymentWinner::IsValid(CNode* pnode, std::string& strError)
{
if(IsReferenceNode(vinMasternode)) return true;
@ -647,15 +646,15 @@ bool CMasternodePaymentWinner::IsValid(CNode* pnode, std::string& strError, int&
return false;
}
nRank = mnodeman.GetMasternodeRank(vinMasternode, nBlockHeight-100, MIN_MNW_PEER_PROTO_VERSION);
int n = mnodeman.GetMasternodeRank(vinMasternode, nBlockHeight-100, MIN_MNW_PEER_PROTO_VERSION);
if(nRank > MNPAYMENTS_SIGNATURES_TOTAL)
if(n > MNPAYMENTS_SIGNATURES_TOTAL)
{
//It's common to have masternodes mistakenly think they are in the top 10
// We don't want to print all of these messages, or punish them unless they're way off
if(nRank > MNPAYMENTS_SIGNATURES_TOTAL*2)
if(n > MNPAYMENTS_SIGNATURES_TOTAL*2)
{
strError = strprintf("Masternode not in the top %d (%d)", MNPAYMENTS_SIGNATURES_TOTAL, nRank);
strError = strprintf("Masternode not in the top %d (%d)", MNPAYMENTS_SIGNATURES_TOTAL, n);
LogPrintf("CMasternodePaymentWinner::IsValid - %s\n", strError);
Misbehaving(pnode->GetId(), 20);
}
@ -671,19 +670,18 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight)
//reference node - hybrid mode
int nRank = 9999;
if(!IsReferenceNode(activeMasternode.vin)){
int nRank = mnodeman.GetMasternodeRank(activeMasternode.vin, nBlockHeight-100, MIN_MNW_PEER_PROTO_VERSION);
int n = mnodeman.GetMasternodeRank(activeMasternode.vin, nBlockHeight-100, MIN_MNW_PEER_PROTO_VERSION);
if(nRank == -1)
if(n == -1)
{
LogPrint("mnpayments", "CMasternodePayments::ProcessBlock - Unknown Masternode\n");
return false;
}
if(nRank > MNPAYMENTS_SIGNATURES_TOTAL)
if(n > MNPAYMENTS_SIGNATURES_TOTAL)
{
LogPrint("mnpayments", "CMasternodePayments::ProcessBlock - Masternode not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL, nRank);
LogPrint("mnpayments", "CMasternodePayments::ProcessBlock - Masternode not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL, n);
return false;
}
}
@ -736,7 +734,7 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight)
{
LogPrintf("CMasternodePayments::ProcessBlock() - AddWinningMasternode\n");
if(AddWinningMasternode(newWinner, nRank))
if(AddWinningMasternode(newWinner))
{
newWinner.Relay();
nLastBlockHeight = nBlockHeight;
@ -781,34 +779,19 @@ void CMasternodePayments::Sync(CNode* node, int nCountNeeded)
if(chainActive.Tip() == NULL) return;
int nCount = mnodeman.CountEnabled()*1.5;
int nCount = (mnodeman.CountEnabled()*2);
if(nCountNeeded > nCount) nCountNeeded = nCount;
vector<CInv> vInv;
//get 1 winner per block for the previous nCount blocks
vector<uint256> vecHash;
for(int nBlockHeight = chainActive.Tip()->nHeight-nCount; nBlockHeight < chainActive.Tip()->nHeight-5; nBlockHeight++)
{
if(mapMasternodeBlocks[nBlockHeight].GetPayeeInventoryItems(vecHash)){
BOOST_FOREACH(uint256& nHash, vecHash)
{
CInv inv(MSG_MASTERNODE_WINNER, nHash);
vInv.push_back(inv);
}
}
}
//get 10 winners per block for the previous 5 blocks and next 20 (usually will be 10 though)
std::map<uint256, CMasternodePaymentWinner>::iterator it = mapMasternodePayeeVotes.begin();
while(it != mapMasternodePayeeVotes.end()) {
CMasternodePaymentWinner& winner = (*it).second;
if(winner.nBlockHeight >= chainActive.Tip()->nHeight-5 && winner.nBlockHeight <= chainActive.Tip()->nHeight + 20) {
CMasternodePaymentWinner winner = (*it).second;
if(winner.nBlockHeight >= chainActive.Tip()->nHeight-nCountNeeded && winner.nBlockHeight <= chainActive.Tip()->nHeight + 20) {
CInv inv(MSG_MASTERNODE_WINNER, winner.GetHash());
vInv.push_back(inv);
}
++it;
}
node->PushMessage("ssc", MASTERNODE_SYNC_MNW, (int)vInv.size());
if(vInv.size() > 0) node->PushMessage("inv", vInv);
}

View File

@ -63,21 +63,15 @@ class CMasternodePayee
public:
CScript scriptPubKey;
int nVotes;
uint256 nInvHash;
int nMasternodeRank;
CMasternodePayee() {
scriptPubKey = CScript();
nVotes = 0;
nInvHash = 0;
nMasternodeRank = 99999;
}
CMasternodePayee(CScript payee, int nVotesIn, uint256 nInvHashIn, int nMasternodeRankIn) {
CMasternodePayee(CScript payee, int nVotesIn) {
scriptPubKey = payee;
nVotes = nVotesIn;
nInvHash = nInvHashIn;
nMasternodeRank = nMasternodeRankIn;
}
ADD_SERIALIZE_METHODS;
@ -86,8 +80,6 @@ public:
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(scriptPubKey);
READWRITE(nVotes);
READWRITE(nInvHash);
READWRITE(nMasternodeRank);
}
};
@ -107,23 +99,17 @@ public:
vecPayments.clear();
}
void AddPayee(CScript payeeIn, int nIncrement, uint256 nInvHashIn, int nMasternodeRankIn){
void AddPayee(CScript payeeIn, int nIncrement){
LOCK(cs_vecPayments);
BOOST_FOREACH(CMasternodePayee& payee, vecPayments){
if(payee.scriptPubKey == payeeIn) {
payee.nVotes += nIncrement;
//keep track of the "best" (highest rank) masternode's inventory item so we can send that one
// when syncing, we will consume much less bandwidth because of this
if(payee.nMasternodeRank > nMasternodeRankIn){
payee.nMasternodeRank = nMasternodeRankIn;
payee.nInvHash = nInvHashIn;
}
return;
}
}
CMasternodePayee c(payeeIn, nIncrement, nInvHashIn, nMasternodeRankIn);
CMasternodePayee c(payeeIn, nIncrement);
vecPayments.push_back(c);
}
@ -142,30 +128,6 @@ public:
return (nVotes > -1);
}
int CountVotes()
{
int nVotes = 0;
BOOST_FOREACH(CMasternodePayee& p, vecPayments)
nVotes += p.nVotes;
return nVotes;
}
bool GetPayeeInventoryItems(vector<uint256>& vecHash)
{
LOCK(cs_vecPayments);
BOOST_FOREACH(CMasternodePayee& p, vecPayments){
//if we're syncing another client from a partial list, send everything.
// otherwise, we'll require 2 votes per item (those are the ones that count on the winners list)
if(p.nVotes >= 2 || CountVotes() <= 5){
vecHash.push_back(p.nInvHash);
}
}
return vecHash.size() >= 1;
}
bool HasPayeeWithVotes(CScript payee, int nVotesReq)
{
LOCK(cs_vecPayments);
@ -221,7 +183,7 @@ public:
}
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
bool IsValid(CNode* pnode, std::string& strError, int& nRank);
bool IsValid(CNode* pnode, std::string& strError);
bool SignatureValid();
void Relay();
@ -278,7 +240,7 @@ public:
mapMasternodePayeeVotes.clear();
}
bool AddWinningMasternode(CMasternodePaymentWinner& winner, int nRank);
bool AddWinningMasternode(CMasternodePaymentWinner& winner);
bool ProcessBlock(int nBlockHeight);
void Sync(CNode* node, int nCountNeeded);

View File

@ -348,7 +348,7 @@ void CMasternodeSync::Process()
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return;
int nMnCount = mnodeman.CountEnabled();
int nMnCount = mnodeman.CountEnabled()*2;
pnode->PushMessage("mnget", nMnCount); //sync payees
RequestedMasternodeAttempt++;

View File

@ -271,10 +271,7 @@ int64_t CMasternode::GetLastPaid() {
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 we've synced we'll have 1 vote per winning masternode, those count. Otherwise we'll have 10 votes, then only 2 votes min count
int nMinVotes = masternodePayments.mapMasternodeBlocks[BlockReading->nHeight].CountVotes() >= 6 ? 2 : 1;
if(masternodePayments.mapMasternodeBlocks[BlockReading->nHeight].HasPayeeWithVotes(mnpayee, nMinVotes)){
if(masternodePayments.mapMasternodeBlocks[BlockReading->nHeight].HasPayeeWithVotes(mnpayee, 2)){
return BlockReading->nTime + nOffset;
}
}

View File

@ -24,7 +24,7 @@ Value mnbudget(const Array& params, bool fHelp)
strCommand = params[0].get_str();
if (fHelp ||
(strCommand != "vote-many" && strCommand != "prepare" && strCommand != "submit" && strCommand != "vote" && strCommand != "getvotes" && strCommand != "getinfo" && strCommand != "show" && strCommand != "projection" && strCommand != "check"))
(strCommand != "vote-many" && strCommand != "prepare" && strCommand != "submit" && strCommand != "vote" && strCommand != "getvotes" && strCommand != "getinfo" && strCommand != "show" && strCommand != "projection" && strCommand != "check" && strCommand != "nextblock"))
throw runtime_error(
"mnbudget \"command\"... ( \"passphrase\" )\n"
"Vote or show current budgets\n"
@ -39,8 +39,18 @@ Value mnbudget(const Array& params, bool fHelp)
" show - Show all budgets\n"
" projection - Show the projection of which proposals will be paid the next cycle\n"
" check - Scan proposals and remove invalid\n"
" nextblock - Get next superblock for budget system\n"
);
if(strCommand == "nextblock")
{
CBlockIndex* pindexPrev = chainActive.Tip();
if(!pindexPrev) return "unknown";
int nNext = pindexPrev->nHeight - pindexPrev->nHeight % GetBudgetPaymentCycleBlocks() + GetBudgetPaymentCycleBlocks();
return nNext;
}
if(strCommand == "prepare")
{
int nBlockMin = 0;