Skip to content

Commit 40ae193

Browse files
committed
refactor: config
1 parent c1f112b commit 40ae193

File tree

4 files changed

+53
-138
lines changed

4 files changed

+53
-138
lines changed

universalClient/config/config.go

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,6 @@ func validateConfig(cfg *Config, defaultCfg *Config) error {
4646
if cfg.MaxRetries == 0 && defaultCfg != nil {
4747
cfg.MaxRetries = defaultCfg.MaxRetries
4848
}
49-
if cfg.RetryBackoffSeconds == 0 && defaultCfg != nil {
50-
cfg.RetryBackoffSeconds = defaultCfg.RetryBackoffSeconds
51-
}
52-
53-
// Set defaults for startup config from default config
54-
if cfg.InitialFetchRetries == 0 && defaultCfg != nil {
55-
cfg.InitialFetchRetries = defaultCfg.InitialFetchRetries
56-
}
57-
if cfg.InitialFetchTimeoutSeconds == 0 && defaultCfg != nil {
58-
cfg.InitialFetchTimeoutSeconds = defaultCfg.InitialFetchTimeoutSeconds
59-
}
6049

6150
// Set defaults for registry config from default config
6251
if len(cfg.PushChainGRPCURLs) == 0 && defaultCfg != nil {
@@ -86,51 +75,14 @@ func validateConfig(cfg *Config, defaultCfg *Config) error {
8675
cfg.KeyringBackend = defaultCfg.KeyringBackend
8776
}
8877

89-
// Set defaults for event monitoring from default config
90-
if cfg.EventPollingIntervalSeconds == 0 && defaultCfg != nil {
91-
cfg.EventPollingIntervalSeconds = defaultCfg.EventPollingIntervalSeconds
92-
}
93-
94-
// Set defaults for transaction cleanup from default config
95-
if cfg.TransactionCleanupIntervalSeconds == 0 && defaultCfg != nil {
96-
cfg.TransactionCleanupIntervalSeconds = defaultCfg.TransactionCleanupIntervalSeconds
97-
}
98-
if cfg.TransactionRetentionPeriodSeconds == 0 && defaultCfg != nil {
99-
cfg.TransactionRetentionPeriodSeconds = defaultCfg.TransactionRetentionPeriodSeconds
100-
}
101-
102-
// Initialize ChainConfigs if nil or empty
103-
if (cfg.ChainConfigs == nil || len(cfg.ChainConfigs) == 0) && defaultCfg != nil {
78+
// Initialize ChainConfigs if empty
79+
if len(cfg.ChainConfigs) == 0 && defaultCfg != nil {
10480
cfg.ChainConfigs = defaultCfg.ChainConfigs
10581
}
10682

107-
// Set defaults for RPC pool config from default config
108-
if defaultCfg != nil {
109-
if cfg.RPCPoolConfig.HealthCheckIntervalSeconds == 0 {
110-
cfg.RPCPoolConfig.HealthCheckIntervalSeconds = defaultCfg.RPCPoolConfig.HealthCheckIntervalSeconds
111-
}
112-
if cfg.RPCPoolConfig.UnhealthyThreshold == 0 {
113-
cfg.RPCPoolConfig.UnhealthyThreshold = defaultCfg.RPCPoolConfig.UnhealthyThreshold
114-
}
115-
if cfg.RPCPoolConfig.RecoveryIntervalSeconds == 0 {
116-
cfg.RPCPoolConfig.RecoveryIntervalSeconds = defaultCfg.RPCPoolConfig.RecoveryIntervalSeconds
117-
}
118-
if cfg.RPCPoolConfig.MinHealthyEndpoints == 0 {
119-
cfg.RPCPoolConfig.MinHealthyEndpoints = defaultCfg.RPCPoolConfig.MinHealthyEndpoints
120-
}
121-
if cfg.RPCPoolConfig.RequestTimeoutSeconds == 0 {
122-
cfg.RPCPoolConfig.RequestTimeoutSeconds = defaultCfg.RPCPoolConfig.RequestTimeoutSeconds
123-
}
124-
if cfg.RPCPoolConfig.LoadBalancingStrategy == "" {
125-
cfg.RPCPoolConfig.LoadBalancingStrategy = defaultCfg.RPCPoolConfig.LoadBalancingStrategy
126-
}
127-
}
128-
129-
// Validate load balancing strategy
130-
if cfg.RPCPoolConfig.LoadBalancingStrategy != "" &&
131-
cfg.RPCPoolConfig.LoadBalancingStrategy != "round-robin" &&
132-
cfg.RPCPoolConfig.LoadBalancingStrategy != "weighted" {
133-
return fmt.Errorf("load balancing strategy must be 'round-robin' or 'weighted'")
83+
// Set NodeHome default
84+
if cfg.NodeHome == "" {
85+
cfg.NodeHome = constant.DefaultNodeHome
13486
}
13587

13688
// Set TSS defaults

universalClient/config/config_test.go

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ func TestConfigValidation(t *testing.T) {
3636
// Check that defaults were set
3737
assert.NotZero(t, cfg.ConfigRefreshIntervalSeconds)
3838
assert.NotZero(t, cfg.MaxRetries)
39-
assert.NotZero(t, cfg.RetryBackoffSeconds)
40-
assert.NotZero(t, cfg.InitialFetchRetries)
41-
assert.NotZero(t, cfg.InitialFetchTimeoutSeconds)
4239
assert.NotZero(t, cfg.QueryServerPort)
4340
assert.Equal(t, KeyringBackendTest, cfg.KeyringBackend) // Defaults to test when empty
4441
assert.NotEmpty(t, cfg.PushChainGRPCURLs)
@@ -57,9 +54,6 @@ func TestValidConfigScenarios(t *testing.T) {
5754
LogFormat: "json",
5855
ConfigRefreshIntervalSeconds: 30,
5956
MaxRetries: 5,
60-
RetryBackoffSeconds: 2,
61-
InitialFetchRetries: 3,
62-
InitialFetchTimeoutSeconds: 20,
6357
PushChainGRPCURLs: []string{"localhost:9090"},
6458
QueryServerPort: 8080,
6559
TSSP2PPrivateKeyHex: testTSSPrivateKeyHex,
@@ -93,11 +87,8 @@ func TestValidConfigScenarios(t *testing.T) {
9387
},
9488
validate: func(t *testing.T, cfg *Config) {
9589
// These should match the default config values
96-
assert.Equal(t, 60, cfg.ConfigRefreshIntervalSeconds) // Default is 10
90+
assert.Equal(t, 60, cfg.ConfigRefreshIntervalSeconds) // Default is 60
9791
assert.Equal(t, 3, cfg.MaxRetries)
98-
assert.Equal(t, 1, cfg.RetryBackoffSeconds)
99-
assert.Equal(t, 5, cfg.InitialFetchRetries)
100-
assert.Equal(t, 30, cfg.InitialFetchTimeoutSeconds)
10192
assert.Equal(t, []string{"localhost:9090"}, cfg.PushChainGRPCURLs)
10293
assert.Equal(t, 8080, cfg.QueryServerPort)
10394
},
@@ -225,9 +216,6 @@ func TestSaveAndLoad(t *testing.T) {
225216
LogFormat: "json",
226217
ConfigRefreshIntervalSeconds: 20,
227218
MaxRetries: 5,
228-
RetryBackoffSeconds: 2,
229-
InitialFetchRetries: 10,
230-
InitialFetchTimeoutSeconds: 60,
231219
PushChainGRPCURLs: []string{"localhost:9090", "localhost:9091"},
232220
QueryServerPort: 8888,
233221
TSSP2PPrivateKeyHex: testTSSPrivateKeyHex,
@@ -252,9 +240,6 @@ func TestSaveAndLoad(t *testing.T) {
252240
assert.Equal(t, cfg.LogFormat, loadedCfg.LogFormat)
253241
assert.Equal(t, cfg.ConfigRefreshIntervalSeconds, loadedCfg.ConfigRefreshIntervalSeconds)
254242
assert.Equal(t, cfg.MaxRetries, loadedCfg.MaxRetries)
255-
assert.Equal(t, cfg.RetryBackoffSeconds, loadedCfg.RetryBackoffSeconds)
256-
assert.Equal(t, cfg.InitialFetchRetries, loadedCfg.InitialFetchRetries)
257-
assert.Equal(t, cfg.InitialFetchTimeoutSeconds, loadedCfg.InitialFetchTimeoutSeconds)
258243
assert.Equal(t, cfg.PushChainGRPCURLs, loadedCfg.PushChainGRPCURLs)
259244
assert.Equal(t, cfg.QueryServerPort, loadedCfg.QueryServerPort)
260245
})
@@ -319,9 +304,6 @@ func TestConfigJSONMarshaling(t *testing.T) {
319304
LogFormat: "console",
320305
ConfigRefreshIntervalSeconds: 15,
321306
MaxRetries: 3,
322-
RetryBackoffSeconds: 1,
323-
InitialFetchRetries: 5,
324-
InitialFetchTimeoutSeconds: 30,
325307
PushChainGRPCURLs: []string{"host1:9090", "host2:9090"},
326308
QueryServerPort: 8080,
327309
}
@@ -340,9 +322,6 @@ func TestConfigJSONMarshaling(t *testing.T) {
340322
assert.Equal(t, cfg.LogFormat, unmarshaledCfg.LogFormat)
341323
assert.Equal(t, cfg.ConfigRefreshIntervalSeconds, unmarshaledCfg.ConfigRefreshIntervalSeconds)
342324
assert.Equal(t, cfg.MaxRetries, unmarshaledCfg.MaxRetries)
343-
assert.Equal(t, cfg.RetryBackoffSeconds, unmarshaledCfg.RetryBackoffSeconds)
344-
assert.Equal(t, cfg.InitialFetchRetries, unmarshaledCfg.InitialFetchRetries)
345-
assert.Equal(t, cfg.InitialFetchTimeoutSeconds, unmarshaledCfg.InitialFetchTimeoutSeconds)
346325
assert.Equal(t, cfg.PushChainGRPCURLs, unmarshaledCfg.PushChainGRPCURLs)
347326
assert.Equal(t, cfg.QueryServerPort, unmarshaledCfg.QueryServerPort)
348327
})

universalClient/config/default_config.json

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,15 @@
66
"push_chain_grpc_urls": [
77
"localhost:9090"
88
],
9+
"push_valoper_address": "pushvaloper1vzuw2x3k2ccme70zcgswv8d88kyc07grdpvw3e",
910
"tss_p2p_private_key_hex": "0101010101010101010101010101010101010101010101010101010101010101",
1011
"tss_password": "defaultpassword",
1112
"tss_p2p_listen": "/ip4/0.0.0.0/tcp/39000",
1213
"config_refresh_interval_seconds": 60,
1314
"max_retries": 3,
14-
"retry_backoff_seconds": 1,
15-
"initial_fetch_retries": 5,
16-
"initial_fetch_timeout_seconds": 30,
1715
"query_server_port": 8080,
1816
"keyring_backend": "test",
1917
"key_check_interval": 30,
20-
"event_polling_interval_seconds": 5,
21-
"database_base_dir": "",
22-
"transaction_cleanup_interval_seconds": 3600,
23-
"transaction_retention_period_seconds": 86400,
24-
"rpc_pool_config": {
25-
"health_check_interval_seconds": 30,
26-
"unhealthy_threshold": 3,
27-
"recovery_interval_seconds": 300,
28-
"min_healthy_endpoints": 1,
29-
"request_timeout_seconds": 10,
30-
"load_balancing_strategy": "round-robin"
31-
},
3218
"chain_configs": {
3319
"eip155:11155111": {
3420
"rpc_urls": [
@@ -37,6 +23,7 @@
3723
],
3824
"cleanup_interval_seconds": 1800,
3925
"retention_period_seconds": 43200,
26+
"event_polling_interval_seconds": 5,
4027
"gas_price_interval_seconds": 60,
4128
"event_start_from": 9084430
4229
},
@@ -46,6 +33,7 @@
4633
],
4734
"cleanup_interval_seconds": 1800,
4835
"retention_period_seconds": 43200,
36+
"event_polling_interval_seconds": 5,
4937
"gas_price_interval_seconds": 60,
5038
"event_start_from": 203887665
5139
},
@@ -55,6 +43,7 @@
5543
],
5644
"cleanup_interval_seconds": 1800,
5745
"retention_period_seconds": 43200,
46+
"event_polling_interval_seconds": 5,
5847
"gas_price_interval_seconds": 60,
5948
"event_start_from": 32257378
6049
},
@@ -64,6 +53,7 @@
6453
],
6554
"cleanup_interval_seconds": 1800,
6655
"retention_period_seconds": 43200,
56+
"event_polling_interval_seconds": 5,
6757
"gas_price_interval_seconds": 60,
6858
"event_start_from": 68905309
6959
},
@@ -73,8 +63,21 @@
7363
],
7464
"cleanup_interval_seconds": 7200,
7565
"retention_period_seconds": 172800,
66+
"event_polling_interval_seconds": 5,
7667
"gas_price_interval_seconds": 30,
7768
"event_start_from": 403697270
69+
},
70+
"push_42101-1": {
71+
"cleanup_interval_seconds": 1800,
72+
"retention_period_seconds": 43200,
73+
"event_polling_interval_seconds": 5,
74+
"event_start_from": 100000
75+
},
76+
"localchain_9000-1": {
77+
"cleanup_interval_seconds": 1800,
78+
"retention_period_seconds": 43200,
79+
"event_polling_interval_seconds": 5,
80+
"event_start_from": 100000
7881
}
7982
}
8083
}

