@@ -489,13 +489,13 @@ static std::vector<RPCArg> FundTxDoc(bool solving_data = true)
489
489
return args;
490
490
}
491
491
492
- void FundTransaction (CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out, int & change_position , const UniValue& options, CCoinControl& coinControl, bool override_min_fee)
492
+ CreatedTransactionResult FundTransaction (CWallet& wallet, const CMutableTransaction& tx, const UniValue& options, CCoinControl& coinControl, bool override_min_fee)
493
493
{
494
494
// Make sure the results are valid at least up to the most recent block
495
495
// the user could have gotten from another RPC command prior to now
496
496
wallet.BlockUntilSyncedToCurrentChain ();
497
497
498
- change_position = - 1 ;
498
+ std::optional< unsigned int > change_position ;
499
499
bool lockUnspents = false ;
500
500
UniValue subtractFeeFromOutputs;
501
501
std::set<int > setSubtractFeeFromOutputs;
@@ -553,7 +553,11 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out,
553
553
}
554
554
555
555
if (options.exists (" changePosition" ) || options.exists (" change_position" )) {
556
- change_position = (options.exists (" change_position" ) ? options[" change_position" ] : options[" changePosition" ]).getInt <int >();
556
+ int pos = (options.exists (" change_position" ) ? options[" change_position" ] : options[" changePosition" ]).getInt <int >();
557
+ if (pos < 0 || (unsigned int )pos > tx.vout .size ()) {
558
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " changePosition out of bounds" );
559
+ }
560
+ change_position = (unsigned int )pos;
557
561
}
558
562
559
563
if (options.exists (" change_type" )) {
@@ -703,9 +707,6 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out,
703
707
if (tx.vout .size () == 0 )
704
708
throw JSONRPCError (RPC_INVALID_PARAMETER, " TX must have at least one output" );
705
709
706
- if (change_position != -1 && (change_position < 0 || (unsigned int )change_position > tx.vout .size ()))
707
- throw JSONRPCError (RPC_INVALID_PARAMETER, " changePosition out of bounds" );
708
-
709
710
for (unsigned int idx = 0 ; idx < subtractFeeFromOutputs.size (); idx++) {
710
711
int pos = subtractFeeFromOutputs[idx].getInt <int >();
711
712
if (setSubtractFeeFromOutputs.count (pos))
@@ -717,11 +718,11 @@ void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out,
717
718
setSubtractFeeFromOutputs.insert (pos);
718
719
}
719
720
720
- bilingual_str error;
721
-
722
- if (!FundTransaction (wallet, tx, fee_out, change_position, error, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
723
- throw JSONRPCError (RPC_WALLET_ERROR, error.original );
721
+ auto txr = FundTransaction (wallet, tx, change_position, lockUnspents, setSubtractFeeFromOutputs, coinControl);
722
+ if (!txr) {
723
+ throw JSONRPCError (RPC_WALLET_ERROR, ErrorString (txr).original );
724
724
}
725
+ return *txr;
725
726
}
726
727
727
728
static void SetOptionsInputWeights (const UniValue& inputs, UniValue& options)
@@ -844,17 +845,15 @@ RPCHelpMan fundrawtransaction()
844
845
throw JSONRPCError (RPC_DESERIALIZATION_ERROR, " TX decode failed" );
845
846
}
846
847
847
- CAmount fee;
848
- int change_position;
849
848
CCoinControl coin_control;
850
849
// Automatically select (additional) coins. Can be overridden by options.add_inputs.
851
850
coin_control.m_allow_other_inputs = true ;
852
- FundTransaction (*pwallet, tx, fee, change_position , request.params [1 ], coin_control, /* override_min_fee=*/ true );
851
+ auto txr = FundTransaction (*pwallet, tx, request.params [1 ], coin_control, /* override_min_fee=*/ true );
853
852
854
853
UniValue result (UniValue::VOBJ);
855
- result.pushKV (" hex" , EncodeHexTx (CTransaction (tx) ));
856
- result.pushKV (" fee" , ValueFromAmount (fee));
857
- result.pushKV (" changepos" , change_position );
854
+ result.pushKV (" hex" , EncodeHexTx (*txr. tx ));
855
+ result.pushKV (" fee" , ValueFromAmount (txr. fee ));
856
+ result.pushKV (" changepos" , txr. change_pos ? ( int )*txr. change_pos : - 1 );
858
857
859
858
return result;
860
859
},
@@ -1272,18 +1271,16 @@ RPCHelpMan send()
1272
1271
PreventOutdatedOptions (options);
1273
1272
1274
1273
1275
- CAmount fee;
1276
- int change_position;
1277
1274
bool rbf{options.exists (" replaceable" ) ? options[" replaceable" ].get_bool () : pwallet->m_signal_rbf };
1278
1275
CMutableTransaction rawTx = ConstructTransaction (options[" inputs" ], request.params [0 ], options[" locktime" ], rbf);
1279
1276
CCoinControl coin_control;
1280
1277
// Automatically select coins, unless at least one is manually selected. Can
1281
1278
// be overridden by options.add_inputs.
1282
1279
coin_control.m_allow_other_inputs = rawTx.vin .size () == 0 ;
1283
1280
SetOptionsInputWeights (options[" inputs" ], options);
1284
- FundTransaction (*pwallet, rawTx, fee, change_position , options, coin_control, /* override_min_fee=*/ false );
1281
+ auto txr = FundTransaction (*pwallet, rawTx, options, coin_control, /* override_min_fee=*/ false );
1285
1282
1286
- return FinishTransaction (pwallet, options, rawTx );
1283
+ return FinishTransaction (pwallet, options, CMutableTransaction (*txr. tx ) );
1287
1284
}
1288
1285
};
1289
1286
}
@@ -1699,8 +1696,6 @@ RPCHelpMan walletcreatefundedpsbt()
1699
1696
1700
1697
UniValue options{request.params [3 ].isNull () ? UniValue::VOBJ : request.params [3 ]};
1701
1698
1702
- CAmount fee;
1703
- int change_position;
1704
1699
const UniValue &replaceable_arg = options[" replaceable" ];
1705
1700
const bool rbf{replaceable_arg.isNull () ? wallet.m_signal_rbf : replaceable_arg.get_bool ()};
1706
1701
CMutableTransaction rawTx = ConstructTransaction (request.params [0 ], request.params [1 ], request.params [2 ], rbf);
@@ -1709,10 +1704,10 @@ RPCHelpMan walletcreatefundedpsbt()
1709
1704
// be overridden by options.add_inputs.
1710
1705
coin_control.m_allow_other_inputs = rawTx.vin .size () == 0 ;
1711
1706
SetOptionsInputWeights (request.params [0 ], options);
1712
- FundTransaction (wallet, rawTx, fee, change_position , options, coin_control, /* override_min_fee=*/ true );
1707
+ auto txr = FundTransaction (wallet, rawTx, options, coin_control, /* override_min_fee=*/ true );
1713
1708
1714
1709
// Make a blank psbt
1715
- PartiallySignedTransaction psbtx (rawTx );
1710
+ PartiallySignedTransaction psbtx (CMutableTransaction (*txr. tx ) );
1716
1711
1717
1712
// Fill transaction with out data but don't sign
1718
1713
bool bip32derivs = request.params [4 ].isNull () ? true : request.params [4 ].get_bool ();
@@ -1728,8 +1723,8 @@ RPCHelpMan walletcreatefundedpsbt()
1728
1723
1729
1724
UniValue result (UniValue::VOBJ);
1730
1725
result.pushKV (" psbt" , EncodeBase64 (ssTx.str ()));
1731
- result.pushKV (" fee" , ValueFromAmount (fee));
1732
- result.pushKV (" changepos" , change_position );
1726
+ result.pushKV (" fee" , ValueFromAmount (txr. fee ));
1727
+ result.pushKV (" changepos" , txr. change_pos ? ( int )*txr. change_pos : - 1 );
1733
1728
return result;
1734
1729
},
1735
1730
};
0 commit comments