diff options
author | Wladimir J. van der Laan <laanwj@protonmail.com> | 2019-09-18 16:47:23 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@protonmail.com> | 2019-09-18 16:49:18 +0200 |
commit | 0ee0474234654d1587afd5816ca6794620a11f16 (patch) | |
tree | e916bb6afda8cef3ffdd85323544bd19a8601eed /src | |
parent | dd8cf82e96042cb59354ee1677830f414a5baaaf (diff) | |
parent | 2dfd6834ef8737e16e4b96df0c459f30a0721d6c (diff) |
Merge #16521: rpc: Use the default maxfeerate value as BTC/kB
2dfd6834ef8737e16e4b96df0c459f30a0721d6c test: Add test for default maxfeerate in sendrawtransaction (Joonmo Yang)
261843e4bef96ab296a9775819a99bfa60cad743 wallet/rpc: Use the default maxfeerate value as BTC/kB (Joonmo Yang)
Pull request description:
Fixes https://github.com/bitcoin/bitcoin/issues/16382
This patch tries to treat `maxfeerate` in sendrawtransaction/testmempoolaccept RPC as a rate(BTC/kB) instead of an absolute value(BTC).
The included test case checks if the new behavior works correctly, by using the transaction with an absolute fee of ~0.02BTC, where the fee rate is ~0.2BTC/kB.
This test should be failing if the default `maxfeerate` is 0.1BTC, but pass if the default value is 0.1BTC/kB
ACKs for top commit:
laanwj:
ACK 2dfd6834ef8737e16e4b96df0c459f30a0721d6c (ACKs by Sjors and MarcoFalke above for trivially different code)
Tree-SHA512: a1795bffe8a182acef8844797955db1f60bb0c0ded97148f3572dc265234d5219271a3a7aa0b6418a43f73b2b2720ef7412ba169c99bb1cdcac52051f537d6af
Diffstat (limited to 'src')
-rw-r--r-- | src/rpc/rawtransaction.cpp | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 4003299662..461e8025da 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -14,6 +14,7 @@ #include <node/coin.h> #include <node/psbt.h> #include <node/transaction.h> +#include <policy/policy.h> #include <policy/rbf.h> #include <primitives/transaction.h> #include <psbt.h> @@ -38,11 +39,11 @@ #include <univalue.h> -/** High fee for sendrawtransaction and testmempoolaccept. - * By default, transaction with a fee higher than this will be rejected by the - * RPCs. This can be overridden with the maxfeerate argument. +/** High fee rate for sendrawtransaction and testmempoolaccept. + * By default, transaction with a fee rate higher than this will be rejected by + * the RPCs. This can be overridden with the maxfeerate argument. */ -constexpr static CAmount DEFAULT_MAX_RAW_TX_FEE{COIN / 10}; +static const CFeeRate DEFAULT_MAX_RAW_TX_FEE_RATE{COIN / 10}; static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { @@ -775,7 +776,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) "\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n", { {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"}, - {"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(DEFAULT_MAX_RAW_TX_FEE), + {"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK()), "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kB.\nSet to 0 to accept any fee rate.\n"}, }, @@ -805,19 +806,17 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); CTransactionRef tx(MakeTransactionRef(std::move(mtx))); - CAmount max_raw_tx_fee = DEFAULT_MAX_RAW_TX_FEE; + CFeeRate max_raw_tx_fee_rate = DEFAULT_MAX_RAW_TX_FEE_RATE; // TODO: temporary migration code for old clients. Remove in v0.20 if (request.params[1].isBool()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Second argument must be numeric (maxfeerate) and no longer supports a boolean. To allow a transaction with high fees, set maxfeerate to 0."); } else if (!request.params[1].isNull()) { - size_t weight = GetTransactionWeight(*tx); - CFeeRate fr(AmountFromValue(request.params[1])); - // the +3/4 part rounds the value up, and is the same formula used when - // calculating the fee for a transaction - // (see GetVirtualTransactionSize) - max_raw_tx_fee = fr.GetFee((weight+3)/4); + max_raw_tx_fee_rate = CFeeRate(AmountFromValue(request.params[1])); } + int64_t virtual_size = GetVirtualTransactionSize(*tx); + CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size); + std::string err_string; AssertLockNotHeld(cs_main); const TransactionError err = BroadcastTransaction(tx, err_string, max_raw_tx_fee, /*relay*/ true, /*wait_callback*/ true); @@ -841,7 +840,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) {"rawtx", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""}, }, }, - {"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(DEFAULT_MAX_RAW_TX_FEE), "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kB\n"}, + {"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK()), "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kB\n"}, }, RPCResult{ "[ (array) The result of the mempool acceptance test for each raw transaction in the input array.\n" @@ -881,19 +880,17 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request) CTransactionRef tx(MakeTransactionRef(std::move(mtx))); const uint256& tx_hash = tx->GetHash(); - CAmount max_raw_tx_fee = DEFAULT_MAX_RAW_TX_FEE; + CFeeRate max_raw_tx_fee_rate = DEFAULT_MAX_RAW_TX_FEE_RATE; // TODO: temporary migration code for old clients. Remove in v0.20 if (request.params[1].isBool()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Second argument must be numeric (maxfeerate) and no longer supports a boolean. To allow a transaction with high fees, set maxfeerate to 0."); } else if (!request.params[1].isNull()) { - size_t weight = GetTransactionWeight(*tx); - CFeeRate fr(AmountFromValue(request.params[1])); - // the +3/4 part rounds the value up, and is the same formula used when - // calculating the fee for a transaction - // (see GetVirtualTransactionSize) - max_raw_tx_fee = fr.GetFee((weight+3)/4); + max_raw_tx_fee_rate = CFeeRate(AmountFromValue(request.params[1])); } + int64_t virtual_size = GetVirtualTransactionSize(*tx); + CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size); + UniValue result(UniValue::VARR); UniValue result_0(UniValue::VOBJ); result_0.pushKV("txid", tx_hash.GetHex()); |