github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/contracts/chief/service.go (about) 1 package chief 2 3 import ( 4 "context" 5 "errors" 6 "math/big" 7 "time" 8 9 "github.com/SmartMeshFoundation/Spectrum/contracts/statute" 10 11 "fmt" 12 13 "github.com/SmartMeshFoundation/Spectrum/accounts/abi/bind" 14 "github.com/SmartMeshFoundation/Spectrum/common" 15 chieflib "github.com/SmartMeshFoundation/Spectrum/contracts/chief/lib" 16 "github.com/SmartMeshFoundation/Spectrum/eth" 17 "github.com/SmartMeshFoundation/Spectrum/internal/ethapi" 18 "github.com/SmartMeshFoundation/Spectrum/les" 19 "github.com/SmartMeshFoundation/Spectrum/log" 20 "github.com/SmartMeshFoundation/Spectrum/node" 21 "github.com/SmartMeshFoundation/Spectrum/p2p" 22 "github.com/SmartMeshFoundation/Spectrum/params" 23 "github.com/SmartMeshFoundation/Spectrum/rpc" 24 ) 25 26 /* 27 type Service interface { 28 Protocols() []p2p.Protocol 29 APIs() []rpc.API 30 Start(server *p2p.Server) error 31 Stop() error 32 } 33 */ 34 35 const DEF_TIMEOUT = time.Second * 3 36 37 // volunteer : peer.td - current.td < 200 38 var ( 39 min_td = big.NewInt(200) 40 ) 41 42 //implements node.Service 43 type TribeService struct { 44 tribeChief_0_0_2 *chieflib.TribeChief 45 tribeChief_0_0_3 *chieflib.TribeChief_0_0_3 46 tribeChief_0_0_4 *chieflib.TribeChief_0_0_4 47 tribeChief_0_0_5 *chieflib.TribeChief_0_0_5 48 tribeChief_0_0_6 *chieflib.TribeChief_0_0_6 49 tribeChief_0_0_7 *chieflib.TribeChief_0_0_7 50 tribeChief_1_0_0 *chieflib.TribeChief_1_0_0 51 poc *chieflib.POC_1_0_0 52 base *chieflib.ChiefBase_1_0_0 53 quit chan int 54 server *p2p.Server // peers and nodekey ... 55 ethereum *eth.Ethereum 56 ctx *node.ServiceContext 57 } 58 59 func NewTribeService(ctx *node.ServiceContext) (node.Service, error) { 60 var ( 61 apiBackend ethapi.Backend 62 ethereum *eth.Ethereum 63 ) 64 if err := ctx.Service(ðereum); err == nil { 65 apiBackend = ethereum.ApiBackend 66 } else { 67 var ethereum *les.LightEthereum 68 if err := ctx.Service(ðereum); err == nil { 69 apiBackend = ethereum.ApiBackend 70 } else { 71 return nil, err 72 } 73 } 74 75 ts := &TribeService{ 76 quit: make(chan int), 77 ethereum: ethereum, 78 ctx: ctx, 79 } 80 if v0_0_2 := params.GetChiefInfoByVsn("0.0.2"); v0_0_2 != nil { 81 contract_0_0_2, err := chieflib.NewTribeChief(v0_0_2.Addr, eth.NewContractBackend(apiBackend)) 82 if err != nil { 83 return nil, err 84 } 85 ts.tribeChief_0_0_2 = contract_0_0_2 86 } 87 if v0_0_3 := params.GetChiefInfoByVsn("0.0.3"); v0_0_3 != nil { 88 contract_0_0_3, err := chieflib.NewTribeChief_0_0_3(v0_0_3.Addr, eth.NewContractBackend(apiBackend)) 89 if err != nil { 90 return nil, err 91 } 92 ts.tribeChief_0_0_3 = contract_0_0_3 93 } 94 if v0_0_4 := params.GetChiefInfoByVsn("0.0.4"); v0_0_4 != nil { 95 contract_0_0_4, err := chieflib.NewTribeChief_0_0_4(v0_0_4.Addr, eth.NewContractBackend(apiBackend)) 96 if err != nil { 97 return nil, err 98 } 99 ts.tribeChief_0_0_4 = contract_0_0_4 100 } 101 if v0_0_5 := params.GetChiefInfoByVsn("0.0.5"); v0_0_5 != nil { 102 contract_0_0_5, err := chieflib.NewTribeChief_0_0_5(v0_0_5.Addr, eth.NewContractBackend(apiBackend)) 103 if err != nil { 104 return nil, err 105 } 106 ts.tribeChief_0_0_5 = contract_0_0_5 107 } 108 if v0_0_6 := params.GetChiefInfoByVsn("0.0.6"); v0_0_6 != nil { 109 contract_0_0_6, err := chieflib.NewTribeChief_0_0_6(v0_0_6.Addr, eth.NewContractBackend(apiBackend)) 110 if err != nil { 111 return nil, err 112 } 113 ts.tribeChief_0_0_6 = contract_0_0_6 114 } 115 if v0_0_7 := params.GetChiefInfoByVsn("0.0.7"); v0_0_7 != nil { 116 contract_0_0_7, err := chieflib.NewTribeChief_0_0_7(v0_0_7.Addr, eth.NewContractBackend(apiBackend)) 117 if err != nil { 118 return nil, err 119 } 120 ts.tribeChief_0_0_7 = contract_0_0_7 121 } 122 if v1_0_0 := params.GetChiefInfoByVsn("1.0.0"); v1_0_0 != nil { 123 ab := eth.NewContractBackend(apiBackend) 124 contract_1_0_0, err := chieflib.NewTribeChief_1_0_0(v1_0_0.Addr, ab) 125 if err != nil { 126 return nil, err 127 } 128 129 ts.tribeChief_1_0_0 = contract_1_0_0 130 poc, err := chieflib.NewPOC_1_0_0(v1_0_0.PocAddr, ab) 131 if err != nil { 132 return nil, err 133 } 134 ts.poc = poc 135 136 base, err := chieflib.NewChiefBase_1_0_0(v1_0_0.BaseAddr, ab) 137 if err != nil { 138 return nil, err 139 } 140 ts.base = base 141 142 log.Info("<<TribeService>> chief-1.0.0 and poc init success.") 143 } 144 return ts, nil 145 } 146 147 func (self *TribeService) Protocols() []p2p.Protocol { return nil } 148 func (self *TribeService) APIs() []rpc.API { return nil } 149 150 func (self *TribeService) Start(server *p2p.Server) error { 151 self.server = server 152 go self.loop() 153 close(params.InitTribeStatus) 154 return nil 155 } 156 func (self *TribeService) loop() { 157 for { 158 select { 159 case <-self.quit: 160 break 161 case mbox := <-params.MboxChan: 162 switch mbox.Method { 163 case "GetStatus": 164 self.getstatus(mbox) 165 case "GetNodeKey": 166 self.getnodekey(mbox) 167 case params.Chief100Update: 168 self.chief100FetchNextRoundSigner(mbox) 169 case "FilterVolunteer": 170 self.filterVolunteer(mbox) 171 case "GetVolunteers": 172 self.getVolunteers(mbox) 173 case "VerifyMiner": // for 1.0.0 vrf selected 174 self.VerifyMiner(mbox) 175 176 } 177 } 178 } 179 } 180 181 func (self *TribeService) Stop() error { 182 close(self.quit) 183 return nil 184 } 185 186 func (self *TribeService) _getVolunteers(blockNumber *big.Int, blockHash common.Hash) (params.ChiefVolunteers, error) { 187 var ( 188 empty = params.ChiefVolunteers{} 189 chiefInfo = params.GetChiefInfo(blockNumber) 190 ) 191 if chiefInfo == nil { 192 log.Debug("=>TribeService.getVolunteers", "empty_chief", chiefInfo.Version, "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 193 return empty, errors.New("can_not_empty_chiefInfo") 194 } else { 195 ctx, cancel := context.WithTimeout(context.Background(), DEF_TIMEOUT) 196 defer cancel() 197 opts := new(bind.CallOptsWithNumber) 198 opts.Context = ctx 199 opts.Hash = &blockHash 200 switch chiefInfo.Version { 201 case "0.0.6": 202 v, err := self.tribeChief_0_0_6.GetVolunteers(opts) 203 if err != nil { 204 log.Error("=>TribeService.getVolunteers", "err", err, "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 205 return empty, err 206 } 207 return params.ChiefVolunteers{ 208 VolunteerList: v.VolunteerList, 209 WeightList: v.WeightList, 210 Length: v.Length, 211 }, nil 212 case "0.0.7": 213 v, err := self.tribeChief_0_0_7.GetVolunteers(opts) 214 if err != nil { 215 log.Error("=>TribeService.getVolunteers", "err", err, "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 216 return empty, err 217 } 218 return params.ChiefVolunteers{ 219 VolunteerList: v.VolunteerList, 220 WeightList: v.WeightList, 221 Length: v.Length, 222 }, nil 223 case "1.0.0": 224 // TODO 225 v, err := self.tribeChief_1_0_0.GetVolunteers(opts) 226 if err != nil { 227 log.Error("=>TribeService.getVolunteers", "err", err, "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 228 return empty, err 229 } 230 return params.ChiefVolunteers{ 231 VolunteerList: v.VolunteerList, 232 WeightList: v.WeightList, 233 Length: v.Length, 234 }, nil 235 default: 236 log.Error("=>TribeService.getVolunteers", "fail_vsn", chiefInfo.Version, "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 237 return empty, errors.New("fail_vsn_now") 238 } 239 } 240 } 241 242 func (self *TribeService) getVolunteers(mbox params.Mbox) { 243 var ( 244 blockNumber *big.Int 245 blockHash common.Hash 246 success = params.MBoxSuccess{Success: true} 247 ) 248 // hash and number can not nil 249 if h, ok := mbox.Params["hash"]; ok { 250 bh := h.(common.Hash) 251 blockHash = bh 252 } 253 if n, ok := mbox.Params["number"]; ok { 254 blockNumber = n.(*big.Int) 255 } 256 entity, err := self._getVolunteers(blockNumber, blockHash) 257 if err == nil { 258 success.Entity = entity 259 } else { 260 success.Success = false 261 success.Entity = err 262 } 263 mbox.Rtn <- success 264 } 265 266 func (self *TribeService) filterVolunteer(mbox params.Mbox) { 267 var ( 268 blockNumber *big.Int 269 blockHash *common.Hash 270 addr common.Address 271 vlist = make([]common.Address, 0, 1) 272 success = params.MBoxSuccess{Success: true} 273 ) 274 // hash and number can not nil 275 if h, ok := mbox.Params["hash"]; ok { 276 bh := h.(common.Hash) 277 blockHash = &bh 278 } 279 if n, ok := mbox.Params["number"]; ok { 280 blockNumber = n.(*big.Int) 281 } 282 if a, ok := mbox.Params["address"]; ok { 283 addr = a.(common.Address) 284 vlist = append(vlist[:], addr) 285 } 286 log.Debug("=>TribeService.filterVolunteer", "blockNumber", blockNumber, "blockHash", blockHash.Hex(), "addr", addr.Hex()) 287 288 chiefInfo := params.GetChiefInfo(blockNumber) 289 if chiefInfo == nil { 290 log.Error("=>TribeService.filterVolunteer", "empty_chief", chiefInfo.Version, "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 291 success.Success = false 292 success.Entity = errors.New("cchiefInfo_can_not_empty") 293 } else { 294 ctx, cancel := context.WithTimeout(context.Background(), DEF_TIMEOUT) 295 defer cancel() 296 opts := new(bind.CallOptsWithNumber) 297 opts.Context = ctx 298 opts.Hash = blockHash 299 switch chiefInfo.Version { 300 case "0.0.6": 301 rlist, err := self.tribeChief_0_0_6.FilterVolunteer(opts, vlist) 302 if err != nil { 303 log.Error("=>TribeService.filterVolunteer", "err", err, "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 304 success.Success = false 305 success.Entity = err 306 } 307 success.Entity = rlist[0] 308 case "0.0.7": 309 rlist, err := self.tribeChief_0_0_7.FilterVolunteer(opts, vlist) 310 if err != nil { 311 log.Error("=>TribeService.filterVolunteer", "err", err, "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 312 success.Success = false 313 success.Entity = err 314 } 315 success.Entity = rlist[0] 316 default: 317 log.Error("=>TribeService.filterVolunteer", "fail_vsn", chiefInfo.Version, "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 318 success.Success = false 319 success.Entity = errors.New("fail_vsn_now") 320 } 321 } 322 mbox.Rtn <- success 323 } 324 325 func (self *TribeService) getnodekey(mbox params.Mbox) { 326 success := params.MBoxSuccess{Success: true} 327 success.Entity = self.server.PrivateKey 328 mbox.Rtn <- success 329 } 330 331 func (self *TribeService) getstatus(mbox params.Mbox) { 332 var ( 333 blockNumber *big.Int = nil 334 blockHash *common.Hash = nil 335 ) 336 // hash and number can not nil 337 if h, ok := mbox.Params["hash"]; ok { 338 bh := h.(common.Hash) 339 blockHash = &bh 340 } 341 if n, ok := mbox.Params["number"]; ok { 342 blockNumber = n.(*big.Int) 343 } 344 log.Debug("=>TribeService.getstatus", "blockNumber", blockNumber, "blockHash", blockHash.Hex()) 345 346 success := params.MBoxSuccess{Success: true} 347 chiefStatus, err := self.getChiefStatus(blockNumber, blockHash) 348 if err != nil { 349 success.Success = false 350 success.Entity = err 351 log.Debug("chief.mbox.rtn: getstatus <-", "success", success.Success, "err", err) 352 } else { 353 entity := chiefStatus 354 success.Entity = entity 355 log.Debug("chief.mbox.rtn: getstatus <-", "success", success.Success) 356 //log.Debug("chief.mbox.rtn: getstatus <-", "success", success.Success, "entity", entity) 357 } 358 mbox.Rtn <- success 359 } 360 func (self *TribeService) chief100FetchNextRoundSigner(mbox params.Mbox) { 361 success := params.MBoxSuccess{Success: true} 362 var ( 363 blockNumber *big.Int 364 hash common.Hash 365 vrfn *big.Int 366 v common.Address 367 ) 368 hash = mbox.Params["hash"].(common.Hash) 369 blockNumber = mbox.Params["number"].(*big.Int) //如果出错.立即崩溃亏即可 370 vrfn = mbox.Params["vrfn"].(*big.Int) 371 if params.IsSIP100Block(blockNumber) { 372 nl := self.minerList(blockNumber, hash) 373 v = self.takeMiner(nl, hash, vrfn.Bytes()) 374 log.Debug("chief.mbox.rtn chief100: update <-", "addr", v.String()) 375 } 376 success.Success = true 377 success.Entity = v 378 mbox.Rtn <- success 379 log.Debug("chief.mbox.rtn: update <-", "success", success) 380 381 } 382 383 // -------------------------------------------------------------------------------------------------- 384 // inner private 385 // -------------------------------------------------------------------------------------------------- 386 func (self *TribeService) getChiefStatus(blockNumber *big.Int, blockHash *common.Hash) (params.ChiefStatus, error) { 387 log.Debug(fmt.Sprintf("[getChiefStatus],blockNumber=%s,blockHash=%s", blockNumber, blockHash.String())) 388 ctx, cancel := context.WithTimeout(context.Background(), DEF_TIMEOUT) 389 defer cancel() 390 //opts := &bind.CallOpts{Context: ctx} 391 opts := new(bind.CallOptsWithNumber) 392 opts.Context = ctx 393 opts.Hash = blockHash 394 if chiefInfo := params.GetChiefInfo(blockNumber); chiefInfo != nil { 395 switch chiefInfo.Version { 396 case "0.0.2": 397 chiefStatus, err := self.tribeChief_0_0_2.GetStatus(opts) 398 if err != nil { 399 return params.ChiefStatus{}, err 400 } 401 return params.ChiefStatus{ 402 VolunteerList: chiefStatus.VolunteerList, 403 SignerList: chiefStatus.SignerList, 404 ScoreList: chiefStatus.ScoreList, 405 NumberList: chiefStatus.NumberList, 406 BlackList: nil, 407 Number: chiefStatus.Number, 408 }, nil 409 case "0.0.3": 410 chiefStatus, err := self.tribeChief_0_0_3.GetStatus(opts) 411 if err != nil { 412 return params.ChiefStatus{}, err 413 } 414 return params.ChiefStatus{ 415 VolunteerList: chiefStatus.VolunteerList, 416 SignerList: chiefStatus.SignerList, 417 ScoreList: chiefStatus.ScoreList, 418 NumberList: chiefStatus.NumberList, 419 BlackList: nil, 420 Number: chiefStatus.Number, 421 }, nil 422 case "0.0.4": 423 chiefStatus, err := self.tribeChief_0_0_4.GetStatus(opts) 424 if err != nil { 425 return params.ChiefStatus{}, err 426 } 427 return params.ChiefStatus{ 428 VolunteerList: chiefStatus.VolunteerList, 429 SignerList: chiefStatus.SignerList, 430 ScoreList: chiefStatus.ScoreList, 431 NumberList: chiefStatus.NumberList, 432 BlackList: nil, 433 Number: chiefStatus.Number, 434 }, nil 435 case "0.0.5": 436 chiefStatus, err := self.tribeChief_0_0_5.GetStatus(opts) 437 if err != nil { 438 return params.ChiefStatus{}, err 439 } 440 epoch, err := self.tribeChief_0_0_5.GetEpoch(opts) 441 if err != nil { 442 return params.ChiefStatus{}, err 443 } 444 signerLimit, err := self.tribeChief_0_0_5.GetSignerLimit(opts) 445 if err != nil { 446 return params.ChiefStatus{}, err 447 } 448 volunteerLimit, err := self.tribeChief_0_0_5.GetVolunteerLimit(opts) 449 if err != nil { 450 return params.ChiefStatus{}, err 451 } 452 return params.ChiefStatus{ 453 VolunteerList: chiefStatus.VolunteerList, 454 SignerList: chiefStatus.SignerList, 455 ScoreList: chiefStatus.ScoreList, 456 NumberList: chiefStatus.NumberList, 457 BlackList: chiefStatus.BlackList, 458 Number: chiefStatus.Number, 459 Epoch: epoch, 460 SignerLimit: signerLimit, 461 VolunteerLimit: volunteerLimit, 462 }, nil 463 case "0.0.6": 464 chiefStatus, err := self.tribeChief_0_0_6.GetStatus(opts) 465 if err != nil { 466 return params.ChiefStatus{}, err 467 } 468 epoch, err := self.tribeChief_0_0_6.GetEpoch(opts) 469 if err != nil { 470 return params.ChiefStatus{}, err 471 } 472 signerLimit, err := self.tribeChief_0_0_6.GetSignerLimit(opts) 473 if err != nil { 474 return params.ChiefStatus{}, err 475 } 476 volunteerLimit, err := self.tribeChief_0_0_6.GetVolunteerLimit(opts) 477 if err != nil { 478 return params.ChiefStatus{}, err 479 } 480 return params.ChiefStatus{ 481 VolunteerList: nil, 482 SignerList: chiefStatus.SignerList, 483 ScoreList: chiefStatus.ScoreList, 484 NumberList: chiefStatus.NumberList, 485 BlackList: chiefStatus.BlackList, 486 Number: chiefStatus.Number, 487 Epoch: epoch, 488 SignerLimit: signerLimit, 489 VolunteerLimit: volunteerLimit, 490 TotalVolunteer: chiefStatus.TotalVolunteer, 491 }, nil 492 case "0.0.7": 493 chiefStatus, err := self.tribeChief_0_0_7.GetStatus(opts) 494 if err != nil { 495 return params.ChiefStatus{}, err 496 } 497 epoch, err := self.tribeChief_0_0_7.GetEpoch(opts) 498 if err != nil { 499 return params.ChiefStatus{}, err 500 } 501 signerLimit, err := self.tribeChief_0_0_7.GetSignerLimit(opts) 502 if err != nil { 503 return params.ChiefStatus{}, err 504 } 505 volunteerLimit, err := self.tribeChief_0_0_7.GetVolunteerLimit(opts) 506 if err != nil { 507 return params.ChiefStatus{}, err 508 } 509 return params.ChiefStatus{ 510 VolunteerList: nil, 511 SignerList: chiefStatus.SignerList, 512 ScoreList: chiefStatus.ScoreList, 513 NumberList: chiefStatus.NumberList, 514 BlackList: chiefStatus.BlackList, 515 Number: chiefStatus.Number, 516 Epoch: epoch, 517 SignerLimit: signerLimit, 518 VolunteerLimit: volunteerLimit, 519 TotalVolunteer: chiefStatus.TotalVolunteer, 520 }, nil 521 case "1.0.0": 522 chiefStatus, err := self.tribeChief_1_0_0.GetStatus(opts) 523 if err != nil { 524 return params.ChiefStatus{}, err 525 } 526 epoch, err := self.tribeChief_1_0_0.GetEpoch(opts) 527 if err != nil { 528 return params.ChiefStatus{}, err 529 } 530 signerLimit, err := self.tribeChief_1_0_0.GetSignerLimit(opts) 531 if err != nil { 532 return params.ChiefStatus{}, err 533 } 534 volunteerLimit, err := self.tribeChief_1_0_0.GetVolunteerLimit(opts) 535 if err != nil { 536 return params.ChiefStatus{}, err 537 } 538 leaderList, leaderLimit, err := self.GetLeaders(blockNumber, blockHash) 539 if err != nil { 540 return params.ChiefStatus{}, err 541 } 542 return params.ChiefStatus{ 543 LeaderLimit: leaderLimit, 544 LeaderList: leaderList, 545 VolunteerList: nil, 546 SignerList: chiefStatus.SignerList, 547 ScoreList: chiefStatus.ScoreList, 548 NumberList: chiefStatus.NumberList, 549 BlackList: chiefStatus.BlackList, 550 Number: chiefStatus.Number, 551 Epoch: epoch, 552 SignerLimit: signerLimit, 553 VolunteerLimit: volunteerLimit, 554 TotalVolunteer: chiefStatus.TotalVolunteer, 555 }, nil 556 } 557 } 558 return params.ChiefStatus{}, errors.New("status_not_found") 559 } 560 561 func (self *TribeService) isVolunteer(dict map[common.Address]interface{}, add common.Address) bool { 562 //TODO ****** 关于选拔的各种规则 563 // Rule.1 : Do not repeat the selection 564 if _, ok := dict[add]; ok { 565 return false 566 } 567 return true 568 } 569 570 func (self *TribeService) VerifyMiner(mbox params.Mbox) { 571 var ( 572 parentblockHash common.Hash 573 addr common.Address 574 vrfn []byte 575 result bool 576 ) 577 578 // hash and number can not nil 579 if parenthash, ok := mbox.Params["parenthash"]; ok { 580 bh := parenthash.(common.Hash) 581 parentblockHash = bh 582 } 583 if a, ok := mbox.Params["addr"]; ok { 584 addr = a.(common.Address) 585 } 586 if a, ok := mbox.Params["vrfn"]; ok { 587 vrfn = a.([]byte) 588 } 589 success := params.MBoxSuccess{Success: true} 590 defer func() { 591 success.Entity = result 592 mbox.Rtn <- success 593 }() 594 result = self.verifyMiner(addr, parentblockHash, vrfn) 595 if !result { 596 log.Error("VerifyMiner failed", "hash", parentblockHash.Hex(), "miners", success.Entity) 597 return 598 } 599 } 600 601 // poc normalList and meshboxList 602 func (self *TribeService) minerList(num *big.Int, hash common.Hash) []common.Address { 603 var ( 604 ss *statute.StatuteService 605 nl = make([]common.Address, 0) 606 opts = new(bind.CallOptsWithNumber) 607 ) 608 ctx, cancel := context.WithTimeout(context.Background(), DEF_TIMEOUT) 609 defer cancel() 610 opts.Context = ctx 611 opts.Hash = &hash 612 613 vll, err := self.poc.GetNormalList(opts) 614 if err != nil { 615 log.Error("poc.GetNormalList__fail", "err", err) 616 } 617 618 err = self.ctx.Service(&ss) 619 if err != nil { 620 log.Error("get_StatuteService_fail", "err", err) 621 } 622 //暂时不允许meshbox参与出块,如果meshbox出快了也需要抵押 623 //mbs, err := ss.GetMeshboxList() 624 //if err != nil { 625 // log.Error("poc.GetMeshboxList__fail", "err", err) 626 //} 627 //if mbs != nil && len(mbs) > 0 { 628 // nl = append(nl, mbs...) 629 //} 630 631 if vll != nil && len(vll) > 0 { 632 nl = append(nl, vll...) 633 } 634 return nl 635 } 636 637 //下一轮出块节点不能包含当前这一轮的出块人以及下一轮已经被选出来的出块人 638 func (self *TribeService) getNextRoundSignerExcludeList(blockNumber *big.Int, blockHash common.Hash) (addrs []common.Address) { 639 //为了兼容考虑,这里的volunteers是已经选出的下一轮出块人列表,可能没有满员 640 vl, err := self._getVolunteers(blockNumber, blockHash) 641 if err != nil { 642 log.Warn("tribeservice_getVolunteers_fail", "err", err) 643 } 644 for _, a := range vl.VolunteerList { 645 addrs = append(addrs, a) 646 } 647 chiefStatus, err := self.getChiefStatus(blockNumber, &blockHash) 648 if err != nil { 649 log.Warn("getChiefStatus", "err", err) 650 } 651 for _, a := range chiefStatus.SignerList { 652 addrs = append(addrs, a) 653 } 654 return addrs 655 } 656 657 //从nl也就是可能出块节列表中根据vrf选择一个,如果选中的人已经在下一轮出块列表中就尝试选择下一个,takerMiner只会在1.0.0版本后使用 658 func (self *TribeService) takeMiner(nl []common.Address, hash common.Hash, _vrfn []byte) common.Address { 659 if nl != nil && len(nl) > 0 { 660 var ( 661 block = self.ethereum.BlockChain().GetBlockByHash(hash) 662 vrfn = new(big.Int).SetBytes(_vrfn[:]) 663 fn func(_vrfn *big.Int) common.Address 664 ) 665 if block == nil { 666 panic(errors.New("get block by hash fail")) 667 } 668 //排除当前signerList的原因是有可能被选中作为下一轮出块节点,但是同时又 669 excludes := self.getNextRoundSignerExcludeList(block.Number(), block.Hash()) 670 fn = func(_vrfn *big.Int) common.Address { 671 m := big.NewInt(int64(len(nl))) 672 x := new(big.Int).Sub(_vrfn, vrfn) 673 if x.Cmp(m) >= 0 { 674 return common.Address{} 675 } 676 idx := new(big.Int).Mod(_vrfn, m) 677 addrLog := make([]string, 0) 678 for _, n := range nl { 679 addrLog = append(addrLog[:], n.Hex()) 680 } 681 log.Debug("fetchVolunteer-1.0.0-volunteers", "num", block.Number(), "addrList", addrLog) 682 // skip if `n` in volunteer list 683 v := nl[idx.Int64()] 684 685 for _, vol := range excludes { 686 if vol == v { 687 return fn(new(big.Int).Add(_vrfn, big.NewInt(1))) 688 } 689 } 690 log.Debug("fetchVolunteer-1.0.0-final", "num", block.Number(), "idx", idx.String(), "addr", v.Hex(), "vrfn", _vrfn) 691 return v 692 } 693 return fn(vrfn) 694 } 695 return common.Address{} 696 } 697 698 func (self *TribeService) verifyMiner(vol common.Address, hash common.Hash, vrfn []byte) bool { 699 block := self.ethereum.BlockChain().GetBlockByHash(hash) 700 ci := params.GetChiefInfo(block.Number()) 701 switch ci.Version { 702 case "1.0.0": 703 m := self.takeMiner(self.minerList(block.Number(), block.Hash()), hash, vrfn) 704 log.Debug("<<TribeService.verifyMiner>>", "result", vol == m, "c", vol.Hex(), "t", m.Hex()) 705 if vol == m { 706 return true 707 } 708 default: 709 return true 710 } 711 return false 712 } 713 714 func (self *TribeService) GetLeaders(num *big.Int, hash *common.Hash) ([]common.Address, *big.Int, error) { 715 ci := params.GetChiefInfo(num) 716 if ci != nil { 717 switch ci.Version { 718 case "1.0.0": 719 var ( 720 leaders = make([]common.Address, 0) 721 opts = new(bind.CallOptsWithNumber) 722 ) 723 ctx, cancel := context.WithTimeout(context.Background(), DEF_TIMEOUT) 724 defer cancel() 725 opts.Context = ctx 726 opts.Hash = hash 727 leaders, err := self.base.TakeLeaderList(opts) 728 if err != nil { 729 return nil, nil, err 730 } 731 limit, err := self.base.TakeLeaderLimit(opts) 732 if err != nil { 733 return nil, nil, err 734 } 735 return leaders, limit, nil 736 } 737 } 738 return nil, nil, errors.New(fmt.Sprintf("not_support_vsn : %s", ci.Version)) 739 }