diff --git a/src/main.cpp b/src/main.cpp index eabc5952a2f2..3caec4451776 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2791,14 +2791,14 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) { // When we reach this point, we switched to a new tip (stored in pindexNewTip). // Notifications/callbacks that can run without cs_main - if (masternodeSync.IsSynced()) { + if (!fInitialDownload) { uint256 hashNewTip = pindexNewTip->GetBlockHash(); // Relay inventory, but don't relay old inventory during initial block download. int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(); { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) - // if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) + if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip)); } // Notify external listeners about the new tip. @@ -3252,6 +3252,7 @@ bool CheckWork(const CBlock block, CBlockIndex * const pindexPrev) { uint256 hashProofOfStake; uint256 hash = block.GetHash(); + if(!CheckProofOfStake(block, hashProofOfStake)) { LogPrintf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str()); @@ -3373,7 +3374,7 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc if (hash != Params().HashGenesisBlock()) { BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) - return state.DoS(0, error("%s : prev block not found", __func__), 0, "bad-prevblk"); + return state.DoS(0, error("%s : prev block %s not found", __func__, block.hashPrevBlock.ToString().c_str()), 0, "bad-prevblk"); pindexPrev = (*mi).second; if (pindexPrev->nStatus & BLOCK_FAILED_MASK) return state.DoS(100, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); @@ -3402,7 +3403,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, if (block.GetHash() != Params().HashGenesisBlock()) { BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) - return state.DoS(0, error("%s : prev block not found", __func__), 0, "bad-prevblk"); + return state.DoS(0, error("%s : prev block %s not found", __func__, block.hashPrevBlock.ToString().c_str()), 0, "bad-prevblk"); pindexPrev = (*mi).second; if (pindexPrev->nStatus & BLOCK_FAILED_MASK) return state.DoS(100, error("%s : prev block invalid", __func__), REJECT_INVALID, "bad-prevblk"); @@ -3527,6 +3528,14 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis if (!pblock->CheckBlockSignature()) return error("ProcessNewBlock() : bad proof-of-stake block signature"); + //if we get this far, check if the prev block is our prev block, if not then request sync and return false + BlockMap::iterator mi = mapBlockIndex.find(pblock->hashPrevBlock); + if (mi == mapBlockIndex.end()) + { + pfrom->PushMessage("getblocks", chainActive.GetLocator(), uint256(0)); + return false; + } + while(true) { TRY_LOCK(cs_main, lockMain); if(!lockMain) { MilliSleep(50); continue; } @@ -4787,28 +4796,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK) pfrom->AskFor(inv); - + if (inv.type == MSG_BLOCK) { UpdateBlockAvailability(pfrom->GetId(), inv.hash); if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) { - // First request the headers preceeding the announced block. In the normal fully-synced - // case where a new block is announced that succeeds the current tip (no reorganization), - // there are no such headers. - // Secondly, and only when we are close to being synced, we request the announced block directly, - // to avoid an extra round-trip. Note that we must *first* ask for the headers, so by the - // time the block arrives, the header chain leading up to it is already validated. Not - // doing this will result in the received block being rejected as an orphan in case it is - // not a direct successor. - pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexBestHeader), inv.hash); - CNodeState *nodestate = State(pfrom->GetId()); - if (chainActive.Tip()->GetBlockTime() > GetAdjustedTime() - Params().TargetSpacing() * 20 && - nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) { - vToFetch.push_back(inv); - // Mark block as in flight already, even though the actual "getdata" message only goes out - // later (within the same cs_main lock, though). - MarkBlockAsInFlight(pfrom->GetId(), inv.hash); - } - LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id); + // Add this to the list of blocks to request + vToFetch.push_back(inv); + LogPrint("net", "getblocks (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id); } } @@ -4847,7 +4841,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "getblocks") + else if (strCommand == "getblocks" || strCommand == "getheaders") { CBlockLocator locator; uint256 hashStop; @@ -4862,7 +4856,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (pindex) pindex = chainActive.Next(pindex); int nLimit = 500; - LogPrint("net", "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop==uint256(0) ? "end" : hashStop.ToString(), nLimit, pfrom->id); + LogPrintf("getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop==uint256(0) ? "end" : hashStop.ToString(), nLimit, pfrom->id); for (; pindex; pindex = chainActive.Next(pindex)) { if (pindex->GetBlockHash() == hashStop) @@ -4883,7 +4877,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "getheaders") + else if (strCommand == "tempdisable") { CBlockLocator locator; uint256 hashStop; @@ -5088,7 +5082,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - else if (strCommand == "headers" && !fImporting && !fReindex) // Ignore headers received while importing + else if (strCommand == "tempdisable" && !fImporting && !fReindex) // Ignore headers received while importing { std::vector headers; @@ -5136,7 +5130,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Headers message had its maximum size; the peer may have more headers. // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // from there instead. - LogPrint("net", "more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); + LogPrintf("more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight); pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256(0)); } @@ -5148,20 +5142,26 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, CBlock block; vRecv >> block; - CInv inv(MSG_BLOCK, block.GetHash()); - LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id); + //sometimes we will be sent their most recent block and its not the one we want, in that case tell where we are + if(block.hashPrevBlock != chainActive.Tip()->GetBlockHash()) + pfrom->PushMessage("getblocks", chainActive.GetLocator(), uint256(0)); + else + { + CInv inv(MSG_BLOCK, block.GetHash()); + LogPrint("net", "received block %s peer=%d\n", inv.hash.ToString(), pfrom->id); - pfrom->AddInventoryKnown(inv); + pfrom->AddInventoryKnown(inv); - CValidationState state; - ProcessNewBlock(state, pfrom, &block); - int nDoS; - if (state.IsInvalid(nDoS)) { - pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), - state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); - if (nDoS > 0) { - TRY_LOCK(cs_main, lockMain); - if(lockMain) Misbehaving(pfrom->GetId(), nDoS); + CValidationState state; + ProcessNewBlock(state, pfrom, &block); + int nDoS; + if (state.IsInvalid(nDoS)) { + pfrom->PushMessage("reject", strCommand, state.GetRejectCode(), + state.GetRejectReason().substr(0, MAX_REJECT_MESSAGE_LENGTH), inv.hash); + if (nDoS > 0) { + TRY_LOCK(cs_main, lockMain); + if(lockMain) Misbehaving(pfrom->GetId(), nDoS); + } } } @@ -5640,10 +5640,12 @@ bool SendMessages(CNode* pto, bool fSendTrickle) if (nSyncStarted == 0 || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 6 * 60 * 60) { // NOTE: was "close to today" and 24h in Bitcoin state.fSyncStarted = true; nSyncStarted++; - CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader; - LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight); - pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0)); + //CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader; + //LogPrint("net", "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->id, pto->nStartingHeight); + //pto->PushMessage("getheaders", chainActive.GetLocator(pindexStart), uint256(0)); + pto->PushMessage("getblocks", chainActive.GetLocator(chainActive.Tip()), uint256(0)); } + } // Resend wallet transactions that haven't gotten in a block yet @@ -5732,7 +5734,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) BOOST_FOREACH(CBlockIndex *pindex, vToDownload) { vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash())); MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), pindex); - LogPrint("net", "Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), + LogPrintf("Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(), pindex->nHeight, pto->id); } if (state.nBlocksInFlight == 0 && staller != -1) { diff --git a/src/net.cpp b/src/net.cpp index 7823b36dca22..b8255f66ae42 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1727,7 +1727,8 @@ void StartNode(boost::thread_group& threadGroup) threadGroup.create_thread(boost::bind(&LoopForever, "dumpaddr", &DumpAddresses, DUMP_ADDRESSES_INTERVAL * 1000)); // ppcoin:mint proof-of-stake blocks in the background - threadGroup.create_thread(boost::bind(&TraceThread, "stakemint", &ThreadStakeMinter)); + if(GetBoolArg("-staking", true)) + threadGroup.create_thread(boost::bind(&TraceThread, "stakemint", &ThreadStakeMinter)); } bool StopNode() diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 6959d3280cfb..f66291472f87 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -59,33 +59,18 @@ QList TransactionRecord::decomposeTransaction(const CWallet * { if(IsMine(*wallet, outAddress)) { - TransactionRecord txrMultiSendRec = TransactionRecord(hash, nTime, TransactionRecord::RecvWithAddress, CBitcoinAddress(outAddress).ToString(), wtx.vout[i].nValue, 0); - parts.append(txrMultiSendRec); + TransactionRecord txrMasternodeRec = TransactionRecord(hash, nTime, TransactionRecord::RecvWithAddress, CBitcoinAddress(outAddress).ToString(), wtx.vout[i].nValue, 0); + parts.append(txrMasternodeRec); } } } } else { - TransactionRecord txrCoinStake = TransactionRecord(hash, nTime, TransactionRecord::StakeMint, CBitcoinAddress(address).ToString(), -nDebit, wtx.GetValueOut()); - // Stake generation + //stake reward + TransactionRecord txrCoinStake = TransactionRecord(hash, nTime, TransactionRecord::StakeMint, CBitcoinAddress(address).ToString(), nNet, 0); parts.append(txrCoinStake); - - //if some of your outputs went to another address we will make them as a sendtoaddress tx - for(unsigned int i = 0; i < wtx.vout.size(); i++) - { - if(i == 0) - continue; //first tx is blank - CTxDestination outAddress; - if(ExtractDestination(wtx.vout[i].scriptPubKey, outAddress)) - { - if(CBitcoinAddress(outAddress).ToString() != CBitcoinAddress(address).ToString()) - { - TransactionRecord txrCoinStakeMultiSend = TransactionRecord(hash, nTime, TransactionRecord::SendToAddress, CBitcoinAddress(outAddress).ToString(), wtx.vout[i].nValue * -1, 0); - parts.append(txrCoinStakeMultiSend); - } - } - } + } } else if (nNet > 0 || wtx.IsCoinBase()) diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index f756a624c482..4c44cfeb9db3 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -52,7 +52,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) int confirmsTotal = GetIXConfirmations(wtx.GetHash()) + confirms; entry.push_back(Pair("confirmations", confirmsTotal)); entry.push_back(Pair("bcconfirmations", confirms)); - if (wtx.IsCoinBase()) + if (wtx.IsCoinBase() || wtx.IsCoinStake()) entry.push_back(Pair("generated", true)); if (confirms > 0) { diff --git a/src/version.h b/src/version.h index 17383936e962..952ce93b3747 100644 --- a/src/version.h +++ b/src/version.h @@ -11,7 +11,7 @@ * network protocol versioning */ -static const int PROTOCOL_VERSION = 70500; +static const int PROTOCOL_VERSION = 70600; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; @@ -20,11 +20,11 @@ static const int INIT_PROTO_VERSION = 209; static const int GETHEADERS_VERSION = 70077; //! disconnect from peers older than this proto version -static const int MIN_PEER_PROTO_VERSION = 70500; -static const int MIN_PEER_PROTO_VERSION_POS = 70500; +static const int MIN_PEER_PROTO_VERSION = 70600; +static const int MIN_PEER_PROTO_VERSION_POS = 70600; //! minimum peer version accepted by ObfuscationPool -static const int MIN_POOL_PEER_PROTO_VERSION = 70500; +static const int MIN_POOL_PEER_PROTO_VERSION = 70600; //! minimum peer version for masternode budgets static const int MIN_BUDGET_PEER_PROTO_VERSION = 70106; @@ -35,8 +35,8 @@ static const int MIN_MNW_PEER_PROTO_VERSION = 70104; //! 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 = 70400; -static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70500; +static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1 = 70500; +static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2 = 70600; //! nTime field added to CAddress, starting with this version; //! if possible, avoid requesting addresses nodes older than this