Skip to content

Commit

Permalink
Add CCoinsViewCache::GetCoinsReadOnly() method for read-only caching …
Browse files Browse the repository at this point in the history
…to decrease count of worthless flushing events;

Remove target mismatch messages from proof-of-stake miner;
Add generator field to getblock output.
  • Loading branch information
alex authored and alex committed Jan 20, 2014
1 parent 6b190c1 commit 4a1fde4
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 14 deletions.
10 changes: 5 additions & 5 deletions src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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)
Expand All @@ -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())
{
Expand All @@ -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);
Expand All @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
19 changes: 19 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 2 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 7 additions & 2 deletions src/rpcblockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
8 changes: 4 additions & 4 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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"))
Expand Down

0 comments on commit 4a1fde4

Please sign in to comment.