github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/orgchain/storages/ledger_partial_header.go (about)

     1  package storages
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  
     7  	"github.com/sixexorg/magnetic-ring/common"
     8  	"github.com/sixexorg/magnetic-ring/core/orgchain/types"
     9  )
    10  
    11  func (this *LedgerStoreImp) AddHeaders(headers []*types.Header) error {
    12  	sort.Slice(headers, func(i, j int) bool {
    13  		return headers[i].Height < headers[j].Height
    14  	})
    15  	var err error
    16  	for _, header := range headers {
    17  		err = this.AddHeader(header)
    18  		if err != nil {
    19  			return err
    20  		}
    21  	}
    22  	return nil
    23  }
    24  
    25  func (this *LedgerStoreImp) AddHeader(header *types.Header) error {
    26  	nextHeaderHeight := this.GetCurrentHeaderHeight() + 1
    27  	if header.Height != nextHeaderHeight {
    28  		return fmt.Errorf("header height %d not equal next header height %d", header.Height, nextHeaderHeight)
    29  	}
    30  	err := this.verifyHeader(header)
    31  	if err != nil {
    32  		return fmt.Errorf("verifyHeader error %s", err)
    33  	}
    34  	this.addHeaderCache(header)
    35  	this.setHeaderIndex(header.Height, header.Hash())
    36  	return nil
    37  }
    38  
    39  //GetHeaderByHash return the block header by block hash
    40  func (this *LedgerStoreImp) GetHeaderByHash(blockHash common.Hash) (*types.Header, error) {
    41  	header := this.getHeaderCache(blockHash)
    42  	if header != nil {
    43  		return header, nil
    44  	}
    45  	return this.blockStore.GetHeader(blockHash)
    46  }
    47  func (this *LedgerStoreImp) GetBlockHeaderHashByHeight(height uint64) common.Hash {
    48  	return this.getHeaderIndex(height)
    49  }
    50  
    51  //GetCurrentHeaderHeight return the current header height.
    52  //In block sync states, Header height is usually higher than block height that is has already committed to storage
    53  func (this *LedgerStoreImp) GetCurrentHeaderHeight() uint64 {
    54  	this.lock.RLock()
    55  	defer this.lock.RUnlock()
    56  	size := len(this.headerIndex)
    57  	if size == 0 {
    58  		return 0
    59  	}
    60  	return uint64(size)
    61  }
    62  
    63  //GetCurrentHeaderHash return the current header hash. The current header means the latest header.
    64  func (this *LedgerStoreImp) GetCurrentHeaderHash() common.Hash {
    65  	this.lock.RLock()
    66  	defer this.lock.RUnlock()
    67  	size := len(this.headerIndex)
    68  	if size == 0 {
    69  		return common.Hash{}
    70  	}
    71  	return this.headerIndex[uint64(size)]
    72  }
    73  func (this *LedgerStoreImp) addHeaderCache(header *types.Header) {
    74  	this.lock.Lock()
    75  	defer this.lock.Unlock()
    76  	this.headerCache[header.Hash()] = header
    77  }
    78  
    79  func (this *LedgerStoreImp) delHeaderCache(blockHash common.Hash) {
    80  	this.lock.Lock()
    81  	defer this.lock.Unlock()
    82  	delete(this.headerCache, blockHash)
    83  }
    84  
    85  func (this *LedgerStoreImp) getHeaderCache(blockHash common.Hash) *types.Header {
    86  	this.lock.RLock()
    87  	defer this.lock.RUnlock()
    88  	header, ok := this.headerCache[blockHash]
    89  	if !ok {
    90  		return nil
    91  	}
    92  	return header
    93  }
    94  func (this *LedgerStoreImp) setHeaderIndex(height uint64, blockHash common.Hash) {
    95  	this.lock.Lock()
    96  	defer this.lock.Unlock()
    97  	this.headerIndex[height] = blockHash
    98  }
    99  
   100  func (this *LedgerStoreImp) getHeaderIndex(height uint64) common.Hash {
   101  	this.lock.RLock()
   102  	defer this.lock.RUnlock()
   103  	blockHash, ok := this.headerIndex[height]
   104  	if !ok {
   105  		return common.Hash{}
   106  	}
   107  	return blockHash
   108  }
   109  func (this *LedgerStoreImp) saveHeaderIndexList() error {
   110  	this.lock.RLock()
   111  	storeCount := this.storedIndexCount
   112  	currHeight := this.currBlockHeight
   113  	if currHeight-storeCount < HEADER_INDEX_BATCH_SIZE {
   114  		this.lock.RUnlock()
   115  		return nil
   116  	}
   117  
   118  	headerList := make([]common.Hash, HEADER_INDEX_BATCH_SIZE)
   119  	for i := uint64(0); i < HEADER_INDEX_BATCH_SIZE; i++ {
   120  		height := storeCount + i
   121  		headerList[i] = this.headerIndex[height]
   122  	}
   123  	this.lock.RUnlock()
   124  	err := this.blockStore.SaveHeaderIndexList(storeCount, headerList)
   125  	if err != nil {
   126  		return fmt.Errorf("SaveHeaderIndexList start %d error %s", storeCount, err)
   127  	}
   128  
   129  	this.lock.Lock()
   130  	this.storedIndexCount += HEADER_INDEX_BATCH_SIZE
   131  	this.lock.Unlock()
   132  	return nil
   133  }