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<unsigned char> &vchCryptedSecret)
+bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char> &vchCryptedSecret, int64 nCreateTime)
{
+ if(!nCreateTime)
+ nCreateTime = GetTime();
+ if (!nTimeFirstKey || nCreateTime < nTimeFirstKey)
+ nTimeFirstKey = nCreateTime;
+
if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
return false;
if (!fFileBacked)
{
LOCK(cs_wallet);
if (pwalletdbEncryption)
- return pwalletdbEncryption->WriteCryptedKey(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))
}
// 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);
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->GetValueOut()) * (GetTime()-pcoin.first->nTime) / CENT;
+ CBigNum bnCentSecond = CBigNum(pcoin.first->vout[pcoin.second].nValue) * (GetTime()-pcoin.first->nTime) / CENT;
CBigNum bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60);
vchPubKey = CPubKey();
}
-void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress)
+void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
{
setAddress.clear();
NotifyTransactionChanged(this, hashTx, CT_UPDATED);
}
}
+
+void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64> &mapKeyBirth) const {
+ mapKeyBirth.clear();
+
+ // get birth times for keys with metadata
+ for (std::map<CKeyID, CKeyMetadata>::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<CKeyID, CBlockIndex*> mapKeyFirstBlock;
+ std::set<CKeyID> 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<CKeyID> vAffected;
+ for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
+ // iterate over all wallet transactions...
+ const CWalletTx &wtx = (*it).second;
+ std::map<uint256, CBlockIndex*>::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<CKeyID, CBlockIndex*>::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<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
+ mapKeyBirth[it->first] = it->second->nTime - 7200; // block times can be 2h off
+}