@@ -982,6 +982,13 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const CBlockI
982
982
return false ;
983
983
}
984
984
985
+ bool CWallet::TransactionCanBeAbandoned (const uint256& hashTx) const
986
+ {
987
+ LOCK2 (cs_main, cs_wallet);
988
+ const CWalletTx* wtx = GetWalletTx (hashTx);
989
+ return wtx && !wtx->isAbandoned () && wtx->GetDepthInMainChain () <= 0 && !wtx->InMempool ();
990
+ }
991
+
985
992
bool CWallet::AbandonTransaction (const uint256& hashTx)
986
993
{
987
994
LOCK2 (cs_main, cs_wallet);
@@ -1977,6 +1984,19 @@ CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth, cons
1977
1984
return balance;
1978
1985
}
1979
1986
1987
+ CAmount CWallet::GetAvailableBalance (const CCoinControl* coinControl) const
1988
+ {
1989
+ CAmount balance = 0 ;
1990
+ std::vector<COutput> vCoins;
1991
+ AvailableCoins (vCoins, true , coinControl);
1992
+ for (const COutput& out : vCoins) {
1993
+ if (out.fSpendable ) {
1994
+ balance += out.tx ->tx ->vout [out.i ].nValue ;
1995
+ }
1996
+ }
1997
+ return balance;
1998
+ }
1999
+
1980
2000
void CWallet::AvailableCoins (std::vector<COutput> &vCoins, bool fOnlySafe , const CCoinControl *coinControl, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t &nMaximumCount, const int &nMinDepth, const int &nMaxDepth) const
1981
2001
{
1982
2002
vCoins.clear ();
@@ -2088,6 +2108,69 @@ void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const
2088
2108
}
2089
2109
}
2090
2110
2111
+ std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins () const
2112
+ {
2113
+ // TODO: Add AssertLockHeld(cs_wallet) here.
2114
+ //
2115
+ // Because the return value from this function contains pointers to
2116
+ // CWalletTx objects, callers to this function really should acquire the
2117
+ // cs_wallet lock before calling it. However, the current caller doesn't
2118
+ // acquire this lock yet. There was an attempt to add the missing lock in
2119
+ // https://github.com/bitcoin/bitcoin/pull/10340, but that change has been
2120
+ // postponed until after https://github.com/bitcoin/bitcoin/pull/10244 to
2121
+ // avoid adding some extra complexity to the Qt code.
2122
+
2123
+ std::map<CTxDestination, std::vector<COutput>> result;
2124
+
2125
+ std::vector<COutput> availableCoins;
2126
+ AvailableCoins (availableCoins);
2127
+
2128
+ LOCK2 (cs_main, cs_wallet);
2129
+ for (auto & coin : availableCoins) {
2130
+ CTxDestination address;
2131
+ if (coin.fSpendable &&
2132
+ ExtractDestination (FindNonChangeParentOutput (*coin.tx ->tx , coin.i ).scriptPubKey , address)) {
2133
+ result[address].emplace_back (std::move (coin));
2134
+ }
2135
+ }
2136
+
2137
+ std::vector<COutPoint> lockedCoins;
2138
+ ListLockedCoins (lockedCoins);
2139
+ for (const auto & output : lockedCoins) {
2140
+ auto it = mapWallet.find (output.hash );
2141
+ if (it != mapWallet.end ()) {
2142
+ int depth = it->second .GetDepthInMainChain ();
2143
+ if (depth >= 0 && output.n < it->second .tx ->vout .size () &&
2144
+ IsMine (it->second .tx ->vout [output.n ]) == ISMINE_SPENDABLE) {
2145
+ CTxDestination address;
2146
+ if (ExtractDestination (FindNonChangeParentOutput (*it->second .tx , output.n ).scriptPubKey , address)) {
2147
+ result[address].emplace_back (
2148
+ &it->second , output.n , depth, true /* spendable */ , true /* solvable */ , false /* safe */ );
2149
+ }
2150
+ }
2151
+ }
2152
+ }
2153
+
2154
+ return result;
2155
+ }
2156
+
2157
+ const CTxOut& CWallet::FindNonChangeParentOutput (const CTransaction& tx, int output) const
2158
+ {
2159
+ const CTransaction* ptx = &tx;
2160
+ int n = output;
2161
+ while (IsChange (ptx->vout [n]) && ptx->vin .size () > 0 ) {
2162
+ const COutPoint& prevout = ptx->vin [0 ].prevout ;
2163
+ auto it = mapWallet.find (prevout.hash );
2164
+ if (it == mapWallet.end () || it->second .tx ->vout .size () <= prevout.n ||
2165
+ !IsMine (it->second .tx ->vout [prevout.n ])) {
2166
+ break ;
2167
+ }
2168
+ ptx = it->second .tx .get ();
2169
+ n = prevout.n ;
2170
+ }
2171
+ return ptx->vout [n];
2172
+ }
2173
+
2091
2174
static void ApproximateBestSubset (const std::vector<CInputCoin>& vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
2092
2175
std::vector<char >& vfBest, CAmount& nBest, int iterations = 1000 )
2093
2176
{
@@ -3408,7 +3491,7 @@ bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
3408
3491
return (setLockedCoins.count (outpt) > 0 );
3409
3492
}
3410
3493
3411
- void CWallet::ListLockedCoins (std::vector<COutPoint>& vOutpts)
3494
+ void CWallet::ListLockedCoins (std::vector<COutPoint>& vOutpts) const
3412
3495
{
3413
3496
AssertLockHeld (cs_wallet); // setLockedCoins
3414
3497
for (std::set<COutPoint>::iterator it = setLockedCoins.begin ();
@@ -3609,6 +3692,20 @@ bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, st
3609
3692
return false ;
3610
3693
}
3611
3694
3695
+ std::vector<std::string> CWallet::GetDestValues (const std::string& prefix) const
3696
+ {
3697
+ LOCK (cs_wallet);
3698
+ std::vector<std::string> values;
3699
+ for (const auto & address : mapAddressBook) {
3700
+ for (const auto & data : address.second .destdata ) {
3701
+ if (!data.first .compare (0 , prefix.size (), prefix)) {
3702
+ values.emplace_back (data.second );
3703
+ }
3704
+ }
3705
+ }
3706
+ return values;
3707
+ }
3708
+
3612
3709
std::string CWallet::GetWalletHelpString (bool showDebug)
3613
3710
{
3614
3711
std::string strUsage = HelpMessageGroup (_ (" Wallet options:" ));
0 commit comments