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;
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;
// 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;
}
map<uint256, CAlert> mapAlerts;
CCriticalSection cs_mapAlerts;
+static string strMintMessage = _("Info: Minting suspended due to locked wallet.");
+static string strMintWarning;
+
string GetWarnings(string strFor)
{
int nPriority = 0;
if (GetBoolArg("-testsafemode"))
strRPC = "test";
+ // ppcoin: wallet lock warning for minting
+ if (strMintWarning != "")
+ {
+ nPriority = 0;
+ strStatusBar = strMintWarning;
+ }
+
// Misc warnings like out of disk space and clock is wrong
if (strMiscWarning != "")
{
uint64 nLastBlockTx = 0;
uint64 nLastBlockSize = 0;
-CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfWorkOnly)
+// CreateNewBlock:
+// fProofOfStake: try (best effort) to make a proof-of-stake block
+CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake)
{
CReserveKey reservekey(pwallet);
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) // attemp to find a coinstake
{
while (nLastCoinStakeCheckTime < GetAdjustedTime())
{
// 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))
// Fill in header
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
- pblock->nTime = max(pblock->GetBlockTime(), pblock->GetMaxTransactionTime());
+ pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, pblock->GetMaxTransactionTime());
pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift);
pblock->UpdateTime(pindexPrev);
pblock->nNonce = 0;
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
CReserveKey reservekey(pwallet);
unsigned int nExtraNonce = 0;
- while (fGenerateBitcoins)
+ while (fGenerateBitcoins || fProofOfStake)
{
if (fShutdown)
return;
Sleep(1000);
if (fShutdown)
return;
- if (!fGenerateBitcoins)
+ if ((!fGenerateBitcoins) && !fProofOfStake)
return;
}
+ while (pwallet->IsLocked())
+ {
+ strMintWarning = strMintMessage;
+ Sleep(1000);
+ }
+ strMintWarning = "";
//
// Create new block
unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
CBlockIndex* pindexPrev = pindexBest;
- auto_ptr<CBlock> pblock(CreateNewBlock(pwallet));
+ auto_ptr<CBlock> pblock(CreateNewBlock(pwallet, fProofOfStake));
if (!pblock.get())
return;
IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);
// ppcoin: if proof-of-stake block found then process block
- if (pblock->IsProofOfStake())
+ if (fProofOfStake)
{
- if (!pblock->SignBlock(*pwalletMain))
+ if (pblock->IsProofOfStake())
{
- error("BitcoinMiner: Unable to sign new proof-of-stake block");
- return;
+ if (!pblock->SignBlock(*pwalletMain))
+ {
+ strMintWarning = strMintMessage;
+ continue;
+ }
+ strMintWarning = "";
+ 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);
}
- printf("BitcoinMiner : 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;
}
assert(hash == pblock->GetHash());
if (!pblock->SignBlock(*pwalletMain))
{
- error("BitcoinMiner: Unable to sign new proof-of-work block");
- return;
+ strMintWarning = strMintMessage;
+ break;
}
-
+ strMintWarning = "";
SetThreadPriority(THREAD_PRIORITY_NORMAL);
CheckWork(pblock.get(), *pwalletMain, reservekey);
SetThreadPriority(THREAD_PRIORITY_LOWEST);
break;
// Update nTime every few seconds
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
- pblock->nTime = max(pblock->GetBlockTime(), pblock->GetMaxTransactionTime());
+ pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, pblock->GetMaxTransactionTime());
pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift);
pblock->UpdateTime(pindexPrev);
nBlockTime = ByteReverse(pblock->nTime);
try
{
vnThreadsRunning[THREAD_MINER]++;
- BitcoinMiner(pwallet);
+ BitcoinMiner(pwallet, false);
vnThreadsRunning[THREAD_MINER]--;
}
catch (std::exception& e) {