X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=fb12cb0c96589f0e1d2e113e08ba1d97a456cbd7;hb=b0368da0e15b5506548da3462e14b038ca21ae69;hp=c78a15367bd821b99f28a65d9b2d1a5affb10e9d;hpb=3802178d00f0794d8369924cd333e12bfc1f946c;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index c78a153..fb12cb0 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -102,6 +102,22 @@ bool CWallet::AddCScript(const CScript& redeemScript) return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript); } +bool CWallet::AddWatchOnly(const CTxDestination &dest) +{ + if (!CCryptoKeyStore::AddWatchOnly(dest)) + return false; + nTimeFirstKey = 1; // No birthday information for watch-only keys. + if (!fFileBacked) + return true; + return CWalletDB(strWalletFile).WriteWatchOnly(dest); +} + +bool CWallet::LoadWatchOnly(const CTxDestination &dest) +{ + printf("Loaded %s!\n", CBitcoinAddress(dest).ToString().c_str()); + return CCryptoKeyStore::AddWatchOnly(dest); +} + // ppcoin: optional setting to unlock wallet for block minting only; // serves to disable the trivial sendmoney when OS account compromised bool fWalletUnlockMintOnly = false; @@ -370,7 +386,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock) printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str()); else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n])) { - printf("WalletUpdateSpent found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + printf("WalletUpdateSpent found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit(false)).c_str(), wtx.GetHash().ToString().c_str()); wtx.MarkSpent(txin.prevout.n); wtx.WriteToDisk(); NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED); @@ -572,7 +588,7 @@ bool CWallet::EraseFromWallet(uint256 hash) } -bool CWallet::IsMine(const CTxIn &txin) const +isminetype CWallet::IsMine(const CTxIn &txin) const { { LOCK(cs_wallet); @@ -581,11 +597,10 @@ bool CWallet::IsMine(const CTxIn &txin) const { const CWalletTx& prev = (*mi).second; if (txin.prevout.n < prev.vout.size()) - if (IsMine(prev.vout[txin.prevout.n])) - return true; + return IsMine(prev.vout[txin.prevout.n]); } } - return false; + return MINE_NO; } int64 CWallet::GetDebit(const CTxIn &txin) const @@ -682,7 +697,7 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l if (GetBlocksToMaturity() > 0) nGeneratedImmature = pwallet->GetCredit(*this); else - nGeneratedMature = GetCredit(); + nGeneratedMature = GetCredit(false); return; } @@ -906,7 +921,7 @@ void CWallet::ReacceptWalletTransactions() } if (fUpdated) { - printf("ReacceptWalletTransactions found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + printf("ReacceptWalletTransactions found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit(false)).c_str(), wtx.GetHash().ToString().c_str()); wtx.MarkDirty(); wtx.WriteToDisk(); } @@ -1019,13 +1034,28 @@ int64 CWallet::GetBalance() const { const CWalletTx* pcoin = &(*it).second; if (pcoin->IsTrusted()) - nTotal += pcoin->GetAvailableCredit(); + nTotal += pcoin->GetAvailableCredit(false); } } return nTotal; } +void CWallet::GetBalance(int64 &nTotal, int64 &nWatchOnly) const +{ + { + LOCK(cs_wallet); + for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsTrusted()) { + nWatchOnly += pcoin->GetAvailableCredit(true); + nTotal += pcoin->GetAvailableCredit(false); + } + } + } +} + int64 CWallet::GetUnconfirmedBalance() const { int64 nTotal = 0; @@ -1035,7 +1065,7 @@ int64 CWallet::GetUnconfirmedBalance() const { const CWalletTx* pcoin = &(*it).second; if (!pcoin->IsFinal() || !pcoin->IsTrusted()) - nTotal += pcoin->GetAvailableCredit(); + nTotal += pcoin->GetAvailableCredit(false); } } return nTotal; @@ -1079,11 +1109,15 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const if(pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0) continue; - for (unsigned int i = 0; i < pcoin->vout.size(); i++) - if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue >= nMinimumInputValue && - (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) - vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); - + for (unsigned int i = 0; i < pcoin->vout.size(); i++) { + isminetype mine = IsMine(pcoin->vout[i]); + if (!(pcoin->IsSpent(i)) && mine != MINE_NO && + pcoin->vout[i].nValue >= nMinimumInputValue && + (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i))) + { + vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain(), mine == MINE_SPENDABLE)); + } + } } } } @@ -1104,9 +1138,12 @@ void CWallet::AvailableCoinsMinConf(vector& vCoins, int nConf) const if(pcoin->GetDepthInMainChain() < nConf) continue; - for (unsigned int i = 0; i < pcoin->vout.size(); i++) - if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && pcoin->vout[i].nValue >= nMinimumInputValue) - vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); + for (unsigned int i = 0; i < pcoin->vout.size(); i++) { + isminetype mine = IsMine(pcoin->vout[i]); + + if (!(pcoin->IsSpent(i)) && mine != MINE_NO && pcoin->vout[i].nValue >= nMinimumInputValue) + vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain(), mine == MINE_SPENDABLE)); + } } } } @@ -1190,8 +1227,11 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, in random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); - BOOST_FOREACH(COutput output, vCoins) + BOOST_FOREACH(const COutput &output, vCoins) { + if (!output.fSpendable) + continue; + const CWalletTx *pcoin = output.tx; if (output.nDepth < (pcoin->IsFromMe() ? nConfMine : nConfTheirs)) @@ -1292,6 +1332,8 @@ bool CWallet::SelectCoins(int64 nTargetValue, unsigned int nSpendTime, setvout[out.i].nValue; setCoinsRet.insert(make_pair(out.tx, out.i)); } @@ -1314,6 +1356,8 @@ bool CWallet::SelectCoinsSimple(int64 nTargetValue, unsigned int nSpendTime, int BOOST_FOREACH(COutput output, vCoins) { + if(!output.fSpendable) + continue; const CWalletTx *pcoin = output.tx; int i = output.i; @@ -1394,18 +1438,21 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW // if sub-cent change is required, the fee must be raised to at least MIN_TX_FEE // or until nChange becomes zero // NOTE: this depends on the exact behaviour of GetMinFee - if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT) + if (wtxNew.nTime < FEE_SWITCH_TIME && !fTestNet) { - int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet); - nChange -= nMoveToFee; - nFeeRet += nMoveToFee; - } + if (nFeeRet < MIN_TX_FEE && nChange > 0 && nChange < CENT) + { + int64 nMoveToFee = min(nChange, MIN_TX_FEE - nFeeRet); + nChange -= nMoveToFee; + nFeeRet += nMoveToFee; + } - // ppcoin: sub-cent change is moved to fee - if (nChange > 0 && nChange < MIN_TXOUT_AMOUNT) - { - nFeeRet += nChange; - nChange = 0; + // sub-cent change is moved to fee + if (nChange > 0 && nChange < CENT) + { + nFeeRet += nChange; + nChange = 0; + } } if (nChange > 0) @@ -1460,7 +1507,15 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW // Check that enough fee is included int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000); - int64 nMinFee = wtxNew.GetMinFee(1, false, GMF_SEND, nBytes); + bool fAllowFree = CTransaction::AllowFree(dPriority); + + // Disable free transactions until 1 July 2014 + if (!fTestNet && wtxNew.nTime < FEE_SWITCH_TIME) + { + fAllowFree = false; + } + + int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND, nBytes); if (nFeeRet < max(nPayFee, nMinFee)) { @@ -1486,6 +1541,22 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, coinControl); } +void CWallet::GetStakeWeightFromValue(const int64& nTime, const int64& nValue, uint64& nWeight) +{ + int64 nTimeWeight = GetWeight(nTime, (int64)GetTime()); + + // If time weight is lower or equal to zero then weight is zero. + if (nTimeWeight <= 0) + { + nWeight = 0; + return; + } + + CBigNum bnCoinDayWeight = CBigNum(nValue) * nTimeWeight / COIN / (24 * 60 * 60); + nWeight = bnCoinDayWeight.getuint64(); +} + + // NovaCoin: get current stake weight bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight) { @@ -1800,9 +1871,9 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int return error("CreateCoinStake : exceeded coinstake size limit"); // Check enough fee is paid - if (nMinFee < txNew.GetMinFee() - MIN_TX_FEE) + if (nMinFee < txNew.GetMinFee(1, false, GMF_BLOCK, nBytes) - CENT) { - nMinFee = txNew.GetMinFee() - MIN_TX_FEE; + nMinFee = txNew.GetMinFee(1, false, GMF_BLOCK, nBytes) - CENT; continue; // try signing again } else @@ -1980,12 +2051,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(false)); } 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(false)); } } @@ -2354,6 +2425,16 @@ void CWallet::FixSpentCoins(int& nMismatchFound, int64& nBalanceInQuestion, bool pcoin->WriteToDisk(); } } + + } + + if(IsMine((CTransaction)*pcoin) && (pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetDepthInMainChain() == 0) + { + printf("FixSpentCoins %s tx %s\n", fCheckOnly ? "found" : "removed", pcoin->GetHash().ToString().c_str()); + if (!fCheckOnly) + { + EraseFromWallet(pcoin->GetHash()); + } } } }