X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=149e02ff8801db2fcf34a56ada760c84b64339f4;hb=d008ea3376606276a86ed3c972654363eb23f47d;hp=2ea0ef929526a2927b4ed9ecf057ca4cda37f725;hpb=7ee562be0d193150f2e57787744175d017540f9e;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index 2ea0ef9..149e02f 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -13,8 +13,10 @@ #include "coincontrol.h" #include +#include "main.h" + using namespace std; -extern int nStakeMaxAge; + bool fCoinsDataActual; @@ -391,6 +393,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock) wtx.MarkSpent(txin.prevout.n); wtx.WriteToDisk(); NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED); + vMintingWalletUpdated.push_back(txin.prevout.hash); } } } @@ -408,6 +411,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock) wtx.MarkUnspent(&txout - &tx.vout[0]); wtx.WriteToDisk(); NotifyTransactionChanged(this, hash, CT_UPDATED); + vMintingWalletUpdated.push_back(hash); } } } @@ -538,7 +542,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) // Notify UI of new or updated transaction NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED); - + vMintingWalletUpdated.push_back(hash); // notify an external script when a wallet transaction comes in or is updated std::string strCmd = GetArg("-walletnotify", ""); @@ -644,8 +648,7 @@ bool CWallet::IsChange(const CTxOut& txout) const int64 CWalletTx::GetTxTime() const { - int64 n = nTimeSmart; - return n ? n : nTimeReceived; + return nTime; } int CWalletTx::GetRequestCount() const @@ -907,7 +910,7 @@ void CWallet::ReacceptWalletTransactions() // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat if (txindex.vSpent.size() != wtx.vout.size()) { - printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %"PRIszu" != wtx.vout.size() %"PRIszu"\n", txindex.vSpent.size(), wtx.vout.size()); + printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %" PRIszu " != wtx.vout.size() %" PRIszu "\n", txindex.vSpent.size(), wtx.vout.size()); continue; } for (unsigned int i = 0; i < txindex.vSpent.size(); i++) @@ -1622,41 +1625,37 @@ void CWallet::GetStakeWeightFromValue(const int64& nTime, const int64& nValue, u } -// NovaCoin: get current stake weight -bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight) +// NovaCoin: get current stake miner statistics +void CWallet::GetStakeStats(float &nKernelsRate, float &nCoinDaysRate) { - if (mapMeta.size() == 0 || !fCoinsDataActual) - return false; + static uint64 nLastKernels = 0, nLastCoinDays = 0; + static float nLastKernelsRate = 0, nLastCoinDaysRate = 0; + static int64 nLastTime = GetTime(); - // txid => ((txindex, (tx, vout.n)), (block, modifier)) - for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++) + if (nKernelsTried < nLastKernels) { - // Get coin - CoinsSet::value_type pcoin = meta_item->second.first.second; + nLastKernels = 0; + nLastCoinDays = 0; - int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)GetTime()); - CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60); - - // Weight is greater than zero - if (nTimeWeight > 0) - { - nWeight += bnCoinDayWeight.getuint64(); - } + nLastTime = GetTime(); + } - // Weight is greater than zero, but the maximum value isn't reached yet - if (nTimeWeight > 0 && nTimeWeight < nStakeMaxAge) - { - nMinWeight += bnCoinDayWeight.getuint64(); - } + int64 nInterval = GetTime() - nLastTime; + //if (nKernelsTried > 1000 && nInterval > 5) + if (nInterval > 10) + { + nKernelsRate = nLastKernelsRate = ( nKernelsTried - nLastKernels ) / (float) nInterval; + nCoinDaysRate = nLastCoinDaysRate = ( nCoinDaysTried - nLastCoinDays ) / (float) nInterval; - // Maximum weight was reached - if (nTimeWeight == nStakeMaxAge) - { - nMaxWeight += bnCoinDayWeight.getuint64(); - } + nLastKernels = nKernelsTried; + nLastCoinDays = nCoinDaysTried; + nLastTime = GetTime(); + } + else + { + nKernelsRate = nLastKernelsRate; + nCoinDaysRate = nLastCoinDaysRate; } - - return true; } bool CWallet::MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nOutputValue, list& listMerged) @@ -1846,7 +1845,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int // Add meta record // txid => ((txindex, (tx, vout.n)), (block, modifier)) - mapMeta[pcoin->first->GetHash()] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier)); + mapMeta[make_pair(pcoin->first->GetHash(), pcoin->second)] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier)); if (fDebug) printf("Load coin: %s\n", pcoin->first->GetHash().GetHex().c_str()); @@ -1854,9 +1853,11 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int } if (fDebug) - printf("Stake miner: %zu meta items loaded for %zu coins\n", mapMeta.size(), setCoins.size()); + printf("Stake miner: %" PRIszu " meta items loaded for %" PRIszu " coins\n", mapMeta.size(), setCoins.size()); fCoinsDataActual = true; + nKernelsTried = 0; + nCoinDaysTried = 0; } } @@ -1874,7 +1875,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int COutPoint prevoutStake; CoinsSet::value_type kernelcoin; - if (ScanForStakeKernelHash(mapMeta, settings, kernelcoin, nTimeTx, nBlockTime)) + if (ScanForStakeKernelHash(mapMeta, settings, kernelcoin, nTimeTx, nBlockTime, nKernelsTried, nCoinDaysTried)) { // Found a kernel if (fDebug && GetBoolArg("-printcoinstake")) @@ -1942,7 +1943,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (nCredit == 0 || nCredit > nBalance - nReserveBalance) return false; - // txid => ((txindex, (tx, vout.n)), (block, modifier)) + // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier)) for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++) { // Get coin @@ -1983,7 +1984,13 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int CTxDB txdb("r"); if (!txNew.GetCoinAge(txdb, nCoinAge)) return error("CreateCoinStake : failed to calculate coin age"); - nCredit += GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime); + + int64 nReward = GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime); + // Refuse to create mint that has zero or negative reward + if(nReward <= 0) + return false; + + nCredit += nReward; } int64 nMinFee = 0; @@ -2058,6 +2065,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) coin.MarkSpent(txin.prevout.n); coin.WriteToDisk(); NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED); + vMintingWalletUpdated.push_back(coin.GetHash()); } if (fFileBacked) @@ -2192,12 +2200,12 @@ void CWallet::PrintWallet(const CBlock& block) if (block.IsProofOfWork() && mapWallet.count(block.vtx[0].GetHash())) { CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()]; - printf(" mine: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); + printf(" mine: %d %d %" PRI64d "", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); } if (block.IsProofOfStake() && mapWallet.count(block.vtx[1].GetHash())) { CWalletTx& wtx = mapWallet[block.vtx[1].GetHash()]; - printf(" stake: %d %d %"PRI64d"", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); + printf(" stake: %d %d %" PRI64d "", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit()); } } @@ -2260,7 +2268,7 @@ bool CWallet::NewKeyPool() walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey())); setKeyPool.insert(nIndex); } - printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys); + printf("CWallet::NewKeyPool wrote %" PRI64d " new keys\n", nKeys); } return true; } @@ -2290,7 +2298,7 @@ bool CWallet::TopUpKeyPool(unsigned int nSize) if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) throw runtime_error("TopUpKeyPool() : writing generated key failed"); setKeyPool.insert(nEnd); - printf("keypool added key %"PRI64d", size=%"PRIszu"\n", nEnd, setKeyPool.size()); + printf("keypool added key %" PRI64d ", size=%" PRIszu "\n", nEnd, setKeyPool.size()); } } return true; @@ -2320,7 +2328,7 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); assert(keypool.vchPubKey.IsValid()); if (fDebug && GetBoolArg("-printkeypool")) - printf("keypool reserve %"PRI64d"\n", nIndex); + printf("keypool reserve %" PRI64d "\n", nIndex); } } @@ -2348,7 +2356,7 @@ void CWallet::KeepKey(int64 nIndex) walletdb.ErasePool(nIndex); } if(fDebug) - printf("keypool keep %"PRI64d"\n", nIndex); + printf("keypool keep %" PRI64d "\n", nIndex); } void CWallet::ReturnKey(int64 nIndex) @@ -2359,7 +2367,7 @@ void CWallet::ReturnKey(int64 nIndex) setKeyPool.insert(nIndex); } if(fDebug) - printf("keypool return %"PRI64d"\n", nIndex); + printf("keypool return %" PRI64d "\n", nIndex); } bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse) @@ -2663,7 +2671,10 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx) // Only notify UI if this transaction is in this wallet map::const_iterator mi = mapWallet.find(hashTx); if (mi != mapWallet.end()) + { NotifyTransactionChanged(this, hashTx, CT_UPDATED); + vMintingWalletUpdated.push_back(hashTx); + } } } @@ -2717,3 +2728,21 @@ void CWallet::GetKeyBirthTimes(std::map &mapKeyBirth) const { for (std::map::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++) mapKeyBirth[it->first] = it->second->nTime - 7200; // block times can be 2h off } + +void CWallet::ClearOrphans() +{ + list orphans; + + LOCK(cs_wallet); + for(map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx *wtx = &(*it).second; + if((wtx->IsCoinBase() || wtx->IsCoinStake()) && !wtx->IsInMainChain()) + { + orphans.push_back(wtx->GetHash()); + } + } + + for(list::const_iterator it = orphans.begin(); it != orphans.end(); ++it) + EraseFromWallet(*it); +}