Skip to content

fix(net): improve block sync resilience and transaction handling - #7050

Merged
lvs0075 merged 6 commits into
tronprotocol:release_v4.8.3from
xxo1shine:fix/sync-block-failure-recovery
Oct 26, 2026
Merged

lvs0075 merged 6 commits into
tronprotocol:release_v4.8.3from
xxo1shine:fix/sync-block-failure-recovery

Conversation

@xxo1shine

@xxo1shine xxo1shine commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Release the global sync request on every block processing failure so another peer can supply the block without waiting for cache expiration. Disconnect only the sender and preserve other peers' queued blocks and sync progress.

Separate basic block validation from advertised-block witness checks. Check witness activity first and log and record inactive-witness blocks per connection. Apply the repeated-occurrence disconnect rule before timestamp, Merkle-root and signature validation; all blocks that pass that rule still undergo basic validation. Disconnect the sender with BAD_BLOCK only when another inactive-witness block arrives within half the current maintenance interval. A first occurrence, or one outside that interval, continues normal block processing. Keep advertisement recovery on the sync path and retain log-only handling for failures during advertised block application.

Unify block application errors as BAD_BLOCK while retaining their causes. Log P2P failure details without a stack trace and keep stack traces for unexpected sync failures.

Track permission-update owners when blocks are rolled back so cached transaction verification is invalidated. Clear transaction results before caching relay messages and omit full hash lists when transaction inventory is rate limited.

Remove the ret fields from transactions before broadcasting them to peers.

Remove the verbose log that prints the entire peer-provided transaction hash list when TRX inventory messages are dropped due to rate limiting.

Why are these changes required?

This PR has been tested by:

  • ./gradlew clean build -x test on ARM64 / JDK 17.
  • Focused tests: BlockFetchFailureTest, TronNetDelegateTest, BlockMsgHandlerTest, and BlockAlreadyKnownCounterTest (36 tests).
  • :framework:checkstyleMain, :framework:checkstyleTest, and :plugins:checkstyleMain.
  • Repository Math usage check.
  • Full unit suite and a new manual network run were not performed for this update.

Follow up

Extra details

wb added 2 commits October 20, 2026 14:09
Track permission-update owners when blocks are rolled back so cached transaction verification is invalidated. Clear transaction results before caching relay messages and omit full hash lists when transaction inventory is rate limited.
Release the global sync request on every block processing failure so
another peer can supply the block without waiting for cache expiration.
Disconnect only the sender and preserve other peers' queued blocks and
sync progress.

Reject advertised blocks whose witness is outside the active set instead
of silently dropping them. Keep advertisement recovery on the sync path
and retain log-only handling for failures during advertised block application.

Unify block application errors as BAD_BLOCK while retaining their causes.
Log P2P failure details without a stack trace and keep stack traces for
unexpected sync failures.
Clear results only on the transaction copy cached for relay. Keep the original capsule unchanged so broadcasting cannot erase pending execution results or race with block assembly.

@halibobo1205 halibobo1205 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.

LGTM.

Before merge: CI last ran before #7035 landed, so a re-run on the current base would be good. This also conflicts with #7005 in BlockMsgHandler, and the two PRs handle inactive-witness blocks and failed fetch retries differently, so whichever lands second needs a behaviour decision, not just a rebase.

Comment on lines +365 to +368
if (!witnessScheduleStore.getActiveWitnesses().contains(block.getWitnessAddress())) {
throw new P2pException(TypeEnum.BAD_BLOCK,
"Block witness is not active: " + block.getBlockId().getString());
}

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.

This confilcts with PR #7005. Please drop these changes.

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.

We've already discussed and resolved the conflict with PR #7005. Thanks!

wb added 2 commits October 26, 2026 17:30
Avoid disconnecting a peer for a single inactive-witness block. Separate
basic block validation from advertised-block witness checks, record the
last inactive-witness block time per connection, and disconnect only on
a repeat within half the current maintenance interval.

Log every inactive-witness occurrence before applying the disconnect
condition. Keep timestamp, Merkle-root and signature validation ahead of
the witness check and allow isolated occurrences to continue processing.
Apply the advertised-block witness activity and repeat-offense checks
before basic block validation. Log inactive-witness occurrences before
rejecting repeats, and retain timestamp, Merkle-root and signature checks
for every response that passes the witness check.
Return the advertised-block validation result and stop processing blocks from inactive witnesses before synchronization or relay. Preserve basic block validation and the existing disconnect policy for repeated inactive-witness blocks.
@lvs0075
lvs0075 merged commit d7df62b into tronprotocol:release_v4.8.3 Oct 26, 2026
10 checks passed
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.

4 participants