github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/core/ppos_storage/ppos_storageCache.go (about)

     1  package ppos_storage
     2  
     3  import (
     4  	"github.com/PlatONnetwork/PlatON-Go/common"
     5  	"github.com/PlatONnetwork/PlatON-Go/core/types"
     6  	"github.com/PlatONnetwork/PlatON-Go/p2p/discover"
     7  	"github.com/PlatONnetwork/PlatON-Go/crypto"
     8  	"github.com/PlatONnetwork/PlatON-Go/log"
     9  	"github.com/golang/protobuf/proto"
    10  	"math/big"
    11  	"errors"
    12  	"fmt"
    13  	"sort"
    14  	"sync"
    15  	"crypto/md5"
    16  )
    17  
    18  const (
    19  	PREVIOUS = iota
    20  	CURRENT
    21  	NEXT
    22  	IMMEDIATE
    23  	RESERVE
    24  )
    25  
    26  var (
    27  	ParamsIllegalErr 			= errors.New("Params illegal")
    28  	TicketNotFindErr        	= errors.New("The Ticket not find")
    29  )
    30  
    31  var ticketCache = sync.Map{}
    32  
    33  func PutTicket(txHash common.Hash, ticket *types.Ticket) {
    34  	ticketCache.Store(txHash, ticket)
    35  }
    36  
    37  func GetTicket(txHash common.Hash) *types.Ticket {
    38  	if value, ok := ticketCache.Load(txHash); ok {
    39  		return value.(*types.Ticket)
    40  	}
    41  	return nil
    42  }
    43  
    44  func RemoveTicket(txHash common.Hash) {
    45  	ticketCache.Delete(txHash)
    46  }
    47  
    48  type refundStorage map[discover.NodeID]types.RefundQueue
    49  
    50  type candidate_temp struct {
    51  	// previous witness
    52  	pres types.CandidateQueue
    53  	// current witness
    54  	currs types.CandidateQueue
    55  	// next witness
    56  	nexts types.CandidateQueue
    57  	//immediate
    58  	imms types.CandidateQueue
    59  	// reserve
    60  	res types.CandidateQueue
    61  	// refund
    62  	refunds refundStorage
    63  }
    64  
    65  type ticketDependency struct {
    66  	// ticket age
    67  	//Age uint64
    68  	// ticket count
    69  	Num uint32
    70  	// ticketIds
    71  	Tinfo []*ticketInfo
    72  }
    73  
    74  type ticketInfo struct {
    75  	TxHash			common.Hash
    76  	// The number of remaining tickets
    77  	Remaining		uint32
    78  	Price 			*big.Int
    79  }
    80  
    81  func (t *ticketInfo) SubRemaining() {
    82  	if t.Remaining > 0 {
    83  		t.Remaining--
    84  	}
    85  }
    86  
    87  //func (td *ticketDependency) AddAge(number uint64) {
    88  //	if number > 0 {
    89  //		td.Age += number
    90  //	}
    91  //}
    92  //
    93  //func (td *ticketDependency) SubAge(number uint64) {
    94  //	if number > 0 && td.Age >= number {
    95  //		td.Age -= number
    96  //	}
    97  //}
    98  
    99  func (td *ticketDependency) subNum() {
   100  	if td.Num > 0 {
   101  		td.Num--
   102  	}
   103  }
   104  
   105  type ticket_temp struct {
   106  	// total remian  k-v
   107  	Sq int32
   108  	// ticketInfo  map[txHash]ticketInfo
   109  	//Infos map[common.Hash]*types.Ticket
   110  	// ExpireTicket  map[blockNumber]txHash
   111  	//Ets map[string][]common.Hash
   112  	// ticket's attachment  of node
   113  	Dependencys map[discover.NodeID]*ticketDependency
   114  }
   115  
   116  type Ppos_storage struct {
   117  	c_storage *candidate_temp
   118  	t_storage *ticket_temp
   119  }
   120  
   121  func (ps *Ppos_storage) Copy() *Ppos_storage {
   122  
   123  	//if  verifyStorageEmpty(ps) {
   124  	//	return NewPPOS_storage()
   125  	//}
   126  
   127  	if nil == ps {
   128  		return NewPPOS_storage()
   129  	}
   130  
   131  	ppos_storage := &Ppos_storage{
   132  		c_storage: ps.CopyCandidateStorage(),
   133  		t_storage: ps.CopyTicketStorage(),
   134  	}
   135  	return ppos_storage
   136  }
   137  
   138  
   139  func NewPPOS_storage () *Ppos_storage {
   140  
   141  	cache := &Ppos_storage{
   142  		c_storage: &candidate_temp{
   143  			pres: 	make(types.CandidateQueue, 0),
   144  			currs:  make(types.CandidateQueue, 0),
   145  			nexts: 	make(types.CandidateQueue, 0),
   146  			imms: 	make(types.CandidateQueue, 0),
   147  			res: 	make(types.CandidateQueue, 0),
   148  			refunds: make(refundStorage, 0),
   149  		},
   150  
   151  		t_storage: &ticket_temp{
   152  			Sq: 	-1,
   153  			Dependencys: 	make(map[discover.NodeID]*ticketDependency),
   154  		},
   155  	}
   156  
   157  	/*cache := new(Ppos_storage)
   158  
   159  	c := new(candidate_temp)
   160  	t:= new(ticket_temp)
   161  
   162  	c.pres = make(types.CandidateQueue, 0)
   163  	c.currs = make(types.CandidateQueue, 0)
   164  	c.nexts = make(types.CandidateQueue, 0)
   165  
   166  	c.imms = make(types.CandidateQueue, 0)
   167  	c.res = make(types.CandidateQueue, 0)
   168  
   169  	c.refunds = make(refundStorage, 0)
   170  
   171  	t.Sq = -1
   172  	t.Dependencys = make(map[discover.NodeID]*ticketDependency)
   173  
   174  	cache.c_storage = c
   175  	cache.t_storage = t*/
   176  
   177  
   178  	return cache
   179  }
   180  
   181  /** candidate related func */
   182  
   183  //func (p *Ppos_storage) CopyCandidateStorage ()  *candidate_temp {
   184  //	start := common.NewTimer()
   185  //	start.Begin()
   186  //
   187  //	temp := new(candidate_temp)
   188  //
   189  //	type result struct {
   190  //		Status int
   191  //		Data   interface{}
   192  //	}
   193  //	var wg sync.WaitGroup
   194  //	wg.Add(6)
   195  //	resCh := make(chan *result, 6)
   196  //
   197  //	loadQueueFunc := func(flag int) {
   198  //		res := new(result)
   199  //		switch flag {
   200  //		case PREVIOUS:
   201  //			res.Status = PREVIOUS
   202  //			res.Data = p.c_storage.pres.DeepCopy()
   203  //			resCh <- res
   204  //		case CURRENT:
   205  //			res.Status = CURRENT
   206  //			res.Data = p.c_storage.currs.DeepCopy()
   207  //			resCh <- res
   208  //		case NEXT:
   209  //			res.Status = NEXT
   210  //			res.Data = p.c_storage.nexts.DeepCopy()
   211  //			resCh <- res
   212  //		case IMMEDIATE:
   213  //			res.Status = IMMEDIATE
   214  //			res.Data = p.c_storage.imms.DeepCopy()
   215  //			resCh <- res
   216  //		case RESERVE:
   217  //			res.Status = RESERVE
   218  //			res.Data = p.c_storage.res.DeepCopy()
   219  //			resCh <- res
   220  //		}
   221  //		wg.Done()
   222  //	}
   223  //
   224  //	go loadQueueFunc(PREVIOUS)
   225  //	go loadQueueFunc(CURRENT)
   226  //	go loadQueueFunc(NEXT)
   227  //	go loadQueueFunc(IMMEDIATE)
   228  //	go loadQueueFunc(RESERVE)
   229  //
   230  //	go func() {
   231  //		res := new(result)
   232  //		cache := make(refundStorage, len(p.c_storage.refunds))
   233  //		for nodeId, queue := range p.c_storage.refunds {
   234  //			cache[nodeId] = queue.DeepCopy()
   235  //		}
   236  //		res.Status = REFUND
   237  //		res.Data = cache
   238  //		resCh <- res
   239  //		wg.Done()
   240  //	}()
   241  //	wg.Wait()
   242  //	close(resCh)
   243  //	for res := range resCh {
   244  //		switch res.Status {
   245  //		case PREVIOUS:
   246  //			temp.pres = res.Data.(types.CandidateQueue)
   247  //		case CURRENT:
   248  //			temp.currs = res.Data.(types.CandidateQueue)
   249  //		case NEXT:
   250  //			temp.nexts = res.Data.(types.CandidateQueue)
   251  //		case IMMEDIATE:
   252  //			temp.imms = res.Data.(types.CandidateQueue)
   253  //		case RESERVE:
   254  //			temp.res = res.Data.(types.CandidateQueue)
   255  //		case REFUND:
   256  //			temp.refunds = res.Data.(refundStorage)
   257  //		}
   258  //	}
   259  //	log.Debug("CopyCandidateStorage", "Time spent", fmt.Sprintf("%v ms", start.End()))
   260  //	return temp
   261  //}
   262  
   263  func (p *Ppos_storage) CopyCandidateStorage ()  *candidate_temp {
   264  	start := common.NewTimer()
   265  	start.Begin()
   266  
   267  	cache := make(refundStorage, len(p.c_storage.refunds))
   268  	for nodeId, queue := range p.c_storage.refunds {
   269  		cache[nodeId] = queue.DeepCopy()
   270  	}
   271  
   272  	temp := &candidate_temp{
   273  		pres: 		p.c_storage.pres.DeepCopy(),
   274  		currs: 		p.c_storage.currs.DeepCopy(),
   275  		nexts: 		p.c_storage.nexts.DeepCopy(),
   276  
   277  		imms: 		p.c_storage.imms.DeepCopy(),
   278  		res: 		p.c_storage.res.DeepCopy(),
   279  
   280  		refunds: 	cache,
   281  	}
   282  
   283  	/*temp := new(candidate_temp)
   284  
   285  	temp.pres = p.c_storage.pres.DeepCopy()
   286  	temp.currs = p.c_storage.currs.DeepCopy()
   287  	temp.nexts = p.c_storage.nexts.DeepCopy()
   288  
   289  	temp.imms = p.c_storage.imms.DeepCopy()
   290  	temp.res = p.c_storage.res.DeepCopy()
   291  
   292  	temp.refunds = cache*/
   293  
   294  
   295  	log.Debug("CopyCandidateStorage", "Time spent", fmt.Sprintf("%v ms", start.End()))
   296  	return temp
   297  }
   298  
   299  func (p *Ppos_storage) CopyTicketStorage() *ticket_temp {
   300  
   301  	start := common.NewTimer()
   302  	start.Begin()
   303  
   304  	cache := make(map[discover.NodeID]*ticketDependency, len(p.t_storage.Dependencys))
   305  
   306  	for key := range p.t_storage.Dependencys {
   307  		temp := p.t_storage.Dependencys[key]
   308  		tinfos := make([]*ticketInfo, len(temp.Tinfo))
   309  
   310  		for j, tin := range temp.Tinfo {
   311  
   312  			t := &ticketInfo{
   313  				TxHash: 	tin.TxHash,
   314  				Remaining: 	tin.Remaining,
   315  				Price: 		tin.Price,
   316  			}
   317  			tinfos[j] = t
   318  
   319  		}
   320  
   321  		cache[key] = &ticketDependency{
   322  			temp.Num,
   323  			tinfos,
   324  		}
   325  	}
   326  
   327  	ticket_cache := &ticket_temp{
   328  		Sq: 	p.t_storage.Sq,
   329  		Dependencys: 	cache,
   330  	}
   331  
   332  
   333  	/*ticket_cache := new(ticket_temp)
   334  
   335  	ticket_cache.Sq = p.t_storage.Sq
   336  	//ticket_cache.Infos = make(map[common.Hash]*types.Ticket)
   337  	//ticket_cache.Ets = make(map[string][]common.Hash)
   338  	ticket_cache.Dependencys = make(map[discover.NodeID]*ticketDependency)
   339  
   340  	//for key := range p.t_storage.Infos {
   341  	//	ticket := p.t_storage.Infos[key]
   342  	//	ticket_cache.Infos[key] = ticket.DeepCopy()
   343  	//}
   344  	//for key := range p.t_storage.Ets {
   345  	//	value := p.t_storage.Ets[key]
   346  	//	list := make([]common.Hash, len(value))
   347  	//	copy(list, value)
   348  	//	ticket_cache.Ets[key] = list
   349  	//}
   350  	//for key := range p.t_storage.Dependencys {
   351  	//	temp := p.t_storage.Dependencys[key]
   352  	//	tids := make([]common.Hash, len(temp.Tids))
   353  	//	copy(tids, temp.Tids)
   354  	//	ticket_cache.Dependencys[key] = &ticketDependency{
   355  	//		//temp.Age,
   356  	//		temp.Num,
   357  	//		tids,
   358  	//	}
   359  	//}
   360  	for key := range p.t_storage.Dependencys {
   361  		temp := p.t_storage.Dependencys[key]
   362  
   363  		tinfos := make([]*ticketInfo, len(temp.Tinfo))
   364  
   365  		for j, tin := range temp.Tinfo {
   366  
   367  			t := &ticketInfo{
   368  				TxHash: 	tin.TxHash,
   369  				Remaining: 	tin.Remaining,
   370  				Price: 		tin.Price,
   371  			}
   372  			tinfos[j] = t
   373  
   374  		}
   375  		ticket_cache.Dependencys[key] = &ticketDependency{
   376  			//temp.Age,
   377  			temp.Num,
   378  			tinfos,
   379  		}
   380  	}*/
   381  
   382  
   383  	log.Debug("CopyTicketStorage", "Time spent", fmt.Sprintf("%v ms", start.End()))
   384  	return ticket_cache
   385  }
   386  
   387  // Get CandidateQueue
   388  // flag:
   389  // 0: previous witness
   390  // 1: current witness
   391  // 2: next witness
   392  // 3: immediate
   393  // 4: reserve
   394  func (p *Ppos_storage) GetCandidateQueue(flag int) types.CandidateQueue {
   395  	switch flag {
   396  	case PREVIOUS:
   397  		PrintObject("Pres queue", p.c_storage.pres)
   398  
   399  		queueCopy := make(types.CandidateQueue, len(p.c_storage.pres))
   400  		copy(queueCopy, p.c_storage.pres)
   401  
   402  		return queueCopy
   403  	case CURRENT:
   404  		PrintObject("Curr queue", p.c_storage.currs)
   405  
   406  		queueCopy := make(types.CandidateQueue, len(p.c_storage.currs))
   407  		copy(queueCopy, p.c_storage.currs)
   408  
   409  		return queueCopy
   410  	case NEXT:
   411  		PrintObject("Next queue", p.c_storage.nexts)
   412  
   413  		queueCopy := make(types.CandidateQueue, len(p.c_storage.nexts))
   414  		copy(queueCopy, p.c_storage.nexts)
   415  
   416  		return queueCopy
   417  	case IMMEDIATE:
   418  		PrintObject("Imms queue", p.c_storage.imms)
   419  
   420  		queueCopy := make(types.CandidateQueue, len(p.c_storage.imms))
   421  		copy(queueCopy, p.c_storage.imms)
   422  
   423  		return queueCopy
   424  	case RESERVE:
   425  		PrintObject("Res queue", p.c_storage.res)
   426  
   427  		queueCopy := make(types.CandidateQueue, len(p.c_storage.res))
   428  		copy(queueCopy, p.c_storage.res)
   429  
   430  		return queueCopy
   431  	default:
   432  		return nil
   433  	}
   434  }
   435  
   436  // Set CandidateQueue
   437  func (p *Ppos_storage) SetCandidateQueue(queue types.CandidateQueue, flag int) {
   438  	switch flag {
   439  	case PREVIOUS:
   440  		p.c_storage.pres = queue
   441  	case CURRENT:
   442  		p.c_storage.currs = queue
   443  	case NEXT:
   444  		p.c_storage.nexts = queue
   445  	case IMMEDIATE:
   446  		p.c_storage.imms = queue
   447  	case RESERVE:
   448  		p.c_storage.res = queue
   449  	}
   450  }
   451  
   452  // Delete CandidateQueue
   453  func (p *Ppos_storage) DelCandidateQueue(flag int)  {
   454  	switch flag {
   455  	case PREVIOUS:
   456  		p.c_storage.pres = make(types.CandidateQueue, 0)
   457  	case CURRENT:
   458  		p.c_storage.currs = make(types.CandidateQueue, 0)
   459  	case NEXT:
   460  		p.c_storage.nexts = make(types.CandidateQueue, 0)
   461  	case IMMEDIATE:
   462  		p.c_storage.imms = make(types.CandidateQueue, 0)
   463  	case RESERVE:
   464  		p.c_storage.res = make(types.CandidateQueue, 0)
   465  	}
   466  }
   467  
   468  // Get Refund
   469  func (p *Ppos_storage) GetRefunds(nodeId discover.NodeID) types.RefundQueue {
   470  	if queue, ok := p.c_storage.refunds[nodeId]; ok {
   471  		queueCopy := make(types.RefundQueue, len(queue))
   472  		copy(queueCopy, queue)
   473  		return queueCopy
   474  	} else {
   475  		return make(types.RefundQueue, 0)
   476  	}
   477  }
   478  
   479  
   480  
   481  // Set Refund
   482  func (p *Ppos_storage) SetRefund(nodeId discover.NodeID, refund *types.CandidateRefund) {
   483  
   484  	if queue, ok := p.c_storage.refunds[nodeId]; ok {
   485  		queue = append(queue, refund)
   486  		p.c_storage.refunds[nodeId] = queue
   487  	} else {
   488  		queue = make(types.RefundQueue, 0)
   489  		//queue[0] = refund
   490  		queue = append(queue, refund)
   491  		p.c_storage.refunds[nodeId] = queue
   492  	}
   493  }
   494  
   495  func (p *Ppos_storage) SetRefunds(nodeId discover.NodeID, refundArr types.RefundQueue) {
   496  	if len(refundArr) == 0 {
   497  		delete(p.c_storage.refunds, nodeId)
   498  		return
   499  	}
   500  	p.c_storage.refunds[nodeId] = refundArr
   501  }
   502  
   503  func (p *Ppos_storage) AppendRefunds(nodeId discover.NodeID, refundArr types.RefundQueue) {
   504  	if len(refundArr) == 0 {
   505  		return
   506  	}
   507  	if queue, ok := p.c_storage.refunds[nodeId]; ok {
   508  		queue = append(queue, refundArr ...)
   509  		p.c_storage.refunds[nodeId] = queue
   510  	} else {
   511  		p.c_storage.refunds[nodeId] = refundArr
   512  	}
   513  }
   514  
   515  // Delete RefundArr
   516  func (p *Ppos_storage) DelRefunds(nodeId discover.NodeID) {
   517  	delete(p.c_storage.refunds, nodeId)
   518  }
   519  
   520  /** ticket related func */
   521  
   522  // Get total remian
   523  func (p *Ppos_storage) GetTotalRemian() int32 {
   524  	return p.t_storage.Sq
   525  }
   526  
   527  // Set total remain
   528  func (p *Ppos_storage) SetTotalRemain(count int32) {
   529  	p.t_storage.Sq = count
   530  }
   531  
   532  // Get TicketInfo
   533  /*func (p *Ppos_storage) GetTicketInfo(txHash common.Hash) *types.Ticket {
   534  	ticket, ok := p.t_storage.Infos[txHash]
   535  	if ok {
   536  		return ticket
   537  	}
   538  	return nil
   539  }*/
   540  
   541  func (p *Ppos_storage) GetTicketInfo(txHash common.Hash) *ticketInfo {
   542  	for _, obj := range p.t_storage.Dependencys {
   543  		for index := range obj.Tinfo {
   544  			 tinfo := obj.Tinfo[index]
   545  			if tinfo.TxHash == txHash {
   546  				return tinfo
   547  			}
   548  		}
   549  	}
   550  	return nil
   551  }
   552  
   553  //Set TicketInfo
   554  //func (p *Ppos_storage) SetTicketInfo(txHash common.Hash, ) {
   555  //	p.t_storage.Infos[txHash] = ticket
   556  //}
   557  //
   558  //func (p *Ppos_storage) removeTicketInfo(txHash common.Hash) {
   559  //	delete(p.t_storage.Infos, txHash)
   560  //}
   561  
   562  //GetTiketArr
   563  //func (p *Ppos_storage) GetTicketArr(txHashs ...common.Hash) []*types.Ticket {
   564  //	tickets := make([]*types.Ticket, 0)
   565  //	if len(txHashs) > 0 {
   566  //		for index := range txHashs {
   567  //			if ticket := p.GetTicketInfo(txHashs[index]); ticket != nil {
   568  //				newTicket := *ticket
   569  //				tickets = append(tickets, &newTicket)
   570  //			}
   571  //		}
   572  //	}
   573  //	return tickets
   574  //}
   575  
   576  //Get ExpireTicket
   577  //func (p *Ppos_storage) GetExpireTicket(blockNumber *big.Int) []common.Hash {
   578  //	ids, ok := p.t_storage.Ets[blockNumber.String()]
   579  //	if ok {
   580  //		return ids
   581  //	}
   582  //	return nil
   583  //}
   584  //
   585  //// Set ExpireTicket
   586  //func (p *Ppos_storage) SetExpireTicket(blockNumber *big.Int, txHash common.Hash) {
   587  //	ids, ok := p.t_storage.Ets[blockNumber.String()]
   588  //	if !ok {
   589  //		ids = make([]common.Hash, 0)
   590  //	}
   591  //	ids = append(ids, txHash)
   592  //	p.t_storage.Ets[blockNumber.String()] = ids
   593  //}
   594  //
   595  //func (p *Ppos_storage) RemoveExpireTicket(blockNumber *big.Int, txHash common.Hash) {
   596  //	ids, ok := p.t_storage.Ets[blockNumber.String()]
   597  //	if ok {
   598  //		ids = removeTicketId(txHash, ids)
   599  //		if len(ids) == 0 {
   600  //			delete(p.t_storage.Ets, blockNumber.String())
   601  //		} else {
   602  //			p.t_storage.Ets[blockNumber.String()] = ids
   603  //		}
   604  //	}
   605  //}
   606  
   607  //Get ticket dependency
   608  func (p *Ppos_storage) GetTicketDependency(nodeId discover.NodeID) *ticketDependency {
   609  	value, ok := p.t_storage.Dependencys[nodeId]
   610  	if ok {
   611  		return value
   612  	}
   613  	return nil
   614  }
   615  
   616  // Set ticket dependency
   617  func (p *Ppos_storage) SetTicketDependency(nodeId discover.NodeID, ependency *ticketDependency) {
   618  	p.t_storage.Dependencys[nodeId] = ependency
   619  }
   620  
   621  func (p *Ppos_storage) RemoveTicketDependency(nodeId discover.NodeID) {
   622  	delete(p.t_storage.Dependencys, nodeId)
   623  }
   624  
   625  /*func (p *Ppos_storage) GetCandidateTxHashs(nodeId discover.NodeID) []common.Hash {
   626  	value, ok := p.t_storage.Dependencys[nodeId]
   627  	if ok {
   628  		return value.Tids
   629  	}
   630  	return nil
   631  }*/
   632  
   633  func (p *Ppos_storage) GetCandidateTxHashs(nodeId discover.NodeID) []common.Hash {
   634  	value, ok := p.t_storage.Dependencys[nodeId]
   635  	if ok {
   636  		tids := make([]common.Hash, 0)
   637  		for index := range value.Tinfo {
   638  			tids = append(tids, value.Tinfo[index].TxHash)
   639  		}
   640  		return tids
   641  	}
   642  	return nil
   643  }
   644  
   645  /*func (p *Ppos_storage) AppendTicket(nodeId discover.NodeID, txHash common.Hash, ticket *types.Ticket) error {
   646  	p.SetTicketInfo(txHash, ticket)
   647  	value := p.GetTicketDependency(nodeId)
   648  	if nil == value {
   649  		value = new(ticketDependency)
   650  		value.Tids = make([]common.Hash, 0)
   651  	}
   652  	value.Num += ticket.Remaining
   653  	value.Tids = append(value.Tids, txHash)
   654  	p.SetTicketDependency(nodeId, value)
   655  	return nil
   656  }*/
   657  
   658  func (p *Ppos_storage) AppendTicket(nodeId discover.NodeID, txHash common.Hash, count uint32, price *big.Int) error {
   659  	value := p.GetTicketDependency(nodeId)
   660  	if nil == value {
   661  		value = new(ticketDependency)
   662  		value.Tinfo = make([]*ticketInfo, 0)
   663  	}
   664  	value.Num += count
   665  	tinfo := &ticketInfo{
   666  		txHash,
   667  		count,
   668  		price,
   669  	}
   670  	value.Tinfo = append(value.Tinfo, tinfo)
   671  	p.SetTicketDependency(nodeId, value)
   672  	return nil
   673  }
   674  
   675  
   676  /*func (p *Ppos_storage) SubTicket(nodeId discover.NodeID, txHash common.Hash) error {
   677  	value := p.GetTicketDependency(nodeId)
   678  	if nil != value {
   679  		ticket := p.GetTicketInfo(txHash)
   680  		if ticket == nil {
   681  			return TicketNotFindErr
   682  		}
   683  		ticket.SubRemaining()
   684  		value.subNum()
   685  		if ticket.Remaining == 0 {
   686  			p.removeTicketInfo(txHash)
   687  			if list := removeTicketId(txHash, value.Tids); len(list) > 0 {
   688  				value.Tids = list
   689  			} else {
   690  				value.Tids = make([]common.Hash, 0)
   691  			}
   692  		} else {
   693  			p.SetTicketInfo(txHash, ticket)
   694  		}
   695  	}
   696  	return nil
   697  }*/
   698  
   699  func (p *Ppos_storage) SubTicket(nodeId discover.NodeID, txHash common.Hash) (*ticketInfo, error) {
   700  	value := p.GetTicketDependency(nodeId)
   701  	if nil != value {
   702  		ticket := p.GetTicketInfo(txHash)
   703  		if ticket == nil {
   704  			return nil, TicketNotFindErr
   705  		}
   706  		ticket.SubRemaining()
   707  		value.subNum()
   708  		if ticket.Remaining == 0 {
   709  			if list := removeTinfo(txHash, value.Tinfo); len(list) > 0 {
   710  				value.Tinfo = list
   711  			} else {
   712  				value.Tinfo = make([]*ticketInfo, 0)
   713  			}
   714  		}
   715  		return ticket, nil
   716  	}
   717  	return nil, nil
   718  }
   719  
   720  /*func (p *Ppos_storage) RemoveTicket(nodeId discover.NodeID, txHash common.Hash) error {
   721  	ticket := p.GetTicketInfo(txHash)
   722  	if ticket == nil {
   723  		return TicketNotFindErr
   724  	}
   725  	value := p.GetTicketDependency(nodeId)
   726  	if nil != value {
   727  		value.Num -= ticket.Remaining
   728  		if list := removeTicketId(txHash, value.Tids); len(list) > 0 {
   729  			value.Tids = list
   730  		} else {
   731  			value.Tids = make([]common.Hash, 0)
   732  		}
   733  	}
   734  	p.removeTicketInfo(txHash)
   735  	return nil
   736  }*/
   737  
   738  func (p *Ppos_storage) RemoveTicket(nodeId discover.NodeID, txHash common.Hash) (*ticketInfo, error) {
   739  	ticket := p.GetTicketInfo(txHash)
   740  	if ticket == nil {
   741  		return nil, TicketNotFindErr
   742  	}
   743  	value := p.GetTicketDependency(nodeId)
   744  	if nil != value {
   745  		value.Num -= ticket.Remaining
   746  		if list := removeTinfo(txHash, value.Tinfo); len(list) > 0 {
   747  			value.Tinfo = list
   748  		} else {
   749  			value.Tinfo = make([]*ticketInfo, 0)
   750  		}
   751  		if value.Num == 0 {
   752  			p.RemoveTicketDependency(nodeId)
   753  		}
   754  	}
   755  	return ticket, nil
   756  }
   757  
   758  func (p *Ppos_storage) GetCandidateTicketCount(nodeId discover.NodeID) uint32 {
   759  	if value := p.GetTicketDependency(nodeId); value != nil {
   760  		log.Debug("Gets the ticket count of node", "nodeId", nodeId.String(), "tcount", value.Num)
   761  		return value.Num
   762  	}
   763  	log.Debug("Gets the ticket count of node", "nodeId", nodeId.String(), "tcount", 0)
   764  	return 0
   765  }
   766  
   767  func (p *Ppos_storage) GetCandidateTicketAge(nodeId discover.NodeID) uint64 {
   768  	/*if value := p.GetTicketDependency(nodeId); value != nil {
   769  		return value.Age
   770  	}*/
   771  	return 0
   772  }
   773  
   774  func (p *Ppos_storage) SetCandidateTicketAge(nodeId discover.NodeID, age uint64) {
   775  	/*if value := p.GetTicketDependency(nodeId); value != nil {
   776  		value.Age = age
   777  	}*/
   778  }
   779  
   780  func (p *Ppos_storage) GetTicketRemainByTxHash(txHash common.Hash) uint32 {
   781  	//PrintObject("Call GetTicketRemainByTxHash", p.t_storage.Dependencys)
   782  	//log.Debug("Call GetTicketRemainByTxHash", "ticketId", txHash.Hex())
   783  	for _, depen := range p.t_storage.Dependencys {
   784  		for _, field := range depen.Tinfo {
   785  			if txHash == field.TxHash {
   786  				return field.Remaining
   787  			}
   788  		}
   789  	}
   790  	return 0
   791  }
   792  
   793  
   794  func removeTicketId(hash common.Hash, hashs []common.Hash) []common.Hash {
   795  	for index, tempHash := range hashs {
   796  		if tempHash == hash {
   797  			if len(hashs) == 1 {
   798  				return nil
   799  			}
   800  			start := hashs[:index]
   801  			end := hashs[index+1:]
   802  			return append(start, end...)
   803  		}
   804  	}
   805  	return hashs
   806  }
   807  
   808  func removeTinfo(hash common.Hash, tinfos []*ticketInfo) []*ticketInfo {
   809  	for index, info := range tinfos {
   810  		if info.TxHash == hash {
   811  			if len(tinfos) == 1 {
   812  				return nil
   813  			}
   814  			start := tinfos[:index]
   815  			end := tinfos[index+1:]
   816  			return append(start, end...)
   817  		}
   818  	}
   819  	return tinfos
   820  }
   821  
   822  
   823  func (p *Ppos_storage) CalculateHash(blockNumber *big.Int, blockHash common.Hash) (common.Hash, error) {
   824  	log.Debug("Call CalculateHash start ...", "blockNumber", blockNumber, "blockHash", blockHash.Hex())
   825  	start := common.NewTimer()
   826  	start.Begin()
   827  
   828  	if verifyStorageEmpty(p) {
   829  		return common.Hash{}, nil
   830  	}
   831  
   832  	// declare can refund func
   833  	RefundIdQueueFunc := func(refundMap refundStorage) ([]string, []*RefundArr) {
   834  
   835  		PrintObject("RefundIdQueueFunc, Refunds", refundMap)
   836  
   837  		if len(refundMap) == 0 {
   838  			return nil, nil
   839  		}
   840  
   841  		nodeIdStrArr := make([]string, len(refundMap))
   842  
   843  		tempMap := make(map[string]discover.NodeID, len(refundMap))
   844  
   845  		var i int = 0
   846  
   847  		for nodeId := range refundMap {
   848  
   849  			nodeIdStr := nodeId.String()
   850  
   851  			nodeIdStrArr[i]= nodeIdStr
   852  
   853  			tempMap[nodeIdStr] = nodeId
   854  			
   855  			i ++
   856  		}
   857  
   858  		sort.Strings(nodeIdStrArr)
   859  
   860  		refundArrQueue := make([]*RefundArr, 0)
   861  
   862  		for _, nodeIdStr := range nodeIdStrArr {
   863  
   864  			nodeId := tempMap[nodeIdStr]
   865  
   866  			rs := refundMap[nodeId]
   867  
   868  			if len(rs) == 0 {
   869  				continue
   870  			}
   871  			defeats := make([]*Refund, len(rs))
   872  			for i, refund := range rs {
   873  				refundInfo := &Refund{
   874  					Deposit:     	refund.Deposit.String(),
   875  					BlockNumber:	refund.BlockNumber.String(),
   876  					Owner:			refund.Owner.String(),
   877  				}
   878  				defeats[i] = refundInfo
   879  			}
   880  
   881  			refundArr := &RefundArr{
   882  				Defeats: defeats,
   883  			}
   884  
   885  			refundArrQueue = append(refundArrQueue, refundArr)
   886  		}
   887  		return nodeIdStrArr, refundArrQueue
   888  	}
   889  
   890  	// declare can dependency func
   891  	DependencyFunc := func(dependencys map[discover.NodeID]*ticketDependency) ([]string, []*TicketDependency) {
   892  
   893  		PrintObject("DependencyFunc, dependencys", dependencys)
   894  
   895  		if len(dependencys) == 0 {
   896  			return nil, nil
   897  		}
   898  
   899  		nodeIdStrArr := make([]string, len(dependencys))
   900  
   901  		tempMap := make(map[string]discover.NodeID, len(dependencys))
   902  
   903  
   904  		var i int = 0
   905  		for nodeId := range dependencys {
   906  
   907  
   908  			nodeIdStr := nodeId.String()
   909  
   910  			nodeIdStrArr[i] = nodeIdStr
   911  
   912  			tempMap[nodeIdStr] = nodeId
   913  
   914  			i++
   915  		}
   916  
   917  		sort.Strings(nodeIdStrArr)
   918  
   919  		dependencyArr := make([]*TicketDependency, 0)
   920  
   921  
   922  		for _, nodeIdStr := range nodeIdStrArr {
   923  			nodeId := tempMap[nodeIdStr]
   924  
   925  
   926  			depen := dependencys[nodeId]
   927  
   928  			if depen.Num == 0 && len(depen.Tinfo) == 0 {
   929  				continue
   930  			}
   931  
   932  			fieldArr := make([]*Field, len(depen.Tinfo))
   933  
   934  
   935  			for i, field := range depen.Tinfo {
   936  
   937  				f := &Field{
   938  					TxHash:		field.TxHash.String(),
   939  					Remaining: 	field.Remaining,
   940  					Price: 		field.Price.String(),
   941  				}
   942  				fieldArr[i] = f
   943  			}
   944  
   945  			depenInfo := &TicketDependency{
   946  				//Age:  dependency.Age,
   947  				Num:  depen.Num,
   948  				//Tids: tidArr,
   949  				Tinfo: 	fieldArr,
   950  			}
   951  
   952  			dependencyArr = append(dependencyArr, depenInfo)
   953  
   954  		}
   955  
   956  		return nodeIdStrArr, dependencyArr
   957  	}
   958  
   959  
   960  	sortTemp := new(SortTemp)
   961  
   962  	var wg sync.WaitGroup
   963  	wg.Add(7)
   964  
   965  	resqueue := make([][]*CandidateInfo, 5)
   966  
   967  	/**
   968  	calculate can dependency Hash
   969  	*/
   970  	go func() {
   971  		resqueue[0] = buildPBcanqueue("DependencyFunc, pres", p.c_storage.pres)
   972  		wg.Done()
   973  	}()
   974  
   975  	go func() {
   976  		resqueue[1] = buildPBcanqueue("DependencyFunc, currs", p.c_storage.currs)
   977  		wg.Done()
   978  	}()
   979  
   980  	go func() {
   981  		resqueue[2] = buildPBcanqueue("DependencyFunc, nexts", p.c_storage.nexts)
   982  		wg.Done()
   983  	}()
   984  
   985  	go func() {
   986  		resqueue[3] = buildPBcanqueue("DependencyFunc, imms", p.c_storage.imms)
   987  		wg.Done()
   988  	}()
   989  
   990  	go func() {
   991  		resqueue[4] = buildPBcanqueue("DependencyFunc, res", p.c_storage.res)
   992  		wg.Done()
   993  	}()
   994  
   995  	go func() {
   996  		refundNodeIdArr, refundArr := RefundIdQueueFunc(p.c_storage.refunds)
   997  		sortTemp.ReIds = refundNodeIdArr
   998  		sortTemp.Refunds = refundArr
   999  		wg.Done()
  1000  	}()
  1001  
  1002  	// calculate tick dependency Hash
  1003  	go func() {
  1004  		dependencyNodeIdArr, dependencyArr := DependencyFunc(p.t_storage.Dependencys)
  1005  		sortTemp.NodeIds = dependencyNodeIdArr
  1006  		sortTemp.Deps = dependencyArr
  1007  		wg.Done()
  1008  	}()
  1009  
  1010  	wg.Wait()
  1011  
  1012  	// assemble data
  1013  	sortTemp.Sq = p.t_storage.Sq
  1014  
  1015  	for _, canArr := range resqueue {
  1016  		if len(canArr) != 0 {
  1017  			sortTemp.Cans = append(sortTemp.Cans, canArr...)
  1018  		}
  1019  	}
  1020  
  1021  	//PrintObject("Call CalculateHash build SortTemp: blockNumber:" + blockNumber.String() + ",blockHash:" + blockHash.Hex() + ", sortTemp", sortTemp)
  1022  
  1023  	log.Debug("Call CalculateHash build SortTemp success ...","blockNumber", blockNumber, "blockHash", blockHash.Hex(), "Build data Time spent", fmt.Sprintf("%v ms", start.End()))
  1024  
  1025  	data, err := proto.Marshal(sortTemp)
  1026  	if err != nil {
  1027  		log.Error("Failed to Call CalculateHash, protobuf is failed", "blockNumber", blockNumber, "blockHash", blockHash.Hex(),  "err", err)
  1028  		return common.Hash{}, err
  1029  	}
  1030  	log.Debug("Call CalculateHash protobuf success ...", "blockNumber", blockNumber, "blockHash", blockHash.Hex(),  "Made protobuf Time spent", fmt.Sprintf("%v ms", start.End()))
  1031  	ret := crypto.Keccak256Hash(data)
  1032  	log.Debug("Call CalculateHash finish ...", "blockNumber", blockNumber, "blockHash", blockHash.Hex(), "proto out len", len(data), "Hash", string(ret[:]),"md5",  md5.Sum(data),  "ppos storage Hash", ret.Hex(), "Total Time spent", fmt.Sprintf("%v ms", start.End()))
  1033  
  1034  	/*PrintObject("Call CalculateHash Data Cans", sortTemp.Cans)
  1035  	PrintObject("Call CalculateHash Data ReIds", sortTemp.ReIds)
  1036  	PrintObject("Call CalculateHash Data Refunds", sortTemp.Refunds)
  1037  	PrintObject("Call CalculateHash Data Sq", sortTemp.Sq)
  1038  	PrintObject("Call CalculateHash Data NodeIds", sortTemp.NodeIds)
  1039  	PrintObject("Call CalculateHash Data Deps", sortTemp.Deps)*/
  1040  
  1041  	return ret, nil
  1042  
  1043  }