Skip to content

Commit 3b35e48

Browse files
committed
[RPC] add feerate option to fundrawtransaction
1 parent a9c8b74 commit 3b35e48

File tree

5 files changed

+26
-6
lines changed

5 files changed

+26
-6
lines changed

qa/rpc-tests/fundrawtransaction.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,14 @@ def run_test(self):
677677
assert(signedtx["complete"])
678678
self.nodes[0].sendrawtransaction(signedtx["hex"])
679679

680+
inputs = []
681+
outputs = {self.nodes[2].getnewaddress() : 1}
682+
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
683+
result = self.nodes[3].fundrawtransaction(rawtx, )
684+
result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2000})
685+
result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10000})
686+
assert_equal(result['fee']*2, result2['fee'])
687+
assert_equal(result['fee']*10, result3['fee'])
680688

681689
if __name__ == '__main__':
682690
RawTransactionsTest().main()

src/coincontrol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class CCoinControl
1818
bool fAllowWatchOnly;
1919
//! Minimum absolute fee (not per kilobyte)
2020
CAmount nMinimumTotalFee;
21+
//! Feerate to use (0 = estimate fee with payTxFee fallback)
22+
CFeeRate nFeeRate;
2123

2224
CCoinControl()
2325
{
@@ -31,6 +33,7 @@ class CCoinControl
3133
fAllowWatchOnly = false;
3234
setSelected.clear();
3335
nMinimumTotalFee = 0;
36+
nFeeRate = CFeeRate(0);
3437
}
3538

3639
bool HasSelected() const

src/wallet/rpcwallet.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2458,6 +2458,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
24582458
" \"changePosition\" (numeric, optional, default random) The index of the change output\n"
24592459
" \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
24602460
" \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
2461+
" \"feeRate\" (numeric, optional, default 0=estimate) Set a specific feerate (fee per KB)\n"
24612462
" }\n"
24622463
" for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
24632464
"\nResult:\n"
@@ -2484,6 +2485,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
24842485
int changePosition = -1;
24852486
bool includeWatching = false;
24862487
bool lockUnspents = false;
2488+
CFeeRate feeRate = CFeeRate(0);
24872489

24882490
if (params.size() > 1) {
24892491
if (params[1].type() == UniValue::VBOOL) {
@@ -2495,7 +2497,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
24952497

24962498
UniValue options = params[1];
24972499

2498-
RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL), true, true);
2500+
RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL)("feeRate", UniValue::VNUM), true, true);
24992501

25002502
if (options.exists("changeAddress")) {
25012503
CBitcoinAddress address(options["changeAddress"].get_str());
@@ -2514,6 +2516,9 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
25142516

25152517
if (options.exists("lockUnspents"))
25162518
lockUnspents = options["lockUnspents"].get_bool();
2519+
2520+
if (options.exists("feeRate"))
2521+
feeRate = CFeeRate(options["feeRate"].get_real());
25172522
}
25182523
}
25192524

@@ -2529,16 +2534,16 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
25292534
throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
25302535

25312536
CMutableTransaction tx(origTx);
2532-
CAmount nFee;
2537+
CAmount nFeeOut;
25332538
string strFailReason;
25342539

2535-
if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress))
2540+
if(!pwalletMain->FundTransaction(tx, nFeeOut, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress))
25362541
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
25372542

25382543
UniValue result(UniValue::VOBJ);
25392544
result.push_back(Pair("hex", EncodeHexTx(tx)));
25402545
result.push_back(Pair("changepos", changePosition));
2541-
result.push_back(Pair("fee", ValueFromAmount(nFee)));
2546+
result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
25422547

25432548
return result;
25442549
}

src/wallet/wallet.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1918,7 +1918,7 @@ bool CWallet::SelectCoins(const vector<COutput>& vAvailableCoins, const CAmount&
19181918
return res;
19191919
}
19201920

1921-
bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange)
1921+
bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange)
19221922
{
19231923
vector<CRecipient> vecSend;
19241924

@@ -1933,6 +1933,8 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
19331933
coinControl.destChange = destChange;
19341934
coinControl.fAllowOtherInputs = true;
19351935
coinControl.fAllowWatchOnly = includeWatching;
1936+
coinControl.nFeeRate = specificFeeRate;
1937+
19361938
BOOST_FOREACH(const CTxIn& txin, tx.vin)
19371939
coinControl.Select(txin.prevout);
19381940

@@ -2242,6 +2244,8 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
22422244
if (coinControl && nFeeNeeded > 0 && coinControl->nMinimumTotalFee > nFeeNeeded) {
22432245
nFeeNeeded = coinControl->nMinimumTotalFee;
22442246
}
2247+
if (coinControl && coinControl->nFeeRate > CFeeRate(0))
2248+
nFeeNeeded = coinControl->nFeeRate.GetFee(nBytes);
22452249

22462250
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
22472251
// because we must be at the maximum allowed fee.

src/wallet/wallet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
740740
* Insert additional inputs into the transaction by
741741
* calling CreateTransaction();
742742
*/
743-
bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination());
743+
bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination());
744744

745745
/**
746746
* Create a new transaction paying the recipients with a set of coins

0 commit comments

Comments
 (0)