diff --git a/internal/controller/node/plan_execution_test.go b/internal/controller/node/plan_execution_test.go index e304995..a04c53b 100644 --- a/internal/controller/node/plan_execution_test.go +++ b/internal/controller/node/plan_execution_test.go @@ -431,13 +431,16 @@ func TestConfigApply_UserOverridesTakePrecedence(t *testing.T) { } } -func TestConfigApply_NoOverridesYieldsNil(t *testing.T) { +func TestConfigApply_ReplayerDefaultOverrides(t *testing.T) { node := replayerNode() planner, _ := PlannerForNode(node, testSnapshotRegion) b, _ := planner.BuildTask(node, taskConfigApply) task := b.(sidecar.ConfigApplyTask) - if task.Intent.Overrides != nil { - t.Errorf("expected nil overrides when none specified, got %v", task.Intent.Overrides) + if task.Intent.Overrides[keyConcurrencyWorkers] != defaultConcurrencyWorkers { + t.Errorf("concurrency_workers = %q, want %q", task.Intent.Overrides[keyConcurrencyWorkers], defaultConcurrencyWorkers) + } + if _, ok := task.Intent.Overrides[keyPruning]; ok { + t.Errorf("replayer should not set pruning override (ModeArchive handles it), got %q", task.Intent.Overrides[keyPruning]) } } @@ -958,17 +961,63 @@ func TestConfigApply_StateSyncFieldsNotSet(t *testing.T) { } } -func TestConfigApply_FullNodeWithSnapshotGeneration(t *testing.T) { +func TestConfigApply_FullNodeSnapshotProducerProfile(t *testing.T) { node := snapshotNode() node.Spec.FullNode.SnapshotGeneration = &seiv1alpha1.SnapshotGenerationConfig{KeepRecent: 5} planner, _ := PlannerForNode(node, testSnapshotRegion) b, _ := planner.BuildTask(node, taskConfigApply) task := b.(sidecar.ConfigApplyTask) - if task.Intent.Overrides["storage.pruning"] != "nothing" { - t.Errorf("storage.pruning = %q", task.Intent.Overrides["storage.pruning"]) + checks := map[string]string{ + keyPruning: valCustom, + keyPruningKeepRecent: "50000", + keyPruningKeepEvery: "0", + keyPruningInterval: "10", + keyMinRetainBlocks: "50000", + keyConcurrencyWorkers: defaultConcurrencyWorkers, + keySnapshotInterval: "2000", + keySnapshotKeepRecent: "5", + } + for k, want := range checks { + if got := task.Intent.Overrides[k]; got != want { + t.Errorf("%s = %q, want %q", k, got, want) + } } - if task.Intent.Overrides["storage.snapshot_interval"] != "2000" { - t.Errorf("storage.snapshot_interval = %q", task.Intent.Overrides["storage.snapshot_interval"]) +} + +func TestConfigApply_FullNodeRPCProfile(t *testing.T) { + node := genesisNode() + node.Spec.Validator = nil + node.Spec.FullNode = &seiv1alpha1.FullNodeSpec{} + planner, _ := PlannerForNode(node, testSnapshotRegion) + b, _ := planner.BuildTask(node, taskConfigApply) + task := b.(sidecar.ConfigApplyTask) + checks := map[string]string{ + keyPruning: valCustom, + keyPruningKeepRecent: "86400", + keyPruningKeepEvery: "500", + keyPruningInterval: "10", + keyConcurrencyWorkers: defaultConcurrencyWorkers, + } + for k, want := range checks { + if got := task.Intent.Overrides[k]; got != want { + t.Errorf("%s = %q, want %q", k, got, want) + } + } + if _, ok := task.Intent.Overrides[keyMinRetainBlocks]; ok { + t.Errorf("RPC profile should not set min_retain_blocks (use ModeFull default)") + } +} + +func TestConfigApply_ArchiveDefaultOverrides(t *testing.T) { + node := snapshotterNode() + planner, _ := PlannerForNode(node, testSnapshotRegion) + b, _ := planner.BuildTask(node, taskConfigApply) + task := b.(sidecar.ConfigApplyTask) + if task.Intent.Overrides[keyConcurrencyWorkers] != defaultConcurrencyWorkers { + t.Errorf("concurrency_workers = %q, want %q", task.Intent.Overrides[keyConcurrencyWorkers], defaultConcurrencyWorkers) + } + if _, ok := task.Intent.Overrides[keyPruning]; ok { + t.Errorf("archive should not set pruning override (ModeArchive handles it), got %q", task.Intent.Overrides[keyPruning]) } } diff --git a/internal/controller/node/planner_archive.go b/internal/controller/node/planner_archive.go index 9d0d4d9..ecf17fa 100644 --- a/internal/controller/node/planner_archive.go +++ b/internal/controller/node/planner_archive.go @@ -47,11 +47,13 @@ func (p *archiveNodePlanner) buildConfigApply(node *seiv1alpha1.SeiNode) sidecar } func (p *archiveNodePlanner) controllerOverrides(node *seiv1alpha1.SeiNode) map[string]string { - overrides := make(map[string]string) + overrides := map[string]string{ + keyConcurrencyWorkers: defaultConcurrencyWorkers, + } sg := node.Spec.Archive.SnapshotGeneration if sg != nil { - overrides["storage.snapshot_interval"] = strconv.FormatInt(defaultSnapshotInterval, 10) - overrides["storage.snapshot_keep_recent"] = strconv.FormatInt(int64(sg.KeepRecent), 10) + overrides[keySnapshotInterval] = strconv.FormatInt(defaultSnapshotInterval, 10) + overrides[keySnapshotKeepRecent] = strconv.FormatInt(int64(sg.KeepRecent), 10) } return overrides } diff --git a/internal/controller/node/planner_full.go b/internal/controller/node/planner_full.go index 43c878b..bf10ac8 100644 --- a/internal/controller/node/planner_full.go +++ b/internal/controller/node/planner_full.go @@ -50,12 +50,22 @@ func (p *fullNodePlanner) buildConfigApply(node *seiv1alpha1.SeiNode) sidecar.Ta } func (p *fullNodePlanner) controllerOverrides(node *seiv1alpha1.SeiNode) map[string]string { - overrides := make(map[string]string) + overrides := map[string]string{ + keyConcurrencyWorkers: defaultConcurrencyWorkers, + keyPruning: valCustom, + keyPruningInterval: "10", + } + sg := node.Spec.FullNode.SnapshotGeneration if sg != nil { - overrides["storage.pruning"] = valNothing - overrides["storage.snapshot_interval"] = strconv.FormatInt(defaultSnapshotInterval, 10) - overrides["storage.snapshot_keep_recent"] = strconv.FormatInt(int64(sg.KeepRecent), 10) + overrides[keyPruningKeepRecent] = "50000" + overrides[keyPruningKeepEvery] = "0" + overrides[keyMinRetainBlocks] = "50000" + overrides[keySnapshotInterval] = strconv.FormatInt(defaultSnapshotInterval, 10) + overrides[keySnapshotKeepRecent] = strconv.FormatInt(int64(sg.KeepRecent), 10) + } else { + overrides[keyPruningKeepRecent] = "86400" + overrides[keyPruningKeepEvery] = "500" } return overrides } diff --git a/internal/controller/node/planner_replay.go b/internal/controller/node/planner_replay.go index dfd24ed..f6a3d96 100644 --- a/internal/controller/node/planner_replay.go +++ b/internal/controller/node/planner_replay.go @@ -41,9 +41,15 @@ func (p *replayerPlanner) BuildTask(node *seiv1alpha1.SeiNode, taskType string) return sidecar.ConfigApplyTask{ Intent: seiconfig.ConfigIntent{ Mode: seiconfig.ModeArchive, - Overrides: mergeOverrides(nil, node.Spec.Overrides), + Overrides: mergeOverrides(p.controllerOverrides(), node.Spec.Overrides), }, }, nil } return buildSharedTask(node, node.Spec.Replayer.Peers, &node.Spec.Replayer.Snapshot, taskType, p.snapshotRegion) } + +func (p *replayerPlanner) controllerOverrides() map[string]string { + return map[string]string{ + keyConcurrencyWorkers: defaultConcurrencyWorkers, + } +} diff --git a/internal/controller/node/task_builders.go b/internal/controller/node/task_builders.go index 81f10b1..2aae763 100644 --- a/internal/controller/node/task_builders.go +++ b/internal/controller/node/task_builders.go @@ -17,7 +17,21 @@ const ( resultExportRegion = "eu-central-1" resultExportPrefix = "shadow-results/" + // sei-config unified schema keys used by planner controllerOverrides. + keyConcurrencyWorkers = "chain.concurrency_workers" + keyMinRetainBlocks = "chain.min_retain_blocks" + keyPruning = "storage.pruning" + keyPruningKeepRecent = "storage.pruning_keep_recent" + keyPruningKeepEvery = "storage.pruning_keep_every" + keyPruningInterval = "storage.pruning_interval" + keySnapshotInterval = "storage.snapshot_interval" + keySnapshotKeepRecent = "storage.snapshot_keep_recent" + + valCustom = "custom" valNothing = "nothing" + + // Matches sei-infra production config across all node roles. + defaultConcurrencyWorkers = "500" ) // mergeOverrides combines controller-generated overrides with user-specified