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

Code before:
        ExternalSigner signer = ExternalSignerScriptPubKeyMan::GetExternalSigner();
        return signer_spk_man->DisplayAddress(dest, signer);
    }
    return util::Error{_("There is no ScriptPubKeyManager for this address")};
}

bool CWallet::LockCoin(const COutPoint& output, WalletBatch* batch)
{
    AssertLockHeld(cs_wallet);
    setLockedCoins.insert(output);
    if (batch) {
        return batch->WriteLockedUTXO(output);
    }
    return true;
}

bool CWallet::UnlockCoin(const COutPoint& output, WalletBatch* batch)
{
    AssertLockHeld(cs_wallet);
    bool was_locked = setLockedCoins.erase(output);
    if (batch && was_locked) {
        return batch->EraseLockedUTXO(output);
    }
    return true;
}

bool CWallet::UnlockAllCoins()
{
    AssertLockHeld(cs_wallet);
    bool success = true;
    WalletBatch batch(GetDatabase());
    for (auto it = setLockedCoins.begin(); it != setLockedCoins.end(); ++it) {
        success &= batch.EraseLockedUTXO(*it);
    }
    setLockedCoins.clear();
    return success;
}

bool CWallet::IsLockedCoin(const COutPoint& output) const
{
    AssertLockHeld(cs_wallet);
    return setLockedCoins.count(output) > 0;
}

void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) const
{
    AssertLockHeld(cs_wallet);
    for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
         it != setLockedCoins.end(); it++) {
        COutPoint outpt = (*it);
        vOutpts.push_back(outpt);

Review comment (suggestion):
This is the only place where I find the usage of `LoadLockedCoin` unusual because it comes prior to actually locking the coin in disk. But seems unavoidable because persisting in disk is conditional.

Code after:

util::Result<void> CWallet::DisplayAddress(const CTxDestination& dest)
{
    CScript scriptPubKey = GetScriptForDestination(dest);
    for (const auto& spk_man : GetScriptPubKeyMans(scriptPubKey)) {
        auto signer_spk_man = dynamic_cast<ExternalSignerScriptPubKeyMan *>(spk_man);
        if (signer_spk_man == nullptr) {
            continue;
        }
        ExternalSigner signer = ExternalSignerScriptPubKeyMan::GetExternalSigner();
        return signer_spk_man->DisplayAddress(dest, signer);
    }
    return util::Error{_("There is no ScriptPubKeyManager for this address")};
}

void CWallet::LoadLockedCoin(const COutPoint& coin, bool persistent)
{
    AssertLockHeld(cs_wallet);
    m_locked_coins.emplace(coin, persistent);
}

bool CWallet::LockCoin(const COutPoint& output, bool persist)
{
    AssertLockHeld(cs_wallet);
    LoadLockedCoin(output, persist);
    if (persist) {
        WalletBatch batch(GetDatabase());
        return batch.WriteLockedUTXO(output);
    }
    return true;
}

bool CWallet::UnlockCoin(const COutPoint& output)
{
    AssertLockHeld(cs_wallet);
    auto locked_coin_it = m_locked_coins.find(output);
    if (locked_coin_it != m_locked_coins.end()) {
        bool persisted = locked_coin_it->second;
        m_locked_coins.erase(locked_coin_it);
        if (persisted) {
            WalletBatch batch(GetDatabase());
            return batch.EraseLockedUTXO(output);
        }
    }
    return true;
}

bool CWallet::UnlockAllCoins()
{
    AssertLockHeld(cs_wallet);
    bool success = true;