I’d like to improve the Taproot control size check in IsWitnessStandard. Rather than just checking emptiness, we should perform all three checks implemented in VerifyTaprootControlBlockSize (see below). This way we can invalidate the transaction earlier when it’s clear that the control size is incompatible with consensus rules (saving compute).
Old checks:
control.size() > 0
New checks:
control.size() >= TAPROOT_CONTROL_BASE_SIZEcontrol.size() <= TAPROOT_CONTROL_MAX_SIZE(control.size() - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE == 0
For example, a single byte control block wouldn’t be empty, but it would be invalid because it’s shorter than TAPROOT_CONTROL_BASE_SIZE (33). IsWitnessStandard should return false in that case.
This PR also adds a helper function for the control block size check to reduce repetition and to improve readability of the (rather heavy) functions that call it. We have four instances of the same check.
I ran:
cmake -B build -DENABLE_WALLET=OFF && cmake --build build -j 8 && ctest --test-dir build -j 8
Looking forward to your feedback.