Merge remote-tracking branch 'upstream/v0.12.0.x' into Wallet_Restart

This commit is contained in:
crowning- 2015-07-03 07:55:29 +02:00
commit 3195e04d7d
21 changed files with 19768 additions and 21954 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, 6)
define(_CLIENT_VERSION_BUILD, 7)
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

@ -84,6 +84,7 @@ static const Checkpoints::CCheckpointData data = {
static Checkpoints::MapCheckpoints mapCheckpointsTestnet =
boost::assign::map_list_of
( 261, uint256("00000c26026d0815a7e2ce4fa270775f61403c040647ff2c3091f99e894a4618"))
( 77100, uint256("00000133e07bae4d3553fd8d86cb5a961d638cae72d179ede8ca436c60a2c3c0"))
;
static const Checkpoints::CCheckpointData dataTestnet = {
&mapCheckpointsTestnet,

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 6
#define CLIENT_VERSION_BUILD 7
//! Set to true for release, false for prerelease or test build
#define CLIENT_VERSION_IS_RELEASE true

View File

@ -2356,25 +2356,33 @@ void ThreadCheckDarkSendPool()
if(c % 5 == 0 && RequestedMasternodeAssets <= 2){
bool fIsInitialDownload = IsInitialBlockDownload();
if(!fIsInitialDownload) {
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
if (pnode->nVersion >= MIN_POOL_PEER_PROTO_VERSION) {
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev != NULL) {
if(pindexPrev->nTime > GetAdjustedTime() - (60*24))
{
//keep track of who we've asked for the list
if(pnode->HasFulfilledRequest("mnsync")) continue;
pnode->FulfilledRequest("mnsync");
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
if (pnode->nVersion >= MIN_POOL_PEER_PROTO_VERSION) {
LogPrintf("Successfully synced, asking for Masternode list and payment list\n");
//keep track of who we've asked for the list
if(pnode->HasFulfilledRequest("mnsync")) continue;
pnode->FulfilledRequest("mnsync");
//request full mn list only if Masternodes.dat was updated quite a long time ago
mnodeman.DsegUpdate(pnode);
LogPrintf("Successfully synced, asking for Masternode list and payment list\n");
pnode->PushMessage("mnget"); //sync payees
pnode->PushMessage("mnvs"); //sync masternode votes
pnode->PushMessage("getsporks"); //get current network sporks
RequestedMasternodeAssets++;
break;
//request full mn list only if Masternodes.dat was updated quite a long time ago
mnodeman.DsegUpdate(pnode);
pnode->PushMessage("mnget"); //sync payees
uint256 n = 0;
pnode->PushMessage("mnvs", n); //sync masternode votes
pnode->PushMessage("getsporks"); //get current network sporks
RequestedMasternodeAssets++;
break;
}
}
}
}
}

View File

@ -27,7 +27,7 @@ class CConsensusVote;
class CTransaction;
class CTransactionLock;
static const int MIN_INSTANTX_PROTO_VERSION = 70082;
static const int MIN_INSTANTX_PROTO_VERSION = 70083;
extern map<uint256, CTransaction> mapTxLockReq;
extern map<uint256, CTransaction> mapTxLockReqRejected;

View File

@ -16,8 +16,13 @@ CCriticalSection cs_budget;
std::map<uint256, CBudgetProposalBroadcast> mapSeenMasternodeBudgetProposals;
std::map<uint256, CBudgetVote> mapSeenMasternodeBudgetVotes;
std::map<uint256, CBudgetVote> mapOrphanMasternodeBudgetVotes;
std::map<uint256, CFinalizedBudgetBroadcast> mapSeenFinalizedBudgets;
std::map<uint256, CFinalizedBudgetVote> mapSeenFinalizedBudgetVotes;
std::map<uint256, CFinalizedBudgetVote> mapOrphanFinalizedBudgetVotes;
std::map<uint256, int64_t> askedForSourceProposalOrBudget;
int nSubmittedFinalBudget;
int GetBudgetPaymentCycleBlocks(){
@ -27,6 +32,28 @@ int GetBudgetPaymentCycleBlocks(){
return 50;
}
void CheckOrphanVotes()
{
std::map<uint256, CBudgetVote>::iterator it1 = mapOrphanMasternodeBudgetVotes.begin();
while(it1 != mapOrphanMasternodeBudgetVotes.end()){
if(budget.UpdateProposal(((*it1).second), NULL)){
LogPrintf("CheckOrphanVotes: Proposal/Budget is known, activating and removing orphan vote\n");
mapOrphanMasternodeBudgetVotes.erase(it1++);
} else {
++it1;
}
}
std::map<uint256, CFinalizedBudgetVote>::iterator it2 = mapOrphanFinalizedBudgetVotes.begin();
while(it2 != mapOrphanFinalizedBudgetVotes.end()){
if(budget.UpdateFinalizedBudget(((*it2).second),NULL)){
LogPrintf("CheckOrphanVotes: Proposal/Budget is known, activating and removing orphan vote\n");
mapOrphanFinalizedBudgetVotes.erase(it2++);
} else {
++it2;
}
}
}
void SubmitFinalBudget()
{
CBlockIndex* pindexPrev = chainActive.Tip();
@ -85,7 +112,7 @@ void SubmitFinalBudget()
mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
vote.Relay();
budget.UpdateFinalizedBudget(vote);
budget.UpdateFinalizedBudget(vote, NULL);
}
//
@ -574,14 +601,20 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
LOCK(cs_budget);
if (strCommand == "mnvs") { //Masternode vote sync
if(pfrom->HasFulfilledRequest("mnvs")) {
LogPrintf("mnvs - peer already asked me for the list\n");
Misbehaving(pfrom->GetId(), 20);
return;
bool IsLocal = pfrom->addr.IsRFC1918() || pfrom->addr.IsLocal();
if(!IsLocal){
if(pfrom->HasFulfilledRequest("mnvs")) {
LogPrintf("mnvs - peer already asked me for the list\n");
Misbehaving(pfrom->GetId(), 20);
return;
}
}
uint256 nProp;
vRecv >> nProp;
pfrom->FulfilledRequest("mnvs");
budget.Sync(pfrom);
budget.Sync(pfrom, nProp);
LogPrintf("mnvs - Sent Masternode votes to %s\n", pfrom->addr.ToString().c_str());
}
@ -622,6 +655,9 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
//can only do this four times a day on the network
if(!IsSyncingMasternodeAssets()) pmn->nVotedTimes+=25;
//We might have active votes for this proposal that are valid now
CheckOrphanVotes();
} else {
LogPrintf("mvote - masternode can't vote again - vin:%s \n", pmn->vin.ToString().c_str());
return;
@ -650,7 +686,7 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
mapSeenMasternodeBudgetVotes.insert(make_pair(vote.GetHash(), vote));
if(IsSyncingMasternodeAssets() || pmn->nVotedTimes < 100){
budget.UpdateProposal(vote);
budget.UpdateProposal(vote, pfrom);
vote.Relay();
if(!IsSyncingMasternodeAssets()) pmn->nVotedTimes++;
} else {
@ -691,6 +727,9 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
prop.Relay();
if(!IsSyncingMasternodeAssets()) pmn->nVotedTimes++;
//we might have active votes for this budget that are now valid
CheckOrphanVotes();
} else {
LogPrintf("mvote - masternode can't vote again - vin:%s \n", pmn->vin.ToString().c_str());
return;
@ -719,7 +758,7 @@ void CBudgetManager::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
if(IsSyncingMasternodeAssets() || pmn->nVotedTimes < 100){
budget.UpdateFinalizedBudget(vote);
budget.UpdateFinalizedBudget(vote, pfrom);
vote.Relay();
if(!IsSyncingMasternodeAssets()) pmn->nVotedTimes++;
} else {
@ -735,38 +774,98 @@ bool CBudgetManager::PropExists(uint256 nHash)
return false;
}
void CBudgetManager::Sync(CNode* node)
void CBudgetManager::Sync(CNode* pfrom, uint256 nProp)
{
std::map<uint256, CBudgetProposal>::iterator it = mapProposals.begin();
while(it != mapProposals.end()){
(*it).second.Sync(node);
++it;
/*
Sync with a client on the network
--
This code checks each of the hash maps for all known budget proposals and finalized budget proposals, then checks them against the
budget object to see if they're OK. If all checks pass, we'll send it to the peer.
*/
std::map<uint256, CBudgetProposalBroadcast>::iterator it1 = mapSeenMasternodeBudgetProposals.begin();
while(it1 != mapSeenMasternodeBudgetProposals.end()){
CBudgetProposal* bp = budget.FindProposal((*it1).first);
if(bp && (nProp == 0 || (*it1).first == nProp)){
pfrom->PushMessage("mprop", ((*it1).second));
}
it1++;
}
std::map<uint256, CBudgetVote>::iterator it2 = mapSeenMasternodeBudgetVotes.begin();
while(it2 != mapSeenMasternodeBudgetVotes.end()){
CBudgetProposal* bp = budget.FindProposal((*it2).second.nProposalHash);
if(bp && (nProp == 0 || (*it1).first == nProp)){
pfrom->PushMessage("mvote", ((*it2).second));
}
it2++;
}
std::map<uint256, CFinalizedBudgetBroadcast>::iterator it3 = mapSeenFinalizedBudgets.begin();
while(it3 != mapSeenFinalizedBudgets.end()){
CFinalizedBudget* bp = budget.FindFinalizedBudget((*it3).first);
if(bp && (nProp == 0 || (*it1).first == nProp)){
pfrom->PushMessage("fbs", ((*it3).second));
}
it3++;
}
std::map<uint256, CFinalizedBudgetVote>::iterator it4 = mapSeenFinalizedBudgetVotes.begin();
while(it4 != mapSeenFinalizedBudgetVotes.end()){
CFinalizedBudget* bp = budget.FindFinalizedBudget((*it4).second.nBudgetHash);
if(bp && (nProp == 0 || (*it1).first == nProp)){
pfrom->PushMessage("fbvote", ((*it4).second));
}
it4++;
}
}
void CBudgetManager::UpdateProposal(CBudgetVote& vote)
bool CBudgetManager::UpdateProposal(CBudgetVote& vote, CNode* pfrom)
{
LOCK(cs);
if(!mapProposals.count(vote.nProposalHash)){
LogPrintf("ERROR : Unknown proposal %d\n", vote.nProposalHash.ToString().c_str());
return;
if(pfrom){
LogPrintf("Unknown proposal %d, Asking for source proposal\n", vote.nProposalHash.ToString().c_str());
mapOrphanMasternodeBudgetVotes[vote.nProposalHash] = vote;
if(!askedForSourceProposalOrBudget.count(vote.nProposalHash)){
pfrom->PushMessage("mnvs", vote.nProposalHash);
askedForSourceProposalOrBudget[vote.nProposalHash] = GetTime();
}
}
return false;
}
mapProposals[vote.nProposalHash].AddOrUpdateVote(vote);
return true;
}
void CBudgetManager::UpdateFinalizedBudget(CFinalizedBudgetVote& vote)
bool CBudgetManager::UpdateFinalizedBudget(CFinalizedBudgetVote& vote, CNode* pfrom)
{
LOCK(cs);
if(!mapFinalizedBudgets.count(vote.nBudgetHash)){
LogPrintf("ERROR: Unknown Finalized Proposal %s\n", vote.nBudgetHash.ToString().c_str());
//should ask for it
return;
if(pfrom){
LogPrintf("Unknown Finalized Proposal %s, Asking for source proposal\n", vote.nBudgetHash.ToString().c_str());
mapOrphanFinalizedBudgetVotes[vote.nBudgetHash] = vote;
if(!askedForSourceProposalOrBudget.count(vote.nBudgetHash)){
pfrom->PushMessage("mnvs", vote.nBudgetHash);
askedForSourceProposalOrBudget[vote.nBudgetHash] = GetTime();
}
}
return false;
}
mapFinalizedBudgets[vote.nBudgetHash].AddOrUpdateVote(vote);
return true;
}
CBudgetProposal::CBudgetProposal()
@ -925,18 +1024,6 @@ int CBudgetProposal::GetRemainingPaymentCount()
return (GetBlockEndCycle()-GetBlockCurrentCycle())/GetBudgetPaymentCycleBlocks();
}
void CBudgetProposal::Sync(CNode* node)
{
//send the proposal
node->PushMessage("mprop", (*this));
std::map<uint256, CBudgetVote>::iterator it = mapVotes.begin();
while(it != mapVotes.end()){
node->PushMessage("mvote", (*it).second);
++it;
}
}
CBudgetProposalBroadcast::CBudgetProposalBroadcast()
{
vin = CTxIn();
@ -1178,16 +1265,16 @@ int64_t CFinalizedBudget::GetTotalPayout()
}
std::string CFinalizedBudget::GetProposals() {
std::string ret = "aeu";
std::string ret = "";
BOOST_FOREACH(CTxBudgetPayment& payment, vecProposals){
CFinalizedBudget* prop = budget.FindFinalizedBudget(payment.nProposalHash);
CBudgetProposal* prop = budget.FindProposal(payment.nProposalHash);
std::string token = payment.nProposalHash.ToString();
if(prop) token = prop->GetName();
if(ret == "") {ret = token;}
else {ret = "," + token;}
else {ret += "," + token;}
}
return ret;
}
@ -1288,7 +1375,7 @@ void CFinalizedBudget::SubmitVote()
mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
vote.Relay();
budget.UpdateFinalizedBudget(vote);
budget.UpdateFinalizedBudget(vote, NULL);
}
CFinalizedBudgetBroadcast::CFinalizedBudgetBroadcast()

View File

@ -85,7 +85,10 @@ public:
mapFinalizedBudgets.clear();
}
void Sync(CNode* node);
int sizeFinalized() {return (int)mapFinalizedBudgets.size();}
int sizeProposals() {return (int)mapProposals.size();}
void Sync(CNode* node, uint256 nProp);
void Calculate();
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
@ -103,9 +106,10 @@ public:
std::vector<CFinalizedBudget*> GetFinalizedBudgets();
bool IsBudgetPaymentBlock(int nBlockHeight);
void AddProposal(CBudgetProposal& prop);
void UpdateProposal(CBudgetVote& vote);
void AddFinalizedBudget(CFinalizedBudget& prop);
void UpdateFinalizedBudget(CFinalizedBudgetVote& vote);
bool UpdateProposal(CBudgetVote& vote, CNode* pfrom);
bool UpdateFinalizedBudget(CFinalizedBudgetVote& vote, CNode* pfrom);
bool PropExists(uint256 nHash);
bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight);
std::string GetRequiredPaymentsString(int64_t nBlockHeight);
@ -181,8 +185,6 @@ public:
CFinalizedBudget();
CFinalizedBudget(const CFinalizedBudget& other);
void Sync(CNode* node);
void Clean(CFinalizedBudgetVote& vote);
void AddOrUpdateVote(CFinalizedBudgetVote& vote);
double GetScore();
@ -359,8 +361,6 @@ public:
CBudgetProposal(const CBudgetProposal& other);
CBudgetProposal(CTxIn vinIn, std::string strProposalNameIn, std::string strURLIn, int nBlockStartIn, int nBlockEndIn, CScript addressIn, CAmount nAmountIn);
void Sync(CNode* node);
void Calculate();
void AddOrUpdateVote(CBudgetVote& vote);
bool HasMinimumRequiredSupport();

View File

@ -23,15 +23,14 @@ bool IsBlockValueValid(int64_t nBlockValue, int64_t nExpectedValue){
CBlockIndex* pindexPrev = chainActive.Tip();
if(pindexPrev == NULL) return true;
//while syncing take the longest chain
if (fImporting || fReindex || pindexPrev->nHeight+1 < Checkpoints::GetTotalBlocksEstimate()) {
if(budget.sizeFinalized() == 0 && budget.sizeProposals() == 0) { //there is no budget data to use to check anything
//super blocks will always be on these blocks, max 100 per budgeting
if((pindexPrev->nHeight+1) % GetBudgetPaymentCycleBlocks() < 100){
return true;
} else {
if(nBlockValue > nExpectedValue) return false;
}
} else { // we're synced so check the budget schedule
} else { // we're synced and have data so check the budget schedule
if(budget.IsBudgetPaymentBlock(pindexPrev->nHeight+1)){
//the value of the block is evaluated in CheckBlock
return true;

View File

@ -319,12 +319,14 @@ void CMasternodeMan::DsegUpdate(CNode* pnode)
{
LOCK(cs);
std::map<CNetAddr, int64_t>::iterator it = mWeAskedForMasternodeList.find(pnode->addr);
if (it != mWeAskedForMasternodeList.end())
{
if (GetTime() < (*it).second) {
LogPrintf("dseg - we already asked %s for the list; skipping...\n", pnode->addr.ToString());
return;
if(!(pnode->addr.IsRFC1918() || pnode->addr.IsLocal())){
std::map<CNetAddr, int64_t>::iterator it = mWeAskedForMasternodeList.find(pnode->addr);
if (it != mWeAskedForMasternodeList.end())
{
if (GetTime() < (*it).second) {
LogPrintf("dseg - we already asked %s for the list; skipping...\n", pnode->addr.ToString());
return;
}
}
}
pnode->PushMessage("dseg", CTxIn());
@ -659,7 +661,9 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
if(vin == CTxIn()) { //only should ask for this once
//local network
if(!pfrom->addr.IsRFC1918() && Params().NetworkID() == CBaseChainParams::MAIN) {
bool isLocal = (pfrom->addr.IsRFC1918() || pfrom->addr.IsLocal());
if(!isLocal && Params().NetworkID() == CBaseChainParams::MAIN) {
std::map<CNetAddr, int64_t>::iterator i = mAskedUsForMasternodeList.find(pfrom->addr);
if (i != mAskedUsForMasternodeList.end()){
int64_t t = (*i).second;

View File

@ -22,19 +22,15 @@ static const char* ppszTypeName[] =
"tx lock request",
"tx lock vote",
"spork",
"masternode winner",
"masternode scan",
"masternode vote",
"masternode proposal",
"masternode quorum",
"masternode announce",
"masternode ping",
"unknown",
"unknown",
"unknown",
"unknown",
"unknown",
"unknown"
"mn winner",
"mn scan error",
"mn budget vote",
"mn budget proposal",
"mn budget finalized",
"mn budget finalized vote",
"mn quorum",
"mn announce",
"mn ping"
};
CMessageHeader::CMessageHeader()
@ -133,7 +129,7 @@ CInv::CInv(const std::string& strType, const uint256& hashIn)
}
}
if (i == ARRAYLEN(ppszTypeName))
throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType));
LogPrint("net", "CInv::CInv(string, uint256) : unknown type '%s'", strType);
hash = hashIn;
}
@ -150,7 +146,8 @@ bool CInv::IsKnownType() const
const char* CInv::GetCommand() const
{
if (!IsKnownType())
throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type));
LogPrint("net", "CInv::GetCommand() : type=%d unknown type", type);
return ppszTypeName[type];
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -223,7 +223,7 @@ Value mnbudget(const Array& params, bool fHelp)
mapSeenMasternodeBudgetVotes.insert(make_pair(vote.GetHash(), vote));
vote.Relay();
budget.UpdateProposal(vote);
budget.UpdateProposal(vote, NULL);
}
@ -400,7 +400,7 @@ Value mnfinalbudget(const Array& params, bool fHelp)
mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
vote.Relay();
budget.UpdateFinalizedBudget(vote);
budget.UpdateFinalizedBudget(vote, NULL);
return "success";
@ -455,7 +455,7 @@ Value mnfinalbudget(const Array& params, bool fHelp)
mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
vote.Relay();
budget.UpdateFinalizedBudget(vote);
budget.UpdateFinalizedBudget(vote, NULL);
success++;
}
@ -488,7 +488,7 @@ Value mnfinalbudget(const Array& params, bool fHelp)
mapSeenFinalizedBudgetVotes.insert(make_pair(vote.GetHash(), vote));
vote.Relay();
budget.UpdateFinalizedBudget(vote);
budget.UpdateFinalizedBudget(vote, NULL);
return "success";
}

View File

@ -10,7 +10,7 @@
* network protocol versioning
*/
static const int PROTOCOL_VERSION = 70082;
static const int PROTOCOL_VERSION = 70083;
//! initial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209;
@ -22,13 +22,13 @@ 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 = 70082;
static const int MIN_POOL_PEER_PROTO_VERSION = 70083;
//! 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 = 70082;
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70083;
//! nTime field added to CAddress, starting with this version;
//! if possible, avoid requesting addresses nodes older than this