@@ -1152,7 +1152,7 @@ CAmount CWallet::GetImmatureWatchOnlyBalance() const
1152
1152
/* *
1153
1153
* populate vCoins with vector of available COutputs.
1154
1154
*/
1155
- void CWallet::AvailableCoins (vector<COutput>& vCoins, bool fOnlyConfirmed , const CCoinControl *coinControl) const
1155
+ void CWallet::AvailableCoins (vector<COutput>& vCoins, bool fOnlyConfirmed , const CCoinControl *coinControl, bool includeWatching ) const
1156
1156
{
1157
1157
vCoins.clear ();
1158
1158
@@ -1181,7 +1181,7 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
1181
1181
if (!(IsSpent (wtxid, i)) && mine != ISMINE_NO &&
1182
1182
!IsLockedCoin ((*it).first , i) && pcoin->vout [i].nValue > 0 &&
1183
1183
(!coinControl || !coinControl->HasSelected () || coinControl->IsSelected ((*it).first , i)))
1184
- vCoins.push_back (COutput (pcoin, i, nDepth, (mine & ISMINE_SPENDABLE) != ISMINE_NO));
1184
+ vCoins.push_back (COutput (pcoin, i, nDepth, (( mine & ISMINE_SPENDABLE) != ISMINE_NO) || (includeWatching && ((mine & ISMINE_WATCH_ONLY) != ISMINE_NO)) ));
1185
1185
}
1186
1186
}
1187
1187
}
@@ -1334,10 +1334,10 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int
1334
1334
return true ;
1335
1335
}
1336
1336
1337
- bool CWallet::SelectCoins (const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int > >& setCoinsRet, CAmount& nValueRet, vector<CTxIn> vPresetVINs, const CCoinControl* coinControl) const
1337
+ bool CWallet::SelectCoins (const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int > >& setCoinsRet, CAmount& nValueRet, vector<CTxIn> vPresetVINs, const CCoinControl* coinControl, bool includeWatching ) const
1338
1338
{
1339
1339
vector<COutput> vCoins;
1340
- AvailableCoins (vCoins, true , coinControl);
1340
+ AvailableCoins (vCoins, true , coinControl, includeWatching );
1341
1341
1342
1342
// create a empty set to store possible VINS
1343
1343
set<pair<const CWalletTx*,unsigned int > > setTempCoins;
@@ -1404,37 +1404,48 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*
1404
1404
}
1405
1405
1406
1406
1407
- bool CWallet::FundTransaction (const CTransaction& txToFund, CMutableTransaction& txNew, CAmount &nFeeRet, std::string& strFailReason)
1407
+ bool CWallet::FundTransaction (const CTransaction& txToFund, CMutableTransaction& txNew, CAmount &nFeeRet, std::string& strFailReason, bool includeWatching )
1408
1408
{
1409
-
1409
+
1410
1410
vector<pair<CScript, CAmount> > vecSend;
1411
1411
vector<CTxIn> vin;
1412
-
1412
+
1413
1413
BOOST_FOREACH (const CTxOut& txOut, txToFund.vout )
1414
1414
{
1415
1415
vecSend.push_back (make_pair (txOut.scriptPubKey , txOut.nValue ));
1416
1416
}
1417
-
1417
+
1418
1418
BOOST_FOREACH (const CTxIn& txIn, txToFund.vin )
1419
1419
{
1420
1420
vin.push_back (txIn);
1421
1421
}
1422
-
1422
+
1423
1423
CReserveKey reservekey (this );
1424
1424
CWalletTx wtx;
1425
- return CreateTransaction (vecSend, vin, wtx, txNew, reservekey, nFeeRet, strFailReason, NULL , false );
1425
+
1426
+ // always try first without including watchonly
1427
+ bool result = CreateTransaction (vecSend, vin, wtx, txNew, reservekey, nFeeRet, strFailReason, NULL , false , false );
1428
+
1429
+ // There may be a solution including watchonly, which may also be a
1430
+ // solution that does not pay any fees.
1431
+ if (!result && includeWatching)
1432
+ result = CreateTransaction (vecSend, vin, wtx, txNew, reservekey, nFeeRet, strFailReason, NULL , false , includeWatching);
1433
+
1434
+ return result;
1426
1435
}
1427
1436
1428
1437
bool CWallet::CreateTransaction (const vector<pair<CScript, CAmount> >& vecSend,
1429
- CWalletTx& wtxNew, CMutableTransaction& txNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
1438
+ CWalletTx& wtxNew, CMutableTransaction& txNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign, bool includeWatching )
1430
1439
{
1431
1440
vector<CTxIn> vINs;
1432
- return CreateTransaction (vecSend, vINs, wtxNew, txNew, reservekey, nFeeRet, strFailReason, coinControl, sign);
1441
+ return CreateTransaction (vecSend, vINs, wtxNew, txNew, reservekey, nFeeRet, strFailReason, coinControl, sign, includeWatching );
1433
1442
}
1434
1443
1435
1444
bool CWallet::CreateTransaction (const vector<pair<CScript, CAmount> >& vecSend, const vector<CTxIn> vINs,
1436
- CWalletTx& wtxNew, CMutableTransaction& txNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
1445
+ CWalletTx& wtxNew, CMutableTransaction& txNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign, bool includeWatching )
1437
1446
{
1447
+ bool cannotFundFee = false ; // used with includeWatching
1448
+
1438
1449
CAmount nValue = 0 ;
1439
1450
BOOST_FOREACH (const PAIRTYPE (CScript, CAmount)& s, vecSend)
1440
1451
{
@@ -1481,10 +1492,22 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
1481
1492
// Choose coins to use
1482
1493
set<pair<const CWalletTx*,unsigned int > > setCoins;
1483
1494
CAmount nValueIn = 0 ;
1484
- if (!SelectCoins (nTotalValue, setCoins, nValueIn, vINs, coinControl))
1495
+ if (!SelectCoins (nTotalValue, setCoins, nValueIn, vINs, coinControl, includeWatching ))
1485
1496
{
1486
- strFailReason = _ (" Insufficient funds" );
1487
- return false ;
1497
+ // fee selection is not mandatory when using includeWatching
1498
+ if (includeWatching && SelectCoins (nTotalValue - nFeeRet, setCoins, nValueIn, vINs, coinControl, includeWatching) && nTotalValue >= nValue)
1499
+ {
1500
+ nFeeRet = 0 ;
1501
+
1502
+ // no more funds available for fee, but target met anyway
1503
+ cannotFundFee = true ;
1504
+ }
1505
+
1506
+ else
1507
+ {
1508
+ strFailReason = _ (" Insufficient funds" );
1509
+ return false ;
1510
+ }
1488
1511
}
1489
1512
BOOST_FOREACH (PAIRTYPE (const CWalletTx*, unsigned int ) pcoin, setCoins)
1490
1513
{
@@ -1554,10 +1577,11 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
1554
1577
BOOST_FOREACH (const PAIRTYPE (const CWalletTx*,unsigned int )& coin, setCoins)
1555
1578
txNew.vin .push_back (CTxIn (coin.first ->GetHash (),coin.second ));
1556
1579
1557
- // Sign
1580
+ // Sign (also calculate fee)
1558
1581
int nIn = 0 ;
1559
1582
BOOST_FOREACH (const PAIRTYPE (const CWalletTx*,unsigned int )& coin, setCoins)
1560
- if (!SignSignature (*this , *coin.first , txNew, nIn++))
1583
+ // when unsignable and watchonly enabled, this may be a watchonly so don't error
1584
+ if (!SignSignature (*this , *coin.first , txNew, nIn++) && !includeWatching)
1561
1585
{
1562
1586
strFailReason = _ (" Signing transaction failed" );
1563
1587
return false ;
@@ -1573,14 +1597,19 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
1573
1597
strFailReason = _ (" Transaction too large" );
1574
1598
return false ;
1575
1599
}
1576
-
1577
- // remove signature if we used the signing only for the fee calculation
1600
+
1601
+ // remove signature if we used the signing only for the fee calculation
1578
1602
if (!sign)
1579
1603
{
1580
1604
BOOST_FOREACH (CTxIn& vin, txNew.vin )
1581
1605
vin.scriptSig = CScript ();
1582
1606
}
1583
-
1607
+
1608
+ // There are no more available funds for funding a transaction
1609
+ // fee, and includeWatching should de-prioritize fee funding.
1610
+ if (includeWatching && cannotFundFee)
1611
+ return true ;
1612
+
1584
1613
dPriority = wtxNew.ComputePriority (dPriority, nBytes);
1585
1614
1586
1615
// Can we complete this as a free transaction?
@@ -1620,13 +1649,13 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, CAmount> >& vecSend,
1620
1649
}
1621
1650
1622
1651
bool CWallet::CreateTransaction (CScript scriptPubKey, const CAmount& nValue,
1623
- CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
1652
+ CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign, bool includeWatching )
1624
1653
{
1625
1654
vector< pair<CScript, CAmount> > vecSend;
1626
1655
vecSend.push_back (make_pair (scriptPubKey, nValue));
1627
1656
CMutableTransaction txNew;
1628
1657
vector<CTxIn> vINs;
1629
- return CreateTransaction (vecSend, vINs, wtxNew, txNew, reservekey, nFeeRet, strFailReason, coinControl, sign);
1658
+ return CreateTransaction (vecSend, vINs, wtxNew, txNew, reservekey, nFeeRet, strFailReason, coinControl, sign, includeWatching );
1630
1659
}
1631
1660
1632
1661
/* *
0 commit comments