mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 01:43:47 +00:00
core/light: implement atomic getter/setter for headerchain
This commit is contained in:
parent
9fa6dfe81c
commit
498fd65a20
3 changed files with 21 additions and 27 deletions
|
|
@ -1482,9 +1482,6 @@ func (bc *BlockChain) writeHeader(header *types.Header) error {
|
||||||
// CurrentHeader retrieves the current head header of the canonical chain. The
|
// CurrentHeader retrieves the current head header of the canonical chain. The
|
||||||
// header is retrieved from the HeaderChain's internal cache.
|
// header is retrieved from the HeaderChain's internal cache.
|
||||||
func (bc *BlockChain) CurrentHeader() *types.Header {
|
func (bc *BlockChain) CurrentHeader() *types.Header {
|
||||||
bc.mu.RLock()
|
|
||||||
defer bc.mu.RUnlock()
|
|
||||||
|
|
||||||
return bc.hc.CurrentHeader()
|
return bc.hc.CurrentHeader()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/hashicorp/golang-lru"
|
"github.com/hashicorp/golang-lru"
|
||||||
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -51,8 +52,8 @@ type HeaderChain struct {
|
||||||
chainDb ethdb.Database
|
chainDb ethdb.Database
|
||||||
genesisHeader *types.Header
|
genesisHeader *types.Header
|
||||||
|
|
||||||
currentHeader *types.Header // Current head of the header chain (may be above the block chain!)
|
currentHeader atomic.Value // Current head of the header chain (may be above the block chain!)
|
||||||
currentHeaderHash common.Hash // Hash of the current head of the header chain (prevent recomputing all the time)
|
currentHeaderHash common.Hash // Hash of the current head of the header chain (prevent recomputing all the time)
|
||||||
|
|
||||||
headerCache *lru.Cache // Cache for the most recent block headers
|
headerCache *lru.Cache // Cache for the most recent block headers
|
||||||
tdCache *lru.Cache // Cache for the most recent block total difficulties
|
tdCache *lru.Cache // Cache for the most recent block total difficulties
|
||||||
|
|
@ -95,13 +96,13 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
|
||||||
return nil, ErrNoGenesis
|
return nil, ErrNoGenesis
|
||||||
}
|
}
|
||||||
|
|
||||||
hc.currentHeader = hc.genesisHeader
|
hc.currentHeader.Store(hc.genesisHeader)
|
||||||
if head := GetHeadBlockHash(chainDb); head != (common.Hash{}) {
|
if head := GetHeadBlockHash(chainDb); head != (common.Hash{}) {
|
||||||
if chead := hc.GetHeaderByHash(head); chead != nil {
|
if chead := hc.GetHeaderByHash(head); chead != nil {
|
||||||
hc.currentHeader = chead
|
hc.currentHeader.Store(chead)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hc.currentHeaderHash = hc.currentHeader.Hash()
|
hc.currentHeaderHash = hc.CurrentHeader().Hash()
|
||||||
|
|
||||||
return hc, nil
|
return hc, nil
|
||||||
}
|
}
|
||||||
|
|
@ -139,7 +140,7 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
|
||||||
if ptd == nil {
|
if ptd == nil {
|
||||||
return NonStatTy, consensus.ErrUnknownAncestor
|
return NonStatTy, consensus.ErrUnknownAncestor
|
||||||
}
|
}
|
||||||
localTd := hc.GetTd(hc.currentHeaderHash, hc.currentHeader.Number.Uint64())
|
localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64())
|
||||||
externTd := new(big.Int).Add(header.Difficulty, ptd)
|
externTd := new(big.Int).Add(header.Difficulty, ptd)
|
||||||
|
|
||||||
// Irrelevant of the canonical status, write the td and header to the database
|
// Irrelevant of the canonical status, write the td and header to the database
|
||||||
|
|
@ -181,7 +182,8 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
|
||||||
if err := WriteHeadHeaderHash(hc.chainDb, hash); err != nil {
|
if err := WriteHeadHeaderHash(hc.chainDb, hash); err != nil {
|
||||||
log.Crit("Failed to insert head header hash", "err", err)
|
log.Crit("Failed to insert head header hash", "err", err)
|
||||||
}
|
}
|
||||||
hc.currentHeaderHash, hc.currentHeader = hash, types.CopyHeader(header)
|
hc.currentHeaderHash = hash
|
||||||
|
hc.currentHeader.Store(types.CopyHeader(header))
|
||||||
|
|
||||||
status = CanonStatTy
|
status = CanonStatTy
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -383,7 +385,7 @@ func (hc *HeaderChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||||
// CurrentHeader retrieves the current head header of the canonical chain. The
|
// CurrentHeader retrieves the current head header of the canonical chain. The
|
||||||
// header is retrieved from the HeaderChain's internal cache.
|
// header is retrieved from the HeaderChain's internal cache.
|
||||||
func (hc *HeaderChain) CurrentHeader() *types.Header {
|
func (hc *HeaderChain) CurrentHeader() *types.Header {
|
||||||
return hc.currentHeader
|
return hc.currentHeader.Load().(*types.Header)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCurrentHeader sets the current head header of the canonical chain.
|
// SetCurrentHeader sets the current head header of the canonical chain.
|
||||||
|
|
@ -391,7 +393,7 @@ func (hc *HeaderChain) SetCurrentHeader(head *types.Header) {
|
||||||
if err := WriteHeadHeaderHash(hc.chainDb, head.Hash()); err != nil {
|
if err := WriteHeadHeaderHash(hc.chainDb, head.Hash()); err != nil {
|
||||||
log.Crit("Failed to insert head header hash", "err", err)
|
log.Crit("Failed to insert head header hash", "err", err)
|
||||||
}
|
}
|
||||||
hc.currentHeader = head
|
hc.currentHeader.Store(head)
|
||||||
hc.currentHeaderHash = head.Hash()
|
hc.currentHeaderHash = head.Hash()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -403,19 +405,20 @@ type DeleteCallback func(common.Hash, uint64)
|
||||||
// will be deleted and the new one set.
|
// will be deleted and the new one set.
|
||||||
func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) {
|
func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) {
|
||||||
height := uint64(0)
|
height := uint64(0)
|
||||||
if hc.currentHeader != nil {
|
|
||||||
height = hc.currentHeader.Number.Uint64()
|
if hdr := hc.CurrentHeader(); hdr != nil {
|
||||||
|
height = hdr.Number.Uint64()
|
||||||
}
|
}
|
||||||
|
|
||||||
for hc.currentHeader != nil && hc.currentHeader.Number.Uint64() > head {
|
for hdr := hc.CurrentHeader(); hdr != nil && hdr.Number.Uint64() > head; hdr = hc.CurrentHeader() {
|
||||||
hash := hc.currentHeader.Hash()
|
hash := hdr.Hash()
|
||||||
num := hc.currentHeader.Number.Uint64()
|
num := hdr.Number.Uint64()
|
||||||
if delFn != nil {
|
if delFn != nil {
|
||||||
delFn(hash, num)
|
delFn(hash, num)
|
||||||
}
|
}
|
||||||
DeleteHeader(hc.chainDb, hash, num)
|
DeleteHeader(hc.chainDb, hash, num)
|
||||||
DeleteTd(hc.chainDb, hash, num)
|
DeleteTd(hc.chainDb, hash, num)
|
||||||
hc.currentHeader = hc.GetHeader(hc.currentHeader.ParentHash, hc.currentHeader.Number.Uint64()-1)
|
hc.currentHeader.Store(hc.GetHeader(hdr.ParentHash, hdr.Number.Uint64()-1))
|
||||||
}
|
}
|
||||||
// Roll back the canonical chain numbering
|
// Roll back the canonical chain numbering
|
||||||
for i := height; i > head; i-- {
|
for i := height; i > head; i-- {
|
||||||
|
|
@ -426,10 +429,10 @@ func (hc *HeaderChain) SetHead(head uint64, delFn DeleteCallback) {
|
||||||
hc.tdCache.Purge()
|
hc.tdCache.Purge()
|
||||||
hc.numberCache.Purge()
|
hc.numberCache.Purge()
|
||||||
|
|
||||||
if hc.currentHeader == nil {
|
if hc.CurrentHeader() == nil {
|
||||||
hc.currentHeader = hc.genesisHeader
|
hc.currentHeader.Store(hc.genesisHeader)
|
||||||
}
|
}
|
||||||
hc.currentHeaderHash = hc.currentHeader.Hash()
|
hc.currentHeaderHash = hc.CurrentHeader().Hash()
|
||||||
|
|
||||||
if err := WriteHeadHeaderHash(hc.chainDb, hc.currentHeaderHash); err != nil {
|
if err := WriteHeadHeaderHash(hc.chainDb, hc.currentHeaderHash); err != nil {
|
||||||
log.Crit("Failed to reset head header hash", "err", err)
|
log.Crit("Failed to reset head header hash", "err", err)
|
||||||
|
|
|
||||||
|
|
@ -171,9 +171,6 @@ func (bc *LightChain) SetHead(head uint64) {
|
||||||
|
|
||||||
// GasLimit returns the gas limit of the current HEAD block.
|
// GasLimit returns the gas limit of the current HEAD block.
|
||||||
func (self *LightChain) GasLimit() uint64 {
|
func (self *LightChain) GasLimit() uint64 {
|
||||||
self.mu.RLock()
|
|
||||||
defer self.mu.RUnlock()
|
|
||||||
|
|
||||||
return self.hc.CurrentHeader().GasLimit
|
return self.hc.CurrentHeader().GasLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -387,9 +384,6 @@ func (self *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int)
|
||||||
// CurrentHeader retrieves the current head header of the canonical chain. The
|
// CurrentHeader retrieves the current head header of the canonical chain. The
|
||||||
// header is retrieved from the HeaderChain's internal cache.
|
// header is retrieved from the HeaderChain's internal cache.
|
||||||
func (self *LightChain) CurrentHeader() *types.Header {
|
func (self *LightChain) CurrentHeader() *types.Header {
|
||||||
self.mu.RLock()
|
|
||||||
defer self.mu.RUnlock()
|
|
||||||
|
|
||||||
return self.hc.CurrentHeader()
|
return self.hc.CurrentHeader()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue