mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-16 17:03:46 +00:00
core: optimize HasBlock check
This avoids a random database read to get the number.
This commit is contained in:
parent
9956e2a2ca
commit
d4486f0cb0
6 changed files with 19 additions and 11 deletions
|
|
@ -164,7 +164,7 @@ func ImportChain(chain *core.BlockChain, fn string) error {
|
|||
|
||||
func hasAllBlocks(chain *core.BlockChain, bs []*types.Block) bool {
|
||||
for _, b := range bs {
|
||||
if !chain.HasBlock(b.Hash()) {
|
||||
if !chain.HasBlock(b.Hash(), b.NumberU64()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -516,8 +516,12 @@ func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
|
|||
|
||||
// HasBlock checks if a block is fully present in the database or not, caching
|
||||
// it if present.
|
||||
func (bc *BlockChain) HasBlock(hash common.Hash) bool {
|
||||
return bc.GetBlockByHash(hash) != nil
|
||||
func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
|
||||
if bc.blockCache.Contains(hash) {
|
||||
return true
|
||||
}
|
||||
ok, _ := bc.chainDb.Has(blockBodyKey(hash, number))
|
||||
return ok
|
||||
}
|
||||
|
||||
// HasBlockAndState checks if a block and associated state trie is fully present
|
||||
|
|
@ -723,7 +727,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
|
|||
return i, fmt.Errorf("containing header #%d [%x…] unknown", block.Number(), block.Hash().Bytes()[:4])
|
||||
}
|
||||
// Skip if the entire data is already known
|
||||
if bc.HasBlock(block.Hash()) {
|
||||
if bc.HasBlock(block.Hash(), block.NumberU64()) {
|
||||
stats.ignored++
|
||||
continue
|
||||
}
|
||||
|
|
@ -793,7 +797,7 @@ func (bc *BlockChain) WriteBlock(block *types.Block) (status WriteStatus, err er
|
|||
bc.mu.Lock()
|
||||
defer bc.mu.Unlock()
|
||||
|
||||
if bc.HasBlock(block.Hash()) {
|
||||
if bc.HasBlock(block.Hash(), block.NumberU64()) {
|
||||
log.Trace("Block existed", "hash", block.Hash())
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ func GetHeader(db DatabaseReader, hash common.Hash, number uint64) *types.Header
|
|||
|
||||
// GetBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
|
||||
func GetBodyRLP(db DatabaseReader, hash common.Hash, number uint64) rlp.RawValue {
|
||||
data, _ := db.Get(append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...))
|
||||
data, _ := db.Get(blockBodyKey(hash, number))
|
||||
return data
|
||||
}
|
||||
|
||||
|
|
@ -178,6 +178,10 @@ func headerKey(hash common.Hash, number uint64) []byte {
|
|||
return append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
|
||||
}
|
||||
|
||||
func blockBodyKey(hash common.Hash, number uint64) []byte {
|
||||
return append(append(bodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
|
||||
}
|
||||
|
||||
// GetBody retrieves the block body (transactons, uncles) corresponding to the
|
||||
// hash, nil if none found.
|
||||
func GetBody(db DatabaseReader, hash common.Hash, number uint64) *types.Body {
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ func (api *PrivateAdminAPI) ExportChain(file string) (bool, error) {
|
|||
|
||||
func hasAllBlocks(chain *core.BlockChain, bs []*types.Block) bool {
|
||||
for _, b := range bs {
|
||||
if !chain.HasBlock(b.Hash()) {
|
||||
if !chain.HasBlock(b.Hash(), b.NumberU64()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -609,7 +609,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
|||
// Schedule all the unknown hashes for retrieval
|
||||
unknown := make(newBlockHashesData, 0, len(announces))
|
||||
for _, block := range announces {
|
||||
if !pm.blockchain.HasBlock(block.Hash) {
|
||||
if !pm.blockchain.HasBlock(block.Hash, block.Number) {
|
||||
unknown = append(unknown, block)
|
||||
}
|
||||
}
|
||||
|
|
@ -699,7 +699,7 @@ func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) {
|
|||
return
|
||||
}
|
||||
// Otherwise if the block is indeed in out own chain, announce it
|
||||
if pm.blockchain.HasBlock(hash) {
|
||||
if pm.blockchain.HasBlock(hash, block.NumberU64()) {
|
||||
for _, peer := range peers {
|
||||
peer.SendNewBlockHashes([]common.Hash{hash}, []uint64{block.NumberU64()})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,8 +252,8 @@ func (self *LightChain) GetBodyRLP(ctx context.Context, hash common.Hash) (rlp.R
|
|||
|
||||
// HasBlock checks if a block is fully present in the database or not, caching
|
||||
// it if present.
|
||||
func (bc *LightChain) HasBlock(hash common.Hash) bool {
|
||||
blk, _ := bc.GetBlockByHash(NoOdr, hash)
|
||||
func (bc *LightChain) HasBlock(hash common.Hash, number uint64) bool {
|
||||
blk, _ := bc.GetBlock(NoOdr, hash, number)
|
||||
return blk != nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue