added stake cache + checked ismine
This commit is contained in:
59
src/pos.cpp
59
src/pos.cpp
@@ -154,3 +154,62 @@ bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsig
|
||||
|
||||
return VerifyScript(txin.scriptSig, txout.scriptPubKey, flags, TransactionSignatureChecker(&txTo, nIn), NULL);
|
||||
}
|
||||
|
||||
bool CheckKernel(CBlockIndex* pindexPrev, unsigned int nBits, uint32_t nTimeBlock, const COutPoint& prevout, uint32_t* pBlockTime){
|
||||
std::map<COutPoint, CStakeCache> tmp;
|
||||
return CheckKernel(pindexPrev, nBits, nTimeBlock, prevout, pBlockTime, tmp);
|
||||
}
|
||||
|
||||
bool CheckKernel(CBlockIndex* pindexPrev, unsigned int nBits, uint32_t nTime, const COutPoint& prevout, uint32_t* pBlockTime, const std::map<COutPoint, CStakeCache>& cache)
|
||||
{
|
||||
uint256 hashProofOfStake, targetProofOfStake;
|
||||
auto it=cache.find(prevout);
|
||||
|
||||
if(it == cache.end()) {
|
||||
CTransaction txPrev;
|
||||
CDiskTxPos txindex;
|
||||
if (!ReadFromDisk(txPrev, txindex, *pblocktree, prevout))
|
||||
return false;
|
||||
|
||||
// Read block header
|
||||
CBlock block;
|
||||
const CDiskBlockPos& pos = CDiskBlockPos(txindex.nFile, txindex.nPos);
|
||||
if (!ReadBlockFromDisk(block, pos, Params().GetConsensus()))
|
||||
return false;
|
||||
|
||||
int nDepth;
|
||||
if (IsConfirmedInNPrevBlocks(txindex, pindexPrev, Params().GetConsensus().nStakeMinConfirmations - 1, nDepth))
|
||||
return false;
|
||||
|
||||
if (pBlockTime)
|
||||
*pBlockTime = block.GetBlockTime();
|
||||
|
||||
return CheckStakeKernelHash(pindexPrev, nBits, new CCoins(txPrev, pindexPrev->nHeight), prevout, nTime);
|
||||
}else{
|
||||
//found in cache
|
||||
const CStakeCache& stake = it->second;
|
||||
if (pBlockTime)
|
||||
*pBlockTime = stake.blockFrom.GetBlockTime();
|
||||
return CheckStakeKernelHash(pindexPrev, nBits, new CCoins(stake.txPrev, pindexPrev->nHeight), prevout, nTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CacheKernel(std::map<COutPoint, CStakeCache>& cache, const COutPoint& prevout){
|
||||
if(cache.find(prevout) != cache.end()){
|
||||
//already in cache
|
||||
return;
|
||||
}
|
||||
CTransaction txPrev;
|
||||
CDiskTxPos txindex;
|
||||
if (!ReadFromDisk(txPrev, txindex, *pblocktree, prevout))
|
||||
return;
|
||||
// Read block
|
||||
CBlock block;
|
||||
const CDiskBlockPos& pos = CDiskBlockPos(txindex.nFile, txindex.nPos);
|
||||
if (!ReadBlockFromDisk(block, pos, Params().GetConsensus()))
|
||||
return;
|
||||
CStakeCache c(block, txindex, txPrev);
|
||||
cache.insert({prevout, c});
|
||||
}
|
||||
|
||||
|
||||
11
src/pos.h
11
src/pos.h
@@ -21,11 +21,22 @@ using namespace std;
|
||||
/** Compute the hash modifier for proof-of-stake */
|
||||
uint256 ComputeStakeModifier(const CBlockIndex* pindexPrev, const uint256& kernel);
|
||||
|
||||
struct CStakeCache{
|
||||
CStakeCache(CBlockHeader blockFrom_, CDiskTxPos txindex_, const CTransaction txPrev_) : blockFrom(blockFrom_), txindex(txindex_), txPrev(txPrev_){
|
||||
}
|
||||
CBlockHeader blockFrom;
|
||||
CDiskTxPos txindex;
|
||||
const CTransaction txPrev;
|
||||
};
|
||||
|
||||
// Check whether the coinstake timestamp meets protocol
|
||||
bool CheckCoinStakeTimestamp(int64_t nTimeBlock, int64_t nTimeTx);
|
||||
bool CheckStakeBlockTimestamp(int64_t nTimeBlock);
|
||||
bool CheckKernel(CBlockIndex* pindexPrev, unsigned int nBits, uint32_t nTime, const COutPoint& prevout, uint32_t* pBlockTime = NULL);
|
||||
bool CheckKernel(CBlockIndex* pindexPrev, unsigned int nBits, uint32_t nTime, const COutPoint& prevout, uint32_t* pBlockTime, const std::map<COutPoint, CStakeCache>& cache);
|
||||
bool CheckStakeKernelHash(const CBlockIndex* pindexPrev, unsigned int nBits, const CCoins* txPrev, const COutPoint& prevout, unsigned int nTimeTx);
|
||||
bool IsConfirmedInNPrevBlocks(const CDiskTxPos& txindex, const CBlockIndex* pindexFrom, int nMaxDepth, int& nActualDepth);
|
||||
bool CheckProofOfStake(CBlockIndex* pindexPrev, const CTransaction& tx, unsigned int nBits, CValidationState &state);
|
||||
void CacheKernel(std::map<COutPoint, CStakeCache>& cache, const COutPoint& prevout);
|
||||
bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType);
|
||||
#endif // BLACKCOIN_POS_H
|
||||
|
||||
@@ -67,7 +67,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||
CScript subscript;
|
||||
if (keystore.GetCScript(scriptID, subscript)) {
|
||||
isminetype ret = IsMine(keystore, subscript);
|
||||
if (ret == ISMINE_SPENDABLE)
|
||||
if (ret == ISMINE_SPENDABLE || ret == ISMINE_WATCH_SOLVABLE || ret == ISMINE_NO)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
@@ -84,6 +84,9 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
|
||||
return ISMINE_SPENDABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (keystore.HaveWatchOnly(scriptPubKey)) {
|
||||
|
||||
@@ -661,31 +661,6 @@ bool CWallet::SelectCoinsForStaking(CAmount& nTargetValue, std::set<std::pair<co
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckKernel(CBlockIndex* pindexPrev, unsigned int nBits, int64_t nTime, const COutPoint& prevout, int64_t* pBlockTime)
|
||||
{
|
||||
uint256 hashProofOfStake, targetProofOfStake;
|
||||
|
||||
CTransaction txPrev;
|
||||
CDiskTxPos txindex;
|
||||
if (!ReadFromDisk(txPrev, txindex, *pblocktree, prevout))
|
||||
return false;
|
||||
|
||||
// Read block header
|
||||
CBlock block;
|
||||
const CDiskBlockPos& pos = CDiskBlockPos(txindex.nFile, txindex.nPos);
|
||||
if (!ReadBlockFromDisk(block, pos, Params().GetConsensus()))
|
||||
return false;
|
||||
|
||||
int nDepth;
|
||||
if (IsConfirmedInNPrevBlocks(txindex, pindexPrev, Params().GetConsensus().nStakeMinConfirmations - 1, nDepth))
|
||||
return false;
|
||||
|
||||
if (pBlockTime)
|
||||
*pBlockTime = block.GetBlockTime();
|
||||
|
||||
return CheckStakeKernelHash(pindexPrev, nBits, new CCoins(txPrev, pindexPrev->nHeight), prevout, nTime);
|
||||
}
|
||||
|
||||
// miner's coin stake reward
|
||||
int64_t GetProofOfStakeReward(const CBlockIndex* pindexPrev, int64_t nCoinAge, int64_t nFees)
|
||||
{
|
||||
@@ -735,6 +710,21 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
|
||||
if (setCoins.empty())
|
||||
return false;
|
||||
|
||||
static std::map<COutPoint, CStakeCache> stakeCache;
|
||||
if(stakeCache.size() > setCoins.size() + 100){
|
||||
//Determining if the cache is still valid is harder than just clearing it when it gets too big, so instead just clear it
|
||||
//when it has more than 100 entries more than the actual setCoins.
|
||||
stakeCache.clear();
|
||||
}
|
||||
if(GetBoolArg("-stakecache", DEFAULT_STAKE_CACHE)) {
|
||||
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*, unsigned int)& pcoin, setCoins)
|
||||
{
|
||||
boost::this_thread::interruption_point();
|
||||
COutPoint prevoutStake = COutPoint(pcoin.first->GetHash(), pcoin.second);
|
||||
CacheKernel(stakeCache, prevoutStake); //this will do a 2 disk loads per op
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int64_t nCredit = 0;
|
||||
CScript scriptPubKeyKernel;
|
||||
@@ -748,9 +738,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int
|
||||
// Search backward in time from the given txNew timestamp
|
||||
// Search nSearchInterval seconds back up to nMaxStakeSearchInterval
|
||||
COutPoint prevoutStake = COutPoint(pcoin.first->GetHash(), pcoin.second);
|
||||
int64_t nBlockTime;
|
||||
uint32_t nBlockTime;
|
||||
//LogPrintf("looking for coinstake \n");
|
||||
if (CheckKernel(pindexPrev, nBits, txNew.nTime - n, prevoutStake, &nBlockTime))
|
||||
if (CheckKernel(pindexPrev, nBits, txNew.nTime - n, prevoutStake, &nBlockTime, stakeCache))
|
||||
{
|
||||
// Found a kernel
|
||||
LogPrint("coinstake", "CreateCoinStake : kernel found\n");
|
||||
|
||||
@@ -932,6 +932,7 @@ public:
|
||||
|
||||
/* Set the current HD master key (will reset the chain child index counters) */
|
||||
bool SetHDMasterKey(const CPubKey& key);
|
||||
static const bool DEFAULT_STAKE_CACHE = true;
|
||||
};
|
||||
|
||||
/** A key allocated from the key pool. */
|
||||
@@ -989,5 +990,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
bool CheckKernel(CBlockIndex* pindexPrev, unsigned int nBits, int64_t nTime, const COutPoint& prevout, int64_t* pBlockTime = NULL);
|
||||
#endif // BITCOIN_WALLET_WALLET_H
|
||||
|
||||
Reference in New Issue
Block a user