Skip to content

feat(crypto): add strict ECDSA validation - #7001

Open
Federico2014 wants to merge 23 commits into
tronprotocol:release_v4.8.3from
Federico2014:feature/strict-ecdsa-validation-v4.8.3
Open

Federico2014 wants to merge 23 commits into
tronprotocol:release_v4.8.3from
Federico2014:feature/strict-ecdsa-validation-v4.8.3

Conversation

@Federico2014

@Federico2014 Federico2014 commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

  • Add proposal 100 (ALLOW_STRICT_ECDSA_VALIDATION), gated by block version 39, to enable strict ECDSA recovery for transaction consensus verification, witness verification, and the affected TVM signature precompiles. Strict recovery checks scalar bounds and recovery inputs and rejects point-at-infinity public keys.
  • Accept 65–68 bytes per signature at transaction admission and auxiliary-query entry points. Auxiliary queries and fast-forward HELLO authentication also use strict ECDSA recovery upon upgrade, independently of proposal activation.
  • Validate P2P signature lengths in TransactionsMsgHandler.check() before removing any request entries or submitting normal or smart-contract tasks. After the existing duplicate-ID, unsolicited-transaction, and missing-contract checks pass, the first transaction containing a signature outside 65–68 bytes rejects the entire response batch with BAD_TRX; the P2P handler disconnects the peer with BAD_TX. Outstanding requests remain available to AdvService.onDisconnect() for retry against other announcers or fetch-cache invalidation when no alternative exists.
  • Expose a shared Prometheus rejection counter with fixed source and reason labels. P2P validation increments it once for the first invalid-length transaction detected in a rejected batch, then stops checking that batch. API broadcast increments it once for a transaction rejected for invalid signature length. Multiple invalid signatures in the detected transaction still contribute only one count.
  • Trim witness-signature trailing bytes during P2P block sanitization, including historical synchronization, while checking the original block size before trimming.
  • Invalidate queued transaction verification caches on activation and require verified pending transactions before reusing their results.
  • Handle failed address recovery explicitly in ValidateMultiSign, normalize component-based SignUtils recovery failures to SignatureException, and remove unused ECKey overloads. Remove the four-argument TransactionCapsule.checkWeight overload so callers select the recovery mode explicitly. Move the test-only permission-aware signing logic out of TransactionCapsule.addSign into TransactionUtils.addTransactionSign under framework/src/test; it uses explicit strict recovery for existing signatures and delegates signing to TransactionCapsule.sign.

Why are these changes required?

Malformed signatures and unused trailing bytes can produce inconsistent validation or unnecessary storage and response costs. The proposal controls consensus recovery changes so that legacy recovery remains available before activation. Separate admission, query, and HELLO policies take effect upon software upgrade and therefore require client and peer migration before deployment.

RPC broadcast already rejects signatures outside 65–68 bytes. A peer forwarding a transaction outside that admission range is treated as misbehaving and disconnected. Rejecting the response batch before request cleanup lets the existing disconnect handler recover every outstanding item, including fetching a valid signature variant with the same txID from another announcer. This avoids leaving rejected IDs blocked in the fetch cache. Rejected signatures are not repaired or forwarded; accepted 66–68-byte transaction signatures retain their original bytes.

The shared rejection counter makes signature-length admission failures observable for both peer traffic and API broadcasts when Prometheus metrics are enabled, including during client migration.

Related TIP: tronprotocol/tips#935

This PR has been tested by:

  • Latest head 9933f7071d: Checkstyle and PR Lint, check-math, and single-node smoke passed. The multi-platform PR Build is still in progress as of this update.
  • Local helper-cleanup validation: TransactionCapsuleTest, WalletTest, TransactionUtilsTest, and all six existing shielded-transaction call sites passed: 68 tests passed, 1 skipped. This includes rejecting an unauthorized signing key. ./gradlew clean build -x test, the CI Checkstyle command, and the Math-usage check also passed. These local checks preceded the rebase onto the updated release branch; the helper-cleanup patch was unchanged by the rebase.
  • Earlier revision 07f7b077cd passed PR Build: Rocky Linux and Debian 11 on JDK 8 / x86_64, Ubuntu 24 and macOS 26 on JDK 17 / aarch64, Coverage Base, and Coverage Gate. Single-node smoke, Checkstyle and PR Lint, and check-math also passed.
  • Regression coverage includes 65–68-byte acceptance, invalid-length batch rejection before either P2P dispatch path, preserved outstanding requests, BAD_TX disconnection, retry against an available or busy announcer, and fetch-cache invalidation when no alternative exists. Counter tests cover the first-invalid-transaction P2P contract, API rejection counts, multisign transactions, cumulative counts, source separation, structural-check precedence, and metrics-disabled behavior.
  • Additional coverage includes strict and legacy ECKey/SignUtils recovery, query and HELLO policy, transaction and witness validation, witness sanitization, activation/cache invalidation and rollback, TVM signature precompiles, and configuration wiring. Activation fixtures cover legacy rules in maintenance block H and strict rules from H+1, including the accepted 65–68-byte range and rejection of longer signatures after activation.
  • A full local test run was stopped after HTTP/2, database-tool and gRPC timeout failures outside the edited files; a full local-suite pass is not claimed. Full historical replay, multi-node activation, and mixed-version deployment validation remain open.

