Add CCoinsViewCache::GetCoinsReadOnly() method for read-only caching to decrease...
authoralex <alex@alex-VirtualBox.(none)>
Mon, 20 Jan 2014 22:40:34 +0000 (02:40 +0400)
committeralex <alex@alex-VirtualBox.(none)>
Mon, 20 Jan 2014 22:40:34 +0000 (02:40 +0400)
Remove target mismatch messages from proof-of-stake miner;
Add generator field to getblock output.

src/kernel.cpp
src/kernel.h
src/main.cpp
src/main.h
src/miner.cpp
src/rpcblockchain.cpp
src/wallet.cpp

index 5cf4b34..b099b54 100644 (file)
@@ -270,7 +270,7 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier
 //   quantities so as to generate blocks faster, degrading the system back into
 //   a proof-of-work situation.
 //
-bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool& fFatal, bool fPrintProofOfStake)
+bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool& fFatal, bool fMiner, bool fPrintProofOfStake)
 {
     if (nTimeTx < txPrev.nTime)  // Transaction timestamp violation
     {
@@ -324,7 +324,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned
     if (CBigNum(hashProofOfStake) > bnCoinDayWeight * bnTargetPerCoinDay)
     {
         fFatal = true;
-        return error("CheckStakeKernelHash() : proof-of-stake for block %s not meeting target", hashBlockFrom.ToString().c_str());
+        return !fMiner? error("CheckStakeKernelHash() : proof-of-stake not meeting target") : false;
     }
 
     if (fDebug && !fPrintProofOfStake)
@@ -343,7 +343,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned
 }
 
 // Check kernel hash target and coinstake signature
-bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake, bool& fFatal)
+bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake, bool& fFatal, bool fMiner)
 {
     if (!tx.IsCoinStake())
     {
@@ -360,7 +360,7 @@ bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hash
     CCoins coins;
     CCoinsViewCache &view = *pcoinsTip;
 
-    if (!view.GetCoins(txin.prevout.hash, coins))
+    if (!view.GetCoinsReadOnly(txin.prevout.hash, coins))
         return fDebug? error("CheckProofOfStake() : INFO: read coins for txPrev failed") : false;  // previous transaction not in main chain, may occur during initial download
 
     CBlockIndex* pindex = FindBlockByHeight(coins.nHeight);
@@ -387,7 +387,7 @@ bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hash
         return error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx.GetHash().ToString().c_str());
     }
 
-    if (!CheckStakeKernelHash(nBits, block, nTxPos, txPrev, txin.prevout, tx.nTime, hashProofOfStake, targetProofOfStake, fFatal, fDebug))
+    if (!CheckStakeKernelHash(nBits, block, nTxPos, txPrev, txin.prevout, tx.nTime, hashProofOfStake, targetProofOfStake, fFatal, fMiner, fDebug))
     {
         if (fFatal)
             return false;
index 246feb2..6b9cd6b 100644 (file)
@@ -18,11 +18,11 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexPrev, uint64& nStakeModif
 
 // Check whether stake kernel meets hash target
 // Sets hashProofOfStake and targetProofOfStake on success return
-bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool& fFatal, bool fPrintProofOfStake=false);
+bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned int nTxPrevOffset, const CTransaction& txPrev, const COutPoint& prevout, unsigned int nTimeTx, uint256& hashProofOfStake, uint256& targetProofOfStake, bool& fFatal, bool fMiner=false, bool fPrintProofOfStake=false);
 
 // Check kernel hash target and coinstake signature
 // Sets hashProofOfStake and targetProofOfStake on success return
-bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake, bool& fFatal);
+bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake, bool& fFatal, bool fMiner=false);
 
 // Check whether the coinstake timestamp meets protocol
 bool CheckCoinStakeTimestamp(int64 nTimeBlock, int64 nTimeTx);
index ce8748b..c632ba7 100644 (file)
@@ -220,6 +220,23 @@ bool CCoinsViewCache::GetCoins(uint256 txid, CCoins &coins) {
     return false;
 }
 
