Repository: bitcoin/bitcoin
File: src/wallet/wallet.cpp (C++)

Code before:
    if (m_attaching_chain || role == ChainstateRole::BACKGROUND) {
        return;
    }
    WalletBatch batch(GetDatabase());
    batch.WriteBestBlock(loc);
}

void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in)
{
    LOCK(cs_wallet);
    if (nWalletVersion >= nVersion)
        return;
    WalletLogPrintf("Setting minversion to %d\n", nVersion);
    nWalletVersion = nVersion;

    {
        WalletBatch* batch = batch_in ? batch_in : new WalletBatch(GetDatabase());
        if (nWalletVersion > 40000)
            batch->WriteMinVersion(nWalletVersion);
        if (!batch_in)
            delete batch;
    }
}

std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
{
    std::set<uint256> result;
    AssertLockHeld(cs_wallet);

    const auto it = mapWallet.find(txid);
    if (it == mapWallet.end())
        return result;
    const CWalletTx& wtx = it->second;

    std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;

    for (const CTxIn& txin : wtx.tx->vin)
    {
        if (mapTxSpends.count(txin.prevout) <= 1)
            continue;  // No conflict if zero or one spends
        range = mapTxSpends.equal_range(txin.prevout);
        for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it)
            result.insert(_it->second);
    }
    return result;
}

bool CWallet::HasWalletSpend(const CTransactionRef& tx) const
{
    AssertLockHeld(cs_wallet);
    const Txid& txid = tx->GetHash();

Review comment (performance):
In commit "wallet: Update best block record after block dis/connect" (f1f254f6c9d3cead617300367442c1bbb449af7c)

EDIT: Martin left a similar suggestion https://github.com/bitcoin/bitcoin/pull/30221#discussion_r2085051375. Would be nice to follow up on any of these ideas.

---

It seems like this code is redundant and could be simplified:

```diff
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -666,12 +666,7 @@ void CWallet::SetLastBlockProcessed(int block_height, uint256 block_hash)
     AssertLockHeld(cs_wallet);
 
     SetLastBlockProcessedInMem(block_height, block_hash);
-
-    CBlockLocator loc;
-    chain().findBlock(m_last_block_processed, FoundBlock().locator(loc));
-
-    WalletBatch batch(GetDatabase());
-    batch.WriteBestBlock(loc);
+    WriteBestBlock();
 }
 
 void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in)
```

But this also makes me think it might be better to just delete the SetLastBlockProcessed method, and only keep SetLastBlockProcessedInMem and WriteBestBlock methods to avoid confusing the two concepts. (I do think keeping InMem suffix is nice in either case and clarifies things).

Code after:

    m_last_block_processed = block_hash;
    m_last_block_processed_height = block_height;
}

void CWallet::SetLastBlockProcessed(int block_height, uint256 block_hash)
{
    AssertLockHeld(cs_wallet);

    SetLastBlockProcessedInMem(block_height, block_hash);
    WriteBestBlock();
}

void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch* batch_in)
{
    LOCK(cs_wallet);
    if (nWalletVersion >= nVersion)
        return;
    WalletLogPrintf("Setting minversion to %d\n", nVersion);
    nWalletVersion = nVersion;

    {
        WalletBatch* batch = batch_in ? batch_in : new WalletBatch(GetDatabase());
        if (nWalletVersion > 40000)
            batch->WriteMinVersion(nWalletVersion);
        if (!batch_in)
            delete batch;
    }
}

std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
{
    std::set<uint256> result;
    AssertLockHeld(cs_wallet);

    const auto it = mapWallet.find(txid);
    if (it == mapWallet.end())
        return result;
    const CWalletTx& wtx = it->second;

    std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;

    for (const CTxIn& txin : wtx.tx->vin)
    {
        if (mapTxSpends.count(txin.prevout) <= 1)
            continue;  // No conflict if zero or one spends
        range = mapTxSpends.equal_range(txin.prevout);
        for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it)
            result.insert(_it->second);
    }
    return result;