github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/core/ppos/candidate_state.go (about) 1 package pposm 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "github.com/PlatONnetwork/PlatON-Go/common" 8 "github.com/PlatONnetwork/PlatON-Go/core/ppos_storage" 9 "github.com/PlatONnetwork/PlatON-Go/core/state" 10 "github.com/PlatONnetwork/PlatON-Go/core/types" 11 "github.com/PlatONnetwork/PlatON-Go/core/vm" 12 "github.com/PlatONnetwork/PlatON-Go/log" 13 "github.com/PlatONnetwork/PlatON-Go/p2p/discover" 14 "github.com/PlatONnetwork/PlatON-Go/params" 15 "math/big" 16 "net" 17 "strconv" 18 "strings" 19 "sync" 20 ) 21 22 const ( 23 GET_WITNESS = 1 24 GET_IM_RE = 2 25 GET_WIT_IM_RE = 3 26 ) 27 28 var ( 29 //CandidateEncodeErr = errors.New("Candidate encoding err") 30 //CandidateDecodeErr = errors.New("Candidate decoding err") 31 CandidateEmptyErr = errors.New("Candidate is empty") 32 ContractBalanceNotEnoughErr = errors.New("Contract's balance is not enough") 33 CandidateOwnerErr = errors.New("CandidateOwner Addr is illegal") 34 DepositLowErr = errors.New("Candidate deposit too low") 35 WithdrawPriceErr = errors.New("Withdraw Price err") 36 WithdrawLowErr = errors.New("Withdraw Price too low") 37 RefundEmptyErr = errors.New("Refund is empty") 38 ) 39 40 type candidateStorage map[discover.NodeID]*types.Candidate 41 type refundStorage map[discover.NodeID]types.CandidateQueue 42 43 type CandidatePool struct { 44 // min deposit allow threshold 45 threshold *big.Int 46 // min deposit limit percentage 47 depositLimit uint32 48 // allow put into immedidate condition 49 allowed uint32 50 // allow immediate elected max count 51 maxCount uint32 52 // allow witness max count 53 maxChair uint32 54 // allow block interval for refunds 55 refundBlockNumber uint32 56 57 // previous witness 58 preOriginCandidates candidateStorage 59 // current witnesses 60 originCandidates candidateStorage 61 // next witnesses 62 nextOriginCandidates candidateStorage 63 // immediates 64 immediateCandidates candidateStorage 65 // reserves 66 reserveCandidates candidateStorage 67 // refunds 68 defeatCandidates refundStorage 69 70 // cache 71 //immediateCacheArr types.CandidateQueue 72 //reserveCacheArr types.CandidateQueue 73 74 storage *ppos_storage.Ppos_storage 75 } 76 77 // Initialize the global candidate pool object 78 func NewCandidatePool(configs *params.PposConfig) *CandidatePool { 79 80 log.Debug("Build a New CandidatePool Info ...") 81 if "" == strings.TrimSpace(configs.CandidateConfig.Threshold) { 82 configs.CandidateConfig.Threshold = "1000000000000000000000000" 83 } 84 var threshold *big.Int 85 if thd, ok := new(big.Int).SetString(configs.CandidateConfig.Threshold, 10); !ok { 86 threshold, _ = new(big.Int).SetString("1000000000000000000000000", 10) 87 } else { 88 threshold = thd 89 } 90 return &CandidatePool{ 91 threshold: threshold, 92 depositLimit: configs.CandidateConfig.DepositLimit, 93 allowed: configs.CandidateConfig.Allowed, 94 maxCount: configs.CandidateConfig.MaxCount, 95 maxChair: configs.CandidateConfig.MaxChair, 96 refundBlockNumber: configs.CandidateConfig.RefundBlockNumber, 97 preOriginCandidates: make(candidateStorage, 0), 98 originCandidates: make(candidateStorage, 0), 99 nextOriginCandidates: make(candidateStorage, 0), 100 immediateCandidates: make(candidateStorage, 0), 101 reserveCandidates: make(candidateStorage, 0), 102 defeatCandidates: make(refundStorage, 0), 103 //immediateCacheArr: make(types.CandidateQueue, 0), 104 //reserveCacheArr: make(types.CandidateQueue, 0), 105 } 106 } 107 108 // flag: 109 // 0: only init previous witness and current witness and next witness 110 // 1:init previous witness and current witness and next witness and immediate and reserve 111 // 2: init all information 112 //func (c *CandidatePool) initDataByState(state vm.StateDB, flag int) error { 113 // log.Info("init data by stateDB...", "statedb addr", fmt.Sprintf("%p", state)) 114 // 115 // parentRoutineID := fmt.Sprintf("%s", common.CurrentGoRoutineID()) 116 // 117 // //loading candidates func 118 // loadWitFunc := func(title string, canMap candidateStorage, 119 // getIndexFn func(state vm.StateDB) ([]discover.NodeID, error), 120 // getInfoFn func(state vm.StateDB, id discover.NodeID) (*types.Candidate, error)) error { 121 // 122 // log.Debug("initDataByState by Getting "+title+" parent routine "+parentRoutineID, "statedb addr", fmt.Sprintf("%p", state)) 123 // var witnessIds []discover.NodeID 124 // if ids, err := getIndexFn(state); nil != err { 125 // log.Error("Failed to decode "+title+" witnessIds on initDataByState", " err", err) 126 // return err 127 // } else { 128 // witnessIds = ids 129 // } 130 // 131 // PrintObject(title+" witnessIds", witnessIds) 132 // for _, witnessId := range witnessIds { 133 // 134 // if ca, err := getInfoFn(state, witnessId); nil != err { 135 // log.Error("Failed to decode "+title+" witness Candidate on initDataByState", "err", err) 136 // return CandidateDecodeErr 137 // } else { 138 // if nil != ca { 139 // PrintObject(title+"Id:"+witnessId.String()+", can", ca) 140 // canMap[witnessId] = ca 141 // } else { 142 // delete(canMap, witnessId) 143 // } 144 // } 145 // } 146 // return nil 147 // } 148 // 149 // witErrCh := make(chan error, 3) 150 // var wg sync.WaitGroup 151 // wg.Add(3) 152 // 153 // // loading witnesses 154 // go func() { 155 // c.preOriginCandidates = make(candidateStorage, 0) 156 // witErrCh <- loadWitFunc("previous", c.preOriginCandidates, getPreviousWitnessIdsState, getPreviousWitnessByState) 157 // wg.Done() 158 // }() 159 // go func() { 160 // c.originCandidates = make(candidateStorage, 0) 161 // witErrCh <- loadWitFunc("current", c.originCandidates, getWitnessIdsByState, getWitnessByState) 162 // wg.Done() 163 // }() 164 // go func() { 165 // c.nextOriginCandidates = make(candidateStorage, 0) 166 // witErrCh <- loadWitFunc("next", c.nextOriginCandidates, getNextWitnessIdsByState, getNextWitnessByState) 167 // wg.Done() 168 // }() 169 // var err error 170 // for i := 1; i <= 3; i++ { 171 // if err = <-witErrCh; nil != err { 172 // break 173 // } 174 // } 175 // wg.Wait() 176 // close(witErrCh) 177 // if nil != err { 178 // return err 179 // } 180 // 181 // // loading elected candidates 182 // if flag == 1 || flag == 2 { 183 // 184 // loadElectedFunc := func(title string, canMap candidateStorage, 185 // getIndexFn func(state vm.StateDB) ([]discover.NodeID, error), 186 // getInfoFn func(state vm.StateDB, id discover.NodeID) (*types.Candidate, error)) (types.CandidateQueue, error) { 187 // var witnessIds []discover.NodeID 188 // 189 // log.Debug("initDataByState by Getting "+title+" parent routine "+parentRoutineID, "statedb addr", fmt.Sprintf("%p", state)) 190 // if ids, err := getIndexFn(state); nil != err { 191 // log.Error("Failed to decode "+title+"Ids on initDataByState", " err", err) 192 // return nil, err 193 // } else { 194 // witnessIds = ids 195 // } 196 // // cache 197 // canCache := make(types.CandidateQueue, 0) 198 // 199 // PrintObject(title+" Ids", witnessIds) 200 // for _, witnessId := range witnessIds { 201 // 202 // if ca, err := getInfoFn(state, witnessId); nil != err { 203 // log.Error("Failed to decode "+title+" Candidate on initDataByState", "err", err) 204 // return nil, CandidateDecodeErr 205 // } else { 206 // if nil != ca { 207 // PrintObject(title+"Id:"+witnessId.String()+", can", ca) 208 // canMap[witnessId] = ca 209 // canCache = append(canCache, ca) 210 // } else { 211 // delete(canMap, witnessId) 212 // } 213 // } 214 // } 215 // return canCache, nil 216 // } 217 // type result struct { 218 // Type int // 1: immediate; 2: reserve 219 // Arr types.CandidateQueue 220 // Err error 221 // } 222 // resCh := make(chan *result, 2) 223 // wg.Add(2) 224 // go func() { 225 // res := new(result) 226 // res.Type = IS_IMMEDIATE 227 // c.immediateCandidates = make(candidateStorage, 0) 228 // if arr, err := loadElectedFunc("immediate", c.immediateCandidates, getImmediateIdsByState, getImmediateByState); nil != err { 229 // res.Err = err 230 // resCh <- res 231 // } else { 232 // res.Arr = arr 233 // resCh <- res 234 // } 235 // wg.Done() 236 // }() 237 // go func() { 238 // res := new(result) 239 // res.Type = IS_RESERVE 240 // c.reserveCandidates = make(candidateStorage, 0) 241 // if arr, err := loadElectedFunc("reserve", c.reserveCandidates, getReserveIdsByState, getReserveByState); nil != err { 242 // res.Err = err 243 // resCh <- res 244 // } else { 245 // res.Arr = arr 246 // resCh <- res 247 // } 248 // wg.Done() 249 // }() 250 // wg.Wait() 251 // close(resCh) 252 // for res := range resCh { 253 // if nil != res.Err { 254 // return res.Err 255 // } 256 // switch res.Type { 257 // case IS_IMMEDIATE: 258 // c.immediateCacheArr = res.Arr 259 // case IS_RESERVE: 260 // c.reserveCacheArr = res.Arr 261 // default: 262 // continue 263 // } 264 // } 265 // 266 // } 267 // 268 // // load refunds 269 // if flag == 2 { 270 // 271 // var defeatIds []discover.NodeID 272 // c.defeatCandidates = make(refundStorage, 0) 273 // if ids, err := getDefeatIdsByState(state); nil != err { 274 // log.Error("Failed to decode defeatIds on initDataByState", "err", err) 275 // return err 276 // } else { 277 // defeatIds = ids 278 // } 279 // PrintObject("defeatIds", defeatIds) 280 // for _, defeatId := range defeatIds { 281 // if arr, err := getDefeatsByState(state, defeatId); nil != err { 282 // log.Error("Failed to decode defeat CandidateArr on initDataByState", "err", err) 283 // return CandidateDecodeErr 284 // } else { 285 // if nil != arr && len(arr) != 0 { 286 // PrintObject("defeatId:"+defeatId.String()+", arr", arr) 287 // c.defeatCandidates[defeatId] = arr 288 // } else { 289 // delete(c.defeatCandidates, defeatId) 290 // } 291 // } 292 // } 293 // } 294 // return nil 295 //} 296 297 func (c *CandidatePool) initDataByState(state vm.StateDB) { 298 c.storage = state.GetPPOSCache() 299 300 log.Debug("initDataByState", "state addr", fmt.Sprintf("%p", state)) 301 log.Debug("initDataByState", "ppos storage addr", fmt.Sprintf("%p", c.storage)) 302 } 303 304 // flag: 305 // 1: witness 306 // 2: im and re (im/re) 307 // 3 : wit + im/re 308 func (c *CandidatePool) initData2Cache(state vm.StateDB, flag int) { 309 c.initDataByState(state) 310 311 loadQueueFunc := func(arr types.CandidateQueue, canMap candidateStorage) { 312 for _, can := range arr { 313 canMap[can.CandidateId] = can 314 } 315 } 316 var wg sync.WaitGroup 317 318 switch flag { 319 case GET_WITNESS: 320 wg.Add(3) 321 c.getWitnessMap(&wg, loadQueueFunc) 322 wg.Wait() 323 case GET_IM_RE: 324 wg.Add(2) 325 c.getImAndReMap(&wg, loadQueueFunc) 326 wg.Wait() 327 case GET_WIT_IM_RE: 328 wg.Add(5) 329 c.getWitnessMap(&wg, loadQueueFunc) 330 c.getImAndReMap(&wg, loadQueueFunc) 331 wg.Wait() 332 default: 333 return 334 } 335 } 336 337 func (c *CandidatePool) getWitnessMap(wg *sync.WaitGroup, loadQueueFunc func(arr types.CandidateQueue, canMap candidateStorage)) { 338 go func() { 339 loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.PREVIOUS), c.preOriginCandidates) 340 wg.Done() 341 }() 342 go func() { 343 loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.CURRENT), c.originCandidates) 344 wg.Done() 345 }() 346 go func() { 347 loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.NEXT), c.nextOriginCandidates) 348 wg.Done() 349 }() 350 } 351 func (c *CandidatePool) getImAndReMap(wg *sync.WaitGroup, loadQueueFunc func(arr types.CandidateQueue, canMap candidateStorage)) { 352 go func() { 353 loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.IMMEDIATE), c.immediateCandidates) 354 wg.Done() 355 }() 356 go func() { 357 loadQueueFunc(c.storage.GetCandidateQueue(ppos_storage.RESERVE), c.reserveCandidates) 358 wg.Done() 359 }() 360 } 361 362 // pledge Candidate 363 func (c *CandidatePool) SetCandidate(state vm.StateDB, nodeId discover.NodeID, can *types.Candidate) error { 364 log.Debug("Call SetCandidate start ...", "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber) 365 366 PrintObject("Call SetCandidate start ...", *can) 367 368 c.initData2Cache(state, GET_IM_RE) 369 var nodeIds []discover.NodeID 370 371 // If it is the first pledge, judge the pledge threshold 372 if !c.checkFirstThreshold(can) { 373 log.Warn("Failed to checkFirstThreshold on SetCandidate", "Deposit", can.Deposit.String(), "threshold", c.threshold) 374 return errors.New(DepositLowErr.Error() + ", Current Deposit:" + can.Deposit.String() + ", target threshold:" + fmt.Sprint(c.threshold)) 375 } 376 377 // Before each pledge, we need to check whether the current can deposit is not less 378 // than the minimum can deposit when the corresponding queue to be placed is full. 379 //if _, ok := c.checkDeposit(state, can, false); !ok { 380 if ok := c.checkDeposit(can); !ok { 381 log.Warn("Failed to checkDeposit on SetCandidate", "nodeId", nodeId.String(), " err", DepositLowErr) 382 return DepositLowErr 383 } 384 nodeIds = c.setCandidateInfo(state, nodeId, can, can.BlockNumber, nil) 385 //go ticketPool.DropReturnTicket(state, nodeIds...) 386 if len(nodeIds) > 0 { 387 if err := tContext.DropReturnTicket(state, can.BlockNumber, nodeIds...); nil != err { 388 log.Error("Failed to DropReturnTicket on SetCandidate ...", "current blockNumber", can.BlockNumber, "err", err) 389 //return err 390 } 391 } 392 log.Debug("Call SetCandidate successfully...") 393 return nil 394 } 395 396 // If TCout is small, you must first move to reserves, otherwise it will be counted. 397 func (c *CandidatePool) setCandidateInfo(state vm.StateDB, nodeId discover.NodeID, can *types.Candidate, currentBlockNumber *big.Int, promoteReserveFunc func(state vm.StateDB, currentBlockNumber *big.Int)/* []discover.NodeID*/) []discover.NodeID { 398 399 var allowed, delimmediate, delreserve bool 400 // check ticket count 401 if c.checkTicket(tContext.GetCandidateTicketCount(state, nodeId)) { 402 allowed = true 403 if _, ok := c.reserveCandidates[can.CandidateId]; ok { 404 delreserve = true 405 } 406 c.immediateCandidates[can.CandidateId] = can 407 } else { 408 if _, ok := c.immediateCandidates[can.CandidateId]; ok { 409 delimmediate = true 410 } 411 c.reserveCandidates[can.CandidateId] = can 412 } 413 414 // delete Func 415 delCandidateFunc := func(nodeId discover.NodeID, flag int) { 416 queue := c.getCandidateQueue(flag) 417 /*//for i, id := range ids { 418 for i := 0; i < len(ids); i++ { 419 id := ids[i] 420 if id == can.CandidateId { 421 ids = append(ids[:i], ids[i+1:]...) 422 i-- 423 } 424 }*/ 425 for i, can := range queue { 426 if can.CandidateId == nodeId { 427 queue = append(queue[:i], queue[i+1:]...) 428 break 429 } 430 } 431 c.setCandidateQueue(queue, flag) 432 } 433 434 435 /** 436 handle the reserve queue func 437 */ 438 handleReserveFunc := func(re_queue types.CandidateQueue) []discover.NodeID { 439 440 re_queueCopy := make(types.CandidateQueue, len(re_queue)) 441 copy(re_queueCopy, re_queue) 442 443 str := "Call setCandidateInfo to handleReserveFunc to sort the reserve queue ..." 444 445 // sort reserve array 446 makeCandidateSort(str, state, re_queueCopy) 447 448 nodeIds := make([]discover.NodeID, 0) 449 450 451 if len(re_queueCopy) > int(c.maxCount) { 452 // Intercepting the lost candidates to tmpArr 453 tempArr := (re_queueCopy)[c.maxCount:] 454 // qualified elected candidates 455 re_queueCopy = (re_queueCopy)[:c.maxCount] 456 457 // handle tmpArr 458 for _, tmpCan := range tempArr { 459 deposit, _ := new(big.Int).SetString(tmpCan.Deposit.String(), 10) 460 refund := &types.CandidateRefund{ 461 Deposit: deposit, 462 BlockNumber: big.NewInt(currentBlockNumber.Int64()), 463 Owner: tmpCan.Owner, 464 } 465 c.setRefund(tmpCan.CandidateId, refund) 466 nodeIds = append(nodeIds, tmpCan.CandidateId) 467 } 468 } 469 470 c.setCandidateQueue(re_queueCopy, ppos_storage.RESERVE) 471 472 return nodeIds 473 } 474 475 476 var str string 477 // using the cache handle current queue 478 cacheArr := make(types.CandidateQueue, 0) 479 if allowed { 480 481 /** first delete this can on reserves */ 482 if delreserve { 483 delCandidateFunc(can.CandidateId, ppos_storage.RESERVE) 484 } 485 486 str = "Call setCandidateInfo to sort the immediate queue ..." 487 for _, v := range c.immediateCandidates { 488 cacheArr = append(cacheArr, v) 489 } 490 } else { 491 492 /** first delete this can on immediates */ 493 if delimmediate { 494 delCandidateFunc(can.CandidateId, ppos_storage.IMMEDIATE) 495 } 496 497 498 str = "Call setCandidateInfo to sort the reserve queue ..." 499 for _, v := range c.reserveCandidates { 500 cacheArr = append(cacheArr, v) 501 } 502 } 503 504 505 // sort cache array 506 makeCandidateSort(str, state, cacheArr) 507 508 nodeIds := make([]discover.NodeID, 0) 509 510 if len(cacheArr) > int(c.maxCount) { 511 // Intercepting the lost candidates to tmpArr 512 tempArr := (cacheArr)[c.maxCount:] 513 // qualified elected candidates 514 cacheArr = (cacheArr)[:c.maxCount] 515 516 // add reserve queue cache 517 addreserveQueue := make(types.CandidateQueue, 0) 518 519 // handle tmpArr 520 for _, tmpCan := range tempArr { 521 522 523 // if ticket count great allowed && no need delete reserve 524 // so this can move to reserve from immediate now 525 if allowed { 526 addreserveQueue = append(addreserveQueue, tmpCan) 527 } else { 528 529 deposit, _ := new(big.Int).SetString(tmpCan.Deposit.String(), 10) 530 refund := &types.CandidateRefund{ 531 Deposit: deposit, 532 BlockNumber: big.NewInt(currentBlockNumber.Int64()), 533 Owner: tmpCan.Owner, 534 } 535 c.setRefund(tmpCan.CandidateId, refund) 536 nodeIds = append(nodeIds, tmpCan.CandidateId) 537 } 538 539 } 540 541 if len(addreserveQueue) != 0 { 542 re_queue := c.getCandidateQueue(ppos_storage.RESERVE) 543 re_queue = append(re_queue, addreserveQueue...) 544 if ids := handleReserveFunc(re_queue); len(ids) != 0 { 545 nodeIds = append(nodeIds, ids...) 546 } 547 //c.setCandidateQueue(re_queue, ppos_storage.RESERVE) 548 } 549 550 } 551 552 if allowed { 553 c.setCandidateQueue(cacheArr, ppos_storage.IMMEDIATE) 554 } else { 555 c.setCandidateQueue(cacheArr, ppos_storage.RESERVE) 556 } 557 558 if nil != promoteReserveFunc { 559 promoteReserveFunc(state, currentBlockNumber) 560 } 561 562 return nodeIds 563 } 564 565 566 567 // If TCout is small, you must first move to reserves, otherwise it will be counted. 568 func (c *CandidatePool) electionUpdateCanById(state vm.StateDB, currentBlockNumber *big.Int, nodeIds ... discover.NodeID) []discover.NodeID { 569 570 im_del_temp := make(candidateStorage, 0) 571 re_del_temp := make(candidateStorage, 0) 572 573 for _, nodeId := range nodeIds { 574 // check ticket count 575 if c.checkTicket(tContext.GetCandidateTicketCount(state, nodeId)) { 576 if can, ok := c.reserveCandidates[nodeId]; ok { 577 re_del_temp[nodeId] = can 578 } 579 580 } else { 581 if can, ok := c.immediateCandidates[nodeId]; ok { 582 im_del_temp[nodeId] = can 583 } 584 } 585 } 586 587 if len(im_del_temp) == 0 && len(re_del_temp) == 0 { 588 log.Debug("Call Election to electionUpdateCanById, had not change on double queue ...") 589 return nil 590 } 591 592 im_queue := c.getCandidateQueue(ppos_storage.IMMEDIATE) 593 594 re_queue := c.getCandidateQueue(ppos_storage.RESERVE) 595 596 597 PrintObject("Call Election to electionUpdateCanById, Before shuffle double queue the old immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue) 598 599 PrintObject("Call Election to electionUpdateCanById, Before shuffle double queue the old reserve queue len:=" + fmt.Sprint(len(re_queue)) + " ,queue is", re_queue) 600 601 // immediate queue 602 for _, can := range re_del_temp{ 603 im_queue = append(im_queue, can) 604 } 605 // for i := 0; i < len(ids); i++ { 606 for i := 0; i < len(im_queue); i++ { 607 im := im_queue[i] 608 if _, ok := im_del_temp[im.CandidateId]; ok { 609 im_queue = append(im_queue[:i], im_queue[i+1:]...) 610 i-- 611 } 612 } 613 614 // reserve queue 615 for i := 0; i < len(re_queue); i++ { 616 re := re_queue[i] 617 if _, ok := re_del_temp[re.CandidateId]; ok { 618 re_queue = append(re_queue[:i], re_queue[i+1:]...) 619 i-- 620 } 621 } 622 for _, can := range im_del_temp { 623 re_queue = append(re_queue, can) 624 } 625 626 627 PrintObject("Call Election to electionUpdateCanById, After shuffle double queue the old immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue) 628 629 PrintObject("Call Election to electionUpdateCanById, After shuffle double queue the old reserve queue len:=" + fmt.Sprint(len(re_queue)) + " ,queue is", re_queue) 630 631 632 /** 633 handle the reserve queue func 634 */ 635 handleReserveFunc := func(re_queue types.CandidateQueue) []discover.NodeID { 636 637 re_queueCopy := make(types.CandidateQueue, len(re_queue)) 638 copy(re_queueCopy, re_queue) 639 640 str := "Call Election to handleReserveFunc to sort the reserve queue ..." 641 642 // sort reserve array 643 makeCandidateSort(str, state, re_queueCopy) 644 645 nodeIds := make([]discover.NodeID, 0) 646 647 648 if len(re_queueCopy) > int(c.maxCount) { 649 // Intercepting the lost candidates to tmpArr 650 tempArr := (re_queueCopy)[c.maxCount:] 651 // qualified elected candidates 652 re_queueCopy = (re_queueCopy)[:c.maxCount] 653 654 // handle tmpArr 655 for _, tmpCan := range tempArr { 656 deposit, _ := new(big.Int).SetString(tmpCan.Deposit.String(), 10) 657 refund := &types.CandidateRefund{ 658 Deposit: deposit, 659 BlockNumber: big.NewInt(currentBlockNumber.Int64()), 660 Owner: tmpCan.Owner, 661 } 662 c.setRefund(tmpCan.CandidateId, refund) 663 nodeIds = append(nodeIds, tmpCan.CandidateId) 664 } 665 } 666 667 PrintObject("Call Election to electionUpdateCanById to handleReserveFunc, Finally shuffle double queue the old reserve queue len:=" + fmt.Sprint(len(re_queueCopy)) + " ,queue is", re_queueCopy) 668 669 c.setCandidateQueue(re_queueCopy, ppos_storage.RESERVE) 670 671 return nodeIds 672 } 673 674 675 676 677 678 str := "Call Election to start sort immediate queue ..." 679 680 // sort immediate array 681 makeCandidateSort(str, state, im_queue) 682 683 nodeIdArr := make([]discover.NodeID, 0) 684 685 if len(im_queue) > int(c.maxCount) { 686 // Intercepting the lost candidates to tmpArr 687 tempArr := (im_queue)[c.maxCount:] 688 // qualified elected candidates 689 im_queue = (im_queue)[:c.maxCount] 690 691 // add reserve queue cache 692 addreserveQueue := make(types.CandidateQueue, 0) 693 694 // handle tmpArr 695 for _, tmpCan := range tempArr { 696 addreserveQueue = append(addreserveQueue, tmpCan) 697 } 698 699 if len(addreserveQueue) != 0 { 700 // append into reserve queue 701 re_queue = append(re_queue, addreserveQueue...) 702 } 703 704 }/*else { 705 PrintObject("Call Election to electionUpdateCanById to direct, Finally shuffle double queue the old reserve queue is", re_queue) 706 c.setCandidateQueue(re_queue, ppos_storage.RESERVE) 707 }*/ 708 709 // hanle and sets reserve queue 710 if ids := handleReserveFunc(re_queue); len(ids) != 0 { 711 nodeIdArr = append(nodeIdArr, ids...) 712 } 713 714 PrintObject("Call Election to electionUpdateCanById, Finally shuffle double queue the old immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue) 715 // set immediate queue 716 c.setCandidateQueue(im_queue, ppos_storage.IMMEDIATE) 717 718 c.promoteReserveQueue(state, currentBlockNumber) 719 720 return nodeIdArr 721 } 722 723 724 725 // Getting immediate or reserve candidate info by nodeId 726 func (c *CandidatePool) GetCandidate(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) *types.Candidate { 727 return c.getCandidate(state, nodeId, blockNumber) 728 } 729 730 // Getting immediate or reserve candidate info arr by nodeIds 731 func (c *CandidatePool) GetCandidateArr(state vm.StateDB, blockNumber *big.Int, nodeIds ...discover.NodeID) types.CandidateQueue { 732 return c.getCandidates(state, blockNumber, nodeIds...) 733 } 734 735 // candidate withdraw from immediates or reserve elected candidates 736 func (c *CandidatePool) WithdrawCandidate(state vm.StateDB, nodeId discover.NodeID, price, blockNumber *big.Int) error { 737 log.Info("WithdrawCandidate...", "nodeId", nodeId.String(), "price", price.String(), "blockNumber", blockNumber.String(), "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber) 738 739 c.initData2Cache(state, GET_IM_RE) 740 var nodeIds []discover.NodeID 741 742 if arr, err := c.withdrawCandidate(state, nodeId, price, blockNumber); nil != err { 743 return err 744 } else { 745 nodeIds = arr 746 } 747 //go ticketPool.DropReturnTicket(state, nodeIds...) 748 if len(nodeIds) > 0 { 749 if err := tContext.DropReturnTicket(state, blockNumber, nodeIds...); nil != err { 750 log.Error("Failed to DropReturnTicket on WithdrawCandidate ...", "blockNumber", blockNumber.String(), "err", err) 751 } 752 } 753 return nil 754 } 755 756 func (c *CandidatePool) withdrawCandidate(state vm.StateDB, nodeId discover.NodeID, price, blockNumber *big.Int) ([]discover.NodeID, error) { 757 758 if price.Cmp(new(big.Int).SetUint64(0)) <= 0 { 759 log.Error("Failed to WithdrawCandidate price invalid", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), " price", price.String()) 760 return nil, WithdrawPriceErr 761 } 762 763 // cache 764 var can *types.Candidate 765 var isImmediate bool 766 767 if imCan, ok := c.immediateCandidates[nodeId]; !ok { 768 reCan, ok := c.reserveCandidates[nodeId] 769 if !ok { 770 log.Error("Failed to WithdrawCandidate current Candidate is empty", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), "price", price.String()) 771 return nil, CandidateEmptyErr 772 } else { 773 can = reCan 774 } 775 } else { 776 can = imCan 777 isImmediate = true 778 } 779 780 781 // delete Func 782 delCandidateFunc := func(nodeId discover.NodeID, flag int) { 783 queue := c.getCandidateQueue(flag) 784 785 for i, can := range queue { 786 if can.CandidateId == nodeId { 787 queue = append(queue[:i], queue[i+1:]...) 788 break 789 } 790 } 791 c.setCandidateQueue(queue, flag) 792 } 793 794 var nodeIdArr []discover.NodeID 795 deposit, _ := new(big.Int).SetString(can.Deposit.String(), 10) 796 // check withdraw price 797 if can.Deposit.Cmp(price) < 0 { 798 log.Error("Failed to WithdrawCandidate refund price must less or equal deposit", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), " price", price.String()) 799 return nil, WithdrawPriceErr 800 } else if can.Deposit.Cmp(price) == 0 { // full withdraw 801 802 log.Info("WithdrawCandidate into full withdraw", "blockNumber", blockNumber.String(), "canId", can.CandidateId.String(), "current can deposit", can.Deposit.String(), "withdraw price is", price.String()) 803 804 if isImmediate { 805 delCandidateFunc(can.CandidateId, ppos_storage.IMMEDIATE) 806 } else { 807 delCandidateFunc(can.CandidateId, ppos_storage.RESERVE) 808 } 809 810 refund := &types.CandidateRefund{ 811 Deposit: deposit, 812 BlockNumber: big.NewInt(blockNumber.Int64()), 813 Owner: can.Owner, 814 } 815 816 c.setRefund(can.CandidateId, refund) 817 818 c.promoteReserveQueue(state, blockNumber) 819 820 nodeIds := []discover.NodeID{nodeId} 821 822 nodeIdArr = nodeIds 823 824 } else { // withdraw a few ... 825 /*// Only withdraw part of the refunds, need to reorder the immediate elected candidates 826 // The remaining candiate price to update current candidate info 827 828 log.Info("WithdrawCandidate into withdraw a few", "canId", can.CandidateId.String(), "current can deposit", can.Deposit.String(), "withdraw price is", price.String()) 829 830 if err := c.checkWithdraw(can.Deposit, price); nil != err { 831 log.Error("Failed to price invalid on WithdrawCandidate", " price", price.String(), "err", err) 832 return nil, err 833 } 834 835 remainMoney := new(big.Int).Sub(can.Deposit, price) 836 half_threshold := new(big.Int).Mul(c.threshold, big.NewInt(2)) 837 838 var isFullWithdraw bool 839 var canNew *types.Candidate 840 var refund *types.CandidateRefund 841 842 if remainMoney.Cmp(half_threshold) < 0 { // full withdraw 843 isFullWithdraw = true 844 845 refund = &types.CandidateRefund{ 846 Deposit: deposit, 847 BlockNumber: big.NewInt(blockNumber.Int64()), 848 Owner: can.Owner, 849 } 850 851 } else { 852 // remain info 853 canNew = &types.Candidate{ 854 Deposit: remainMoney, 855 BlockNumber: big.NewInt(can.BlockNumber.Int64()), 856 TxIndex: can.TxIndex, 857 CandidateId: can.CandidateId, 858 Host: can.Host, 859 Port: can.Port, 860 Owner: can.Owner, 861 Extra: can.Extra, 862 Fee: can.Fee, 863 } 864 865 refund = &types.CandidateRefund{ 866 Deposit: price, 867 BlockNumber: big.NewInt(blockNumber.Int64()), 868 Owner: can.Owner, 869 } 870 871 } 872 873 if isFullWithdraw { 874 if isImmediate { 875 delCandidateFunc(can.CandidateId, ppos_storage.IMMEDIATE) 876 } else { 877 delCandidateFunc(can.CandidateId, ppos_storage.RESERVE) 878 } 879 880 c.setRefund(can.CandidateId, refund) 881 882 nIds := c.shuffleQueue(state, blockNumber) 883 nodeIds := []discover.NodeID{nodeId} 884 885 if len(nIds) != 0 { 886 nodeIds = append(nodeIds, nIds...) 887 } 888 889 nodeIdArr = nodeIds 890 } else { 891 892 handleFunc := func(nodeId discover.NodeID, flag int) { 893 queue := c.getCandidateQueue(flag) 894 895 for i, can := range queue { 896 if can.CandidateId == nodeId { 897 queue[i] = canNew 898 break 899 } 900 } 901 c.setCandidateQueue(queue, flag) 902 c.setRefund(nodeId, refund) 903 } 904 905 if isImmediate { 906 handleFunc(can.CandidateId, ppos_storage.IMMEDIATE) 907 } else { 908 handleFunc(can.CandidateId, ppos_storage.RESERVE) 909 } 910 nodeIdArr = append(nodeIdArr, nodeId) 911 if arr := c.shuffleQueue(state, blockNumber); len(arr) != 0 { 912 nodeIdArr = append(nodeIdArr, arr...) 913 } 914 }*/ 915 log.Error("Failed to WithdrawCandidate, must full withdraw", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), "the can deposit", can.Deposit.String(), "current will withdraw price", price.String()) 916 return nil, WithdrawLowErr 917 } 918 log.Info("Call WithdrawCandidate SUCCESS !!!!!!!!!!!!") 919 return nodeIdArr, nil 920 } 921 922 // Getting elected candidates array 923 // flag: 924 // 0: Getting all elected candidates array 925 // 1: Getting all immediate elected candidates array 926 // 2: Getting all reserve elected candidates array 927 func (c *CandidatePool) GetChosens(state vm.StateDB, flag int, blockNumber *big.Int) types.KindCanQueue { 928 log.Debug("Call GetChosens getting immediate or reserve candidates ...", "blockNumber", blockNumber.String(), "flag", flag) 929 c.initDataByState(state) 930 im := make(types.CandidateQueue, 0) 931 re := make(types.CandidateQueue, 0) 932 arr := make(types.KindCanQueue, 0) 933 if flag == 0 || flag == 1 { 934 im = c.getCandidateQueue(ppos_storage.IMMEDIATE) 935 } 936 if flag == 0 || flag == 2 { 937 re = c.getCandidateQueue(ppos_storage.RESERVE) 938 939 } 940 arr = append(arr, im, re) 941 PrintObject("GetChosens return", arr) 942 return arr 943 } 944 945 // Getting elected candidates array 946 // flag: 947 // 0: Getting all elected candidates array 948 // 1: Getting all immediate elected candidates array 949 // 2: Getting all reserve elected candidates array 950 func (c *CandidatePool) GetCandidatePendArr(state vm.StateDB, flag int, blockNumber *big.Int) types.CandidateQueue { 951 log.Debug("Call GetCandidatePendArr getting immediate candidates ...", "blockNumber", blockNumber.String(), "flag", flag) 952 c.initDataByState(state) 953 arr := make(types.CandidateQueue, 0) 954 if flag == 0 || flag == 1 { 955 if queue := c.getCandidateQueue(ppos_storage.IMMEDIATE); len(queue) != 0 { 956 arr = append(arr, queue...) 957 } 958 } 959 if flag == 0 || flag == 2 { 960 if queue := c.getCandidateQueue(ppos_storage.RESERVE); len(queue) != 0 { 961 arr = append(arr, queue...) 962 } 963 } 964 PrintObject("GetChosens ==>", arr) 965 return arr 966 } 967 968 // Getting current witness array 969 func (c *CandidatePool) GetChairpersons(state vm.StateDB, blockNumber *big.Int) types.CandidateQueue { 970 log.Debug("Call GetChairpersons getting witnesses ...", "blockNumber", blockNumber.String()) 971 c.initDataByState(state) 972 return c.getCandidateQueue(ppos_storage.CURRENT) 973 } 974 975 // Getting all refund array by nodeId 976 func (c *CandidatePool) GetDefeat(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) types.RefundQueue { 977 log.Debug("Call GetDefeat getting defeat arr", "blockNumber", blockNumber, "nodeId", nodeId.String()) 978 c.initDataByState(state) 979 return c.getRefunds(nodeId) 980 } 981 982 // Checked current candidate was defeat by nodeId 983 func (c *CandidatePool) IsDefeat(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) bool { 984 log.Debug("Call IsDefeat", "blockNumber", blockNumber.String()) 985 986 c.initData2Cache(state, GET_IM_RE) 987 988 if _, ok := c.immediateCandidates[nodeId]; ok { 989 return false 990 } 991 if _, ok := c.reserveCandidates[nodeId]; ok { 992 return false 993 } 994 if queue := c.getRefunds(nodeId); len(queue) != 0 { 995 return true 996 } 997 return false 998 } 999 1000 func (c *CandidatePool) IsChosens(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) bool { 1001 log.Debug("Call IsChosens", "blockNumber", blockNumber.String()) 1002 c.initData2Cache(state, GET_IM_RE) 1003 if _, ok := c.immediateCandidates[nodeId]; ok { 1004 return true 1005 } 1006 if _, ok := c.reserveCandidates[nodeId]; ok { 1007 return true 1008 } 1009 return false 1010 } 1011 1012 // Getting owner's address of candidate info by nodeId 1013 func (c *CandidatePool) GetOwner(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) common.Address { 1014 log.Debug("Call GetOwner", "blockNumber", blockNumber.String(), "curr nodeId", nodeId.String()) 1015 1016 //c.initData2Cache(state, GET_WIT_IM_RE) 1017 c.initData2Cache(state, GET_IM_RE) 1018 1019 /*pre_can, pre_ok := c.preOriginCandidates[nodeId] 1020 or_can, or_ok := c.originCandidates[nodeId] 1021 ne_can, ne_ok := c.nextOriginCandidates[nodeId]*/ 1022 1023 im_can, im_ok := c.immediateCandidates[nodeId] 1024 re_can, re_ok := c.reserveCandidates[nodeId] 1025 1026 queue := c.getRefunds(nodeId) 1027 1028 de_ok := len(queue) != 0 1029 1030 /* 1031 if pre_ok { 1032 return pre_can.Owner 1033 } 1034 if or_ok { 1035 return or_can.Owner 1036 } 1037 if ne_ok { 1038 return ne_can.Owner 1039 }*/ 1040 if im_ok { 1041 return im_can.Owner 1042 } 1043 if re_ok { 1044 return re_can.Owner 1045 } 1046 if de_ok { 1047 return queue[0].Owner 1048 } 1049 return common.Address{} 1050 } 1051 1052 // refund once 1053 func (c *CandidatePool) RefundBalance(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) error { 1054 1055 log.Info("Call RefundBalance", "curr blocknumber", blockNumber.String(), "curr nodeId", nodeId.String(), "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber) 1056 1057 c.initDataByState(state) 1058 queueCopy := c.getRefunds(nodeId) 1059 1060 if len(queueCopy) == 0 { 1061 log.Warn("Warning Call RefundBalance the refund is empty") 1062 return RefundEmptyErr 1063 } 1064 // cache 1065 // Used for verification purposes, that is, the beneficiary in the pledge refund information of each nodeId should be the same 1066 var addr common.Address 1067 // Grand total refund amount for one-time 1068 amount := big.NewInt(0) 1069 1070 // cantract balance 1071 contractBalance := state.GetBalance(common.CandidatePoolAddr) 1072 1073 1074 PrintObject("Call RefundBalance Into a few RefundBlockNumber Remain Refund Arr ,Before Calculate curr blocknumber:" + blockNumber.String() + " ,len:=" + fmt.Sprint(len(queueCopy)) + " ,refunds is", queueCopy) 1075 1076 // Traverse all refund information belong to this nodeId 1077 for index := 0; index < len(queueCopy); index++ { 1078 refund := queueCopy[index] 1079 sub := new(big.Int).Sub(blockNumber, refund.BlockNumber) 1080 log.Info("Check defeat detail on RefundBalance", "nodeId:", nodeId.String(), "curr blocknumber:", blockNumber.String(), "withdraw candidate blocknumber:", refund.BlockNumber.String(), " diff:", sub.String(), "config.RefundBlockNumber", c.refundBlockNumber) 1081 if sub.Cmp(new(big.Int).SetUint64(uint64(c.refundBlockNumber))) >= 0 { // allow refund 1082 1083 queueCopy = append(queueCopy[:index], queueCopy[index+1:]...) 1084 index-- 1085 // add up the refund price 1086 amount = new(big.Int).Add(amount, refund.Deposit) 1087 1088 } else { 1089 log.Warn("block height number had mismatch, No refunds allowed on RefundBalance", "curr blocknumber:", blockNumber.String(), "deposit block height", refund.BlockNumber.String(), "nodeId", nodeId.String(), "allowed block interval", c.refundBlockNumber) 1090 continue 1091 } 1092 1093 if addr == common.ZeroAddr { 1094 addr = refund.Owner 1095 } else { 1096 if addr != refund.Owner { 1097 log.Error("Failed to RefundBalance Different beneficiary addresses under the same node", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String(), "addr1", addr.String(), "addr2", refund.Owner) 1098 return CandidateOwnerErr 1099 } 1100 } 1101 1102 // check contract account balance 1103 if (contractBalance.Cmp(amount)) < 0 { 1104 PrintObject("Failed to RefundBalance constract account insufficient balance ,curr blocknumber:" + blockNumber.String() + ",len:=" + fmt.Sprint(len(queueCopy)) + " ,remain refunds is", queueCopy) 1105 log.Error("Failed to RefundBalance constract account insufficient balance ", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String(), "contract's balance", state.GetBalance(common.CandidatePoolAddr).String(), "amount", amount.String()) 1106 return ContractBalanceNotEnoughErr 1107 } 1108 } 1109 1110 PrintObject("Call RefundBalance Into a few RefundBlockNumber Remain Refund Arr , After Calculate curr blocknumber:" + blockNumber.String() + " ,len:=" + fmt.Sprint(len(queueCopy)) + " ,refunds is", queueCopy) 1111 1112 // update the tire 1113 if len(queueCopy) == 0 { // full RefundBlockNumber 1114 log.Info("Call RefundBalance Into full RefundBlockNumber ...", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String()) 1115 c.delRefunds(nodeId) 1116 } else { 1117 log.Info("Call RefundBalance Into a few RefundBlockNumber ...", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String()) 1118 // If have some remaining, update that 1119 c.setRefunds(nodeId, queueCopy) 1120 } 1121 log.Info("Call RefundBalance to tansfer value:", "curr blocknumber:", blockNumber.String(), "nodeId", nodeId.String(), "contractAddr", common.CandidatePoolAddr.String(), 1122 "owner's addr", addr.String(), "Return the amount to be transferred:", amount.String()) 1123 1124 // sub contract account balance 1125 state.SubBalance(common.CandidatePoolAddr, amount) 1126 // add owner balace 1127 state.AddBalance(addr, amount) 1128 log.Debug("Call RefundBalance success ...") 1129 return nil 1130 } 1131 1132 // set elected candidate extra value 1133 func (c *CandidatePool) SetCandidateExtra(state vm.StateDB, nodeId discover.NodeID, extra string) error { 1134 1135 log.Info("Call SetCandidateExtra:", "nodeId", nodeId.String(), "extra", extra) 1136 1137 c.initDataByState(state) 1138 im_queue := c.getCandidateQueue(ppos_storage.IMMEDIATE) 1139 1140 for i, can := range im_queue { 1141 if can.CandidateId == nodeId { 1142 can.Extra = extra 1143 im_queue[i] = can 1144 c.setCandidateQueue(im_queue, ppos_storage.IMMEDIATE) 1145 log.Debug("Call SetCandidateExtra SUCCESS !!!!!! ") 1146 return nil 1147 } 1148 } 1149 1150 re_queue := c.getCandidateQueue(ppos_storage.RESERVE) 1151 1152 for i, can := range re_queue { 1153 if can.CandidateId == nodeId { 1154 can.Extra = extra 1155 re_queue[i] = can 1156 c.setCandidateQueue(re_queue, ppos_storage.RESERVE) 1157 log.Debug("Call SetCandidateExtra SUCCESS !!!!!! ") 1158 return nil 1159 } 1160 } 1161 return CandidateEmptyErr 1162 } 1163 1164 // Announce witness 1165 func (c *CandidatePool) Election(state *state.StateDB, parentHash common.Hash, currBlockNumber *big.Int) ([]*discover.Node, error) { 1166 log.Info("Call Election start ...", "current blockNumber", currBlockNumber.String(), "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber) 1167 c.initData2Cache(state, GET_IM_RE) 1168 1169 var nodes []*discover.Node 1170 var nextQueue types.CandidateQueue 1171 var isEmptyElection bool 1172 1173 if nodeArr, canArr, flag, err := c.election(state, parentHash, currBlockNumber); nil != err { 1174 return nil, err 1175 } else { 1176 nodes, nextQueue, isEmptyElection = nodeArr, canArr, flag 1177 } 1178 1179 1180 nodeIds := make([]discover.NodeID, 0) 1181 1182 for _, can := range nextQueue { 1183 // Release lucky ticket TODO 1184 if (common.Hash{}) != can.TxHash { 1185 if err := tContext.ReturnTicket(state, can.CandidateId, can.TxHash, currBlockNumber); nil != err { 1186 log.Error("Failed to ReturnTicket on Election", "current blockNumber", currBlockNumber.String(), "nodeId", can.CandidateId.String(), "ticketId", can.TxHash.String(), "err", err) 1187 continue 1188 } 1189 1190 if !isEmptyElection { 1191 nodeIds = append(nodeIds, can.CandidateId) 1192 } 1193 } 1194 1195 /** 1196 handing before Re-pledging 1197 */ 1198 /*if flag, nIds := c.repledgCheck(state, can, currBlockNumber); !flag { 1199 nodeIds = append(nodeIds, nIds...) 1200 // continue handle next one 1201 continue 1202 }*/ 1203 1204 /*if !isEmptyElection { 1205 PrintObject("Election Update Candidate to SetCandidate again ...", *can) 1206 // Because you need to first ensure if you are in immediates, and if so, move to reserves 1207 if ids := c.setCandidateInfo(state, can.CandidateId, can, currBlockNumber, c.promoteReserveQueue); len(ids) != 0 { 1208 nodeIds = append(nodeIds, ids...) 1209 } 1210 }*/ 1211 1212 } 1213 1214 1215 //var dropTick_nodeIds []discover.NodeID 1216 1217 // finally update the double queue once 1218 if !isEmptyElection && len(nodeIds) != 0 { 1219 1220 nodeIds = c.electionUpdateCanById(state, currBlockNumber, nodeIds...) 1221 } 1222 1223 // Release the lost list 1224 //go ticketPool.DropReturnTicket(state, nodeIds...) 1225 if len(nodeIds) > 0 { 1226 if err := tContext.DropReturnTicket(state, currBlockNumber, nodeIds...); nil != err { 1227 log.Error("Failed to DropReturnTicket on Election ...", "current blockNumber", currBlockNumber.String(), "err", err) 1228 } 1229 } 1230 return nodes, nil 1231 } 1232 1233 //return params 1234 // []*discover.Node: the cleaned nodeId 1235 // types.CandidateQueue: the next witness 1236 // bool: is empty election 1237 // error: err 1238 func (c *CandidatePool) election(state *state.StateDB, parentHash common.Hash, blockNumber *big.Int) ([]*discover.Node, types.CandidateQueue, bool, error) { 1239 1240 imm_queue := c.getCandidateQueue(ppos_storage.IMMEDIATE) 1241 1242 str := "When Election, to election to sort immediate queue ..." 1243 // sort immediate candidates 1244 makeCandidateSort(str, state, imm_queue) 1245 1246 log.Info("When Election, Sorted the immediate array length:", "current blockNumber", blockNumber.String(), "len", len(imm_queue)) 1247 PrintObject("When Election, Sorted the immediate array: current blockNumber:" + blockNumber.String() + ":", imm_queue) 1248 // cache ids 1249 immediateIds := make([]discover.NodeID, len(imm_queue)) 1250 for i, can := range imm_queue { 1251 immediateIds[i] = can.CandidateId 1252 } 1253 PrintObject("When Election, current immediate is: current blockNumber:" + blockNumber.String() + " ,len:=" + fmt.Sprint(len(immediateIds)) + " ,arr is:", immediateIds) 1254 1255 // a certain number of witnesses in front of the cache 1256 var nextIdArr []discover.NodeID 1257 // If the number of candidate selected does not exceed the number of witnesses 1258 if len(immediateIds) <= int(c.maxChair) { 1259 nextIdArr = make([]discover.NodeID, len(immediateIds)) 1260 copy(nextIdArr, immediateIds) 1261 1262 } else { 1263 // If the number of candidate selected exceeds the number of witnesses, the top N is extracted. 1264 nextIdArr = make([]discover.NodeID, c.maxChair) 1265 copy(nextIdArr, immediateIds) 1266 } 1267 1268 log.Info("When Election, Selected next round of witnesses Ids's count:", "current blockNumber", blockNumber.String(), "len", len(nextIdArr)) 1269 PrintObject("When Election, Selected next round of witnesses Ids: current blockNumber:" + blockNumber.String() + ":", nextIdArr) 1270 1271 nextQueue := make(types.CandidateQueue, len(nextIdArr)) 1272 1273 1274 for i, next_canId := range nextIdArr { 1275 im_can := c.immediateCandidates[next_canId] 1276 // deepCopy 1277 can := *im_can 1278 nextQueue[i] = &can 1279 } 1280 1281 1282 log.Info("When Election, the count of the copy the witness info from immediate:", "current blockNumber", blockNumber.String(), "len", len(nextQueue)) 1283 PrintObject("When Election, the information of the copy the witness info from immediate: current blockNumber:" + blockNumber.String() + ":", nextQueue) 1284 1285 // clear all old nextwitnesses information (If it is forked, the next round is no empty.) 1286 c.delCandidateQueue(ppos_storage.NEXT) 1287 1288 nodeArr := make([]*discover.Node, 0) 1289 // Check election whether it's empty or not 1290 nextQueue, isEmptyElection := c.handleEmptyElection(nextQueue) 1291 1292 // handle all next witness information 1293 for i, can := range nextQueue { 1294 // After election to call Selected LuckyTicket TODO 1295 luckyId, err := tContext.SelectionLuckyTicket(state, can.CandidateId, parentHash) 1296 if nil != err { 1297 log.Error("Failed to take luckyId on Election", "current blockNumber", blockNumber.String(), "nodeId", can.CandidateId.String(), "err", err) 1298 return nil, nil, false, errors.New(err.Error() + ", nodeId: " + can.CandidateId.String()) 1299 } 1300 log.Debug("Call Election, select lucky ticket Id is", "current blockNumber", blockNumber.String(), "lucky ticket Id", luckyId.Hex()) 1301 if can.TxHash != luckyId { 1302 can.TxHash = luckyId 1303 if luckyId == (common.Hash{}) { 1304 can.TOwner = common.Address{} 1305 } else { 1306 if tick := tContext.GetTicket(state, luckyId); nil != tick { 1307 can.TOwner = tick.Owner 1308 }else { 1309 can.TOwner = common.Address{} 1310 log.Error("Failed to Gets lucky ticketInfo on Election", "current blockNumber", blockNumber.String(), "nodeId", can.CandidateId.String(), "lucky ticketId", luckyId.Hex()) 1311 } 1312 1313 } 1314 } 1315 1316 nextQueue[i] = can 1317 1318 if node, err := buildWitnessNode(can); nil != err { 1319 log.Error("Failed to build Node on Election", "current blockNumber", blockNumber.String(), "nodeId", can.CandidateId.String(), "err", err) 1320 continue 1321 } else { 1322 nodeArr = append(nodeArr, node) 1323 } 1324 } 1325 1326 // set next witness 1327 c.setCandidateQueue(nextQueue, ppos_storage.NEXT) 1328 1329 log.Info("When Election,next round witness node count is:", "current blockNumber", blockNumber.String(), "len", len(nodeArr)) 1330 PrintObject("When Election,next round witness node information is: current blockNumber:" + blockNumber.String() + ":", nodeArr) 1331 log.Info("Call Election SUCCESS !!!!!!!", "current blockNumber", blockNumber.String()) 1332 return nodeArr, nextQueue, isEmptyElection, nil 1333 } 1334 1335 // return params 1336 // types.CandidateQueue:the next witness 1337 // bool: is empty election 1338 func (c *CandidatePool) handleEmptyElection(nextQueue types.CandidateQueue) (types.CandidateQueue, bool) { 1339 // There is'nt empty election 1340 if len(nextQueue) != 0 { 1341 return nextQueue, false 1342 } 1343 log.Info("Call Election, current is emptyElection, we take current witness become next witness ...") 1344 // empty election 1345 // Otherwise, it means that the next witness is nil, then we need to check whether the current round has a witness. 1346 // If had, use the current round of witness as the next witness, 1347 // [remark]: The pool of rewards need to use the witness can info 1348 return c.getCandidateQueue(ppos_storage.CURRENT).DeepCopy(), true 1349 } 1350 1351 /*// The operation before re-setcandiate after election 1352 // false: direct get out 1353 // true: pass 1354 func (c *CandidatePool) repledgCheck(state vm.StateDB, can *types.Candidate, currentBlockNumber *big.Int) (bool, []discover.NodeID) { 1355 1356 nodeIds := make([]discover.NodeID, 0) 1357 // If the verification does not pass, 1358 // it will drop the list directly, 1359 // but before the list is dropped, 1360 // it needs to determine which queue was in the queue. 1361 if _, ok := c.checkDeposit(state, can, true); !ok { 1362 log.Warn("Failed to checkDeposit on preElectionReset", "nodeId", can.CandidateId.String(), " err", DepositLowErr) 1363 var del int // del: 1 del immiedate; 2 del reserve 1364 if _, ok := c.immediateCandidates[can.CandidateId]; ok { 1365 del = IS_IMMEDIATE 1366 } 1367 if _, ok := c.reserveCandidates[can.CandidateId]; ok { 1368 del = IS_RESERVE 1369 } 1370 1371 delCanFunc := func(flag int) { 1372 queue := c.getCandidateQueue(flag) 1373 1374 for i := 0; i < len(queue); i++ { 1375 ca := queue[i] 1376 if ca.CandidateId == can.CandidateId { 1377 queue = append(queue[:i], queue[i+1:]...) 1378 break 1379 } 1380 } 1381 1382 c.setCandidateQueue(queue, flag) 1383 deposit, _ := new(big.Int).SetString(can.Deposit.String(), 10) 1384 refund := &types.CandidateRefund{ 1385 Deposit: deposit, 1386 BlockNumber: big.NewInt(currentBlockNumber.Int64()), 1387 Owner: can.Owner, 1388 } 1389 c.setRefund(can.CandidateId, refund) 1390 nodeIds = append(nodeIds, can.CandidateId) 1391 1392 *//*nIds := c.promoteReserveQueue(state, currentBlockNumber) 1393 1394 if len(nIds) != 0 { 1395 nodeIds = append(nodeIds, nIds...) 1396 }*//* 1397 1398 c.promoteReserveQueue(state, currentBlockNumber) 1399 } 1400 if del == IS_IMMEDIATE { 1401 *//** first delete this can on immediates *//* 1402 delCanFunc(ppos_storage.IMMEDIATE) 1403 return false, nodeIds 1404 } else { 1405 *//** first delete this can on reserves *//* 1406 delCanFunc(ppos_storage.RESERVE) 1407 return false, nodeIds 1408 } 1409 } 1410 return true, nodeIds 1411 }*/ 1412 1413 // switch next witnesses to current witnesses 1414 func (c *CandidatePool) Switch(state *state.StateDB, blockNumber *big.Int) bool { 1415 log.Info("Call Switch start ...", "blockNumber", blockNumber.String()) 1416 c.initDataByState(state) 1417 curr_queue := c.getCandidateQueue(ppos_storage.CURRENT) 1418 next_queue := c.getCandidateQueue(ppos_storage.NEXT) 1419 1420 // set previous witness 1421 c.setCandidateQueue(curr_queue, ppos_storage.PREVIOUS) 1422 1423 // set current witness 1424 c.setCandidateQueue(next_queue, ppos_storage.CURRENT) 1425 1426 // set next witness 1427 c.delCandidateQueue(ppos_storage.NEXT) 1428 1429 log.Info("Call Switch SUCCESS !!!!!!!") 1430 return true 1431 } 1432 1433 // Getting nodes of witnesses 1434 // flag: 1435 // -1: the previous round of witnesses 1436 // 0: the current round of witnesses 1437 // 1: the next round of witnesses 1438 func (c *CandidatePool) GetWitness(state *state.StateDB, flag int, blockNumber *big.Int) ([]*discover.Node, error) { 1439 log.Debug("Call GetWitness", "blockNumber", blockNumber.String(), "flag", strconv.Itoa(flag)) 1440 c.initDataByState(state) 1441 var queue types.CandidateQueue 1442 1443 if flag == PREVIOUS_C { 1444 queue = c.getCandidateQueue(ppos_storage.PREVIOUS) 1445 } else if flag == CURRENT_C { 1446 queue = c.getCandidateQueue(ppos_storage.CURRENT) 1447 } else if flag == NEXT_C { 1448 queue = c.getCandidateQueue(ppos_storage.NEXT) 1449 } 1450 1451 arr := make([]*discover.Node, 0) 1452 for _, can := range queue { 1453 if node, err := buildWitnessNode(can); nil != err { 1454 log.Error("Failed to build Node on GetWitness", "nodeId", can.CandidateId.String(), "err", err) 1455 return nil, err 1456 } else { 1457 arr = append(arr, node) 1458 } 1459 } 1460 return arr, nil 1461 } 1462 1463 // Getting previous and current and next witnesses 1464 func (c *CandidatePool) GetAllWitness(state *state.StateDB, blockNumber *big.Int) ([]*discover.Node, []*discover.Node, []*discover.Node, error) { 1465 log.Debug("Call GetAllWitness ...", "blockNumber", blockNumber.String()) 1466 c.initDataByState(state) 1467 loadFunc := func(title string, flag int) ([]*discover.Node, error) { 1468 queue := c.getCandidateQueue(flag) 1469 arr := make([]*discover.Node, 0) 1470 for _, can := range queue { 1471 if node, err := buildWitnessNode(can); nil != err { 1472 log.Error("Failed to build Node on Get "+title+" Witness", "nodeId", can.CandidateId.String(), "err", err) 1473 return nil, err 1474 } else { 1475 arr = append(arr, node) 1476 } 1477 } 1478 return arr, nil 1479 } 1480 1481 preArr, curArr, nextArr := make([]*discover.Node, 0), make([]*discover.Node, 0), make([]*discover.Node, 0) 1482 1483 type result struct { 1484 Type int // -1: previous; 0: current; 1: next 1485 Err error 1486 nodes []*discover.Node 1487 } 1488 var wg sync.WaitGroup 1489 wg.Add(3) 1490 resCh := make(chan *result, 3) 1491 1492 go func() { 1493 res := new(result) 1494 res.Type = PREVIOUS_C 1495 if nodes, err := loadFunc("previous", ppos_storage.PREVIOUS); nil != err { 1496 res.Err = err 1497 } else { 1498 res.nodes = nodes 1499 } 1500 resCh <- res 1501 wg.Done() 1502 }() 1503 go func() { 1504 res := new(result) 1505 res.Type = CURRENT_C 1506 if nodes, err := loadFunc("current", ppos_storage.CURRENT); nil != err { 1507 res.Err = err 1508 } else { 1509 res.nodes = nodes 1510 } 1511 resCh <- res 1512 wg.Done() 1513 }() 1514 go func() { 1515 res := new(result) 1516 res.Type = NEXT_C 1517 if nodes, err := loadFunc("next", ppos_storage.NEXT); nil != err { 1518 res.Err = err 1519 } else { 1520 res.nodes = nodes 1521 } 1522 resCh <- res 1523 wg.Done() 1524 }() 1525 wg.Wait() 1526 close(resCh) 1527 for res := range resCh { 1528 if nil != res.Err { 1529 return nil, nil, nil, res.Err 1530 } 1531 switch res.Type { 1532 case PREVIOUS_C: 1533 preArr = res.nodes 1534 case CURRENT_C: 1535 curArr = res.nodes 1536 case NEXT_C: 1537 nextArr = res.nodes 1538 default: 1539 continue 1540 } 1541 } 1542 return preArr, curArr, nextArr, nil 1543 } 1544 1545 // Getting can by witnesses 1546 // flag: 1547 // -1: previous round 1548 // 0: current round 1549 // 1: next round 1550 func (c *CandidatePool) GetWitnessCandidate(state vm.StateDB, nodeId discover.NodeID, flag int, blockNumber *big.Int) *types.Candidate { 1551 1552 log.Debug("Call GetWitnessCandidate", "blockNumber", blockNumber.String(), "nodeId", nodeId.String(), "flag", flag) 1553 1554 c.initDataByState(state) 1555 switch flag { 1556 case PREVIOUS_C: 1557 1558 for _, can := range c.getCandidateQueue(ppos_storage.PREVIOUS) { 1559 if can.CandidateId == nodeId { 1560 return can 1561 } 1562 } 1563 log.Warn("Call GetWitnessCandidate, can no exist in previous witnesses ", "nodeId", nodeId.String()) 1564 return nil 1565 1566 case CURRENT_C: 1567 1568 for _, can := range c.getCandidateQueue(ppos_storage.CURRENT) { 1569 if can.CandidateId == nodeId { 1570 return can 1571 } 1572 } 1573 log.Warn("Call GetWitnessCandidate, can no exist in current witnesses ", "nodeId", nodeId.String()) 1574 return nil 1575 1576 case NEXT_C: 1577 1578 for _, can := range c.getCandidateQueue(ppos_storage.NEXT) { 1579 if can.CandidateId == nodeId { 1580 return can 1581 } 1582 } 1583 log.Warn("Call GetWitnessCandidate, can no exist in next witnesses ", "nodeId", nodeId.String()) 1584 return nil 1585 1586 default: 1587 log.Error("Failed to found can on GetWitnessCandidate, flag is invalid", "flag", flag) 1588 return nil 1589 } 1590 } 1591 1592 func (c *CandidatePool) GetRefundInterval(blockNumber *big.Int) uint32 { 1593 log.Info("Call GetRefundInterval", "blockNumber", blockNumber.String(), "RefundBlockNumber", c.refundBlockNumber) 1594 return c.refundBlockNumber 1595 } 1596 1597 // According to the nodeId to ensure the current candidate's stay 1598 func (c *CandidatePool) UpdateElectedQueue(state vm.StateDB, currBlockNumber *big.Int, nodeIds ...discover.NodeID) error { 1599 log.Info("Call UpdateElectedQueue start ...", "threshold", c.threshold.String(), "depositLimit", c.depositLimit, "allowed", c.allowed, "maxCount", c.maxCount, "maxChair", c.maxChair, "refundBlockNumber", c.refundBlockNumber) 1600 arr := c.updateQueue(state, currBlockNumber, nodeIds...) 1601 log.Info("Call UpdateElectedQueue SUCCESS !!!!!!!!! ") 1602 //go ticketPool.DropReturnTicket(state, ids...) 1603 if len(arr) > 0 { 1604 return tContext.DropReturnTicket(state, currBlockNumber, arr...) 1605 } 1606 return nil 1607 } 1608 1609 func (c *CandidatePool) updateQueue(state vm.StateDB, currentBlockNumber *big.Int, nodeIds ...discover.NodeID) []discover.NodeID { 1610 log.Info("Call UpdateElectedQueue Update the Campaign queue Start ...") 1611 PrintObject("Call UpdateElectedQueue input param's nodeIds len:= " + fmt.Sprint(len(nodeIds)) + " ,is:", nodeIds) 1612 if len(nodeIds) == 0 { 1613 log.Debug("UpdateElectedQueue FINISH, input param's nodeIds is empty !!!!!!!!!!") 1614 return nil 1615 } 1616 1617 c.initData2Cache(state, GET_IM_RE) 1618 1619 1620 /** 1621 delete can by queue 1622 */ 1623 delCanFromQueueFunc := func(title string, nodeId discover.NodeID, queue types.CandidateQueue, flag int) types.CandidateQueue { 1624 1625 1626 queueCopy := make(types.CandidateQueue, len(queue)) 1627 copy(queueCopy, queue) 1628 1629 log.Debug("Call UpdateElectedQueue, Before delete the can by old queue, the queue is " + title, "queue len", len(queueCopy), "nodeId", nodeId.String()) 1630 1631 for i, can := range queueCopy { 1632 if nodeId == can.CandidateId { 1633 queueCopy = append(queueCopy[:i], queueCopy[i+1:]...) 1634 break 1635 } 1636 } 1637 1638 PrintObject("Call UpdateElectedQueue, After delete the can by old queue, the queue is " + title + ", queue len:" + fmt.Sprint(len(queueCopy)) + " ,the remain queue is", queueCopy) 1639 1640 if len(queueCopy) != 0 { 1641 c.setCandidateQueue(queueCopy, flag) 1642 }else { 1643 c.delCandidateQueue(flag) 1644 } 1645 1646 return queueCopy 1647 } 1648 1649 1650 /** 1651 handler the Reserve queue 1652 */ 1653 handleReserveFunc := func(re_queue types.CandidateQueue) []discover.NodeID { 1654 1655 queueCopy := make(types.CandidateQueue, len(re_queue)) 1656 copy(queueCopy, re_queue) 1657 1658 PrintObject("Call UpdateElectedQueue, handleReserveFunc, Before update the reserve len is " + fmt.Sprint(len(queueCopy)) + ", config.maxCount:" + fmt.Sprint(c.maxCount) + " , the queue is", queueCopy) 1659 1660 str := "Call UpdateElectedQueue, handleReserveFunc, o sort reserve queue ..." 1661 makeCandidateSort(str, state, queueCopy) 1662 if len(queueCopy) > int(c.maxCount) { 1663 // Intercepting the lost candidates to tmpArr 1664 tmpArr := (queueCopy)[c.maxCount:] 1665 // qualified elected candidates 1666 queueCopy = (queueCopy)[:c.maxCount] 1667 1668 // cache 1669 nodeIdQueue := make([]discover.NodeID, 0) 1670 1671 // handle tmpArr 1672 for _, tmpCan := range tmpArr { 1673 deposit, _ := new(big.Int).SetString(tmpCan.Deposit.String(), 10) 1674 refund := &types.CandidateRefund{ 1675 Deposit: deposit, 1676 BlockNumber: big.NewInt(currentBlockNumber.Int64()), 1677 Owner: tmpCan.Owner, 1678 } 1679 1680 c.setRefund(tmpCan.CandidateId, refund) 1681 nodeIdQueue = append(nodeIdQueue, tmpCan.CandidateId) 1682 1683 delete(c.reserveCandidates, tmpCan.CandidateId) 1684 1685 } 1686 1687 1688 1689 PrintObject("Call UpdateElectedQueue, handleReserveFunc, After update the reserve len is " + fmt.Sprint(len(queueCopy)) + " , the queue is", queueCopy) 1690 1691 c.setCandidateQueue(queueCopy, ppos_storage.RESERVE) 1692 1693 return nodeIdQueue 1694 }else { 1695 1696 PrintObject("Call UpdateElectedQueue, handleReserveFunc, After update the reserve len is " + fmt.Sprint(len(queueCopy)) + " , the queue is", queueCopy) 1697 1698 c.setCandidateQueue(queueCopy, ppos_storage.RESERVE) 1699 return nil 1700 } 1701 } 1702 1703 /** 1704 This function handles Immediate queues and Reserve queues 1705 for moving into the opposing queue 1706 */ 1707 workFunc := func(oldQueueFlag, newQueueFlag int, can *types.Candidate) []discover.NodeID { 1708 old_queue := c.getCandidateQueue(oldQueueFlag) 1709 new_queue := c.getCandidateQueue(newQueueFlag) 1710 1711 //old_queueCopy := make(types.CandidateQueue, len(old_queue)) 1712 //new_queueCopy := make(types.CandidateQueue, len(new_queue)) 1713 1714 nodeIdQueue := make([]discover.NodeID, 0) 1715 1716 /** 1717 immediate move to reserve 1718 */ 1719 if oldQueueFlag == ppos_storage.IMMEDIATE { 1720 1721 log.Debug("Call UpdateElectedQueue, workFunc the old queue is immediate", "nodeId", can.CandidateId.String()) 1722 1723 // delete immediate 1724 delCanFromQueueFunc("imms", can.CandidateId, old_queue, oldQueueFlag) 1725 delete(c.immediateCandidates, can.CandidateId) 1726 1727 1728 // input reserve 1729 new_queue = append(new_queue, can) 1730 if nodeIdArr := handleReserveFunc(new_queue); len(nodeIdArr) != 0 { 1731 nodeIdQueue = append(nodeIdQueue, nodeIdArr...) 1732 } 1733 return nodeIdQueue 1734 } else { 1735 1736 log.Debug("Call UpdateElectedQueue, workFunc the old queue is reserve", "nodeId", can.CandidateId.String()) 1737 1738 /** 1739 reserve move to immediate 1740 */ 1741 // delete reserve 1742 old_queue = delCanFromQueueFunc("res", can.CandidateId, old_queue, oldQueueFlag) 1743 delete(c.reserveCandidates, can.CandidateId) 1744 1745 str := "Call UpdateElectedQueue, workFunc to sort immediate queue ..." 1746 // input immediate 1747 new_queue = append(new_queue, can) 1748 makeCandidateSort(str, state, new_queue) 1749 1750 var inRes bool 1751 if len(new_queue) > int(c.maxCount) { 1752 // Intercepting the lost candidates to tmpArr 1753 tmpArr := (new_queue)[c.maxCount:] 1754 // qualified elected candidates 1755 new_queue = (new_queue)[:c.maxCount] 1756 1757 inRes = true 1758 // reenter into reserve 1759 old_queue = append(old_queue, tmpArr...) 1760 } 1761 1762 log.Debug("Call UpdateElectedQueue, workFunc the old queue is reserve, the new immediate", "len", len(new_queue), "config.maxCount", c.maxCount) 1763 PrintObject("Call UpdateElectedQueue, workFunc the old queue is reserve, the new immediate", new_queue) 1764 1765 // update immediate 1766 c.setCandidateQueue(new_queue, ppos_storage.IMMEDIATE) 1767 if inRes { 1768 1769 log.Debug("Call UpdateElectedQueue, workFunc the old queue is reserve, the new immediate, had add reserve", "reserver len", len(old_queue)) 1770 1771 if nodeIdArr := handleReserveFunc(old_queue); len(nodeIdArr) != 0 { 1772 nodeIdQueue = append(nodeIdQueue, nodeIdArr...) 1773 } 1774 } 1775 return nodeIdQueue 1776 } 1777 1778 } 1779 1780 1781 resNodeIds := make([]discover.NodeID, 0) 1782 1783 /** 1784 ######## 1785 Real Handle Can queue 1786 ######## 1787 */ 1788 for _, nodeId := range nodeIds { 1789 1790 tcount := c.checkTicket(tContext.GetCandidateTicketCount(state, nodeId)) 1791 1792 switch c.checkExist(nodeId) { 1793 1794 case IS_IMMEDIATE: 1795 log.Debug("Call UpdateElectedQueue The current nodeId was originally in the Immediate ...") 1796 can := c.immediateCandidates[nodeId] 1797 1798 if !tcount { 1799 1800 log.Debug("Call UpdateElectedQueue, the node will from immediate to reserve ...", "nodeId", nodeId.String()) 1801 if ids := workFunc(ppos_storage.IMMEDIATE, ppos_storage.RESERVE, can); len(ids) != 0 { 1802 resNodeIds = append(resNodeIds, ids...) 1803 } 1804 } 1805 1806 case IS_RESERVE: 1807 log.Debug("Call UpdateElectedQueue The current nodeId was originally in the Reserve ...") 1808 can := c.reserveCandidates[nodeId] 1809 1810 if tcount { 1811 1812 log.Debug("Call UpdateElectedQueue, the node will from reserve to immediate ...", "nodeId", nodeId.String()) 1813 if ids := workFunc(ppos_storage.RESERVE, ppos_storage.IMMEDIATE, can); len(ids) != 0 { 1814 resNodeIds = append(resNodeIds, ids...) 1815 } 1816 } 1817 1818 default: 1819 continue 1820 } 1821 } 1822 1823 // promoteReserve queues 1824 c.promoteReserveQueue(state, currentBlockNumber) 1825 1826 return resNodeIds 1827 } 1828 1829 func (c *CandidatePool) checkFirstThreshold(can *types.Candidate) bool { 1830 var exist bool 1831 if _, ok := c.immediateCandidates[can.CandidateId]; ok { 1832 exist = true 1833 } 1834 1835 if _, ok := c.reserveCandidates[can.CandidateId]; ok { 1836 exist = true 1837 } 1838 1839 if !exist && can.Deposit.Cmp(c.threshold) < 0 { 1840 return false 1841 } 1842 return true 1843 } 1844 1845 // false: invalid deposit 1846 // true: pass 1847 //func (c *CandidatePool) checkDeposit(state vm.StateDB, can *types.Candidate, holdself bool) (bool, bool) { 1848 // 1849 // 1850 // 1851 // 1852 // 1853 // // Number of vote ticket by nodes 1854 // tcount := c.checkTicket(tContext.GetCandidateTicketCount(state, can.CandidateId)) 1855 // 1856 // // if self have already exist: 1857 // // b、no first pledge: x >= self * 110% 1858 // // 1859 // // if the pool is full:(Only reserve pool) 1860 // // c、x > last * 110 % 1861 // 1862 // 1863 // compareFunc := func(target, current *types.Candidate, logA, logB string) (bool, bool) { 1864 // lastDeposit := target.Deposit 1865 // 1866 // // y = 100 + x 1867 // percentage := new(big.Int).Add(big.NewInt(100), big.NewInt(int64(c.depositLimit))) 1868 // // z = old * y 1869 // tmp := new(big.Int).Mul(lastDeposit, percentage) 1870 // // z/100 == old * (100 + x) / 100 == old * (y%) 1871 // tmp = new(big.Int).Div(tmp, big.NewInt(100)) 1872 // if can.Deposit.Cmp(tmp) < 0 { 1873 // // If last is self and holdslef flag is true 1874 // // we must return true (Keep self on staying in the original queue) 1875 // if holdself && can.CandidateId == target.CandidateId { 1876 // log.Debug(logA + tmp.String()) 1877 // return tcount, true 1878 // } 1879 // log.Debug(logB + tmp.String()) 1880 // return tcount, false 1881 // } 1882 // return tcount, true 1883 // } 1884 // 1885 // 1886 // //var queueFlag int 1887 // var storageMap candidateStorage 1888 // 1889 // if _, ok := c.immediateCandidates[can.CandidateId]; ok { 1890 // //queueFlag = IS_IMMEDIATE 1891 // storageMap = c.immediateCandidates 1892 // } 1893 // if _, ok := c.reserveCandidates[can.CandidateId]; ok { 1894 // //queueFlag = IS_RESERVE 1895 // storageMap = c.reserveCandidates 1896 // } 1897 // 1898 // /* 1899 // If the current number of votes achieving the conditions for entering the immediate queue 1900 // */ 1901 // if tcount { 1902 // 1903 // // if it already exist immediate 1904 // // compare old self deposit 1905 // if old_self, ok := storageMap[can.CandidateId]; ok { 1906 // 1907 // logA := `The can already exist in queue, and holdslef is true, Keep self on staying in the original queue, current can nodeId:` + can.CandidateId.String() + 1908 // ` the length of current queue:` + fmt.Sprint(len(storageMap)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + 1909 // ` current can's Deposit: ` + can.Deposit.String() + ` 110% of it old_self in the queue: ` 1910 // 1911 // logB := `The can already exist in queue, and holdslef is true,and the current can's Deposit is less than 110% of the it old self in the queue.` + 1912 // `the length of current queue:` + fmt.Sprint(len(storageMap)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + ` current can's Deposit:` + 1913 // can.Deposit.String() + ` 110% of it old_self in the queue: ` 1914 // 1915 // return compareFunc(old_self, can, logA, logB) 1916 // } 1917 // 1918 // } 1919 // 1920 // /** 1921 // If the can will enter the reserve pool 1922 // */ 1923 // 1924 // if !tcount { 1925 // 1926 // reserveArr := c.storage.GetCandidateQueue(ppos_storage.RESERVE) 1927 // 1928 // // Is first pledge and the reserve pool is full 1929 // if _, ok := storageMap[can.CandidateId]; !ok && uint32(len(reserveArr)) == c.maxCount { 1930 // last := reserveArr[len(reserveArr)-1] 1931 // 1932 // logA := `The reserve pool is full, and last is self and holdslef is true, Keep self on staying in the original queue, the length of current reserve pool: ` + 1933 // fmt.Sprint(len(reserveArr)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + ` current can nodeId: ` + can.CandidateId.String() + ` last can nodeId: ` + 1934 // last.CandidateId.String() + ` current can's Deposit: ` + can.Deposit.String() + ` 110% of the last can in the reserve pool:` 1935 // 1936 // logB := `The reserve pool is full,and the current can's Deposit is less than 110% of the last can in the reserve pool., the length of current reserve pool:` + 1937 // fmt.Sprint(len(reserveArr)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + ` current can's Deposit:` + can.Deposit.String() + 1938 // `110% of the last can in the reserve pool:` 1939 // 1940 // return compareFunc(last, can, logA, logB) 1941 // 1942 // } else if old_self, ok := storageMap[can.CandidateId]; ok { // Is'nt first pledge 1943 // logA := `The can already exist in reserve, and holdslef is true, Keep self on staying in the original queue, current can nodeId:` + can.CandidateId.String() + 1944 // ` the length of current reserve pool:` + fmt.Sprint(len(reserveArr)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + 1945 // ` current can's Deposit: ` + can.Deposit.String() + ` 110% of it old_self in the reserve pool: ` 1946 // 1947 // logB := `The can already exist in reserve, and holdslef is true,and the current can's Deposit is less than 110% of the it old self in the reserve pool.` + 1948 // `the length of current reserve pool:` + fmt.Sprint(len(reserveArr)) + ` the limit of Configuration:` + fmt.Sprint(c.maxCount) + ` current can's Deposit:` + 1949 // can.Deposit.String() + ` 110% of it old_self in the reserve pool: ` 1950 // 1951 // return compareFunc(old_self, can, logA, logB) 1952 // } 1953 // } 1954 // return tcount, true 1955 //} 1956 1957 func (c *CandidatePool) checkDeposit (can *types.Candidate) bool { 1958 1959 im_queue := c.getCandidateQueue(ppos_storage.IMMEDIATE) 1960 1961 re_queue := c.getCandidateQueue(ppos_storage.RESERVE) 1962 1963 if len(im_queue) == int(c.maxCount) && len(re_queue) == int(c.maxCount) { 1964 last := re_queue[len(re_queue)-1] 1965 1966 lastDeposit := last.Deposit 1967 1968 // y = 100 + x 1969 percentage := new(big.Int).Add(big.NewInt(100), big.NewInt(int64(c.depositLimit))) 1970 // z = old * y 1971 tmp := new(big.Int).Mul(lastDeposit, percentage) 1972 // z/100 == old * (100 + x) / 100 == old * (y%) 1973 tmp = new(big.Int).Div(tmp, big.NewInt(100)) 1974 if can.Deposit.Cmp(tmp) < 0 { 1975 log.Debug("The current can's Deposit is less than 110% of the last can in the reserve queue.", "current can Deposit", can.Deposit.String(), "last can Deposit", last.Deposit.String(), "the target Deposit", tmp.String()) 1976 return false 1977 } 1978 } 1979 return true 1980 } 1981 1982 1983 func (c *CandidatePool) checkWithdraw(source, price *big.Int) error { 1984 // y = old * x 1985 percentage := new(big.Int).Mul(source, big.NewInt(int64(c.depositLimit))) 1986 // y/100 == old * (x/100) == old * x% 1987 tmp := new(big.Int).Div(percentage, big.NewInt(100)) 1988 if price.Cmp(tmp) < 0 { 1989 log.Debug("When withdrawing the refund, the amount of the current can't be refunded is less than 10% of the remaining amount of self:", "The current amount of can want to refund:", price.String(), "current Can own deposit remaining amount:", tmp.String()) 1990 return WithdrawLowErr 1991 } 1992 return nil 1993 } 1994 1995 // 0: empty 1996 // 1: in immediates 1997 // 2: in reserves 1998 func (c *CandidatePool) checkExist(nodeId discover.NodeID) int { 1999 log.Info("Check which queue the current nodeId originally belongs to:", "nodeId", nodeId.String()) 2000 if _, ok := c.immediateCandidates[nodeId]; ok { 2001 log.Info("The current nodeId originally belonged to the immediate queue ...", "nodeId", nodeId.String()) 2002 return IS_IMMEDIATE 2003 } 2004 if _, ok := c.reserveCandidates[nodeId]; ok { 2005 log.Info("The current nodeId originally belonged to the reserve queue ...", "nodeId", nodeId.String()) 2006 return IS_RESERVE 2007 } 2008 log.Info("The current nodeId does not belong to any queue ...", "nodeId", nodeId.String()) 2009 return IS_LOST 2010 } 2011 2012 func (c *CandidatePool) checkTicket(t_count uint32) bool { 2013 log.Debug("Compare the current candidate’s votes to:", "t_count", t_count, "the allowed limit of config:", c.allowed) 2014 if t_count >= c.allowed { 2015 log.Debug(" The current candidate’s votes are in line with the immediate pool....") 2016 return true 2017 } 2018 log.Debug("Not eligible to enter the immediate pool ...") 2019 return false 2020 } 2021 2022 func (c *CandidatePool) getCandidate(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) *types.Candidate { 2023 log.Debug("Call GetCandidate", "blockNumber", blockNumber.String(), "nodeId", nodeId.String()) 2024 c.initData2Cache(state, GET_IM_RE) 2025 if candidatePtr, ok := c.immediateCandidates[nodeId]; ok { 2026 PrintObject("Call GetCandidate return immediate:", *candidatePtr) 2027 return candidatePtr 2028 } 2029 if candidatePtr, ok := c.reserveCandidates[nodeId]; ok { 2030 PrintObject("Call GetCandidate return reserve:", *candidatePtr) 2031 return candidatePtr 2032 } 2033 return nil 2034 } 2035 2036 func (c *CandidatePool) getCandidates(state vm.StateDB, blockNumber *big.Int, nodeIds ...discover.NodeID) types.CandidateQueue { 2037 log.Debug("Call GetCandidates...", "blockNumber", blockNumber.String()) 2038 c.initData2Cache(state, GET_IM_RE) 2039 canArr := make(types.CandidateQueue, 0) 2040 tem := make(map[discover.NodeID]struct{}, 0) 2041 for _, nodeId := range nodeIds { 2042 if _, ok := tem[nodeId]; ok { 2043 continue 2044 } 2045 if candidatePtr, ok := c.immediateCandidates[nodeId]; ok { 2046 canArr = append(canArr, candidatePtr) 2047 tem[nodeId] = struct{}{} 2048 } 2049 if _, ok := tem[nodeId]; ok { 2050 continue 2051 } 2052 if candidatePtr, ok := c.reserveCandidates[nodeId]; ok { 2053 canArr = append(canArr, candidatePtr) 2054 tem[nodeId] = struct{}{} 2055 } 2056 } 2057 return canArr 2058 } 2059 2060 func (c *CandidatePool) MaxChair() uint32 { 2061 return c.maxChair 2062 } 2063 2064 func (c *CandidatePool) MaxCount() uint32 { 2065 return c.maxCount 2066 } 2067 2068 // TODO 2069 func (c *CandidatePool) promoteReserveQueue(state vm.StateDB, currentBlockNumber *big.Int) /*[]discover.NodeID */ { 2070 2071 log.Debug("Call promoteReserveQueue Start ...", "blockNumber", currentBlockNumber.String()) 2072 2073 // Violence traverses the pools 2074 im_queue := c.storage.GetCandidateQueue(ppos_storage.IMMEDIATE) 2075 re_queue := c.storage.GetCandidateQueue(ppos_storage.RESERVE) 2076 2077 PrintObject("Call promoteReserveQueue Before the immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue) 2078 PrintObject("Call promoteReserveQueue Before the reserve queue len:=" + fmt.Sprint(len(re_queue)) + " ,queue is", re_queue) 2079 2080 2081 // current ticket price 2082 ticket_price := tContext.GetTicketPrice(state) 2083 2084 2085 //for i, can := range re_queue { 2086 for i := 0; i < len(re_queue); i++ { 2087 2088 // current re can 2089 can := re_queue[i] 2090 2091 log.Debug("Call promoteReserveQueue for range , Current reserve id", "blockNumber", currentBlockNumber.String(), "nodeId", can.CandidateId.String()) 2092 2093 re_tCount := tContext.GetCandidateTicketCount(state, can.CandidateId) 2094 if re_tCount < c.allowed { 2095 continue 2096 } 2097 2098 // check immediate 2099 // if the immediate queue is full 2100 // We can take the immediate last can and current reserve can compare 2101 if uint32(len(im_queue)) >= c.maxCount { 2102 2103 // last im can 2104 last := im_queue[len(im_queue)-1] 2105 last_tCount := tContext.GetCandidateTicketCount(state, last.CandidateId) 2106 2107 last_tmoney := new(big.Int).Mul(big.NewInt(int64(last_tCount)), ticket_price) 2108 last_money := new(big.Int).Add(last.Deposit, last_tmoney) 2109 2110 // current re can 2111 re_tmoney := new(big.Int).Mul(big.NewInt(int64(re_tCount)), ticket_price) 2112 re_money := new(big.Int).Add(can.Deposit, re_tmoney) 2113 2114 // Terminate the cycle comparison. 2115 // When current re can's money is 2116 // less than the last one in the im queue 2117 if types.CompareCan(can, last, re_money, last_money) < 0 { 2118 break 2119 } 2120 2121 2122 // into immediate queue If match condition 2123 im_queue = append(im_queue, can) 2124 re_queue = append(re_queue[:i], re_queue[i+1:]...) 2125 i-- 2126 } else { 2127 // direct - into immediate queue 2128 im_queue = append(im_queue, can) 2129 re_queue = append(re_queue[:i], re_queue[i+1:]...) 2130 i-- 2131 } 2132 } 2133 2134 2135 str := "Call promoteReserveQueue to sort the new immediate queue ..." 2136 // sort immediate 2137 makeCandidateSort(str, state, im_queue) 2138 2139 //nodeIds := make([]discover.NodeID, 0) 2140 2141 var addRe_queue types.CandidateQueue 2142 2143 2144 // Cut off the immediate queue 2145 if len(im_queue) > int(c.maxCount) { 2146 // Intercepting the lost candidates to tmpArr 2147 tempArr := (im_queue)[c.maxCount:] 2148 // qualified elected candidates 2149 im_queue = (im_queue)[:c.maxCount] 2150 2151 2152 2153 2154 //newRe_queue = make(types.CandidateQueue, 0) 2155 addRe_queue = make(types.CandidateQueue, len(tempArr)) 2156 2157 // handle tmpArr 2158 for i, tmpCan := range tempArr { 2159 2160 addRe_queue[i] = tmpCan 2161 } 2162 } 2163 2164 // Sets the new immediate queue 2165 c.setCandidateQueue(im_queue, ppos_storage.IMMEDIATE) 2166 2167 // sort new reserve queue 2168 if len(addRe_queue) > 0 { 2169 re_queue = append(re_queue, addRe_queue...) 2170 2171 str := "Call promoteReserveQueue to sort the new reserve queue ..." 2172 makeCandidateSort(str, state, re_queue) 2173 2174 } 2175 2176 // Sets the new reserve queue 2177 c.setCandidateQueue(re_queue, ppos_storage.RESERVE) 2178 2179 PrintObject("Call promoteReserveQueue Finish the immediate queue len:=" + fmt.Sprint(len(im_queue)) + " ,queue is", im_queue) 2180 PrintObject("Call promoteReserveQueue Finish the reserve queue len:=" + fmt.Sprint(len(re_queue)) + " ,queue is", re_queue) 2181 log.Debug("Call promoteReserveQueue Finish !!! ...", "blockNumber", currentBlockNumber.String()) 2182 } 2183 2184 /** builin function */ 2185 2186 func (c *CandidatePool) setCandidateQueue(queue types.CandidateQueue, flag int) { 2187 c.storage.SetCandidateQueue(queue, flag) 2188 } 2189 2190 func (c *CandidatePool) getCandidateQueue(flag int) types.CandidateQueue { 2191 return c.storage.GetCandidateQueue(flag) 2192 } 2193 2194 func (c *CandidatePool) delCandidateQueue(flag int) { 2195 c.storage.DelCandidateQueue(flag) 2196 } 2197 2198 func (c *CandidatePool) setRefund(nodeId discover.NodeID, refund *types.CandidateRefund) { 2199 c.storage.SetRefund(nodeId, refund) 2200 } 2201 2202 func (c *CandidatePool) setRefunds(nodeId discover.NodeID, refundArr types.RefundQueue) { 2203 c.storage.SetRefunds(nodeId, refundArr) 2204 } 2205 2206 func (c *CandidatePool) appendRefunds(nodeId discover.NodeID, refundArr types.RefundQueue) { 2207 c.storage.AppendRefunds(nodeId, refundArr) 2208 } 2209 2210 func (c *CandidatePool) getRefunds(nodeId discover.NodeID) types.RefundQueue { 2211 return c.storage.GetRefunds(nodeId) 2212 } 2213 2214 func (c *CandidatePool) delRefunds(nodeId discover.NodeID) { 2215 c.storage.DelRefunds(nodeId) 2216 } 2217 2218 /*func getPreviousWitnessIdsState(state vm.StateDB) ([]discover.NodeID, error) { 2219 var witnessIds []discover.NodeID 2220 if valByte := state.GetState(common.CandidatePoolAddr, PreviousWitnessListKey()); len(valByte) != 0 { 2221 if err := rlp.DecodeBytes(valByte, &witnessIds); nil != err { 2222 return nil, err 2223 } 2224 } else { 2225 return nil, nil 2226 } 2227 return witnessIds, nil 2228 } 2229 2230 func setPreviosWitnessIdsState(state vm.StateDB, arrVal []byte) { 2231 state.SetState(common.CandidatePoolAddr, PreviousWitnessListKey(), arrVal) 2232 } 2233 2234 func getPreviousWitnessByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) { 2235 var can types.Candidate 2236 if valByte := state.GetState(common.CandidatePoolAddr, PreviousWitnessKey(id)); len(valByte) != 0 { 2237 if err := rlp.DecodeBytes(valByte, &can); nil != err { 2238 return nil, err 2239 } 2240 } else { 2241 return nil, nil 2242 } 2243 return &can, nil 2244 } 2245 2246 func setPreviousWitnessState(state vm.StateDB, id discover.NodeID, val []byte) { 2247 state.SetState(common.CandidatePoolAddr, PreviousWitnessKey(id), val) 2248 } 2249 2250 func getWitnessIdsByState(state vm.StateDB) ([]discover.NodeID, error) { 2251 var witnessIds []discover.NodeID 2252 if valByte := state.GetState(common.CandidatePoolAddr, WitnessListKey()); len(valByte) != 0 { 2253 if err := rlp.DecodeBytes(valByte, &witnessIds); nil != err { 2254 return nil, err 2255 } 2256 } else { 2257 return nil, nil 2258 } 2259 return witnessIds, nil 2260 } 2261 2262 func setWitnessIdsState(state vm.StateDB, arrVal []byte) { 2263 state.SetState(common.CandidatePoolAddr, WitnessListKey(), arrVal) 2264 } 2265 2266 func getWitnessByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) { 2267 var can types.Candidate 2268 if valByte := state.GetState(common.CandidatePoolAddr, WitnessKey(id)); len(valByte) != 0 { 2269 if err := rlp.DecodeBytes(valByte, &can); nil != err { 2270 return nil, err 2271 } 2272 } else { 2273 return nil, nil 2274 } 2275 return &can, nil 2276 } 2277 2278 func setWitnessState(state vm.StateDB, id discover.NodeID, val []byte) { 2279 state.SetState(common.CandidatePoolAddr, WitnessKey(id), val) 2280 } 2281 2282 func getNextWitnessIdsByState(state vm.StateDB) ([]discover.NodeID, error) { 2283 var nextWitnessIds []discover.NodeID 2284 if valByte := state.GetState(common.CandidatePoolAddr, NextWitnessListKey()); len(valByte) != 0 { 2285 if err := rlp.DecodeBytes(valByte, &nextWitnessIds); nil != err { 2286 return nil, err 2287 } 2288 } else { 2289 return nil, nil 2290 } 2291 return nextWitnessIds, nil 2292 } 2293 2294 func setNextWitnessIdsState(state vm.StateDB, arrVal []byte) { 2295 state.SetState(common.CandidatePoolAddr, NextWitnessListKey(), arrVal) 2296 } 2297 2298 func getNextWitnessByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) { 2299 var can types.Candidate 2300 if valByte := state.GetState(common.CandidatePoolAddr, NextWitnessKey(id)); len(valByte) != 0 { 2301 if err := rlp.DecodeBytes(valByte, &can); nil != err { 2302 return nil, err 2303 } 2304 } else { 2305 return nil, nil 2306 } 2307 return &can, nil 2308 } 2309 2310 func setNextWitnessState(state vm.StateDB, id discover.NodeID, val []byte) { 2311 state.SetState(common.CandidatePoolAddr, NextWitnessKey(id), val) 2312 } 2313 2314 func getImmediateIdsByState(state vm.StateDB) ([]discover.NodeID, error) { 2315 var immediateIds []discover.NodeID 2316 if valByte := state.GetState(common.CandidatePoolAddr, ImmediateListKey()); len(valByte) != 0 { 2317 if err := rlp.DecodeBytes(valByte, &immediateIds); nil != err { 2318 return nil, err 2319 } 2320 } else { 2321 return nil, nil 2322 } 2323 return immediateIds, nil 2324 } 2325 2326 func setImmediateIdsState(state vm.StateDB, arrVal []byte) { 2327 state.SetState(common.CandidatePoolAddr, ImmediateListKey(), arrVal) 2328 } 2329 2330 func getImmediateByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) { 2331 var can types.Candidate 2332 if valByte := state.GetState(common.CandidatePoolAddr, ImmediateKey(id)); len(valByte) != 0 { 2333 if err := rlp.DecodeBytes(valByte, &can); nil != err { 2334 return nil, err 2335 } 2336 } else { 2337 return nil, nil 2338 } 2339 return &can, nil 2340 } 2341 2342 func setImmediateState(state vm.StateDB, id discover.NodeID, val []byte) { 2343 state.SetState(common.CandidatePoolAddr, ImmediateKey(id), val) 2344 } 2345 2346 func getReserveIdsByState(state vm.StateDB) ([]discover.NodeID, error) { 2347 var reserveIds []discover.NodeID 2348 if valByte := state.GetState(common.CandidatePoolAddr, ReserveListKey()); len(valByte) != 0 { 2349 if err := rlp.DecodeBytes(valByte, &reserveIds); nil != err { 2350 return nil, err 2351 } 2352 } else { 2353 return nil, nil 2354 } 2355 return reserveIds, nil 2356 } 2357 2358 func setReserveIdsState(state vm.StateDB, arrVal []byte) { 2359 state.SetState(common.CandidatePoolAddr, ReserveListKey(), arrVal) 2360 } 2361 2362 func getReserveByState(state vm.StateDB, id discover.NodeID) (*types.Candidate, error) { 2363 var can types.Candidate 2364 if valByte := state.GetState(common.CandidatePoolAddr, ReserveKey(id)); len(valByte) != 0 { 2365 if err := rlp.DecodeBytes(valByte, &can); nil != err { 2366 return nil, err 2367 } 2368 } else { 2369 return nil, nil 2370 } 2371 return &can, nil 2372 } 2373 2374 func setReserveState(state vm.StateDB, id discover.NodeID, val []byte) { 2375 state.SetState(common.CandidatePoolAddr, ReserveKey(id), val) 2376 } 2377 2378 func getDefeatIdsByState(state vm.StateDB) ([]discover.NodeID, error) { 2379 var defeatIds []discover.NodeID 2380 if valByte := state.GetState(common.CandidatePoolAddr, DefeatListKey()); len(valByte) != 0 { 2381 if err := rlp.DecodeBytes(valByte, &defeatIds); nil != err { 2382 return nil, err 2383 } 2384 } else { 2385 return nil, nil 2386 } 2387 return defeatIds, nil 2388 } 2389 2390 func setDefeatIdsState(state vm.StateDB, arrVal []byte) { 2391 state.SetState(common.CandidatePoolAddr, DefeatListKey(), arrVal) 2392 } 2393 2394 func getDefeatsByState(state vm.StateDB, id discover.NodeID) (types.CandidateQueue, error) { 2395 var canArr types.CandidateQueue 2396 if valByte := state.GetState(common.CandidatePoolAddr, DefeatKey(id)); len(valByte) != 0 { 2397 if err := rlp.DecodeBytes(valByte, &canArr); nil != err { 2398 return nil, err 2399 } 2400 } else { 2401 return nil, nil 2402 } 2403 return canArr, nil 2404 } 2405 2406 func setDefeatState(state vm.StateDB, id discover.NodeID, val []byte) { 2407 log.Debug("SetDefeatArr ... ...", "nodeId:", id.String(), "keyTrie:", buildKeyTrie(DefeatKey(id))) 2408 state.SetState(common.CandidatePoolAddr, DefeatKey(id), val) 2409 }*/ 2410 2411 func copyCandidateMapByIds(target, source candidateStorage, ids []discover.NodeID) { 2412 for _, id := range ids { 2413 if v, ok := source[id]; ok { 2414 target[id] = v 2415 } 2416 } 2417 } 2418 2419 //func GetCandidatePtr() *CandidatePool { 2420 // return candidatePool 2421 //} 2422 2423 func PrintObject(s string, obj interface{}) { 2424 objs, _ := json.Marshal(obj) 2425 log.Debug(s, "==", string(objs)) 2426 } 2427 2428 func buildWitnessNode(can *types.Candidate) (*discover.Node, error) { 2429 if nil == can { 2430 return nil, CandidateEmptyErr 2431 } 2432 ip := net.ParseIP(can.Host) 2433 // uint16 2434 var port uint16 2435 if portInt, err := strconv.Atoi(can.Port); nil != err { 2436 return nil, err 2437 } else { 2438 port = uint16(portInt) 2439 } 2440 return discover.NewNode(can.CandidateId, ip, port, port), nil 2441 } 2442 2443 func makeCandidateSort(logStr string, state vm.StateDB, arr types.CandidateQueue) { 2444 2445 log.Debug(logStr) 2446 2447 cand := make(types.CanConditions, 0) 2448 for _, can := range arr { 2449 tCount := tContext.GetCandidateTicketCount(state, can.CandidateId) 2450 price := tContext.GetTicketPrice(state) 2451 tprice := new(big.Int).Mul(big.NewInt(int64(tCount)), price) 2452 2453 money := new(big.Int).Add(can.Deposit, tprice) 2454 2455 cand[can.CandidateId] = money 2456 } 2457 arr.CandidateSort(cand) 2458 } 2459 2460 /* 2461 func ImmediateKey(nodeId discover.NodeID) []byte { 2462 return immediateKey(nodeId.Bytes()) 2463 } 2464 func immediateKey(key []byte) []byte { 2465 return append(append(common.CandidatePoolAddr.Bytes(), ImmediateBytePrefix...), key...) 2466 } 2467 2468 func ReserveKey(nodeId discover.NodeID) []byte { 2469 return reserveKey(nodeId.Bytes()) 2470 } 2471 2472 func reserveKey(key []byte) []byte { 2473 return append(append(common.CandidatePoolAddr.Bytes(), ReserveBytePrefix...), key...) 2474 } 2475 2476 func PreviousWitnessKey(nodeId discover.NodeID) []byte { 2477 return prewitnessKey(nodeId.Bytes()) 2478 } 2479 2480 func prewitnessKey(key []byte) []byte { 2481 return append(append(common.CandidatePoolAddr.Bytes(), PreWitnessBytePrefix...), key...) 2482 } 2483 2484 func WitnessKey(nodeId discover.NodeID) []byte { 2485 return witnessKey(nodeId.Bytes()) 2486 } 2487 func witnessKey(key []byte) []byte { 2488 return append(append(common.CandidatePoolAddr.Bytes(), WitnessBytePrefix...), key...) 2489 } 2490 2491 func NextWitnessKey(nodeId discover.NodeID) []byte { 2492 return nextWitnessKey(nodeId.Bytes()) 2493 } 2494 func nextWitnessKey(key []byte) []byte { 2495 return append(append(common.CandidatePoolAddr.Bytes(), NextWitnessBytePrefix...), key...) 2496 } 2497 2498 func DefeatKey(nodeId discover.NodeID) []byte { 2499 return defeatKey(nodeId.Bytes()) 2500 } 2501 func defeatKey(key []byte) []byte { 2502 return append(append(common.CandidatePoolAddr.Bytes(), DefeatBytePrefix...), key...) 2503 } 2504 2505 func ImmediateListKey() []byte { 2506 return append(common.CandidatePoolAddr.Bytes(), ImmediateListBytePrefix...) 2507 } 2508 2509 func ReserveListKey() []byte { 2510 return append(common.CandidatePoolAddr.Bytes(), ReserveListBytePrefix...) 2511 } 2512 2513 func PreviousWitnessListKey() []byte { 2514 return append(common.CandidatePoolAddr.Bytes(), PreWitnessListBytePrefix...) 2515 } 2516 2517 func WitnessListKey() []byte { 2518 return append(common.CandidatePoolAddr.Bytes(), WitnessListBytePrefix...) 2519 } 2520 2521 func NextWitnessListKey() []byte { 2522 return append(common.CandidatePoolAddr.Bytes(), NextWitnessListBytePrefix...) 2523 } 2524 2525 func DefeatListKey() []byte { 2526 return append(common.CandidatePoolAddr.Bytes(), DefeatListBytePrefix...) 2527 } 2528 2529 func (c *CandidatePool) ForEachStorage(state vm.StateDB, title string) { 2530 c.lock.Lock() 2531 log.Debug(title + ":Full view of data in the candidate pool ...") 2532 c.initDataByState(state, 2) 2533 c.lock.Unlock() 2534 } 2535 */