universalClient/config/types.go

Lines changed: 29 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package config
22

3+
import "fmt"
4+
35
// KeyringBackend represents the type of keyring backend to use
46
type KeyringBackend string
57

@@ -17,36 +19,23 @@ type Config struct {
1719
LogFormat string `json:"log_format"` // "json" or "console"
1820
LogSampler bool `json:"log_sampler"` // if true, samples logs (e.g., 1 in 5)
1921

22+
// Node Config
23+
NodeHome string `json:"node_home"` // Node home directory (default: ~/.puniversal)
24+
2025
// Push Chain configuration
2126
PushChainID string `json:"push_chain_id"` // Push Chain chain ID (default: localchain_9000-1)
2227
PushChainGRPCURLs []string `json:"push_chain_grpc_urls"` // Push Chain gRPC endpoints (default: ["localhost:9090"])
28+
PushValoperAddress string `json:"push_valoper_address"` // Push Chain validator operator address (pushvaloper1...)
2329
ConfigRefreshIntervalSeconds int `json:"config_refresh_interval_seconds"` // How often to refresh configs in seconds (default: 60)
2430
MaxRetries int `json:"max_retries"` // Max retry attempts for registry queries (default: 3)
25-
RetryBackoffSeconds int `json:"retry_backoff_seconds"` // Initial retry backoff duration in seconds (default: 1)
26-
27-
// Startup configuration
28-
InitialFetchRetries int `json:"initial_fetch_retries"` // Number of retries for initial config fetch (default: 5)
29-
InitialFetchTimeoutSeconds int `json:"initial_fetch_timeout_seconds"` // Timeout per initial fetch attempt in seconds (default: 30)
3031

32+
// Query Server Config
3133
QueryServerPort int `json:"query_server_port"` // Port for HTTP query server (default: 8080)
3234

3335
// Keyring configuration
3436
KeyringBackend KeyringBackend `json:"keyring_backend"` // Keyring backend type (file/test)
3537
KeyringPassword string `json:"keyring_password"` // Password for file backend keyring encryption
3638

37-
// Event monitoring configuration
38-
EventPollingIntervalSeconds int `json:"event_polling_interval_seconds"` // How often to poll for new events in seconds (default: 5)
39-
40-
// Database configuration
41-
DatabaseBaseDir string `json:"database_base_dir"` // Base directory for chain databases (default: ~/.puniversal/databases)
42-
43-
// Transaction cleanup configuration (global defaults)
44-
TransactionCleanupIntervalSeconds int `json:"transaction_cleanup_interval_seconds"` // Global default: How often to run cleanup in seconds (default: 3600)
45-
TransactionRetentionPeriodSeconds int `json:"transaction_retention_period_seconds"` // Global default: How long to keep confirmed transactions in seconds (default: 86400)
46-
47-
// RPC Pool configuration
48-
RPCPoolConfig RPCPoolConfig `json:"rpc_pool_config"` // RPC pool configuration
49-
5039
// Unified per-chain configuration
5140
ChainConfigs map[string]ChainSpecificConfig `json:"chain_configs"` // Map of chain ID to all chain-specific settings
5241

@@ -63,52 +52,44 @@ type ChainSpecificConfig struct {
6352
RPCURLs []string `json:"rpc_urls,omitempty"` // RPC endpoints for this chain
6453

6554
// Transaction Cleanup Configuration
66-
CleanupIntervalSeconds *int `json:"cleanup_interval_seconds,omitempty"` // How often to run cleanup for this chain (optional, uses global default if not set)
67-
RetentionPeriodSeconds *int `json:"retention_period_seconds,omitempty"` // How long to keep confirmed transactions for this chain (optional, uses global default if not set)
55+
CleanupIntervalSeconds *int `json:"cleanup_interval_seconds,omitempty"` // How often to run cleanup for this chain (required)
56+
RetentionPeriodSeconds *int `json:"retention_period_seconds,omitempty"` // How long to keep confirmed transactions for this chain (required)
6857

6958
// Event Monitoring Configuration
70-
EventPollingIntervalSeconds *int `json:"event_polling_interval_seconds,omitempty"` // How often to poll for new events for this chain (optional, uses global default if not set)
59+
EventPollingIntervalSeconds *int `json:"event_polling_interval_seconds,omitempty"` // How often to poll for new events for this chain (required)
7160

7261
// Event Start Cursor
7362
// If set to a non-negative value, gateway event watchers start from this
7463
// block/slot for this chain. If set to -1 or not present, start from the
7564
// latest block/slot (or from DB resume point when available).
7665
EventStartFrom *int64 `json:"event_start_from,omitempty"`
7766

78-
// Future chain-specific settings can be added here
79-
}
67+
// Gas Oracle Configuration
68+
GasPriceIntervalSeconds *int `json:"gas_price_interval_seconds,omitempty"` // How often to fetch and vote on gas price (default: 30 seconds)
8069

81-
// RPCPoolConfig holds configuration for RPC endpoint pooling
82-
type RPCPoolConfig struct {
83-
HealthCheckIntervalSeconds int `json:"health_check_interval_seconds"` // How often to check endpoint health in seconds (default: 30)
84-
UnhealthyThreshold int `json:"unhealthy_threshold"` // Consecutive failures before marking unhealthy (default: 3)
85-
RecoveryIntervalSeconds int `json:"recovery_interval_seconds"` // How long to wait before retesting excluded endpoint in seconds (default: 300)
86-
MinHealthyEndpoints int `json:"min_healthy_endpoints"` // Minimum healthy endpoints required (default: 1)
87-
RequestTimeoutSeconds int `json:"request_timeout_seconds"` // Timeout for individual RPC requests in seconds (default: 10)
88-
LoadBalancingStrategy string `json:"load_balancing_strategy"` // "round-robin" or "weighted" (default: "round-robin")
70+
// Future chain-specific settings can be added here
8971
}
9072

9173
// GetChainCleanupSettings returns cleanup settings for a specific chain
92-
// Falls back to global defaults if no chain-specific settings exist
93-
func (c *Config) GetChainCleanupSettings(chainID string) (cleanupInterval, retentionPeriod int) {
94-
// Start with global defaults
95-
cleanupInterval = c.TransactionCleanupIntervalSeconds
96-
retentionPeriod = c.TransactionRetentionPeriodSeconds
74+
// Returns chain-specific settings (required per chain)
75+
func (c *Config) GetChainCleanupSettings(chainID string) (cleanupInterval, retentionPeriod int, err error) {
76+
if c.ChainConfigs == nil {
77+
return 0, 0, fmt.Errorf("no chain configs found")
78+
}
9779

98-
// Check for chain-specific overrides in unified config
99-
if c.ChainConfigs != nil {
100-
if config, ok := c.ChainConfigs[chainID]; ok {
101-
// Override with chain-specific values if provided
102-
if config.CleanupIntervalSeconds != nil {
103-
cleanupInterval = *config.CleanupIntervalSeconds
104-
}
105-
if config.RetentionPeriodSeconds != nil {
106-
retentionPeriod = *config.RetentionPeriodSeconds
107-
}
108-
}
80+
config, ok := c.ChainConfigs[chainID]
81+
if !ok {
82+
return 0, 0, fmt.Errorf("no config found for chain %s", chainID)
83+
}
84+
85+
if config.CleanupIntervalSeconds == nil {
86+
return 0, 0, fmt.Errorf("cleanup_interval_seconds is required for chain %s", chainID)
87+
}
88+
if config.RetentionPeriodSeconds == nil {
89+
return 0, 0, fmt.Errorf("retention_period_seconds is required for chain %s", chainID)
10990
}
11091

111-
return cleanupInterval, retentionPeriod
92+
return *config.CleanupIntervalSeconds, *config.RetentionPeriodSeconds, nil
11293
}
11394

11495
// GetChainConfig returns the complete configuration for a specific chain

0 commit comments

Comments
 (0)