Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Already on GitHub? Sign in to your account
Add multiple options to fundrawtransaction #7518
Conversation
promag
and 1 other
commented on an outdated diff
Feb 11, 2016
| @@ -2468,7 +2468,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) | ||
| + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") | ||
| ); | ||
| - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); | ||
| + // RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); |
promag
Contributor
|
promag
and 1 other
commented on an outdated diff
Feb 11, 2016
| @@ -735,7 +735,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface | ||
| * Insert additional inputs into the transaction by | ||
| * calling CreateTransaction(); | ||
| */ | ||
| - bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching); | ||
| + bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching, const CTxDestination& destChange); |
luke-jr
Member
|
|
You need to update the help. I suggest replacing the Boolean with the Object entirely, and just supporting the boolean in code as a backward compatibility thing. |
|
@luke-jr done. |
luke-jr
and 1 other
commented on an outdated diff
Feb 11, 2016
| @@ -2468,7 +2472,7 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) | ||
| + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") | ||
| ); | ||
| - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); | ||
| + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); |
luke-jr
Member
|
luke-jr
commented on an outdated diff
Feb 11, 2016
|
@luke-jr ok, added a test for the changeAddress option. |
luke-jr
commented on an outdated diff
Feb 13, 2016
|
@luke-jr done. |
laanwj
added
the
Wallet
label
Feb 13, 2016
promag
changed the title from
[RPC] Add changeAddress option to fundrawtransaction
to
[RPC] Add change options to fundrawtransaction
Feb 13, 2016
|
Added changePosition option to specify the desired vout index of change address. |
MarcoFalke
commented on the diff
Feb 13, 2016
| @@ -575,7 +601,7 @@ def run_test(self): | ||
| outputs = {self.nodes[2].getnewaddress() : watchonly_amount / 2} | ||
| rawtx = self.nodes[3].createrawtransaction(inputs, outputs) | ||
| - result = self.nodes[3].fundrawtransaction(rawtx, True) | ||
| + result = self.nodes[3].fundrawtransaction(rawtx, {'includeWatching': True }) |
MarcoFalke
Member
|
promag
commented on the diff
Feb 13, 2016
| @@ -591,6 +617,7 @@ def run_test(self): | ||
| outputs = {self.nodes[2].getnewaddress() : watchonly_amount} | ||
| rawtx = self.nodes[3].createrawtransaction(inputs, outputs) | ||
| + # Backward compatibility test (2nd param is includeWatching) | ||
| result = self.nodes[3].fundrawtransaction(rawtx, True) |
|
|
promag
commented on the diff
Feb 13, 2016
| @@ -735,7 +735,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface | ||
| * Insert additional inputs into the transaction by | ||
| * calling CreateTransaction(); | ||
| */ | ||
| - bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching); |
promag
Contributor
|
jonasschnelli
commented on an outdated diff
Feb 19, 2016
| @@ -2468,7 +2473,31 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) | ||
| + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") | ||
| ); | ||
| - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); | ||
| + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); | ||
| + | ||
| + CTxDestination changeAddress = CNoDestination(); | ||
| + int changePosition = -1; | ||
| + bool includeWatching = false; | ||
| + | ||
| + if (params.size() > 1) { | ||
| + if (params[1].type() == UniValue::VBOOL) { |
jonasschnelli
Member
|
jonasschnelli
commented on an outdated diff
Feb 19, 2016
jonasschnelli
commented on an outdated diff
Feb 19, 2016
| nFeeRet += nChange; | ||
| reservekey.ReturnKey(); | ||
| } | ||
| else | ||
| { | ||
| - // Insert change txn at random position: | ||
| - nChangePosRet = GetRandInt(txNew.vout.size()+1); | ||
| - vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet; | ||
| + if (nChangePos == -1) { | ||
| + // Insert change txn at random position: |
|
|
jonasschnelli
and 1 other
commented on an outdated diff
Feb 19, 2016
| + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); | ||
| + | ||
| + CTxDestination changeAddress = CNoDestination(); | ||
| + int changePosition = -1; | ||
| + bool includeWatching = false; | ||
| + | ||
| + if (params.size() > 1) { | ||
| + if (params[1].type() == UniValue::VBOOL) { | ||
| + includeWatching = params[1].get_bool(); | ||
| + } | ||
| + else { | ||
| + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); | ||
| + | ||
| + UniValue options = params[1]; | ||
| + | ||
| + if (options.exists("changeAddress")) |
jonasschnelli
Member
|
jonasschnelli
commented on the diff
Feb 19, 2016
| - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); | ||
| + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); | ||
| + | ||
| + CTxDestination changeAddress = CNoDestination(); | ||
| + int changePosition = -1; | ||
| + bool includeWatching = false; | ||
| + | ||
| + if (params.size() > 1) { | ||
| + if (params[1].type() == UniValue::VBOOL) { | ||
| + includeWatching = params[1].get_bool(); | ||
| + } | ||
| + else { | ||
| + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VOBJ)); | ||
| + | ||
| + UniValue options = params[1]; | ||
| + |
jonasschnelli
Member
|
|
utACK. I'm not sure if we should add the backward compatibility fallback (includeWatchonly = true). Because it could also lead to problems in future. If so, we should also mention in in the RPC help (something like IMO a API break would be acceptable. |
jonasschnelli
added
the
RPC/REST/ZMQ
label
Feb 19, 2016
promag
changed the title from
[RPC] Add change options to fundrawtransaction
to
Add change options to fundrawtransaction
Feb 25, 2016
added a commit
to bitcoinknots/bitcoin
that referenced
this pull request
Feb 25, 2016
nunofgs
commented
Mar 2, 2016
|
@promag: it would be useful to add an option "lockUnspents: true" to ensure that chosen unspents are effectively locked before sending the transaction. |
promag
changed the title from
Add change options to fundrawtransaction
to
Add multiple options to fundrawtransaction
Mar 5, 2016
|
@nunofgs lockUnspents option added. Missing test for the moment. |
|
Visited all comments and rebased. Please review. |
|
What about adding unlockUnspents option to |
ruimarinho
commented
Mar 7, 2016
|
@promag I think that should be part of the standard process - as soon as the transaction is sent to the network, the unspents should be unlocked and considered spent. |
|
@ruimarinho: you probably mean "locking". I think locking of the unspents should happen somewhere between sign and send. I'm fine with an option in fundrawtransaction, but IMO we should not make it the default. |
|
@jonasschnelli sure, default for locking is false. The use case is to prevent consecutive |
ruimarinho
commented
Mar 7, 2016
|
@jonasschnelli if I call |
|
@ruimarinho: Yes. There is no such thing as a auto-release because the intention is the keep these unspents locked. But if you lock the unspents in |
|
@jonasschnelli the same applies if someone locks some unspents with |
|
@promag: yes. Agree. The default value is debatable. |
|
Rebased. |
MarcoFalke
and 1 other
commented on an outdated diff
Mar 25, 2016
|
I really think this is useful! |
|
@MarcoFalke fixed |
jonasschnelli
commented on an outdated diff
Mar 29, 2016
| @@ -1908,7 +1908,7 @@ bool CWallet::SelectCoins(const vector<COutput>& vAvailableCoins, const CAmount& | ||
| return res; | ||
| } | ||
| -bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching) | ||
| +bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool includeWatching, const CTxDestination& destChange) |
|
|
|
I think this PR should be in 0.13 (once finalized)! Some issues: 1)
2)
Happy to test again. |
|
@jonasschnelli Thanks, I'll add tests to cover those cases. BTW, travis is not picking this PR? |
|
Please review. @jonasschnelli FYI
|
ruimarinho
commented
Mar 30, 2016
|
@jonasschnelli, since you're more involved in this PR, what do you think of @promag's suggestion above?
|
|
@ruimarinho maybe a separate PR on top of this because that is a change on |
|
@ruimarinho: Yes. A common problems of Bitcoin Core pulls is the "expanding scope". Keep it simple, add other features later in a different PR. I think we need to distinct FRT and keep it – relatively simple. If we add options to set the fee, the only thing thats left is the coin selection then? not? Maybe someone could just grab the unspents over And if you know the changeoutputs address, you could rewrite the transaction after FRT (on your side of the application) and change its fee. @promag: thanks. Will re-test soon. |
@jonasschnelli this is not entirely correct because there may be a better subset of unspents to better satisfy the output value + fixed fee. But since the fee is very low this may be a good tradeoff. Edit: Also there this special case when no change is created, so the application has to create one to adjust the difference. 2nd edit:: And the worst case is when the total input value of the selected unspents isn't enough to cover the fixed fee. So I would say that having the option to specify the fixed fee is the way to go. |
@jonasschnelli actually this is accomplished with |
Yes. This is a point.
createrawtransaction does not use coinselection IMO. FRT does. |
jonasschnelli
commented on an outdated diff
Mar 30, 2016
| tx.vin.push_back(txin); | ||
| + | ||
| + if (lockUnspents) | ||
| + LockCoin(txin.prevout); |
jonasschnelli
Member
|
|
The type check works and I think it's great. |
|
@jonasschnelli Thanks! Fixed and rebased. |
ruimarinho
commented
Mar 31, 2016
|
I was not suggesting otherwise regarding merging this PR and only then creating a new one to add the fixed fee feature :) like @promag mentioned on the edited comments, I believe there is still space for such feature as at least two scenarios are not covered by standard calls. |
ruimarinho
commented on the diff
Mar 31, 2016
| @@ -2451,8 +2451,14 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) | ||
| "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" | ||
| "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" | ||
| "\nArguments:\n" | ||
| - "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" | ||
| - "2. includeWatching (boolean, optional, default false) Also select inputs which are watch only\n" | ||
| + "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" | ||
| + "2. options (object, optional)\n" | ||
| + " {\n" | ||
| + " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\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" |
ruimarinho
|
jonasschnelli
commented on the diff
Mar 31, 2016
| @@ -2451,8 +2451,14 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp) | ||
| "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n" | ||
| "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n" | ||
| "\nArguments:\n" | ||
| - "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" | ||
| - "2. includeWatching (boolean, optional, default false) Also select inputs which are watch only\n" | ||
| + "1. \"hexstring\" (string, required) The hex string of the raw transaction\n" | ||
| + "2. options (object, optional)\n" |
jonasschnelli
Member
|
jonasschnelli
commented on the diff
Mar 31, 2016
| return false; | ||
| - if (nChangePosRet != -1) | ||
| - tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]); | ||
| + if (nChangePosInOut != -1) | ||
| + tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.vout[nChangePosInOut]); |
jonasschnelli
Member
|
|
Allmost done. Last iteration:
|
|
@jonasschnelli updated and rebased. not sure where is the best place to put the new help message. |
|
ping @promag: Would be nice if you could take the change output order check into Please also fix the commit order. The head commit is from March 5, but the HEAD~2 is March 30.
|
promag
commented on the diff
Apr 6, 2016
| nFeeRet += nChange; | ||
| reservekey.ReturnKey(); | ||
| } | ||
| else | ||
| { | ||
| - // Insert change txn at random position: | ||
| - nChangePosRet = GetRandInt(txNew.vout.size()+1); | ||
| - vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet; | ||
| + if (nChangePosInOut == -1) | ||
| + { | ||
| + // Insert change txn at random position: | ||
| + nChangePosInOut = GetRandInt(txNew.vout.size()+1); | ||
| + } | ||
| + else if (nChangePosInOut > txNew.vout.size()) |
promag
Contributor
|
This was referenced Apr 7, 2016
promag
added some commits
Mar 29, 2016
|
Tested ACK 18be394. This is very useful. |
|
utACK 18be394 |
promag commentedFeb 11, 2016
This PR allows to specify an address to receive the change of the fund. Currently
fundrawtransactionaccepts a boolean for the second parameter. With this change the second parameter can be either a boolean or a JSON object with the following optional keys:includeWatching,changeAddressandchangePosition.