feat(crypto): add proposal-gated ECDSA validation - #49
Conversation
📝 WalkthroughWalkthroughThe 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. ChangesStrict ECDSA validation
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
Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (20)
actuator/src/main/java/org/tron/core/utils/ProposalUtil.javachainbase/src/main/java/org/tron/core/capsule/BlockCapsule.javachainbase/src/main/java/org/tron/core/capsule/TransactionCapsule.javachainbase/src/main/java/org/tron/core/store/DynamicPropertiesStore.javacommon/src/main/java/org/tron/core/Constant.javacommon/src/main/java/org/tron/core/config/Parameter.javacrypto/src/main/java/org/tron/common/crypto/ECKey.javacrypto/src/main/java/org/tron/common/crypto/SignUtils.javaframework/src/main/java/org/tron/core/Wallet.javaframework/src/main/java/org/tron/core/consensus/ProposalService.javaframework/src/main/java/org/tron/core/db/Manager.javaframework/src/test/java/org/tron/common/crypto/ECKeyTest.javaframework/src/test/java/org/tron/core/WalletMockTest.javaframework/src/test/java/org/tron/core/actuator/utils/ProposalUtilTest.javaframework/src/test/java/org/tron/core/capsule/BlockCapsuleTest.javaframework/src/test/java/org/tron/core/capsule/TransactionCapsuleTest.javaframework/src/test/java/org/tron/core/db/ManagerMockTest.javaframework/src/test/java/org/tron/core/db/ManagerTest.javaframework/src/test/java/org/tron/core/net/messagehandler/TransactionsMsgHandlerTest.javaframework/src/test/java/org/tron/core/services/ProposalServiceTest.java
💤 Files with no reviewable changes (1)
- common/src/main/java/org/tron/core/Constant.java
There was a problem hiding this comment.
All reported issues were addressed across 20 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
307fb5c to
f0483b0
Compare
|
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. |
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/sscalar bounds before elliptic-curve recovery, preserves high-S signatures, and usesBigIntegers.modOddInversefor 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, withisVerifiedpublished through a volatile field. This prevents an in-flight legacy validation from restoringisVerified=trueafter 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:
./gradlew :framework:test --tests org.tron.core.capsule.TransactionCapsuleTest --tests org.tron.common.crypto.ECKeyTestWalletMockTest,ProposalUtilTest,BlockCapsuleTest,ManagerMockTest,ManagerTest,TransactionsMsgHandlerTest, andProposalServiceTestr/svalues0,n, andn+1, invalid wire recovery values, invalid compact headers and recovery IDs, and valid high-S signatures../gradlew :framework:checkstyleMain./gradlew :framework:checkstyleTestFollow 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:
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.