Skip to content

Commit 9753286

Browse files
committed
Change mapTxSpends to be a std::unordered_multimap
1 parent 1f798fe commit 9753286

File tree

4 files changed

+28
-20
lines changed

4 files changed

+28
-20
lines changed

src/wallet/feebumper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace wallet {
2121
//! mined, or conflicts with a mined transaction. Return a feebumper::Result.
2222
static feebumper::Result PreconditionChecks(const CWallet& wallet, const CWalletTx& wtx, std::vector<bilingual_str>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
2323
{
24-
if (wallet.HasWalletSpend(wtx.GetHash())) {
24+
if (wallet.HasWalletSpend(wtx.tx)) {
2525
errors.push_back(Untranslated("Transaction has descendants in the wallet"));
2626
return feebumper::Result::INVALID_PARAMETER;
2727
}

src/wallet/test/wallet_tests.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -843,16 +843,16 @@ BOOST_FIXTURE_TEST_CASE(ZapSelectTx, TestChain100Setup)
843843

844844
{
845845
auto block_hash = block_tx.GetHash();
846-
auto prev_hash = m_coinbase_txns[0]->GetHash();
846+
auto prev_tx = m_coinbase_txns[0];
847847

848848
LOCK(wallet->cs_wallet);
849-
BOOST_CHECK(wallet->HasWalletSpend(prev_hash));
849+
BOOST_CHECK(wallet->HasWalletSpend(prev_tx));
850850
BOOST_CHECK_EQUAL(wallet->mapWallet.count(block_hash), 1u);
851851

852852
std::vector<uint256> vHashIn{ block_hash }, vHashOut;
853853
BOOST_CHECK_EQUAL(wallet->ZapSelectTx(vHashIn, vHashOut), DBErrors::LOAD_OK);
854854

855-
BOOST_CHECK(!wallet->HasWalletSpend(prev_hash));
855+
BOOST_CHECK(!wallet->HasWalletSpend(prev_tx));
856856
BOOST_CHECK_EQUAL(wallet->mapWallet.count(block_hash), 0u);
857857
}
858858

src/wallet/wallet.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -569,11 +569,17 @@ std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
569569
return result;
570570
}
571571

572-
bool CWallet::HasWalletSpend(const uint256& txid) const
572+
bool CWallet::HasWalletSpend(const CTransactionRef& tx) const
573573
{
574574
AssertLockHeld(cs_wallet);
575-
auto iter = mapTxSpends.lower_bound(COutPoint(txid, 0));
576-
return (iter != mapTxSpends.end() && iter->first.hash == txid);
575+
const uint256& txid = tx->GetHash();
576+
for (unsigned int i = 0; i < tx->vout.size(); ++i) {
577+
auto iter = mapTxSpends.find(COutPoint(txid, i));
578+
if (iter != mapTxSpends.end()) {
579+
return true;
580+
}
581+
}
582+
return false;
577583
}
578584

579585
void CWallet::Flush()
@@ -1191,12 +1197,13 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
11911197
batch.WriteTx(wtx);
11921198
NotifyTransactionChanged(wtx.GetHash(), CT_UPDATED);
11931199
// Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too
1194-
TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
1195-
while (iter != mapTxSpends.end() && iter->first.hash == now) {
1196-
if (!done.count(iter->second)) {
1197-
todo.insert(iter->second);
1200+
for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
1201+
std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(COutPoint(now, i));
1202+
for (TxSpends::const_iterator iter = range.first; iter != range.second; ++iter) {
1203+
if (!done.count(iter->second)) {
1204+
todo.insert(iter->second);
1205+
}
11981206
}
1199-
iter++;
12001207
}
12011208
// If a transaction changes 'conflicted' state, that changes the balance
12021209
// available of the outputs it spends. So force those to be recomputed
@@ -1242,12 +1249,13 @@ void CWallet::MarkConflicted(const uint256& hashBlock, int conflicting_height, c
12421249
wtx.MarkDirty();
12431250
batch.WriteTx(wtx);
12441251
// Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too
1245-
TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
1246-
while (iter != mapTxSpends.end() && iter->first.hash == now) {
1247-
if (!done.count(iter->second)) {
1248-
todo.insert(iter->second);
1249-
}
1250-
iter++;
1252+
for (unsigned int i = 0; i < wtx.tx->vout.size(); ++i) {
1253+
std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(COutPoint(now, i));
1254+
for (TxSpends::const_iterator iter = range.first; iter != range.second; ++iter) {
1255+
if (!done.count(iter->second)) {
1256+
todo.insert(iter->second);
1257+
}
1258+
}
12511259
}
12521260
// If a transaction changes 'conflicted' state, that changes the balance
12531261
// available of the outputs it spends. So force those to be recomputed

src/wallet/wallet.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
259259
* detect and report conflicts (double-spends or
260260
* mutated transactions where the mutant gets mined).
261261
*/
262-
typedef std::multimap<COutPoint, uint256> TxSpends;
262+
typedef std::unordered_multimap<COutPoint, uint256, SaltedOutpointHasher> TxSpends;
263263
TxSpends mapTxSpends GUARDED_BY(cs_wallet);
264264
void AddToSpends(const COutPoint& outpoint, const uint256& wtxid, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
265265
void AddToSpends(const CWalletTx& wtx, WalletBatch* batch = nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
@@ -708,7 +708,7 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
708708
std::set<uint256> GetConflicts(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
709709

710710
//! Check if a given transaction has any of its outputs spent by another transaction in the wallet
711-
bool HasWalletSpend(const uint256& txid) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
711+
bool HasWalletSpend(const CTransactionRef& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
712712

713713
//! Flush wallet (bitdb flush)
714714
void Flush();

0 commit comments

Comments
 (0)