Skip to content

feat(crypto): add proposal-gated ECDSA validation - #49

Open
Federico2014 wants to merge 2 commits into
developfrom
feature/strict-ecdsa-validation
Open

feat(crypto): add proposal-gated ECDSA validation#49
Federico2014 wants to merge 2 commits into
developfrom
feature/strict-ecdsa-validation

Conversation

@Federico2014

@Federico2014 Federico2014 commented Aug 5, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

This PR tightens fresh RPC and P2P ECDSA signature admission to exactly 65 bytes and introduces proposal-gated strict consensus validation for transaction and block-witness signatures. Strict mode validates the encoded length, normalized recovery ID, and r/s scalar bounds before elliptic-curve recovery, preserves high-S signatures, and uses BigIntegers.modOddInverse for valid modular inverses.

It adds proposal 99 (ALLOW_STRICT_ECDSA_VALIDATION) and block version 4.8.3 support for one-way activation. When the proposal becomes active during maintenance processing, cached transaction verification results are invalidated across the pending, re-push, popped, and pushing queues. Block verification reuses a pending result only when the cached capsule is explicitly verified and its signatures match.

Transaction signature validation and cache invalidation are synchronized per TransactionCapsule, with isVerified published through a volatile field. This prevents an in-flight legacy validation from restoring isVerified=true after activation invalidation, without serializing validation of different transactions on a global lock.

Why are these changes required?

Padded and malformed ECDSA signatures create non-canonical encodings and may reach expensive or failure-prone elliptic-curve operations. Proposal-gated consensus activation preserves historical compatibility while allowing the network to enforce strict validation for post-activation blocks and transactions.

A successful verification cache entry is valid only for the rule set under which it was computed. Invalidating and coordinating cached results at the activation boundary ensures that a transaction accepted under legacy rules cannot bypass strict validation when it is later considered for block inclusion.

This PR has been tested by:

  • Unit Tests:
    • ./gradlew :framework:test --tests org.tron.core.capsule.TransactionCapsuleTest --tests org.tron.common.crypto.ECKeyTest
    • Targeted tests for WalletMockTest, ProposalUtilTest, BlockCapsuleTest, ManagerMockTest, ManagerTest, TransactionsMsgHandlerTest, and ProposalServiceTest
    • Coverage includes the activation/validation overlap, signature lengths, r/s values 0, n, and n+1, invalid wire recovery values, invalid compact headers and recovery IDs, and valid high-S signatures.
  • Checkstyle:
    • ./gradlew :framework:checkstyleMain
    • ./gradlew :framework:checkstyleTest
  • Manual Testing: Not performed.

Follow up

Coordinate the final TIP review, release version, and proposal activation schedule before enabling proposal 99.

Extra details

Related TIP draft: Federico2014/tips#2

Compatibility:

  • Fresh RPC, P2P, and relay admission requires exactly 65-byte signatures independently of proposal activation.
  • Consensus validation retains legacy behavior before activation and applies strict validation after activation.
  • Historical padded signatures remain verifiable, and read-only signature-weight and approved-list APIs remain legacy-compatible.
  • The new dynamic property defaults to disabled; no database migration is required.

Consensus upgrade: all block-producing and validating nodes must run a release containing this change before proposal 99 is activated.

Cross-module impact: crypto validation, chainbase state, proposal processing, admission checks, and transaction-cache lifecycle changes share one activation boundary and must be deployed together.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds fork-gated strict ECDSA validation. It stores activation state through a proposal, enforces 65-byte signatures and recovery bounds, applies strict checks to blocks and transactions, and invalidates cached verification states after activation.

Changes

Strict ECDSA validation

