diff options
author | Sebastian Falbesoner <sebastian.falbesoner@gmail.com> | 2023-05-11 19:54:03 +0200 |
---|---|---|
committer | Sebastian Falbesoner <sebastian.falbesoner@gmail.com> | 2023-06-04 23:50:30 +0200 |
commit | 54877253c807dac7a3720b2c3d1d989c410259a7 (patch) | |
tree | 93247de423ec348fb1368992588d17ed0bfbbeb8 | |
parent | 7f2019755d147e7e17c54f0bb61296211bb45262 (diff) |
test: avoid sporadic MINIMALDATA failure in feature_taproot.py (fixes #27595)
The functional test feature_taproot.py fails in some rare cases on the
execution of the `"branched_codesep"` spending script. The problem
occurs if the first data-push (having random content with a random
length in the range [0, 510]) has a length of 1 and the single byte has
value of [1...16] or [-1]; in this case, the data-push is not minimally
encoded by test framework's CScript class (i.e. doesn't use the special
op-codes OP_1...OP_16 or OP_1NEGATE) and the script interpreter throws
an SCRIPT_ERR_MINIMALDATA error:
```
test_framework.authproxy.JSONRPCException: non-mandatory-script-verify-flag (Data push larger than necessary) (-26)
```
Background:
The functional test framework's CScript class translates passed
bytes/bytearrays always to data pushes using OP_PUSHx/OP_PUSHDATA{1,2,4}
op-codes. E.g. the expression `CScript(bytes([1]))` yields
`bytes([OP_PUSH1, 1])` instead of the minimal-encoded `bytes([OP_1])`.
Fix this by adapting the random-size range to [2,...], i.e. never pass
byte-arrays below length two to be pushed.
Closes #27595.
-rwxr-xr-x | test/functional/feature_taproot.py | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py index 8be2040d91..34197a5c48 100755 --- a/test/functional/feature_taproot.py +++ b/test/functional/feature_taproot.py @@ -738,7 +738,11 @@ def spenders_taproot_active(): scripts = [ ("pk_codesep", CScript(random_checksig_style(pubs[1]) + bytes([OP_CODESEPARATOR]))), # codesep after checksig ("codesep_pk", CScript(bytes([OP_CODESEPARATOR]) + random_checksig_style(pubs[1]))), # codesep before checksig - ("branched_codesep", CScript([random_bytes(random.randrange(511)), OP_DROP, OP_IF, OP_CODESEPARATOR, pubs[0], OP_ELSE, OP_CODESEPARATOR, pubs[1], OP_ENDIF, OP_CHECKSIG])), # branch dependent codesep + ("branched_codesep", CScript([random_bytes(random.randrange(2, 511)), OP_DROP, OP_IF, OP_CODESEPARATOR, pubs[0], OP_ELSE, OP_CODESEPARATOR, pubs[1], OP_ENDIF, OP_CHECKSIG])), # branch dependent codesep + # Note that the first data push in the "branched_codesep" script has the purpose of + # randomizing the sighash, both by varying script size and content. In order to + # avoid MINIMALDATA script verification errors caused by not-minimal-encoded data + # pushes (e.g. `OP_PUSH1 1` instead of `OP_1`), we set a minimum data size of 2 bytes. ] random.shuffle(scripts) tap = taproot_construct(pubs[0], scripts) |