X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=9a37be5a2a4caae7343968258831de1d6d317b82;hb=ac92f740d9fe40de422e8446aa514a254f250f27;hp=e84920f35adac9ad28f02c753fd696d1f923b4e4;hpb=6145f2d5e9f380a11bce933fe343d48fd8936a33;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index e84920f..9a37be5 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -45,19 +45,29 @@ CPubKey CWallet::GenerateNewKey() return key.GetPubKey(); } -bool CWallet::AddKey(const CKey& key) +bool CWallet::AddKey(const CKey& key, int64 nCreateTime) { + if(!nCreateTime) + nCreateTime = GetTime(); + if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) + nTimeFirstKey = nCreateTime; + if (!CCryptoKeyStore::AddKey(key)) return false; if (!fFileBacked) return true; if (!IsCrypted()) - return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey()); + return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetPrivKey(), nCreateTime); return true; } -bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector &vchCryptedSecret) +bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector &vchCryptedSecret, int64 nCreateTime) { + if(!nCreateTime) + nCreateTime = GetTime(); + if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) + nTimeFirstKey = nCreateTime; + if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) return false; if (!fFileBacked) @@ -65,13 +75,22 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vectorWriteCryptedKey(vchPubKey, vchCryptedSecret); + return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret, nCreateTime); else - return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret); + return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, nCreateTime); } return false; } +bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta) +{ + if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey)) + nTimeFirstKey = meta.nCreateTime; + + mapKeyMetadata[pubkey.GetID()] = meta; + return true; +} + bool CWallet::AddCScript(const CScript& redeemScript) { if (!CCryptoKeyStore::AddCScript(redeemScript)) @@ -672,9 +691,10 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, int64& nSent, int64& nFee) const { - nReceived = nSent = nFee = 0; + nGenerated = nReceived = nSent = nFee = 0; int64 allGeneratedImmature, allGeneratedMature, allFee; + allGeneratedImmature = allGeneratedMature = allFee = 0; string strSentAccount; list > listReceived; list > listSent; @@ -1013,6 +1033,9 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed) const if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) continue; + 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 > 0) vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); @@ -1334,6 +1357,79 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet); } +// NovaCoin: get current stake generation power +uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore, enum StakeWeightMode mode) +{ + LOCK2(cs_main, cs_wallet); + + // Choose coins to use + int64 nBalance = GetBalance(); + int64 nReserveBalance = 0; + uint64 nCoinAge = 0; + + if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) + { + error("CreateCoinStake : invalid reserve balance amount"); + return 0; + } + + if (nBalance <= nReserveBalance) + return 0; + + set > setCoins; + vector vwtxPrev; + int64 nValueIn = 0; + if (!SelectCoins(nBalance - nReserveBalance, GetTime(), setCoins, nValueIn)) + return 0; + if (setCoins.empty()) + return 0; + + BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) + { + CTxDB txdb("r"); + CTxIndex txindex; + if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) + continue; + + switch(mode) + { + case STAKE_NORMAL: + // Do not count input that is still less than 30 days old + if (pcoin.first->nTime + nStakeMinAge > GetTime()) + continue; + break; + case STAKE_MAXWEIGHT: + // Do not count input that is still less than 90 days old + if (pcoin.first->nTime + nStakeMaxAge > GetTime()) + continue; + break; + case STAKE_MINWEIGHT: + // Count only inputs with suitable age (from 30 to 90 days old) + if (pcoin.first->nTime + nStakeMaxAge < GetTime()) + continue; + if (pcoin.first->nTime + nStakeMinAge > GetTime()) + continue; + break; + case STAKE_BELOWMIN: + // Count only inputs with suitable age (less than 30 days old) + if (pcoin.first->nTime + nStakeMinAge < GetTime()) + continue; + break; + } + + CBigNum bnCentSecond = CBigNum(pcoin.first->vout[pcoin.second].nValue) * (GetTime()-pcoin.first->nTime) / CENT; + CBigNum bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60); + + + nCoinAge += bnCoinDay.getuint64(); + } + + if (fDebug && GetBoolArg("-printcoinage")) + printf("StakePower bnCoinDay=%"PRI64d"\n", nCoinAge); + + return nCoinAge; +} + // ppcoin: create coin stake transaction bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew) { @@ -2117,7 +2213,7 @@ void CReserveKey::ReturnKey() vchPubKey = CPubKey(); } -void CWallet::GetAllReserveKeys(set& setAddress) +void CWallet::GetAllReserveKeys(set& setAddress) const { setAddress.clear(); @@ -2147,3 +2243,54 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx) NotifyTransactionChanged(this, hashTx, CT_UPDATED); } } + +void CWallet::GetKeyBirthTimes(std::map &mapKeyBirth) const { + mapKeyBirth.clear(); + + // get birth times for keys with metadata + for (std::map::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) + if (it->second.nCreateTime) + mapKeyBirth[it->first] = it->second.nCreateTime; + + // map in which we'll infer heights of other keys + CBlockIndex *pindexMax = FindBlockByHeight(std::max(0, nBestHeight - 144)); // the tip can be reorganised; use a 144-block safety margin + std::map mapKeyFirstBlock; + std::set setKeys; + GetKeys(setKeys); + BOOST_FOREACH(const CKeyID &keyid, setKeys) { + if (mapKeyBirth.count(keyid) == 0) + mapKeyFirstBlock[keyid] = pindexMax; + } + setKeys.clear(); + + // if there are no such keys, we're done + if (mapKeyFirstBlock.empty()) + return; + + // find first block that affects those keys, if there are any left + std::vector vAffected; + for (std::map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) { + // iterate over all wallet transactions... + const CWalletTx &wtx = (*it).second; + std::map::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); + if (blit != mapBlockIndex.end() && blit->second->IsInMainChain()) { + // ... which are already in a block + int nHeight = blit->second->nHeight; + BOOST_FOREACH(const CTxOut &txout, wtx.vout) { + // iterate over all their outputs + ::ExtractAffectedKeys(*this, txout.scriptPubKey, vAffected); + BOOST_FOREACH(const CKeyID &keyid, vAffected) { + // ... and all their affected keys + std::map::iterator rit = mapKeyFirstBlock.find(keyid); + if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight) + rit->second = blit->second; + } + vAffected.clear(); + } + } + } + + // Extract block timestamps for those keys + 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 +}