diff options
author | Ava Chow <github@achow101.com> | 2024-06-17 15:18:08 -0400 |
---|---|---|
committer | Ava Chow <github@achow101.com> | 2024-06-17 15:18:08 -0400 |
commit | 4bcef32a937a57280afe5e601bb90121725aca72 (patch) | |
tree | 665832fa368563b8bba2da2dd22ad9b8b4b761c0 /test/functional/test_framework | |
parent | 808898fddf413dc680fa8cc7d7a2cc906098ebe3 (diff) | |
parent | 5cf0a1f230389ef37e0ff65de5fc98394f32f60c (diff) |
Merge bitcoin/bitcoin#28312: test: fix `keys_to_multisig_script` (P2MS) helper for n/k > 16
5cf0a1f230389ef37e0ff65de5fc98394f32f60c test: add `createmultisig` P2MS encoding test for all n (1..20) (Sebastian Falbesoner)
0570d2c204ec7f10af6bd8e48c23318a48fefc10 test: add unit test for `keys_to_multisig_script` (Sebastian Falbesoner)
0c41fc3fa52ad16923afbd0ec18b9c1b3ded8036 test: fix `keys_to_multisig_script` (P2MS) helper for n/k > 16 (Sebastian Falbesoner)
Pull request description:
While reviewing #28307, I noticed that the test framework's `key_to_multisig_script` helper (introduced in #23305) is broken for pubkey count (n) and threshold (k) values larger than 16. This is due to the implementation currently enforcing a direct single-byte data push (using `CScriptOp.encode_op_n`), which obviously fails for values 17+. Fix that by passing the numbers directly to the CScript list, where it's automatically converted to minimally-encoded pushes (see class method `CScript.__coerce_instance`, branch `isinstance(other, int)`).
The second commit adds a unit test to ensure that the encoding is correct.
ACKs for top commit:
achow101:
ACK 5cf0a1f230389ef37e0ff65de5fc98394f32f60c
tdb3:
ACK 5cf0a1f230389ef37e0ff65de5fc98394f32f60c
rkrux:
reACK [5cf0a1f](https://github.com/bitcoin/bitcoin/pull/28312/commits/5cf0a1f230389ef37e0ff65de5fc98394f32f60c)
Tree-SHA512: 4168a165c3f483ec8e37a27dba1628a7ea0063545a2b7e74d9e20d753fddd7e33d37e1a190434fa6dca39adf9eef5d0211f7a0c1c7b44979f0a3bb350e267562
Diffstat (limited to 'test/functional/test_framework')
-rwxr-xr-x | test/functional/test_framework/script_util.py | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/test/functional/test_framework/script_util.py b/test/functional/test_framework/script_util.py index 62894cc0f4..855f3b8cf5 100755 --- a/test/functional/test_framework/script_util.py +++ b/test/functional/test_framework/script_util.py @@ -3,10 +3,13 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Useful Script constants and utils.""" +import unittest + from test_framework.script import ( CScript, - CScriptOp, OP_0, + OP_15, + OP_16, OP_CHECKMULTISIG, OP_CHECKSIG, OP_DUP, @@ -49,10 +52,8 @@ def keys_to_multisig_script(keys, *, k=None): if k is None: # n-of-n multisig by default k = n assert k <= n - op_k = CScriptOp.encode_op_n(k) - op_n = CScriptOp.encode_op_n(n) checked_keys = [check_key(key) for key in keys] - return CScript([op_k] + checked_keys + [op_n, OP_CHECKMULTISIG]) + return CScript([k] + checked_keys + [n, OP_CHECKMULTISIG]) def keyhash_to_p2pkh_script(hash): @@ -125,3 +126,19 @@ def check_script(script): if isinstance(script, bytes) or isinstance(script, CScript): return script assert False + + +class TestFrameworkScriptUtil(unittest.TestCase): + def test_multisig(self): + fake_pubkey = bytes([0]*33) + # check correct encoding of P2MS script with n,k <= 16 + normal_ms_script = keys_to_multisig_script([fake_pubkey]*16, k=15) + self.assertEqual(len(normal_ms_script), 1 + 16*34 + 1 + 1) + self.assertTrue(normal_ms_script.startswith(bytes([OP_15]))) + self.assertTrue(normal_ms_script.endswith(bytes([OP_16, OP_CHECKMULTISIG]))) + + # check correct encoding of P2MS script with n,k > 16 + max_ms_script = keys_to_multisig_script([fake_pubkey]*20, k=19) + self.assertEqual(len(max_ms_script), 2 + 20*34 + 2 + 1) + self.assertTrue(max_ms_script.startswith(bytes([1, 19]))) # using OP_PUSH1 + self.assertTrue(max_ms_script.endswith(bytes([1, 20, OP_CHECKMULTISIG]))) |