RPC: Add maxfeerate and maxburnamount args to submitpackage

And thread the feerate value through ProcessNewPackage to
reject individual transactions that exceed the given
feerate. This allows subpackage processing, and is
compatible with future package RBF work.
This commit is contained in:
Greg Sanders
2023-11-27 14:50:55 -05:00
parent 45b2a91897
commit 38f70ba6ac
9 changed files with 124 additions and 30 deletions

View File

@ -81,6 +81,7 @@ class RPCPackagesTest(BitcoinTestFramework):
self.test_conflicting()
self.test_rbf()
self.test_submitpackage()
self.test_maxfeerate_maxburn_submitpackage()
def test_independent(self, coin):
self.log.info("Test multiple independent transactions in a package")
@ -356,5 +357,34 @@ class RPCPackagesTest(BitcoinTestFramework):
assert_equal(res["tx-results"][sec_wtxid]["error"], "version")
peer.wait_for_broadcast([first_wtxid])
def test_maxfeerate_maxburn_submitpackage(self):
node = self.nodes[0]
# clear mempool
deterministic_address = node.get_deterministic_priv_key().address
self.generatetoaddress(node, 1, deterministic_address)
self.log.info("Submitpackage maxfeerate arg testing")
chained_txns = self.wallet.create_self_transfer_chain(chain_length=2)
minrate_btc_kvb = min([chained_txn["fee"] / chained_txn["tx"].get_vsize() * 1000 for chained_txn in chained_txns])
chain_hex = [t["hex"] for t in chained_txns]
pkg_result = node.submitpackage(chain_hex, maxfeerate=minrate_btc_kvb - Decimal("0.00000001"))
assert_equal(pkg_result["tx-results"][chained_txns[0]["wtxid"]]["error"], "max feerate exceeded")
assert_equal(pkg_result["tx-results"][chained_txns[1]["wtxid"]]["error"], "bad-txns-inputs-missingorspent")
assert_equal(node.getrawmempool(), [])
self.log.info("Submitpackage maxburnamount arg testing")
tx = tx_from_hex(chain_hex[1])
tx.vout[-1].scriptPubKey = b'a' * 10001 # scriptPubKey bigger than 10k IsUnspendable
chain_hex = [chain_hex[0], tx.serialize().hex()]
# burn test is run before any package evaluation; nothing makes it in and we get broader exception
assert_raises_rpc_error(-25, "Unspendable output exceeds maximum configured by user", node.submitpackage, chain_hex, 0, chained_txns[1]["new_utxo"]["value"] - Decimal("0.00000001"))
assert_equal(node.getrawmempool(), [])
# Relax the restrictions for both and send it; parent gets through as own subpackage
pkg_result = node.submitpackage(chain_hex, maxfeerate=minrate_btc_kvb, maxburnamount=chained_txns[1]["new_utxo"]["value"])
assert "error" not in pkg_result["tx-results"][chained_txns[0]["wtxid"]]
assert_equal(pkg_result["tx-results"][tx.getwtxid()]["error"], "scriptpubkey")
assert_equal(node.getrawmempool(), [chained_txns[0]["txid"]])
if __name__ == "__main__":
RPCPackagesTest().main()