Follow up

  • Complete full DPoS maintenance and multi-node activation validation. Manager-level activation/cache, rollback, in-flight validation, and store-to-VM configuration coverage have been added; their scoped fixtures do not establish end-to-end rollout behavior.
  • Complete database-persistence, full historical-replay, and end-to-end propagation validation. Existing witness and HELLO tests cover handler boundaries; they do not establish full replay or persistence behavior.
  • Complete affected-client measurements, migration notices, the migration deadline, and mixed-version rollout validation before deployment, including P2P batch rejection, peer disconnection, and outstanding-request recovery under both proposal states.
  • Publish the removed APIs and migration guidance in release notes, including exception handling and rebuilding affected callers.
  • Expand SignUtils.isValidLength javadoc with the named consensus callers; it currently describes the accepted range and governance-controlled consensus usage.
  • Track authoritative witness validation against the candidate parent state in a separate change, as discussed in TIP-935; this PR does not resolve the existing preliminary Head-state validation limitation.

Extra details

Consensus upgrade boundary

Proposal 100 (ALLOW_STRICT_ECDSA_VALIDATION) becomes available only after the block-version-39 fork gate (VERSION_4_8_3) passes. Passing that gate does not itself enable strict ECDSA validation; the proposal must also be approved and processed at maintenance. If maintenance block H activates the proposal, H is validated and its transactions executed under the pre-activation rules, and strict consensus rules apply from H+1.

Activation-time block capacity: Activating proposal 100 invalidates cached signature-verification results for queued transactions. Transactions selected from these queues for the first post-activation block (H+1) must be verified again under the strict rules. This extra work consumes the existing block-production time budget, so H+1 may contain significantly fewer transactions than usual. The size and duration of this temporary capacity reduction depend on the queued workload and node performance; any remaining backlog can also affect subsequent blocks.

Before activation, SRs and validating FullNodes must upgrade to a release containing this implementation, targeted for v4.8.3. Nodes that retain legacy validation can disagree with upgraded nodes on the validity of affected blocks after activation. The admission, auxiliary-query, HELLO and witness-normalization changes take effect on software upgrade, so their migration schedule must precede enforcement and must not wait for proposal activation. The entry-point table below describes these separate boundaries; the outstanding candidate-parent witness-validation limitation remains listed under Follow up.

The activation boundary differs by entry point:

Entry point Before proposal activation After proposal activation
RPC broadcast and P2P transaction admission 65–68 bytes on the upgraded node; legacy ECDSA recovery 65–68 bytes; strict ECDSA recovery
getTransactionSignWeight / getTransactionApprovedList 65–68 bytes; strict ECDSA recovery on upgrade Same
Fast-forward HELLO authentication 65–68 bytes; strict ECDSA recovery on upgrade Same
ECDSA transaction verification in blocks Legacy length/recovery behavior 65–68 bytes; strict recovery
P2P witness verification, including historical sync Trim trailing bytes to 65 first, then legacy recovery Trim trailing bytes to 65 first, then strict recovery
Affected TVM signature precompiles Legacy recovery Strict recovery

