mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-22 06:52:36 +01:00
wallet/rpc: Use the default maxfeerate value as BTC/kB
This commit is contained in:
parent
3a3d8b8357
commit
261843e4be
4 changed files with 20 additions and 22 deletions
|
@ -14,6 +14,7 @@
|
||||||
#include <node/coin.h>
|
#include <node/coin.h>
|
||||||
#include <node/psbt.h>
|
#include <node/psbt.h>
|
||||||
#include <node/transaction.h>
|
#include <node/transaction.h>
|
||||||
|
#include <policy/policy.h>
|
||||||
#include <policy/rbf.h>
|
#include <policy/rbf.h>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <psbt.h>
|
#include <psbt.h>
|
||||||
|
@ -37,11 +38,11 @@
|
||||||
|
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
|
|
||||||
/** High fee for sendrawtransaction and testmempoolaccept.
|
/** High fee rate for sendrawtransaction and testmempoolaccept.
|
||||||
* By default, transaction with a fee higher than this will be rejected by the
|
* By default, transaction with a fee rate higher than this will be rejected by
|
||||||
* RPCs. This can be overridden with the maxfeerate argument.
|
* 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)
|
static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
|
||||||
{
|
{
|
||||||
|
@ -771,7 +772,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
|
||||||
"\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n",
|
"\nAlso see createrawtransaction and signrawtransactionwithkey calls.\n",
|
||||||
{
|
{
|
||||||
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
|
{"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 +
|
"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"},
|
"/kB.\nSet to 0 to accept any fee rate.\n"},
|
||||||
},
|
},
|
||||||
|
@ -801,19 +802,17 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
|
||||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
||||||
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
|
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
|
// TODO: temporary migration code for old clients. Remove in v0.20
|
||||||
if (request.params[1].isBool()) {
|
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.");
|
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()) {
|
} else if (!request.params[1].isNull()) {
|
||||||
size_t weight = GetTransactionWeight(*tx);
|
max_raw_tx_fee_rate = CFeeRate(AmountFromValue(request.params[1]));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t virtual_size = GetVirtualTransactionSize(*tx);
|
||||||
|
CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size);
|
||||||
|
|
||||||
std::string err_string;
|
std::string err_string;
|
||||||
AssertLockNotHeld(cs_main);
|
AssertLockNotHeld(cs_main);
|
||||||
const TransactionError err = BroadcastTransaction(tx, err_string, max_raw_tx_fee, /*relay*/ true, /*wait_callback*/ true);
|
const TransactionError err = BroadcastTransaction(tx, err_string, max_raw_tx_fee, /*relay*/ true, /*wait_callback*/ true);
|
||||||
|
@ -837,7 +836,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
|
||||||
{"rawtx", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, ""},
|
{"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{
|
RPCResult{
|
||||||
"[ (array) The result of the mempool acceptance test for each raw transaction in the input array.\n"
|
"[ (array) The result of the mempool acceptance test for each raw transaction in the input array.\n"
|
||||||
|
@ -877,19 +876,17 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
|
||||||
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
|
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
|
||||||
const uint256& tx_hash = tx->GetHash();
|
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
|
// TODO: temporary migration code for old clients. Remove in v0.20
|
||||||
if (request.params[1].isBool()) {
|
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.");
|
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()) {
|
} else if (!request.params[1].isNull()) {
|
||||||
size_t weight = GetTransactionWeight(*tx);
|
max_raw_tx_fee_rate = CFeeRate(AmountFromValue(request.params[1]));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(UniValue::VARR);
|
||||||
UniValue result_0(UniValue::VOBJ);
|
UniValue result_0(UniValue::VOBJ);
|
||||||
result_0.pushKV("txid", tx_hash.GetHex());
|
result_0.pushKV("txid", tx_hash.GetHex());
|
||||||
|
|
|
@ -240,7 +240,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||||
tx.vin.append(CTxIn(COutPoint(int(txid2, 16), 0), b""))
|
tx.vin.append(CTxIn(COutPoint(int(txid2, 16), 0), b""))
|
||||||
tx.vout.append(CTxOut(int(49.95 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) # Huge fee
|
tx.vout.append(CTxOut(int(49.95 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) # Huge fee
|
||||||
tx.calc_sha256()
|
tx.calc_sha256()
|
||||||
txid3 = self.nodes[0].sendrawtransaction(ToHex(tx))
|
txid3 = self.nodes[0].sendrawtransaction(ToHex(tx), 0)
|
||||||
assert tx.wit.is_null()
|
assert tx.wit.is_null()
|
||||||
assert txid3 in self.nodes[0].getrawmempool()
|
assert txid3 in self.nodes[0].getrawmempool()
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
|
||||||
self.check_mempool_result(
|
self.check_mempool_result(
|
||||||
result_expected=[{'txid': tx.rehash(), 'allowed': True}],
|
result_expected=[{'txid': tx.rehash(), 'allowed': True}],
|
||||||
rawtxs=[tx.serialize().hex()],
|
rawtxs=[tx.serialize().hex()],
|
||||||
|
maxfeerate=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.log.info('A transaction with no outputs')
|
self.log.info('A transaction with no outputs')
|
||||||
|
|
|
@ -433,7 +433,7 @@ class WalletTest(BitcoinTestFramework):
|
||||||
# Split into two chains
|
# Split into two chains
|
||||||
rawtx = self.nodes[0].createrawtransaction([{"txid": singletxid, "vout": 0}], {chain_addrs[0]: node0_balance / 2 - Decimal('0.01'), chain_addrs[1]: node0_balance / 2 - Decimal('0.01')})
|
rawtx = self.nodes[0].createrawtransaction([{"txid": singletxid, "vout": 0}], {chain_addrs[0]: node0_balance / 2 - Decimal('0.01'), chain_addrs[1]: node0_balance / 2 - Decimal('0.01')})
|
||||||
signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
|
signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
|
||||||
singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"])
|
singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"], 0)
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
|
|
||||||
# Make a long chain of unconfirmed payments without hitting mempool limit
|
# Make a long chain of unconfirmed payments without hitting mempool limit
|
||||||
|
|
Loading…
Add table
Reference in a new issue