Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 15 additions & 23 deletions core/headerchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@
package core

import (
crand "crypto/rand"
"errors"
"fmt"
"math"
"math/big"
mrand "math/rand"
"sync/atomic"
"time"

Expand All @@ -43,53 +40,48 @@ const (
numberCacheLimit = 2048
)

// HeaderChain implements the basic block header chain logic that is shared by
// core.BlockChain and light.LightChain. It is not usable in itself, only as
// a part of either structure.
// HeaderChain implements the basic block header chain logic. It is not usable
// in itself, but rather an internal structure of core.Blockchain.
//
// HeaderChain is responsible for maintaining the header chain including the
// header query and updating.
//
// The components maintained by headerchain includes: (1) total difficulty
// (2) header (3) block hash -> number mapping (4) canonical number -> hash mapping
// and (5) head header flag.
// The data components maintained by HeaderChain include:
//
// It is not thread safe either, the encapsulating chain structures should do
// the necessary mutex locking/unlocking.
// - total difficulty
// - header
// - block hash -> number mapping
// - canonical number -> hash mapping
// - head header flag.
//
// It is not thread safe, the encapsulating chain structures should do the
// necessary mutex locking/unlocking.
type HeaderChain struct {
config *params.ChainConfig
chainDb ethdb.Database
genesisHeader *types.Header

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)
currentHeader atomic.Pointer[types.Header] // Current head of the header chain (maybe above the block chain!)
currentHeaderHash common.Hash // Hash of the current head of the header chain (prevent recomputing all the time)

headerCache *lru.Cache[common.Hash, *types.Header]
tdCache *lru.Cache[common.Hash, *big.Int] // most recent total difficulties
numberCache *lru.Cache[common.Hash, uint64] // most recent block numbers

procInterrupt func() bool

rand *mrand.Rand
engine consensus.Engine
engine consensus.Engine
}

// NewHeaderChain creates a new HeaderChain structure. ProcInterrupt points
// to the parent's interrupt semaphore.
func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, procInterrupt func() bool) (*HeaderChain, error) {
// Seed a fast but crypto originating random generator
seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
if err != nil {
return nil, err
}
hc := &HeaderChain{
config: config,
chainDb: chainDb,
headerCache: lru.NewCache[common.Hash, *types.Header](headerCacheLimit),
tdCache: lru.NewCache[common.Hash, *big.Int](tdCacheLimit),
numberCache: lru.NewCache[common.Hash, uint64](numberCacheLimit),
procInterrupt: procInterrupt,
rand: mrand.New(mrand.NewSource(seed.Int64())),
engine: engine,
}
hc.genesisHeader = hc.GetHeaderByNumber(0)
Expand Down Expand Up @@ -525,7 +517,7 @@ func (hc *HeaderChain) GetCanonicalHash(number uint64) common.Hash {
// CurrentHeader retrieves the current head header of the canonical chain. The
// header is retrieved from the HeaderChain's internal cache.
func (hc *HeaderChain) CurrentHeader() *types.Header {
return hc.currentHeader.Load().(*types.Header)
return hc.currentHeader.Load()
}

// SetCurrentHeader sets the in-memory head header marker of the canonical chan
Expand Down