The release_v4.8.3 base supports ECKey only after removal of SM2/SM3. Recovery calls use the ECKey-only interfaces while preserving the proposal-controlled strict-validation flag; the 65–68-byte admission/query/HELLO policy remains effective upon software upgrade. TVM precompiles retain their existing input formats; the table describes their recovery mode rather than a uniform 65-byte ABI requirement. Strict transaction and direct witness validation accept 65–68-byte signatures after activation; the proposal does not impose an exact-65-byte restriction. P2P witness normalization still retains a 65-byte prefix before validation. Strict ECDSA recovery deliberately retains high-S acceptance (1 <= s < n) rather than introducing a low-S requirement (s <= n/2). This preserves legacy high-S acceptance and the precompiles' compatibility with Ethereum's ecrecover, which EIP-2 explicitly leaves accepting high-S signatures. TRON's txID excludes signatures, and TransactionCapsule.checkWeight deduplicates by recovered signer address after the VERSION_4_7_1 gate, so replacing s with n-s and flipping the corresponding recovery bit does not create a new txID or add signer weight. Signature-encoding malleability remains: complete serialized transaction bytes and their block Merkle leaves can differ. Low-S signing remains recommended, consistent with the recovery compatibility rationale in TIP-935.

TVM precompile signature-length compatibility

ValidateMultiSign and BatchValidateSign preserve their existing input formats in both legacy and strict recovery modes. Their shared recoverAddrBySign helper requires at least 65 bytes and recovers from the first 65 bytes; it deliberately does not apply the 65–68-byte limit used for outer transaction signatures. An otherwise valid longer byte array reaching this helper therefore retains the same prefix-recovery behavior after proposal activation. These signatures are contract call data. For a signed transaction, caller-supplied call data is included in raw_data and covered by the transaction signing hash, whereas outer Transaction.signature entries are excluded from that hash. This proposal preserves the existing precompile input behavior while changing recovery validation. validateComponents() already checks the r, s, and v bounds in legacy mode; the additional strict-recovery protection on this path rejects point-at-infinity public keys.

Transaction rejection observability

When Prometheus metrics are enabled, P2P and API broadcast admission share tron:tx_reject_total, with fixed labels source and reason. The reason is invalid_signature_length; the source is p2p or api:

  • P2P admission first completes the existing batch-level structural checks. It then stops at the first transaction with an out-of-range signature and increments the source="p2p" series by one, before throwing BAD_TRX. The entire response batch is rejected and the peer is disconnected with BAD_TX. The counter records the first detected invalid transaction; it does not count the batch size or any additional invalid transactions later in that batch.
  • Wallet.broadcastTransaction() increments the source="api" series by one before returning SIGERROR for an invalid signature length. This common entry point covers gRPC broadcast and HTTP broadcasttransaction / broadcasthex.

Multiple invalid signatures in the detected transaction contribute one count. Repeated rejected submissions count as separate rejection events; the counter does not deduplicate transaction IDs. Structural failures for duplicate IDs, unsolicited transactions, or missing contracts are checked before signature lengths and do not increment this counter. Other API rejection reasons, auxiliary queries, and HELLO authentication are also outside this metric. Passing the length check does not imply that a transaction passes subsequent validation.

Both labels have fixed values; peer addresses and transaction IDs are not metric labels. Disabling metrics preserves the same rejection, API response, disconnection, and request-recovery behavior.

Deployment readiness and release notes

The target enforcing node release is v4.8.3. The exact published node builds, affected client/SDK versions, migration deadline and mixed-version validation results are not established by this PR description. Before deployment:

  • Publish the enforcing node versions and the supported or migrated client/SDK and custom-peer versions, including the 65–68-byte signature requirements that take effect on upgrade.
  • Collect recent padded-signature usage measurements, stating the observation period, traffic scope and signature-length distribution. Rejection counters on upgraded nodes help monitor enforcement but do not by themselves establish fleet-wide client migration readiness.
  • Notify affected operators, client maintainers and archive/index consumers; publish a concrete migration deadline before enforcement, with instructions for producing signatures within 65–68 bytes (canonical 65-byte output remains recommended) and adapting query/error handling.
  • Record mixed-version propagation and synchronization results, including padded-transaction handling before and after proposal activation. These deployment checks remain pending; existing handler tests do not replace them.
  • Publish release notes covering all removed Java APIs and constants and their replacements/rebuild requirements listed under Compatibility; RPC broadcast and auxiliary-query response changes; and witness-signature normalization, which preserves block IDs but can change complete serialized block bytes in storage, synchronization and RPC responses. Include the activation-time transaction-capacity impact described below.

Release note: first block after proposal activation

When proposal 100 (ALLOW_STRICT_ECDSA_VALIDATION) takes effect at maintenance block H, cached signature-verification results for queued transactions are cleared. Transactions from those queues must be verified again under the new rules before inclusion. The first block after activation (H+1) may therefore contain significantly fewer transactions than usual, because re-verification consumes part of the block-production time budget. Operators should account for a temporary reduction in transaction throughput at activation; its magnitude and duration depend on the queued workload and node performance.

