X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.cpp;h=835f60c5e5a09642373f203ebd78c3c44c0f5603;hb=8bb29178006eafab89b9c2106bdcd0dd75f21b94;hp=e99e95f75c05f228071a4e2ec20ccc1ec6e99b12;hpb=b0847bc4b54229f1f16494a44aae00057f2a2d52;p=novacoin.git diff --git a/src/main.cpp b/src/main.cpp index e99e95f..835f60c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,14 +52,13 @@ map > mapOrphanTransactionsByPrev; // Constant stuff for coinbase transactions we create: CScript COINBASE_FLAGS; -const string strMessageMagic = "Bitcoin Signed Message:\n"; +const string strMessageMagic = "PPCoin Signed Message:\n"; double dHashesPerSec; int64 nHPSTimerStart; // Settings int64 nTransactionFee = MIN_TX_FEE; -int64 nBalanceReserve = 0; @@ -456,8 +455,9 @@ bool CTransaction::CheckTransaction() const const CTxOut& txout = vout[i]; if (txout.IsEmpty() && (!IsCoinBase()) && (!IsCoinStake())) return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction")); - if (txout.nValue < 0) - return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative")); + // ppcoin: enforce minimum output amount + if ((!txout.IsEmpty()) && txout.nValue < MIN_TXOUT_AMOUNT) + return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue below minimum")); if (txout.nValue > MAX_MONEY) return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue too high")); nValueOut += txout.nValue; @@ -823,7 +823,7 @@ uint256 WantedByOrphan(const CBlock* pblockOrphan) int64 static GetProofOfWorkReward(unsigned int nBits) { - CBigNum bnSubsidyLimit = 9999 * COIN; // subsidy amount for difficulty 1 + CBigNum bnSubsidyLimit = MAX_MINT_PROOF_OF_WORK; CBigNum bnTarget; bnTarget.SetCompact(nBits); CBigNum bnTargetLimit = bnProofOfWorkLimit; @@ -891,7 +891,7 @@ unsigned int ComputeMinWork(unsigned int nBase, int64 nTime) // ppcoin: find last block index up to pindex const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfStake) { - while (pindex && (pindex->IsProofOfStake() != fProofOfStake)) + while (pindex && pindex->pprev && (pindex->IsProofOfStake() != fProofOfStake)) pindex = pindex->pprev; return pindex; } @@ -972,8 +972,7 @@ void static InvalidChainFound(CBlockIndex* pindexNew) } printf("InvalidChainFound: invalid block=%s height=%d trust=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, CBigNum(pindexNew->nChainTrust).ToString().c_str()); printf("InvalidChainFound: current best=%s height=%d trust=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, CBigNum(nBestChainTrust).ToString().c_str()); - if (pindexBest && nBestInvalidTrust > nBestChainTrust + pindexBest->GetBlockTrust() * 6) - printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n"); + // ppcoin: should not enter safe mode for longer invalid chain } void CBlock::UpdateTime(const CBlockIndex* pindexPrev) @@ -1380,7 +1379,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) nTxPos += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); MapPrevTx mapInputs; - if (!(tx.IsCoinBase() || tx.IsCoinStake())) + if (!tx.IsCoinBase()) { bool fInvalid; if (!tx.FetchInputs(txdb, mapQueuedChanges, true, false, mapInputs, fInvalid)) @@ -1396,7 +1395,8 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) return DoS(100, error("ConnectBlock() : too many sigops")); } - nFees += tx.GetValueIn(mapInputs)-tx.GetValueOut(); + if (!tx.IsCoinStake()) + nFees += tx.GetValueIn(mapInputs)-tx.GetValueOut(); if (!tx.ConnectInputs(txdb, mapInputs, mapQueuedChanges, posThisTx, pindex, true, false, fStrictPayToScriptHash)) return false; @@ -2013,7 +2013,10 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // ppcoin: verify hash target and signature of coinstake tx if (pblock->IsProofOfStake() && !pblock->vtx[1].CheckProofOfStake(pblock->nBits)) - return error("ProcessBlock() : check proof-of-stake failed for block %s", hash.ToString().c_str()); + { + printf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str()); + return false; // do not error here as we expect this during initial block download + } CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint(); if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) @@ -2091,6 +2094,11 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) } printf("ProcessBlock: ACCEPTED\n"); + + // ppcoin: if responsible for sync-checkpoint send it + if (pfrom && !CSyncCheckpoint::strMasterPrivKey.empty()) + Checkpoints::SendSyncCheckpoint(Checkpoints::AutoSelectSyncCheckpoint()); + return true; } @@ -2158,7 +2166,7 @@ bool CheckDiskSpace(uint64 nAdditionalBytes) string strMessage = _("Warning: Disk space is low"); strMiscWarning = strMessage; printf("*** %s\n", strMessage.c_str()); - ThreadSafeMessageBox(strMessage, "Bitcoin", wxOK | wxICON_EXCLAMATION | wxMODAL); + ThreadSafeMessageBox(strMessage, "PPCoin", wxOK | wxICON_EXCLAMATION | wxMODAL); StartShutdown(); return false; } @@ -2361,7 +2369,7 @@ void PrintBlockTree() pindex->nBlockPos, block.GetHash().ToString().substr(0,20).c_str(), block.nBits, - DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(), + DateTimeStrFormat(block.GetBlockTime()).c_str(), block.vtx.size()); PrintWallets(block); @@ -2415,17 +2423,19 @@ string GetWarnings(string strFor) strStatusBar = strMiscWarning; } - // Longer invalid proof-of-work chain - if (pindexBest && nBestInvalidTrust > nBestChainTrust + pindexBest->GetBlockTrust() * 6) + // ppcoin: should not enter safe mode for longer invalid chain + // ppcoin: if sync-checkpoint too old enter safe mode + if (Checkpoints::IsMatureSyncCheckpoint()) { nPriority = 2000; - strStatusBar = strRPC = "WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade."; + strStatusBar = strRPC = "WARNING: Checkpoint is too old. Wait for block chain to download, or notify developers of the issue."; } + // ppcoin: if detected invalid checkpoint enter safe mode if (Checkpoints::hashInvalidCheckpoint != 0) { nPriority = 3000; - strStatusBar = strRPC = "WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade."; + strStatusBar = strRPC = "WARNING: Invalid checkpoint found! Displayed transactions may not be correct! You may need to upgrade, or notify developers of the issue."; } // Alerts @@ -2438,6 +2448,8 @@ string GetWarnings(string strFor) { nPriority = alert.nPriority; strStatusBar = alert.strStatusBar; + if (nPriority > 1000) + strRPC = strStatusBar; // ppcoin: safe mode for high alert } } } @@ -2548,7 +2560,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) static map > mapReuseKey; RandAddSeedPerfmon(); if (fDebug) { - printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); + printf("%s ", DateTimeStrFormat(GetTime()).c_str()); printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); } if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) @@ -2840,8 +2852,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Bypass PushInventory, this must send even if redundant, // and we want it right after the last block so they don't // wait for other stuff first. + // ppcoin: send latest proof-of-work block to allow the + // download node to accept as orphan (proof-of-stake + // block might be rejected by stake connection check) vector vInv; - vInv.push_back(CInv(MSG_BLOCK, hashBestChain)); + vInv.push_back(CInv(MSG_BLOCK, GetLastBlockIndex(pindexBest, false)->GetBlockHash())); pfrom->PushMessage("inv", vInv); pfrom->hashContinue = 0; } @@ -3539,7 +3554,7 @@ public: uint64 nLastBlockTx = 0; uint64 nLastBlockSize = 0; -CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfWorkOnly) +CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) { CReserveKey reservekey(pwallet); @@ -3559,10 +3574,10 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfWorkOnly) pblock->vtx.push_back(txNew); // ppcoin: if coinstake available add coinstake tx - static unsigned int nLastCoinStakeCheckTime = GetAdjustedTime() - nMaxClockDrift + 60; // only initialized at startup + static unsigned int nLastCoinStakeCheckTime = GetAdjustedTime() - nMaxClockDrift / 2; // only initialized at startup CBlockIndex* pindexPrev = pindexBest; - if (!fProofOfWorkOnly) + if (fProofOfStake) { while (nLastCoinStakeCheckTime < GetAdjustedTime()) { @@ -3575,7 +3590,7 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfWorkOnly) // mining may have been suspended for a while so // need to take max to satisfy the timestamp protocol nLastCoinStakeCheckTime++; - nLastCoinStakeCheckTime = max(nLastCoinStakeCheckTime, (unsigned int) (GetAdjustedTime() - nMaxClockDrift + 60)); + nLastCoinStakeCheckTime = max(nLastCoinStakeCheckTime, (unsigned int) (GetAdjustedTime() - nMaxClockDrift / 2)); txCoinStake.nTime = nLastCoinStakeCheckTime; } if (pwallet->CreateCoinStake(pblock->nBits, txCoinStake)) @@ -3821,7 +3836,7 @@ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) printf("BitcoinMiner:\n"); printf("new block found \n hash: %s \ntarget: %s\n", hash.GetHex().c_str(), hashTarget.GetHex().c_str()); pblock->print(); - printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str()); + printf("%s ", DateTimeStrFormat(GetTime()).c_str()); printf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue).c_str()); // Found a solution @@ -3853,9 +3868,9 @@ static bool fGenerateBitcoins = false; static bool fLimitProcessors = false; static int nLimitProcessors = -1; -void static BitcoinMiner(CWallet *pwallet) +void BitcoinMiner(CWallet *pwallet, bool fProofOfStake) { - printf("BitcoinMiner started\n"); + printf("CPUMiner started for proof-of-%s\n", fProofOfStake? "stake" : "work"); SetThreadPriority(THREAD_PRIORITY_LOWEST); // Each thread has its own key and counter @@ -3882,7 +3897,7 @@ void static BitcoinMiner(CWallet *pwallet) unsigned int nTransactionsUpdatedLast = nTransactionsUpdated; CBlockIndex* pindexPrev = pindexBest; - auto_ptr pblock(CreateNewBlock(pwallet)); + auto_ptr pblock(CreateNewBlock(pwallet, fProofOfStake)); if (!pblock.get()) return; @@ -3893,13 +3908,14 @@ void static BitcoinMiner(CWallet *pwallet) { if (!pblock->SignBlock(*pwalletMain)) { - error("BitcoinMiner: Unable to sign new proof-of-stake block"); + error("CPUMiner: Unable to sign new proof-of-stake block"); return; } - printf("BitcoinMiner : proof-of-stake block found %s\n", pblock->GetHash().ToString().c_str()); + printf("CPUMiner : proof-of-stake block found %s\n", pblock->GetHash().ToString().c_str()); SetThreadPriority(THREAD_PRIORITY_NORMAL); CheckWork(pblock.get(), *pwalletMain, reservekey); SetThreadPriority(THREAD_PRIORITY_LOWEST); + Sleep(500); continue; } @@ -3982,7 +3998,7 @@ void static BitcoinMiner(CWallet *pwallet) if (GetTime() - nLogTime > 30 * 60) { nLogTime = GetTime(); - printf("%s ", DateTimeStrFormat("%x %H:%M", GetTime()).c_str()); + printf("%s ", DateTimeStrFormat(GetTime()).c_str()); printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[THREAD_MINER], dHashesPerSec/1000.0); } } @@ -4023,7 +4039,7 @@ void static ThreadBitcoinMiner(void* parg) try { vnThreadsRunning[THREAD_MINER]++; - BitcoinMiner(pwallet); + BitcoinMiner(pwallet, false); vnThreadsRunning[THREAD_MINER]--; } catch (std::exception& e) {