fix(block): validate witnesses against candidate-parent state

Closed
FE
19d ago
+995-100

What does this PR do?

Validate external block witness signatures in Manager after establishing the candidate-parent state, for both direct application and fork switching. Defer competing branches until validation is possible, and forward blocks only after successful validation.

Propagate application results to broadcast and synchronization handlers, support retrying signature variants, and avoid blaming a child provider for an invalid ancestor. The database and network changes are coupled through the new block-processing result and signature-failure attribution.

At most four normalized witness signatures are retained per deferred block; overflow requests resynchronization without disconnecting the provider. The Khaos graph node is preserved, and its block is replaced only after candidate-parent signature validation. Already-applied blocks no longer repeat application metrics or broadcasts.

Why are these changes required?

Ingress verification currently reads local state that may differ from the candidate-parent state. This can accept stale signatures or reject valid competing branches after witness-key rotation or strict-ECDSA activation.

Related: https://github.com/Federico2014/java-tron/issues/59

This PR has been tested by:

  • ./gradlew clean build -x test passed on x86_64 / JDK 8.
  • ./gradlew :framework:checkstyleMain :framework:checkstyleTest :plugins:checkstyleMain passed.
  • bash .github/scripts/check_math_usage.sh and git diff --check passed.
  • Focused framework regressions passed: 60 tests across BlockWitnessParentStateTest, ManagerSignaturePreValidationTest, ManagerStrictEcdsaActivationTest, TronNetDelegateTest, BlockAlreadyKnownCounterTest, BlockMsgHandlerTest, SyncServiceTest and KhaosDatabaseTest, run with --max-workers=2. Coverage includes both signature-arrival orders on broadcast and synchronization, bounded signature alternatives and cleanup, duplicate handling, and rejection of signed blocks from an unscheduled witness.
  • Full ./gradlew test was reattempted and stopped after five timeout failures: two DbBackfillBloomTest cases, two RocksDB DbLite cases and StatusLifecycleTest.statusFirstRemainsAValidProbe. These plugin/P2P files are unchanged by this PR. Full-suite success is not established; failures have not been checked against the base branch.

Follow up

Complete multi-node convergence testing and measure validation and propagation costs.

Extra details

Consensus and compatibility risk: this changes block-acceptance decisions around witness-permission updates and strict-ECDSA activation. Mixed-version nodes may disagree on blocks previously accepted using stale state or rejected before candidate-parent validation. Historical replay compatibility must also be verified.

Broadcasting now waits for successful block application, which may increase propagation latency. Deferred-branch handling and synchronization retries require load and convergence testing.

No dependency, configuration or database schema changes. Coordinated rollout or activation gating must be assessed before deployment; safe rolling-upgrade compatibility has not yet been established.


Summary by cubic

Validates witness signatures against the candidate-parent state instead of the current local state, fixing acceptance of stale signatures and rejection of valid competing branches after witness-key rotation or strict-ECDSA activation.

  • Signature checks move from ingress to Manager after the candidate-parent state is established, for both direct application and fork switching.
  • Unverifiable competing branches are deferred until validation is possible, and blocks are broadcast only after successful application.
  • Adds BlockPushResult and BlockSignatureException to distinguish deferred, applied, and invalid blocks, and avoids blaming a peer for an invalid ancestor block.