Compatibility

  • Transaction clients and relay peers: Upgraded admission entry points accept 65–68-byte signatures, preserving the existing 66–68-byte compatibility range. RPC broadcast returns SIGERROR for invalid lengths. P2P ingress completes the existing structural checks and then validates signature lengths in check(). A length failure rejects the entire response batch before any request is removed or transaction is queued, and triggers a BAD_TX disconnect. AdvService.onDisconnect() requeues outstanding items advertised by other active peers, or invalidates their fetch-cache entries when no alternative exists; an available announcer can be fetched immediately, while a busy announcer waits for the existing fetch scheduler. This peer policy takes effect on upgrade, independently of proposal activation. Transaction signatures are never truncated. Otherwise valid transactions with 66–68-byte signatures continue to propagate with their original bytes. Clients and custom relay peers producing signatures outside the range or relying on recovery rejected by the new rules must migrate before enforcement.
  • Auxiliary queries and signature-weight helpers: Both getTransactionSignWeight and getTransactionApprovedList validate original signature lengths after the existing signature-count limit check and before hashing or recovery. Length-error responses use SIGNATURE_FORMAT_ERROR and omit the transaction extension instead of rewriting signatures. They also reject ECDSA signatures that fail strict recovery before proposal activation. The Wallet query entry points call the five-argument TransactionCapsule.checkWeight directly with strictEcdsaValidation=true; consensus callers continue to supply the governance-controlled mode. Query validation can therefore be stricter than pre-activation consensus validation.
  • Fast-forward peers: HELLO authentication accepts 65–68 bytes and strict ECDSA recovery upon upgrade. The standard java-tron HELLO signing path meets these requirements; custom peers producing signatures outside 65–68 bytes or signatures rejected by strict recovery must migrate before upgrading.
  • Block archives and RPC consumers: P2P sanitization trims only witness-signature trailing bytes and preserves the retained 65-byte prefix. A padded witness signature can still pass ingress, even after activation, if that prefix is valid; transaction signatures are not truncated because their complete bytes contribute to txTrieRoot, even though txID excludes signatures. The block ID and signed raw-header digest remain unchanged, but the complete serialized block bytes stored or returned by RPC can differ between an older stored copy and a newly synchronized copy of the same block. Existing database records are not bulk-rewritten. Archive/index consumers comparing complete protobuf bytes must account for this normalization and use the block ID for identity.
  • Transaction utility and query migration: TransactionUtil.truncateSignatures(Transaction) is removed without a deprecated wrapper, breaking downstream source and binary compatibility. For standalone length validation, apply public SignUtils.isValidLength(signature.size()) to each original signature and reject values outside 65–68 bytes without rewriting them. Signature-weight queries previously using TransactionUtil.getTransactionSignWeight(Transaction) must use public Wallet.getTransactionSignWeight(Transaction); approved-list queries use Wallet.getTransactionApprovedList(Transaction). These Wallet entry points perform their own length checks. Wallet.validateSignatureLengths(Transaction) is private and is not a public replacement API; callers must handle query result codes rather than invoke that helper. Existing binaries referencing removed or relocated utility methods must be updated and rebuilt.
  • Removed TransactionCapsule APIs: The four-argument checkWeight(Permission, List<ByteString>, byte[], List<ByteString>) and addSign(byte[], AccountStore) are removed without deprecated wrappers, breaking downstream source and binary compatibility. Use the five-argument checkWeight with an explicit strictEcdsaValidation value: true for strict recovery or false when legacy recovery is intentionally required. addSign had only a test utility caller; its permission and duplicate-signer checks now live in TransactionUtils.addTransactionSign under framework/src/test, which is not a production replacement API. TransactionCapsule.sign(byte[]) remains available to append a signature but does not perform those permission checks. Downstream callers relying on addSign must retain the required checks in their own signing flow and rebuild.
  • Removed ECKey overloads: signatureToKeyBytes(byte[], ECDSASignature), signatureToAddress(byte[], ECDSASignature), and signatureToKey(byte[], String) are removed without deprecated wrappers, breaking downstream source and binary compatibility. These convenience overloads have no remaining in-repository callers and are intentionally removed as selective API cleanup. Removing the two-argument signatureToKey overload is not required by strict recovery; it removes an unused implicit-mode entry point and requires migrated callers to select their recovery mode explicitly. Use the corresponding three-argument overload with strictValidation=false to retain legacy recovery, or true for strict recovery. The three-argument ECKey.recoverPubBytesFromSignature(int, ECDSASignature, byte[]) is also removed; use its four-argument overload with an explicit strictValidation value. This is not a uniform removal policy for all legacy overloads: the two-argument string-based signatureToAddress remains used by PBFT paths in PbftBaseMessage and PbftDataSyncHandler, whose validation behavior is unchanged by this PR. The surviving two-argument string overloads of signatureToAddress and signatureToKeyBytes continue to default to legacy recovery.
  • SignUtils recovery migration and exceptions: Both two-argument SignUtils.signatureToAddress overloads, for Base64 strings and ECDSASignature objects, are removed. Use the corresponding three-argument overload and pass strictEcdsaValidation explicitly: true selects strict recovery, and false retains legacy recovery for callers that intentionally need it. The component-based overload wraps runtime recovery failures as SignatureException with the original cause in both modes; existing checked SignatureException instances pass through that wrapper. Callers relying on an unchecked exception type must adjust their handling. Direct ECKey calls retain their own exception behavior and the surviving implicit-legacy overloads described above.
  • Signature-length helper: SignUtils.isValidLength(int) checks the inclusive 65–68-byte range; it does not select a recovery mode or read governance state. Upgraded admission, HELLO, and auxiliary-query paths apply it independently of proposal activation. TransactionCapsule.checkWeight, BlockCapsule.validateSignature, and Manager.validateTransactionSignatureLengths also reuse it for strict consensus validation, with the applicable strict-validation mode selected by their callers or dynamic properties. Legacy consensus retains its existing minimum-length checks and padded-signature compatibility. Only the five-argument checkWeight remains: Wallet queries and the test signing utility pass true, while consensus callers supply the governance-controlled mode explicitly.
  • Length constants: Constant.PER_SIGN_LENGTH (65) and Constant.MAX_PER_SIGN_LENGTH (68) are retained. SignUtils.isValidLength() checks this inclusive range for admission, queries, HELLO, and proposal-controlled strict consensus validation. Recovery interprets the first 65 bytes while accepted transaction signatures retain their original trailing bytes.
  • Chain-parameter response: getChainParameters adds getAllowStrictEcdsaValidation. Consumers that assume a fixed parameter list must accept this additional entry.

Comment thread actuator/src/main/java/org/tron/core/utils/TransactionUtil.java Outdated
Comment thread actuator/src/main/java/org/tron/core/utils/TransactionUtil.java
Comment thread framework/src/main/java/org/tron/core/net/service/relay/RelayService.java Outdated
Comment thread common/src/main/java/org/tron/core/Constant.java
Comment thread crypto/src/main/java/org/tron/common/crypto/SignUtils.java Outdated
Comment thread chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java
Comment thread chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java
@Federico2014
Federico2014 force-pushed the feature/strict-ecdsa-validation-v4.8.3 branch from 4bca8c9 to 8f787f0 Compare October 8, 2026 14:56
Merge the latest release_v4.8.3 updates while preserving TVM storage optimization at proposal 99 and fork version 38. Move strict ECDSA validation to proposal 100 and fork version 39, retain both governance flags, and verify independent activation and VM snapshot restoration.
@github-actions
github-actions Bot requested a review from 3for October 9, 2026 03:03
Comment on lines +191 to +192
boolean strictEcdsaValidation = CommonParameter.getInstance().isECKeyCryptoEngine()
&& dynamicPropertiesStore.allowStrictEcdsaValidation();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[SHOULD] Revalidate the witness signature after the parent-block state is established

BlockMsgHandler.processBlock() verifies the witness signature before acquiring blockLock, so the proposal activation state may differ from the state when the block is actually applied.

For example, block B may pass verification under the old rules while its parent block A is still being processed. After A activates strict signature validation, B can be applied without revalidation in Manager.processBlock(), potentially causing inconsistent block acceptance between broadcast and synchronization paths.

Suggested fix: Revalidate the witness signature at the beginning of Manager.processBlock(), where the lock is already held and the parent-block state is established:

if (!block.generatedByMyself
    && !block.validateSignature(getDynamicPropertiesStore(), getAccountStore())) {
  throw new ValidateSignatureException(
      "block " + block.getNum() + " signature invalid");
}

