Pieter Wuille
14 years ago
21 changed files with 2360 additions and 2150 deletions
@ -0,0 +1,33 @@ |
|||||||
|
// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include "headers.h" |
||||||
|
#include "db.h" |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// mapKeys
|
||||||
|
//
|
||||||
|
|
||||||
|
std::vector<unsigned char> CKeyStore::GenerateNewKey() |
||||||
|
{ |
||||||
|
RandAddSeedPerfmon(); |
||||||
|
CKey key; |
||||||
|
key.MakeNewKey(); |
||||||
|
if (!AddKey(key)) |
||||||
|
throw std::runtime_error("GenerateNewKey() : AddKey failed"); |
||||||
|
return key.GetPubKey(); |
||||||
|
} |
||||||
|
|
||||||
|
bool CKeyStore::AddKey(const CKey& key) |
||||||
|
{ |
||||||
|
CRITICAL_BLOCK(cs_mapKeys) |
||||||
|
{ |
||||||
|
mapKeys[key.GetPubKey()] = key.GetPrivKey(); |
||||||
|
mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,26 @@ |
|||||||
|
// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
#ifndef BITCOIN_KEYSTORE_H |
||||||
|
#define BITCOIN_KEYSTORE_H |
||||||
|
|
||||||
|
class CKeyStore |
||||||
|
{ |
||||||
|
public: |
||||||
|
std::map<std::vector<unsigned char>, CPrivKey> mapKeys; |
||||||
|
mutable CCriticalSection cs_mapKeys; |
||||||
|
virtual bool AddKey(const CKey& key); |
||||||
|
bool HaveKey(const std::vector<unsigned char> &vchPubKey) const |
||||||
|
{ |
||||||
|
return (mapKeys.count(vchPubKey) > 0); |
||||||
|
} |
||||||
|
CPrivKey GetPrivKey(const std::vector<unsigned char> &vchPubKey) const |
||||||
|
{ |
||||||
|
std::map<std::vector<unsigned char>, CPrivKey>::const_iterator mi = mapKeys.find(vchPubKey); |
||||||
|
if (mi != mapKeys.end()) |
||||||
|
return (*mi).second; |
||||||
|
} |
||||||
|
std::vector<unsigned char> GenerateNewKey(); |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,615 @@ |
|||||||
|
// Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers
|
||||||
|
// Distributed under the MIT/X11 software license, see the accompanying
|
||||||
|
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
#ifndef BITCOIN_WALLET_H |
||||||
|
#define BITCOIN_WALLET_H |
||||||
|
|
||||||
|
#include "bignum.h" |
||||||
|
#include "key.h" |
||||||
|
#include "script.h" |
||||||
|
|
||||||
|
class CWalletTx; |
||||||
|
class CReserveKey; |
||||||
|
class CWalletDB; |
||||||
|
|
||||||
|
class CWallet : public CKeyStore |
||||||
|
{ |
||||||
|
private: |
||||||
|
bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const; |
||||||
|
bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const; |
||||||
|
|
||||||
|
|
||||||
|
public: |
||||||
|
bool fFileBacked; |
||||||
|
std::string strWalletFile; |
||||||
|
|
||||||
|
std::set<int64> setKeyPool; |
||||||
|
CCriticalSection cs_setKeyPool; |
||||||
|
|
||||||
|
CWallet() |
||||||
|
{ |
||||||
|
fFileBacked = false; |
||||||
|
} |
||||||
|
CWallet(std::string strWalletFileIn) |
||||||
|
{ |
||||||
|
strWalletFile = strWalletFileIn; |
||||||
|
fFileBacked = true; |
||||||
|
} |
||||||
|
|
||||||
|
mutable CCriticalSection cs_mapWallet; |
||||||
|
std::map<uint256, CWalletTx> mapWallet; |
||||||
|
std::vector<uint256> vWalletUpdated; |
||||||
|
|
||||||
|
std::map<uint256, int> mapRequestCount; |
||||||
|
mutable CCriticalSection cs_mapRequestCount; |
||||||
|
|
||||||
|
std::map<std::string, std::string> mapAddressBook; |
||||||
|
mutable CCriticalSection cs_mapAddressBook; |
||||||
|
|
||||||
|
std::vector<unsigned char> vchDefaultKey; |
||||||
|
CKey keyUser; |
||||||
|
|
||||||
|
bool AddKey(const CKey& key); |
||||||
|
bool AddToWallet(const CWalletTx& wtxIn); |
||||||
|
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false); |
||||||
|
bool EraseFromWallet(uint256 hash); |
||||||
|
void WalletUpdateSpent(const CTransaction& prevout); |
||||||
|
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false); |
||||||
|
void ReacceptWalletTransactions(); |
||||||
|
void ResendWalletTransactions(); |
||||||
|
int64 GetBalance() const; |
||||||
|
bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); |
||||||
|
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); |
||||||
|
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); |
||||||
|
bool BroadcastTransaction(CWalletTx& wtxNew); |
||||||
|
std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); |
||||||
|
std::string SendMoneyToBitcoinAddress(std::string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false); |
||||||
|
|
||||||
|
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); |
||||||
|
void KeepKey(int64 nIndex); |
||||||
|
void ReturnKey(int64 nIndex); |
||||||
|
std::vector<unsigned char> GetKeyFromKeyPool(); |
||||||
|
int64 GetOldestKeyPoolTime(); |
||||||
|
|
||||||
|
bool IsMine(const CTxIn& txin) const; |
||||||
|
int64 GetDebit(const CTxIn& txin) const; |
||||||
|
bool IsMine(const CTxOut& txout) const |
||||||
|
{ |
||||||
|
return ::IsMine(*this, txout.scriptPubKey); |
||||||
|
} |
||||||
|
int64 GetCredit(const CTxOut& txout) const |
||||||
|
{ |
||||||
|
if (!MoneyRange(txout.nValue)) |
||||||
|
throw std::runtime_error("CWallet::GetCredit() : value out of range"); |
||||||
|
return (IsMine(txout) ? txout.nValue : 0); |
||||||
|
} |
||||||
|
bool IsChange(const CTxOut& txout) const |
||||||
|
{ |
||||||
|
std::vector<unsigned char> vchPubKey; |
||||||
|
if (ExtractPubKey(txout.scriptPubKey, this, vchPubKey)) |
||||||
|
CRITICAL_BLOCK(cs_mapAddressBook) |
||||||
|
if (!mapAddressBook.count(PubKeyToAddress(vchPubKey))) |
||||||
|
return true; |
||||||
|
return false; |
||||||
|
} |
||||||
|
int64 GetChange(const CTxOut& txout) const |
||||||
|
{ |
||||||
|
if (!MoneyRange(txout.nValue)) |
||||||
|
throw std::runtime_error("CWallet::GetChange() : value out of range"); |
||||||
|
if (IsChange(txout) ? txout.nValue : 0); |
||||||
|
} |
||||||
|
bool IsMine(const CTransaction& tx) const |
||||||
|
{ |
||||||
|
BOOST_FOREACH(const CTxOut& txout, tx.vout) |
||||||
|
if (IsMine(txout)) |
||||||
|
return true; |
||||||
|
return false; |
||||||
|
} |
||||||
|
bool IsFromMe(const CTransaction& tx) const |
||||||
|
{ |
||||||
|
return (GetDebit(tx) > 0); |
||||||
|
} |
||||||
|
int64 GetDebit(const CTransaction& tx) const |
||||||
|
{ |
||||||
|
int64 nDebit = 0; |
||||||
|
BOOST_FOREACH(const CTxIn& txin, tx.vin) |
||||||
|
{ |
||||||
|
nDebit += GetDebit(txin); |
||||||
|
if (!MoneyRange(nDebit)) |
||||||
|
throw std::runtime_error("CWallet::GetDebit() : value out of range"); |
||||||
|
} |
||||||
|
return nDebit; |
||||||
|
} |
||||||
|
int64 GetCredit(const CTransaction& tx) const |
||||||
|
{ |
||||||
|
int64 nCredit = 0; |
||||||
|
BOOST_FOREACH(const CTxOut& txout, tx.vout) |
||||||
|
{ |
||||||
|
nCredit += GetCredit(txout); |
||||||
|
if (!MoneyRange(nCredit)) |
||||||
|
throw std::runtime_error("CWallet::GetCredit() : value out of range"); |
||||||
|
} |
||||||
|
return nCredit; |
||||||
|
} |
||||||
|
int64 GetChange(const CTransaction& tx) const |
||||||
|
{ |
||||||
|
int64 nChange = 0; |
||||||
|
BOOST_FOREACH(const CTxOut& txout, tx.vout) |
||||||
|
{ |
||||||
|
nChange += GetChange(txout); |
||||||
|
if (!MoneyRange(nChange)) |
||||||
|
throw std::runtime_error("CWallet::GetChange() : value out of range"); |
||||||
|
} |
||||||
|
return nChange; |
||||||
|
} |
||||||
|
void SetBestChain(const CBlockLocator& loc) |
||||||
|
{ |
||||||
|
CWalletDB walletdb(strWalletFile); |
||||||
|
walletdb.WriteBestBlock(loc); |
||||||
|
} |
||||||
|
|
||||||
|
bool LoadWallet(bool& fFirstRunRet); |
||||||
|
// bool BackupWallet(const std::string& strDest);
|
||||||
|
|
||||||
|
bool SetAddressBookName(const std::string& strAddress, const std::string& strName) |
||||||
|
{ |
||||||
|
if (!fFileBacked) |
||||||
|
return false; |
||||||
|
return CWalletDB(strWalletFile).WriteName(strAddress, strName); |
||||||
|
} |
||||||
|
|
||||||
|
void UpdatedTransaction(const uint256 &hashTx) |
||||||
|
{ |
||||||
|
CRITICAL_BLOCK(cs_mapWallet) |
||||||
|
vWalletUpdated.push_back(hashTx); |
||||||
|
} |
||||||
|
|
||||||
|
void PrintWallet(const CBlock& block); |
||||||
|
|
||||||
|
void Inventory(const uint256 &hash) |
||||||
|
{ |
||||||
|
CRITICAL_BLOCK(cs_mapRequestCount) |
||||||
|
{ |
||||||
|
std::map<uint256, int>::iterator mi = mapRequestCount.find(hash); |
||||||
|
if (mi != mapRequestCount.end()) |
||||||
|
(*mi).second++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
class CReserveKey |
||||||
|
{ |
||||||
|
protected: |
||||||
|
CWallet* pwallet; |
||||||
|
int64 nIndex; |
||||||
|
std::vector<unsigned char> vchPubKey; |
||||||
|
public: |
||||||
|
CReserveKey(CWallet* pwalletIn) |
||||||
|
{ |
||||||
|
nIndex = -1; |
||||||
|
pwallet = pwalletIn; |
||||||
|
} |
||||||
|
|
||||||
|
~CReserveKey() |
||||||
|
{ |
||||||
|
if (!fShutdown) |
||||||
|
ReturnKey(); |
||||||
|
} |
||||||
|
|
||||||
|
void ReturnKey(); |
||||||
|
std::vector<unsigned char> GetReservedKey(); |
||||||
|
void KeepKey(); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// A transaction with a bunch of additional info that only the owner cares
|
||||||
|
// about. It includes any unrecorded transactions needed to link it back
|
||||||
|
// to the block chain.
|
||||||
|
//
|
||||||
|
class CWalletTx : public CMerkleTx |
||||||
|
{ |
||||||
|
public: |
||||||
|
const CWallet* pwallet; |
||||||
|
|
||||||
|
std::vector<CMerkleTx> vtxPrev; |
||||||
|
std::map<std::string, std::string> mapValue; |
||||||
|
std::vector<std::pair<std::string, std::string> > vOrderForm; |
||||||
|
unsigned int fTimeReceivedIsTxTime; |
||||||
|
unsigned int nTimeReceived; // time received by this node
|
||||||
|
char fFromMe; |
||||||
|
std::string strFromAccount; |
||||||
|
std::vector<char> vfSpent; |
||||||
|
|
||||||
|
// memory only
|
||||||
|
mutable char fDebitCached; |
||||||
|
mutable char fCreditCached; |
||||||
|
mutable char fAvailableCreditCached; |
||||||
|
mutable char fChangeCached; |
||||||
|
mutable int64 nDebitCached; |
||||||
|
mutable int64 nCreditCached; |
||||||
|
mutable int64 nAvailableCreditCached; |
||||||
|
mutable int64 nChangeCached; |
||||||
|
|
||||||
|
// memory only UI hints
|
||||||
|
mutable unsigned int nTimeDisplayed; |
||||||
|
mutable int nLinesDisplayed; |
||||||
|
mutable char fConfirmedDisplayed; |
||||||
|
|
||||||
|
CWalletTx() |
||||||
|
{ |
||||||
|
Init(NULL); |
||||||
|
} |
||||||
|
|
||||||
|
CWalletTx(const CWallet* pwalletIn) |
||||||
|
{ |
||||||
|
Init(pwalletIn); |
||||||
|
} |
||||||
|
|
||||||
|
CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn) |
||||||
|
{ |
||||||
|
Init(pwalletIn); |
||||||
|
} |
||||||
|
|
||||||
|
CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn) |
||||||
|
{ |
||||||
|
Init(pwalletIn); |
||||||
|
} |
||||||
|
|
||||||
|
void Init(const CWallet* pwalletIn) |
||||||
|
{ |
||||||
|
pwallet = pwalletIn; |
||||||
|
vtxPrev.clear(); |
||||||
|
mapValue.clear(); |
||||||
|
vOrderForm.clear(); |
||||||
|
fTimeReceivedIsTxTime = false; |
||||||
|
nTimeReceived = 0; |
||||||
|
fFromMe = false; |
||||||
|
strFromAccount.clear(); |
||||||
|
vfSpent.clear(); |
||||||
|
fDebitCached = false; |
||||||
|
fCreditCached = false; |
||||||
|
fAvailableCreditCached = false; |
||||||
|
fChangeCached = false; |
||||||
|
nDebitCached = 0; |
||||||
|
nCreditCached = 0; |
||||||
|
nAvailableCreditCached = 0; |
||||||
|
nChangeCached = 0; |
||||||
|
nTimeDisplayed = 0; |
||||||
|
nLinesDisplayed = 0; |
||||||
|
fConfirmedDisplayed = false; |
||||||
|
} |
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE |
||||||
|
( |
||||||
|
CWalletTx* pthis = const_cast<CWalletTx*>(this); |
||||||
|
if (fRead) |
||||||
|
pthis->Init(NULL); |
||||||
|
char fSpent = false; |
||||||
|
|
||||||
|
if (!fRead) |
||||||
|
{ |
||||||
|
pthis->mapValue["fromaccount"] = pthis->strFromAccount; |
||||||
|
|
||||||
|
std::string str; |
||||||
|
BOOST_FOREACH(char f, vfSpent) |
||||||
|
{ |
||||||
|
str += (f ? '1' : '0'); |
||||||
|
if (f) |
||||||
|
fSpent = true; |
||||||
|
} |
||||||
|
pthis->mapValue["spent"] = str; |
||||||
|
} |
||||||
|
|
||||||
|
nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action); |
||||||
|
READWRITE(vtxPrev); |
||||||
|
READWRITE(mapValue); |
||||||
|
READWRITE(vOrderForm); |
||||||
|
READWRITE(fTimeReceivedIsTxTime); |
||||||
|
READWRITE(nTimeReceived); |
||||||
|
READWRITE(fFromMe); |
||||||
|
READWRITE(fSpent); |
||||||
|
|
||||||
|
if (fRead) |
||||||
|
{ |
||||||
|
pthis->strFromAccount = pthis->mapValue["fromaccount"]; |
||||||
|
|
||||||
|
if (mapValue.count("spent")) |
||||||
|
BOOST_FOREACH(char c, pthis->mapValue["spent"]) |
||||||
|
pthis->vfSpent.push_back(c != '0'); |
||||||
|
else |
||||||
|
pthis->vfSpent.assign(vout.size(), fSpent); |
||||||
|
} |
||||||
|
|
||||||
|
pthis->mapValue.erase("fromaccount"); |
||||||
|
pthis->mapValue.erase("version"); |
||||||
|
pthis->mapValue.erase("spent"); |
||||||
|
) |
||||||
|
|
||||||
|
// marks certain txout's as spent
|
||||||
|
// returns true if any update took place
|
||||||
|
bool UpdateSpent(const std::vector<char>& vfNewSpent) |
||||||
|
{ |
||||||
|
bool fReturn = false; |
||||||
|
for (int i=0; i < vfNewSpent.size(); i++) |
||||||
|
{ |
||||||
|
if (i == vfSpent.size()) |
||||||
|
break; |
||||||
|
|
||||||
|
if (vfNewSpent[i] && !vfSpent[i]) |
||||||
|
{ |
||||||
|
vfSpent[i] = true; |
||||||
|
fReturn = true; |
||||||
|
fAvailableCreditCached = false; |
||||||
|
} |
||||||
|
} |
||||||
|
return fReturn; |
||||||
|
} |
||||||
|
|
||||||
|
void MarkDirty() |
||||||
|
{ |
||||||
|
fCreditCached = false; |
||||||
|
fAvailableCreditCached = false; |
||||||
|
fDebitCached = false; |
||||||
|
fChangeCached = false; |
||||||
|
} |
||||||
|
|
||||||
|
void MarkSpent(unsigned int nOut) |
||||||
|
{ |
||||||
|
if (nOut >= vout.size()) |
||||||
|
throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range"); |
||||||
|
vfSpent.resize(vout.size()); |
||||||
|
if (!vfSpent[nOut]) |
||||||
|
{ |
||||||
|
vfSpent[nOut] = true; |
||||||
|
fAvailableCreditCached = false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool IsSpent(unsigned int nOut) const |
||||||
|
{ |
||||||
|
if (nOut >= vout.size()) |
||||||
|
throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range"); |
||||||
|
if (nOut >= vfSpent.size()) |
||||||
|
return false; |
||||||
|
return (!!vfSpent[nOut]); |
||||||
|
} |
||||||
|
|
||||||
|
int64 GetDebit() const |
||||||
|
{ |
||||||
|
if (vin.empty()) |
||||||
|
return 0; |
||||||
|
if (fDebitCached) |
||||||
|
return nDebitCached; |
||||||
|
nDebitCached = pwallet->GetDebit(*this); |
||||||
|
fDebitCached = true; |
||||||
|
return nDebitCached; |
||||||
|
} |
||||||
|
|
||||||
|
int64 GetCredit(bool fUseCache=true) const |
||||||
|
{ |
||||||
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
|
if (IsCoinBase() && GetBlocksToMaturity() > 0) |
||||||
|
return 0; |
||||||
|
|
||||||
|
// GetBalance can assume transactions in mapWallet won't change
|
||||||
|
if (fUseCache && fCreditCached) |
||||||
|
return nCreditCached; |
||||||
|
nCreditCached = pwallet->GetCredit(*this); |
||||||
|
fCreditCached = true; |
||||||
|
return nCreditCached; |
||||||
|
} |
||||||
|
|
||||||
|
int64 GetAvailableCredit(bool fUseCache=true) const |
||||||
|
{ |
||||||
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
|
if (IsCoinBase() && GetBlocksToMaturity() > 0) |
||||||
|
return 0; |
||||||
|
|
||||||
|
if (fUseCache && fAvailableCreditCached) |
||||||
|
return nAvailableCreditCached; |
||||||
|
|
||||||
|
int64 nCredit = 0; |
||||||
|
for (int i = 0; i < vout.size(); i++) |
||||||
|
{ |
||||||
|
if (!IsSpent(i)) |
||||||
|
{ |
||||||
|
const CTxOut &txout = vout[i]; |
||||||
|
nCredit += pwallet->GetCredit(txout); |
||||||
|
if (!MoneyRange(nCredit)) |
||||||
|
throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
nAvailableCreditCached = nCredit; |
||||||
|
fAvailableCreditCached = true; |
||||||
|
return nCredit; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
int64 GetChange() const |
||||||
|
{ |
||||||
|
if (fChangeCached) |
||||||
|
return nChangeCached; |
||||||
|
nChangeCached = pwallet->GetChange(*this); |
||||||
|
fChangeCached = true; |
||||||
|
return nChangeCached; |
||||||
|
} |
||||||
|
|
||||||
|
void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<std::string /* address */, int64> >& listReceived, |
||||||
|
std::list<std::pair<std::string /* address */, int64> >& listSent, int64& nFee, std::string& strSentAccount) const; |
||||||
|
|
||||||
|
void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived, |
||||||
|
int64& nSent, int64& nFee) const; |
||||||
|
|
||||||
|
bool IsFromMe() const |
||||||
|
{ |
||||||
|
return (GetDebit() > 0); |
||||||
|
} |
||||||
|
|
||||||
|
bool IsConfirmed() const |
||||||
|
{ |
||||||
|
// Quick answer in most cases
|
||||||
|
if (!IsFinal()) |
||||||
|
return false; |
||||||
|
if (GetDepthInMainChain() >= 1) |
||||||
|
return true; |
||||||
|
if (!IsFromMe()) // using wtx's cached debit
|
||||||
|
return false; |
||||||
|
|
||||||
|
// If no confirmations but it's from us, we can still
|
||||||
|
// consider it confirmed if all dependencies are confirmed
|
||||||
|
std::map<uint256, const CMerkleTx*> mapPrev; |
||||||
|
std::vector<const CMerkleTx*> vWorkQueue; |
||||||
|
vWorkQueue.reserve(vtxPrev.size()+1); |
||||||
|
vWorkQueue.push_back(this); |
||||||
|
for (int i = 0; i < vWorkQueue.size(); i++) |
||||||
|
{ |
||||||
|
const CMerkleTx* ptx = vWorkQueue[i]; |
||||||
|
|
||||||
|
if (!ptx->IsFinal()) |
||||||
|
return false; |
||||||
|
if (ptx->GetDepthInMainChain() >= 1) |
||||||
|
continue; |
||||||
|
if (!pwallet->IsFromMe(*ptx)) |
||||||
|
return false; |
||||||
|
|
||||||
|
if (mapPrev.empty()) |
||||||
|
BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) |
||||||
|
mapPrev[tx.GetHash()] = &tx; |
||||||
|
|
||||||
|
BOOST_FOREACH(const CTxIn& txin, ptx->vin) |
||||||
|
{ |
||||||
|
if (!mapPrev.count(txin.prevout.hash)) |
||||||
|
return false; |
||||||
|
vWorkQueue.push_back(mapPrev[txin.prevout.hash]); |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
bool WriteToDisk(); |
||||||
|
|
||||||
|
int64 GetTxTime() const; |
||||||
|
int GetRequestCount() const; |
||||||
|
|
||||||
|
void AddSupportingTransactions(CTxDB& txdb); |
||||||
|
|
||||||
|
bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true); |
||||||
|
bool AcceptWalletTransaction(); |
||||||
|
|
||||||
|
void RelayWalletTransaction(CTxDB& txdb); |
||||||
|
void RelayWalletTransaction(); |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Private key that includes an expiration date in case it never gets used.
|
||||||
|
//
|
||||||
|
class CWalletKey |
||||||
|
{ |
||||||
|
public: |
||||||
|
CPrivKey vchPrivKey; |
||||||
|
int64 nTimeCreated; |
||||||
|
int64 nTimeExpires; |
||||||
|
std::string strComment; |
||||||
|
//// todo: add something to note what created it (user, getnewaddress, change)
|
||||||
|
//// maybe should have a map<string, string> property map
|
||||||
|
|
||||||
|
CWalletKey(int64 nExpires=0) |
||||||
|
{ |
||||||
|
nTimeCreated = (nExpires ? GetTime() : 0); |
||||||
|
nTimeExpires = nExpires; |
||||||
|
} |
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE |
||||||
|
( |
||||||
|
if (!(nType & SER_GETHASH)) |
||||||
|
READWRITE(nVersion); |
||||||
|
READWRITE(vchPrivKey); |
||||||
|
READWRITE(nTimeCreated); |
||||||
|
READWRITE(nTimeExpires); |
||||||
|
READWRITE(strComment); |
||||||
|
) |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Account information.
|
||||||
|
// Stored in wallet with key "acc"+string account name
|
||||||
|
//
|
||||||
|
class CAccount |
||||||
|
{ |
||||||
|
public: |
||||||
|
std::vector<unsigned char> vchPubKey; |
||||||
|
|
||||||
|
CAccount() |
||||||
|
{ |
||||||
|
SetNull(); |
||||||
|
} |
||||||
|
|
||||||
|
void SetNull() |
||||||
|
{ |
||||||
|
vchPubKey.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE |
||||||
|
( |
||||||
|
if (!(nType & SER_GETHASH)) |
||||||
|
READWRITE(nVersion); |
||||||
|
READWRITE(vchPubKey); |
||||||
|
) |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Internal transfers.
|
||||||
|
// Database key is acentry<account><counter>
|
||||||
|
//
|
||||||
|
class CAccountingEntry |
||||||
|
{ |
||||||
|
public: |
||||||
|
std::string strAccount; |
||||||
|
int64 nCreditDebit; |
||||||
|
int64 nTime; |
||||||
|
std::string strOtherAccount; |
||||||
|
std::string strComment; |
||||||
|
|
||||||
|
CAccountingEntry() |
||||||
|
{ |
||||||
|
SetNull(); |
||||||
|
} |
||||||
|
|
||||||
|
void SetNull() |
||||||
|
{ |
||||||
|
nCreditDebit = 0; |
||||||
|
nTime = 0; |
||||||
|
strAccount.clear(); |
||||||
|
strOtherAccount.clear(); |
||||||
|
strComment.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
IMPLEMENT_SERIALIZE |
||||||
|
( |
||||||
|
if (!(nType & SER_GETHASH)) |
||||||
|
READWRITE(nVersion); |
||||||
|
// Note: strAccount is serialized as part of the key, not here.
|
||||||
|
READWRITE(nCreditDebit); |
||||||
|
READWRITE(nTime); |
||||||
|
READWRITE(strOtherAccount); |
||||||
|
READWRITE(strComment); |
||||||
|
) |
||||||
|
}; |
||||||
|
|
||||||
|
bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut); |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue