Bug
In src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/__init__.py, both scalar pair decoders construct an InvalidParameter exception but never raise it:
def decode_g1_scalar_pair(data: Bytes) -> Tuple[Point3D[FQ], int]:
if len(data) != 160:
InvalidParameter("Input should be 160 bytes long") # should be: raise InvalidParameter(...)
...
def decode_g2_scalar_pair(data: Bytes) -> Tuple[Point3D[FQ2], int]:
if len(data) != 288:
InvalidParameter("Input should be 288 bytes long") # should be: raise InvalidParameter(...)
...
Python silently discards the constructed object. The length guard is a no-op.
Why it hasn't caused issues
The current callers (bls12_g1_msm, bls12_g2_msm) always validate len(data) % LENGTH_PER_PAIR != 0 before looping, and pass exact-length slices to the decoders. So the guard is currently unreachable. But it creates a false contract: anyone calling these functions directly (tests, tooling, forks) would receive no protection.
Fix
Add raise to both guards.
Bug
In
src/ethereum/forks/prague/vm/precompiled_contracts/bls12_381/__init__.py, both scalar pair decoders construct anInvalidParameterexception but never raise it:Python silently discards the constructed object. The length guard is a no-op.
Why it hasn't caused issues
The current callers (
bls12_g1_msm,bls12_g2_msm) always validatelen(data) % LENGTH_PER_PAIR != 0before looping, and pass exact-length slices to the decoders. So the guard is currently unreachable. But it creates a false contract: anyone calling these functions directly (tests, tooling, forks) would receive no protection.Fix
Add
raiseto both guards.