mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-09 03:18:09 -03:00
test: add -blockmaxweight
startup option functional test
This commit is contained in:
parent
703373df8c
commit
b55bb95d8d
1 changed files with 84 additions and 0 deletions
|
@ -23,7 +23,9 @@ from test_framework.messages import (
|
|||
CBlockHeader,
|
||||
COIN,
|
||||
DEFAULT_COINBASE_TX_WEIGHT,
|
||||
MAX_BLOCK_WEIGHT,
|
||||
ser_uint256,
|
||||
WITNESS_SCALE_FACTOR
|
||||
)
|
||||
from test_framework.p2p import P2PDataStore
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
|
@ -190,6 +192,87 @@ class MiningTest(BitcoinTestFramework):
|
|||
assert_equal(result, "inconclusive")
|
||||
assert_equal(prune_node.getblock(pruned_blockhash, verbosity=0), pruned_block)
|
||||
|
||||
|
||||
def send_transactions(self, utxos, fee_rate, target_vsize):
|
||||
"""
|
||||
Helper to create and send transactions with the specified target virtual size and fee rate.
|
||||
"""
|
||||
for utxo in utxos:
|
||||
self.wallet.send_self_transfer(
|
||||
from_node=self.nodes[0],
|
||||
utxo_to_spend=utxo,
|
||||
target_vsize=target_vsize,
|
||||
fee_rate=fee_rate,
|
||||
)
|
||||
|
||||
def verify_block_template(self, expected_tx_count, expected_weight):
|
||||
"""
|
||||
Create a block template and check that it satisfies the expected transaction count and total weight.
|
||||
"""
|
||||
response = self.nodes[0].getblocktemplate(NORMAL_GBT_REQUEST_PARAMS)
|
||||
self.log.info(f"Testing block template: contains {expected_tx_count} transactions, and total weight <= {expected_weight}")
|
||||
assert_equal(len(response["transactions"]), expected_tx_count)
|
||||
total_weight = sum(transaction["weight"] for transaction in response["transactions"])
|
||||
assert_greater_than_or_equal(expected_weight, total_weight)
|
||||
|
||||
def test_block_max_weight(self):
|
||||
self.log.info("Testing default and custom -blockmaxweight startup options.")
|
||||
|
||||
# Restart the node to allow large transactions
|
||||
LARGE_TXS_COUNT = 10
|
||||
LARGE_VSIZE = int(((MAX_BLOCK_WEIGHT - DEFAULT_COINBASE_TX_WEIGHT) / WITNESS_SCALE_FACTOR) / LARGE_TXS_COUNT)
|
||||
HIGH_FEERATE = Decimal("0.0003")
|
||||
self.restart_node(0, extra_args=[f"-datacarriersize={LARGE_VSIZE}"])
|
||||
|
||||
# Ensure the mempool is empty
|
||||
assert_equal(len(self.nodes[0].getrawmempool()), 0)
|
||||
|
||||
# Generate UTXOs and send 10 large transactions with a high fee rate
|
||||
utxos = [self.wallet.get_utxo(confirmed_only=True) for _ in range(LARGE_TXS_COUNT + 4)] # Add 4 more utxos that will be used in the test later
|
||||
self.send_transactions(utxos[:LARGE_TXS_COUNT], HIGH_FEERATE, LARGE_VSIZE)
|
||||
|
||||
# Send 2 normal transactions with a lower fee rate
|
||||
NORMAL_VSIZE = int(2000 / WITNESS_SCALE_FACTOR)
|
||||
NORMAL_FEERATE = Decimal("0.0001")
|
||||
self.send_transactions(utxos[LARGE_TXS_COUNT:LARGE_TXS_COUNT + 2], NORMAL_FEERATE, NORMAL_VSIZE)
|
||||
|
||||
# Check that the mempool contains all transactions
|
||||
self.log.info(f"Testing that the mempool contains {LARGE_TXS_COUNT + 2} transactions.")
|
||||
assert_equal(len(self.nodes[0].getrawmempool()), LARGE_TXS_COUNT + 2)
|
||||
|
||||
# Verify the block template includes only the 10 high-fee transactions
|
||||
self.log.info("Testing that the block template includes only the 10 large transactions.")
|
||||
self.verify_block_template(
|
||||
expected_tx_count=LARGE_TXS_COUNT,
|
||||
expected_weight=MAX_BLOCK_WEIGHT - DEFAULT_COINBASE_TX_WEIGHT,
|
||||
)
|
||||
|
||||
# Test block template creation with custom -blockmaxweight
|
||||
custom_block_weight = MAX_BLOCK_WEIGHT - 2000
|
||||
# Reducing the weight by 2000 units will prevent 1 large transaction from fitting into the block.
|
||||
self.restart_node(0, extra_args=[f"-datacarriersize={LARGE_VSIZE}", f"-blockmaxweight={custom_block_weight}"])
|
||||
|
||||
self.log.info("Testing the block template with custom -blockmaxweight to include 9 large and 2 normal transactions.")
|
||||
self.verify_block_template(
|
||||
expected_tx_count=11,
|
||||
expected_weight=MAX_BLOCK_WEIGHT - DEFAULT_COINBASE_TX_WEIGHT - 2000,
|
||||
)
|
||||
|
||||
# Ensure the block weight does not exceed the maximum
|
||||
self.log.info(f"Testing that the block weight will never exceed {MAX_BLOCK_WEIGHT - DEFAULT_COINBASE_TX_WEIGHT}.")
|
||||
self.restart_node(0, extra_args=[f"-datacarriersize={LARGE_VSIZE}", f"-blockmaxweight={MAX_BLOCK_WEIGHT}"])
|
||||
self.log.info("Sending 2 additional normal transactions to fill the mempool to the maximum block weight.")
|
||||
self.send_transactions(utxos[LARGE_TXS_COUNT + 2:], NORMAL_FEERATE, NORMAL_VSIZE)
|
||||
self.log.info(f"Testing that the mempool's weight matches the maximum block weight: {MAX_BLOCK_WEIGHT}.")
|
||||
assert_equal(self.nodes[0].getmempoolinfo()['bytes'] * WITNESS_SCALE_FACTOR, MAX_BLOCK_WEIGHT)
|
||||
|
||||
self.log.info("Testing that the block template includes only 10 transactions and cannot reach full block weight.")
|
||||
self.verify_block_template(
|
||||
expected_tx_count=LARGE_TXS_COUNT,
|
||||
expected_weight=MAX_BLOCK_WEIGHT - DEFAULT_COINBASE_TX_WEIGHT,
|
||||
)
|
||||
|
||||
|
||||
def run_test(self):
|
||||
node = self.nodes[0]
|
||||
self.wallet = MiniWallet(node)
|
||||
|
@ -407,6 +490,7 @@ class MiningTest(BitcoinTestFramework):
|
|||
assert_equal(node.submitblock(hexdata=block.serialize().hex()), 'duplicate') # valid
|
||||
|
||||
self.test_blockmintxfee_parameter()
|
||||
self.test_block_max_weight()
|
||||
self.test_timewarp()
|
||||
self.test_pruning()
|
||||
|
||||
|
|
Loading…
Reference in a new issue