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