github.com/annchain/OG@v0.0.9/consensus/term/archive/term.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package archive 15 16 import ( 17 "github.com/annchain/OG/arefactor/og/types" 18 "github.com/annchain/OG/common" 19 "github.com/annchain/OG/common/crypto" 20 "github.com/annchain/OG/consensus/campaign" 21 "sync" 22 23 log "github.com/sirupsen/logrus" 24 ) 25 26 type Term struct { 27 id uint32 `json:"id"` 28 flag bool 29 partsNum int 30 senators Senators `json:"senators"` 31 formerSenators map[uint32]Senators `json:"former_senators"` 32 candidates map[common.Address]*campaign.Campaign 33 publicKeys []crypto.PublicKey 34 formerPublicKeys []crypto.PublicKey 35 alsorans map[common.Address]*campaign.Campaign 36 campaigns map[common.Address]*campaign.Campaign 37 startedHeight uint64 38 generateCampaignHeight uint64 39 newTerm bool 40 termChangeInterval int 41 42 mu sync.RWMutex 43 currentTermChange *campaign.TermChange 44 genesisTermChange *campaign.TermChange 45 started bool 46 } 47 48 func NewTerm(id uint32, participantNumber int, termChangeInterval int) *Term { 49 return &Term{ 50 id: id, 51 flag: false, 52 partsNum: participantNumber, 53 termChangeInterval: termChangeInterval, 54 senators: make(Senators), 55 formerSenators: make(map[uint32]Senators), 56 candidates: make(map[common.Address]*campaign.Campaign), 57 alsorans: make(map[common.Address]*campaign.Campaign), 58 campaigns: make(map[common.Address]*campaign.Campaign), 59 } 60 } 61 62 func (t *Term) ID() uint32 { 63 t.mu.RLock() 64 defer t.mu.RUnlock() 65 66 return t.id 67 } 68 69 func (t *Term) UpdateID(id uint32) { 70 t.mu.Lock() 71 defer t.mu.Unlock() 72 73 t.id = id 74 } 75 76 func (t *Term) SwitchFlag(flag bool) { 77 t.mu.Lock() 78 defer t.mu.Unlock() 79 t.flag = flag 80 } 81 82 func (t *Term) SetStartedHeight(h uint64) { 83 t.mu.Lock() 84 defer t.mu.Unlock() 85 t.startedHeight = h 86 } 87 88 func (t *Term) GetGenesisTermChange() *campaign.TermChange { 89 t.mu.RLock() 90 defer t.mu.RUnlock() 91 return t.genesisTermChange 92 } 93 94 func (t *Term) Changing() bool { 95 t.mu.RLock() 96 defer t.mu.RUnlock() 97 98 return t.flag 99 } 100 101 func (t *Term) Started() bool { 102 return t.started 103 } 104 105 func (t *Term) GetCandidate(addr common.Address) *campaign.Campaign { 106 t.mu.RLock() 107 defer t.mu.RUnlock() 108 109 return t.candidates[addr] 110 } 111 112 func (t *Term) Candidates() map[common.Address]*campaign.Campaign { 113 t.mu.RLock() 114 defer t.mu.RUnlock() 115 116 return t.candidates 117 } 118 119 func (t *Term) AddCandidate(c *campaign.Campaign, publicKey crypto.PublicKey) { 120 t.mu.Lock() 121 defer t.mu.Unlock() 122 123 t.candidates[c.Sender()] = c 124 t.publicKeys = append(t.publicKeys, publicKey) 125 //sort.Sort(t.publicKeys) 126 } 127 128 func (t *Term) AddCampaign(c *campaign.Campaign) { 129 t.mu.Lock() 130 defer t.mu.Unlock() 131 132 t.campaigns[c.Sender()] = c 133 } 134 135 func (t *Term) GetCampaign(addr common.Address) *campaign.Campaign { 136 t.mu.RLock() 137 defer t.mu.RUnlock() 138 139 return t.campaigns[addr] 140 } 141 142 func (t *Term) Campaigns() map[common.Address]*campaign.Campaign { 143 t.mu.RLock() 144 defer t.mu.RUnlock() 145 146 return t.campaigns 147 } 148 149 func (t *Term) GetAlsoran(addr common.Address) *campaign.Campaign { 150 t.mu.RLock() 151 defer t.mu.RUnlock() 152 153 return t.alsorans[addr] 154 } 155 156 func (t *Term) Alsorans() map[common.Address]*campaign.Campaign { 157 t.mu.RLock() 158 defer t.mu.RUnlock() 159 160 return t.alsorans 161 } 162 163 func (t *Term) AddAlsorans(camps []*campaign.Campaign) { 164 t.mu.Lock() 165 defer t.mu.Unlock() 166 167 for _, c := range camps { 168 if c == nil { 169 continue 170 } 171 // TODO 172 // this check is not proper enough, try optimize it. 173 if t.hasCampaign(c.Sender()) { 174 continue 175 } 176 t.alsorans[c.Sender()] = c 177 } 178 } 179 180 func (t *Term) HasCampaign(address common.Address) bool { 181 t.mu.RLock() 182 defer t.mu.RUnlock() 183 184 return t.hasCampaign(address) 185 } 186 187 func (t *Term) hasCampaign(address common.Address) bool { 188 if _, exists := t.candidates[address]; exists { 189 log.Debug("exist in candidates") 190 return true 191 } 192 if _, exists := t.campaigns[address]; exists { 193 log.Debug("exist in campaigns") 194 return true 195 } 196 if _, exists := t.alsorans[address]; exists { 197 log.Debug("exist in alsorans") 198 return true 199 } 200 return false 201 } 202 203 // CanChange returns true if the campaigns cached reaches the 204 // term change requirments. 205 func (t *Term) CanChange(lastHeight uint64, isGenesis bool) bool { 206 //TODO change this in future , make more slower 207 var a = 1 208 var b = 0 209 t.mu.RLock() 210 defer t.mu.RUnlock() 211 212 // TODO: 213 // term change requirements are not enough now. 214 if len(t.campaigns) == 0 { 215 return false 216 } 217 if len(t.campaigns) < t.partsNum { 218 log.WithField("len ", len(t.campaigns)).Debug("not enough campaigns , waiting") 219 return false 220 } 221 if isGenesis { 222 log.Debug("is genesis consensus, change term") 223 return true 224 } 225 if lastHeight-t.startedHeight < uint64(t.termChangeInterval*a+b) { 226 return false 227 } 228 return true 229 } 230 231 func (t *Term) ChangeTerm(tc *campaign.TermChange, lastHeight uint64) error { 232 t.mu.Lock() 233 defer t.mu.Unlock() 234 235 snts := make(map[common.Address]*Senator) 236 for addr, c := range t.candidates { 237 s := newSenator(addr, c.PublicKey, tc.PkBls) 238 snts[addr] = s 239 } 240 241 t.formerPublicKeys = t.publicKeys 242 if t.id == 0 { 243 t.genesisTermChange = tc 244 } 245 246 t.currentTermChange = tc 247 248 t.candidates = make(map[common.Address]*campaign.Campaign) 249 t.alsorans = make(map[common.Address]*campaign.Campaign) 250 t.campaigns = make(map[common.Address]*campaign.Campaign) 251 t.publicKeys = nil 252 253 formerSnts := t.senators 254 t.formerSenators[t.id] = formerSnts 255 256 t.senators = snts 257 t.started = true 258 259 // TODO 260 // 1. update id. 261 // 2. process alsorans. 262 263 t.id++ 264 t.startedHeight = lastHeight 265 log.WithField("startedHeight", t.startedHeight).WithField("len senators ", len(t.senators)).WithField("id ", t.id).Info("term changed , id updated") 266 t.flag = false 267 return nil 268 } 269 270 type Senator struct { 271 addr common.Address 272 pk []byte 273 blspk []byte 274 Id int 275 CampaignHash types.Hash 276 // TODO: 277 // more variables? 278 } 279 280 func newSenator(addr common.Address, publickey, blspk []byte) *Senator { 281 s := &Senator{} 282 s.addr = addr 283 s.pk = publickey 284 s.blspk = blspk 285 286 return s 287 } 288 289 type Senators map[common.Address]*Senator 290 291 func (t *Term) GetSenator(address common.Address) *Senator { 292 t.mu.RLock() 293 defer t.mu.RUnlock() 294 if v, ok := t.senators[address]; ok { 295 return v 296 } 297 return nil 298 } 299 300 func (t *Term) ClearCampaigns() { 301 t.mu.Lock() 302 defer t.mu.Unlock() 303 t.campaigns = nil 304 } 305 306 func (t *Term) GetFormerPks() []crypto.PublicKey { 307 return t.formerPublicKeys 308 }