mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-01 03:16:09 +02:00
Make CWalletTx store a CTransactionRef instead of inheriting
This commit is contained in:
@@ -75,7 +75,7 @@ struct CompareValueOnly
|
||||
|
||||
std::string COutput::ToString() const
|
||||
{
|
||||
return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue));
|
||||
return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->tx->vout[i].nValue));
|
||||
}
|
||||
|
||||
const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
|
||||
@@ -400,7 +400,7 @@ set<uint256> CWallet::GetConflicts(const uint256& txid) const
|
||||
|
||||
std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
|
||||
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.tx->vin)
|
||||
{
|
||||
if (mapTxSpends.count(txin.prevout) <= 1)
|
||||
continue; // No conflict if zero or one spends
|
||||
@@ -552,7 +552,7 @@ void CWallet::AddToSpends(const uint256& wtxid)
|
||||
if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
|
||||
return;
|
||||
|
||||
BOOST_FOREACH(const CTxIn& txin, thisTx.vin)
|
||||
BOOST_FOREACH(const CTxIn& txin, thisTx.tx->vin)
|
||||
AddToSpends(txin.prevout, wtxid);
|
||||
}
|
||||
|
||||
@@ -795,7 +795,7 @@ bool CWallet::GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bFo
|
||||
for (map<uint256, CWalletTx>::iterator it = mapWallet.begin();
|
||||
it != mapWallet.end() && account.vchPubKey.IsValid();
|
||||
++it)
|
||||
BOOST_FOREACH(const CTxOut& txout, (*it).second.vout)
|
||||
BOOST_FOREACH(const CTxOut& txout, (*it).second.tx->vout)
|
||||
if (txout.scriptPubKey == scriptPubKey) {
|
||||
bForceNew = true;
|
||||
break;
|
||||
@@ -954,7 +954,7 @@ bool CWallet::LoadToWallet(const CWalletTx& wtxIn)
|
||||
wtx.BindWallet(this);
|
||||
wtxOrdered.insert(make_pair(wtx.nOrderPos, TxPair(&wtx, (CAccountingEntry*)0)));
|
||||
AddToSpends(hash);
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin) {
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.tx->vin) {
|
||||
if (mapWallet.count(txin.prevout.hash)) {
|
||||
CWalletTx& prevtx = mapWallet[txin.prevout.hash];
|
||||
if (prevtx.nIndex == -1 && !prevtx.hashUnset()) {
|
||||
@@ -993,7 +993,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex
|
||||
if (fExisted && !fUpdate) return false;
|
||||
if (fExisted || IsMine(tx) || IsFromMe(tx))
|
||||
{
|
||||
CWalletTx wtx(this,tx);
|
||||
CWalletTx wtx(this, MakeTransactionRef(tx));
|
||||
|
||||
// Get merkle branch if transaction was found in a block
|
||||
if (posInBlock != -1)
|
||||
@@ -1052,7 +1052,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
|
||||
}
|
||||
// If a transaction changes 'conflicted' state, that changes the balance
|
||||
// available of the outputs it spends. So force those to be recomputed
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.tx->vin)
|
||||
{
|
||||
if (mapWallet.count(txin.prevout.hash))
|
||||
mapWallet[txin.prevout.hash].MarkDirty();
|
||||
@@ -1113,7 +1113,7 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
|
||||
}
|
||||
// If a transaction changes 'conflicted' state, that changes the balance
|
||||
// available of the outputs it spends. So force those to be recomputed
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.tx->vin)
|
||||
{
|
||||
if (mapWallet.count(txin.prevout.hash))
|
||||
mapWallet[txin.prevout.hash].MarkDirty();
|
||||
@@ -1148,8 +1148,8 @@ isminetype CWallet::IsMine(const CTxIn &txin) const
|
||||
if (mi != mapWallet.end())
|
||||
{
|
||||
const CWalletTx& prev = (*mi).second;
|
||||
if (txin.prevout.n < prev.vout.size())
|
||||
return IsMine(prev.vout[txin.prevout.n]);
|
||||
if (txin.prevout.n < prev.tx->vout.size())
|
||||
return IsMine(prev.tx->vout[txin.prevout.n]);
|
||||
}
|
||||
}
|
||||
return ISMINE_NO;
|
||||
@@ -1163,9 +1163,9 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
|
||||
if (mi != mapWallet.end())
|
||||
{
|
||||
const CWalletTx& prev = (*mi).second;
|
||||
if (txin.prevout.n < prev.vout.size())
|
||||
if (IsMine(prev.vout[txin.prevout.n]) & filter)
|
||||
return prev.vout[txin.prevout.n].nValue;
|
||||
if (txin.prevout.n < prev.tx->vout.size())
|
||||
if (IsMine(prev.tx->vout[txin.prevout.n]) & filter)
|
||||
return prev.tx->vout[txin.prevout.n].nValue;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -1380,14 +1380,14 @@ void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
|
||||
CAmount nDebit = GetDebit(filter);
|
||||
if (nDebit > 0) // debit>0 means we signed/sent this transaction
|
||||
{
|
||||
CAmount nValueOut = GetValueOut();
|
||||
CAmount nValueOut = tx->GetValueOut();
|
||||
nFee = nDebit - nValueOut;
|
||||
}
|
||||
|
||||
// Sent/received.
|
||||
for (unsigned int i = 0; i < vout.size(); ++i)
|
||||
for (unsigned int i = 0; i < tx->vout.size(); ++i)
|
||||
{
|
||||
const CTxOut& txout = vout[i];
|
||||
const CTxOut& txout = tx->vout[i];
|
||||
isminetype fIsMine = pwallet->IsMine(txout);
|
||||
// Only need to handle txouts if AT LEAST one of these is true:
|
||||
// 1) they debit from us (sent)
|
||||
@@ -1573,7 +1573,7 @@ set<uint256> CWalletTx::GetConflicts() const
|
||||
|
||||
CAmount CWalletTx::GetDebit(const isminefilter& filter) const
|
||||
{
|
||||
if (vin.empty())
|
||||
if (tx->vin.empty())
|
||||
return 0;
|
||||
|
||||
CAmount debit = 0;
|
||||
@@ -1663,11 +1663,11 @@ CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
|
||||
|
||||
CAmount nCredit = 0;
|
||||
uint256 hashTx = GetHash();
|
||||
for (unsigned int i = 0; i < vout.size(); i++)
|
||||
for (unsigned int i = 0; i < tx->vout.size(); i++)
|
||||
{
|
||||
if (!pwallet->IsSpent(hashTx, i))
|
||||
{
|
||||
const CTxOut &txout = vout[i];
|
||||
const CTxOut &txout = tx->vout[i];
|
||||
nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
|
||||
if (!MoneyRange(nCredit))
|
||||
throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
|
||||
@@ -1706,11 +1706,11 @@ CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
|
||||
return nAvailableWatchCreditCached;
|
||||
|
||||
CAmount nCredit = 0;
|
||||
for (unsigned int i = 0; i < vout.size(); i++)
|
||||
for (unsigned int i = 0; i < tx->vout.size(); i++)
|
||||
{
|
||||
if (!pwallet->IsSpent(GetHash(), i))
|
||||
{
|
||||
const CTxOut &txout = vout[i];
|
||||
const CTxOut &txout = tx->vout[i];
|
||||
nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
|
||||
if (!MoneyRange(nCredit))
|
||||
throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
|
||||
@@ -1758,23 +1758,23 @@ bool CWalletTx::IsTrusted() const
|
||||
return false;
|
||||
|
||||
// Trusted if all inputs are from us and are in the mempool:
|
||||
BOOST_FOREACH(const CTxIn& txin, vin)
|
||||
BOOST_FOREACH(const CTxIn& txin, tx->vin)
|
||||
{
|
||||
// Transactions not sent by us: not trusted
|
||||
const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
|
||||
if (parent == NULL)
|
||||
return false;
|
||||
const CTxOut& parentOut = parent->vout[txin.prevout.n];
|
||||
const CTxOut& parentOut = parent->tx->vout[txin.prevout.n];
|
||||
if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWalletTx::IsEquivalentTo(const CWalletTx& tx) const
|
||||
bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
|
||||
{
|
||||
CMutableTransaction tx1 = *this;
|
||||
CMutableTransaction tx2 = tx;
|
||||
CMutableTransaction tx1 = *this->tx;
|
||||
CMutableTransaction tx2 = *_tx.tx;
|
||||
for (unsigned int i = 0; i < tx1.vin.size(); i++) tx1.vin[i].scriptSig = CScript();
|
||||
for (unsigned int i = 0; i < tx2.vin.size(); i++) tx2.vin[i].scriptSig = CScript();
|
||||
return CTransaction(tx1) == CTransaction(tx2);
|
||||
@@ -1957,10 +1957,10 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
|
||||
if (nDepth == 0 && !pcoin->InMempool())
|
||||
continue;
|
||||
|
||||
for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
|
||||
isminetype mine = IsMine(pcoin->vout[i]);
|
||||
for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) {
|
||||
isminetype mine = IsMine(pcoin->tx->vout[i]);
|
||||
if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
|
||||
!IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
|
||||
!IsLockedCoin((*it).first, i) && (pcoin->tx->vout[i].nValue > 0 || fIncludeZeroValue) &&
|
||||
(!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected(COutPoint((*it).first, i))))
|
||||
vCoins.push_back(COutput(pcoin, i, nDepth,
|
||||
((mine & ISMINE_SPENDABLE) != ISMINE_NO) ||
|
||||
@@ -2043,7 +2043,7 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int
|
||||
continue;
|
||||
|
||||
int i = output.i;
|
||||
CAmount n = pcoin->vout[i].nValue;
|
||||
CAmount n = pcoin->tx->vout[i].nValue;
|
||||
|
||||
pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
|
||||
|
||||
@@ -2130,7 +2130,7 @@ bool CWallet::SelectCoins(const vector<COutput>& vAvailableCoins, const CAmount&
|
||||
{
|
||||
if (!out.fSpendable)
|
||||
continue;
|
||||
nValueRet += out.tx->vout[out.i].nValue;
|
||||
nValueRet += out.tx->tx->vout[out.i].nValue;
|
||||
setCoinsRet.insert(make_pair(out.tx, out.i));
|
||||
}
|
||||
return (nValueRet >= nTargetValue);
|
||||
@@ -2150,9 +2150,9 @@ bool CWallet::SelectCoins(const vector<COutput>& vAvailableCoins, const CAmount&
|
||||
{
|
||||
const CWalletTx* pcoin = &it->second;
|
||||
// Clearly invalid input, fail
|
||||
if (pcoin->vout.size() <= outpoint.n)
|
||||
if (pcoin->tx->vout.size() <= outpoint.n)
|
||||
return false;
|
||||
nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue;
|
||||
nValueFromPresetInputs += pcoin->tx->vout[outpoint.n].nValue;
|
||||
setPresetCoins.insert(make_pair(pcoin, outpoint.n));
|
||||
} else
|
||||
return false; // TODO: Allow non-wallet inputs
|
||||
@@ -2208,10 +2208,10 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool ov
|
||||
return false;
|
||||
|
||||
if (nChangePosInOut != -1)
|
||||
tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.vout[nChangePosInOut]);
|
||||
tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.tx->vout[nChangePosInOut]);
|
||||
|
||||
// Add new txins (keeping original txin scriptSig/order)
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.vin)
|
||||
BOOST_FOREACH(const CTxIn& txin, wtx.tx->vin)
|
||||
{
|
||||
if (!coinControl.IsSelected(txin.prevout))
|
||||
{
|
||||
@@ -2351,7 +2351,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||
}
|
||||
BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
|
||||
{
|
||||
CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
|
||||
CAmount nCredit = pcoin.first->tx->vout[pcoin.second].nValue;
|
||||
//The coin age after the next block (depth+1) is used instead of the current,
|
||||
//reflecting an assumption the user would accept a bit more delay for
|
||||
//a chance at a free transaction.
|
||||
@@ -2466,10 +2466,10 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
|
||||
{
|
||||
bool signSuccess;
|
||||
const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
|
||||
const CScript& scriptPubKey = coin.first->tx->vout[coin.second].scriptPubKey;
|
||||
SignatureData sigdata;
|
||||
if (sign)
|
||||
signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata);
|
||||
signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->tx->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata);
|
||||
else
|
||||
signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata);
|
||||
|
||||
@@ -2494,16 +2494,16 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||
}
|
||||
|
||||
// Embed the constructed transaction data in wtxNew.
|
||||
*static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
|
||||
wtxNew.SetTx(MakeTransactionRef(std::move(txNew)));
|
||||
|
||||
// Limit size
|
||||
if (GetTransactionWeight(txNew) >= MAX_STANDARD_TX_WEIGHT)
|
||||
if (GetTransactionWeight(wtxNew) >= MAX_STANDARD_TX_WEIGHT)
|
||||
{
|
||||
strFailReason = _("Transaction too large");
|
||||
return false;
|
||||
}
|
||||
|
||||
dPriority = wtxNew.ComputePriority(dPriority, nBytes);
|
||||
dPriority = wtxNew.tx->ComputePriority(dPriority, nBytes);
|
||||
|
||||
// Allow to override the default confirmation target over the CoinControl instance
|
||||
int currentConfirmationTarget = nTxConfirmTarget;
|
||||
@@ -2555,7 +2555,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon
|
||||
{
|
||||
{
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
|
||||
LogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString());
|
||||
{
|
||||
// Take key pair from key pool so it won't be used again
|
||||
reservekey.KeepKey();
|
||||
@@ -2565,7 +2565,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon
|
||||
AddToWallet(wtxNew);
|
||||
|
||||
// Notify that old coins are spent
|
||||
BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
|
||||
BOOST_FOREACH(const CTxIn& txin, wtxNew.tx->vin)
|
||||
{
|
||||
CWalletTx &coin = mapWallet[txin.prevout.hash];
|
||||
coin.BindWallet(this);
|
||||
@@ -2939,15 +2939,15 @@ std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
|
||||
if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
|
||||
continue;
|
||||
|
||||
for (unsigned int i = 0; i < pcoin->vout.size(); i++)
|
||||
for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++)
|
||||
{
|
||||
CTxDestination addr;
|
||||
if (!IsMine(pcoin->vout[i]))
|
||||
if (!IsMine(pcoin->tx->vout[i]))
|
||||
continue;
|
||||
if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
|
||||
if(!ExtractDestination(pcoin->tx->vout[i].scriptPubKey, addr))
|
||||
continue;
|
||||
|
||||
CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
|
||||
CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->tx->vout[i].nValue;
|
||||
|
||||
if (!balances.count(addr))
|
||||
balances[addr] = 0;
|
||||
@@ -2969,16 +2969,16 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||
{
|
||||
CWalletTx *pcoin = &walletEntry.second;
|
||||
|
||||
if (pcoin->vin.size() > 0)
|
||||
if (pcoin->tx->vin.size() > 0)
|
||||
{
|
||||
bool any_mine = false;
|
||||
// group all input addresses with each other
|
||||
BOOST_FOREACH(CTxIn txin, pcoin->vin)
|
||||
BOOST_FOREACH(CTxIn txin, pcoin->tx->vin)
|
||||
{
|
||||
CTxDestination address;
|
||||
if(!IsMine(txin)) /* If this input isn't mine, ignore it */
|
||||
continue;
|
||||
if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
|
||||
if(!ExtractDestination(mapWallet[txin.prevout.hash].tx->vout[txin.prevout.n].scriptPubKey, address))
|
||||
continue;
|
||||
grouping.insert(address);
|
||||
any_mine = true;
|
||||
@@ -2987,7 +2987,7 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||
// group change with input addresses
|
||||
if (any_mine)
|
||||
{
|
||||
BOOST_FOREACH(CTxOut txout, pcoin->vout)
|
||||
BOOST_FOREACH(CTxOut txout, pcoin->tx->vout)
|
||||
if (IsChange(txout))
|
||||
{
|
||||
CTxDestination txoutAddr;
|
||||
@@ -3004,11 +3004,11 @@ set< set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||
}
|
||||
|
||||
// group lone addrs by themselves
|
||||
for (unsigned int i = 0; i < pcoin->vout.size(); i++)
|
||||
if (IsMine(pcoin->vout[i]))
|
||||
for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++)
|
||||
if (IsMine(pcoin->tx->vout[i]))
|
||||
{
|
||||
CTxDestination address;
|
||||
if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
|
||||
if(!ExtractDestination(pcoin->tx->vout[i].scriptPubKey, address))
|
||||
continue;
|
||||
grouping.insert(address);
|
||||
groupings.insert(grouping);
|
||||
@@ -3275,7 +3275,7 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
|
||||
if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
|
||||
// ... which are already in a block
|
||||
int nHeight = blit->second->nHeight;
|
||||
BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
|
||||
BOOST_FOREACH(const CTxOut &txout, wtx.tx->vout) {
|
||||
// iterate over all their outputs
|
||||
CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
|
||||
BOOST_FOREACH(const CKeyID &keyid, vAffected) {
|
||||
|
||||
Reference in New Issue
Block a user