Refactor shard handling to use configurable shard number from config#62
Refactor shard handling to use configurable shard number from config#62Salty-SourKey wants to merge 2 commits intomainfrom
Conversation
Code Review: Configurable Shard Number RefactorThank you for this PR! The goal of making shard count configurable is valuable. However, there's a critical bug that will cause runtime panics in tests and potentially in production. 🔴 Critical Issue: Uninitialized Global ConfigurationProblem: The PR introduces a global Location: var Configuration Config // ⚠️ Never set anywhere!
func GetConfig() Config {
return Configuration // Always returns {ShardNum: 0, ...}
}Impact:
Root Cause: Neither 🔧 Recommended FixOption 1: Initialize the global in Load functions (recommended) // config/config.go
func Load(configPath string) (*Config, error) {
// ... existing code ...
if err := json.Unmarshal(data, cfg); err != nil {
return nil, fmt.Errorf("failed to parse config file: %w", err)
}
Configuration = *cfg // ✅ Set global
return cfg, nil
}
func LoadDefault() (*Config, error) {
// ... existing code ...
cfg, err := Load(path)
if err == nil {
Configuration = *cfg // ✅ Set global (or rely on Load())
return cfg, nil
}
// ...
}Option 2: Initialize in main entry points In both cfg, err := config.LoadDefault()
if err != nil {
log.Fatal(err)
}
config.Configuration = *cfg // ✅ Set globalFor tests: Add initialization in test setup: // internal/shard/shard_test.go
func setupTestServer(t *testing.T, shardID int, orchestratorURL string) *Server {
t.Helper()
// Initialize config for tests
config.Configuration = config.Config{ShardNum: 8} // ✅ Match test expectations
return NewServerForTest(shardID, orchestratorURL, config.NetworkConfig{})
}📋 Other Issues
✅ What Works Well
🧪 Testing RecommendationsBefore merging:
📝 Documentation Updates NeededPer
SummaryCannot merge until the initialization bug is fixed. Once Let me know if you need any clarification on the fix! |
Code Review - PR #62: Refactor shard handling to use configurable shard numberThank you for this refactoring! The goal of making the shard count configurable is excellent. However, I've identified several critical issues that need to be addressed before merging. 🚨 Critical Issues1. Uninitialized Configuration in Tests (Race Condition & Panics)Problem: The global
Affected locations:
Fix required: // Add to test files or a test_utils.go
func init() {
config.Configuration = config.Config{
ShardNum: 8, // or load from test config
// ... other fields
}
}Or better yet, add a test helper: func setupTestConfig(t *testing.T) {
t.Helper()
config.Configuration = config.Config{
ShardNum: 8,
StorageDir: t.TempDir(),
TestAccountNum: 100,
}
}2. Orchestrator Still Uses Parameter Instead of ConfigProblem: The orchestrator's Location: Current (inconsistent): service, err := orchestrator.NewService(*numShards, *bytecodePath, networkConfig)Should be: // Ensure config is loaded before creating service
cfg, err := config.LoadDefault()
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
service, err := orchestrator.NewService(cfg.ShardNum, *bytecodePath, networkConfig)
// OR refactor NewService to read from config.GetConfig().ShardNum internallyWhy this matters: Currently, the orchestrator and shards can have different shard counts, breaking the entire system. The config must be the single source of truth. 3. Thread Safety Concern: Global Variable AccessProblem: func GetConfig() Config {
return Configuration // Returns a copy
}This is actually good for thread safety (prevents concurrent modification), but the initialization in Configuration = *cfg // Unprotected write to global variablePotential race condition:
Recommended fix: var (
Configuration Config
configMu sync.RWMutex
)
func GetConfig() Config {
configMu.RLock()
defer configMu.RUnlock()
return Configuration
}
func Load(configPath string) (*Config, error) {
// ... parse config ...
configMu.Lock()
Configuration = *cfg
configMu.Unlock()
return cfg, nil
}Alternative (simpler): Use
|
This pull request makes the number of shards (
ShardNum) fully configurable throughout the codebase, replacing the previous use of a hardcoded constant (NumShards). The value is now read from the global configuration, allowing for dynamic adjustment of the sharding scheme without code changes. Key updates include removing theNumShardsconstant, updating all shard calculations to use the configuration value, and ensuring the configuration is accessible where needed.Configuration refactor and usage:
NumShardsconstant and all its usages, centralizing the shard count in theconfigpackage asShardNumwithin the global configuration ([[1]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-86825c80bb79bd22c948318cf94fe4b66e4665be4a3e6c9629f7ac48d1abca07L18-L21),[[2]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L1204)).config.GetConfig().ShardNuminstead of the hardcoded constant ([[1]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L600-R600),[[2]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L672-R672),[[3]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L1029-R1029),[[4]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L1053-R1053),[[5]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L1138-R1138),[[6]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L1254-R1261),[[7]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L1310-R1309),[[8]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-92e3f20f15139f3a0f08b79893a50c6a572c0a0a6113fa3646ecb27c24c1e601L329-R329)).Configuration access and initialization:
Configurationvariable and aGetConfig()accessor inconfig/config.goto provide easy access to the loaded configuration throughout the application ([config/config.goR24-R29](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-fe44f09c4d5977b5f5eaea29170b6a0748819c9d02271746a20d81a5f3efca17R24-R29)).NumShardsto instead use the value from the configuration ([[1]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-ac581fb50a47860df636cb782d9b0d799cb03fc7a2269862499bad2a2d549516L58-R59),[[2]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-ce0efdc296e84775ac5f762e0e12b55f9b13c4b0232acb70120618501e543d0eL652-R652),[[3]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L588-R588),[[4]](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-f46d0f5ecb747bfa1413f2a709dd83173502c13e32221cd521e07d58bb1dcbe9L1289-R1288)).Imports and cleanup:
configpackage in files that now require access to the configuration ([internal/orchestrator/simulator.goR14](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-ac581fb50a47860df636cb782d9b0d799cb03fc7a2269862499bad2a2d549516R14)).statedb.go([internal/orchestrator/statedb.goL713](https://github.com/The-Sharding-Resurrection/Matrix/pull/62/files#diff-86825c80bb79bd22c948318cf94fe4b66e4665be4a3e6c9629f7ac48d1abca07L713)).