X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fkernel.cpp;h=18db341bc1b2a4fd92c429a8893a3d5b56388149;hb=f5875a9a87b3341857381e847703cc4ae4890737;hp=bf3fadeff668e43ff02c540aac25eab09d23e13d;hpb=1cb6116de830fb37b6961a8bd424b9368b397bee;p=novacoin.git diff --git a/src/kernel.cpp b/src/kernel.cpp index bf3fade..18db341 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -298,6 +298,15 @@ static bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier return true; } +bool GetKernelStakeModifier(uint256 hashBlockFrom, uint64& nStakeModifier) +{ + int nStakeModifierHeight; + int64 nStakeModifierTime; + + return GetKernelStakeModifier(hashBlockFrom, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, false); +} + + // ppcoin kernel protocol // coinstake must meet hash target according to the protocol: // kernel (input 0) must meet the formula @@ -380,6 +389,82 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned return true; } +// Scan given coins set for kernel solution +bool ScanForStakeKernelHash(CoinsSet &setCoins, MetaMap &mapMeta, KernelSearchSettings &settings, CoinsSet::value_type &kernelcoin, unsigned int &nTimeTx, unsigned int &nBlockTime) +{ + uint256 hashProofOfStake = 0; + + for(CoinsSet::const_iterator pcoin = setCoins.begin(); pcoin != setCoins.end(); pcoin++) + { + if (!fCoinsDataActual) + break; + + MetaMap::const_iterator mi = mapMeta.find(pcoin->first->GetHash()); + if (mi == mapMeta.end()) + { + if (fDebug) + printf("Unable to find %s in mapMeta, stopping\n", pcoin->first->GetHash().GetHex().c_str()); + fCoinsDataActual = false; + break; + } + + CTxIndex txindex = (*mi).second.first; + CBlock block = (*mi).second.second.first; + uint64 nStakeModifier = (*mi).second.second.second; + + static int nMaxStakeSearchInterval = 60; + + // only count coins meeting min age requirement + if (nStakeMinAge + block.nTime > settings.nTime - nMaxStakeSearchInterval) + continue; + + // Transaction offset inside block + unsigned int nTxOffset = txindex.pos.nTxPos - txindex.pos.nBlockPos; + + // Current timestamp scanning interval + unsigned int nCurrentSearchInterval = min((int64)settings.nSearchInterval, (int64)nMaxStakeSearchInterval); + + nBlockTime = block.nTime; + CBigNum bnTargetPerCoinDay; + bnTargetPerCoinDay.SetCompact(settings.nBits); + int64 nValueIn = pcoin->first->vout[pcoin->second].nValue; + + // Search backward in time from the given timestamp + // Search nSearchInterval seconds back up to nMaxStakeSearchInterval + // Stopping search in case of shutting down or cache invalidation + for (unsigned int n=0; nfirst->nTime, (int64)nTimeTx) / COIN / (24 * 60 * 60); + CBigNum bnTargetProofOfStake = bnCoinDayWeight * bnTargetPerCoinDay; + + // Build kernel + CDataStream ss(SER_GETHASH, 0); + ss << nStakeModifier; + ss << nBlockTime << nTxOffset << pcoin->first->nTime << pcoin->second << nTimeTx; + + // Calculate kernel hash + hashProofOfStake = Hash(ss.begin(), ss.end()); + + if (bnTargetProofOfStake >= CBigNum(hashProofOfStake)) + { + if (fDebug) + printf("nStakeModifier=0x%016"PRI64x", nBlockTime=%u nTxOffset=%u nTxPrevTime=%u nVout=%u nTimeTx=%u hashProofOfStake=%s Success=true\n", + nStakeModifier, nBlockTime, nTxOffset, pcoin->first->nTime, pcoin->second, nTimeTx, hashProofOfStake.GetHex().c_str()); + + kernelcoin = *pcoin; + return true; + } + + if (fDebug) + printf("nStakeModifier=0x%016"PRI64x", nBlockTime=%u nTxOffset=%u nTxPrevTime=%u nTxNumber=%u nTimeTx=%u hashProofOfStake=%s Success=false\n", + nStakeModifier, nBlockTime, nTxOffset, pcoin->first->nTime, pcoin->second, nTimeTx, hashProofOfStake.GetHex().c_str()); + } + } + + return false; +} + // Check kernel hash target and coinstake signature bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hashProofOfStake, uint256& targetProofOfStake) { @@ -396,8 +481,12 @@ bool CheckProofOfStake(const CTransaction& tx, unsigned int nBits, uint256& hash if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) return tx.DoS(1, error("CheckProofOfStake() : INFO: read txPrev failed")); // previous transaction not in main chain, may occur during initial download +#ifndef USE_LEVELDB + txdb.Close(); +#endif + // Verify signature - if (!VerifySignature(txPrev, tx, 0, STANDARD_SCRIPT_VERIFY_FLAGS, 0)) + if (!VerifySignature(txPrev, tx, 0, MANDATORY_SCRIPT_VERIFY_FLAGS, 0)) return tx.DoS(100, error("CheckProofOfStake() : VerifySignature failed on coinstake %s", tx.GetHash().ToString().c_str())); // Read block header