From 7bc64a8859c3644fdf2eeff59f72a778ae60ea3f Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Fri, 16 May 2025 16:27:28 +0200 Subject: [PATCH] test: properly check for per-tx sigops limit Currently the per-tx sigops limit standardness check (bounded by `MAX_STANDARD_TX_SIGOPS_COST`, throwing "bad-txns-too-many-sigops" if exceeded) is only indirectly tested with the much higher per-block consensus limit (`MAX_BLOCK_SIGOPS_COST`), i.e. an increase in the limit would still pass all tests. Refine that by splitting up the invalid tx template `TooManySigops` in a per-block and a per-tx one. The involved functional tests taking use of these templates are `feature_block.py` and `p2p_invalid_txs.py`. --- test/functional/data/invalid_txs.py | 22 ++++++++++++++++++-- test/functional/test_framework/blocktools.py | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py index d2d7202d860..a5147dd62ab 100644 --- a/test/functional/data/invalid_txs.py +++ b/test/functional/data/invalid_txs.py @@ -30,7 +30,11 @@ from test_framework.messages import ( MAX_MONEY, SEQUENCE_FINAL, ) -from test_framework.blocktools import create_tx_with_script, MAX_BLOCK_SIGOPS +from test_framework.blocktools import ( + create_tx_with_script, + MAX_BLOCK_SIGOPS, + MAX_STANDARD_TX_SIGOPS, +) from test_framework.script import ( CScript, OP_0, @@ -233,7 +237,7 @@ class InvalidOPIFConstruction(BadTxTemplate): amount=(self.spend_avail // 2)) -class TooManySigops(BadTxTemplate): +class TooManySigopsPerBlock(BadTxTemplate): reject_reason = "bad-txns-too-many-sigops" block_reject_reason = "bad-blk-sigops, out-of-bounds SigOpCount" expect_disconnect = False @@ -245,6 +249,20 @@ class TooManySigops(BadTxTemplate): output_script=lotsa_checksigs, amount=1) + +class TooManySigopsPerTransaction(BadTxTemplate): + reject_reason = "bad-txns-too-many-sigops" + expect_disconnect = False + valid_in_block = True + + def get_tx(self): + lotsa_checksigs = CScript([OP_CHECKSIG] * (MAX_STANDARD_TX_SIGOPS + 1)) + return create_tx_with_script( + self.spend_tx, 0, + output_script=lotsa_checksigs, + amount=1) + + def getDisabledOpcodeTemplate(opcode): """ Creates disabled opcode tx template class""" def get_tx(self): diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py index c36fdb5c76e..c12277b11ee 100644 --- a/test/functional/test_framework/blocktools.py +++ b/test/functional/test_framework/blocktools.py @@ -49,6 +49,7 @@ from .util import assert_equal MAX_BLOCK_SIGOPS = 20000 MAX_BLOCK_SIGOPS_WEIGHT = MAX_BLOCK_SIGOPS * WITNESS_SCALE_FACTOR +MAX_STANDARD_TX_SIGOPS = 4000 MAX_STANDARD_TX_WEIGHT = 400000 # Genesis block time (regtest)