mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-19 05:45:05 +01:00
Merge bitcoin/bitcoin#25659: wallet: simplify ListCoins implementation
a2ac6f9582
wallet: unify FindNonChangeParentOutput functions (furszy)b3f4e82737
wallet: simplify ListCoins implementation (furszy) Pull request description: Focused on the following changes: 1) Removed the entire locked coins lookup that was inside `ListCoins` by including them directly on the `AvailableCoins` result (where we were skipping them before). 2) Unified both `FindNonChangeParentOutput` functions (only called from `ListCoins`) ACKs for top commit: achow101: ACKa2ac6f9582
aureleoules: ACKa2ac6f9582
, LGTM theStack: Code-review ACKa2ac6f9582
Tree-SHA512: f72b21ee1600c5992559b5dcd8ff260527afac2ec696737f998343a0850b84d439e7f86ea52a14cc0cddabf132a30bf5b52fb34950578ac323083d4375b937f1
This commit is contained in:
commit
8ae2808a43
@ -362,28 +362,24 @@ CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinContr
|
||||
return AvailableCoins(wallet, coinControl).GetTotalAmount();
|
||||
}
|
||||
|
||||
const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const CTransaction& tx, int output)
|
||||
{
|
||||
AssertLockHeld(wallet.cs_wallet);
|
||||
const CTransaction* ptx = &tx;
|
||||
int n = output;
|
||||
while (OutputIsChange(wallet, ptx->vout[n]) && ptx->vin.size() > 0) {
|
||||
const COutPoint& prevout = ptx->vin[0].prevout;
|
||||
auto it = wallet.mapWallet.find(prevout.hash);
|
||||
if (it == wallet.mapWallet.end() || it->second.tx->vout.size() <= prevout.n ||
|
||||
!wallet.IsMine(it->second.tx->vout[prevout.n])) {
|
||||
break;
|
||||
}
|
||||
ptx = it->second.tx.get();
|
||||
n = prevout.n;
|
||||
}
|
||||
return ptx->vout[n];
|
||||
}
|
||||
|
||||
const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const COutPoint& outpoint)
|
||||
{
|
||||
AssertLockHeld(wallet.cs_wallet);
|
||||
return FindNonChangeParentOutput(wallet, *wallet.GetWalletTx(outpoint.hash)->tx, outpoint.n);
|
||||
const CWalletTx* wtx{Assert(wallet.GetWalletTx(outpoint.hash))};
|
||||
|
||||
const CTransaction* ptx = wtx->tx.get();
|
||||
int n = outpoint.n;
|
||||
while (OutputIsChange(wallet, ptx->vout[n]) && ptx->vin.size() > 0) {
|
||||
const COutPoint& prevout = ptx->vin[0].prevout;
|
||||
const CWalletTx* it = wallet.GetWalletTx(prevout.hash);
|
||||
if (!it || it->tx->vout.size() <= prevout.n ||
|
||||
!wallet.IsMine(it->tx->vout[prevout.n])) {
|
||||
break;
|
||||
}
|
||||
ptx = it->tx.get();
|
||||
n = prevout.n;
|
||||
}
|
||||
return ptx->vout[n];
|
||||
}
|
||||
|
||||
std::map<CTxDestination, std::vector<COutput>> ListCoins(const CWallet& wallet)
|
||||
@ -392,37 +388,19 @@ std::map<CTxDestination, std::vector<COutput>> ListCoins(const CWallet& wallet)
|
||||
|
||||
std::map<CTxDestination, std::vector<COutput>> result;
|
||||
|
||||
for (COutput& coin : AvailableCoinsListUnspent(wallet).All()) {
|
||||
CCoinControl coin_control;
|
||||
// Include watch-only for LegacyScriptPubKeyMan wallets without private keys
|
||||
coin_control.fAllowWatchOnly = wallet.GetLegacyScriptPubKeyMan() && wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
|
||||
CoinFilterParams coins_params;
|
||||
coins_params.only_spendable = false;
|
||||
coins_params.skip_locked = false;
|
||||
for (const COutput& coin : AvailableCoins(wallet, &coin_control, /*feerate=*/std::nullopt, coins_params).All()) {
|
||||
CTxDestination address;
|
||||
if ((coin.spendable || (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && coin.solvable)) &&
|
||||
ExtractDestination(FindNonChangeParentOutput(wallet, coin.outpoint).scriptPubKey, address)) {
|
||||
result[address].emplace_back(std::move(coin));
|
||||
result[address].emplace_back(coin);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<COutPoint> lockedCoins;
|
||||
wallet.ListLockedCoins(lockedCoins);
|
||||
// Include watch-only for LegacyScriptPubKeyMan wallets without private keys
|
||||
const bool include_watch_only = wallet.GetLegacyScriptPubKeyMan() && wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
|
||||
const isminetype is_mine_filter = include_watch_only ? ISMINE_WATCH_ONLY : ISMINE_SPENDABLE;
|
||||
for (const COutPoint& output : lockedCoins) {
|
||||
auto it = wallet.mapWallet.find(output.hash);
|
||||
if (it != wallet.mapWallet.end()) {
|
||||
const auto& wtx = it->second;
|
||||
int depth = wallet.GetTxDepthInMainChain(wtx);
|
||||
if (depth >= 0 && output.n < wtx.tx->vout.size() &&
|
||||
wallet.IsMine(wtx.tx->vout[output.n]) == is_mine_filter
|
||||
) {
|
||||
CTxDestination address;
|
||||
if (ExtractDestination(FindNonChangeParentOutput(wallet, *wtx.tx, output.n).scriptPubKey, address)) {
|
||||
const auto out = wtx.tx->vout.at(output.n);
|
||||
result[address].emplace_back(
|
||||
COutPoint(wtx.GetHash(), output.n), out, depth, CalculateMaximumSignedInputSize(out, &wallet, /*coin_control=*/nullptr), /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ false, wtx.GetTxTime(), CachedTxIsFromMe(wallet, wtx, ISMINE_ALL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,6 @@ CAmount GetAvailableBalance(const CWallet& wallet, const CCoinControl* coinContr
|
||||
/**
|
||||
* Find non-change parent output.
|
||||
*/
|
||||
const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const CTransaction& tx, int output) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||
const CTxOut& FindNonChangeParentOutput(const CWallet& wallet, const COutPoint& outpoint) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user