X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=2645f8cf5c946171ea0f4fb54eb1e4efb45f58b2;hb=3176e0f244d929669aa3e1d81e0787d82d9150d3;hp=1066dff2d4da66473a991290fae440f2717aa237;hpb=7552b10584388bb3509e046bf11b66578e965814;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index 1066dff..2645f8c 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1,14 +1,15 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers -// Copyright (c) 2011-2012 The PPCoin developers +// Copyright (c) 2011-2013 The PPCoin developers +// Copyright (c) 2013 NovaCoin Developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "wallet.h" #include "walletdb.h" #include "crypter.h" -#include "checkpoints.h" #include "ui_interface.h" +#include "kernel.h" using namespace std; @@ -18,9 +19,9 @@ using namespace std; // mapWallet // -std::vector CWallet::GenerateNewKey() +std::vector CWallet::GenerateNewKey(bool bCompressed = true) { - bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets + bool fCompressed = bCompressed ? CanSupportFeature(FEATURE_COMPRPUBKEY) : false; // default to compressed public keys if we want 0.6.0 wallets RandAddSeedPerfmon(); CKey key; @@ -71,7 +72,7 @@ bool CWallet::AddCScript(const CScript& redeemScript) return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript); } -// ppcoin: optional setting to create coinstake only when unlocked; +// ppcoin: optional setting to unlock wallet for block minting only; // serves to disable the trivial sendmoney when OS account compromised bool fWalletUnlockMintOnly = false; @@ -834,7 +835,10 @@ void CWallet::ResendWalletTransactions() BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted) { CWalletTx& wtx = *item.second; - wtx.RelayWalletTransaction(txdb); + if (wtx.CheckTransaction()) + wtx.RelayWalletTransaction(txdb); + else + printf("ResendWalletTransactions() : CheckTransaction failed for transaction %s\n", wtx.GetHash().ToString().c_str()); } } } @@ -1247,21 +1251,18 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int CBlock block; if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) continue; - if (block.GetBlockTime() + nStakeMinAge > txNew.nTime - (60 * 60 * 2)) + static int nMaxStakeSearchInterval = 60; + if (block.GetBlockTime() + nStakeMinAge > txNew.nTime - nMaxStakeSearchInterval) continue; // only count coins meeting min age requirement - int64 nValueIn = pcoin.first->vout[pcoin.second].nValue; - CBigNum bnCoinDay = CBigNum(nValueIn) * min(txNew.nTime-pcoin.first->nTime, (unsigned int)STAKE_MAX_AGE) / COIN / (24 * 60 * 60); - bool fKernelFound = false; - for (int n=0; nnTime << pcoin.second << txNew.nTime; - if (CBigNum(Hash(ss.begin(), ss.end())) <= bnCoinDay * bnTargetPerCoinDay) + // Search backward in time from the given txNew timestamp + // Search nSearchInterval seconds back up to nMaxStakeSearchInterval + uint256 hashProofOfStake = 0; + COutPoint prevoutStake = COutPoint(pcoin.first->GetHash(), pcoin.second); + if (CheckStakeKernelHash(nBits, block, txindex.pos.nTxPos - txindex.pos.nBlockPos, *pcoin.first, prevoutStake, txNew.nTime - n, hashProofOfStake)) { // Found a kernel if (fDebug && GetBoolArg("-printcoinstake")) @@ -1298,7 +1299,8 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int } else scriptPubKeyOut = scriptPubKeyKernel; - + + txNew.nTime -= n; txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); nCredit += pcoin.first->vout[pcoin.second].nValue; vwtxPrev.push_back(pcoin.first); @@ -1308,6 +1310,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (fDebug && GetBoolArg("-printcoinstake")) printf("CreateCoinStake : added kernel type=%d\n", whichType); fKernelFound = true; + break; } } if (fKernelFound || fShutdown) @@ -1322,6 +1325,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey)) && pcoin.first->GetHash() != txNew.vin[0].prevout.hash) { + // Stop adding more inputs if already too many inputs + if (txNew.vin.size() >= 100) + break; // Stop adding more inputs if value is already pretty significant if (nCredit > nCombineThreshold) break; @@ -1331,6 +1337,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int // Do not add additional significant input if (pcoin.first->vout[pcoin.second].nValue > nCombineThreshold) continue; + // Do not add input that is still too young + if (pcoin.first->nTime + STAKE_MAX_AGE > txNew.nTime) + continue; txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); nCredit += pcoin.first->vout[pcoin.second].nValue; vwtxPrev.push_back(pcoin.first); @@ -1368,7 +1377,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int // Limit size unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); if (nBytes >= MAX_BLOCK_SIZE_GEN/5) - return false; + return error("CreateCoinStake : exceeded coinstake size limit"); // Check enough fee is paid if (nMinFee < txNew.GetMinFee() - MIN_TX_FEE) @@ -1751,45 +1760,8 @@ int64 CWallet::GetOldestKeyPoolTime() } // ppcoin: check 'spent' consistency between wallet and txindex -bool CWallet::CheckSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion) -{ - nMismatchFound = 0; - nBalanceInQuestion = 0; - - LOCK(cs_wallet); - vector vCoins; - vCoins.reserve(mapWallet.size()); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) - vCoins.push_back(&(*it).second); - - CTxDB txdb("r"); - BOOST_FOREACH(const CWalletTx* pcoin, vCoins) - { - // Find the corresponding transaction index - CTxIndex txindex; - if (!txdb.ReadTxIndex(pcoin->GetHash(), txindex)) - continue; - for (int n=0; n < pcoin->vout.size(); n++) - { - if (IsMine(pcoin->vout[n]) && pcoin->IsSpent(n) && (txindex.vSpent.size() <= n || txindex.vSpent[n].IsNull())) - { - printf("CheckSpentCoins found lost coin %sppc %s[%d]\n", FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n); - nMismatchFound++; - nBalanceInQuestion += pcoin->vout[n].nValue; - } - else if (IsMine(pcoin->vout[n]) && !pcoin->IsSpent(n) && (txindex.vSpent.size() > n && !txindex.vSpent[n].IsNull())) - { - printf("CheckSpentCoins found spent coin %sppc %s[%d]\n", FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n); - nMismatchFound++; - nBalanceInQuestion += pcoin->vout[n].nValue; - } - } - } - return (nMismatchFound == 0); -} - // ppcoin: fix wallet spent state according to txindex -void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion) +void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion, bool fCheckOnly) { nMismatchFound = 0; nBalanceInQuestion = 0; @@ -1811,19 +1783,27 @@ void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion) { if (IsMine(pcoin->vout[n]) && pcoin->IsSpent(n) && (txindex.vSpent.size() <= n || txindex.vSpent[n].IsNull())) { - printf("FixSpentCoins found lost coin %sppc %s[%d]\n", FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n); + printf("FixSpentCoins found lost coin %sppc %s[%d], %s\n", + FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); nMismatchFound++; nBalanceInQuestion += pcoin->vout[n].nValue; - pcoin->MarkUnspent(n); - pcoin->WriteToDisk(); + if (!fCheckOnly) + { + pcoin->MarkUnspent(n); + pcoin->WriteToDisk(); + } } else if (IsMine(pcoin->vout[n]) && !pcoin->IsSpent(n) && (txindex.vSpent.size() > n && !txindex.vSpent[n].IsNull())) { - printf("FixSpentCoins found spent coin %sppc %s[%d]\n", FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n); + printf("FixSpentCoins found spent coin %sppc %s[%d], %s\n", + FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); nMismatchFound++; nBalanceInQuestion += pcoin->vout[n].nValue; - pcoin->MarkSpent(n); - pcoin->WriteToDisk(); + if (!fCheckOnly) + { + pcoin->MarkSpent(n); + pcoin->WriteToDisk(); + } } } }