aboutsummaryrefslogtreecommitdiff
path: root/src/wallet.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet.h')
-rw-r--r--src/wallet.h125
1 files changed, 25 insertions, 100 deletions
diff --git a/src/wallet.h b/src/wallet.h
index eb192f1ca6..7feb86d294 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -108,11 +108,15 @@ private:
int64_t nNextResend;
int64_t nLastResend;
- // Used to detect and report conflicted transactions:
- typedef std::multimap<COutPoint, uint256> TxConflicts;
- TxConflicts mapTxConflicts;
- void AddToConflicts(const uint256& wtxhash);
- void SyncMetaData(std::pair<TxConflicts::iterator, TxConflicts::iterator>);
+ // Used to keep track of spent outpoints, and
+ // detect and report conflicts (double-spends or
+ // mutated transactions where the mutant gets mined).
+ typedef std::multimap<COutPoint, uint256> TxSpends;
+ TxSpends mapTxSpends;
+ void AddToSpends(const COutPoint& outpoint, const uint256& wtxid);
+ void AddToSpends(const uint256& wtxid);
+
+ void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>);
public:
/// Main wallet lock.
@@ -169,12 +173,16 @@ public:
int64_t nTimeFirstKey;
+ const CWalletTx* GetWalletTx(const uint256& hash) const;
+
// check whether we are allowed to upgrade (or already support) to the named feature
bool CanSupportFeature(enum WalletFeature wf) { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; }
void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl = NULL) const;
bool SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const;
+ bool IsSpent(const uint256& hash, unsigned int n) const;
+
bool IsLockedCoin(uint256 hash, unsigned int n) const;
void LockCoin(COutPoint& output);
void UnlockCoin(COutPoint& output);
@@ -234,7 +242,6 @@ public:
void SyncTransaction(const uint256 &hash, const CTransaction& tx, const CBlock* pblock);
bool AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate);
void EraseFromWallet(const uint256 &hash);
- void WalletUpdateSpent(const CTransaction& prevout);
int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
void ReacceptWalletTransactions();
void ResendWalletTransactions();
@@ -439,7 +446,6 @@ private:
const CWallet* pwallet;
public:
- std::vector<CMerkleTx> vtxPrev;
mapValue_t mapValue;
std::vector<std::pair<std::string, std::string> > vOrderForm;
unsigned int fTimeReceivedIsTxTime;
@@ -447,7 +453,6 @@ public:
unsigned int nTimeSmart;
char fFromMe;
std::string strFromAccount;
- std::vector<char> vfSpent; // which outputs are already spent
int64_t nOrderPos; // position in ordered transaction list
// memory only
@@ -485,7 +490,6 @@ public:
void Init(const CWallet* pwalletIn)
{
pwallet = pwalletIn;
- vtxPrev.clear();
mapValue.clear();
vOrderForm.clear();
fTimeReceivedIsTxTime = false;
@@ -493,7 +497,6 @@ public:
nTimeSmart = 0;
fFromMe = false;
strFromAccount.clear();
- vfSpent.clear();
fDebitCached = false;
fCreditCached = false;
fImmatureCreditCached = false;
@@ -518,15 +521,6 @@ public:
{
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;
-
WriteOrderPos(pthis->nOrderPos, pthis->mapValue);
if (nTimeSmart)
@@ -534,7 +528,8 @@ public:
}
nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
- READWRITE(vtxPrev);
+ std::vector<CMerkleTx> vUnused; // Used to be vtxPrev
+ READWRITE(vUnused);
READWRITE(mapValue);
READWRITE(vOrderForm);
READWRITE(fTimeReceivedIsTxTime);
@@ -546,12 +541,6 @@ public:
{
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);
-
ReadOrderPos(pthis->nOrderPos, pthis->mapValue);
pthis->nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(pthis->mapValue["timesmart"]) : 0;
@@ -564,26 +553,6 @@ public:
pthis->mapValue.erase("timesmart");
)
- // marks certain txout's as spent
- // returns true if any update took place
- bool UpdateSpent(const std::vector<char>& vfNewSpent)
- {
- bool fReturn = false;
- for (unsigned 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;
- }
-
// make sure balances are recalculated
void MarkDirty()
{
@@ -599,27 +568,6 @@ public:
MarkDirty();
}
- 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_t GetDebit() const
{
if (vin.empty())
@@ -661,6 +609,9 @@ public:
int64_t GetAvailableCredit(bool fUseCache=true) const
{
+ if (pwallet == 0)
+ return 0;
+
// Must wait until coinbase is safely deep enough in the chain before valuing it
if (IsCoinBase() && GetBlocksToMaturity() > 0)
return 0;
@@ -671,7 +622,7 @@ public:
int64_t nCredit = 0;
for (unsigned int i = 0; i < vout.size(); i++)
{
- if (!IsSpent(i))
+ if (!pwallet->IsSpent(GetHash(), i))
{
const CTxOut &txout = vout[i];
nCredit += pwallet->GetCredit(txout);
@@ -719,38 +670,14 @@ public:
if (!bSpendZeroConfChange || !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 (unsigned int i = 0; i < vWorkQueue.size(); i++)
+ // Trusted if all inputs are from us and are in the mempool:
+ BOOST_FOREACH(const CTxIn& txin, vin)
{
- const CMerkleTx* ptx = vWorkQueue[i];
-
- if (!IsFinalTx(*ptx))
+ // Transactions not sent by us: not trusted
+ const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
+ const CTxOut& parentOut = parent->vout[txin.prevout.n];
+ if (parent == NULL || !pwallet->IsMine(parentOut))
return false;
- int nPDepth = ptx->GetDepthInMainChain();
- if (nPDepth >= 1)
- continue;
- if (nPDepth < 0)
- return false;
- 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;
}
@@ -760,8 +687,6 @@ public:
int64_t GetTxTime() const;
int GetRequestCount() const;
- void AddSupportingTransactions();
- bool AcceptWalletTransaction();
void RelayWalletTransaction();
std::set<uint256> GetConflicts() const;