+// Select coins from read-only cache or database
+bool CCoinsViewCache::GetCoinsReadOnly(uint256 txid, CCoins &coins) {
+    if (cacheCoins.count(txid)) {
+        coins = cacheCoins[txid]; // get from cache
+        return true;
+    }
+    if (cacheCoinsReadOnly.count(txid)) {
+        coins = cacheCoinsReadOnly[txid]; // get from read-only cache
+        return true;
+    }
+    if (base->GetCoins(txid, coins)) {
+        cacheCoinsReadOnly[txid] = coins; // save to read-only cache
+        return true;
+    }
+    return false;
+}
+
 bool CCoinsViewCache::SetCoins(uint256 txid, const CCoins &coins) {
     cacheCoins[txid] = coins;
     return true;
@@ -248,6 +265,8 @@ bool CCoinsViewCache::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlo
 }
 
 bool CCoinsViewCache::Flush() {
+    cacheCoinsReadOnly.clear(); // purge read-only cache
+
     bool fOk = base->BatchWrite(cacheCoins, pindexTip);
     if (fOk)
         cacheCoins.clear();
index ace3a8b..5fb66e1 100644 (file)
@@ -2009,10 +2009,12 @@ class CCoinsViewCache : public CCoinsViewBacked
 protected:
     CBlockIndex *pindexTip;
     std::map<uint256,CCoins> cacheCoins;
+    std::map<uint256,CCoins> cacheCoinsReadOnly;
 
 public:
     CCoinsViewCache(CCoinsView &baseIn, bool fDummy = false);
     bool GetCoins(uint256 txid, CCoins &coins);
+    bool GetCoinsReadOnly(uint256 txid, CCoins &coins);
     bool SetCoins(uint256 txid, const CCoins &coins);
     bool HaveCoins(uint256 txid);
     CBlockIndex *GetBestBlock();
index b7b8db0..756cf6f 100644 (file)
@@ -484,7 +484,7 @@ bool CheckStake(CBlock* pblock, CWallet& wallet)
         return error("CheckStake() : %s is not a proof-of-stake block", hashBlock.GetHex().c_str());
 
     // verify hash target and signature of coinstake tx
-    if (!CheckProofOfStake(pblock->vtx[1], pblock->nBits, proofHash, hashTarget, fFatal))
+    if (!CheckProofOfStake(pblock->vtx[1], pblock->nBits, proofHash, hashTarget, fFatal, true))
         return error("CheckStake() : proof-of-stake checking failed");
 
     //// debug print
index 3d2aacd..3f9241e 100644 (file)
@@ -138,8 +138,13 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool fPri
 
     result.push_back(Pair("tx", txinfo));
 
-    if ( block.IsProofOfStake() || (!fTestNet && block.GetBlockTime() < ENTROPY_SWITCH_TIME) )
-        result.push_back(Pair("signature", HexStr(block.vchBlockSig.begin(), block.vchBlockSig.end())));
+    if ( block.IsProofOfStake() )
+    {
+        CKey key;
+        block.GetGenerator(key);
+        result.push_back(Pair("generator", HexStr(key.GetPubKey().Raw())));
+        result.push_back(Pair("signature", HexStr(block.vchBlockSig)));
+    }
 
     return result;
 }
index b3c1b25..55630af 100644 (file)
@@ -1452,7 +1452,7 @@ bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint
         CCoins coins;
         {
             LOCK2(cs_main, cs_wallet);
-            if (!view.GetCoins(pcoin.first->GetHash(), coins))
+            if (!view.GetCoinsReadOnly(pcoin.first->GetHash(), coins))
                 continue;
         }
 
@@ -1528,7 +1528,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
         CCoins coins;
         {
             LOCK2(cs_main, cs_wallet);
-            if (!view.GetCoins(pcoin.first->GetHash(), coins))
+            if (!view.GetCoinsReadOnly(pcoin.first->GetHash(), coins))
                 continue;
         }
 
@@ -1558,13 +1558,13 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
 
         bool fFatal = false;
         bool fKernelFound = false;
-        for (unsigned int n=0; n<min(nSearchInterval,(int64)nMaxStakeSearchInterval) && !fKernelFound && !fShutdown && pindexPrev == pindexBest && !fFatal; n++)
+        for (unsigned int n=0; n<min(nSearchInterval,(int64)nMaxStakeSearchInterval) && !fKernelFound && !fShutdown && pindexPrev == pindexBest; n++)
         {
             // Search backward in time from the given txNew timestamp 
             // Search nSearchInterval seconds back up to nMaxStakeSearchInterval
             uint256 hashProofOfStake = 0, targetProofOfStake = 0;
             COutPoint prevoutStake = COutPoint(pcoin.first->GetHash(), pcoin.second);
-            if (CheckStakeKernelHash(nBits, block, nTxPos, *pcoin.first, prevoutStake, txNew.nTime - n, hashProofOfStake, targetProofOfStake, fFatal))
+            if (CheckStakeKernelHash(nBits, block, nTxPos, *pcoin.first, prevoutStake, txNew.nTime - n, hashProofOfStake, targetProofOfStake, fFatal, true))
             {
                 // Found a kernel
                 if (fDebug && GetBoolArg("-printcoinstake"))