diff --git a/block/components.go b/block/components.go index 5a7f4a7493..5eb5855d28 100644 --- a/block/components.go +++ b/block/components.go @@ -150,7 +150,11 @@ func NewSyncComponents( blockOpts BlockOptions, raftNode common.RaftNode, ) (*Components, error) { - cacheManager, err := cache.NewManager(config, store, logger) + newCacheManager := cache.NewManager + if daClient == nil { + newCacheManager = cache.NewManagerWithoutDAInclusionRestore + } + cacheManager, err := newCacheManager(config, store, logger) if err != nil { return nil, fmt.Errorf("failed to create cache manager: %w", err) } diff --git a/block/components_test.go b/block/components_test.go index 310f383f56..d8ddc53ba2 100644 --- a/block/components_test.go +++ b/block/components_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/evstack/ev-node/block/internal/cache" coresequencer "github.com/evstack/ev-node/core/sequencer" "github.com/evstack/ev-node/pkg/config" datypes "github.com/evstack/ev-node/pkg/da/types" @@ -165,6 +166,62 @@ func TestNewSyncComponents_WithoutDA(t *testing.T) { assert.Nil(t, components.Submitter) } +func TestNewSyncComponents_WithoutDADoesNotRestoreDAInclusionCache(t *testing.T) { + daConfig := config.DefaultConfig() + daConfig.DA.Address = "ws://da.example.invalid" + require.True(t, daConfig.DAEnabled()) + + rootDir := t.TempDir() + database, err := store.NewDefaultKVStore(rootDir, "data", "ev-node") + require.NoError(t, err) + diskStore := store.New(store.NewEvNodeKVStore(database)) + + previousDAManager, err := cache.NewManager(daConfig, diskStore, zerolog.Nop()) + require.NoError(t, err) + previousDAManager.SetHeaderDAIncluded("persisted-da-header", 9001, 42) + previousDAManager.SetDataDAIncluded("persisted-da-data", 9001, 42) + require.NoError(t, previousDAManager.SaveToStore()) + require.NoError(t, diskStore.Close()) + + reopenedDatabase, err := store.NewDefaultKVStore(rootDir, "data", "ev-node") + require.NoError(t, err) + reopenedStore := store.New(store.NewEvNodeKVStore(reopenedDatabase)) + t.Cleanup(func() { + require.NoError(t, reopenedStore.Close()) + }) + + p2pConfig := config.DefaultConfig() + require.False(t, p2pConfig.DAEnabled()) + + components, err := NewSyncComponents( + p2pConfig, + genesis.Genesis{ + ChainID: "da-to-p2p-repro", + InitialHeight: 1, + StartTime: time.Now(), + ProposerAddress: []byte("test-proposer"), + }, + reopenedStore, + testmocks.NewMockExecutor(t), + nil, + extmocks.NewMockStore[*types.P2PSignedHeader](t), + extmocks.NewMockStore[*types.P2PData](t), + noopDAHintAppender{}, + noopDAHintAppender{}, + zerolog.Nop(), + NopMetrics(), + DefaultBlockOptions(), + nil, + ) + require.NoError(t, err) + require.Nil(t, components.Submitter) + + _, headerLoaded := components.Cache.GetHeaderDAIncludedByHeight(42) + _, dataLoaded := components.Cache.GetDataDAIncludedByHeight(42) + require.False(t, headerLoaded, "P2P-only startup must not restore persisted DA header state") + require.False(t, dataLoaded, "P2P-only startup must not restore persisted DA data state") +} + func TestNewAggregatorComponents_Creation(t *testing.T) { ds := sync.MutexWrap(datastore.NewMapDatastore()) memStore := store.New(ds) diff --git a/block/internal/cache/manager.go b/block/internal/cache/manager.go index 1581c66f9d..c2e2521baf 100644 --- a/block/internal/cache/manager.go +++ b/block/internal/cache/manager.go @@ -93,6 +93,15 @@ type implementation struct { // NewManager creates a new Manager, restoring or clearing persisted state as configured. func NewManager(cfg config.Config, st store.Store, logger zerolog.Logger) (Manager, error) { + return newManager(cfg, st, logger, true) +} + +// NewManagerWithoutDAInclusionRestore creates a Manager without restoring persisted DA inclusion state. +func NewManagerWithoutDAInclusionRestore(cfg config.Config, st store.Store, logger zerolog.Logger) (Manager, error) { + return newManager(cfg, st, logger, false) +} + +func newManager(cfg config.Config, st store.Store, logger zerolog.Logger, restoreDAInclusion bool) (Manager, error) { headerCache := NewCache(st, HeaderDAIncludedPrefix) dataCache := NewCache(st, DataDAIncludedPrefix) @@ -121,7 +130,7 @@ func NewManager(cfg config.Config, st store.Store, logger zerolog.Logger) (Manag if err := impl.ClearFromStore(); err != nil { logger.Warn().Err(err).Msg("failed to clear cache from disk, starting with empty cache") } - } else { + } else if restoreDAInclusion { // Restore existing cache from store if err := impl.RestoreFromStore(); err != nil { logger.Warn().Err(err).Msg("failed to load cache from disk, starting with empty cache")