fix(txpool): add EIP-2 signature malleability check and unify tx hash computation#17
Open
wpank wants to merge 1 commit into
Open
fix(txpool): add EIP-2 signature malleability check and unify tx hash computation#17wpank wants to merge 1 commit into
wpank wants to merge 1 commit into
Conversation
… computation Add EIP-2 low-s signature validation to reject transactions with high-s values, preventing transaction malleability attacks where an observer can create a second valid transaction with a different hash from any pending transaction. Also unify hash computation across both insertion paths (validator and Mempool::insert) to use the canonical Ethereum tx hash via envelope.tx_hash() instead of divergent keccak256 encodings. Closes #195, #197 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes two critical security issues in the transaction pool:
EIP-2 signature malleability (closes #195): The validator accepted ECDSA signatures with high
svalues, allowing an observer to take any valid pending transaction and produce a second valid transaction with a different hash but the same sender and nonce. This pollutes the mempool and breaks hash-based transaction identity. The fix adds anormalize_s()check afterSignature::from_slice()to reject signatures wheresis in the upper half of the secp256k1 curve order.Inconsistent tx hash computation (closes #197): The
Mempool::insert()path computed the transaction hash askeccak256(raw_2718_bytes)while the validator path computed it askeccak256(rlp_encode(envelope)). Neither is the canonical Ethereum transaction hash (keccak256(encode_2718(envelope))), and the mismatch meant the same transaction inserted via different paths would have different hashes in the pool'sby_hashmap, bypassing duplicate detection. Both paths now useenvelope.tx_hash()which returns the canonical hash.Additionally fixes a pre-existing compile error where
rejection_reason()was missing match arms forGasLimitTooHighandInitcodeTooLargeerror variants, and removes the now-unusedalloy-rlpdependency.Changes
crates/node/txpool/src/validator.rs: Add EIP-2 low-s check, use canonicaltx_hash(), remove unusedkeccak256importcrates/node/txpool/src/pool.rs: Use canonicaltx_hash()intx_to_ordered(), add missing match arms inrejection_reason()crates/node/txpool/Cargo.toml: Remove unusedalloy-rlpdependencyTest plan
k256::ecdsa::SigningKey::sign_prehash_recoverablewhich produces low-s signatures by default)recover_sender_and_hash()Mempool::insert()and validatorvalidate()produce the same hash for the same transaction🤖 Generated with Claude Code