github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/common/localconfig/config.go (about) 1 // Copyright hechain. All Rights Reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package localconfig 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "path/filepath" 10 "sync" 11 "time" 12 13 "github.com/Shopify/sarama" 14 bccsp "github.com/hechain20/hechain/bccsp/factory" 15 "github.com/hechain20/hechain/common/flogging" 16 "github.com/hechain20/hechain/common/viperutil" 17 coreconfig "github.com/hechain20/hechain/core/config" 18 "github.com/hechain20/hechain/internal/pkg/comm" 19 ) 20 21 var logger = flogging.MustGetLogger("localconfig") 22 23 // TopLevel directly corresponds to the orderer config YAML. 24 type TopLevel struct { 25 General General 26 FileLedger FileLedger 27 Kafka Kafka 28 Debug Debug 29 Consensus interface{} 30 Operations Operations 31 Metrics Metrics 32 ChannelParticipation ChannelParticipation 33 Admin Admin 34 } 35 36 // General contains config which should be common among all orderer types. 37 type General struct { 38 ListenAddress string 39 ListenPort uint16 40 TLS TLS 41 Cluster Cluster 42 Keepalive Keepalive 43 ConnectionTimeout time.Duration 44 GenesisMethod string // For compatibility only, will be replaced by BootstrapMethod 45 GenesisFile string // For compatibility only, will be replaced by BootstrapFile 46 BootstrapMethod string 47 BootstrapFile string 48 Profile Profile 49 LocalMSPDir string 50 LocalMSPID string 51 BCCSP *bccsp.FactoryOpts 52 Authentication Authentication 53 MaxRecvMsgSize int32 54 MaxSendMsgSize int32 55 } 56 57 type Cluster struct { 58 ListenAddress string 59 ListenPort uint16 60 ServerCertificate string 61 ServerPrivateKey string 62 ClientCertificate string 63 ClientPrivateKey string 64 RootCAs []string 65 DialTimeout time.Duration 66 RPCTimeout time.Duration 67 ReplicationBufferSize int 68 ReplicationPullTimeout time.Duration 69 ReplicationRetryTimeout time.Duration 70 ReplicationBackgroundRefreshInterval time.Duration 71 ReplicationMaxRetries int 72 SendBufferSize int 73 CertExpirationWarningThreshold time.Duration 74 TLSHandshakeTimeShift time.Duration 75 } 76 77 // Keepalive contains configuration for gRPC servers. 78 type Keepalive struct { 79 ServerMinInterval time.Duration 80 ServerInterval time.Duration 81 ServerTimeout time.Duration 82 } 83 84 // TLS contains configuration for TLS connections. 85 type TLS struct { 86 Enabled bool 87 PrivateKey string 88 Certificate string 89 RootCAs []string 90 ClientAuthRequired bool 91 ClientRootCAs []string 92 TLSHandshakeTimeShift time.Duration 93 } 94 95 // SASLPlain contains configuration for SASL/PLAIN authentication 96 type SASLPlain struct { 97 Enabled bool 98 User string 99 Password string 100 } 101 102 // Authentication contains configuration parameters related to authenticating 103 // client messages. 104 type Authentication struct { 105 TimeWindow time.Duration 106 NoExpirationChecks bool 107 } 108 109 // Profile contains configuration for Go pprof profiling. 110 type Profile struct { 111 Enabled bool 112 Address string 113 } 114 115 // FileLedger contains configuration for the file-based ledger. 116 type FileLedger struct { 117 Location string 118 Prefix string // For compatibility only. This setting is no longer supported. 119 } 120 121 // Kafka contains configuration for the Kafka-based orderer. 122 type Kafka struct { 123 Retry Retry 124 Verbose bool 125 Version sarama.KafkaVersion // TODO Move this to global config 126 TLS TLS 127 SASLPlain SASLPlain 128 Topic Topic 129 } 130 131 // Retry contains configuration related to retries and timeouts when the 132 // connection to the Kafka cluster cannot be established, or when Metadata 133 // requests needs to be repeated (because the cluster is in the middle of a 134 // leader election). 135 type Retry struct { 136 ShortInterval time.Duration 137 ShortTotal time.Duration 138 LongInterval time.Duration 139 LongTotal time.Duration 140 NetworkTimeouts NetworkTimeouts 141 Metadata Metadata 142 Producer Producer 143 Consumer Consumer 144 } 145 146 // NetworkTimeouts contains the socket timeouts for network requests to the 147 // Kafka cluster. 148 type NetworkTimeouts struct { 149 DialTimeout time.Duration 150 ReadTimeout time.Duration 151 WriteTimeout time.Duration 152 } 153 154 // Metadata contains configuration for the metadata requests to the Kafka 155 // cluster. 156 type Metadata struct { 157 RetryMax int 158 RetryBackoff time.Duration 159 } 160 161 // Producer contains configuration for the producer's retries when failing to 162 // post a message to a Kafka partition. 163 type Producer struct { 164 RetryMax int 165 RetryBackoff time.Duration 166 } 167 168 // Consumer contains configuration for the consumer's retries when failing to 169 // read from a Kafa partition. 170 type Consumer struct { 171 RetryBackoff time.Duration 172 } 173 174 // Topic contains the settings to use when creating Kafka topics 175 type Topic struct { 176 ReplicationFactor int16 177 } 178 179 // Debug contains configuration for the orderer's debug parameters. 180 type Debug struct { 181 BroadcastTraceDir string 182 DeliverTraceDir string 183 } 184 185 // Operations configures the operations endpoint for the orderer. 186 type Operations struct { 187 ListenAddress string 188 TLS TLS 189 } 190 191 // Metrics configures the metrics provider for the orderer. 192 type Metrics struct { 193 Provider string 194 Statsd Statsd 195 } 196 197 // Statsd provides the configuration required to emit statsd metrics from the orderer. 198 type Statsd struct { 199 Network string 200 Address string 201 WriteInterval time.Duration 202 Prefix string 203 } 204 205 // Admin configures the admin endpoint for the orderer. 206 type Admin struct { 207 ListenAddress string 208 TLS TLS 209 } 210 211 // ChannelParticipation provides the channel participation API configuration for the orderer. 212 // Channel participation uses the same ListenAddress and TLS settings of the Operations service. 213 type ChannelParticipation struct { 214 Enabled bool 215 MaxRequestBodySize uint32 216 } 217 218 // Defaults carries the default orderer configuration values. 219 var Defaults = TopLevel{ 220 General: General{ 221 ListenAddress: "127.0.0.1", 222 ListenPort: 7050, 223 BootstrapMethod: "file", 224 BootstrapFile: "genesisblock", 225 Profile: Profile{ 226 Enabled: false, 227 Address: "0.0.0.0:6060", 228 }, 229 Cluster: Cluster{ 230 ReplicationMaxRetries: 12, 231 RPCTimeout: time.Second * 7, 232 DialTimeout: time.Second * 5, 233 ReplicationBufferSize: 20971520, 234 SendBufferSize: 10, 235 ReplicationBackgroundRefreshInterval: time.Minute * 5, 236 ReplicationRetryTimeout: time.Second * 5, 237 ReplicationPullTimeout: time.Second * 5, 238 CertExpirationWarningThreshold: time.Hour * 24 * 7, 239 }, 240 LocalMSPDir: "msp", 241 LocalMSPID: "SampleOrg", 242 BCCSP: bccsp.GetDefaultOpts(), 243 Authentication: Authentication{ 244 TimeWindow: time.Duration(15 * time.Minute), 245 }, 246 MaxRecvMsgSize: comm.DefaultMaxRecvMsgSize, 247 MaxSendMsgSize: comm.DefaultMaxSendMsgSize, 248 }, 249 FileLedger: FileLedger{ 250 Location: "/var/hyperledger/production/orderer", 251 }, 252 Kafka: Kafka{ 253 Retry: Retry{ 254 ShortInterval: 1 * time.Minute, 255 ShortTotal: 10 * time.Minute, 256 LongInterval: 10 * time.Minute, 257 LongTotal: 12 * time.Hour, 258 NetworkTimeouts: NetworkTimeouts{ 259 DialTimeout: 30 * time.Second, 260 ReadTimeout: 30 * time.Second, 261 WriteTimeout: 30 * time.Second, 262 }, 263 Metadata: Metadata{ 264 RetryBackoff: 250 * time.Millisecond, 265 RetryMax: 3, 266 }, 267 Producer: Producer{ 268 RetryBackoff: 100 * time.Millisecond, 269 RetryMax: 3, 270 }, 271 Consumer: Consumer{ 272 RetryBackoff: 2 * time.Second, 273 }, 274 }, 275 Verbose: false, 276 Version: sarama.V0_10_2_0, 277 TLS: TLS{ 278 Enabled: false, 279 }, 280 Topic: Topic{ 281 ReplicationFactor: 3, 282 }, 283 }, 284 Debug: Debug{ 285 BroadcastTraceDir: "", 286 DeliverTraceDir: "", 287 }, 288 Operations: Operations{ 289 ListenAddress: "127.0.0.1:0", 290 }, 291 Metrics: Metrics{ 292 Provider: "disabled", 293 }, 294 ChannelParticipation: ChannelParticipation{ 295 Enabled: false, 296 MaxRequestBodySize: 1024 * 1024, 297 }, 298 Admin: Admin{ 299 ListenAddress: "127.0.0.1:0", 300 }, 301 } 302 303 // Load parses the orderer YAML file and environment, producing 304 // a struct suitable for config use, returning error on failure. 305 func Load() (*TopLevel, error) { 306 return cache.load() 307 } 308 309 // configCache stores marshalled bytes of config structures that produced from 310 // EnhancedExactUnmarshal. Cache key is the path of the configuration file that was used. 311 type configCache struct { 312 mutex sync.Mutex 313 cache map[string][]byte 314 } 315 316 var cache = &configCache{} 317 318 // Load will load the configuration and cache it on the first call; subsequent 319 // calls will return a clone of the configuration that was previously loaded. 320 func (c *configCache) load() (*TopLevel, error) { 321 var uconf TopLevel 322 323 config := viperutil.New() 324 config.SetConfigName("orderer") 325 326 if err := config.ReadInConfig(); err != nil { 327 return nil, fmt.Errorf("Error reading configuration: %s", err) 328 } 329 330 c.mutex.Lock() 331 defer c.mutex.Unlock() 332 serializedConf, ok := c.cache[config.ConfigFileUsed()] 333 if !ok { 334 err := config.EnhancedExactUnmarshal(&uconf) 335 if err != nil { 336 return nil, fmt.Errorf("Error unmarshalling config into struct: %s", err) 337 } 338 339 serializedConf, err = json.Marshal(uconf) 340 if err != nil { 341 return nil, err 342 } 343 344 if c.cache == nil { 345 c.cache = map[string][]byte{} 346 } 347 c.cache[config.ConfigFileUsed()] = serializedConf 348 } 349 350 err := json.Unmarshal(serializedConf, &uconf) 351 if err != nil { 352 return nil, err 353 } 354 uconf.completeInitialization(filepath.Dir(config.ConfigFileUsed())) 355 356 return &uconf, nil 357 } 358 359 func (c *TopLevel) completeInitialization(configDir string) { 360 defer func() { 361 // Translate any paths for cluster TLS configuration if applicable 362 if c.General.Cluster.ClientPrivateKey != "" { 363 coreconfig.TranslatePathInPlace(configDir, &c.General.Cluster.ClientPrivateKey) 364 } 365 if c.General.Cluster.ClientCertificate != "" { 366 coreconfig.TranslatePathInPlace(configDir, &c.General.Cluster.ClientCertificate) 367 } 368 c.General.Cluster.RootCAs = translateCAs(configDir, c.General.Cluster.RootCAs) 369 // Translate any paths for general TLS configuration 370 c.General.TLS.RootCAs = translateCAs(configDir, c.General.TLS.RootCAs) 371 c.General.TLS.ClientRootCAs = translateCAs(configDir, c.General.TLS.ClientRootCAs) 372 coreconfig.TranslatePathInPlace(configDir, &c.General.TLS.PrivateKey) 373 coreconfig.TranslatePathInPlace(configDir, &c.General.TLS.Certificate) 374 coreconfig.TranslatePathInPlace(configDir, &c.General.BootstrapFile) 375 coreconfig.TranslatePathInPlace(configDir, &c.General.LocalMSPDir) 376 // Translate file ledger location 377 coreconfig.TranslatePathInPlace(configDir, &c.FileLedger.Location) 378 }() 379 380 for { 381 switch { 382 case c.General.ListenAddress == "": 383 logger.Infof("General.ListenAddress unset, setting to %s", Defaults.General.ListenAddress) 384 c.General.ListenAddress = Defaults.General.ListenAddress 385 case c.General.ListenPort == 0: 386 logger.Infof("General.ListenPort unset, setting to %v", Defaults.General.ListenPort) 387 c.General.ListenPort = Defaults.General.ListenPort 388 case c.General.BootstrapMethod == "": 389 if c.General.GenesisMethod != "" { 390 // This is to keep the compatibility with old config file that uses genesismethod 391 logger.Warn("General.GenesisMethod should be replaced by General.BootstrapMethod") 392 c.General.BootstrapMethod = c.General.GenesisMethod 393 } else { 394 c.General.BootstrapMethod = Defaults.General.BootstrapMethod 395 } 396 case c.General.BootstrapFile == "": 397 if c.General.GenesisFile != "" { 398 // This is to keep the compatibility with old config file that uses genesisfile 399 logger.Warn("General.GenesisFile should be replaced by General.BootstrapFile") 400 c.General.BootstrapFile = c.General.GenesisFile 401 } else { 402 c.General.BootstrapFile = Defaults.General.BootstrapFile 403 } 404 case c.General.Cluster.RPCTimeout == 0: 405 c.General.Cluster.RPCTimeout = Defaults.General.Cluster.RPCTimeout 406 case c.General.Cluster.DialTimeout == 0: 407 c.General.Cluster.DialTimeout = Defaults.General.Cluster.DialTimeout 408 case c.General.Cluster.ReplicationMaxRetries == 0: 409 c.General.Cluster.ReplicationMaxRetries = Defaults.General.Cluster.ReplicationMaxRetries 410 case c.General.Cluster.SendBufferSize == 0: 411 c.General.Cluster.SendBufferSize = Defaults.General.Cluster.SendBufferSize 412 case c.General.Cluster.ReplicationBufferSize == 0: 413 c.General.Cluster.ReplicationBufferSize = Defaults.General.Cluster.ReplicationBufferSize 414 case c.General.Cluster.ReplicationPullTimeout == 0: 415 c.General.Cluster.ReplicationPullTimeout = Defaults.General.Cluster.ReplicationPullTimeout 416 case c.General.Cluster.ReplicationRetryTimeout == 0: 417 c.General.Cluster.ReplicationRetryTimeout = Defaults.General.Cluster.ReplicationRetryTimeout 418 case c.General.Cluster.ReplicationBackgroundRefreshInterval == 0: 419 c.General.Cluster.ReplicationBackgroundRefreshInterval = Defaults.General.Cluster.ReplicationBackgroundRefreshInterval 420 case c.General.Cluster.CertExpirationWarningThreshold == 0: 421 c.General.Cluster.CertExpirationWarningThreshold = Defaults.General.Cluster.CertExpirationWarningThreshold 422 case c.Kafka.TLS.Enabled && c.Kafka.TLS.Certificate == "": 423 logger.Panicf("General.Kafka.TLS.Certificate must be set if General.Kafka.TLS.Enabled is set to true.") 424 case c.Kafka.TLS.Enabled && c.Kafka.TLS.PrivateKey == "": 425 logger.Panicf("General.Kafka.TLS.PrivateKey must be set if General.Kafka.TLS.Enabled is set to true.") 426 case c.Kafka.TLS.Enabled && c.Kafka.TLS.RootCAs == nil: 427 logger.Panicf("General.Kafka.TLS.CertificatePool must be set if General.Kafka.TLS.Enabled is set to true.") 428 429 case c.Kafka.SASLPlain.Enabled && c.Kafka.SASLPlain.User == "": 430 logger.Panic("General.Kafka.SASLPlain.User must be set if General.Kafka.SASLPlain.Enabled is set to true.") 431 case c.Kafka.SASLPlain.Enabled && c.Kafka.SASLPlain.Password == "": 432 logger.Panic("General.Kafka.SASLPlain.Password must be set if General.Kafka.SASLPlain.Enabled is set to true.") 433 434 case c.General.Profile.Enabled && c.General.Profile.Address == "": 435 logger.Infof("Profiling enabled and General.Profile.Address unset, setting to %s", Defaults.General.Profile.Address) 436 c.General.Profile.Address = Defaults.General.Profile.Address 437 438 case c.General.LocalMSPDir == "": 439 logger.Infof("General.LocalMSPDir unset, setting to %s", Defaults.General.LocalMSPDir) 440 c.General.LocalMSPDir = Defaults.General.LocalMSPDir 441 case c.General.LocalMSPID == "": 442 logger.Infof("General.LocalMSPID unset, setting to %s", Defaults.General.LocalMSPID) 443 c.General.LocalMSPID = Defaults.General.LocalMSPID 444 445 case c.General.Authentication.TimeWindow == 0: 446 logger.Infof("General.Authentication.TimeWindow unset, setting to %s", Defaults.General.Authentication.TimeWindow) 447 c.General.Authentication.TimeWindow = Defaults.General.Authentication.TimeWindow 448 449 case c.Kafka.Retry.ShortInterval == 0: 450 logger.Infof("Kafka.Retry.ShortInterval unset, setting to %v", Defaults.Kafka.Retry.ShortInterval) 451 c.Kafka.Retry.ShortInterval = Defaults.Kafka.Retry.ShortInterval 452 case c.Kafka.Retry.ShortTotal == 0: 453 logger.Infof("Kafka.Retry.ShortTotal unset, setting to %v", Defaults.Kafka.Retry.ShortTotal) 454 c.Kafka.Retry.ShortTotal = Defaults.Kafka.Retry.ShortTotal 455 case c.Kafka.Retry.LongInterval == 0: 456 logger.Infof("Kafka.Retry.LongInterval unset, setting to %v", Defaults.Kafka.Retry.LongInterval) 457 c.Kafka.Retry.LongInterval = Defaults.Kafka.Retry.LongInterval 458 case c.Kafka.Retry.LongTotal == 0: 459 logger.Infof("Kafka.Retry.LongTotal unset, setting to %v", Defaults.Kafka.Retry.LongTotal) 460 c.Kafka.Retry.LongTotal = Defaults.Kafka.Retry.LongTotal 461 462 case c.Kafka.Retry.NetworkTimeouts.DialTimeout == 0: 463 logger.Infof("Kafka.Retry.NetworkTimeouts.DialTimeout unset, setting to %v", Defaults.Kafka.Retry.NetworkTimeouts.DialTimeout) 464 c.Kafka.Retry.NetworkTimeouts.DialTimeout = Defaults.Kafka.Retry.NetworkTimeouts.DialTimeout 465 case c.Kafka.Retry.NetworkTimeouts.ReadTimeout == 0: 466 logger.Infof("Kafka.Retry.NetworkTimeouts.ReadTimeout unset, setting to %v", Defaults.Kafka.Retry.NetworkTimeouts.ReadTimeout) 467 c.Kafka.Retry.NetworkTimeouts.ReadTimeout = Defaults.Kafka.Retry.NetworkTimeouts.ReadTimeout 468 case c.Kafka.Retry.NetworkTimeouts.WriteTimeout == 0: 469 logger.Infof("Kafka.Retry.NetworkTimeouts.WriteTimeout unset, setting to %v", Defaults.Kafka.Retry.NetworkTimeouts.WriteTimeout) 470 c.Kafka.Retry.NetworkTimeouts.WriteTimeout = Defaults.Kafka.Retry.NetworkTimeouts.WriteTimeout 471 472 case c.Kafka.Retry.Metadata.RetryBackoff == 0: 473 logger.Infof("Kafka.Retry.Metadata.RetryBackoff unset, setting to %v", Defaults.Kafka.Retry.Metadata.RetryBackoff) 474 c.Kafka.Retry.Metadata.RetryBackoff = Defaults.Kafka.Retry.Metadata.RetryBackoff 475 case c.Kafka.Retry.Metadata.RetryMax == 0: 476 logger.Infof("Kafka.Retry.Metadata.RetryMax unset, setting to %v", Defaults.Kafka.Retry.Metadata.RetryMax) 477 c.Kafka.Retry.Metadata.RetryMax = Defaults.Kafka.Retry.Metadata.RetryMax 478 479 case c.Kafka.Retry.Producer.RetryBackoff == 0: 480 logger.Infof("Kafka.Retry.Producer.RetryBackoff unset, setting to %v", Defaults.Kafka.Retry.Producer.RetryBackoff) 481 c.Kafka.Retry.Producer.RetryBackoff = Defaults.Kafka.Retry.Producer.RetryBackoff 482 case c.Kafka.Retry.Producer.RetryMax == 0: 483 logger.Infof("Kafka.Retry.Producer.RetryMax unset, setting to %v", Defaults.Kafka.Retry.Producer.RetryMax) 484 c.Kafka.Retry.Producer.RetryMax = Defaults.Kafka.Retry.Producer.RetryMax 485 486 case c.Kafka.Retry.Consumer.RetryBackoff == 0: 487 logger.Infof("Kafka.Retry.Consumer.RetryBackoff unset, setting to %v", Defaults.Kafka.Retry.Consumer.RetryBackoff) 488 c.Kafka.Retry.Consumer.RetryBackoff = Defaults.Kafka.Retry.Consumer.RetryBackoff 489 490 case c.Kafka.Version == sarama.KafkaVersion{}: 491 logger.Infof("Kafka.Version unset, setting to %v", Defaults.Kafka.Version) 492 c.Kafka.Version = Defaults.Kafka.Version 493 494 case c.Admin.TLS.Enabled && !c.Admin.TLS.ClientAuthRequired: 495 logger.Panic("Admin.TLS.ClientAuthRequired must be set to true if Admin.TLS.Enabled is set to true") 496 497 case c.General.MaxRecvMsgSize == 0: 498 logger.Infof("General.MaxRecvMsgSize is unset, setting to %v", Defaults.General.MaxRecvMsgSize) 499 c.General.MaxRecvMsgSize = Defaults.General.MaxRecvMsgSize 500 case c.General.MaxSendMsgSize == 0: 501 logger.Infof("General.MaxSendMsgSize is unset, setting to %v", Defaults.General.MaxSendMsgSize) 502 c.General.MaxSendMsgSize = Defaults.General.MaxSendMsgSize 503 default: 504 return 505 } 506 } 507 } 508 509 func translateCAs(configDir string, certificateAuthorities []string) []string { 510 var results []string 511 for _, ca := range certificateAuthorities { 512 result := coreconfig.TranslatePath(configDir, ca) 513 results = append(results, result) 514 } 515 return results 516 }