mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
core, cmd: add generic LRU implementation (#26162)
This commit is contained in:
parent
96e2743508
commit
c47819c7d6
5 changed files with 65 additions and 86 deletions
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb/leveldb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb/leveldb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
"github.com/XinFinOrg/XDPoSChain/trie"
|
"github.com/XinFinOrg/XDPoSChain/trie"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -29,7 +29,7 @@ var (
|
||||||
sercureKey = []byte("secure-key-")
|
sercureKey = []byte("secure-key-")
|
||||||
nWorker = runtime.NumCPU() / 2
|
nWorker = runtime.NumCPU() / 2
|
||||||
cleanAddress = []common.Address{common.BlockSignersBinary}
|
cleanAddress = []common.Address{common.BlockSignersBinary}
|
||||||
cache *lru.Cache
|
cache *lru.Cache[common.Hash, struct{}]
|
||||||
finish = int32(0)
|
finish = int32(0)
|
||||||
running = true
|
running = true
|
||||||
stateRoots = make(chan TrieRoot)
|
stateRoots = make(chan TrieRoot)
|
||||||
|
|
@ -58,7 +58,7 @@ func main() {
|
||||||
currentHeader := core.GetHeader(lddb, head, core.GetBlockNumber(lddb, head))
|
currentHeader := core.GetHeader(lddb, head, core.GetBlockNumber(lddb, head))
|
||||||
tridb := trie.NewDatabase(lddb)
|
tridb := trie.NewDatabase(lddb)
|
||||||
catchEventInterupt(db)
|
catchEventInterupt(db)
|
||||||
cache, _ = lru.New(*cacheSize)
|
cache = lru.NewCache[common.Hash, struct{}](*cacheSize)
|
||||||
go func() {
|
go func() {
|
||||||
for i := uint64(1); i <= currentHeader.Number.Uint64(); i++ {
|
for i := uint64(1); i <= currentHeader.Number.Uint64(); i++ {
|
||||||
hash := core.GetCanonicalHash(lddb, i)
|
hash := core.GetCanonicalHash(lddb, i)
|
||||||
|
|
@ -222,7 +222,7 @@ func processNodes(node StateNode, db *leveldb.Database) ([17]*StateNode, [17]*[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache.Add(commonHash, true)
|
cache.Add(commonHash, struct{}{})
|
||||||
}
|
}
|
||||||
return newNodes, keys, number
|
return newNodes, keys, number
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/mclock"
|
"github.com/XinFinOrg/XDPoSChain/common/mclock"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/sort"
|
"github.com/XinFinOrg/XDPoSChain/common/sort"
|
||||||
|
|
@ -52,7 +53,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
"github.com/XinFinOrg/XDPoSChain/trie"
|
"github.com/XinFinOrg/XDPoSChain/trie"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -140,37 +140,40 @@ type BlockChain struct {
|
||||||
|
|
||||||
stateCache state.Database // State database to reuse between imports (contains state cache)
|
stateCache state.Database // State database to reuse between imports (contains state cache)
|
||||||
|
|
||||||
bodyCache *lru.Cache // Cache for the most recent block bodies
|
bodyCache *lru.Cache[common.Hash, *types.Body] // Cache for the most recent block bodies
|
||||||
bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format
|
bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue] // Cache for the most recent block bodies in RLP encoded format
|
||||||
blockCache *lru.Cache // Cache for the most recent entire blocks
|
blockCache *lru.Cache[common.Hash, *types.Block] // Cache for the most recent entire blocks
|
||||||
futureBlocks *lru.Cache // future blocks are blocks added for later processing
|
resultProcess *lru.Cache[common.Hash, *ResultProcessBlock] // Cache for processed blocks
|
||||||
resultProcess *lru.Cache // Cache for processed blocks
|
calculatingBlock *lru.Cache[common.Hash, *CalculatedBlock] // Cache for processing blocks
|
||||||
calculatingBlock *lru.Cache // Cache for processing blocks
|
downloadingBlock *lru.Cache[common.Hash, struct{}] // Cache for downloading blocks (avoid duplication from fetcher)
|
||||||
downloadingBlock *lru.Cache // Cache for downloading blocks (avoid duplication from fetcher)
|
badBlocks *lru.Cache[common.Hash, *types.Header] // Bad block cache
|
||||||
quit chan struct{} // blockchain quit channel
|
|
||||||
running int32 // running must be called atomically
|
// future blocks are blocks added for later processing
|
||||||
// procInterrupt must be atomically called
|
futureBlocks *lru.Cache[common.Hash, *types.Block]
|
||||||
procInterrupt int32 // interrupt signaler for block processing
|
|
||||||
wg sync.WaitGroup // chain processing wait group for shutting down
|
wg sync.WaitGroup // chain processing wait group for shutting down
|
||||||
|
quit chan struct{} // shutdown signal, closed in Stop.
|
||||||
|
running int32 // 0 if chain is running, 1 when stopped
|
||||||
|
procInterrupt int32 // interrupt signaler for block processing
|
||||||
|
|
||||||
engine consensus.Engine
|
engine consensus.Engine
|
||||||
processor Processor // block processor interface
|
processor Processor // block processor interface
|
||||||
validator Validator // block and state validator interface
|
validator Validator // block and state validator interface
|
||||||
vmConfig vm.Config
|
vmConfig vm.Config
|
||||||
|
|
||||||
badBlocks *lru.Cache // Bad block cache
|
|
||||||
shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block.
|
shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block.
|
||||||
IPCEndpoint string
|
IPCEndpoint string
|
||||||
Client bind.ContractBackend // Global ipc client instance.
|
Client bind.ContractBackend // Global ipc client instance.
|
||||||
|
|
||||||
// Blocks hash array by block number
|
// Blocks hash array by block number
|
||||||
// cache field for tracking finality purpose, can't use for tracking block vs block relationship
|
// cache field for tracking finality purpose, can't use for tracking block vs block relationship
|
||||||
blocksHashCache *lru.Cache
|
blocksHashCache *lru.Cache[uint64, []common.Hash]
|
||||||
|
|
||||||
resultTrade *lru.Cache // trades result: key - takerOrderHash, value: trades corresponding to takerOrder
|
resultTrade *lru.Cache[common.Hash, interface{}] // trades result: key - takerOrderHash, value: trades corresponding to takerOrder
|
||||||
rejectedOrders *lru.Cache // rejected orders: key - takerOrderHash, value: rejected orders corresponding to takerOrder
|
rejectedOrders *lru.Cache[common.Hash, interface{}] // rejected orders: key - takerOrderHash, value: rejected orders corresponding to takerOrder
|
||||||
resultLendingTrade *lru.Cache
|
resultLendingTrade *lru.Cache[common.Hash, interface{}]
|
||||||
rejectedLendingItem *lru.Cache
|
rejectedLendingItem *lru.Cache[common.Hash, interface{}]
|
||||||
finalizedTrade *lru.Cache // include both trades which force update to closed/liquidated by the protocol
|
finalizedTrade *lru.Cache[common.Hash, interface{}] // include both trades which force update to closed/liquidated by the protocol
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlockChain returns a fully initialised block chain using information
|
// NewBlockChain returns a fully initialised block chain using information
|
||||||
|
|
@ -183,24 +186,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
||||||
TrieTimeLimit: 5 * time.Minute,
|
TrieTimeLimit: 5 * time.Minute,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bodyCache, _ := lru.New(bodyCacheLimit)
|
|
||||||
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
|
||||||
blockCache, _ := lru.New(blockCacheLimit)
|
|
||||||
blocksHashCache, _ := lru.New(blocksHashCacheLimit)
|
|
||||||
futureBlocks, _ := lru.New(maxFutureBlocks)
|
|
||||||
badBlocks, _ := lru.New(badBlockLimit)
|
|
||||||
resultProcess, _ := lru.New(blockCacheLimit)
|
|
||||||
preparingBlock, _ := lru.New(blockCacheLimit)
|
|
||||||
downloadingBlock, _ := lru.New(blockCacheLimit)
|
|
||||||
|
|
||||||
// for XDCx
|
|
||||||
resultTrade, _ := lru.New(tradingstate.OrderCacheLimit)
|
|
||||||
rejectedOrders, _ := lru.New(tradingstate.OrderCacheLimit)
|
|
||||||
|
|
||||||
// XDCxlending
|
|
||||||
resultLendingTrade, _ := lru.New(tradingstate.OrderCacheLimit)
|
|
||||||
rejectedLendingItem, _ := lru.New(tradingstate.OrderCacheLimit)
|
|
||||||
finalizedTrade, _ := lru.New(tradingstate.OrderCacheLimit)
|
|
||||||
bc := &BlockChain{
|
bc := &BlockChain{
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
cacheConfig: cacheConfig,
|
cacheConfig: cacheConfig,
|
||||||
|
|
@ -208,22 +194,22 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
||||||
triegc: prque.New(nil),
|
triegc: prque.New(nil),
|
||||||
stateCache: state.NewDatabase(db),
|
stateCache: state.NewDatabase(db),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
bodyCache: bodyCache,
|
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
|
||||||
bodyRLPCache: bodyRLPCache,
|
bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit),
|
||||||
blockCache: blockCache,
|
blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit),
|
||||||
futureBlocks: futureBlocks,
|
futureBlocks: lru.NewCache[common.Hash, *types.Block](maxFutureBlocks),
|
||||||
resultProcess: resultProcess,
|
resultProcess: lru.NewCache[common.Hash, *ResultProcessBlock](blockCacheLimit),
|
||||||
calculatingBlock: preparingBlock,
|
calculatingBlock: lru.NewCache[common.Hash, *CalculatedBlock](blockCacheLimit),
|
||||||
downloadingBlock: downloadingBlock,
|
downloadingBlock: lru.NewCache[common.Hash, struct{}](blockCacheLimit),
|
||||||
engine: engine,
|
engine: engine,
|
||||||
vmConfig: vmConfig,
|
vmConfig: vmConfig,
|
||||||
badBlocks: badBlocks,
|
badBlocks: lru.NewCache[common.Hash, *types.Header](badBlockLimit),
|
||||||
blocksHashCache: blocksHashCache,
|
blocksHashCache: lru.NewCache[uint64, []common.Hash](blocksHashCacheLimit),
|
||||||
resultTrade: resultTrade,
|
resultTrade: lru.NewCache[common.Hash, interface{}](tradingstate.OrderCacheLimit),
|
||||||
rejectedOrders: rejectedOrders,
|
rejectedOrders: lru.NewCache[common.Hash, interface{}](tradingstate.OrderCacheLimit),
|
||||||
resultLendingTrade: resultLendingTrade,
|
resultLendingTrade: lru.NewCache[common.Hash, interface{}](tradingstate.OrderCacheLimit),
|
||||||
rejectedLendingItem: rejectedLendingItem,
|
rejectedLendingItem: lru.NewCache[common.Hash, interface{}](tradingstate.OrderCacheLimit),
|
||||||
finalizedTrade: finalizedTrade,
|
finalizedTrade: lru.NewCache[common.Hash, interface{}](tradingstate.OrderCacheLimit),
|
||||||
}
|
}
|
||||||
bc.SetValidator(NewBlockValidator(chainConfig, bc, engine))
|
bc.SetValidator(NewBlockValidator(chainConfig, bc, engine))
|
||||||
bc.SetProcessor(NewStateProcessor(chainConfig, bc, engine))
|
bc.SetProcessor(NewStateProcessor(chainConfig, bc, engine))
|
||||||
|
|
@ -720,8 +706,7 @@ func (bc *BlockChain) Genesis() *types.Block {
|
||||||
func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
|
func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
|
||||||
// Short circuit if the body's already in the cache, retrieve otherwise
|
// Short circuit if the body's already in the cache, retrieve otherwise
|
||||||
if cached, ok := bc.bodyCache.Get(hash); ok {
|
if cached, ok := bc.bodyCache.Get(hash); ok {
|
||||||
body := cached.(*types.Body)
|
return cached
|
||||||
return body
|
|
||||||
}
|
}
|
||||||
body := GetBody(bc.db, hash, bc.hc.GetBlockNumber(hash))
|
body := GetBody(bc.db, hash, bc.hc.GetBlockNumber(hash))
|
||||||
if body == nil {
|
if body == nil {
|
||||||
|
|
@ -737,7 +722,7 @@ func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
|
||||||
func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
|
func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
|
||||||
// Short circuit if the body's already in the cache, retrieve otherwise
|
// Short circuit if the body's already in the cache, retrieve otherwise
|
||||||
if cached, ok := bc.bodyRLPCache.Get(hash); ok {
|
if cached, ok := bc.bodyRLPCache.Get(hash); ok {
|
||||||
return cached.(rlp.RawValue)
|
return cached
|
||||||
}
|
}
|
||||||
body := GetBodyRLP(bc.db, hash, bc.hc.GetBlockNumber(hash))
|
body := GetBodyRLP(bc.db, hash, bc.hc.GetBlockNumber(hash))
|
||||||
if len(body) == 0 {
|
if len(body) == 0 {
|
||||||
|
|
@ -794,7 +779,7 @@ func (bc *BlockChain) HasBlockAndFullState(hash common.Hash, number uint64) bool
|
||||||
func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
|
func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
|
||||||
// Short circuit if the block's already in the cache, retrieve otherwise
|
// Short circuit if the block's already in the cache, retrieve otherwise
|
||||||
if block, ok := bc.blockCache.Get(hash); ok {
|
if block, ok := bc.blockCache.Get(hash); ok {
|
||||||
return block.(*types.Block)
|
return block
|
||||||
}
|
}
|
||||||
block := GetBlock(bc.db, hash, number)
|
block := GetBlock(bc.db, hash, number)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
|
|
@ -847,7 +832,7 @@ func (bc *BlockChain) GetBlocksHashCache(number uint64) []common.Hash {
|
||||||
cached, ok := bc.blocksHashCache.Get(number)
|
cached, ok := bc.blocksHashCache.Get(number)
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
return cached.([]common.Hash)
|
return cached
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -980,7 +965,7 @@ func (bc *BlockChain) procFutureBlocks() {
|
||||||
blocks := make([]*types.Block, 0, bc.futureBlocks.Len())
|
blocks := make([]*types.Block, 0, bc.futureBlocks.Len())
|
||||||
for _, hash := range bc.futureBlocks.Keys() {
|
for _, hash := range bc.futureBlocks.Keys() {
|
||||||
if block, exist := bc.futureBlocks.Peek(hash); exist {
|
if block, exist := bc.futureBlocks.Peek(hash); exist {
|
||||||
blocks = append(blocks, block.(*types.Block))
|
blocks = append(blocks, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(blocks) > 0 {
|
if len(blocks) > 0 {
|
||||||
|
|
@ -1491,7 +1476,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, []
|
||||||
for i, block := range chain {
|
for i, block := range chain {
|
||||||
headers[i] = block.Header()
|
headers[i] = block.Header()
|
||||||
seals[i] = verifySeals
|
seals[i] = verifySeals
|
||||||
bc.downloadingBlock.Add(block.Hash(), true)
|
bc.downloadingBlock.Add(block.Hash(), struct{}{})
|
||||||
}
|
}
|
||||||
abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
|
abort, results := bc.engine.VerifyHeaders(bc, headers, seals)
|
||||||
defer close(abort)
|
defer close(abort)
|
||||||
|
|
@ -1805,11 +1790,11 @@ func (bc *BlockChain) getResultBlock(block *types.Block, verifiedM2 bool) (*Resu
|
||||||
if verifiedM2 {
|
if verifiedM2 {
|
||||||
if result, check := bc.resultProcess.Get(block.HashNoValidator()); check {
|
if result, check := bc.resultProcess.Get(block.HashNoValidator()); check {
|
||||||
log.Debug("Get result block from cache ", "number", block.NumberU64(), "hash", block.Hash(), "hash no validator", block.HashNoValidator())
|
log.Debug("Get result block from cache ", "number", block.NumberU64(), "hash", block.Hash(), "hash no validator", block.HashNoValidator())
|
||||||
return result.(*ResultProcessBlock), nil
|
return result, nil
|
||||||
}
|
}
|
||||||
log.Debug("Not found cache prepare block ", "number", block.NumberU64(), "hash", block.Hash(), "validator", block.HashNoValidator())
|
log.Debug("Not found cache prepare block ", "number", block.NumberU64(), "hash", block.Hash(), "validator", block.HashNoValidator())
|
||||||
if calculatedBlock, _ := bc.calculatingBlock.Get(block.HashNoValidator()); calculatedBlock != nil {
|
if calculatedBlock, _ := bc.calculatingBlock.Get(block.HashNoValidator()); calculatedBlock != nil {
|
||||||
calculatedBlock.(*CalculatedBlock).stop = true
|
calculatedBlock.stop = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
calculatedBlock = &CalculatedBlock{block, false}
|
calculatedBlock = &CalculatedBlock{block, false}
|
||||||
|
|
@ -2007,7 +1992,7 @@ func (bc *BlockChain) UpdateBlocksHashCache(block *types.Block) []common.Hash {
|
||||||
cached, ok := bc.blocksHashCache.Get(blockNumber)
|
cached, ok := bc.blocksHashCache.Get(blockNumber)
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
hashArr := cached.([]common.Hash)
|
hashArr := cached
|
||||||
hashArr = append(hashArr, block.Hash())
|
hashArr = append(hashArr, block.Hash())
|
||||||
bc.blocksHashCache.Remove(blockNumber)
|
bc.blocksHashCache.Remove(blockNumber)
|
||||||
bc.blocksHashCache.Add(blockNumber, hashArr)
|
bc.blocksHashCache.Add(blockNumber, hashArr)
|
||||||
|
|
@ -2340,8 +2325,7 @@ type BadBlockArgs struct {
|
||||||
func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) {
|
func (bc *BlockChain) BadBlocks() ([]BadBlockArgs, error) {
|
||||||
headers := make([]BadBlockArgs, 0, bc.badBlocks.Len())
|
headers := make([]BadBlockArgs, 0, bc.badBlocks.Len())
|
||||||
for _, hash := range bc.badBlocks.Keys() {
|
for _, hash := range bc.badBlocks.Keys() {
|
||||||
if hdr, exist := bc.badBlocks.Peek(hash); exist {
|
if header, exist := bc.badBlocks.Peek(hash); exist {
|
||||||
header := hdr.(*types.Header)
|
|
||||||
headers = append(headers, BadBlockArgs{header.Hash(), header})
|
headers = append(headers, BadBlockArgs{header.Hash(), header})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1367,7 +1367,7 @@ func TestBlocksHashCacheUpdate(t *testing.T) {
|
||||||
}
|
}
|
||||||
cachedAt, _ := chain.blocksHashCache.Get(uint64(3))
|
cachedAt, _ := chain.blocksHashCache.Get(uint64(3))
|
||||||
|
|
||||||
if len(cachedAt.([]common.Hash)) != 2 {
|
if len(cachedAt) != 2 {
|
||||||
t.Error("BlocksHashCache doesn't add new cache after concating new fork ")
|
t.Error("BlocksHashCache doesn't add new cache after concating new fork ")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,13 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -56,9 +56,9 @@ type HeaderChain struct {
|
||||||
currentHeader atomic.Value // 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[common.Hash, *types.Header]
|
||||||
tdCache *lru.Cache // Cache for the most recent block total difficulties
|
tdCache *lru.Cache[common.Hash, *big.Int] // most recent total difficulties
|
||||||
numberCache *lru.Cache // Cache for the most recent block numbers
|
numberCache *lru.Cache[common.Hash, uint64] // most recent block numbers
|
||||||
|
|
||||||
procInterrupt func() bool
|
procInterrupt func() bool
|
||||||
|
|
||||||
|
|
@ -72,10 +72,6 @@ type HeaderChain struct {
|
||||||
// procInterrupt points to the parent's interrupt semaphore
|
// procInterrupt points to the parent's interrupt semaphore
|
||||||
// wg points to the parent's shutdown wait group
|
// wg points to the parent's shutdown wait group
|
||||||
func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, procInterrupt func() bool) (*HeaderChain, error) {
|
func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, procInterrupt func() bool) (*HeaderChain, error) {
|
||||||
headerCache, _ := lru.New(headerCacheLimit)
|
|
||||||
tdCache, _ := lru.New(tdCacheLimit)
|
|
||||||
numberCache, _ := lru.New(numberCacheLimit)
|
|
||||||
|
|
||||||
// Seed a fast but crypto originating random generator
|
// Seed a fast but crypto originating random generator
|
||||||
seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
|
seed, err := crand.Int(crand.Reader, big.NewInt(math.MaxInt64))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -85,9 +81,9 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
|
||||||
hc := &HeaderChain{
|
hc := &HeaderChain{
|
||||||
config: config,
|
config: config,
|
||||||
chainDb: chainDb,
|
chainDb: chainDb,
|
||||||
headerCache: headerCache,
|
headerCache: lru.NewCache[common.Hash, *types.Header](headerCacheLimit),
|
||||||
tdCache: tdCache,
|
tdCache: lru.NewCache[common.Hash, *big.Int](tdCacheLimit),
|
||||||
numberCache: numberCache,
|
numberCache: lru.NewCache[common.Hash, uint64](numberCacheLimit),
|
||||||
procInterrupt: procInterrupt,
|
procInterrupt: procInterrupt,
|
||||||
rand: mrand.New(mrand.NewSource(seed.Int64())),
|
rand: mrand.New(mrand.NewSource(seed.Int64())),
|
||||||
engine: engine,
|
engine: engine,
|
||||||
|
|
@ -113,7 +109,7 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
|
||||||
// from the cache or database
|
// from the cache or database
|
||||||
func (hc *HeaderChain) GetBlockNumber(hash common.Hash) uint64 {
|
func (hc *HeaderChain) GetBlockNumber(hash common.Hash) uint64 {
|
||||||
if cached, ok := hc.numberCache.Get(hash); ok {
|
if cached, ok := hc.numberCache.Get(hash); ok {
|
||||||
return cached.(uint64)
|
return cached
|
||||||
}
|
}
|
||||||
number := GetBlockNumber(hc.chainDb, hash)
|
number := GetBlockNumber(hc.chainDb, hash)
|
||||||
if number != missingNumber {
|
if number != missingNumber {
|
||||||
|
|
@ -312,7 +308,7 @@ func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []co
|
||||||
func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
|
func (hc *HeaderChain) GetTd(hash common.Hash, number uint64) *big.Int {
|
||||||
// Short circuit if the td's already in the cache, retrieve otherwise
|
// Short circuit if the td's already in the cache, retrieve otherwise
|
||||||
if cached, ok := hc.tdCache.Get(hash); ok {
|
if cached, ok := hc.tdCache.Get(hash); ok {
|
||||||
return cached.(*big.Int)
|
return cached
|
||||||
}
|
}
|
||||||
td := GetTd(hc.chainDb, hash, number)
|
td := GetTd(hc.chainDb, hash, number)
|
||||||
if td == nil {
|
if td == nil {
|
||||||
|
|
@ -344,7 +340,7 @@ func (hc *HeaderChain) WriteTd(hash common.Hash, number uint64, td *big.Int) err
|
||||||
func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header {
|
func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header {
|
||||||
// Short circuit if the header's already in the cache, retrieve otherwise
|
// Short circuit if the header's already in the cache, retrieve otherwise
|
||||||
if header, ok := hc.headerCache.Get(hash); ok {
|
if header, ok := hc.headerCache.Get(hash); ok {
|
||||||
return header.(*types.Header)
|
return header
|
||||||
}
|
}
|
||||||
header := GetHeader(hc.chainDb, hash, number)
|
header := GetHeader(hc.chainDb, hash, number)
|
||||||
if header == nil {
|
if header == nil {
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/trie"
|
"github.com/XinFinOrg/XDPoSChain/trie"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -107,16 +107,15 @@ func NewDatabase(db ethdb.Database) Database {
|
||||||
// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
|
// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
|
||||||
// large memory cache.
|
// large memory cache.
|
||||||
func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
|
func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
|
||||||
csc, _ := lru.New(codeSizeCacheSize)
|
|
||||||
return &cachingDB{
|
return &cachingDB{
|
||||||
db: trie.NewDatabaseWithCache(db, cache),
|
db: trie.NewDatabaseWithCache(db, cache),
|
||||||
codeSizeCache: csc,
|
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type cachingDB struct {
|
type cachingDB struct {
|
||||||
db *trie.Database
|
db *trie.Database
|
||||||
codeSizeCache *lru.Cache
|
codeSizeCache *lru.Cache[common.Hash, int]
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenTrie opens the main account trie at a specific root hash.
|
// OpenTrie opens the main account trie at a specific root hash.
|
||||||
|
|
@ -151,7 +150,7 @@ func (db *cachingDB) ContractCode(addrHash, codeHash common.Hash) ([]byte, error
|
||||||
// ContractCodeSize retrieves a particular contracts code's size.
|
// ContractCodeSize retrieves a particular contracts code's size.
|
||||||
func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, error) {
|
func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, error) {
|
||||||
if cached, ok := db.codeSizeCache.Get(codeHash); ok {
|
if cached, ok := db.codeSizeCache.Get(codeHash); ok {
|
||||||
return cached.(int), nil
|
return cached, nil
|
||||||
}
|
}
|
||||||
code, err := db.ContractCode(addrHash, codeHash)
|
code, err := db.ContractCode(addrHash, codeHash)
|
||||||
return len(code), err
|
return len(code), err
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue