From 7ca8de26584231ec238a71926846f89c2128b18c Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Tue, 24 Mar 2026 18:36:52 +0100 Subject: [PATCH 1/5] fix(syncer): refetch latest da height instead of da height +1 --- block/internal/syncing/syncer.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/block/internal/syncing/syncer.go b/block/internal/syncing/syncer.go index 3dcf80ea3..29c12ca11 100644 --- a/block/internal/syncing/syncer.go +++ b/block/internal/syncing/syncer.go @@ -355,7 +355,9 @@ 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)) + // state.DaHeight-1 if the latest DAHeight was containing more heights. + // s.daRetrieverHeight.Store(max(s.genesis.DAStartHeight, s.cache.DaHeight(), state.DAHeight-1)) + s.daRetrieverHeight.Store(max(s.genesis.DAStartHeight, state.DAHeight-1)) // TODO: s.cache.DaHeight() should only be used if p2p works. s.logger.Info(). Uint64("height", state.LastBlockHeight). From dbdd2cc2b5ac6e5fe9de9733a68e91354637d8f1 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 25 Mar 2026 11:04:30 +0100 Subject: [PATCH 2/5] wip --- block/internal/syncing/syncer.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/block/internal/syncing/syncer.go b/block/internal/syncing/syncer.go index 29c12ca11..d151bca55 100644 --- a/block/internal/syncing/syncer.go +++ b/block/internal/syncing/syncer.go @@ -355,9 +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. - // state.DaHeight-1 if the latest DAHeight was containing more heights. - // s.daRetrieverHeight.Store(max(s.genesis.DAStartHeight, s.cache.DaHeight(), state.DAHeight-1)) - s.daRetrieverHeight.Store(max(s.genesis.DAStartHeight, state.DAHeight-1)) // TODO: s.cache.DaHeight() should only be used if p2p works. + // Only use cache.DaHeight() when P2P is enabled, as it contains P2P-specific synchronization info. + daHeight := max(s.genesis.DAStartHeight, state.DAHeight-1) + if s.headerStore != nil { + daHeight = max(daHeight, s.cache.DaHeight()) + } + s.daRetrieverHeight.Store(daHeight) s.logger.Info(). Uint64("height", state.LastBlockHeight). From 5ec817806196ef24815b62c5291d747139c521e4 Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 25 Mar 2026 11:10:22 +0100 Subject: [PATCH 3/5] fixes --- block/internal/syncing/syncer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block/internal/syncing/syncer.go b/block/internal/syncing/syncer.go index d151bca55..dcc9acd2a 100644 --- a/block/internal/syncing/syncer.go +++ b/block/internal/syncing/syncer.go @@ -355,9 +355,9 @@ 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. - // Only use cache.DaHeight() when P2P is enabled, as it contains P2P-specific synchronization info. + // Only use cache.DaHeight() when P2P is actively syncing (headerStore has higher height than current state). daHeight := max(s.genesis.DAStartHeight, state.DAHeight-1) - if s.headerStore != nil { + if s.headerStore.Height() > state.LastBlockHeight { daHeight = max(daHeight, s.cache.DaHeight()) } s.daRetrieverHeight.Store(daHeight) From e5aae154e49271d18f0dee6d9e1b5e4a881c739a Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 25 Mar 2026 11:43:40 +0100 Subject: [PATCH 4/5] fix changelog and underflow --- CHANGELOG.md | 1 + block/internal/syncing/syncer.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24eaa6173..e6a17a0a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/block/internal/syncing/syncer.go b/block/internal/syncing/syncer.go index dcc9acd2a..136b22a5d 100644 --- a/block/internal/syncing/syncer.go +++ b/block/internal/syncing/syncer.go @@ -356,7 +356,7 @@ 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. // Only use cache.DaHeight() when P2P is actively syncing (headerStore has higher height than current state). - daHeight := max(s.genesis.DAStartHeight, state.DAHeight-1) + daHeight := max(s.genesis.DAStartHeight, min(state.DAHeight-1, 0)) if s.headerStore.Height() > state.LastBlockHeight { daHeight = max(daHeight, s.cache.DaHeight()) } From 37ee626db72c4d0891dd43ea4d92f054933da79d Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Wed, 25 Mar 2026 12:09:47 +0100 Subject: [PATCH 5/5] fix nil --- block/internal/syncing/syncer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/internal/syncing/syncer.go b/block/internal/syncing/syncer.go index 136b22a5d..a1b926725 100644 --- a/block/internal/syncing/syncer.go +++ b/block/internal/syncing/syncer.go @@ -357,7 +357,7 @@ func (s *Syncer) initializeState() error { // 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)) - if s.headerStore.Height() > state.LastBlockHeight { + if s.headerStore != nil && s.headerStore.Height() > state.LastBlockHeight { daHeight = max(daHeight, s.cache.DaHeight()) } s.daRetrieverHeight.Store(daHeight)