Fixes #22865. Required for #21702 tests.
The basic issue is that that the current exclude flag doesn’t play nicely with flags like DISCOURAGE_UPGRADABLE_NOPS + SOME_OPCODE_VERIFY.
When you have a valid TX under SOME_OPCODE_VERIFY, then the tests will try disabling that flag and it will trip over DISCOURAGE_UPGRADABLE_NOPS.
When you exclude DISCOURAGE_UPGRADABLE_NOPS, then it gets re-included when the test checks all cominations of the excluded flags being re-enabled to show failure, but then it doesn’t fail when SOME_OPCODE_VERIFY is set.
To address this, we add two optional fields: 1, a list of flags to always enable; 2, a bool of if to disable the one-by-one checker.
By then testing the same vector with:
0...'DISCOURAGE_UPGRADABLE_NOPS', 'NONE', true]
1...'NONE', 'SOME_OPCODE_VERIFY']
we get around the one flag at a time checker.
An alternative approach, that would provide better testing coverage, would allow a more abritrary relationship checker that can be specificed by the test writer (e.g., a map of flag to implied flag) to be used during the one-by-one checker.
We cannot simply apply these rules in FillFlags/TrimFlags because if we have a transaction that should fail normally with VERIFY_SOME_OPCODE and DISCOURAGE_UPGRADABLE_OPCODES we can’t support both cases.
This gap arose when implementing test vectors for BIP-119. Along the way I also discovered that, e.g., CHECKSEQUENCEVERIFY’s Upgradable NOP treatment is improperly asserted as per:
0 // To provide for future soft-fork extensibility, if the
1 // operand has the disabled lock-time flag set,
2 // CHECKSEQUENCEVERIFY behaves as a NOP.
3 if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0)
4 break
which does not assert the proper DISCOURAGE_UPGRADABLE_NOP behavior. I beleive that lack of discouragement to be mildly worrying but not a major security concern. Fixing the testing harnesses would allow us to properly implement DISCOURAGE_UPGRADABLE_NOPS for CSV and add the corresponding test cases.