github.com/turingchain2020/turingchain@v1.1.21/types/config_mver.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 fmt "fmt" 9 "sort" 10 "strings" 11 12 tml "github.com/BurntSushi/toml" 13 ) 14 15 //multi version config 16 type versionList struct { 17 data []int64 18 key string 19 prefix string 20 suffix string 21 forkname map[int64]string 22 } 23 24 type mversion struct { 25 data map[string]interface{} 26 version map[string]*versionList 27 } 28 29 func newMversion(cfgstring string) *mversion { 30 cfg := make(map[string]interface{}) 31 if _, err := tml.Decode(cfgstring, &cfg); err != nil { 32 panic(err) 33 } 34 flat := FlatConfig(cfg) 35 mver := &mversion{ 36 data: make(map[string]interface{}), 37 version: make(map[string]*versionList), 38 } 39 for k, v := range flat { 40 if !strings.HasPrefix(k, "mver.") { 41 continue 42 } 43 mver.data[k] = v 44 } 45 return mver 46 } 47 48 func (m *mversion) Get(key string, height int64) (interface{}, error) { 49 vlist, ok := m.version[key] 50 if !ok { 51 return m.get(key) 52 } 53 key = vlist.GetForkName(height) 54 return m.get(key) 55 } 56 57 func (m *mversion) get(key string) (interface{}, error) { 58 if data, ok := m.data[key]; ok { 59 return data, nil 60 } 61 tlog.Error("mver config " + key + " not found") 62 return nil, ErrNotFound 63 } 64 65 // UpdateFork 根据Forks信息, 适配mver下的fork, 66 // 该函数调用需要在所有代码中fork以及toml中fork 67 // 载入之后以及载入toml中的mver配置之后调用 68 func (m *mversion) UpdateFork(f *Forks) { 69 for k := range m.data { 70 //global fork 71 //mver.forkname.name 72 //mver.consensus.forkname.name 73 items := strings.Split(k, ".") 74 if len(items) < 3 { 75 continue 76 } 77 forkname := items[len(items)-2] 78 if !f.HasFork(forkname) { 79 //maybe sub forl 80 //mver.exec.sub.token.forkname 81 forkname = items[len(items)-3] + "." + items[len(items)-2] 82 if !f.HasFork(forkname) { 83 continue 84 } 85 } 86 id := f.GetFork(forkname) 87 items[len(items)-2] = items[len(items)-1] 88 suffix := items[len(items)-1] 89 prefix := strings.Join(items[0:len(items)-2], ".") 90 items = items[0 : len(items)-1] 91 key := strings.Join(items, ".") 92 if _, ok := m.version[key]; !ok { 93 m.version[key] = &versionList{key: key, prefix: prefix, suffix: suffix} 94 } 95 err := m.version[key].addItem(id, key, forkname) 96 if err != nil { 97 panic(err) 98 } 99 } 100 //sort all []int data 101 for k, v := range m.version { 102 sort.Slice(v.data, func(i, j int) bool { return v.data[i] < v.data[j] }) 103 m.version[k] = v 104 } 105 } 106 107 func (v *versionList) addItem(forkid int64, key, forkname string) error { 108 if v.key != key { 109 return fmt.Errorf("version list key not the same") 110 } 111 if len(v.forkname) == 0 { 112 v.forkname = make(map[int64]string) 113 } 114 //这里要允许替换: 有时候会有相同的fork高度 115 if _, ok := v.forkname[forkid]; ok { 116 //以字母顺序替换 117 if strings.Compare(forkname, v.forkname[forkid]) > 0 { 118 tlog.Warn(key + " same fork height is set: old name is '" + v.forkname[forkid] + "' new name is '" + forkname + "'") 119 v.forkname[forkid] = forkname 120 } 121 return nil 122 } 123 v.forkname[forkid] = forkname 124 v.data = append(v.data, forkid) 125 return nil 126 } 127 128 func (v *versionList) GetForkName(height int64) string { 129 if len(v.data) == 0 { 130 return v.key 131 } 132 //find first big than [0, 10, 20] 11 133 for i := len(v.data) - 1; i >= 0; i-- { 134 if height >= v.data[i] { 135 //fork find 136 forkname := v.forkname[v.data[i]] 137 if strings.Contains(forkname, ".") { 138 items := strings.Split(forkname, ".") 139 forkname = items[1] 140 } 141 s := v.prefix + "." + forkname + "." + v.suffix 142 return s 143 } 144 } 145 return v.key 146 }