@ -2739,6 +2739,10 @@ UniValue bumpfee(const JSONRPCRequest& request)
throw JSONRPCError ( RPC_MISC_ERROR , " Transaction does not have a change output " ) ;
throw JSONRPCError ( RPC_MISC_ERROR , " Transaction does not have a change output " ) ;
}
}
// signature sizes can vary by a byte, so add 1 for each input when calculating the new fee
int64_t txSize = GetVirtualTransactionSize ( * ( wtx . tx ) ) ;
const int64_t maxNewTxSize = txSize + wtx . tx - > vin . size ( ) ;
// optional parameters
// optional parameters
bool specifiedConfirmTarget = false ;
bool specifiedConfirmTarget = false ;
int newConfirmTarget = nTxConfirmTarget ;
int newConfirmTarget = nTxConfirmTarget ;
@ -2764,10 +2768,11 @@ UniValue bumpfee(const JSONRPCRequest& request)
}
}
} else if ( options . exists ( " totalFee " ) ) {
} else if ( options . exists ( " totalFee " ) ) {
totalFee = options [ " totalFee " ] . get_int64 ( ) ;
totalFee = options [ " totalFee " ] . get_int64 ( ) ;
if ( totalFee < = 0 ) {
CAmount requiredFee = CWallet : : GetRequiredFee ( maxNewTxSize ) ;
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid totalFee (cannot be <= 0) " ) ;
if ( totalFee < requiredFee ) {
} else if ( totalFee > maxTxFee ) {
throw JSONRPCError ( RPC_INVALID_PARAMETER ,
throw JSONRPCError ( RPC_INVALID_PARAMETER , " Invalid totalFee (cannot be higher than maxTxFee) " ) ;
strprintf ( " Insufficient totalFee (cannot be less than required fee %s) " ,
FormatMoney ( requiredFee ) ) ) ;
}
}
}
}
@ -2776,10 +2781,6 @@ UniValue bumpfee(const JSONRPCRequest& request)
}
}
}
}
// signature sizes can vary by a byte, so add 1 for each input when calculating the new fee
int64_t txSize = GetVirtualTransactionSize ( * ( wtx . tx ) ) ;
const int64_t maxNewTxSize = txSize + wtx . tx - > vin . size ( ) ;
// calculate the old fee and fee-rate
// calculate the old fee and fee-rate
CAmount nOldFee = wtx . GetDebit ( ISMINE_SPENDABLE ) - wtx . tx - > GetValueOut ( ) ;
CAmount nOldFee = wtx . GetDebit ( ISMINE_SPENDABLE ) - wtx . tx - > GetValueOut ( ) ;
CFeeRate nOldFeeRate ( nOldFee , txSize ) ;
CFeeRate nOldFeeRate ( nOldFee , txSize ) ;
@ -2794,22 +2795,29 @@ UniValue bumpfee(const JSONRPCRequest& request)
nNewFee = totalFee ;
nNewFee = totalFee ;
nNewFeeRate = CFeeRate ( totalFee , maxNewTxSize ) ;
nNewFeeRate = CFeeRate ( totalFee , maxNewTxSize ) ;
} else {
} else {
// use the user-defined payTxFee if possible, otherwise use smartfee / fallbackfee
// if user specified a confirm target then don't consider any global payTxFee
if ( ! specifiedConfirmTarget & & payTxFee . GetFeePerK ( ) ! = 0 ) {
if ( specifiedConfirmTarget ) {
nNewFeeRate = payTxFee ;
nNewFee = CWallet : : GetMinimumFee ( maxNewTxSize , newConfirmTarget , mempool , CAmount ( 0 ) ) ;
} else {
nNewFeeRate = mempool . estimateSmartFee ( newConfirmTarget ) ;
}
}
if ( nNewFeeRate . GetFeePerK ( ) = = 0 ) {
// otherwise use the regular wallet logic to select payTxFee or default confirm target
nNewFeeRate = CWallet : : fallbackFee ;
else {
nNewFee = CWallet : : GetMinimumFee ( maxNewTxSize , newConfirmTarget , mempool ) ;
}
}
nNewFeeRate = CFeeRate ( nNewFee , maxNewTxSize ) ;
// new fee rate must be at least old rate + minimum incremental relay rate
// new fee rate must be at least old rate + minimum incremental relay rate
if ( nNewFeeRate . GetFeePerK ( ) < nOldFeeRate . GetFeePerK ( ) + : : incrementalRelayFee . GetFeePerK ( ) ) {
if ( nNewFeeRate . GetFeePerK ( ) < nOldFeeRate . GetFeePerK ( ) + : : incrementalRelayFee . GetFeePerK ( ) ) {
nNewFeeRate = CFeeRate ( nOldFeeRate . GetFeePerK ( ) + : : incrementalRelayFee . GetFeePerK ( ) ) ;
nNewFeeRate = CFeeRate ( nOldFeeRate . GetFeePerK ( ) + : : incrementalRelayFee . GetFeePerK ( ) ) ;
nNewFee = nNewFeeRate . GetFee ( maxNewTxSize ) ;
}
}
}
nNewFee = nNewFeeRate . GetFee ( maxNewTxSize ) ;
// Check that in all cases the new fee doesn't violate maxTxFee
if ( nNewFee > maxTxFee ) {
throw JSONRPCError ( RPC_MISC_ERROR ,
strprintf ( " Specified or calculated fee %s is too high (cannot be higher than maxTxFee %s) " ,
FormatMoney ( nNewFee ) , FormatMoney ( maxTxFee ) ) ) ;
}
}
// check that fee rate is higher than mempool's minimum fee
// check that fee rate is higher than mempool's minimum fee