fix(utxo): validate public_key hex format before address converter (#6114)#6337
fix(utxo): validate public_key hex format before address converter (#6114)#6337crowniteto wants to merge 2 commits into
Conversation
…cottcjn#6114) Malformed public_key strings (non-hex, wrong length) passed through to address_from_pubkey() which calls bytes.fromhex() — causing unhandled ValueError/500 instead of structured 400. Fix: - Pre-validate public_key is exactly 64 hex chars (32-byte Ed25519) - Return 400 with clear error message on invalid format - Wrap _addr_from_pk_fn call in try/except as defense-in-depth - 3 regression tests covering non-hex, short, and valid keys
CyberNomad2000
left a comment
There was a problem hiding this comment.
Approved current head 0f2b990966fb84fa0494e41b6fcc73a514478a92.
I checked the /utxo/transfer path against #6114. The PR now rejects non-hex and wrong-length public_key strings before calling the address converter, while still allowing valid 64-character hex material to proceed to the existing address/signature validation path.
Local validation run:
python -m py_compile node/utxo_endpoints.py tests/test_utxo_malformed_pubkey_6114.py tests/test_p2p_blocks.py
python -m pytest tests/test_utxo_malformed_pubkey_6114.py -q
Result: 3 passed in 0.30s.
Non-blocking cleanup: tests/test_p2p_blocks.py appears to be an accidental one-line placeholder (import pytest) unrelated to this fix, so I would remove it before merge if you want the PR to stay tight.
jaxint
left a comment
There was a problem hiding this comment.
LGTM! Great work on this PR. 🚀
jaxint
left a comment
There was a problem hiding this comment.
Great work! Thanks for contributing to RustChain! 🦀
jaxint
left a comment
There was a problem hiding this comment.
Great work! Thanks for contributing to RustChain! 🦀
jaxint
left a comment
There was a problem hiding this comment.
Great work on this PR! The code looks clean and well-structured.
Review powered by RustChain Bounty Program
Wallet: AhqbFaPBPLMMiaLDzA9WhQcyvv4hMxiteLhPk3NhG1iG
jaxint
left a comment
There was a problem hiding this comment.
Great work! Thanks for contributing to RustChain! 🦀
MolhamHamwi
left a comment
There was a problem hiding this comment.
Reviewed node/utxo_endpoints.py and tests/test_utxo_malformed_pubkey_6114.py.
- The new validation happens before
_addr_from_pk_fn(public_key), so non-hex or wrong-length keys now return the route's structured 400 response instead of lettingbytes.fromhex()escape as a 500. - The tests cover the two important malformed classes separately (non-hex content and too-short hex) and also include a valid 64-character hex case to verify the new guard does not reject correctly shaped Ed25519 keys before the existing signature/address checks run.
Local validation: python3 -m pytest -q tests/test_utxo_malformed_pubkey_6114.py passed (3 passed).
I received RTC compensation for this review.
HuiNeng6
left a comment
There was a problem hiding this comment.
Code Review
Observations:
-
Line 454-463 (utxo_endpoints.py): Comprehensive validation before passing to address converter. Checks both length (64 chars for 32-byte Ed25519) and hex character validity. This prevents malformed keys from reaching the crypto library and causing unpredictable errors.
-
Error message design: The error response includes
got: public_key[:20]...which is helpful for debugging without exposing full potentially-malicious input. Good balance between security and usability. -
Test coverage (test_utxo_malformed_pubkey_6114.py): Three test cases cover different failure modes: non-hex chars, too-short hex, and valid-hex-length case. The fixture uses a stub
_addr_from_pkthat only validates hex format, cleanly separating the validation layer from downstream crypto. -
Minor issue: The file
tests/test_p2p_blocks.pywith justimport pytestseems like an unintended artifact — should be removed before merge.
Assessment: Thorough review (10-15 RTC eligible)
Disclosure: I received RTC compensation for this review.
jaxint
left a comment
There was a problem hiding this comment.
Great work! Thanks for contributing to RustChain! 🦀
jaxint
left a comment
There was a problem hiding this comment.
Code review completed. Thanks for contributing to RustChain! 🚀
jaxint
left a comment
There was a problem hiding this comment.
Code review completed. Thanks for contributing! 🚀
jaxint
left a comment
There was a problem hiding this comment.
Great work! Thanks for contributing to RustChain! 🦀
jaxint
left a comment
There was a problem hiding this comment.
Great work! Thanks for contributing to RustChain! 🦀
jaxint
left a comment
There was a problem hiding this comment.
Great work! Thanks for contributing to RustChain! 🦀
shadow88sky
left a comment
There was a problem hiding this comment.
Reviewed the UTXO malformed public_key fix and the submitted tests. The core change looks directionally good: malformed non-hex and wrong-length public keys are rejected before address conversion, and the focused regression suite passes locally.
One cleanup note: the PR also includes tests/test_p2p_blocks.py, which currently contains only import pytest and no tests. Running it directly returns pytest exit code 5 (no tests ran). Since the PR is otherwise a small UTXO validation fix, I would remove or split that placeholder file so the branch stays tightly scoped.
Validation performed:
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .venv/bin/python -m pytest tests/test_utxo_malformed_pubkey_6114.py -q
-> 3 passed in 0.07s
.venv/bin/python -m py_compile node/utxo_endpoints.py tests/test_utxo_malformed_pubkey_6114.py tests/test_p2p_blocks.py
-> passed
git diff --check HEAD~5..HEAD
-> passed
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .venv/bin/python -m pytest tests/test_p2p_blocks.py -q
-> no tests ran (exit code 5)
jaxint
left a comment
There was a problem hiding this comment.
Great work! Thanks for contributing to RustChain! 🦀
jaxint
left a comment
There was a problem hiding this comment.
Great work! Thanks for contributing to RustChain! 🦀
Summary
Fixes #6114 — malformed strings (non-hex, wrong length) in were passed through to which calls , causing an unhandled / 500 response instead of a structured 400.
Changes
Test Results