diff --git a/cmd/indexer/main.go b/cmd/indexer/main.go index 93aa69a..8d5c159 100644 --- a/cmd/indexer/main.go +++ b/cmd/indexer/main.go @@ -170,8 +170,8 @@ func runIndexer(chains []string, configPath string, debug, manual, catchup, from // If no chains specified, use all configured chains if len(chains) == 0 { - chains = cfg.Chains.Names() - logger.Info("No chains specified, using all configured chains", "chains", chains) + chains = cfg.Chains.EnabledNames() + logger.Info("No chains specified, using enabled configured chains", "chains", chains) } else { logger.Info("Indexing specified chains", "chains", chains) } diff --git a/configs/config.example.yaml b/configs/config.example.yaml index 8b9e6dc..81fa271 100644 --- a/configs/config.example.yaml +++ b/configs/config.example.yaml @@ -4,6 +4,7 @@ version: "1.0.0" # Global defaults - applies to all chains unless overridden defaults: + enabled: false # chains inherit this unless they override enabled below from_latest: true # start indexing from the latest block poll_interval: "5s" # how often to poll for new blocks reorg_rollback_window: 20 # number of blocks to roll back on reorg @@ -47,6 +48,7 @@ chains: slow_max_pending_blocks: 400 ethereum_mainnet: + enabled: true # example override: this chain starts even when defaults.enabled is false network_id: "ethereum_mainnet" internal_code: "ETH_MAINNET" type: "evm" diff --git a/pkg/common/config/chains.go b/pkg/common/config/chains.go index 505e032..ce81537 100644 --- a/pkg/common/config/chains.go +++ b/pkg/common/config/chains.go @@ -31,6 +31,17 @@ func (c Chains) Names() []string { return names } +// EnabledNames returns chain names whose enabled flag is either true or omitted. +func (c Chains) EnabledNames() []string { + names := make([]string, 0, len(c)) + for k, chain := range c { + if chain.Enabled == nil || *chain.Enabled { + names = append(names, k) + } + } + return names +} + // Validate checks if given chain names exist in config. func (c Chains) Validate(names []string) error { for _, name := range names { @@ -60,6 +71,10 @@ func (c Chains) ApplyDefaults(def Defaults) error { if strings.TrimSpace(chain.InternalCode) == "" { chain.InternalCode = strings.ToUpper(name) } + if chain.Enabled == nil && def.Enabled != nil { + enabled := *def.Enabled + chain.Enabled = &enabled + } if !chain.FromLatest { chain.FromLatest = def.FromLatest } diff --git a/pkg/common/config/chains_test.go b/pkg/common/config/chains_test.go index fb9fea3..0e65cee 100644 --- a/pkg/common/config/chains_test.go +++ b/pkg/common/config/chains_test.go @@ -36,3 +36,91 @@ func TestApplyDefaults_MergesStatusThresholds(t *testing.T) { require.Equal(t, uint64(30), chain.Status.HealthyMaxPendingBlocks) require.Equal(t, uint64(120), chain.Status.SlowMaxPendingBlocks) } + +func TestApplyDefaults_AppliesEnabledDefaultWhenOmitted(t *testing.T) { + t.Parallel() + + enabled := false + chains := Chains{ + "ethereum_mainnet": { + Type: enum.NetworkTypeEVM, + PollInterval: time.Second, + Nodes: []NodeConfig{{URL: "https://example.com"}}, + }, + } + + err := chains.ApplyDefaults(Defaults{ + Enabled: &enabled, + PollInterval: time.Second, + ReorgRollbackWindow: 20, + }) + require.NoError(t, err) + + require.NotNil(t, chains["ethereum_mainnet"].Enabled) + require.False(t, *chains["ethereum_mainnet"].Enabled) +} + +func TestApplyDefaults_PreservesExplicitEnabledValue(t *testing.T) { + t.Parallel() + + defaultEnabled := false + chainEnabled := true + chains := Chains{ + "ethereum_mainnet": { + Enabled: &chainEnabled, + Type: enum.NetworkTypeEVM, + PollInterval: time.Second, + Nodes: []NodeConfig{{URL: "https://example.com"}}, + }, + } + + err := chains.ApplyDefaults(Defaults{ + Enabled: &defaultEnabled, + PollInterval: time.Second, + ReorgRollbackWindow: 20, + }) + require.NoError(t, err) + + require.NotNil(t, chains["ethereum_mainnet"].Enabled) + require.True(t, *chains["ethereum_mainnet"].Enabled) +} + +func TestEnabledNames_DefaultsToEnabledWhenOmitted(t *testing.T) { + t.Parallel() + + disabled := false + chains := Chains{ + "ethereum_mainnet": { + Type: enum.NetworkTypeEVM, + Nodes: []NodeConfig{{URL: "https://example.com"}}, + }, + "tron_mainnet": { + Enabled: &disabled, + Type: enum.NetworkTypeTron, + Nodes: []NodeConfig{{URL: "https://example.com"}}, + }, + } + + require.ElementsMatch(t, []string{"ethereum_mainnet"}, chains.EnabledNames()) +} + +func TestEnabledNames_IncludesExplicitlyEnabledChains(t *testing.T) { + t.Parallel() + + enabled := true + disabled := false + chains := Chains{ + "ethereum_mainnet": { + Enabled: &enabled, + Type: enum.NetworkTypeEVM, + Nodes: []NodeConfig{{URL: "https://example.com"}}, + }, + "tron_mainnet": { + Enabled: &disabled, + Type: enum.NetworkTypeTron, + Nodes: []NodeConfig{{URL: "https://example.com"}}, + }, + } + + require.ElementsMatch(t, []string{"ethereum_mainnet"}, chains.EnabledNames()) +} diff --git a/pkg/common/config/types.go b/pkg/common/config/types.go index 510c102..fd41a7c 100644 --- a/pkg/common/config/types.go +++ b/pkg/common/config/types.go @@ -28,6 +28,7 @@ type Config struct { } type Defaults struct { + Enabled *bool `yaml:"enabled"` FromLatest bool `yaml:"from_latest"` TwoWayIndexing bool `yaml:"two_way_indexing"` PollInterval time.Duration `yaml:"poll_interval" validate:"required"` @@ -42,6 +43,7 @@ type Chains map[string]ChainConfig type ChainConfig struct { Name string `yaml:"-"` + Enabled *bool `yaml:"enabled"` NetworkId string `yaml:"network_id"` InternalCode string `yaml:"internal_code"` NativeDenom string `yaml:"native_denom"`