Layer / File(s) Summary
Activation contract and dynamic property
common/src/main/java/org/tron/core/config/Parameter.java, actuator/src/main/java/org/tron/core/utils/ProposalUtil.java, chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java, framework/src/main/java/org/tron/core/consensus/ProposalService.java, framework/src/main/java/org/tron/core/Wallet.java, framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java, framework/src/test/java/org/tron/core/services/ProposalServiceTest.java
Adds fork version VERSION_4_8_3, proposal type 99, proposal validation, dynamic-property storage, proposal processing, chain-parameter exposure, and activation tests.
Strict signature and recovery primitives
common/src/main/java/org/tron/core/Constant.java, crypto/src/main/java/org/tron/common/crypto/ECKey.java, crypto/src/main/java/org/tron/common/crypto/SignUtils.java, framework/src/test/java/org/tron/common/crypto/ECKeyTest.java
Requires exact 65-byte signatures in strict mode and validates recovery IDs, r, s, message hashes, and modular inversion. Existing permissive overloads remain available.
Block and transaction validation
chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java, chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java, framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java, framework/src/test/java/org/tron/core/capsule/TransactionCapsuleTest.java, framework/src/test/java/org/tron/core/WalletMockTest.java, framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java
Passes the strict-validation setting through witness and transaction signature validation. Tests update padded-signature handling and invalid component rejection.
Verification cache invalidation
framework/src/main/java/org/tron/core/db/Manager.java, framework/src/test/java/org/tron/core/db/ManagerMockTest.java, framework/src/test/java/org/tron/core/db/ManagerTest.java
Revalidates unverified transactions and clears verification flags across pending, repush, popped, and pushing collections when strict validation activates.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ProposalService
  participant DynamicPropertiesStore
  participant Manager
  participant TransactionCapsule
  participant ECKey
  ProposalService->>DynamicPropertiesStore: save strict validation value
  Manager->>DynamicPropertiesStore: detect activation at maintenance boundary
  Manager->>TransactionCapsule: clear verified state
  TransactionCapsule->>ECKey: validate signatures in strict mode
  ECKey-->>TransactionCapsule: accept or reject recovered signature
Loading

Possibly related issues

  • Federico2014/tips#2 — Covers governance-activated strict ECDSA validation, 65-byte enforcement, recovery checks, and modular inverse handling.

Possibly related PRs

Suggested reviewers: halibobo1205

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the proposal-gated strict ECDSA validation added by the pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/strict-ecdsa-validation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@framework/src/main/java/org/tron/core/db/Manager.java`:
- Around line 1924-1930: Update the transaction verification cache used by
pushTransaction and validateSignature to bind each cached result to the strict
ECDSA activation state or validation epoch, and revalidate whenever it does not
match the current state. Ensure an in-flight legacy validation cannot restore a
cache entry usable after activation, while preserving normal cache reuse within
the same state. Add an overlap test covering legacy validation blocked until
activation completes.

In `@framework/src/test/java/org/tron/core/WalletMockTest.java`:
- Around line 212-217: Gate strict signature-length validation on the shared
EC-key and dynamic-property activation condition. In
framework/src/test/java/org/tron/core/WalletMockTest.java:212-217, explicitly
test strict validation disabled and enabled, preserving legacy handling before
activation and expecting SIGERROR after activation; update
Wallet.broadcastTransaction accordingly. In
framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java:405-421,
add the same off/on coverage, preserving legacy P2P handling before activation
and expecting BAD_TRX after activation; gate the P2P validation path with the
same condition.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 14f8d709-6824-4aa8-aed3-17684f6258b4

📥 Commits

Reviewing files that changed from the base of the PR and between c2e1eea and 307fb5c.

📒 Files selected for processing (20)
  • actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
  • chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java
  • chainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.java
  • chainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.java
  • common/src/main/java/org/tron/core/Constant.java
  • common/src/main/java/org/tron/core/config/Parameter.java
  • crypto/src/main/java/org/tron/common/crypto/ECKey.java
  • crypto/src/main/java/org/tron/common/crypto/SignUtils.java
  • framework/src/main/java/org/tron/core/Wallet.java
  • framework/src/main/java/org/tron/core/consensus/ProposalService.java
  • framework/src/main/java/org/tron/core/db/Manager.java
  • framework/src/test/java/org/tron/common/crypto/ECKeyTest.java
  • framework/src/test/java/org/tron/core/WalletMockTest.java
  • framework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.java
  • framework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.java
  • framework/src/test/java/org/tron/core/capsule/TransactionCapsuleTest.java
  • framework/src/test/java/org/tron/core/db/ManagerMockTest.java
  • framework/src/test/java/org/tron/core/db/ManagerTest.java
  • framework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.java
  • framework/src/test/java/org/tron/core/services/ProposalServiceTest.java
💤 Files with no reviewable changes (1)
  • common/src/main/java/org/tron/core/Constant.java

Comment thread framework/src/main/java/org/tron/core/db/Manager.java
Comment thread framework/src/test/java/org/tron/core/WalletMockTest.java

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

All reported issues were addressed across 20 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread framework/src/main/java/org/tron/core/db/Manager.java
Comment thread crypto/src/main/java/org/tron/common/crypto/SignUtils.java
Comment thread framework/src/test/java/org/tron/core/capsule/TransactionCapsuleTest.java Outdated
Comment thread actuator/src/main/java/org/tron/core/utils/ProposalUtil.java
@Federico2014
Federico2014 force-pushed the feature/strict-ecdsa-validation branch from 307fb5c to f0483b0 Compare August 5, 2026 10:07
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant