mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-07 21:28:40 +02:00
Merge #19339: validation: re-delegate absurd fee checking from mempool to clients
b048b275d9[validation] Remove absurdfee from accepttomempool (John Newbery)932564b9cfscripted-diff: update max-fee-exceeded error message to include RPC (gzhao408)8f1290c601[rpc/node] check for high fee before ATMP in clients (gzhao408) Pull request description: Picked up from #15810. Add separate fee-checking logic for clients that need to enforce max fee rates, then remove the `absurdFee` logic from ATMP. ATMP's `nAbsurdFee` argument is used to enforce user-specific behavior (it is not policy since it isn't applied consistently: it is only ever used in RPC and wallet, and set to 0 everywhere else internally). It should be removed from `AcceptToMemoryPool` because (1) validation results/mempool behavior should not be user-specific and (2) enforcing a max fee rate should be the responsibility of the client instead of the mempool. Note: this PR does not intend to _remove_ protection from high fees, just re-delegate the responsibility to clients. ACKs for top commit: jnewbery: utACKb048b275d9LarryRuane: re-ACKb048b275d9MarcoFalke: re-ACKb048b275d9, only change is squashing one commit 🏦 instagibbs: utACKb048b275d9Tree-SHA512: 57c17ba16d230a4cae2896dd6a64c924f307757824e35784bf96da7b10aff2d8ea910710edf35e981035623a155f8766209a92a0fdb856549fde78bc3eaae4d2
This commit is contained in:
@@ -667,7 +667,7 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
result = self.nodes[3].fundrawtransaction(rawtx) # uses self.min_relay_tx_fee (set by settxfee)
|
||||
result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2 * self.min_relay_tx_fee})
|
||||
result3 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 10 * self.min_relay_tx_fee})
|
||||
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by -maxtxfee", self.nodes[3].fundrawtransaction, rawtx, {"feeRate": 1})
|
||||
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)", self.nodes[3].fundrawtransaction, rawtx, {"feeRate": 1})
|
||||
result_fee_rate = result['fee'] * 1000 / count_bytes(result['hex'])
|
||||
assert_fee_amount(result2['fee'], count_bytes(result2['hex']), 2 * result_fee_rate)
|
||||
assert_fee_amount(result3['fee'], count_bytes(result3['hex']), 10 * result_fee_rate)
|
||||
|
||||
@@ -192,8 +192,8 @@ class PSBTTest(BitcoinTestFramework):
|
||||
|
||||
# feeRate of 10 BTC / KB produces a total fee well above -maxtxfee
|
||||
# previously this was silently capped at -maxtxfee
|
||||
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by -maxtxfee", self.nodes[1].walletcreatefundedpsbt, [{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():29.99}, 0, {"feeRate": 10, "add_inputs": True})
|
||||
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by -maxtxfee", self.nodes[1].walletcreatefundedpsbt, [{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():1}, 0, {"feeRate": 10, "add_inputs": False})
|
||||
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)", self.nodes[1].walletcreatefundedpsbt, [{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():29.99}, 0, {"feeRate": 10, "add_inputs": True})
|
||||
assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)", self.nodes[1].walletcreatefundedpsbt, [{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():1}, 0, {"feeRate": 10, "add_inputs": False})
|
||||
|
||||
# partially sign multisig things with node 1
|
||||
psbtx = wmulti.walletcreatefundedpsbt(inputs=[{"txid":txid,"vout":p2wsh_pos},{"txid":txid,"vout":p2sh_pos},{"txid":txid,"vout":p2sh_p2wsh_pos}], outputs={self.nodes[1].getnewaddress():29.99}, options={'changeAddress': self.nodes[1].getrawchangeaddress()})['psbt']
|
||||
|
||||
@@ -456,9 +456,9 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
# Thus, testmempoolaccept should reject
|
||||
testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']], 0.00001000)[0]
|
||||
assert_equal(testres['allowed'], False)
|
||||
assert_equal(testres['reject-reason'], 'absurdly-high-fee')
|
||||
assert_equal(testres['reject-reason'], 'max-fee-exceeded')
|
||||
# and sendrawtransaction should throw
|
||||
assert_raises_rpc_error(-26, "absurdly-high-fee", self.nodes[2].sendrawtransaction, rawTxSigned['hex'], 0.00001000)
|
||||
assert_raises_rpc_error(-25, 'Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)', self.nodes[2].sendrawtransaction, rawTxSigned['hex'], 0.00001000)
|
||||
# and the following calls should both succeed
|
||||
testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']])[0]
|
||||
assert_equal(testres['allowed'], True)
|
||||
@@ -480,9 +480,9 @@ class RawTransactionsTest(BitcoinTestFramework):
|
||||
# Thus, testmempoolaccept should reject
|
||||
testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']])[0]
|
||||
assert_equal(testres['allowed'], False)
|
||||
assert_equal(testres['reject-reason'], 'absurdly-high-fee')
|
||||
assert_equal(testres['reject-reason'], 'max-fee-exceeded')
|
||||
# and sendrawtransaction should throw
|
||||
assert_raises_rpc_error(-26, "absurdly-high-fee", self.nodes[2].sendrawtransaction, rawTxSigned['hex'])
|
||||
assert_raises_rpc_error(-25, 'Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)', self.nodes[2].sendrawtransaction, rawTxSigned['hex'])
|
||||
# and the following calls should both succeed
|
||||
testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']], maxfeerate='0.20000000')[0]
|
||||
assert_equal(testres['allowed'], True)
|
||||
|
||||
@@ -348,7 +348,7 @@ def test_maxtxfee_fails(self, rbf_node, dest_address):
|
||||
self.restart_node(1, ['-maxtxfee=0.000025'] + self.extra_args[1])
|
||||
rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
|
||||
rbfid = spend_one_input(rbf_node, dest_address)
|
||||
assert_raises_rpc_error(-4, "Unable to create transaction. Fee exceeds maximum configured by -maxtxfee", rbf_node.bumpfee, rbfid)
|
||||
assert_raises_rpc_error(-4, "Unable to create transaction. Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)", rbf_node.bumpfee, rbfid)
|
||||
self.restart_node(1, self.extra_args[1])
|
||||
rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
|
||||
self.connect_nodes(1, 0)
|
||||
|
||||
@@ -53,12 +53,12 @@ class CreateTxWalletTest(BitcoinTestFramework):
|
||||
self.restart_node(0, extra_args=[fee_setting])
|
||||
assert_raises_rpc_error(
|
||||
-6,
|
||||
"Fee exceeds maximum configured by -maxtxfee",
|
||||
"Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
||||
lambda: self.nodes[0].sendmany(dummy="", amounts=outputs),
|
||||
)
|
||||
assert_raises_rpc_error(
|
||||
-4,
|
||||
"Fee exceeds maximum configured by -maxtxfee",
|
||||
"Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
||||
lambda: self.nodes[0].fundrawtransaction(hexstring=raw_tx),
|
||||
)
|
||||
|
||||
@@ -67,12 +67,12 @@ class CreateTxWalletTest(BitcoinTestFramework):
|
||||
self.nodes[0].settxfee(0.01)
|
||||
assert_raises_rpc_error(
|
||||
-6,
|
||||
"Fee exceeds maximum configured by -maxtxfee",
|
||||
"Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
||||
lambda: self.nodes[0].sendmany(dummy="", amounts=outputs),
|
||||
)
|
||||
assert_raises_rpc_error(
|
||||
-4,
|
||||
"Fee exceeds maximum configured by -maxtxfee",
|
||||
"Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
|
||||
lambda: self.nodes[0].fundrawtransaction(hexstring=raw_tx),
|
||||
)
|
||||
self.nodes[0].settxfee(0)
|
||||
|
||||
Reference in New Issue
Block a user