Skip to content

drop proofs and headers received too late in the next round#7804

Open
sstanculeanu wants to merge 14 commits intofeat/testnet-fixesfrom
round-boundaries-on-interceptor
Open

drop proofs and headers received too late in the next round#7804
sstanculeanu wants to merge 14 commits intofeat/testnet-fixesfrom
round-boundaries-on-interceptor

Conversation

@sstanculeanu
Copy link
Copy Markdown
Collaborator

Reasoning behind the pull request

Proposed changes

Testing procedure

Pre-requisites

Based on the Contributing Guidelines the PR author and the reviewers must check the following requirements are met:

  • was the PR targeted to the correct branch?
  • if this is a larger feature that probably needs more than one PR, is there a feat branch created?
  • if this is a feat branch merging, do all satellite projects have a proper tag inside go.mod?

@sstanculeanu sstanculeanu self-assigned this Mar 27, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 27, 2026

Codecov Report

❌ Patch coverage is 95.16129% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.56%. Comparing base (7caded5) to head (03df0bc).

Files with missing lines Patch % Lines
...de/chainSimulator/components/manualRoundHandler.go 0.00% 2 Missing ⚠️
...rceptors/factory/interceptedTrieNodeDataFactory.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@                    Coverage Diff                     @@
##           feat/supernova-async-exec    #7804   +/-   ##
==========================================================
  Coverage                      77.56%   77.56%           
==========================================================
  Files                            882      882           
  Lines                         123719   123752   +33     
==========================================================
+ Hits                           95958    95987   +29     
- Misses                         21402    21407    +5     
+ Partials                        6359     6358    -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread process/track/baseBlockTrack.go Outdated

currentRoundStart := bbt.roundHandler.TimeStamp()
roundDuration := float64(bbt.roundHandler.TimeDuration())
maxTimeToAcceptProof := time.Duration(roundDuration + roundDuration*receivedProofDelay)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
maxTimeToAcceptProof := time.Duration(roundDuration + roundDuration*receivedProofDelay)
maxTimeToAcceptProof := time.Duration(currentRoundStart + roundDuration*receivedProofDelay)

it should be based on start round time, right?

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.

no, max time parameter is the total amount of time (900 ms in this case), as RemainingTime is called with currentRoundStart

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

aa, right

Comment on lines +2400 to +2406
RemainingTimeCalled: func(startTime time.Time, maxTime time.Duration) time.Duration {
currentTime := time.Now()
elapsedTime := currentTime.Sub(startTime)
remainingTime := maxTime - elapsedTime

return remainingTime
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

can we use real RemainingTime method from round handler?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maybe use real round handler, and call UpdateRound several times to set the desired index (with lower test values)

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.

that should work too, tried to keep it simple

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR attempts to enforce a time window for accepting “next round” headers/proofs, so that items received too late are dropped, and wires round timing data through the process.RoundHandler interface to support that logic.

Changes:

  • Extend process.RoundHandler with TimeStamp() and RemainingTime(...) to support time-window validation.
  • Add a time-window check in baseBlockTrack.checkAgainstRoundHandler.
  • Update mocks and add a unit test intended to cover the “too-late” rejection behavior.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
process/track/baseBlockTrack.go Adds time-window rejection logic for headers/proofs based on round timing.
process/track/baseBlockTrack_test.go Updates round handler setup in tests and adds a new “invalid window” test.
process/mock/rounderMock.go Extends the process mock to support RemainingTime injection via callback.
process/interface.go Extends process.RoundHandler with timestamp and remaining-time methods.
integrationTests/testProcessorNode.go Updates integration-test round handler mock initialization for new interface expectations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2414 to +2416
// wait until after half of the next round passed
timeToSleep := roundDuration + time.Duration(float64(roundDuration)*0.6)
time.Sleep(timeToSleep)
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

The test relies on real time (time.Sleep) to cross the acceptance window, which makes the suite slower and can be flaky under CI scheduling variance. Prefer a deterministic approach (e.g., set RoundTimeStamp far enough in the past or have RemainingTimeCalled return a controlled negative value) so the test doesn’t depend on wall-clock timing.

Copilot uses AI. Check for mistakes.
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.

should work

Comment thread process/track/baseBlockTrack.go Outdated
Comment thread process/track/baseBlockTrack.go Outdated
Comment on lines +502 to +509
roundDuration := float64(bbt.roundHandler.TimeDuration())
maxTimeToAcceptProof := time.Duration(roundDuration + roundDuration*receivedProofDelay)
timeLeftToAcceptProof := bbt.roundHandler.RemainingTime(currentRoundStart, maxTimeToAcceptProof)
if timeLeftToAcceptProof <= 0 {
return fmt.Errorf("%w header round: %d, current round timestamp: %d, time left to accept proof: %d",
process.ErrHigherRoundInBlock,
round,
currentRoundStart.UnixMilli(),
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

The new time-window check is effectively inert with the real consensus/round implementation: RemainingTime(TimeStamp(), 1.5*TimeDuration) will stay >0 because TimeStamp() is updated each round and elapsed is always < TimeDuration(). As a result, headers/proofs won’t actually be dropped “when received too late in the next round”. Consider basing the window on the received item’s round (e.g., compute the start timestamp of that round and enforce acceptance only for the first receivedProofDelay fraction of it), or otherwise use a start time that doesn’t reset every round when validating next-round items.

Suggested change
roundDuration := float64(bbt.roundHandler.TimeDuration())
maxTimeToAcceptProof := time.Duration(roundDuration + roundDuration*receivedProofDelay)
timeLeftToAcceptProof := bbt.roundHandler.RemainingTime(currentRoundStart, maxTimeToAcceptProof)
if timeLeftToAcceptProof <= 0 {
return fmt.Errorf("%w header round: %d, current round timestamp: %d, time left to accept proof: %d",
process.ErrHigherRoundInBlock,
round,
currentRoundStart.UnixMilli(),
roundDuration := bbt.roundHandler.TimeDuration()
maxTimeToAcceptProof := time.Duration(float64(roundDuration) * (1 + receivedProofDelay))
roundDiff := int64(round) - int64(bbt.roundHandler.Index())
itemRoundStart := currentRoundStart.Add(time.Duration(roundDiff) * roundDuration)
timeLeftToAcceptProof := bbt.roundHandler.RemainingTime(itemRoundStart, maxTimeToAcceptProof)
if timeLeftToAcceptProof <= 0 {
return fmt.Errorf("%w header round: %d, item round timestamp: %d, time left to accept proof: %d",
process.ErrHigherRoundInBlock,
round,
itemRoundStart.UnixMilli(),

Copilot uses AI. Check for mistakes.
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.

fixed

Comment thread process/track/baseBlockTrack.go Outdated
Comment on lines +502 to +503
roundDuration := float64(bbt.roundHandler.TimeDuration())
maxTimeToAcceptProof := time.Duration(roundDuration + roundDuration*receivedProofDelay)
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

maxTimeToAcceptProof is built via float64(time.Duration) arithmetic. Converting durations to float can introduce precision/rounding issues and is harder to reason about. Prefer pure time.Duration math (e.g., derive the extra window using integer arithmetic or a rational numerator/denominator) so the acceptance window is exact and overflow-safe.

Suggested change
roundDuration := float64(bbt.roundHandler.TimeDuration())
maxTimeToAcceptProof := time.Duration(roundDuration + roundDuration*receivedProofDelay)
roundDuration := bbt.roundHandler.TimeDuration()
extraWindow := time.Duration(float64(roundDuration.Nanoseconds()) * receivedProofDelay)
maxTimeToAcceptProof := roundDuration + extraWindow

Copilot uses AI. Check for mistakes.
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.

should be ok

@AdoAdoAdo AdoAdoAdo self-requested a review March 30, 2026 13:39
AdoAdoAdo
AdoAdoAdo previously approved these changes Mar 30, 2026
Comment thread process/track/baseBlockTrack.go Outdated
timeLeftToAcceptProof := bbt.roundHandler.RemainingTime(roundTimestamp, maxTimeToAcceptProof)
if timeLeftToAcceptProof <= 0 {
return fmt.Errorf("%w header round: %d, current round timestamp: %d, time left to accept proof: %d",
process.ErrHigherRoundInBlock,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maybe use another error? this one might be misleading.

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.

updated

Base automatically changed from feat/supernova-async-exec to rc/supernova April 6, 2026 07:58
@sstanculeanu sstanculeanu changed the base branch from rc/supernova to feat/testnet-fixes April 6, 2026 12:33
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