@@ -289,9 +289,9 @@ UniValue verifytxoutproof(const JSONRPCRequest& request)
289
289
290
290
UniValue createrawtransaction (const JSONRPCRequest& request)
291
291
{
292
- if (request.fHelp || request.params .size () < 2 || request.params .size () > 3 )
292
+ if (request.fHelp || request.params .size () < 2 || request.params .size () > 4 )
293
293
throw std::runtime_error (
294
- " createrawtransaction [{\" txid\" :\" id\" ,\" vout\" :n},...] {\" address\" :amount,\" data\" :\" hex\" ,...} ( locktime )\n "
294
+ " createrawtransaction [{\" txid\" :\" id\" ,\" vout\" :n},...] {\" address\" :amount,\" data\" :\" hex\" ,...} ( locktime ) ( optintorbf ) \n "
295
295
" \n Create a transaction spending the given inputs and creating new outputs.\n "
296
296
" Outputs can be addresses or data.\n "
297
297
" Returns hex-encoded raw transaction.\n "
@@ -315,6 +315,7 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
315
315
" ,...\n "
316
316
" }\n "
317
317
" 3. locktime (numeric, optional, default=0) Raw locktime. Non-0 value also locktime-activates inputs\n "
318
+ " 4. optintorbf (boolean, optional, default=false) Allow this transaction to be replaced by a transaction with higher fees\n "
318
319
" \n Result:\n "
319
320
" \" transaction\" (string) hex string of the transaction\n "
320
321
@@ -341,6 +342,8 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
341
342
rawTx.nLockTime = nLockTime;
342
343
}
343
344
345
+ bool rbfOptIn = request.params .size () > 3 ? request.params [3 ].isTrue () : false ;
346
+
344
347
for (unsigned int idx = 0 ; idx < inputs.size (); idx++) {
345
348
const UniValue& input = inputs[idx];
346
349
const UniValue& o = input.get_obj ();
@@ -354,16 +357,26 @@ UniValue createrawtransaction(const JSONRPCRequest& request)
354
357
if (nOutput < 0 )
355
358
throw JSONRPCError (RPC_INVALID_PARAMETER, " Invalid parameter, vout must be positive" );
356
359
357
- uint32_t nSequence = (rawTx.nLockTime ? std::numeric_limits<uint32_t >::max () - 1 : std::numeric_limits<uint32_t >::max ());
360
+ uint32_t nSequence;
361
+ if (rbfOptIn) {
362
+ nSequence = std::numeric_limits<uint32_t >::max () - 2 ;
363
+ } else if (rawTx.nLockTime ) {
364
+ nSequence = std::numeric_limits<uint32_t >::max () - 1 ;
365
+ } else {
366
+ nSequence = std::numeric_limits<uint32_t >::max ();
367
+ }
358
368
359
369
// set the sequence number if passed in the parameters object
360
370
const UniValue& sequenceObj = find_value (o, " sequence" );
361
371
if (sequenceObj.isNum ()) {
362
372
int64_t seqNr64 = sequenceObj.get_int64 ();
363
- if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t >::max ())
373
+ if (seqNr64 < 0 || seqNr64 > std::numeric_limits<uint32_t >::max ()) {
364
374
throw JSONRPCError (RPC_INVALID_PARAMETER, " Invalid parameter, sequence number is out of range" );
365
- else
375
+ } else if (seqNr64 <= std::numeric_limits<uint32_t >::max () - 2 && request.params .size () > 3 && request.params [3 ].isFalse ()) {
376
+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Invalid parameter combination: Sequence number contradicts optintorbf option" );
377
+ } else {
366
378
nSequence = (uint32_t )seqNr64;
379
+ }
367
380
}
368
381
369
382
CTxIn in (COutPoint (txid, nOutput), CScript (), nSequence);
0 commit comments