mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 06:58:57 +01:00
Merge #15596: rpc: Ignore sendmany::minconf as dummy value
fabfb79673doc: Add release notes for 15596 (MarcoFalke)fac1a0fe54wallet: Remove unused GetLegacyBalance (MarcoFalke)faa3a246e8scripted-diff: wallet: Rename pcoin to wtx (MarcoFalke)fae5f874d5rpc: Document that minconf is an ignored dummy value (MarcoFalke) Pull request description: Other RPCs such as `sendtoaddress` don't have this option at all and `sendmany` should by default spend from (lets say) our change. ACKs for commit fabfb7: jnewbery: utACKfabfb79673ryanofsky: utACKfabfb79673. Nice writeup! Release notes are only change since previous review. Tree-SHA512: 2526ead2330be7c2beb78b96bc5e55440566c4a3a809bbbd66f5c9fc517f6890affa5d14005dc102644d49679a374510f9507255e870cf88aaa63e429beef658
This commit is contained in:
@@ -2162,9 +2162,9 @@ CAmount CWallet::GetBalance(const isminefilter& filter, const int min_depth) con
|
||||
LOCK(cs_wallet);
|
||||
for (const auto& entry : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &entry.second;
|
||||
if (pcoin->IsTrusted(*locked_chain) && pcoin->GetDepthInMainChain(*locked_chain) >= min_depth) {
|
||||
nTotal += pcoin->GetAvailableCredit(*locked_chain, true, filter);
|
||||
const CWalletTx& wtx = entry.second;
|
||||
if (wtx.IsTrusted(*locked_chain) && wtx.GetDepthInMainChain(*locked_chain) >= min_depth) {
|
||||
nTotal += wtx.GetAvailableCredit(*locked_chain, true, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2180,9 +2180,9 @@ CAmount CWallet::GetUnconfirmedBalance() const
|
||||
LOCK(cs_wallet);
|
||||
for (const auto& entry : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &entry.second;
|
||||
if (!pcoin->IsTrusted(*locked_chain) && pcoin->GetDepthInMainChain(*locked_chain) == 0 && pcoin->InMempool())
|
||||
nTotal += pcoin->GetAvailableCredit(*locked_chain);
|
||||
const CWalletTx& wtx = entry.second;
|
||||
if (!wtx.IsTrusted(*locked_chain) && wtx.GetDepthInMainChain(*locked_chain) == 0 && wtx.InMempool())
|
||||
nTotal += wtx.GetAvailableCredit(*locked_chain);
|
||||
}
|
||||
}
|
||||
return nTotal;
|
||||
@@ -2196,8 +2196,8 @@ CAmount CWallet::GetImmatureBalance() const
|
||||
LOCK(cs_wallet);
|
||||
for (const auto& entry : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &entry.second;
|
||||
nTotal += pcoin->GetImmatureCredit(*locked_chain);
|
||||
const CWalletTx& wtx = entry.second;
|
||||
nTotal += wtx.GetImmatureCredit(*locked_chain);
|
||||
}
|
||||
}
|
||||
return nTotal;
|
||||
@@ -2211,9 +2211,9 @@ CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
|
||||
LOCK(cs_wallet);
|
||||
for (const auto& entry : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &entry.second;
|
||||
if (!pcoin->IsTrusted(*locked_chain) && pcoin->GetDepthInMainChain(*locked_chain) == 0 && pcoin->InMempool())
|
||||
nTotal += pcoin->GetAvailableCredit(*locked_chain, true, ISMINE_WATCH_ONLY);
|
||||
const CWalletTx& wtx = entry.second;
|
||||
if (!wtx.IsTrusted(*locked_chain) && wtx.GetDepthInMainChain(*locked_chain) == 0 && wtx.InMempool())
|
||||
nTotal += wtx.GetAvailableCredit(*locked_chain, true, ISMINE_WATCH_ONLY);
|
||||
}
|
||||
}
|
||||
return nTotal;
|
||||
@@ -2227,53 +2227,13 @@ CAmount CWallet::GetImmatureWatchOnlyBalance() const
|
||||
LOCK(cs_wallet);
|
||||
for (const auto& entry : mapWallet)
|
||||
{
|
||||
const CWalletTx* pcoin = &entry.second;
|
||||
nTotal += pcoin->GetImmatureWatchOnlyCredit(*locked_chain);
|
||||
const CWalletTx& wtx = entry.second;
|
||||
nTotal += wtx.GetImmatureWatchOnlyCredit(*locked_chain);
|
||||
}
|
||||
}
|
||||
return nTotal;
|
||||
}
|
||||
|
||||
// Calculate total balance in a different way from GetBalance. The biggest
|
||||
// difference is that GetBalance sums up all unspent TxOuts paying to the
|
||||
// wallet, while this sums up both spent and unspent TxOuts paying to the
|
||||
// wallet, and then subtracts the values of TxIns spending from the wallet. This
|
||||
// also has fewer restrictions on which unconfirmed transactions are considered
|
||||
// trusted.
|
||||
CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth) const
|
||||
{
|
||||
auto locked_chain = chain().lock();
|
||||
LOCK(cs_wallet);
|
||||
|
||||
CAmount balance = 0;
|
||||
for (const auto& entry : mapWallet) {
|
||||
const CWalletTx& wtx = entry.second;
|
||||
const int depth = wtx.GetDepthInMainChain(*locked_chain);
|
||||
if (depth < 0 || !locked_chain->checkFinalTx(*wtx.tx) || wtx.IsImmatureCoinBase(*locked_chain)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Loop through tx outputs and add incoming payments. For outgoing txs,
|
||||
// treat change outputs specially, as part of the amount debited.
|
||||
CAmount debit = wtx.GetDebit(filter);
|
||||
const bool outgoing = debit > 0;
|
||||
for (const CTxOut& out : wtx.tx->vout) {
|
||||
if (outgoing && IsChange(out)) {
|
||||
debit -= out.nValue;
|
||||
} else if (IsMine(out) & filter && depth >= minDepth) {
|
||||
balance += out.nValue;
|
||||
}
|
||||
}
|
||||
|
||||
// For outgoing txs, subtract amount debited.
|
||||
if (outgoing) {
|
||||
balance -= debit;
|
||||
}
|
||||
}
|
||||
|
||||
return balance;
|
||||
}
|
||||
|
||||
CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const
|
||||
{
|
||||
auto locked_chain = chain().lock();
|
||||
@@ -2300,25 +2260,25 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<
|
||||
for (const auto& entry : mapWallet)
|
||||
{
|
||||
const uint256& wtxid = entry.first;
|
||||
const CWalletTx* pcoin = &entry.second;
|
||||
const CWalletTx& wtx = entry.second;
|
||||
|
||||
if (!locked_chain.checkFinalTx(*pcoin->tx)) {
|
||||
if (!locked_chain.checkFinalTx(*wtx.tx)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pcoin->IsImmatureCoinBase(locked_chain))
|
||||
if (wtx.IsImmatureCoinBase(locked_chain))
|
||||
continue;
|
||||
|
||||
int nDepth = pcoin->GetDepthInMainChain(locked_chain);
|
||||
int nDepth = wtx.GetDepthInMainChain(locked_chain);
|
||||
if (nDepth < 0)
|
||||
continue;
|
||||
|
||||
// We should not consider coins which aren't at least in our mempool
|
||||
// It's possible for these to be conflicted via ancestors which we may never be able to detect
|
||||
if (nDepth == 0 && !pcoin->InMempool())
|
||||
if (nDepth == 0 && !wtx.InMempool())
|
||||
continue;
|
||||
|
||||
bool safeTx = pcoin->IsTrusted(locked_chain);
|
||||
bool safeTx = wtx.IsTrusted(locked_chain);
|
||||
|
||||
// We should not consider coins from transactions that are replacing
|
||||
// other transactions.
|
||||
@@ -2335,7 +2295,7 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<
|
||||
// be a 1-block reorg away from the chain where transactions A and C
|
||||
// were accepted to another chain where B, B', and C were all
|
||||
// accepted.
|
||||
if (nDepth == 0 && pcoin->mapValue.count("replaces_txid")) {
|
||||
if (nDepth == 0 && wtx.mapValue.count("replaces_txid")) {
|
||||
safeTx = false;
|
||||
}
|
||||
|
||||
@@ -2347,7 +2307,7 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<
|
||||
// intending to replace A', but potentially resulting in a scenario
|
||||
// where A, A', and D could all be accepted (instead of just B and
|
||||
// D, or just A and A' like the user would want).
|
||||
if (nDepth == 0 && pcoin->mapValue.count("replaced_by_txid")) {
|
||||
if (nDepth == 0 && wtx.mapValue.count("replaced_by_txid")) {
|
||||
safeTx = false;
|
||||
}
|
||||
|
||||
@@ -2358,8 +2318,8 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<
|
||||
if (nDepth < nMinDepth || nDepth > nMaxDepth)
|
||||
continue;
|
||||
|
||||
for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) {
|
||||
if (pcoin->tx->vout[i].nValue < nMinimumAmount || pcoin->tx->vout[i].nValue > nMaximumAmount)
|
||||
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
|
||||
if (wtx.tx->vout[i].nValue < nMinimumAmount || wtx.tx->vout[i].nValue > nMaximumAmount)
|
||||
continue;
|
||||
|
||||
if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs && !coinControl->IsSelected(COutPoint(entry.first, i)))
|
||||
@@ -2371,20 +2331,20 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<
|
||||
if (IsSpent(locked_chain, wtxid, i))
|
||||
continue;
|
||||
|
||||
isminetype mine = IsMine(pcoin->tx->vout[i]);
|
||||
isminetype mine = IsMine(wtx.tx->vout[i]);
|
||||
|
||||
if (mine == ISMINE_NO) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool solvable = IsSolvable(*this, pcoin->tx->vout[i].scriptPubKey);
|
||||
bool solvable = IsSolvable(*this, wtx.tx->vout[i].scriptPubKey);
|
||||
bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
|
||||
|
||||
vCoins.push_back(COutput(pcoin, i, nDepth, spendable, solvable, safeTx, (coinControl && coinControl->fAllowWatchOnly)));
|
||||
vCoins.push_back(COutput(&wtx, i, nDepth, spendable, solvable, safeTx, (coinControl && coinControl->fAllowWatchOnly)));
|
||||
|
||||
// Checks the sum amount of all UTXO's.
|
||||
if (nMinimumSumAmount != MAX_MONEY) {
|
||||
nTotal += pcoin->tx->vout[i].nValue;
|
||||
nTotal += wtx.tx->vout[i].nValue;
|
||||
|
||||
if (nTotal >= nMinimumSumAmount) {
|
||||
return;
|
||||
@@ -2542,13 +2502,13 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
|
||||
std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
|
||||
if (it != mapWallet.end())
|
||||
{
|
||||
const CWalletTx* pcoin = &it->second;
|
||||
const CWalletTx& wtx = it->second;
|
||||
// Clearly invalid input, fail
|
||||
if (pcoin->tx->vout.size() <= outpoint.n)
|
||||
if (wtx.tx->vout.size() <= outpoint.n)
|
||||
return false;
|
||||
// Just to calculate the marginal byte size
|
||||
nValueFromPresetInputs += pcoin->tx->vout[outpoint.n].nValue;
|
||||
setPresetCoins.insert(CInputCoin(pcoin->tx, outpoint.n));
|
||||
nValueFromPresetInputs += wtx.tx->vout[outpoint.n].nValue;
|
||||
setPresetCoins.insert(CInputCoin(wtx.tx, outpoint.n));
|
||||
} else
|
||||
return false; // TODO: Allow non-wallet inputs
|
||||
}
|
||||
@@ -3586,27 +3546,27 @@ std::map<CTxDestination, CAmount> CWallet::GetAddressBalances(interfaces::Chain:
|
||||
LOCK(cs_wallet);
|
||||
for (const auto& walletEntry : mapWallet)
|
||||
{
|
||||
const CWalletTx *pcoin = &walletEntry.second;
|
||||
const CWalletTx& wtx = walletEntry.second;
|
||||
|
||||
if (!pcoin->IsTrusted(locked_chain))
|
||||
if (!wtx.IsTrusted(locked_chain))
|
||||
continue;
|
||||
|
||||
if (pcoin->IsImmatureCoinBase(locked_chain))
|
||||
if (wtx.IsImmatureCoinBase(locked_chain))
|
||||
continue;
|
||||
|
||||
int nDepth = pcoin->GetDepthInMainChain(locked_chain);
|
||||
if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
|
||||
int nDepth = wtx.GetDepthInMainChain(locked_chain);
|
||||
if (nDepth < (wtx.IsFromMe(ISMINE_ALL) ? 0 : 1))
|
||||
continue;
|
||||
|
||||
for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++)
|
||||
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++)
|
||||
{
|
||||
CTxDestination addr;
|
||||
if (!IsMine(pcoin->tx->vout[i]))
|
||||
if (!IsMine(wtx.tx->vout[i]))
|
||||
continue;
|
||||
if(!ExtractDestination(pcoin->tx->vout[i].scriptPubKey, addr))
|
||||
if(!ExtractDestination(wtx.tx->vout[i].scriptPubKey, addr))
|
||||
continue;
|
||||
|
||||
CAmount n = IsSpent(locked_chain, walletEntry.first, i) ? 0 : pcoin->tx->vout[i].nValue;
|
||||
CAmount n = IsSpent(locked_chain, walletEntry.first, i) ? 0 : wtx.tx->vout[i].nValue;
|
||||
|
||||
if (!balances.count(addr))
|
||||
balances[addr] = 0;
|
||||
@@ -3626,13 +3586,13 @@ std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||
|
||||
for (const auto& walletEntry : mapWallet)
|
||||
{
|
||||
const CWalletTx *pcoin = &walletEntry.second;
|
||||
const CWalletTx& wtx = walletEntry.second;
|
||||
|
||||
if (pcoin->tx->vin.size() > 0)
|
||||
if (wtx.tx->vin.size() > 0)
|
||||
{
|
||||
bool any_mine = false;
|
||||
// group all input addresses with each other
|
||||
for (const CTxIn& txin : pcoin->tx->vin)
|
||||
for (const CTxIn& txin : wtx.tx->vin)
|
||||
{
|
||||
CTxDestination address;
|
||||
if(!IsMine(txin)) /* If this input isn't mine, ignore it */
|
||||
@@ -3646,7 +3606,7 @@ std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||
// group change with input addresses
|
||||
if (any_mine)
|
||||
{
|
||||
for (const CTxOut& txout : pcoin->tx->vout)
|
||||
for (const CTxOut& txout : wtx.tx->vout)
|
||||
if (IsChange(txout))
|
||||
{
|
||||
CTxDestination txoutAddr;
|
||||
@@ -3663,7 +3623,7 @@ std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||
}
|
||||
|
||||
// group lone addrs by themselves
|
||||
for (const auto& txout : pcoin->tx->vout)
|
||||
for (const auto& txout : wtx.tx->vout)
|
||||
if (IsMine(txout))
|
||||
{
|
||||
CTxDestination address;
|
||||
|
||||
Reference in New Issue
Block a user