mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
Merge #9377: fundrawtransaction: Keep change-output keys by default, make it optional
c9f3062
Add fundrawtransactions new reserveChangeKey option to the release notes (Jonas Schnelli)9eb325d
[QA] Add test for fundrawtransactions new reserveChangeKey option (Jonas Schnelli)9aa4e6a
[Wallet] Add an option to keep the change address key, true by default (Jonas Schnelli)
This commit is contained in:
parent
f8b880f4d8
commit
36109e0580
@ -650,7 +650,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||||||
assert_equal(len(self.nodes[3].listunspent(1)), 1)
|
assert_equal(len(self.nodes[3].listunspent(1)), 1)
|
||||||
|
|
||||||
inputs = []
|
inputs = []
|
||||||
outputs = {self.nodes[2].getnewaddress() : 1}
|
outputs = {self.nodes[3].getnewaddress() : 1}
|
||||||
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
|
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
|
||||||
result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee)
|
result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee)
|
||||||
result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee})
|
result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee})
|
||||||
@ -659,6 +659,32 @@ class RawTransactionsTest(BitcoinTestFramework):
|
|||||||
assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate)
|
assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate)
|
||||||
assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate)
|
assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate)
|
||||||
|
|
||||||
|
#############################
|
||||||
|
# Test address reuse option #
|
||||||
|
#############################
|
||||||
|
|
||||||
|
result3 = self.nodes[3].fundrawtransaction(rawtx, {"reserveChangeKey": False})
|
||||||
|
res_dec = self.nodes[0].decoderawtransaction(result3["hex"])
|
||||||
|
changeaddress = ""
|
||||||
|
for out in res_dec['vout']:
|
||||||
|
if out['value'] > 1.0:
|
||||||
|
changeaddress += out['scriptPubKey']['addresses'][0]
|
||||||
|
assert(changeaddress != "")
|
||||||
|
nextaddr = self.nodes[3].getnewaddress()
|
||||||
|
# frt should not have removed the key from the keypool
|
||||||
|
assert(changeaddress == nextaddr)
|
||||||
|
|
||||||
|
result3 = self.nodes[3].fundrawtransaction(rawtx)
|
||||||
|
res_dec = self.nodes[0].decoderawtransaction(result3["hex"])
|
||||||
|
changeaddress = ""
|
||||||
|
for out in res_dec['vout']:
|
||||||
|
if out['value'] > 1.0:
|
||||||
|
changeaddress += out['scriptPubKey']['addresses'][0]
|
||||||
|
assert(changeaddress != "")
|
||||||
|
nextaddr = self.nodes[3].getnewaddress()
|
||||||
|
# Now the change address key should be removed from the keypool
|
||||||
|
assert(changeaddress != nextaddr)
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
# Test subtractFeeFromOutputs option #
|
# Test subtractFeeFromOutputs option #
|
||||||
######################################
|
######################################
|
||||||
|
@ -2608,6 +2608,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
|||||||
" \"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"
|
||||||
|
" \"reserveChangeKey\" (boolean, optional, default true) Reserves the change output key from the keypool\n"
|
||||||
" \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n"
|
" \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific feerate (" + CURRENCY_UNIT + " per KB)\n"
|
||||||
" \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
|
" \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
|
||||||
" The fee will be equally deducted from the amount of each specified output.\n"
|
" The fee will be equally deducted from the amount of each specified output.\n"
|
||||||
@ -2640,6 +2641,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
|||||||
int changePosition = -1;
|
int changePosition = -1;
|
||||||
bool includeWatching = false;
|
bool includeWatching = false;
|
||||||
bool lockUnspents = false;
|
bool lockUnspents = false;
|
||||||
|
bool reserveChangeKey = true;
|
||||||
CFeeRate feeRate = CFeeRate(0);
|
CFeeRate feeRate = CFeeRate(0);
|
||||||
bool overrideEstimatedFeerate = false;
|
bool overrideEstimatedFeerate = false;
|
||||||
UniValue subtractFeeFromOutputs;
|
UniValue subtractFeeFromOutputs;
|
||||||
@ -2661,6 +2663,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
|||||||
{"changePosition", UniValueType(UniValue::VNUM)},
|
{"changePosition", UniValueType(UniValue::VNUM)},
|
||||||
{"includeWatching", UniValueType(UniValue::VBOOL)},
|
{"includeWatching", UniValueType(UniValue::VBOOL)},
|
||||||
{"lockUnspents", UniValueType(UniValue::VBOOL)},
|
{"lockUnspents", UniValueType(UniValue::VBOOL)},
|
||||||
|
{"reserveChangeKey", UniValueType(UniValue::VBOOL)},
|
||||||
{"feeRate", UniValueType()}, // will be checked below
|
{"feeRate", UniValueType()}, // will be checked below
|
||||||
{"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
|
{"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
|
||||||
},
|
},
|
||||||
@ -2684,6 +2687,9 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
|||||||
if (options.exists("lockUnspents"))
|
if (options.exists("lockUnspents"))
|
||||||
lockUnspents = options["lockUnspents"].get_bool();
|
lockUnspents = options["lockUnspents"].get_bool();
|
||||||
|
|
||||||
|
if (options.exists("reserveChangeKey"))
|
||||||
|
reserveChangeKey = options["reserveChangeKey"].get_bool();
|
||||||
|
|
||||||
if (options.exists("feeRate"))
|
if (options.exists("feeRate"))
|
||||||
{
|
{
|
||||||
feeRate = CFeeRate(AmountFromValue(options["feeRate"]));
|
feeRate = CFeeRate(AmountFromValue(options["feeRate"]));
|
||||||
@ -2720,7 +2726,7 @@ UniValue fundrawtransaction(const JSONRPCRequest& request)
|
|||||||
CAmount nFeeOut;
|
CAmount nFeeOut;
|
||||||
string strFailReason;
|
string strFailReason;
|
||||||
|
|
||||||
if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, changeAddress))
|
if(!pwalletMain->FundTransaction(tx, nFeeOut, overrideEstimatedFeerate, feeRate, changePosition, strFailReason, includeWatching, lockUnspents, setSubtractFeeFromOutputs, reserveChangeKey, changeAddress))
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
|
throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason);
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
|
@ -2878,7 +2878,7 @@ struct CompareByPriority
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, 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 std::set<int>& setSubtractFeeFromOutputs, bool keepReserveKey, const CTxDestination& destChange)
|
||||||
{
|
{
|
||||||
vector<CRecipient> vecSend;
|
vector<CRecipient> vecSend;
|
||||||
|
|
||||||
@ -2927,6 +2927,10 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool ov
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optionally keep the change output key
|
||||||
|
if (keepReserveKey)
|
||||||
|
reservekey.KeepKey();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -902,7 +902,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, bool overrideEstimatedFeeRate, const CFeeRate& specificFeeRate, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, 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 std::set<int>& setSubtractFeeFromOutputs, bool keepReserveKey = true, 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