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 }