-
Notifications
You must be signed in to change notification settings - Fork 64
/
config.go
210 lines (170 loc) · 5.85 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
package config
import (
"fmt"
"path/filepath"
"time"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/dymensionxyz/dymint/da/grpc"
"github.com/dymensionxyz/dymint/settlement"
)
const (
// DefaultDymintDir is the default directory for dymint
DefaultDymintDir = ".dymint"
DefaultConfigDirName = "config"
DefaultConfigFileName = "dymint.toml"
)
// NodeConfig stores Dymint node configuration.
type NodeConfig struct {
// parameters below are translated from existing config
RootDir string
DBPath string
P2P P2PConfig
RPC RPCConfig
// parameters below are dymint specific and read from config
Aggregator bool `mapstructure:"aggregator"`
BlockManagerConfig `mapstructure:",squash"`
DALayer string `mapstructure:"da_layer"`
DAConfig string `mapstructure:"da_config"`
SettlementLayer string `mapstructure:"settlement_layer"`
SettlementConfig settlement.Config `mapstructure:",squash"`
Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"`
// Config params for mock grpc da
DAGrpc grpc.Config `mapstructure:",squash"`
BootstrapTime time.Duration `mapstructure:"bootstrap_time"`
}
// BlockManagerConfig consists of all parameters required by BlockManagerConfig
type BlockManagerConfig struct {
// BlockTime defines how often new blocks are produced
BlockTime time.Duration `mapstructure:"block_time"`
// EmptyBlocksMaxTime defines how long should block manager wait for new transactions before producing empty block
EmptyBlocksMaxTime time.Duration `mapstructure:"empty_blocks_max_time"`
// BatchSubmitMaxTime defines how long should block manager wait for before submitting batch
BatchSubmitMaxTime time.Duration `mapstructure:"batch_submit_max_time"`
NamespaceID string `mapstructure:"namespace_id"`
// The size of the batch in blocks. Every batch we'll write to the DA and the settlement layer.
BlockBatchSize uint64 `mapstructure:"block_batch_size"`
// The size of the batch in Bytes. Every batch we'll write to the DA and the settlement layer.
BlockBatchMaxSizeBytes uint64 `mapstructure:"block_batch_max_size_bytes"`
// The number of messages cached by gossipsub protocol
GossipedBlocksCacheSize int `mapstructure:"gossiped_blocks_cache_size"`
}
// GetViperConfig reads configuration parameters from Viper instance.
func (nc *NodeConfig) GetViperConfig(cmd *cobra.Command, homeDir string) error {
v := viper.GetViper()
// Loads dymint toml config file
EnsureRoot(homeDir, nil)
v.SetConfigName("dymint")
v.AddConfigPath(homeDir) // search root directory
v.AddConfigPath(filepath.Join(homeDir, DefaultConfigDirName)) // search root directory /config
// bind flags so we could override config file with flags
err := BindDymintFlags(cmd, v)
if err != nil {
return err
}
// Read viper config
err = v.ReadInConfig()
if err != nil {
return err
}
err = viper.Unmarshal(&nc)
if err != nil {
return err
}
err = nc.Validate()
if err != nil {
return err
}
return nil
}
func (nc NodeConfig) Validate() error {
if err := nc.BlockManagerConfig.Validate(); err != nil {
return fmt.Errorf("BlockManagerConfig: %w", err)
}
if err := nc.validateSettlementLayer(); err != nil {
return fmt.Errorf("SettlementLayer: %w", err)
}
if err := nc.validateDALayer(); err != nil {
return fmt.Errorf("DALayer: %w", err)
}
if err := nc.validateInstrumentation(); err != nil {
return fmt.Errorf("Instrumentation: %w", err)
}
return nil
}
// Validate BlockManagerConfig
func (c BlockManagerConfig) Validate() error {
if c.BlockTime <= 0 {
return fmt.Errorf("block_time must be positive")
}
if c.EmptyBlocksMaxTime < 0 {
return fmt.Errorf("empty_blocks_max_time must be positive or zero to disable")
}
if c.BatchSubmitMaxTime <= 0 {
return fmt.Errorf("batch_submit_max_time must be positive")
}
if c.EmptyBlocksMaxTime != 0 && c.EmptyBlocksMaxTime <= c.BlockTime {
return fmt.Errorf("empty_blocks_max_time must be greater than block_time")
}
if c.BatchSubmitMaxTime < c.BlockTime {
return fmt.Errorf("batch_submit_max_time must be greater than block_time")
}
if c.BlockBatchSize <= 0 {
return fmt.Errorf("block_batch_size must be positive")
}
if c.BlockBatchMaxSizeBytes <= 0 {
return fmt.Errorf("block_batch_size_bytes must be positive")
}
if c.GossipedBlocksCacheSize <= 0 {
return fmt.Errorf("gossiped_blocks_cache_size must be positive")
}
return nil
}
func (nc NodeConfig) validateSettlementLayer() error {
if nc.SettlementLayer == "" {
return fmt.Errorf("SettlementLayer cannot be empty")
}
if nc.SettlementLayer == "mock" {
return nil
}
return nc.SettlementConfig.Validate()
}
func (nc NodeConfig) validateDALayer() error {
if nc.DALayer == "" {
return fmt.Errorf("DALayer cannot be empty")
}
if nc.DALayer == "mock" {
return nil
}
if nc.DAConfig == "" {
return fmt.Errorf("DAConfig cannot be empty")
}
if nc.DAGrpc.Host == "" {
return fmt.Errorf("DAGrpc.Host cannot be empty")
}
if nc.DAGrpc.Port == 0 {
return fmt.Errorf("DAGrpc.Port cannot be 0")
}
return nil
}
func (nc NodeConfig) validateInstrumentation() error {
if nc.Instrumentation == nil {
return nil
}
return nc.Instrumentation.Validate()
}
// InstrumentationConfig defines the configuration for metrics reporting.
type InstrumentationConfig struct {
// When true, Prometheus metrics are served under /metrics on
// PrometheusListenAddr.
// Check out the documentation for the list of available metrics.
Prometheus bool `mapstructure:"prometheus"`
// Address to listen for Prometheus collector(s) connections.
PrometheusListenAddr string `mapstructure:"prometheus_listen_addr"`
}
func (ic InstrumentationConfig) Validate() error {
if ic.Prometheus && ic.PrometheusListenAddr == "" {
return fmt.Errorf("PrometheusListenAddr cannot be empty")
}
return nil
}