Skip to content

fix: reject malformed UTXO public keys#6340

Open
duongynhi000005-oss wants to merge 1 commit into
Scottcjn:mainfrom
duongynhi000005-oss:fix/utxo-malformed-public-key
Open

fix: reject malformed UTXO public keys#6340
duongynhi000005-oss wants to merge 1 commit into
Scottcjn:mainfrom
duongynhi000005-oss:fix/utxo-malformed-public-key

Conversation

@duongynhi000005-oss
Copy link
Copy Markdown

Return HTTP 400 for malformed public_key material in /utxo/transfer instead of letting address conversion exceptions escape.\n\nTests: PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest tests/test_utxo_transfer_json_validation.py -q

@github-actions
Copy link
Copy Markdown
Contributor

Welcome to RustChain! Thanks for your first pull request.

Before we review, please make sure:

  • Non-doc PRs have a BCOS-L1 or BCOS-L2 label
  • Doc-only PRs are exempt from BCOS tier labels when they only touch docs/**, *.md, or common image/PDF files
  • New code files include an SPDX license header
  • You've tested your changes against the live node

Bounty tiers: Micro (1-10 RTC) | Standard (20-50) | Major (75-100) | Critical (100-150)

A maintainer will review your PR soon. Thanks for contributing!

@github-actions github-actions Bot added BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) node Node server related tests Test suite changes size/S PR: 11-50 lines and removed BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) node Node server related tests Test suite changes labels May 25, 2026
Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on this PR! The code looks clean and well-structured.

Review powered by RustChain Bounty Program

Wallet: AhqbFaPBPLMMiaLDzA9WhQcyvv4hMxiteLhPk3NhG1iG

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Copy link
Copy Markdown

@shadow88sky shadow88sky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the /utxo/transfer malformed-public-key fix and the focused regression coverage.

Two concrete observations:

  1. The production change is in the right place in node/utxo_endpoints.py: the endpoint already validates the payload shape and amount before deriving the expected sender address, so wrapping only _addr_from_pk_fn(public_key) keeps malformed key material on the same 400-client-error path without broadening the rest of the transfer flow. This also preserves the existing address-mismatch response when the key is syntactically valid but belongs to a different address.

  2. The new test in tests/test_utxo_transfer_json_validation.py is well-scoped because it monkeypatches the injected address-derivation function to raise ValueError, which matches the real address_from_pubkey() failure mode from bytes.fromhex(public_key_hex). It verifies the endpoint returns {"error": "Invalid public_key"} before signature verification or UTXO state are touched.

Small non-blocking suggestion: if future address derivation starts using a crypto library that raises a more specific exception than ValueError, this guard may need to catch that explicit exception too. For the current implementation, ValueError is the important path.

Local validation:
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 .venv/bin/python -m pytest tests/test_utxo_transfer_json_validation.py -q -> 6 passed.

Copy link
Copy Markdown
Contributor

@HuiNeng6 HuiNeng6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Observations:

  1. Line 454-458 (utxo_endpoints.py): Good defensive programming. Wrapping _addr_from_pk_fn(public_key) in try-except prevents ValueError from propagating to Flask's error handler and potentially returning a generic 500 error instead of a specific 400.

  2. Test coverage: The monkeypatch approach correctly simulates a ValueError from the address derivation function, ensuring the endpoint returns the expected 400 response.

  3. Security consideration: Consider whether ValueError is the only exception that _addr_from_pk_fn can raise — if the underlying crypto library raises different exceptions, those might slip through.

Assessment: Standard review

Disclosure: I received RTC compensation for this review.

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review completed. Thanks for contributing to RustChain! 🚀

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review completed. Thanks for contributing! 🚀

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Thanks for contributing to RustChain! 🦀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/S PR: 11-50 lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants