Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Refetch latest da height instead of da height +1 when P2P is offline [#3201](https://github.com/evstack/ev-node/pull/3201)
- Fix race on startup sync. [#3162](https://github.com/evstack/ev-node/pull/3162)
- Strict raft state. [#3167](https://github.com/evstack/ev-node/pull/3167)
- Retry fetching the timestamp on error in da-client [#3166](https://github.com/evstack/ev-node/pull/3166)
Expand Down
7 changes: 6 additions & 1 deletion block/internal/syncing/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,12 @@ func (s *Syncer) initializeState() error {

// Set DA height to the maximum of the genesis start height, the state's DA height, and the cached DA height.
// The cache's DaHeight() is initialized from store metadata, so it's always correct even after cache clear.
s.daRetrieverHeight.Store(max(s.genesis.DAStartHeight, s.cache.DaHeight(), state.DAHeight))
// Only use cache.DaHeight() when P2P is actively syncing (headerStore has higher height than current state).
daHeight := max(s.genesis.DAStartHeight, min(state.DAHeight-1, 0))
if s.headerStore != nil && s.headerStore.Height() > state.LastBlockHeight {
daHeight = max(daHeight, s.cache.DaHeight())
}
s.daRetrieverHeight.Store(daHeight)

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.

makes sense

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.

⚠️ Potential issue | 🔴 Critical

Critical: min(state.DAHeight-1, 0) always evaluates to 0, ignoring the stored DA height.

The expression min(state.DAHeight-1, 0) will always return 0 when state.DAHeight >= 1 because min(positive_value, 0) is 0. This makes line 359 effectively equivalent to:

daHeight := max(s.genesis.DAStartHeight, 0) // state.DAHeight is ignored

This contradicts the PR objective of refetching DA height - 1. The intent appears to be using max to clamp the underflow, not min.

🐛 Proposed fix to correctly compute DA height - 1 with underflow protection
 	// Set DA height to the maximum of the genesis start height, the state's DA height, and the cached DA height.
 	// The cache's DaHeight() is initialized from store metadata, so it's always correct even after cache clear.
 	// Only use cache.DaHeight() when P2P is actively syncing (headerStore has higher height than current state).
-	daHeight := max(s.genesis.DAStartHeight, min(state.DAHeight-1, 0))
+	var daHeight uint64
+	if state.DAHeight > 0 {
+		daHeight = state.DAHeight - 1
+	}
+	daHeight = max(s.genesis.DAStartHeight, daHeight)
 	if s.headerStore != nil && s.headerStore.Height() > state.LastBlockHeight {
 		daHeight = max(daHeight, s.cache.DaHeight())
 	}
 	s.daRetrieverHeight.Store(daHeight)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@block/internal/syncing/syncer.go` around lines 358 - 363, The computed
daHeight uses min(state.DAHeight-1, 0) which always yields 0 for non-negative DA
heights; change this to clamp the underflow instead by using
max(state.DAHeight-1, 0) so the line becomes daHeight :=
max(s.genesis.DAStartHeight, max(state.DAHeight-1, 0)); update the expression in
syncer.go (referencing daHeight, s.genesis.DAStartHeight, state.DAHeight,
s.cache.DaHeight(), s.headerStore.Height(), and s.daRetrieverHeight.Store) and
ensure any necessary type conversions are applied so the subtraction and
comparison do not underflow for unsigned types.


s.logger.Info().
Uint64("height", state.LastBlockHeight).
Expand Down
Loading