Merge #7967: [RPC] add feerate option to fundrawtransaction
04eaa90 Add more clear interface for CoinControl.h regarding individual feerate (Jonas Schnelli) 3b35e48 [RPC] add feerate option to fundrawtransaction (Jonas Schnelli)
This commit is contained in:
parent
af51e591b4
commit
c69df9b82c
@ -694,6 +694,14 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||||||
assert(signedtx["complete"])
|
assert(signedtx["complete"])
|
||||||
self.nodes[0].sendrawtransaction(signedtx["hex"])
|
self.nodes[0].sendrawtransaction(signedtx["hex"])
|
||||||
|
|
||||||
|
inputs = []
|
||||||
|
outputs = {self.nodes[2].getnewaddress() : 1}
|
||||||
|
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
|
||||||
|
result = self.nodes[3].fundrawtransaction(rawtx, )
|
||||||
|
result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2000})
|
||||||
|
result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10000})
|
||||||
|
assert_equal(result['fee']*2, result2['fee'])
|
||||||
|
assert_equal(result['fee']*10, result3['fee'])
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
RawTransactionsTest().main()
|
RawTransactionsTest().main()
|
||||||
|
@ -20,6 +20,10 @@ public:
|
|||||||
bool fAllowWatchOnly;
|
bool fAllowWatchOnly;
|
||||||
//! Minimum absolute fee (not per kilobyte)
|
//! Minimum absolute fee (not per kilobyte)
|
||||||
CAmount nMinimumTotalFee;
|
CAmount nMinimumTotalFee;
|
||||||
|
//! Override estimated feerate
|
||||||
|
bool fOverrideFeeRate;
|
||||||
|
//! Feerate to use if overrideFeeRate is true
|
||||||
|
CFeeRate nFeeRate;
|
||||||
|
|
||||||
CCoinControl()
|
CCoinControl()
|
||||||
{
|
{
|
||||||
@ -35,6 +39,8 @@ public:
|
|||||||
fUseInstantSend = false;
|
fUseInstantSend = false;
|
||||||
fUsePrivateSend = true;
|
fUsePrivateSend = true;
|
||||||
nMinimumTotalFee = 0;
|
nMinimumTotalFee = 0;
|
||||||
|
nFeeRate = CFeeRate(0);
|
||||||
|
fOverrideFeeRate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasSelected() const
|
bool HasSelected() const
|
||||||
|
@ -2633,6 +2633,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
|
|||||||
" \"changePosition\" (numeric, optional, default random) The index of the change output\n"
|
" \"changePosition\" (numeric, optional, default random) The index of the change output\n"
|
||||||
" \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
|
" \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
|
||||||
" \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
|
" \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
|
||||||
|
" \"feeRate\" (numeric, optional, default 0=estimate) Set a specific feerate (fee per KB)\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
|
" for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
|
||||||
"\nResult:\n"
|
"\nResult:\n"
|
||||||
@ -2659,6 +2660,8 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
|
|||||||
int changePosition = -1;
|
int changePosition = -1;
|
||||||
bool includeWatching = false;
|
bool includeWatching = false;
|
||||||
bool lockUnspents = false;
|
bool lockUnspents = false;
|
||||||
|
CFeeRate feeRate = CFeeRate(0);
|
||||||
|
bool overrideEstimatedFeerate = false;
|
||||||
|
|
||||||
if (params.size() > 1) {
|
if (params.size() > 1) {
|
||||||
if (params[1].type() == UniValue::VBOOL) {
|
if (params[1].type() == UniValue::VBOOL) {
|
||||||
@ -2670,7 +2673,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
UniValue options = params[1];
|
UniValue options = params[1];
|
||||||
|
|
||||||
RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL), true, true);
|
RPCTypeCheckObj(options, boost::assign::map_list_of("changeAddress", UniValue::VSTR)("changePosition", UniValue::VNUM)("includeWatching", UniValue::VBOOL)("lockUnspents", UniValue::VBOOL)("feeRate", UniValue::VNUM), true, true);
|
||||||
|
|
||||||
if (options.exists("changeAddress")) {
|
if (options.exists("changeAddress")) {
|
||||||
CBitcoinAddress address(options["changeAddress"].get_str());
|
CBitcoinAddress address(options["changeAddress"].get_str());
|
||||||
@ -2689,6 +2692,12 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
if (options.exists("lockUnspents"))
|
if (options.exists("lockUnspents"))
|
||||||
lockUnspents = options["lockUnspents"].get_bool();
|
lockUnspents = options["lockUnspents"].get_bool();
|
||||||
|
|
||||||
|
if (options.exists("feeRate"))
|
||||||
|
{
|
||||||
|
feeRate = CFeeRate(options["feeRate"].get_real());
|
||||||
|
overrideEstimatedFeerate = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2704,16 +2713,16 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
|
|||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
|
||||||
|
|
||||||
CMutableTransaction tx(origTx);
|
CMutableTransaction tx(origTx);
|
||||||
CAmount nFee;
|
CAmount nFeeOut;
|
||||||
string strFailReason;
|
string strFailReason;
|
||||||
|
|
||||||
if(!pwalletMain->FundTransaction(tx, nFee, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress))
|
if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, changeAddress))
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
|
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
result.push_back(Pair("hex", EncodeHexTx(tx)));
|
result.push_back(Pair("hex", EncodeHexTx(tx)));
|
||||||
result.push_back(Pair("changepos", changePosition));
|
result.push_back(Pair("changepos", changePosition));
|
||||||
result.push_back(Pair("fee", ValueFromAmount(nFee)));
|
result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2722,7 +2722,7 @@ struct CompareByPriority
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange)
|
bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange)
|
||||||
{
|
{
|
||||||
vector<CRecipient> vecSend;
|
vector<CRecipient> vecSend;
|
||||||
|
|
||||||
@ -2737,6 +2737,9 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
|
|||||||
coinControl.destChange = destChange;
|
coinControl.destChange = destChange;
|
||||||
coinControl.fAllowOtherInputs = true;
|
coinControl.fAllowOtherInputs = true;
|
||||||
coinControl.fAllowWatchOnly = includeWatching;
|
coinControl.fAllowWatchOnly = includeWatching;
|
||||||
|
coinControl.fOverrideFeeRate = overrideEstimatedFeeRate;
|
||||||
|
coinControl.nFeeRate = specificFeeRate;
|
||||||
|
|
||||||
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
BOOST_FOREACH(const CTxIn& txin, tx.vin)
|
||||||
coinControl.Select(txin.prevout);
|
coinControl.Select(txin.prevout);
|
||||||
|
|
||||||
@ -3510,6 +3513,8 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||||||
if(fUseInstantSend) {
|
if(fUseInstantSend) {
|
||||||
nFeeNeeded = std::max(nFeeNeeded, CTxLockRequest(txNew).GetMinFee());
|
nFeeNeeded = std::max(nFeeNeeded, CTxLockRequest(txNew).GetMinFee());
|
||||||
}
|
}
|
||||||
|
if (coinControl && coinControl->fOverrideFeeRate)
|
||||||
|
nFeeNeeded = coinControl->nFeeRate.GetFee(nBytes);
|
||||||
|
|
||||||
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
|
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
|
||||||
// because we must be at the maximum allowed fee.
|
// because we must be at the maximum allowed fee.
|
||||||
|
@ -881,7 +881,7 @@ public:
|
|||||||
* Insert additional inputs into the transaction by
|
* Insert additional inputs into the transaction by
|
||||||
* calling CreateTransaction();
|
* calling CreateTransaction();
|
||||||
*/
|
*/
|
||||||
bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination());
|
bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const CTxDestination& destChange = CNoDestination());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new transaction paying the recipients with a set of coins
|
* Create a new transaction paying the recipients with a set of coins
|
||||||
|
Loading…
Reference in New Issue
Block a user