X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=9a37be5a2a4caae7343968258831de1d6d317b82;hb=ac92f740d9fe40de422e8446aa514a254f250f27;hp=eb83806e81cc8850841ced053fba4dfb68353de0;hpb=bcbca1d182c8544d36058ce3017df04649d083ed;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index eb83806..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)) @@ -1339,7 +1358,7 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w } // NovaCoin: get current stake generation power -uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore) +uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore, enum StakeWeightMode mode) { LOCK2(cs_main, cs_wallet); @@ -1372,9 +1391,31 @@ uint64 CWallet::GetStakeMintPower(const CKeyStore& keystore) if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex)) continue; - // Do not count input that is still too young - if (pcoin.first->nTime + nStakeMaxAge > GetTime()) - 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); @@ -2172,7 +2213,7 @@ void CReserveKey::ReturnKey() vchPubKey = CPubKey(); } -void CWallet::GetAllReserveKeys(set& setAddress) +void CWallet::GetAllReserveKeys(set& setAddress) const { setAddress.clear(); @@ -2202,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 +}