github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/core/ppos_storage/ppos_temp.go (about) 1 package ppos_storage 2 3 import ( 4 "sync" 5 "math/big" 6 "github.com/PlatONnetwork/PlatON-Go/log" 7 "github.com/PlatONnetwork/PlatON-Go/common" 8 9 "github.com/PlatONnetwork/PlatON-Go/ethdb" 10 "github.com/golang/protobuf/proto" 11 "github.com/PlatONnetwork/PlatON-Go/core/types" 12 "errors" 13 "github.com/PlatONnetwork/PlatON-Go/p2p/discover" 14 "fmt" 15 "encoding/json" 16 "crypto/md5" 17 ) 18 19 const ppos_empty_indb = "leveldb: not found" 20 21 var ( 22 WRITE_PPOS_ERR = errors.New("Failed to Write ppos storage into disk") 23 24 // The key of ppos storage in disk (leveldb) 25 PPOS_STORAGE_KEY = []byte("PPOS_STORAGE_KEY") 26 ) 27 28 type numTempMap map[string]hashTempMap 29 type hashTempMap map[common.Hash]*Ppos_storage 30 31 // Global PPOS Dependency TEMP 32 type PPOS_TEMP struct { 33 34 BlockNumber *big.Int 35 BlockHash common.Hash 36 37 db ethdb.Database 38 39 // Record block total count 40 BlockCount uint32 41 42 // global data temp 43 TempMap numTempMap 44 45 lock *sync.Mutex 46 } 47 48 /** 49 This is a Global ppos data temp 50 */ 51 var ppos_temp *PPOS_TEMP 52 53 54 func NewPPosTemp(db ethdb.Database) *PPOS_TEMP { 55 56 timer := common.NewTimer() 57 timer.Begin() 58 59 log.Info("NewPPosTemp start ...") 60 if nil != ppos_temp { 61 return ppos_temp 62 } 63 ppos_temp = new(PPOS_TEMP) 64 65 ppos_temp.db = db 66 67 ppos_temp.BlockCount = 0 68 69 ntemp := make(numTempMap, 0) 70 ppos_temp.TempMap = ntemp 71 ppos_temp.lock = &sync.Mutex{} 72 73 // defualt value 74 ppos_temp.BlockNumber = big.NewInt(0) 75 ppos_temp.BlockHash = common.Hash{} 76 77 if data, err := db.Get(PPOS_STORAGE_KEY); nil != err { 78 if ppos_empty_indb != err.Error() { 79 log.Error("Failed to Call NewPPosTemp to get Global ppos temp by levelDB", "err", err) 80 return ppos_temp 81 } 82 } else { 83 log.Debug("Call NewPPosTemp to Unmarshal Global ppos temp", "pb data len", len(data)) 84 85 pb_pposTemp := new(PB_PPosTemp) 86 if err := proto.Unmarshal(data, pb_pposTemp); err != nil { 87 log.Error("Failed to Call NewPPosTemp to Unmarshal Global ppos temp", "err", err) 88 return ppos_temp 89 }else { 90 /** 91 build global ppos_temp 92 */ 93 94 // TODO 95 log.Debug("NewPPosTemp loading data from disk:", "data len", len(data), "dataMD5", md5.Sum(data)) 96 97 //PrintObject("NewPPosTemp loading data from disk:", pb_pposTemp) 98 99 100 pposStorage := unmarshalPBStorage(pb_pposTemp) 101 102 103 hashMap := make(map[common.Hash]*Ppos_storage, 0) 104 blockHash := common.HexToHash(pb_pposTemp.BlockHash) 105 hashMap[blockHash] = pposStorage 106 ppos_temp.TempMap[pb_pposTemp.BlockNumber] = hashMap 107 108 num, _ := new(big.Int).SetString(pb_pposTemp.BlockNumber, 10) 109 110 ppos_temp.BlockNumber = num 111 ppos_temp.BlockHash = blockHash 112 113 log.Debug("Call NewPPosTemp loading into memory data", "blockNumber", pb_pposTemp.BlockNumber, "blockHash", pb_pposTemp.BlockHash) 114 115 } 116 } 117 118 log.Debug("Call NewPPosTemp finish ...", "time long ms: ", timer.End()) 119 return ppos_temp 120 } 121 122 func GetPPosTempPtr() *PPOS_TEMP { 123 return ppos_temp 124 } 125 126 127 func BuildPposCache(blockNumber *big.Int, blockHash common.Hash) *Ppos_storage { 128 return ppos_temp.getPposCacheFromTemp(blockNumber, blockHash) 129 } 130 131 132 // Get ppos storage cache by same block 133 func (temp *PPOS_TEMP) getPposCacheFromTemp(blockNumber *big.Int, blockHash common.Hash) *Ppos_storage { 134 135 ppos_storage := NewPPOS_storage() 136 137 notGenesisBlock := blockNumber.Cmp(big.NewInt(0)) > 0 138 139 if nil == temp && notGenesisBlock { 140 log.Warn("Warn Call getPposCacheFromTemp of PPOS_TEMP, the Global PPOS_TEMP instance is nil !!!!!!!!!!!!!!!", "blockNumber", blockNumber.Uint64(), "blockHash", blockHash.Hex()) 141 return ppos_storage 142 } 143 144 if !notGenesisBlock || (common.Hash{}) == blockHash { 145 return ppos_storage 146 } 147 148 var storage *Ppos_storage 149 150 temp.lock.Lock() 151 if hashTemp, ok := temp.TempMap[blockNumber.String()]; !ok { 152 log.Warn("Warn Call getPposCacheFromTemp of PPOS_TEMP, the PPOS storage cache is empty by blockNumber !!!!! Direct short-circuit", "blockNumber", blockNumber.Uint64(), "blockHash", blockHash.Hex()) 153 temp.lock.Unlock() 154 return ppos_storage 155 }else { 156 157 if pposStorage, ok := hashTemp[blockHash]; !ok { 158 log.Warn("Warn Call getPposCacheFromTemp of PPOS_TEMP, the PPOS storage cache is empty by blockHash !!!!! Direct short-circuit", "blockNumber", blockNumber.Uint64(), "blockHash", blockHash.Hex()) 159 temp.lock.Unlock() 160 return ppos_storage 161 }else { 162 start := common.NewTimer() 163 start.Begin() 164 storage = pposStorage.Copy() 165 log.Debug("Call getPposCacheFromTemp of PPOS_TEMP, Copy ppos_storage FINISH !!!!!!", "blockNumber", blockNumber.Uint64(), "blockHash", blockHash.Hex(), "Time spent", fmt.Sprintf("%v ms", start.End())) 166 } 167 } 168 temp.lock.Unlock() 169 return storage 170 } 171 172 // Set ppos storage cache by same block 173 func (temp *PPOS_TEMP) SubmitPposCache2Temp(blockNumber, blockInterval *big.Int, blockHash common.Hash, storage *Ppos_storage) { 174 log.Info("Call SubmitPposCache2Temp of PPOS_TEMP", "blockNumber", blockNumber.String(), "blockHash", blockHash.Hex(), 175 "blockInterval", blockInterval, "Before SubmitPposCache2Temp, THEN PPOS_TEMP len ", len(temp.TempMap), "Block Count", temp.BlockCount) 176 177 start := common.NewTimer() 178 start.Begin() 179 180 empty := verifyStorageEmpty(storage) 181 182 183 temp.lock.Lock() 184 /** 185 first condition blockNumber 186 There are four kinds. 187 1a、origin data is empty by blockNumber AND input data is not empty; then we will Add (set) input data into global temp 188 2a、origin data is empty by blockNumber AND input data is empty; then we direct short-circuit 189 3a、origin data is not empty by blockNumber AND input data is not empty; then we will update (set) global temp by indata 190 4a、origin data is not empty by blockNumber AND input data is empty; then we will delete global temp data 191 */ 192 193 originHashTemp, hasNum := temp.TempMap[blockNumber.String()] 194 // match 1a 195 if !hasNum && !empty { 196 originHashTemp = make(hashTempMap, 1) 197 originHashTemp[blockHash] = storage 198 temp.TempMap[blockNumber.String()] = originHashTemp 199 200 temp.BlockCount += 1 201 202 temp.deleteAnyTemp(blockNumber, blockInterval, blockHash) 203 temp.lock.Unlock() 204 return 205 }else if !hasNum && empty { // match 2a 206 log.Debug("Call SubmitPposCache2Temp of PPOS_TEMP, origin ppos_storage and input ppos_storage is empty by BlockNumber !!!! Direct short-circuit", "blockNumber", blockNumber.Uint64(), 207 "blockHash", blockHash.Hex(), "blockInterval", blockInterval, " Before SubmitPposCache2Temp, THEN PPOS_TEMP len ", len(temp.TempMap), "Block Count", temp.BlockCount, "Time spent", fmt.Sprintf("%v ms", start.End())) 208 temp.lock.Unlock() 209 return 210 } 211 212 _, hasHash := originHashTemp[blockHash] 213 214 /** 215 second condition blockHash 216 There are four kinds, too. 217 1b、origin data is empty by blockHash AND input data is not empty; then we will Add (set) indata into global temp 218 2b、origin data is empty by blockHash AND input data is empty; then we direct short-circuit 219 3b、origin data is not empty by blockHash AND input data is not empty; then we will update (set) global temp by indata 220 4b、origin data is not empty by blockHash AND input data is empty; then we will delete global temp data 221 */ 222 223 // match 1b 224 if !hasHash && !empty { 225 originHashTemp[blockHash] = storage 226 temp.TempMap[blockNumber.String()] = originHashTemp 227 228 temp.BlockCount += 1 229 230 temp.deleteAnyTemp(blockNumber, blockInterval, blockHash) 231 temp.lock.Unlock() 232 return 233 }else if !hasHash && empty { // match 2b 234 log.Debug("Call SubmitPposCache2Temp of PPOS_TEMP, origin ppos_storage and input ppos_storage is empty by BlockHash !!!! Direct short-circuit", "blockNumber", blockNumber.Uint64(), 235 "blockHash", blockHash.Hex(), "blockInterval", blockInterval, " Before SubmitPposCache2Temp, THEN PPOS_TEMP len ", len(temp.TempMap), "Block Count", temp.BlockCount, "Time spent", fmt.Sprintf("%v ms", start.End())) 236 temp.lock.Unlock() 237 return 238 } 239 240 // now remain 3a 4a 3b 4b 241 if hasHash && empty { // delete origin data 242 delete(originHashTemp, blockHash) 243 temp.BlockCount -= 1 244 if len(originHashTemp) == 0 { 245 delete(temp.TempMap, blockNumber.String()) 246 } 247 248 temp.deleteAnyTemp(blockNumber, blockInterval, blockHash) 249 }else if hasHash && !empty { 250 originHashTemp[blockHash] = storage 251 temp.TempMap[blockNumber.String()] = originHashTemp 252 253 temp.deleteAnyTemp(blockNumber, blockInterval, blockHash) 254 } 255 temp.lock.Unlock() 256 log.Debug("Call SubmitPposCache2Temp of PPOS_TEMP,SUCCESS !!!!!!", "blockNumber", blockNumber.Uint64(), "blockHash", blockHash.Hex(), 257 "blockInterval", blockInterval, " Before SubmitPposCache2Temp, THEN PPOS_TEMP len ", len(temp.TempMap), "Block Count", temp.BlockCount, "Time spent", fmt.Sprintf("%v ms", start.End())) 258 259 } 260 261 func (temp *PPOS_TEMP) Commit2DB(blockNumber *big.Int, blockHash common.Hash) error { 262 start := common.NewTimer() 263 start.Begin() 264 265 266 var ps *Ppos_storage 267 temp.lock.Lock() 268 if hashMap, ok := temp.TempMap[blockNumber.String()]; !ok { 269 temp.lock.Unlock() 270 return nil 271 }else { 272 if ppos_storage, ok := hashMap[blockHash]; !ok { 273 temp.lock.Unlock() 274 return nil 275 }else { 276 ps = ppos_storage 277 } 278 } 279 temp.lock.Unlock() 280 281 282 283 284 if pposTemp := buildPBStorage(blockNumber, blockHash, ps); nil == pposTemp { 285 log.Debug("Call Commit2DB FINISH !!!! , PPOS storage is Empty, do not write disk AND direct short-circuit ...") 286 return nil 287 }else{ 288 // write ppos_storage into disk with protobuf 289 if data, err := proto.Marshal(pposTemp); nil != err { 290 log.Error("Failed to Commit2DB", "proto err", err, "Time spent", fmt.Sprintf("%v ms", start.End())) 291 return err 292 }else { 293 if len(data) != 0 { 294 295 // TODO 296 297 if err := temp.db.Put(PPOS_STORAGE_KEY, data); err != nil { 298 log.Error("Failed to Call Commit2DB:" + WRITE_PPOS_ERR.Error(), "blockNumber", blockNumber, "blockHash", blockHash.Hex(), "data len", len(data), "Time spent", fmt.Sprintf("%v ms", start.End()), "err", err) 299 return WRITE_PPOS_ERR 300 } 301 302 temp.BlockNumber = blockNumber 303 temp.BlockHash = blockHash 304 305 } 306 log.Info("Call Commit2DB, write ppos storage data to disk", "blockNumber", blockNumber, "blockHash", blockHash.Hex(), "data len", len(data), "dataMD5", md5.Sum(data), "Time spent", fmt.Sprintf("%v ms", start.End())) 307 } 308 } 309 return nil 310 } 311 312 // Gets ppos_storag pb from db 313 func (temp *PPOS_TEMP) GetPPosStorageProto() (common.Hash, []byte, error) { 314 start := common.NewTimer() 315 start.Begin() 316 if data, err := temp.db.Get(PPOS_STORAGE_KEY); nil != err { 317 if ppos_empty_indb == err.Error() { 318 log.Debug("Call GetPPosStorageProto, ppos storage is empty in disk ...") 319 return common.Hash{}, nil, nil 320 }else { 321 log.Warn("Failed to Call GetPPosStorageProto to get Global ppos temp by levelDB", "err", err) 322 return common.Hash{}, nil, err 323 } 324 } else { 325 log.Debug("Call GetPPosStorageProto to Unmarshal Global ppos temp", "pb data len", len(data)) 326 327 pb_pposTemp := new(PB_PPosTemp) 328 if err := proto.Unmarshal(data, pb_pposTemp); err != nil { 329 log.Error("Failed to Call GetPPosStorageProto to Unmarshal Global ppos temp", "err", err) 330 return common.Hash{}, nil, err 331 }else { 332 // TODO 333 334 //PrintObject("GetPPosStorageProto resolve the data of PB:", pb_pposTemp) 335 curr_Num, _ := new(big.Int).SetString(pb_pposTemp.BlockNumber, 10) 336 if curr_Num.Cmp(big.NewInt(common.BaseElection - 1)) < 0 { 337 return common.Hash{}, nil, nil 338 } 339 340 log.Debug("Call GetPPosStorageProto FINISH !!!!", "blockNumber", pb_pposTemp.BlockNumber, "blockHash", pb_pposTemp.BlockHash, "data len", len(data), "dataMD5", md5.Sum(data), "Time spent", fmt.Sprintf("%v ms", start.End())) 341 return common.HexToHash(pb_pposTemp.BlockHash), data, nil 342 } 343 } 344 } 345 346 // Flush data into db 347 func (temp *PPOS_TEMP) PushPPosStorageProto(data []byte) error { 348 if len(data) == 0 { 349 return nil 350 } 351 start := common.NewTimer() 352 start.Begin() 353 pb_pposTemp := new(PB_PPosTemp) 354 if err := proto.Unmarshal(data, pb_pposTemp); err != nil { 355 log.Error("Failed to Call PushPPosStorageProto to Unmarshal Global ppos temp", "err", err) 356 return err 357 }else { 358 /** 359 build global ppos_temp 360 */ 361 // TODO 362 363 log.Debug("PushPPosStorageProto input params:", "data len", len(data), "dataMD5", md5.Sum(data)) 364 365 //PrintObject("PushPPosStorageProto resolve the data of PB, will flush disk:", pb_pposTemp) 366 367 var hashMap map[common.Hash]*Ppos_storage 368 369 ppos_temp.lock.Lock() 370 371 if hashData, ok := ppos_temp.TempMap[pb_pposTemp.BlockNumber]; ok { 372 hashMap = hashData 373 }else { 374 hashMap = make(map[common.Hash]*Ppos_storage, 1) 375 } 376 377 pposStorage := unmarshalPBStorage(pb_pposTemp) 378 379 380 381 blockHash := common.HexToHash(pb_pposTemp.BlockHash) 382 hashMap[blockHash] = pposStorage 383 ppos_temp.TempMap[pb_pposTemp.BlockNumber] = hashMap 384 385 386 387 ppos_temp.lock.Unlock() 388 389 390 // flush data into disk 391 if len(data) != 0 { 392 log.Debug("Call PushPPosStorageProto flush data into disk start ...", "blockNumber", pb_pposTemp.BlockNumber, "blockHash", pb_pposTemp.BlockHash, "data len", len(data)) 393 if err := temp.db.Put(PPOS_STORAGE_KEY, data); err != nil { 394 log.Error("Failed to Call PushPPosStorageProto:" + WRITE_PPOS_ERR.Error(), "blockNumber", pb_pposTemp.BlockNumber, "blockHash", pb_pposTemp.BlockHash, "data len", len(data), "Time spent", fmt.Sprintf("%v ms", start.End()), "err", err) 395 return WRITE_PPOS_ERR 396 } 397 } 398 399 num, _ := new(big.Int).SetString(pb_pposTemp.BlockNumber, 10) 400 401 temp.BlockNumber = num 402 temp.BlockHash = blockHash 403 } 404 405 406 407 log.Debug("Call PushPPosStorageProto FINISH !!!!", "blockNumber", pb_pposTemp.BlockNumber, "blockHash", pb_pposTemp.BlockHash, "data len", len(data), "Time spent", fmt.Sprintf("%v ms", start.End())) 408 return nil 409 } 410 411 412 func buildPBStorage(blockNumber *big.Int, blockHash common.Hash, ps *Ppos_storage) *PB_PPosTemp { 413 ppos_temp := new(PB_PPosTemp) 414 ppos_temp.BlockNumber = blockNumber.String() 415 ppos_temp.BlockHash = blockHash.Hex() 416 417 var empty int = 0 // 0: empty 1: no 418 var wg sync.WaitGroup 419 420 /** 421 candidate related 422 */ 423 if nil != ps.c_storage { 424 425 canTemp := new(CandidateTemp) 426 427 428 wg.Add(6) 429 // previous witness 430 go func() { 431 if queue := buildPBcanqueue("buildPBStorage pres", ps.c_storage.pres); len(queue) != 0 { 432 canTemp.Pres = queue 433 empty |= 1 434 } 435 wg.Done() 436 }() 437 // current witness 438 go func() { 439 if queue := buildPBcanqueue("buildPBStorage currs", ps.c_storage.currs); len(queue) != 0 { 440 canTemp.Currs = queue 441 empty |= 1 442 } 443 wg.Done() 444 }() 445 // next witness 446 go func() { 447 if queue := buildPBcanqueue("buildPBStorage nexts", ps.c_storage.nexts); len(queue) != 0 { 448 canTemp.Nexts = queue 449 empty |= 1 450 } 451 wg.Done() 452 }() 453 // immediate 454 go func() { 455 if queue := buildPBcanqueue("buildPBStorage imms", ps.c_storage.imms); len(queue) != 0 { 456 canTemp.Imms = queue 457 empty |= 1 458 } 459 wg.Done() 460 }() 461 // reserve 462 go func() { 463 if queue := buildPBcanqueue("buildPBStorage res", ps.c_storage.res); len(queue) != 0 { 464 canTemp.Res = queue 465 empty |= 1 466 } 467 wg.Done() 468 }() 469 470 // refund 471 go func() { 472 if refundMap := buildPBrefunds(ps.c_storage.refunds); len(refundMap) != 0 { 473 canTemp.Refunds = refundMap 474 empty |= 1 475 } 476 wg.Done() 477 }() 478 479 wg.Wait() 480 ppos_temp.CanTmp = canTemp 481 } 482 483 /** 484 ticket related 485 */ 486 if nil != ps.t_storage { 487 tickTemp := new(TicketTemp) 488 489 tickTemp.Sq = ps.t_storage.Sq 490 491 // SQ 492 if ps.t_storage.Sq != -1 { 493 empty |= 1 494 } 495 496 //wg.Add(3) 497 498 // ticketInfos 499 /*go func() { 500 if ticketMap := buildPBticketMap(ps.t_storage.Infos); len(ticketMap) != 0 { 501 tickTemp.Infos = ticketMap 502 empty |= 1 503 } 504 wg.Done() 505 }()*/ 506 507 //// ExpireTicket 508 //go func() { 509 // if ets := buildPBexpireTicket(ps.t_storage.Ets); len(ets) != 0 { 510 // tickTemp.Ets = ets 511 // empty |= 1 512 // } 513 // wg.Done() 514 //}() 515 516 // ticket's attachment of node 517 //go func() { 518 if dependency := buildPBdependencys(ps.t_storage.Dependencys); len(dependency) != 0 { 519 tickTemp.Dependencys = dependency 520 empty |= 1 521 } 522 //wg.Done() 523 //}() 524 525 //wg.Wait() 526 ppos_temp.TickTmp = tickTemp 527 } 528 529 if empty == 0 { 530 return nil 531 } 532 return ppos_temp 533 } 534 535 536 func unmarshalPBStorage(pb_temp *PB_PPosTemp) *Ppos_storage { 537 538 ppos_storage := new(Ppos_storage) 539 540 /** 541 candidate related 542 */ 543 canGlobalTemp := pb_temp.CanTmp 544 if nil != canGlobalTemp { 545 546 canTemp := new(candidate_temp) 547 548 buildQueueFunc := func(arr []*CandidateInfo) types.CandidateQueue { 549 if len(arr) == 0 { 550 return nil 551 } 552 queue := make(types.CandidateQueue, len(arr)) 553 for i, can := range arr { 554 deposit, _ := new(big.Int).SetString(can.Deposit, 10) 555 num, _ := new(big.Int).SetString(can.BlockNumber, 10) 556 canInfo := &types.Candidate{ 557 Deposit: deposit, 558 BlockNumber: num, 559 TxIndex: can.TxIndex, 560 CandidateId: discover.MustHexID(can.CandidateId), 561 Host: can.Host, 562 Port: can.Port, 563 Owner: common.HexToAddress(can.Owner), 564 Extra: can.Extra, 565 Fee: can.Fee, 566 TxHash: common.HexToHash(can.TxHash), 567 TOwner: common.HexToAddress(can.TOwner), 568 } 569 queue[i] = canInfo 570 } 571 return queue 572 } 573 574 // previous witness 575 canTemp.pres = buildQueueFunc(canGlobalTemp.Pres) 576 // current witness 577 canTemp.currs = buildQueueFunc(canGlobalTemp.Currs) 578 // next witness 579 canTemp.nexts = buildQueueFunc(canGlobalTemp.Nexts) 580 // immediate 581 canTemp.imms = buildQueueFunc(canGlobalTemp.Imms) 582 // reserve 583 canTemp.res = buildQueueFunc(canGlobalTemp.Res) 584 // refund 585 /*if len(canGlobalTemp.Refunds) != 0 { 586 587 588 }*/ 589 590 591 592 defeatMap := make(refundStorage, len(canGlobalTemp.Refunds)) 593 594 for nodeId, refundArr := range canGlobalTemp.Refunds { 595 596 if len(refundArr.Defeats) == 0 { 597 continue 598 } 599 600 defeatArr := make(types.RefundQueue, len(refundArr.Defeats)) 601 for i, defeat := range refundArr.Defeats { 602 603 deposit, _ := new(big.Int).SetString(defeat.Deposit, 10) 604 num, _ := new(big.Int).SetString(defeat.BlockNumber, 10) 605 606 refund := &types.CandidateRefund{ 607 Deposit: deposit, 608 BlockNumber: num, 609 Owner: common.HexToAddress(defeat.Owner), 610 } 611 defeatArr[i] = refund 612 } 613 defeatMap[discover.MustHexID(nodeId)] = defeatArr 614 } 615 616 canTemp.refunds = defeatMap 617 ppos_storage.c_storage = canTemp 618 } 619 620 621 /** 622 ticket related 623 */ 624 tickGlobalTemp := pb_temp.TickTmp 625 if nil != tickGlobalTemp { 626 627 tickTemp := new(ticket_temp) 628 629 // SQ 630 tickTemp.Sq = tickGlobalTemp.Sq 631 632 // ticketInfo map 633 /*if len(tickGlobalTemp.Infos) != 0 { 634 635 infoMap := make(map[common.Hash]*types.Ticket, len(tickGlobalTemp.Infos)) 636 for tid, tinfo := range tickGlobalTemp.Infos { 637 deposit, _ := new(big.Int).SetString(tinfo.Deposit, 10) 638 num, _ := new(big.Int).SetString(tinfo.BlockNumber, 10) 639 ticketInfo := &types.Ticket{ 640 Owner: common.BytesToAddress(tinfo.Owner), 641 Deposit: deposit, 642 CandidateId: discover.MustBytesID(tinfo.CandidateId), 643 BlockNumber: num, 644 Remaining: tinfo.Remaining, 645 } 646 647 infoMap[common.HexToHash(tid)] = ticketInfo 648 } 649 tickTemp.Infos = infoMap 650 }*/ 651 652 653 //// ExpireTicket map 654 //if len(tickGlobalTemp.Ets) != 0 { 655 // ets := make(map[string][]common.Hash, len(tickGlobalTemp.Ets)) 656 // 657 // for blockNum, ticketIdArr := range tickGlobalTemp.Ets { 658 // 659 // if len(ticketIdArr.TxHashs) == 0 { 660 // continue 661 // } 662 // 663 // ticketIds := make([]common.Hash, len(ticketIdArr.TxHashs)) 664 // for i, ticketId := range ticketIdArr.TxHashs { 665 // ticketIds[i] = common.BytesToHash(ticketId) 666 // } 667 // ets[blockNum] = ticketIds 668 // } 669 // 670 // tickTemp.Ets = ets 671 //} 672 673 // ticket's attachment of node 674 /*if len(tickGlobalTemp.Dependencys) != 0 { 675 676 677 }*/ 678 679 680 681 dependencyMap := make(map[discover.NodeID]*ticketDependency, len(tickGlobalTemp.Dependencys)) 682 683 for nodeIdStr, pb_dependency := range tickGlobalTemp.Dependencys { 684 685 dependencyInfo := new(ticketDependency) 686 //dependencyInfo.Age = pb_dependency.Age 687 dependencyInfo.Num = pb_dependency.Num 688 689 690 /*tidArr := make([]common.Hash, len(pb_dependency.Tids)) 691 692 for i, ticketId := range pb_dependency.Tids { 693 tidArr[i] = common.BytesToHash(ticketId) 694 } 695 696 dependencyInfo.Tids = tidArr*/ 697 698 699 700 fieldArr := make([]*ticketInfo, len(pb_dependency.Tinfo)) 701 for j, field := range pb_dependency.Tinfo { 702 703 price, _ := new(big.Int).SetString(field.Price, 10) 704 f := &ticketInfo{ 705 TxHash: common.HexToHash(field.TxHash), 706 Remaining: field.Remaining, 707 Price: price, 708 } 709 710 fieldArr[j] = f 711 } 712 dependencyInfo.Tinfo = fieldArr 713 714 dependencyMap[discover.MustHexID(nodeIdStr)] = dependencyInfo 715 } 716 717 tickTemp.Dependencys = dependencyMap 718 ppos_storage.t_storage = tickTemp 719 } 720 721 return ppos_storage 722 } 723 724 func buildPBcanqueue (title string, canQqueue types.CandidateQueue) []*CandidateInfo { 725 726 PrintObject(title + " ,buildPBcanqueue:", canQqueue) 727 728 pbQueue := make([]*CandidateInfo, len(canQqueue)) 729 if len(canQqueue) == 0 { 730 return pbQueue 731 } 732 733 for i, can := range canQqueue { 734 canInfo := &CandidateInfo{ 735 Deposit: can.Deposit.String(), 736 BlockNumber: can.BlockNumber.String(), 737 TxIndex: can.TxIndex, 738 CandidateId: can.CandidateId.String(), 739 Host: can.Host, 740 Port: can.Port, 741 Owner: can.Owner.String(), 742 Extra: can.Extra, 743 Fee: can.Fee, 744 TxHash: can.TxHash.String(), 745 TOwner: can.TOwner.String(), 746 } 747 pbQueue[i] = canInfo 748 } 749 return pbQueue 750 } 751 752 753 func buildPBrefunds(refunds refundStorage) map[string]*RefundArr { 754 755 PrintObject("buildPBrefunds", refunds) 756 757 if len(refunds) == 0 { 758 return nil 759 } 760 761 refundMap := make(map[string]*RefundArr, len(refunds)) 762 763 for nodeId, rs := range refunds { 764 765 if len(rs) == 0 { 766 continue 767 } 768 defeats := make([]*Refund, len(rs)) 769 for i, refund := range rs { 770 refundInfo := &Refund{ 771 Deposit: refund.Deposit.String(), 772 BlockNumber: refund.BlockNumber.String(), 773 Owner: refund.Owner.String(), 774 } 775 defeats[i] = refundInfo 776 } 777 778 refundArr := &RefundArr{ 779 Defeats: defeats, 780 } 781 refundMap[nodeId.String()] = refundArr 782 } 783 return refundMap 784 } 785 786 787 //func buildPBticketMap(tickets map[common.Hash]*types.Ticket) map[string]*TicketInfo { 788 // if len(tickets) == 0 { 789 // return nil 790 // } 791 // 792 // pb_ticketMap := make(map[string]*TicketInfo, len(tickets)) 793 // 794 // for tid, tinfo := range tickets { 795 // ticketInfo := &TicketInfo{ 796 // Owner: tinfo.Owner.Bytes(), 797 // Deposit: tinfo.Deposit.String(), 798 // CandidateId: tinfo.CandidateId.Bytes(), 799 // BlockNumber: tinfo.BlockNumber.String(), 800 // Remaining: tinfo.Remaining, 801 // } 802 // pb_ticketMap[tid.String()] = ticketInfo 803 // } 804 // return pb_ticketMap 805 //} 806 807 808 //func buildPBexpireTicket(ets map[string][]common.Hash) map[string]*TxHashArr { 809 // if len(ets) == 0 { 810 // return nil 811 // } 812 // 813 // pb_ets := make(map[string]*TxHashArr, len(ets)) 814 // 815 // for blockNumber, ticketIdArr := range ets { 816 // 817 // if len(ticketIdArr) == 0 { 818 // continue 819 // } 820 // 821 // txHashs := make([][]byte, len(ticketIdArr)) 822 // 823 // for i, tid := range ticketIdArr { 824 // txHashs[i] = tid.Bytes() 825 // } 826 // 827 // txHashArr := new(TxHashArr) 828 // txHashArr.TxHashs = txHashs 829 // pb_ets[blockNumber] = txHashArr 830 // } 831 // return pb_ets 832 //} 833 834 835 func buildPBdependencys(dependencys map[discover.NodeID]*ticketDependency) map[string]*TicketDependency { 836 if len(dependencys) == 0 { 837 return nil 838 } 839 840 pb_dependency := make(map[string]*TicketDependency, len(dependencys)) 841 842 for nodeId, dependency := range dependencys { 843 844 /*tidArr := make([][]byte, len(dependency.Tids)) 845 846 for i, ticketId := range dependency.Tids { 847 tidArr[i] = ticketId.Bytes() 848 }*/ 849 850 851 if dependency.Num == 0 && len(dependency.Tinfo) == 0 { 852 continue 853 } 854 855 fieldArr := make([]*Field, len(dependency.Tinfo)) 856 857 858 for i, field := range dependency.Tinfo { 859 860 f := &Field{ 861 TxHash: field.TxHash.String(), 862 Remaining: field.Remaining, 863 Price: field.Price.String(), 864 } 865 fieldArr[i] = f 866 } 867 868 depenInfo := &TicketDependency{ 869 //Age: dependency.Age, 870 Num: dependency.Num, 871 //Tids: tidArr, 872 Tinfo: fieldArr, 873 } 874 875 pb_dependency[nodeId.String()] = depenInfo 876 } 877 return pb_dependency 878 } 879 880 func (temp *PPOS_TEMP) deleteAnyTemp (blockNumber, blockInterval *big.Int, blockHash common.Hash) { 881 882 // delete font any data 883 if big.NewInt(0).Cmp(blockInterval) > 0 { 884 log.Error("WARN WARN WARN !!! Call SubmitPposCache2Temp of PPOS_TEMP FINISH !!!!!! blockInterval is NEGATIVE NUMBER", "blockNumber", blockNumber.String(), 885 "blockHash", blockHash.Hex(), "blockInterval", blockInterval, "After SubmitPposCache2Temp, THEN PPOS_TEMP len ", len(temp.TempMap), "Block Count", temp.BlockCount) 886 return 887 } 888 889 // blockInterval is the difference of block height between 890 // the highest block in memory and the highest block in the chain 891 interval := new(big.Int).Add(blockInterval, big.NewInt(30)) 892 893 // del old cache 894 // blocknumber: current memory block 895 target := new(big.Int).Sub(blockNumber, interval) 896 for number := range temp.TempMap { 897 if currentNum, ok := new(big.Int).SetString(number, 0); ok { 898 if currentNum.Cmp(target) < 0 { 899 900 hashMap, ok := temp.TempMap[currentNum.String()] 901 902 // delete current number related ppos data 903 delete(temp.TempMap, number) 904 // decr block count 905 if ok { 906 temp.BlockCount -= uint32(len(hashMap)) 907 } 908 } 909 } 910 } 911 log.Debug("Call SubmitPposCache2Temp of PPOS_TEMP FINISH !!!!!!", "blockNumber", blockNumber.String(), "blockHash", blockHash.Hex(), 912 "blockInterval", blockInterval, "After SubmitPposCache2Temp, THEN PPOS_TEMP len ", len(temp.TempMap), "Block Count", temp.BlockCount) 913 914 } 915 916 func verifyStorageEmpty(storage *Ppos_storage) bool { 917 if nil == storage.c_storage && nil == storage.t_storage { 918 return true 919 } 920 921 var canEmpty, tickEmpty bool 922 923 canStorage := storage.c_storage 924 if nil != canStorage { 925 if len(canStorage.pres) == 0 && len(canStorage.currs) == 0 && len(canStorage.nexts) == 0 && 926 len(canStorage.imms) == 0 && len(canStorage.res) == 0 && len(canStorage.refunds) == 0 { 927 canEmpty = true 928 } 929 } 930 931 tickStorage := storage.t_storage 932 if nil != tickStorage { 933 if tickStorage.Sq == -1 && /*len(tickStorage.Infos) == 0 && 934 len(tickStorage.Ets) == 0 &&*/ len(tickStorage.Dependencys) == 0 { 935 tickEmpty = true 936 } 937 } 938 if canEmpty && tickEmpty { 939 return true 940 } 941 return false 942 } 943 944 945 946 func PrintObject(s string, obj interface{}) { 947 objs, _ := json.Marshal(obj) 948 log.Debug(s, "==", string(objs)) 949 }