aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Morcos <morcos@chaincode.com>2017-01-25 22:16:15 -0500
committerAlex Morcos <morcos@chaincode.com>2017-01-26 09:43:00 -0500
commite8021ec9193c7e8137f9716bcafd197a357a624e (patch)
tree31cbe60ee63f4f88613dd9424cadef34ca68d32a
parentae9719ab87a05ca4c3293b2f8675f17b16ed5872 (diff)
downloadbitcoin-e8021ec9193c7e8137f9716bcafd197a357a624e.tar.xz
Use CWallet::GetMinimumFee in bumpfee
Use the wallet's fee calculation logic to properly clamp fee against minimums and maximums when calculating the fee for a bumpfee transaction. Unless totalFee is explictly given, in which case, manually check against min, but do nothing to adjust given fee. In all cases do a final check against maxTxFee (after adding any incremental amount).
-rw-r--r--src/wallet/rpcwallet.cpp42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index b62fbeb10e..9ae36653b8 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2739,6 +2739,10 @@ UniValue bumpfee(const JSONRPCRequest& request)
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
bool specifiedConfirmTarget = false;
int newConfirmTarget = nTxConfirmTarget;
@@ -2764,10 +2768,11 @@ UniValue bumpfee(const JSONRPCRequest& request)
}
} else if (options.exists("totalFee")) {
totalFee = options["totalFee"].get_int64();
- if (totalFee <= 0) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid totalFee (cannot be <= 0)");
- } else if (totalFee > maxTxFee) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid totalFee (cannot be higher than maxTxFee)");
+ CAmount requiredFee = CWallet::GetRequiredFee(maxNewTxSize);
+ if (totalFee < requiredFee ) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER,
+ 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
CAmount nOldFee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut();
CFeeRate nOldFeeRate(nOldFee, txSize);
@@ -2794,24 +2795,31 @@ UniValue bumpfee(const JSONRPCRequest& request)
nNewFee = totalFee;
nNewFeeRate = CFeeRate(totalFee, maxNewTxSize);
} else {
- // use the user-defined payTxFee if possible, otherwise use smartfee / fallbackfee
- if (!specifiedConfirmTarget && payTxFee.GetFeePerK() != 0) {
- nNewFeeRate = payTxFee;
- } else {
- nNewFeeRate = mempool.estimateSmartFee(newConfirmTarget);
+ // if user specified a confirm target then don't consider any global payTxFee
+ if (specifiedConfirmTarget) {
+ nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool, CAmount(0));
}
- if (nNewFeeRate.GetFeePerK() == 0) {
- nNewFeeRate = CWallet::fallbackFee;
+ // otherwise use the regular wallet logic to select payTxFee or default confirm target
+ else {
+ nNewFee = CWallet::GetMinimumFee(maxNewTxSize, newConfirmTarget, mempool);
}
+ nNewFeeRate = CFeeRate(nNewFee, maxNewTxSize);
+
// new fee rate must be at least old rate + minimum incremental relay rate
if (nNewFeeRate.GetFeePerK() < 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
// (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
// This may occur if the user set TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps,