github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/consensus/cbft/ppos.go (about) 1 package cbft 2 3 import ( 4 "github.com/PlatONnetwork/PlatON-Go/common" 5 "github.com/PlatONnetwork/PlatON-Go/core" 6 "github.com/PlatONnetwork/PlatON-Go/core/ppos" 7 "github.com/PlatONnetwork/PlatON-Go/core/state" 8 "github.com/PlatONnetwork/PlatON-Go/core/types" 9 "github.com/PlatONnetwork/PlatON-Go/core/vm" 10 "github.com/PlatONnetwork/PlatON-Go/log" 11 "github.com/PlatONnetwork/PlatON-Go/p2p/discover" 12 "github.com/PlatONnetwork/PlatON-Go/params" 13 "fmt" 14 "math/big" 15 "sync" 16 "github.com/PlatONnetwork/PlatON-Go/core/ppos_storage" 17 ) 18 19 type ppos struct { 20 21 nodeRound roundCache 22 //chain *core.BlockChain 23 lastCycleBlockNum uint64 24 // A round of consensus start time is usually the block time of the last block at the end of the last round of consensus; 25 // if it is the first round, it starts from 1970.1.1.0.0.0.0. Unit: second 26 startTimeOfEpoch int64 27 config *params.PposConfig 28 29 // added by candidateContext module 30 lock sync.RWMutex 31 // the candidateContext pool object pointer 32 candidateContext *pposm.CandidatePoolContext 33 // the ticket pool object pointer 34 ticketContext *pposm.TicketPoolContext 35 36 pposTemp *ppos_storage.PPOS_TEMP 37 } 38 39 40 41 func newPpos(config *params.CbftConfig) *ppos { 42 return &ppos{ 43 lastCycleBlockNum: 0, 44 config: config.PposConfig, 45 candidateContext: pposm.NewCandidatePoolContext(config.PposConfig), 46 ticketContext: pposm.NewTicketPoolContext(config.PposConfig), 47 } 48 } 49 50 51 func (p *ppos) BlockProducerIndex(parentNumber *big.Int, parentHash common.Hash, blockNumber *big.Int, nodeID discover.NodeID, round int32) (int64, []discover.NodeID) { 52 p.lock.RLock() 53 defer p.lock.RUnlock() 54 55 log.Info("BlockProducerIndex", "parentNumber", parentNumber, "parentHash", parentHash.String(), "blockNumber", blockNumber.String(), "nodeID", nodeID.String(), "round", round) 56 57 nodeCache := p.nodeRound.getNodeCache(parentNumber, parentHash) 58 p.printMapInfo("BlockProducerIndex", parentNumber.Uint64(), parentHash) 59 if nodeCache != nil { 60 _former := nodeCache.former 61 _current := nodeCache.current 62 _next := nodeCache.next 63 64 switch round { 65 case former: 66 if _former != nil && _former.start != nil && _former.end != nil && blockNumber.Cmp(_former.start) >= 0 && blockNumber.Cmp(_former.end) <= 0 { 67 return p.roundIndex(nodeID, _former), _former.nodeIds 68 } 69 70 case current: 71 if _current != nil && _current.start != nil && _current.end != nil && blockNumber.Cmp(_current.start) >= 0 && blockNumber.Cmp(_current.end) <= 0 { 72 return p.roundIndex(nodeID, _current), _current.nodeIds 73 } 74 75 case next: 76 if _next != nil && _next.start != nil && _next.end != nil && blockNumber.Cmp(_next.start) >= 0 && blockNumber.Cmp(_next.end) <= 0 { 77 return p.roundIndex(nodeID, _next), _next.nodeIds 78 } 79 80 default: 81 if _former != nil && _former.start != nil && _former.end != nil && blockNumber.Cmp(_former.start) >= 0 && blockNumber.Cmp(_former.end) <= 0 { 82 return p.roundIndex(nodeID, _former), _former.nodeIds 83 } else if _current != nil && _current.start != nil && _current.end != nil && blockNumber.Cmp(_current.start) >= 0 && blockNumber.Cmp(_current.end) <= 0 { 84 return p.roundIndex(nodeID, _current), _current.nodeIds 85 } else if _next != nil && _next.start != nil && _next.end != nil && blockNumber.Cmp(_next.start) >= 0 && blockNumber.Cmp(_next.end) <= 0 { 86 return p.roundIndex(nodeID, _next), _next.nodeIds 87 } 88 } 89 } 90 return -1, nil 91 } 92 93 func (p *ppos) roundIndex(nodeID discover.NodeID, round *pposRound) int64 { 94 for idx, nid := range round.nodeIds { 95 if nid == nodeID { 96 return int64(idx) 97 } 98 } 99 return -1 100 } 101 102 func (p *ppos) NodeIndexInFuture(nodeID discover.NodeID) int64 { 103 return -1 104 } 105 106 func (p *ppos) getFormerNodes (parentNumber *big.Int, parentHash common.Hash, blockNumber *big.Int) []*discover.Node { 107 p.lock.RLock() 108 defer p.lock.RUnlock() 109 110 formerRound := p.nodeRound.getFormerRound(parentNumber, parentHash) 111 if formerRound != nil && len(formerRound.nodes) > 0 && blockNumber.Cmp(formerRound.start) >= 0 && blockNumber.Cmp(formerRound.end) <= 0{ 112 return formerRound.nodes 113 } 114 return nil 115 } 116 117 func (p *ppos) getCurrentNodes (parentNumber *big.Int, parentHash common.Hash, blockNumber *big.Int) []*discover.Node { 118 p.lock.RLock() 119 defer p.lock.RUnlock() 120 121 currentRound := p.nodeRound.getCurrentRound(parentNumber, parentHash) 122 if currentRound != nil && currentRound.start != nil && currentRound.end != nil && len(currentRound.nodes) > 0 && blockNumber.Cmp(currentRound.start) >= 0 && blockNumber.Cmp(currentRound.end) <= 0{ 123 return currentRound.nodes 124 } 125 return nil 126 } 127 128 129 func (p *ppos) consensusNodes(parentNumber *big.Int, parentHash common.Hash, blockNumber *big.Int) []discover.NodeID { 130 p.lock.RLock() 131 defer p.lock.RUnlock() 132 133 log.Debug("call consensusNodes", "parentNumber", parentNumber.Uint64(), "parentHash", parentHash, "blockNumber", blockNumber.Uint64()) 134 nodeCache := p.nodeRound.getNodeCache(parentNumber, parentHash) 135 p.printMapInfo("consensusNodes nodeCache", parentNumber.Uint64(), parentHash) 136 if nodeCache != nil { 137 if nodeCache.former != nil && nodeCache.former.start != nil && nodeCache.former.end != nil && blockNumber.Cmp(nodeCache.former.start) >= 0 && blockNumber.Cmp(nodeCache.former.end) <= 0 { 138 return nodeCache.former.nodeIds 139 } else if nodeCache.current != nil && nodeCache.current.start != nil && nodeCache.current.end != nil && blockNumber.Cmp(nodeCache.current.start) >= 0 && blockNumber.Cmp(nodeCache.current.end) <= 0 { 140 return nodeCache.current.nodeIds 141 } else if nodeCache.next != nil && nodeCache.next.start != nil && nodeCache.next.end != nil && blockNumber.Cmp(nodeCache.next.start) >= 0 && blockNumber.Cmp(nodeCache.next.end) <= 0 { 142 return nodeCache.next.nodeIds 143 } 144 } 145 return nil 146 } 147 148 func (p *ppos) LastCycleBlockNum() uint64 { 149 // Get the block height at the end of the final round of consensus 150 return p.lastCycleBlockNum 151 } 152 153 func (p *ppos) SetLastCycleBlockNum(blockNumber uint64) { 154 // Set the block height at the end of the last round of consensus 155 p.lastCycleBlockNum = blockNumber 156 } 157 158 159 func (p *ppos) StartTimeOfEpoch() int64 { 160 return p.startTimeOfEpoch 161 } 162 163 func (p *ppos) SetStartTimeOfEpoch(startTimeOfEpoch int64) { 164 p.startTimeOfEpoch = startTimeOfEpoch 165 } 166 167 /** ppos was added func */ 168 /** Method provided to the cbft module call */ 169 // Announce witness 170 func (p *ppos) Election(state *state.StateDB, parentHash common.Hash, currBlocknumber *big.Int) ([]*discover.Node, error) { 171 if nextNodes, err := p.candidateContext.Election(state, parentHash, currBlocknumber); nil != err { 172 log.Error("PPOS Election next witness", " err: ", err) 173 /*panic("Election error " + err.Error())*/ 174 return nil, err 175 } else { 176 //d.candidateContext.ForEachStorage(state, "PPOS Election finish,view stateDB content again ...") 177 return nextNodes, nil 178 } 179 } 180 181 // switch next witnesses to current witnesses 182 func (p *ppos) Switch(state *state.StateDB, blockNumber *big.Int) bool { 183 log.Info("Switch begin...") 184 if !p.candidateContext.Switch(state, blockNumber) { 185 return false 186 } 187 log.Info("Switch success...") 188 p.candidateContext.GetAllWitness(state, blockNumber) 189 190 return true 191 } 192 193 // Getting nodes of witnesses 194 // flag:-1: the previous round of witnesses 0: the current round of witnesses 1: the next round of witnesses 195 func (p *ppos) GetWitness(state *state.StateDB, flag int, blockNumber *big.Int) ([]*discover.Node, error) { 196 return p.candidateContext.GetWitness(state, flag, blockNumber) 197 } 198 199 func (p *ppos) GetAllWitness(state *state.StateDB, blockNumber *big.Int) ([]*discover.Node, []*discover.Node, []*discover.Node, error) { 200 return p.candidateContext.GetAllWitness(state, blockNumber) 201 } 202 203 // Getting can by witnesses 204 // flag: 205 // -1: previous round 206 // 0: current round 207 // 1: next round 208 func (p *ppos) GetWitnessCandidate (state vm.StateDB, nodeId discover.NodeID, flag int, blockNumber *big.Int) *types.Candidate { 209 return p.candidateContext.GetWitnessCandidate(state, nodeId, flag, blockNumber) 210 } 211 212 // setting candidate pool of ppos module 213 func (p *ppos) SetCandidateContextOption(blockChain *core.BlockChain, initialNodes []discover.Node) { 214 log.Info("Start node, build the nodeRound ...") 215 216 genesis := blockChain.Genesis() 217 218 // init roundCache by config 219 p.buildGenesisRound(genesis.NumberU64(), genesis.Hash(), initialNodes) 220 p.printMapInfo("Read Genesis block configuration at startup:", genesis.NumberU64(), genesis.Hash()) 221 222 // When the highest block in the chain is not a genesis block, Need to load witness nodeIdList from the stateDB. 223 if genesis.NumberU64() != blockChain.CurrentBlock().NumberU64() { 224 225 currentBlock := blockChain.CurrentBlock() 226 var currBlockNumber uint64 227 var currBlockHash common.Hash 228 var currentBigInt *big.Int 229 230 currBlockNumber = blockChain.CurrentBlock().NumberU64() 231 currentBigInt = blockChain.CurrentBlock().Number() 232 currBlockHash = blockChain.CurrentBlock().Hash() 233 234 235 236 count := 0 237 blockArr := make([]*types.Block, 0) 238 for { 239 if currBlockNumber == genesis.NumberU64() || count == common.BaseIrrCount { 240 break 241 } 242 243 parentNum := currBlockNumber - 1 244 parentBigInt := new(big.Int).Sub(currentBigInt, big.NewInt(1)) 245 parentHash := currentBlock.ParentHash() 246 blockArr = append(blockArr, currentBlock) 247 248 currBlockNumber = parentNum 249 currentBigInt = parentBigInt 250 currBlockHash = parentHash 251 currentBlock = blockChain.GetBlock(currBlockHash, currBlockNumber) 252 count ++ 253 254 } 255 256 for i := len(blockArr) - 1; 0 <= i; i-- { 257 currentBlock := blockArr[i] 258 currentNum := currentBlock.NumberU64() 259 currentBigInt := currentBlock.Number() 260 currentHash := currentBlock.Hash() 261 262 parentNum := currentNum - 1 263 //parentBigInt := new(big.Int).Sub(currentBigInt, big.NewInt(1)) 264 parentHash := currentBlock.ParentHash() 265 266 // Special processing of the last block of the array, that is, 267 // the highest block pushes the BaseIrrCount block forward 268 if i == len(blockArr) - 1 && currentNum > 1 { 269 270 var /*parent,*/ current *state.StateDB 271 272 // parentStateDB by block 273 /*parentStateRoot := blockChain.GetBlock(parentHash, parentNum).Root() 274 log.Debug("Reload the oldest block at startup", "parentNum", parentNum, "parentHash", parentHash, "parentStateRoot", parentStateRoot.String()) 275 if parentState, err := blockChain.StateAt(parentStateRoot, parentBigInt, parentHash); nil != err { 276 log.Error("Failed to load parentStateDB by block", "currtenNum", currentNum, "Hash", currentHash.String(), "parentNum", parentNum, "Hash", parentHash.String(), "err", err) 277 panic("Failed to load parentStateDB by block parentNum" + fmt.Sprint(parentNum) + ", Hash" + parentHash.String() + "err" + err.Error()) 278 }else { 279 parent = parentState 280 }*/ 281 282 // currentStateDB by block 283 stateRoot := blockChain.GetBlock(currentHash, currentNum).Root() 284 log.Debug("Reload the oldest block at startup", "currentNum", currentNum, "currentHash", currentHash, "stateRoot", stateRoot.String()) 285 if currntState, err := blockChain.StateAt(stateRoot, currentBigInt, currentHash); nil != err { 286 log.Error("Failed to load currentStateDB by block", "currtenNum", currentNum, "Hash", currentHash.String(), "err", err) 287 panic("Failed to load currentStateDB by block currentNum" + fmt.Sprint(currentNum) + ", Hash" + currentHash.String() + "err" + err.Error()) 288 }else { 289 current = currntState 290 } 291 292 if err := p.setEarliestIrrNodeCache(/*parent,*/ current, genesis.NumberU64(), currentNum, genesis.Hash(), currentHash); nil != err { 293 log.Error("Failed to setEarliestIrrNodeCache", "currentNum", currentNum, "Hash", currentHash.String(), "err", err) 294 panic("Failed to setEarliestIrrNodeCache currentNum" + fmt.Sprint(currentNum) + ", Hash" + currentHash.String() + "err" + err.Error()) 295 } 296 continue 297 } 298 299 // stateDB by block 300 stateRoot := blockChain.GetBlock(currentHash, currentNum).Root() 301 log.Debug("Reload the front normal fast at startup", "currentNum", currentNum, "currentHash", currentHash, "stateRoot", stateRoot.String()) 302 if currntState, err := blockChain.StateAt(stateRoot, currentBigInt, currentHash); nil != err { 303 log.Error("Failed to load stateDB by block", "currentNum", currentNum, "Hash", currentHash.String(), "err", err) 304 panic("Failed to load stateDB by block currentNum" + fmt.Sprint(currentNum) + ", Hash" + currentHash.String() + "err" + err.Error()) 305 }else { 306 if err := p.setGeneralNodeCache(currntState, genesis.NumberU64(), parentNum, currentNum, genesis.Hash(), parentHash, currentHash); nil != err { 307 log.Error("Failed to setGeneralNodeCache", "currentNum", currentNum, "Hash", currentHash.String(), "err", err) 308 panic("Failed to setGeneralNodeCache currentNum" + fmt.Sprint(currentNum) + ", Hash" + currentHash.String() + "err" + err.Error()) 309 } 310 } 311 } 312 } 313 } 314 315 316 func (p *ppos)buildGenesisRound(blockNumber uint64, blockHash common.Hash, initialNodes []discover.Node) { 317 initNodeArr := make([]*discover.Node, 0, len(initialNodes)) 318 initialNodesIDs := make([]discover.NodeID, 0, len(initialNodes)) 319 for _, n := range initialNodes { 320 node := n 321 initialNodesIDs = append(initialNodesIDs, node.ID) 322 initNodeArr = append(initNodeArr, &node) 323 } 324 325 // previous round 326 formerRound := &pposRound{ 327 nodeIds: make([]discover.NodeID, 0), 328 nodes: make([]*discover.Node, 0), 329 start: big.NewInt(0), 330 end: big.NewInt(0), 331 } 332 333 // current round 334 currentRound := &pposRound{ 335 nodeIds: initialNodesIDs, 336 start: big.NewInt(1), 337 end: big.NewInt(common.BaseSwitchWitness), 338 } 339 340 currentRound.nodes = make([]*discover.Node, len(initNodeArr)) 341 copy(currentRound.nodes, initNodeArr) 342 343 344 log.Debug("Initialize ppos according to the configuration file:", "blockNumber", blockNumber, "blockHash", blockHash.String(), "start", currentRound.start, "end", currentRound.end) 345 346 node := &nodeCache{ 347 former: formerRound, 348 current: currentRound, 349 } 350 res := make(roundCache, 0) 351 hashRound := make(map[common.Hash]*nodeCache, 0) 352 hashRound[blockHash] = node 353 res[blockNumber] = hashRound 354 /* set nodeRound ... */ 355 p.nodeRound = res 356 } 357 358 func (p *ppos)printMapInfo(title string, blockNumber uint64, blockHash common.Hash){ 359 res := p.nodeRound[blockNumber] 360 361 log.Debug(title + ":Traversing out the RoundNodes,num: " + fmt.Sprint(blockNumber) + ", hash: " + blockHash.String()) 362 363 if round, ok := res[blockHash]; ok { 364 if nil != round.former{ 365 pposm.PrintObject(title + ":Traversing out of the round,num: " + fmt.Sprint(blockNumber) + ", hash: " + blockHash.String() + ", previous round: start:" + round.former.start.String() + ", end:" + round.former.end.String() + ", nodes: ", round.former.nodes) 366 } 367 if nil != round.current { 368 pposm.PrintObject(title + ":Traversing out of the round,num: " + fmt.Sprint(blockNumber) + ", hash: " + blockHash.String() + ", current round: start:" + round.current.start.String() + ", end:" + round.current.end.String() + ", nodes: ", round.current.nodes) 369 } 370 if nil != round.next { 371 pposm.PrintObject(title + ":Traversing out of the round,num: " + fmt.Sprint(blockNumber) + ", hash: " + blockHash.String() + ", next round: start:" + round.next.start.String() + ", end:" + round.next.end.String() + ", nodes: ", round.next.nodes) 372 } 373 }else { 374 log.Error(title + ":Traversing out of the round is NOT EXIST !!!!!!!!,num: " + fmt.Sprint(blockNumber) + ", hash: " + blockHash.String()) 375 } 376 } 377 378 /** Method provided to the built-in contract call */ 379 // pledge Candidate 380 func (p *ppos) SetCandidate(state vm.StateDB, nodeId discover.NodeID, can *types.Candidate) error { 381 return p.candidateContext.SetCandidate(state, nodeId, can) 382 } 383 384 // Getting immediate or reserve candidate info by nodeId 385 func (p *ppos) GetCandidate(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) *types.Candidate { 386 return p.candidateContext.GetCandidate(state, nodeId, blockNumber) 387 } 388 389 // Getting immediate or reserve candidate info arr by nodeIds 390 func (p *ppos) GetCandidateArr (state vm.StateDB, blockNumber *big.Int, nodeIds ... discover.NodeID) types.CandidateQueue { 391 return p.candidateContext.GetCandidateArr(state, blockNumber, nodeIds...) 392 } 393 394 // candidate withdraw from elected candidates 395 func (p *ppos) WithdrawCandidate(state vm.StateDB, nodeId discover.NodeID, price, blockNumber *big.Int) error { 396 return p.candidateContext.WithdrawCandidate(state, nodeId, price, blockNumber) 397 } 398 399 // Getting all elected candidates array 400 func (p *ppos) GetChosens(state vm.StateDB, flag int, blockNumber *big.Int) types.KindCanQueue { 401 return p.candidateContext.GetChosens(state, flag, blockNumber) 402 } 403 404 func (p *ppos) GetCandidatePendArr (state vm.StateDB, flag int, blockNumber *big.Int) types.CandidateQueue { 405 return p.candidateContext.GetCandidatePendArr(state, flag, blockNumber) 406 } 407 408 // Getting all witness array 409 func (p *ppos) GetChairpersons(state vm.StateDB, blockNumber *big.Int) []*types.Candidate { 410 return p.candidateContext.GetChairpersons(state, blockNumber) 411 } 412 413 // Getting all refund array by nodeId 414 func (p *ppos) GetDefeat(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) types.RefundQueue { 415 return p.candidateContext.GetDefeat(state, nodeId, blockNumber) 416 } 417 418 // Checked current candidate was defeat by nodeId 419 func (p *ppos) IsDefeat(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) bool { 420 return p.candidateContext.IsDefeat(state, nodeId, blockNumber) 421 } 422 423 // refund once 424 func (p *ppos) RefundBalance(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) error { 425 return p.candidateContext.RefundBalance(state, nodeId, blockNumber) 426 } 427 428 // Getting owner's address of candidate info by nodeId 429 func (p *ppos) GetOwner(state vm.StateDB, nodeId discover.NodeID, blockNumber *big.Int) common.Address { 430 return p.candidateContext.GetOwner(state, nodeId, blockNumber) 431 } 432 433 // Getting allow block interval for refunds 434 func (p *ppos) GetRefundInterval(blockNumber *big.Int) uint32 { 435 return p.candidateContext.GetRefundInterval(blockNumber) 436 } 437 438 439 440 /** about ticketpool's method */ 441 442 func (p *ppos) GetPoolNumber (state vm.StateDB) uint32 { 443 return p.ticketContext.GetPoolNumber(state) 444 } 445 446 func (p *ppos) VoteTicket (state vm.StateDB, owner common.Address, voteNumber uint32, deposit *big.Int, nodeId discover.NodeID, blockNumber *big.Int) (uint32, error) { 447 return p.ticketContext.VoteTicket(state, owner, voteNumber, deposit, nodeId, blockNumber) 448 } 449 450 func (d *ppos) GetTicket(state vm.StateDB, ticketId common.Hash) *types.Ticket { 451 return d.ticketContext.GetTicket(state, ticketId) 452 } 453 454 func (p *ppos) GetTicketList (state vm.StateDB, ticketIds []common.Hash) []*types.Ticket { 455 return p.ticketContext.GetTicketList(state, ticketIds) 456 } 457 458 func (p *ppos) GetCandidateTicketIds (state vm.StateDB, nodeId discover.NodeID) []common.Hash { 459 return p.ticketContext.GetCandidateTicketIds(state, nodeId) 460 } 461 462 func (p *ppos) GetCandidateEpoch (state vm.StateDB, nodeId discover.NodeID) uint64 { 463 return p.ticketContext.GetCandidateEpoch(state, nodeId) 464 } 465 466 func (p *ppos) GetTicketPrice (state vm.StateDB) *big.Int { 467 return p.ticketContext.GetTicketPrice(state) 468 } 469 470 func (p *ppos) Notify (state vm.StateDB, blockNumber *big.Int) error { 471 return p.ticketContext.Notify(state, blockNumber) 472 } 473 474 func (p *ppos) StoreHash (state *state.StateDB, blockNumber *big.Int, blockHash common.Hash) { 475 if err := p.ticketContext.StoreHash(state, blockNumber, blockHash); nil != err { 476 log.Error("Failed to StoreHash", "err", err) 477 panic("Failed to StoreHash err" + err.Error()) 478 } 479 } 480 481 func (p *ppos) Submit2Cache (state *state.StateDB, currBlocknumber, blockInterval *big.Int, currBlockhash common.Hash) { 482 p.pposTemp.SubmitPposCache2Temp(currBlocknumber, blockInterval, currBlockhash, state.SnapShotPPOSCache()) 483 } 484 485 // cbft consensus fork need to update nodeRound 486 func (p *ppos) UpdateNodeList(blockChain *core.BlockChain, blocknumber *big.Int, blockHash common.Hash) { 487 log.Info("---cbft consensus fork,update nodeRound---") 488 // clean nodeCache 489 p.cleanNodeRound() 490 491 492 var curBlockNumber uint64 = blocknumber.Uint64() 493 var curBlockHash common.Hash = blockHash 494 495 currentBlock := blockChain.GetBlock(curBlockHash, curBlockNumber) 496 genesis := blockChain.Genesis() 497 p.lock.Lock() 498 defer p.lock.Unlock() 499 500 count := 0 501 blockArr := make([]*types.Block, 0) 502 for { 503 if curBlockNumber == genesis.NumberU64() || count == common.BaseIrrCount { 504 break 505 } 506 parentNum := curBlockNumber - 1 507 parentHash := currentBlock.ParentHash() 508 blockArr = append(blockArr, currentBlock) 509 510 curBlockNumber = parentNum 511 curBlockHash = parentHash 512 currentBlock = blockChain.GetBlock(curBlockHash, curBlockNumber) 513 count ++ 514 515 } 516 517 for i := len(blockArr) - 1; 0 <= i; i-- { 518 currentBlock := blockArr[i] 519 currentNum := currentBlock.NumberU64() 520 currentBigInt := currentBlock.Number() 521 currentHash := currentBlock.Hash() 522 523 parentNum := currentNum - 1 524 //parentBigInt := new(big.Int).Sub(currentBigInt, big.NewInt(1)) 525 parentHash := currentBlock.ParentHash() 526 527 528 // Special processing of the last block of the array, that is, 529 // the highest block pushes the BaseIrrCount block forward 530 if i == len(blockArr) - 1 && currentNum > 1 { 531 532 var/* parent,*/ current *state.StateDB 533 534 /*// parentStateDB by block 535 parentStateRoot := blockChain.GetBlock(parentHash, parentNum).Root() 536 if parentState, err := blockChain.StateAt(parentStateRoot, parentBigInt, parentHash); nil != err { 537 log.Error("Failed to load parentStateDB by block", "currtenNum", currentNum, "Hash", currentHash.String(), "parentNum", parentNum, "Hash", parentHash.String(), "err", err) 538 panic("Failed to load parentStateDB by block parentNum" + fmt.Sprint(parentNum) + ", Hash" + parentHash.String() + "err" + err.Error()) 539 }else { 540 parent = parentState 541 }*/ 542 543 // currentStateDB by block 544 stateRoot := blockChain.GetBlock(currentHash, currentNum).Root() 545 if currntState, err := blockChain.StateAt(stateRoot, currentBigInt, currentHash); nil != err { 546 log.Error("Failed to load currentStateDB by block", "currentNum", currentNum, "Hash", currentHash.String(), "err", err) 547 panic("Failed to load currentStateDB by block currentNum" + fmt.Sprint(currentNum) + ", Hash" + currentHash.String() + "err" + err.Error()) 548 }else { 549 current = currntState 550 } 551 552 if err := p.setEarliestIrrNodeCache(/*parent,*/ current, genesis.NumberU64(), currentNum, genesis.Hash(), currentHash); nil != err { 553 log.Error("Failed to setEarliestIrrNodeCache", "currentNum", currentNum, "Hash", currentHash.String(), "err", err) 554 panic("Failed to setEarliestIrrNodeCache currentNum" + fmt.Sprint(currentNum) + ", Hash" + currentHash.String() + "err" + err.Error()) 555 } 556 p.printMapInfo("Reload the oldest block when forked", currentNum, currentHash) 557 continue 558 } 559 560 // stateDB by block 561 stateRoot := blockChain.GetBlock(currentHash, currentNum).Root() 562 if currntState, err := blockChain.StateAt(stateRoot, currentBigInt, currentHash); nil != err { 563 log.Error("Failed to load stateDB by block", "currentNum", currentNum, "Hash", currentHash.String(), "err", err) 564 panic("Failed to load stateDB by block currentNum" + fmt.Sprint(currentNum) + ", Hash" + currentHash.String() + "err" + err.Error()) 565 }else { 566 if err := p.setGeneralNodeCache(currntState, genesis.NumberU64(), parentNum, currentNum, genesis.Hash(), parentHash, currentHash); nil != err { 567 log.Error("Failed to setGeneralNodeCache", "currentNum", currentNum, "Hash", currentHash.String(), "err", err) 568 panic("Failed to setGeneralNodeCache currentNum" + fmt.Sprint(currentNum) + ", Hash" + currentHash.String() + "err" + err.Error()) 569 } 570 } 571 p.printMapInfo("Reload the previous normal block when forking", currentNum, currentHash) 572 } 573 } 574 575 func convertNodeID(nodes []*discover.Node) []discover.NodeID { 576 nodesID := make([]discover.NodeID, 0, len(nodes)) 577 for _, n := range nodes { 578 nodesID = append(nodesID, n.ID) 579 } 580 return nodesID 581 } 582 583 // calculate current round number by current blocknumber 584 func calcurround(blocknumber uint64) uint64 { 585 // current num 586 var round uint64 587 div := blocknumber / common.BaseSwitchWitness 588 mod := blocknumber % common.BaseSwitchWitness 589 if (div == 0 && mod == 0) || (div == 0 && mod > 0 && mod < common.BaseSwitchWitness) { // first round 590 round = 1 591 } else if div > 0 && mod == 0 { 592 round = div 593 } else if div > 0 && mod > 0 && mod < common.BaseSwitchWitness { 594 round = div + 1 595 } 596 return round 597 } 598 599 600 func (p *ppos) GetFormerRound(blockNumber *big.Int, blockHash common.Hash) *pposRound { 601 p.lock.RLock() 602 defer p.lock.RUnlock() 603 return p.nodeRound.getFormerRound(blockNumber, blockHash) 604 } 605 606 func (p *ppos) GetCurrentRound (blockNumber *big.Int, blockHash common.Hash) *pposRound { 607 p.lock.RLock() 608 defer p.lock.RUnlock() 609 return p.nodeRound.getCurrentRound(blockNumber, blockHash) 610 } 611 612 func (p *ppos) GetNextRound (blockNumber *big.Int, blockHash common.Hash) *pposRound { 613 p.lock.RLock() 614 defer p.lock.RUnlock() 615 return p.nodeRound.getNextRound(blockNumber, blockHash) 616 } 617 618 func (p *ppos) SetNodeCache (state *state.StateDB, genesisNumber, parentNumber, currentNumber *big.Int, genesisHash, parentHash, currentHash common.Hash) error { 619 p.lock.Lock() 620 defer p.lock.Unlock() 621 return p.setGeneralNodeCache(state, genesisNumber.Uint64(), parentNumber.Uint64(), currentNumber.Uint64(), genesisHash, parentHash, currentHash) 622 } 623 func (p *ppos) setGeneralNodeCache (state *state.StateDB, genesisNumber, parentNumber, currentNumber uint64, genesisHash, parentHash, currentHash common.Hash) error { 624 parentNumBigInt := big.NewInt(int64(parentNumber)) 625 // current round 626 round := calcurround(currentNumber) 627 628 log.Debug("Setting current block Node Cache", "parentNumber", parentNumber, "ParentHash", parentHash.String(), "currentNumber:", currentNumber, "hash", currentHash.String(), "round:", round) 629 630 /** ------------------------------ current ppos ------------------------------ **/ 631 preNodes, curNodes, nextNodes, err := p.candidateContext.GetAllWitness(state, big.NewInt(int64(currentNumber))) 632 633 if nil != err { 634 log.Error("Failed to setting nodeCache on setGeneralNodeCache", "err", err) 635 return err 636 } 637 638 /** ------------------------------ parent ------------------------------ **/ 639 640 parent_Former_Round := p.nodeRound.getFormerRound(parentNumBigInt, parentHash) 641 642 parent_Current_Round := p.nodeRound.getCurrentRound(parentNumBigInt, parentHash) 643 644 parent_Next_Round := p.nodeRound.getNextRound(parentNumBigInt, parentHash) 645 646 /** ------------------------------ genesis ------------------------------ **/ 647 648 genesisNumBigInt := big.NewInt(int64(genesisNumber)) 649 genesis_Current_Round := p.nodeRound.getCurrentRound(genesisNumBigInt, genesisHash) 650 651 /** ------------------------------ end ---------------------------- **/ 652 653 var start, end *big.Int 654 655 // Determine if it is the last block of the current round. 656 // If it is, start is the start of the next round, 657 // and end is the end of the next round. 658 if cmpSwitch(round, currentNumber) == 0 { 659 start = big.NewInt(int64(common.BaseSwitchWitness*round) + 1) 660 end = new(big.Int).Add(start, big.NewInt(int64(common.BaseSwitchWitness-1))) 661 }else { 662 start = big.NewInt(int64(common.BaseSwitchWitness*(round-1)) + 1) 663 end = new(big.Int).Add(start, big.NewInt(int64(common.BaseSwitchWitness-1))) 664 } 665 666 // former 667 formerRound := &pposRound{} 668 // former start, end 669 if round != common.FirstRound { 670 formerRound.start = new(big.Int).Sub(start, new(big.Int).SetUint64(uint64(common.BaseSwitchWitness))) 671 formerRound.end = new(big.Int).Sub(end, new(big.Int).SetUint64(uint64(common.BaseSwitchWitness))) 672 }else { 673 formerRound.start = big.NewInt(0) 674 formerRound.end = big.NewInt(0) 675 } 676 677 log.Debug("Setting current block Node Cache Previous round ", "start",formerRound.start, "end", formerRound.end) 678 679 if len(preNodes) != 0 { 680 formerRound.nodeIds = convertNodeID(preNodes) 681 formerRound.nodes = make([]*discover.Node, len(preNodes)) 682 copy(formerRound.nodes, preNodes) 683 }else { // Reference parent 684 // if last block of round 685 if cmpSwitch(round, currentNumber) == 0 { 686 //parentCurRound := p.nodeRound.getCurrentRound(parentNumBigInt, parentHash) 687 if nil != parent_Current_Round { 688 formerRound.nodeIds = make([]discover.NodeID, len(parent_Current_Round.nodeIds)) 689 copy(formerRound.nodeIds, parent_Current_Round.nodeIds) 690 formerRound.nodes = make([]*discover.Node, len(parent_Current_Round.nodes)) 691 copy(formerRound.nodes, parent_Current_Round.nodes) 692 }else { 693 formerRound.nodeIds = make([]discover.NodeID, len(genesis_Current_Round.nodeIds)) 694 copy(formerRound.nodeIds, genesis_Current_Round.nodeIds) 695 formerRound.nodes = make([]*discover.Node, len(genesis_Current_Round.nodes)) 696 copy(formerRound.nodes, genesis_Current_Round.nodes) 697 } 698 }else { // Is'nt last block of round 699 //parentFormerRound := p.nodeRound.getFormerRound(parentNumBigInt, parentHash) 700 if nil != parent_Former_Round { 701 formerRound.nodeIds = make([]discover.NodeID, len(parent_Former_Round.nodeIds)) 702 copy(formerRound.nodeIds, parent_Former_Round.nodeIds) 703 formerRound.nodes = make([]*discover.Node, len(parent_Former_Round.nodes)) 704 copy(formerRound.nodes, parent_Former_Round.nodes) 705 }else { 706 formerRound.nodeIds = make([]discover.NodeID, len(genesis_Current_Round.nodeIds)) 707 copy(formerRound.nodeIds, genesis_Current_Round.nodeIds) 708 formerRound.nodes = make([]*discover.Node, len(genesis_Current_Round.nodes)) 709 copy(formerRound.nodes, genesis_Current_Round.nodes) 710 } 711 } 712 } 713 714 // current 715 currentRound := &pposRound{} 716 // current start, end 717 currentRound.start = start 718 currentRound.end = end 719 720 log.Debug("Setting current block Node Cache Current round ", "start", currentRound.start, "end",currentRound.end) 721 722 if len(curNodes) != 0 { 723 currentRound.nodeIds = convertNodeID(curNodes) 724 currentRound.nodes = make([]*discover.Node, len(curNodes)) 725 copy(currentRound.nodes, curNodes) 726 }else { // Reference parent 727 // if last block of round 728 if cmpSwitch(round, currentNumber) == 0 { 729 //parentNextRound := p.nodeRound.getNextRound(parentNumBigInt, parentHash) 730 if nil != parent_Next_Round { 731 currentRound.nodeIds = make([]discover.NodeID, len(parent_Next_Round.nodeIds)) 732 copy(currentRound.nodeIds, parent_Next_Round.nodeIds) 733 currentRound.nodes = make([]*discover.Node, len(parent_Next_Round.nodes)) 734 copy(currentRound.nodes, parent_Next_Round.nodes) 735 }else { 736 currentRound.nodeIds = make([]discover.NodeID, len(genesis_Current_Round.nodeIds)) 737 copy(currentRound.nodeIds, genesis_Current_Round.nodeIds) 738 currentRound.nodes = make([]*discover.Node, len(genesis_Current_Round.nodes)) 739 copy(currentRound.nodes, genesis_Current_Round.nodes) 740 } 741 742 }else { // Is'nt last block of round 743 //parentCurRound := p.nodeRound.getCurrentRound(parentNumBigInt, parentHash) 744 if nil != parent_Current_Round { 745 currentRound.nodeIds = make([]discover.NodeID, len(parent_Current_Round.nodeIds)) 746 copy(currentRound.nodeIds, parent_Current_Round.nodeIds) 747 currentRound.nodes = make([]*discover.Node, len(parent_Current_Round.nodes)) 748 copy(currentRound.nodes, parent_Current_Round.nodes) 749 }else { 750 currentRound.nodeIds = make([]discover.NodeID, len(genesis_Current_Round.nodeIds)) 751 copy(currentRound.nodeIds, genesis_Current_Round.nodeIds) 752 currentRound.nodes = make([]*discover.Node, len(genesis_Current_Round.nodes)) 753 copy(currentRound.nodes, genesis_Current_Round.nodes) 754 } 755 } 756 } 757 758 759 // next 760 nextRound := &pposRound{} 761 // next start, end 762 nextRound.start = new(big.Int).Add(start, new(big.Int).SetUint64(uint64(common.BaseSwitchWitness))) 763 nextRound.end = new(big.Int).Add(end, new(big.Int).SetUint64(uint64(common.BaseSwitchWitness))) 764 765 log.Debug("Setting current block Node Cache Next round ", "start", nextRound.start, "end",nextRound.end) 766 767 if len(nextNodes) != 0 { 768 nextRound.nodeIds = convertNodeID(nextNodes) 769 nextRound.nodes = make([]*discover.Node, len(nextNodes)) 770 copy(nextRound.nodes, nextNodes) 771 }else { // Reference parent 772 773 if cmpElection(round, currentNumber) == 0 { // election index == cur index 774 //parentCurRound := p.nodeRound.getCurrentRound(parentNumBigInt, parentHash) 775 if nil != parent_Current_Round { 776 nextRound.nodeIds = make([]discover.NodeID, len(parent_Current_Round.nodeIds)) 777 copy(nextRound.nodeIds, parent_Current_Round.nodeIds) 778 nextRound.nodes = make([]*discover.Node, len(parent_Current_Round.nodes)) 779 copy(nextRound.nodes, parent_Current_Round.nodes) 780 }else { 781 nextRound.nodeIds = make([]discover.NodeID, len(genesis_Current_Round.nodeIds)) 782 copy(nextRound.nodeIds, genesis_Current_Round.nodeIds) 783 nextRound.nodes = make([]*discover.Node, len(genesis_Current_Round.nodes)) 784 copy(nextRound.nodes, genesis_Current_Round.nodes) 785 } 786 }else if cmpElection(round, currentNumber) > 0 && cmpSwitch(round, currentNumber) < 0 { // election index < cur index < switch index 787 //parentNextRound := p.nodeRound.getNextRound(parentNumBigInt, parentHash) 788 if nil != parent_Next_Round { 789 nextRound.nodeIds = make([]discover.NodeID, len(parent_Next_Round.nodeIds)) 790 copy(nextRound.nodeIds, parent_Next_Round.nodeIds) 791 nextRound.nodes = make([]*discover.Node, len(parent_Next_Round.nodes)) 792 copy(nextRound.nodes, parent_Next_Round.nodes) 793 }else { 794 nextRound.nodeIds = make([]discover.NodeID, len(genesis_Current_Round.nodeIds)) 795 copy(nextRound.nodeIds, genesis_Current_Round.nodeIds) 796 nextRound.nodes = make([]*discover.Node, len(genesis_Current_Round.nodes)) 797 copy(nextRound.nodes, genesis_Current_Round.nodes) 798 } 799 }else { // switch index <= cur index < next election index 800 nextRound.nodeIds = make([]discover.NodeID, 0) 801 nextRound.nodes = make([]*discover.Node, 0) 802 } 803 } 804 805 cache := &nodeCache{ 806 former: formerRound, 807 current: currentRound, 808 next: nextRound, 809 } 810 p.nodeRound.setNodeCache(big.NewInt(int64(currentNumber)), currentHash, cache) 811 812 log.Debug("When setting the information of the current block", "currentBlockNum", currentNumber, "parentNum", parentNumber, "currentHash", currentHash.String(), "parentHash", parentHash.String()) 813 p.printMapInfo("When setting the information of the current block", currentNumber, currentHash) 814 815 return nil 816 } 817 818 func (p *ppos) setEarliestIrrNodeCache (/*parentState, */currentState *state.StateDB, genesisNumber, currentNumber uint64, genesisHash, currentHash common.Hash) error { 819 genesisNumBigInt := big.NewInt(int64(genesisNumber)) 820 // current round 821 round := calcurround(currentNumber) 822 log.Debug("Set the farthest allowed cache reserved block", "currentNumber:", currentNumber, "round:", round) 823 824 curr_PRE_Nodes, curr_CURR_Nodes, curr_NEXT_Nodes, err := p.candidateContext.GetAllWitness(currentState, big.NewInt(int64(currentNumber))) 825 826 if nil != err { 827 log.Error("Failed to setting nodeCache by currentStateDB on setEarliestIrrNodeCache", "err", err) 828 return err 829 } 830 831 /*parent_preNodes, parent_curNodes, parent_nextNodes, err := p.candidateContext.GetAllWitness(parentState) 832 if nil != err { 833 log.Error("Failed to setting nodeCache by parentStateDB on setEarliestIrrNodeCache", "err", err) 834 return err 835 }*/ 836 837 genesisCurRound := p.nodeRound.getCurrentRound(genesisNumBigInt, genesisHash) 838 839 var start, end *big.Int 840 841 /** 842 Determine if it is the last block of the current round. 843 If it is, start is the start of the next round, 844 and end is the end of the next round. 845 */ 846 if cmpSwitch(round, currentNumber) == 0 { 847 start = big.NewInt(int64(common.BaseSwitchWitness*round) + 1) 848 end = new(big.Int).Add(start, big.NewInt(int64(common.BaseSwitchWitness-1))) 849 }else { 850 start = big.NewInt(int64(common.BaseSwitchWitness*(round-1)) + 1) 851 end = new(big.Int).Add(start, big.NewInt(int64(common.BaseSwitchWitness-1))) 852 } 853 854 /** 855 Sets former info 856 */ 857 formerRound := &pposRound{} 858 // former start, end 859 if round != common.FirstRound { 860 formerRound.start = new(big.Int).Sub(start, new(big.Int).SetUint64(uint64(common.BaseSwitchWitness))) 861 formerRound.end = new(big.Int).Sub(end, new(big.Int).SetUint64(uint64(common.BaseSwitchWitness))) 862 }else { 863 formerRound.start = big.NewInt(0) 864 formerRound.end = big.NewInt(0) 865 } 866 867 log.Debug("Set the farthest allowed cache reserved block: Previous round ", "start",formerRound.start, "end", formerRound.end) 868 869 // sets previous 870 if len(curr_PRE_Nodes) != 0 { 871 formerRound.nodeIds = convertNodeID(curr_PRE_Nodes) 872 formerRound.nodes = make([]*discover.Node, len(curr_PRE_Nodes)) 873 copy(formerRound.nodes, curr_PRE_Nodes) 874 }else { 875 // Reference parent 876 // if last block of roundcurrentState 877 if cmpSwitch(round, currentNumber) == 0 { 878 // First take the stateDB from the previous block, 879 // the stateDB of the previous block is not, 880 // just take the nodeCache corresponding to the creation block. 881 /*if len(parent_curNodes) != 0 { 882 //formerRound.nodeIds = make([]discover.NodeID, len(parent_curNodes)) 883 formerRound.nodeIds = convertNodeID(parent_curNodes) 884 formerRound.nodes = make([]*discover.Node, len(parent_curNodes)) 885 copy(formerRound.nodes, parent_curNodes) 886 }else { 887 if nil != genesisCurRound { 888 formerRound.nodeIds = make([]discover.NodeID, len(genesisCurRound.nodeIds)) 889 copy(formerRound.nodeIds, genesisCurRound.nodeIds) 890 formerRound.nodes = make([]*discover.Node, len(genesisCurRound.nodes)) 891 copy(formerRound.nodes, genesisCurRound.nodes) 892 } 893 }*/ 894 895 if nil != genesisCurRound { 896 formerRound.nodeIds = make([]discover.NodeID, len(genesisCurRound.nodeIds)) 897 copy(formerRound.nodeIds, genesisCurRound.nodeIds) 898 formerRound.nodes = make([]*discover.Node, len(genesisCurRound.nodes)) 899 copy(formerRound.nodes, genesisCurRound.nodes) 900 } 901 902 }else { // Is'nt last block of round 903 904 /*if len(parent_preNodes) != 0 { 905 //formerRound.nodeIds = make([]discover.NodeID, len(parent_preNodes)) 906 formerRound.nodeIds = convertNodeID(parent_preNodes) 907 formerRound.nodes = make([]*discover.Node, len(parent_preNodes)) 908 copy(formerRound.nodes, parent_preNodes) 909 }else { 910 if nil != genesisCurRound { 911 formerRound.nodeIds = make([]discover.NodeID, len(genesisCurRound.nodeIds)) 912 copy(formerRound.nodeIds, genesisCurRound.nodeIds) 913 formerRound.nodes = make([]*discover.Node, len(genesisCurRound.nodes)) 914 copy(formerRound.nodes, genesisCurRound.nodes) 915 } 916 }*/ 917 918 if nil != genesisCurRound { 919 formerRound.nodeIds = make([]discover.NodeID, len(genesisCurRound.nodeIds)) 920 copy(formerRound.nodeIds, genesisCurRound.nodeIds) 921 formerRound.nodes = make([]*discover.Node, len(genesisCurRound.nodes)) 922 copy(formerRound.nodes, genesisCurRound.nodes) 923 } 924 925 } 926 } 927 928 /** 929 Sets current info 930 */ 931 currentRound := &pposRound{} 932 // current start, end 933 currentRound.start = start 934 currentRound.end = end 935 936 log.Debug("Set the farthest allowed cache reserved block: Current round", "start", currentRound.start, "end",currentRound.end) 937 938 // sets current 939 if len(curr_CURR_Nodes) != 0 { 940 currentRound.nodeIds = convertNodeID(curr_CURR_Nodes) 941 currentRound.nodes = make([]*discover.Node, len(curr_CURR_Nodes)) 942 copy(currentRound.nodes, curr_CURR_Nodes) 943 }else { // Reference parent 944 // if last block of round 945 if cmpSwitch(round, currentNumber) == 0 { 946 /*if len(parent_nextNodes) != 0 { 947 currentRound.nodeIds = convertNodeID(parent_nextNodes) 948 currentRound.nodes = make([]*discover.Node, len(parent_nextNodes)) 949 copy(currentRound.nodes, parent_nextNodes) 950 }else { 951 if nil != genesisCurRound { 952 currentRound.nodeIds = make([]discover.NodeID, len(genesisCurRound.nodeIds)) 953 copy(currentRound.nodeIds, genesisCurRound.nodeIds) 954 currentRound.nodes = make([]*discover.Node, len(genesisCurRound.nodes)) 955 copy(currentRound.nodes, genesisCurRound.nodes) 956 } 957 }*/ 958 959 if nil != genesisCurRound { 960 currentRound.nodeIds = make([]discover.NodeID, len(genesisCurRound.nodeIds)) 961 copy(currentRound.nodeIds, genesisCurRound.nodeIds) 962 currentRound.nodes = make([]*discover.Node, len(genesisCurRound.nodes)) 963 copy(currentRound.nodes, genesisCurRound.nodes) 964 } 965 }else { // Is'nt last block of round 966 967 /*if len(parent_curNodes) != 0 { 968 currentRound.nodeIds = convertNodeID(parent_curNodes) 969 currentRound.nodes = make([]*discover.Node, len(parent_curNodes)) 970 copy(currentRound.nodes, parent_curNodes) 971 }else { 972 if nil != genesisCurRound { 973 currentRound.nodeIds = make([]discover.NodeID, len(genesisCurRound.nodeIds)) 974 copy(currentRound.nodeIds, genesisCurRound.nodeIds) 975 currentRound.nodes = make([]*discover.Node, len(genesisCurRound.nodes)) 976 copy(currentRound.nodes, genesisCurRound.nodes) 977 } 978 }*/ 979 980 if nil != genesisCurRound { 981 currentRound.nodeIds = make([]discover.NodeID, len(genesisCurRound.nodeIds)) 982 copy(currentRound.nodeIds, genesisCurRound.nodeIds) 983 currentRound.nodes = make([]*discover.Node, len(genesisCurRound.nodes)) 984 copy(currentRound.nodes, genesisCurRound.nodes) 985 } 986 987 } 988 } 989 990 /** 991 Sets next info 992 */ 993 nextRound := &pposRound{} 994 // next start, end 995 nextRound.start = new(big.Int).Add(start, new(big.Int).SetUint64(uint64(common.BaseSwitchWitness))) 996 nextRound.end = new(big.Int).Add(end, new(big.Int).SetUint64(uint64(common.BaseSwitchWitness))) 997 998 log.Debug("Set the farthest allowed cache reserved block: Next round", "start", nextRound.start, "end",nextRound.end) 999 1000 // sets next 1001 if len(curr_NEXT_Nodes) != 0 { 1002 nextRound.nodeIds = convertNodeID(curr_NEXT_Nodes) 1003 nextRound.nodes = make([]*discover.Node, len(curr_NEXT_Nodes)) 1004 copy(nextRound.nodes, curr_NEXT_Nodes) 1005 }else { // Reference parent 1006 // election index == cur index || election index < cur index < switch index 1007 if cmpElection(round, currentNumber) == 0 || (cmpElection(round, currentNumber) > 0 && cmpSwitch(round, currentNumber) < 0) { 1008 1009 if nil != genesisCurRound { 1010 nextRound.nodeIds = make([]discover.NodeID, len(genesisCurRound.nodeIds)) 1011 copy(nextRound.nodeIds, genesisCurRound.nodeIds) 1012 nextRound.nodes = make([]*discover.Node, len(genesisCurRound.nodes)) 1013 copy(nextRound.nodes, genesisCurRound.nodes) 1014 } 1015 }else { // parent switch index <= cur index < election index || switch index <= cur index < next election index 1016 nextRound.nodeIds = make([]discover.NodeID, 0) 1017 nextRound.nodes = make([]*discover.Node, 0) 1018 } 1019 } 1020 1021 /* 1022 Sets nodeCache 1023 */ 1024 cache := &nodeCache{ 1025 former: formerRound, 1026 current: currentRound, 1027 next: nextRound, 1028 } 1029 p.nodeRound.setNodeCache(big.NewInt(int64(currentNumber)), currentHash, cache) 1030 log.Debug("Set the farthest allowed to cache the information of the reserved block", "currentBlockNum", currentNumber, "currentHash", currentHash.String()) 1031 p.printMapInfo("Set the farthest allowed to cache the information of the reserved block", currentNumber, currentHash) 1032 return nil 1033 } 1034 1035 1036 func (p *ppos) cleanNodeRound () { 1037 p.lock.Lock() 1038 p.nodeRound = make(roundCache, 0) 1039 p.lock.Unlock() 1040 } 1041 1042 // election index == cur 0 1043 // cur < election index -1 1044 // election index < cur 1 1045 // param invalid -2 1046 func cmpElection (round, currentNumber uint64) int { 1047 // last num of round 1048 last := int(round * common.BaseSwitchWitness) 1049 ele_sub := int(common.BaseSwitchWitness - common.BaseElection) 1050 curr_sub := last - int(currentNumber) 1051 sub := ele_sub - curr_sub 1052 //fmt.Println("sss ", sub) 1053 if curr_sub < int(0) { 1054 return -2 1055 }else if sub > int(0) { 1056 return 1 1057 }else if sub == int(0) { 1058 return 0 1059 }else { 1060 return -1 1061 } 1062 } 1063 1064 // switch index == cur 0 1065 // cur < switch index -1 1066 // switch index < cur 1 1067 // param invalid -2 1068 func cmpSwitch (round, currentNum uint64) int { 1069 last := round * common.BaseSwitchWitness 1070 if last < currentNum { 1071 return 1 1072 }else if last == currentNum { 1073 return 0 1074 }else { 1075 return -1 1076 } 1077 } 1078 1079 func (p *ppos) setPPOS_Temp(){ 1080 p.pposTemp = ppos_storage.GetPPosTempPtr() 1081 } 1082