github.com/turingchain2020/turingchain@v1.1.21/types/config.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package types 6 7 import ( 8 "bytes" 9 "encoding/json" 10 "io/ioutil" 11 "strconv" 12 "strings" 13 "sync" 14 15 "fmt" 16 17 "github.com/turingchain2020/turingchain/common/address" 18 "github.com/turingchain2020/turingchain/types/chaincfg" 19 tml "github.com/BurntSushi/toml" 20 ) 21 22 //Create ... 23 type Create func(cfg *TuringchainConfig) 24 25 //区块链共识相关的参数,重要参数不要随便修改 26 var ( 27 AllowUserExec = [][]byte{ExecerNone} 28 EmptyValue = []byte("FFFFFFFFemptyBVBiCj5jvE15pEiwro8TQRGnJSNsJF") //这字符串表示数据库中的空值 29 cliSysParam = make(map[string]*TuringchainConfig) // map key is title 30 regModuleInit = make(map[string]Create) 31 regExecInit = make(map[string]Create) 32 runonce = sync.Once{} 33 ) 34 35 // coin conversation 36 const ( 37 Coin int64 = 1e8 38 MaxCoin int64 = 1e17 39 MaxTxSize = 100000 //100K 40 MaxTxGroupSize int32 = 20 41 MaxBlockSize = 20000000 //20M 42 MaxTxsPerBlock = 100000 43 TokenPrecision int64 = 1e8 44 MaxTokenBalance int64 = 900 * 1e8 * TokenPrecision //900亿 45 DefaultMinFee int64 = 1e5 46 ) 47 48 //TuringchainConfig ... 49 type TuringchainConfig struct { 50 mcfg *Config 51 scfg *ConfigSubModule 52 minerExecs []string 53 title string 54 55 mu sync.Mutex 56 chainConfig map[string]interface{} 57 mver *mversion 58 coinSymbol string 59 forks *Forks 60 enableCheckFork bool 61 chainID int32 62 } 63 64 //ChainParam 结构体 65 type ChainParam struct { 66 MaxTxNumber int64 67 PowLimitBits uint32 68 } 69 70 //RegFork Reg 注册每个模块的自动初始化函数 71 func RegFork(name string, create Create) { 72 if create == nil { 73 panic("config: Register Module Init is nil") 74 } 75 if _, dup := regModuleInit[name]; dup { 76 panic("config: Register Init called twice for driver " + name) 77 } 78 regModuleInit[name] = create 79 } 80 81 //RegForkInit ... 82 func RegForkInit(cfg *TuringchainConfig) { 83 for _, item := range regModuleInit { 84 item(cfg) 85 } 86 } 87 88 //RegExec ... 89 func RegExec(name string, create Create) { 90 if create == nil { 91 panic("config: Register Exec Init is nil") 92 } 93 if _, dup := regExecInit[name]; dup { 94 panic("config: Register Exec called twice for driver " + name) 95 } 96 regExecInit[name] = create 97 } 98 99 //RegExecInit ... 100 func RegExecInit(cfg *TuringchainConfig) { 101 runonce.Do(func() { 102 for _, item := range regExecInit { 103 item(cfg) 104 } 105 }) 106 } 107 108 //NewTuringchainConfig ... 109 func NewTuringchainConfig(cfgstring string) *TuringchainConfig { 110 turingchainCfg := NewTuringchainConfigNoInit(cfgstring) 111 turingchainCfg.turingchainCfgInit(turingchainCfg.mcfg) 112 return turingchainCfg 113 } 114 115 //NewTuringchainConfigNoInit ... 116 func NewTuringchainConfigNoInit(cfgstring string) *TuringchainConfig { 117 cfg, sub := InitCfgString(cfgstring) 118 turingchainCfg := &TuringchainConfig{ 119 mcfg: cfg, 120 scfg: sub, 121 minerExecs: []string{"ticket"}, //挖矿的合约名单,适配旧配置,默认ticket 122 title: cfg.Title, 123 chainConfig: make(map[string]interface{}), 124 coinSymbol: "trc", 125 forks: &Forks{make(map[string]int64)}, 126 chainID: cfg.ChainID, 127 } 128 // 先将每个模块的fork初始化到TuringchainConfig中,然后如果需要再将toml中的替换 129 turingchainCfg.setDefaultConfig() 130 turingchainCfg.setFlatConfig(cfgstring) 131 turingchainCfg.setMver(cfgstring) 132 // TODO 需要测试是否与NewTuringchainConfig分开 133 RegForkInit(turingchainCfg) 134 RegExecInit(turingchainCfg) 135 136 //设置生成账户地址的版本号 137 address.SetNormalAddrVer(cfg.AddrVer) 138 139 return turingchainCfg 140 } 141 142 //GetModuleConfig ... 143 func (c *TuringchainConfig) GetModuleConfig() *Config { 144 return c.mcfg 145 } 146 147 //GetSubConfig ... 148 func (c *TuringchainConfig) GetSubConfig() *ConfigSubModule { 149 return c.scfg 150 } 151 152 //EnableCheckFork ... 153 func (c *TuringchainConfig) EnableCheckFork(enable bool) { 154 c.enableCheckFork = false 155 } 156 157 //GetForks ... 158 func (c *TuringchainConfig) GetForks() (map[string]int64, error) { 159 if c.forks == nil { 160 return nil, ErrNotFound 161 } 162 return c.forks.forks, nil 163 } 164 165 func (c *TuringchainConfig) setDefaultConfig() { 166 c.S("TestNet", false) 167 c.SetMinFee(DefaultMinFee) 168 for key, cfg := range chaincfg.LoadAll() { 169 c.S("cfg."+key, cfg) 170 } 171 //防止报error 错误,不影响功能 172 if !c.HasConf("cfg.turingchain") { 173 c.S("cfg.turingchain", "") 174 } 175 if !c.HasConf("cfg.local") { 176 c.S("cfg.local", "") 177 } 178 } 179 180 func (c *TuringchainConfig) setFlatConfig(cfgstring string) { 181 c.mu.Lock() 182 defer c.mu.Unlock() 183 cfg := make(map[string]interface{}) 184 if _, err := tml.Decode(cfgstring, &cfg); err != nil { 185 panic(err) 186 } 187 flat := FlatConfig(cfg) 188 for k, v := range flat { 189 c.setChainConfig("config."+k, v) 190 } 191 } 192 193 func (c *TuringchainConfig) setChainConfig(key string, value interface{}) { 194 c.chainConfig[key] = value 195 } 196 197 func (c *TuringchainConfig) getChainConfig(key string) (value interface{}, err error) { 198 if data, ok := c.chainConfig[key]; ok { 199 return data, nil 200 } 201 //报错警告 202 tlog.Error("chain config " + key + " not found") 203 return nil, ErrNotFound 204 } 205 206 // Init 初始化 207 func (c *TuringchainConfig) turingchainCfgInit(cfg *Config) { 208 c.mu.Lock() 209 defer c.mu.Unlock() 210 211 if c.forks == nil { 212 c.forks = &Forks{} 213 } 214 c.forks.SetTestNetFork() 215 216 if cfg != nil { 217 if c.isLocal() { 218 c.setTestNet(true) 219 } else { 220 c.setTestNet(cfg.TestNet) 221 } 222 223 if cfg.Wallet.MinFee < cfg.Mempool.MinTxFeeRate { 224 panic("config must meet: wallet.minFee >= mempool.minTxFeeRate") 225 } 226 if cfg.Mempool.MaxTxFeeRate == 0 { 227 cfg.Mempool.MaxTxFeeRate = 1e7 //0.1 coins 228 } 229 if cfg.Mempool.MaxTxFee == 0 { 230 cfg.Mempool.MaxTxFee = 1e9 // 10 coins 231 } 232 c.setTxFeeConfig(cfg.Mempool.MinTxFeeRate, cfg.Mempool.MaxTxFeeRate, cfg.Mempool.MaxTxFee) 233 if cfg.Consensus != nil { 234 c.setMinerExecs(cfg.Consensus.MinerExecs) 235 } 236 c.setChainConfig("FixTime", cfg.FixTime) 237 if cfg.CoinSymbol != "" { 238 if strings.Contains(cfg.CoinSymbol, "-") { 239 panic("config CoinSymbol must without '-'") 240 } 241 c.coinSymbol = cfg.CoinSymbol 242 } else { 243 if c.isPara() { 244 panic("must config CoinSymbol in para chain") 245 } else { 246 c.coinSymbol = DefaultCoinsSymbol 247 } 248 } 249 //TxHeight 250 c.setChainConfig("TxHeight", cfg.TxHeight) 251 } 252 if c.needSetForkZero() { //local 只用于单元测试 253 if c.isLocal() { 254 c.forks.setLocalFork() 255 c.setChainConfig("Debug", true) 256 } else { 257 c.forks.setForkForParaZero() 258 } 259 } else { 260 if cfg != nil && cfg.Fork != nil { 261 c.initForkConfig(cfg.Fork) 262 } 263 } 264 // 更新fork配置信息 265 if c.mver != nil { 266 c.mver.UpdateFork(c.forks) 267 } 268 } 269 270 func (c *TuringchainConfig) needSetForkZero() bool { 271 if c.isLocal() { 272 return true 273 } else if c.isPara() && 274 (c.mcfg == nil || c.mcfg.Fork == nil || c.mcfg.Fork.System == nil) && 275 !c.mcfg.EnableParaFork { 276 //如果para 没有配置fork,那么默认所有的fork 为 0(一般只用于测试) 277 return true 278 } 279 return false 280 } 281 282 func (c *TuringchainConfig) setTestNet(isTestNet bool) { 283 if !isTestNet { 284 c.setChainConfig("TestNet", false) 285 return 286 } 287 c.setChainConfig("TestNet", true) 288 //const 初始化TestNet 的初始化参数 289 } 290 291 // GetP 获取ChainParam 292 func (c *TuringchainConfig) GetP(height int64) *ChainParam { 293 conf := Conf(c, "mver.consensus") 294 chain := &ChainParam{} 295 chain.MaxTxNumber = conf.MGInt("maxTxNumber", height) 296 chain.PowLimitBits = uint32(conf.MGInt("powLimitBits", height)) 297 return chain 298 } 299 300 // GetMinerExecs 获取挖矿的合约名单 301 func (c *TuringchainConfig) GetMinerExecs() []string { 302 return c.minerExecs 303 } 304 305 func (c *TuringchainConfig) setMinerExecs(execs []string) { 306 if len(execs) > 0 { 307 c.minerExecs = execs 308 } 309 } 310 311 // GetFundAddr 获取基金账户地址 312 func (c *TuringchainConfig) GetFundAddr() string { 313 return c.MGStr("mver.consensus.fundKeyAddr", 0) 314 } 315 316 // G 获取ChainConfig中的配置 317 func (c *TuringchainConfig) G(key string) (value interface{}, err error) { 318 c.mu.Lock() 319 defer c.mu.Unlock() 320 value, err = c.getChainConfig(key) 321 return 322 } 323 324 // MG 获取mver config中的配置 325 func (c *TuringchainConfig) MG(key string, height int64) (value interface{}, err error) { 326 c.mu.Lock() 327 defer c.mu.Unlock() 328 if c.mver == nil { 329 panic("mver is nil") 330 } 331 return c.mver.Get(key, height) 332 } 333 334 // GStr 获取ChainConfig中的字符串格式 335 func (c *TuringchainConfig) GStr(name string) string { 336 value, err := c.G(name) 337 if err != nil { 338 return "" 339 } 340 if i, ok := value.(string); ok { 341 return i 342 } 343 return "" 344 } 345 346 // MGStr 获取mver config 中的字符串格式 347 func (c *TuringchainConfig) MGStr(name string, height int64) string { 348 value, err := c.MG(name, height) 349 if err != nil { 350 return "" 351 } 352 if i, ok := value.(string); ok { 353 return i 354 } 355 return "" 356 } 357 358 func parseInt(value interface{}) int64 { 359 if i, ok := value.(int64); ok { 360 return i 361 } 362 if s, ok := value.(string); ok { 363 if strings.HasPrefix(s, "0x") { 364 i, err := strconv.ParseUint(s, 0, 64) 365 if err == nil { 366 return int64(i) 367 } 368 } 369 } 370 return 0 371 } 372 373 // GInt 解析ChainConfig配置 374 func (c *TuringchainConfig) GInt(name string) int64 { 375 value, err := c.G(name) 376 if err != nil { 377 return 0 378 } 379 return parseInt(value) 380 } 381 382 // MGInt 解析mver config 配置 383 func (c *TuringchainConfig) MGInt(name string, height int64) int64 { 384 value, err := c.MG(name, height) 385 if err != nil { 386 return 0 387 } 388 return parseInt(value) 389 } 390 391 // IsEnable 解析ChainConfig配置 392 func (c *TuringchainConfig) IsEnable(name string) bool { 393 isenable, err := c.G(name) 394 if err == nil && isenable.(bool) { 395 return true 396 } 397 return false 398 } 399 400 // MIsEnable 解析mver config 配置 401 func (c *TuringchainConfig) MIsEnable(name string, height int64) bool { 402 isenable, err := c.MG(name, height) 403 if err == nil && isenable.(bool) { 404 return true 405 } 406 return false 407 } 408 409 // HasConf 解析chainConfig配置 410 func (c *TuringchainConfig) HasConf(key string) bool { 411 c.mu.Lock() 412 defer c.mu.Unlock() 413 _, ok := c.chainConfig[key] 414 return ok 415 } 416 417 // S 设置chainConfig配置 418 func (c *TuringchainConfig) S(key string, value interface{}) { 419 c.mu.Lock() 420 defer c.mu.Unlock() 421 if strings.HasPrefix(key, "config.") { 422 if !c.isLocal() && !c.isTestPara() { //only local and test para can modify for test 423 panic("prefix config. is readonly") 424 } else { 425 tlog.Error("modify " + key + " is only for test") 426 } 427 } 428 c.setChainConfig(key, value) 429 } 430 431 //SetTitleOnlyForTest set title only for test use 432 func (c *TuringchainConfig) SetTitleOnlyForTest(ti string) { 433 c.mu.Lock() 434 defer c.mu.Unlock() 435 c.title = ti 436 437 } 438 439 // GetTitle 获取title 440 func (c *TuringchainConfig) GetTitle() string { 441 c.mu.Lock() 442 defer c.mu.Unlock() 443 return c.title 444 } 445 446 // GetCoinSymbol 获取 coin symbol 447 func (c *TuringchainConfig) GetCoinSymbol() string { 448 c.mu.Lock() 449 defer c.mu.Unlock() 450 return c.coinSymbol 451 } 452 453 func (c *TuringchainConfig) isLocal() bool { 454 return c.title == "local" 455 } 456 457 // IsLocal 是否locak title 458 func (c *TuringchainConfig) IsLocal() bool { 459 c.mu.Lock() 460 defer c.mu.Unlock() 461 return c.isLocal() 462 } 463 464 // GetMinTxFeeRate get min transaction fee rate 465 func (c *TuringchainConfig) GetMinTxFeeRate() int64 { 466 return c.GInt("MinTxFeeRate") 467 } 468 469 // GetMaxTxFeeRate get max transaction fee rate 470 func (c *TuringchainConfig) GetMaxTxFeeRate() int64 { 471 return c.GInt("MaxTxFeeRate") 472 } 473 474 // GetMaxTxFee get max transaction fee 475 func (c *TuringchainConfig) GetMaxTxFee() int64 { 476 return c.GInt("MaxTxFee") 477 } 478 479 // SetTxFeeConfig 设置交易费相关配置 480 func (c *TuringchainConfig) SetTxFeeConfig(minTxFeeRate, maxTxFeeRate, maxTxFee int64) { 481 c.mu.Lock() 482 defer c.mu.Unlock() 483 c.setTxFeeConfig(minTxFeeRate, maxTxFeeRate, maxTxFee) 484 } 485 486 func (c *TuringchainConfig) setTxFeeConfig(minTxFeeRate, maxTxFeeRate, maxTxFee int64) { 487 if minTxFeeRate < 0 { 488 panic("minTxFeeRate less than zero") 489 } 490 491 if minTxFeeRate > maxTxFeeRate || maxTxFeeRate > maxTxFee { 492 panic("SetTxFee, tx fee must meet, minTxFeeRate <= maxTxFeeRate <= maxTxFee") 493 } 494 c.setChainConfig("MinTxFeeRate", minTxFeeRate) 495 c.setChainConfig("MaxTxFeeRate", maxTxFeeRate) 496 c.setChainConfig("MaxTxFee", maxTxFee) 497 c.setChainConfig("MinBalanceTransfer", minTxFeeRate*10) 498 } 499 500 // SetMinFee 设置最小费用 501 func (c *TuringchainConfig) SetMinFee(fee int64) { 502 c.mu.Lock() 503 defer c.mu.Unlock() 504 c.setTxFeeConfig(fee, fee*100, fee*10000) 505 } 506 507 func (c *TuringchainConfig) isPara() bool { 508 return strings.Count(c.title, ".") == 3 && strings.HasPrefix(c.title, ParaKeyX) 509 } 510 511 func (c *TuringchainConfig) isTestPara() bool { 512 return strings.Count(c.title, ".") == 3 && strings.HasPrefix(c.title, ParaKeyX) && strings.HasSuffix(c.title, "test.") 513 } 514 515 // IsPara 是否平行链 516 func (c *TuringchainConfig) IsPara() bool { 517 c.mu.Lock() 518 defer c.mu.Unlock() 519 return c.isPara() 520 } 521 522 // IsParaExecName 是否平行链执行器 523 func IsParaExecName(exec string) bool { 524 return strings.HasPrefix(exec, ParaKeyX) 525 } 526 527 //IsMyParaExecName 是否是我的para链的执行器 528 func (c *TuringchainConfig) IsMyParaExecName(exec string) bool { 529 return IsParaExecName(exec) && strings.HasPrefix(exec, c.GetTitle()) 530 } 531 532 //IsSpecificParaExecName 是否是某一个平行链的执行器 533 func IsSpecificParaExecName(title, exec string) bool { 534 return IsParaExecName(exec) && strings.HasPrefix(exec, title) 535 } 536 537 //GetParaExecTitleName 如果是平行链执行器,获取对应title 538 func GetParaExecTitleName(exec string) (string, bool) { 539 if IsParaExecName(exec) { 540 for i := len(ParaKey); i < len(exec); i++ { 541 if exec[i] == '.' { 542 return exec[:i+1], true 543 } 544 } 545 } 546 return "", false 547 } 548 549 // IsTestNet 是否测试链 550 func (c *TuringchainConfig) IsTestNet() bool { 551 return c.IsEnable("TestNet") 552 } 553 554 // GetParaName 获取平行链name 555 func (c *TuringchainConfig) GetParaName() string { 556 if c.IsPara() { 557 return c.GetTitle() 558 } 559 return "" 560 } 561 562 // FlagKV 获取kv对 563 func FlagKV(key []byte, value int64) *KeyValue { 564 return &KeyValue{Key: key, Value: Encode(&Int64{Data: value})} 565 } 566 567 // MergeConfig Merge配置 568 func MergeConfig(conf map[string]interface{}, def map[string]interface{}) string { 569 errstr := checkConfig("", conf, def) 570 if errstr != "" { 571 return errstr 572 } 573 mergeConfig(conf, def) 574 return "" 575 } 576 577 //检查默认配置文件 578 func checkConfig(key string, conf map[string]interface{}, def map[string]interface{}) string { 579 errstr := "" 580 for key1, value1 := range conf { 581 if vdef, ok := def[key1]; ok { 582 conf1, ok1 := value1.(map[string]interface{}) 583 def1, ok2 := vdef.(map[string]interface{}) 584 if ok1 && ok2 { 585 errstr += checkConfig(getkey(key, key1), conf1, def1) 586 } else { 587 errstr += "rewrite defalut key " + getkey(key, key1) + "\n" 588 } 589 } 590 } 591 return errstr 592 } 593 594 func mergeConfig(conf map[string]interface{}, def map[string]interface{}) { 595 for key1, value1 := range def { 596 if vdef, ok := conf[key1]; ok { 597 conf1, ok1 := value1.(map[string]interface{}) 598 def1, ok2 := vdef.(map[string]interface{}) 599 if ok1 && ok2 { 600 mergeConfig(conf1, def1) 601 conf[key1] = conf1 602 } 603 } else { 604 conf[key1] = value1 605 } 606 } 607 } 608 609 func getkey(key, key1 string) string { 610 if key == "" { 611 return key1 612 } 613 return key + "." + key1 614 } 615 616 //MergeCfg ... 617 func MergeCfg(cfgstring, cfgdefault string) string { 618 if cfgdefault != "" { 619 return mergeCfgString(cfgstring, cfgdefault) 620 } 621 return cfgstring 622 } 623 624 func mergeCfgString(cfgstring, cfgdefault string) string { 625 //1. defconfig 626 def := make(map[string]interface{}) 627 _, err := tml.Decode(cfgdefault, &def) 628 if err != nil { 629 panic(err) 630 } 631 //2. userconfig 632 conf := make(map[string]interface{}) 633 _, err = tml.Decode(cfgstring, &conf) 634 if err != nil { 635 panic(err) 636 } 637 errstr := MergeConfig(conf, def) 638 if errstr != "" { 639 panic(errstr) 640 } 641 buf := new(bytes.Buffer) 642 tml.NewEncoder(buf).Encode(conf) 643 return buf.String() 644 } 645 646 func initCfgString(cfgstring string) (*Config, error) { 647 var cfg Config 648 if _, err := tml.Decode(cfgstring, &cfg); err != nil { 649 return nil, err 650 } 651 return &cfg, nil 652 } 653 654 // InitCfg 初始化配置 655 func InitCfg(path string) (*Config, *ConfigSubModule) { 656 return InitCfgString(readFile(path)) 657 } 658 659 func flatConfig(key string, conf map[string]interface{}, flat map[string]interface{}) { 660 for key1, value1 := range conf { 661 conf1, ok := value1.(map[string]interface{}) 662 if ok { 663 flatConfig(getkey(key, key1), conf1, flat) 664 } else { 665 flat[getkey(key, key1)] = value1 666 } 667 } 668 } 669 670 // FlatConfig Flat配置 671 func FlatConfig(conf map[string]interface{}) map[string]interface{} { 672 flat := make(map[string]interface{}) 673 flatConfig("", conf, flat) 674 return flat 675 } 676 677 func (c *TuringchainConfig) setMver(cfgstring string) { 678 c.mu.Lock() 679 defer c.mu.Unlock() 680 c.mver = newMversion(cfgstring) 681 } 682 683 // InitCfgString 初始化配置 684 func InitCfgString(cfgstring string) (*Config, *ConfigSubModule) { 685 //cfgstring = c.mergeCfg(cfgstring) // TODO 是否可以去除 686 //setFlatConfig(cfgstring) // 将set的全部去除 687 cfg, err := initCfgString(cfgstring) 688 if err != nil { 689 panic(err) 690 } 691 //setMver(cfg.Title, cfgstring) // 将set的全部去除 692 sub, err := initSubModuleString(cfgstring) 693 if err != nil { 694 panic(err) 695 } 696 return cfg, sub 697 } 698 699 //ReadFile ... 700 func ReadFile(path string) string { 701 return readFile(path) 702 } 703 704 func readFile(path string) string { 705 data, err := ioutil.ReadFile(path) 706 if err != nil { 707 panic(err) 708 } 709 return string(data) 710 } 711 712 func initSubModuleString(cfgstring string) (*ConfigSubModule, error) { 713 var cfg subModule 714 if _, err := tml.Decode(cfgstring, &cfg); err != nil { 715 return nil, err 716 } 717 return parseSubModule(&cfg) 718 } 719 720 func parseSubModule(cfg *subModule) (*ConfigSubModule, error) { 721 var subcfg ConfigSubModule 722 subcfg.Store = parseItem(cfg.Store) 723 subcfg.Exec = parseItem(cfg.Exec) 724 subcfg.Consensus = parseItem(cfg.Consensus) 725 subcfg.Wallet = parseItem(cfg.Wallet) 726 subcfg.Mempool = parseItem(cfg.Mempool) 727 subcfg.Metrics = parseItem(cfg.Metrics) 728 subcfg.P2P = parseItem(cfg.P2P) 729 subcfg.Crypto = parseItem(cfg.Crypto) 730 return &subcfg, nil 731 } 732 733 //ModifySubConfig json data modify 734 func ModifySubConfig(sub []byte, key string, value interface{}) ([]byte, error) { 735 var data map[string]interface{} 736 err := json.Unmarshal(sub, &data) 737 if err != nil { 738 return nil, err 739 } 740 data[key] = value 741 return json.Marshal(data) 742 } 743 744 func parseItem(data map[string]interface{}) map[string][]byte { 745 subconfig := make(map[string][]byte) 746 if len(data) == 0 { 747 return subconfig 748 } 749 for key := range data { 750 if key == "sub" { 751 subcfg := data[key].(map[string]interface{}) 752 for k := range subcfg { 753 subconfig[k], _ = json.Marshal(subcfg[k]) 754 } 755 } 756 } 757 return subconfig 758 } 759 760 // ConfQuery 结构体 761 type ConfQuery struct { 762 cfg *TuringchainConfig 763 prefix string 764 } 765 766 // Conf 配置 767 func Conf(cfg *TuringchainConfig, prefix string) *ConfQuery { 768 if prefix == "" || (!strings.HasPrefix(prefix, "config.") && !strings.HasPrefix(prefix, "mver.")) { 769 panic("ConfQuery must init buy prefix config. or mver.") 770 } 771 return &ConfQuery{cfg: cfg, prefix: prefix} 772 } 773 774 // ConfSub 子模块配置 775 func ConfSub(cfg *TuringchainConfig, name string) *ConfQuery { 776 return Conf(cfg, "config.exec.sub."+name) 777 } 778 779 // G 获取指定key的配置信息 780 func (query *ConfQuery) G(key string) (interface{}, error) { 781 return query.cfg.G(getkey(query.prefix, key)) 782 } 783 784 func parseStrList(data interface{}) []string { 785 var list []string 786 if item, ok := data.([]interface{}); ok { 787 for i := 0; i < len(item); i++ { 788 one, ok := item[i].(string) 789 if ok { 790 list = append(list, one) 791 } 792 } 793 } 794 return list 795 } 796 797 // GStrList 解析字符串列表 798 func (query *ConfQuery) GStrList(key string) []string { 799 data, err := query.G(key) 800 if err == nil { 801 return parseStrList(data) 802 } 803 return []string{} 804 } 805 806 // GInt 解析int类型 807 func (query *ConfQuery) GInt(key string) int64 { 808 return query.cfg.GInt(getkey(query.prefix, key)) 809 } 810 811 // GStr 解析string类型 812 func (query *ConfQuery) GStr(key string) string { 813 return query.cfg.GStr(getkey(query.prefix, key)) 814 } 815 816 // IsEnable 解析bool类型 817 func (query *ConfQuery) IsEnable(key string) bool { 818 return query.cfg.IsEnable(getkey(query.prefix, key)) 819 } 820 821 // MG 解析mversion 822 func (query *ConfQuery) MG(key string, height int64) (interface{}, error) { 823 return query.cfg.MG(getkey(query.prefix, key), height) 824 } 825 826 // MGInt 解析mversion int类型配置 827 func (query *ConfQuery) MGInt(key string, height int64) int64 { 828 return query.cfg.MGInt(getkey(query.prefix, key), height) 829 } 830 831 // MGStr 解析mversion string类型配置 832 func (query *ConfQuery) MGStr(key string, height int64) string { 833 return query.cfg.MGStr(getkey(query.prefix, key), height) 834 } 835 836 // MGStrList 解析mversion string list类型配置 837 func (query *ConfQuery) MGStrList(key string, height int64) []string { 838 data, err := query.MG(key, height) 839 if err == nil { 840 return parseStrList(data) 841 } 842 return []string{} 843 } 844 845 // MIsEnable 解析mversion bool类型配置 846 func (query *ConfQuery) MIsEnable(key string, height int64) bool { 847 return query.cfg.MIsEnable(getkey(query.prefix, key), height) 848 } 849 850 //SetCliSysParam ... 851 func SetCliSysParam(title string, cfg *TuringchainConfig) { 852 if cfg == nil { 853 panic("set cli system TuringchainConfig param is nil") 854 } 855 cliSysParam[title] = cfg 856 } 857 858 //GetCliSysParam ... 859 func GetCliSysParam(title string) *TuringchainConfig { 860 if v, ok := cliSysParam[title]; ok { 861 return v 862 } 863 panic(fmt.Sprintln("can not find CliSysParam title", title)) 864 } 865 866 //AssertConfig ... 867 func AssertConfig(check interface{}) { 868 if check == nil { 869 panic("check object is nil (TuringchainConfig)") 870 } 871 } 872 873 // GetChainID 获取链ID,提供给其他模块使用 874 func (c *TuringchainConfig) GetChainID() int32 { 875 c.mu.Lock() 876 defer c.mu.Unlock() 877 return c.chainID 878 }