Please also add a regression test covering B passing preliminary verification under the old rules but being rejected after A activates strict validation.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@3for Revalidation in Manager.processBlock() would catch stale successful checks, but it cannot address valid blocks already rejected by network-layer checks using the wrong permission or branch state. It also adds another witness-signature verification on the serialized block-application path.

sanitize() already mitigates the signature-length difference between legacy and strict rules. The remaining scalar-bound and point-at-infinity cases do not arise from normal SR signing and primarily concern deliberately crafted signatures.

I suggest handling this in a separate PR: move authoritative state-dependent validation into Manager after the correct parent state is established, with corresponding changes to synchronization, broadcasting, caching, and peer attribution. This would address both stale acceptance and premature rejection while avoiding duplicate witness verification.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[MUST] Final witness validation must use the candidate parent's state.

Broadcast ingress validates the witness signature before acquiring blockLock; the direct-chain application path does not revalidate it. A 65-byte legacy-only signature (e.g. the infinity-recovery case documented in TIP-935) can therefore pass preliminary validation before parent H activates strict mode, then reach application under strict rules. Synchronization validates inside the lock and would reject that signature. Witness-prefix normalization does not remove this mode difference.

Please perform authoritative validation for externally received blocks after establishing the candidate-parent state, with deterministic broadcast/sync activation-boundary tests. Also address preliminary Head-state rejection of valid legacy candidates; if that part is deferred, please obtain explicit agreement on the remaining limitation and link a dedicated tracking issue.

@Federico2014
Federico2014 force-pushed the feature/strict-ecdsa-validation-v4.8.3 branch from 436f3a6 to a72b84e Compare October 10, 2026 07:37
Comment thread crypto/src/main/java/org/tron/common/crypto/ECKey.java
@Federico2014
Federico2014 force-pushed the feature/strict-ecdsa-validation-v4.8.3 branch from c53f315 to 3f529d5 Compare October 12, 2026 03:58
Merge release_v4.8.3 while preserving strict ECDSA proposal 100 and
CLOSE_EXCHANGE proposal 101, including their validation and query paths.

Reset the shared version-39 voting fixture between proposal tests and
adapt signature-batch mocks to the boolean transaction admission result.
Comment thread actuator/src/main/java/org/tron/core/utils/TransactionUtil.java Outdated

@lxcmyf lxcmyf left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[MUST] The transaction refetch-cache issue identified in the inline thread blocks this change: rejecting an invalid-signature variant must not suppress fetching a valid transaction with the same ID.

Comment thread chainbase/src/main/java/org/tron/core/capsule/BlockCapsule.java
Comment thread crypto/src/main/java/org/tron/common/crypto/ECKey.java Outdated
Comment thread crypto/src/main/java/org/tron/common/crypto/SignUtils.java Outdated
Comment thread crypto/src/main/java/org/tron/common/crypto/SignUtils.java Outdated
@Federico2014
Federico2014 force-pushed the feature/strict-ecdsa-validation-v4.8.3 branch from 48ff91a to 8238004 Compare October 16, 2026 05:48
@lxcmyf

lxcmyf commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

[SHOULD] Please align the PR description, metric contract, and migration guidance with the current head. Invalid-length P2P input now rejects the entire batch and disconnects the peer, while the description still says per-transaction discard without disconnect; the counter records only the first invalid transaction, and the compatibility section points callers to TransactionUtil.validateSignatureLengths(), which is no longer public.

@Federico2014

Copy link
Copy Markdown
Collaborator Author

@lxcmyf Updated the PR description to match the current head: invalid signature lengths reject the entire P2P batch and disconnect the peer, and the P2P counter increments once for the first invalid transaction detected.

Migration guidance now points to public SignUtils.isValidLength() and Wallet query APIs instead of the private helper. The test and CI evidence has also been refreshed.

Comment thread actuator/src/main/java/org/tron/core/vm/config/ConfigLoader.java Outdated
@Federico2014
Federico2014 force-pushed the feature/strict-ecdsa-validation-v4.8.3 branch from a5e7939 to 705d103 Compare October 19, 2026 07:31
Preserve strict signature-weight queries in Wallet and carry over the upstream contract-count validation. Adapt query tests to allow contract inspection while still forbidding serialization before signature rejection, and cover contract-check precedence.
@Federico2014
Federico2014 force-pushed the feature/strict-ecdsa-validation-v4.8.3 branch from 9933f70 to 98d74da Compare October 20, 2026 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

9 participants