mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
core/rawdb: reduce allocations in rawdb.ReadHeaderNumber
This commit is contained in:
parent
3f7b8bc976
commit
33d97e6054
10 changed files with 56 additions and 50 deletions
|
|
@ -578,8 +578,8 @@ func parseDumpConfig(ctx *cli.Context, db ethdb.Database) (*state.DumpConfig, co
|
||||||
arg := ctx.Args().First()
|
arg := ctx.Args().First()
|
||||||
if hashish(arg) {
|
if hashish(arg) {
|
||||||
hash := common.HexToHash(arg)
|
hash := common.HexToHash(arg)
|
||||||
if number := rawdb.ReadHeaderNumber(db, hash); number != nil {
|
if number := rawdb.ReadHeaderNumber(db, hash); number != rawdb.EmptyNumber {
|
||||||
header = rawdb.ReadHeader(db, hash, *number)
|
header = rawdb.ReadHeader(db, hash, number)
|
||||||
} else {
|
} else {
|
||||||
return nil, common.Hash{}, fmt.Errorf("block %x not found", hash)
|
return nil, common.Hash{}, fmt.Errorf("block %x not found", hash)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,10 @@ func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
|
||||||
|
|
||||||
// GetBlockNumber retrieves the block number associated with a block hash.
|
// GetBlockNumber retrieves the block number associated with a block hash.
|
||||||
func (bc *BlockChain) GetBlockNumber(hash common.Hash) *uint64 {
|
func (bc *BlockChain) GetBlockNumber(hash common.Hash) *uint64 {
|
||||||
return bc.hc.GetBlockNumber(hash)
|
if num := bc.hc.GetBlockNumber(hash); num != rawdb.EmptyNumber {
|
||||||
|
return &num
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHeadersFrom returns a contiguous segment of headers, in rlp-form, going
|
// GetHeadersFrom returns a contiguous segment of headers, in rlp-form, going
|
||||||
|
|
@ -105,10 +108,10 @@ func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
|
||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
number := bc.hc.GetBlockNumber(hash)
|
number := bc.hc.GetBlockNumber(hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
body := rawdb.ReadBody(bc.db, hash, *number)
|
body := rawdb.ReadBody(bc.db, hash, number)
|
||||||
if body == nil {
|
if body == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -125,10 +128,10 @@ func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
|
||||||
return cached
|
return cached
|
||||||
}
|
}
|
||||||
number := bc.hc.GetBlockNumber(hash)
|
number := bc.hc.GetBlockNumber(hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
body := rawdb.ReadBodyRLP(bc.db, hash, *number)
|
body := rawdb.ReadBodyRLP(bc.db, hash, number)
|
||||||
if len(body) == 0 {
|
if len(body) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -178,10 +181,10 @@ func (bc *BlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
|
||||||
// GetBlockByHash retrieves a block from the database by hash, caching it if found.
|
// GetBlockByHash retrieves a block from the database by hash, caching it if found.
|
||||||
func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
|
func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
|
||||||
number := bc.hc.GetBlockNumber(hash)
|
number := bc.hc.GetBlockNumber(hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return bc.GetBlock(hash, *number)
|
return bc.GetBlock(hash, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockByNumber retrieves a block from the database by number, caching it
|
// GetBlockByNumber retrieves a block from the database by number, caching it
|
||||||
|
|
@ -198,17 +201,17 @@ func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
|
||||||
// [deprecated by eth/62]
|
// [deprecated by eth/62]
|
||||||
func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
|
func (bc *BlockChain) GetBlocksFromHash(hash common.Hash, n int) (blocks []*types.Block) {
|
||||||
number := bc.hc.GetBlockNumber(hash)
|
number := bc.hc.GetBlockNumber(hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
block := bc.GetBlock(hash, *number)
|
block := bc.GetBlock(hash, number)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
blocks = append(blocks, block)
|
blocks = append(blocks, block)
|
||||||
hash = block.ParentHash()
|
hash = block.ParentHash()
|
||||||
*number--
|
number--
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -219,14 +222,14 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
|
||||||
return receipts
|
return receipts
|
||||||
}
|
}
|
||||||
number := rawdb.ReadHeaderNumber(bc.db, hash)
|
number := rawdb.ReadHeaderNumber(bc.db, hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
header := bc.GetHeader(hash, *number)
|
header := bc.GetHeader(hash, number)
|
||||||
if header == nil {
|
if header == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
receipts := rawdb.ReadReceipts(bc.db, hash, *number, header.Time, bc.chainConfig)
|
receipts := rawdb.ReadReceipts(bc.db, hash, number, header.Time, bc.chainConfig)
|
||||||
if receipts == nil {
|
if receipts == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -246,10 +249,10 @@ func (bc *BlockChain) GetRawReceipts(hash common.Hash, number uint64) types.Rece
|
||||||
// GetReceiptsRLP retrieves the receipts of a block.
|
// GetReceiptsRLP retrieves the receipts of a block.
|
||||||
func (bc *BlockChain) GetReceiptsRLP(hash common.Hash) rlp.RawValue {
|
func (bc *BlockChain) GetReceiptsRLP(hash common.Hash) rlp.RawValue {
|
||||||
number := rawdb.ReadHeaderNumber(bc.db, hash)
|
number := rawdb.ReadHeaderNumber(bc.db, hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return rawdb.ReadReceiptsRLP(bc.db, hash, *number)
|
return rawdb.ReadReceiptsRLP(bc.db, hash, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUnclesInChain retrieves all the uncles from a given block backwards until
|
// GetUnclesInChain retrieves all the uncles from a given block backwards until
|
||||||
|
|
|
||||||
|
|
@ -778,13 +778,13 @@ func testFastVsFullChains(t *testing.T, scheme string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that hash-to-number mappings are present in all databases.
|
// Check that hash-to-number mappings are present in all databases.
|
||||||
if m := rawdb.ReadHeaderNumber(fastDb, hash); m == nil || *m != num {
|
if m := rawdb.ReadHeaderNumber(fastDb, hash); m == rawdb.EmptyNumber || m != num {
|
||||||
t.Errorf("block #%d [%x]: wrong hash-to-number mapping in fastdb: %v", num, hash, m)
|
t.Errorf("block #%d [%x]: wrong hash-to-number mapping in fastdb: %v", num, hash, m)
|
||||||
}
|
}
|
||||||
if m := rawdb.ReadHeaderNumber(ancientDb, hash); m == nil || *m != num {
|
if m := rawdb.ReadHeaderNumber(ancientDb, hash); m == rawdb.EmptyNumber || m != num {
|
||||||
t.Errorf("block #%d [%x]: wrong hash-to-number mapping in ancientdb: %v", num, hash, m)
|
t.Errorf("block #%d [%x]: wrong hash-to-number mapping in ancientdb: %v", num, hash, m)
|
||||||
}
|
}
|
||||||
if m := rawdb.ReadHeaderNumber(archiveDb, hash); m == nil || *m != num {
|
if m := rawdb.ReadHeaderNumber(archiveDb, hash); m == rawdb.EmptyNumber || m != num {
|
||||||
t.Errorf("block #%d [%x]: wrong hash-to-number mapping in archivedb: %v", num, hash, m)
|
t.Errorf("block #%d [%x]: wrong hash-to-number mapping in archivedb: %v", num, hash, m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,13 +97,13 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c
|
||||||
|
|
||||||
// GetBlockNumber retrieves the block number belonging to the given hash
|
// GetBlockNumber retrieves the block number belonging to the given hash
|
||||||
// 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
|
return cached
|
||||||
}
|
}
|
||||||
number := rawdb.ReadHeaderNumber(hc.chainDb, hash)
|
number := rawdb.ReadHeaderNumber(hc.chainDb, hash)
|
||||||
if number != nil {
|
if number != rawdb.EmptyNumber {
|
||||||
hc.numberCache.Add(hash, *number)
|
hc.numberCache.Add(hash, number)
|
||||||
}
|
}
|
||||||
return number
|
return number
|
||||||
}
|
}
|
||||||
|
|
@ -403,10 +403,10 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header
|
||||||
// found.
|
// found.
|
||||||
func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header {
|
func (hc *HeaderChain) GetHeaderByHash(hash common.Hash) *types.Header {
|
||||||
number := hc.GetBlockNumber(hash)
|
number := hc.GetBlockNumber(hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return hc.GetHeader(hash, *number)
|
return hc.GetHeader(hash, number)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasHeader checks if a block header is present in the database or not.
|
// HasHeader checks if a block header is present in the database or not.
|
||||||
|
|
|
||||||
|
|
@ -142,14 +142,16 @@ func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int
|
||||||
return numbers, hashes
|
return numbers, hashes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const EmptyNumber = ^uint64(0)
|
||||||
|
|
||||||
// ReadHeaderNumber returns the header number assigned to a hash.
|
// ReadHeaderNumber returns the header number assigned to a hash.
|
||||||
func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 {
|
func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) uint64 {
|
||||||
data, _ := db.Get(headerNumberKey(hash))
|
data, _ := db.Get(headerNumberKey(hash))
|
||||||
if len(data) != 8 {
|
if len(data) != 8 {
|
||||||
return nil
|
return EmptyNumber
|
||||||
}
|
}
|
||||||
number := binary.BigEndian.Uint64(data)
|
number := binary.BigEndian.Uint64(data)
|
||||||
return &number
|
return number
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteHeaderNumber stores the hash->number mapping.
|
// WriteHeaderNumber stores the hash->number mapping.
|
||||||
|
|
@ -908,10 +910,10 @@ func ReadHeadHeader(db ethdb.Reader) *types.Header {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
headHeaderNumber := ReadHeaderNumber(db, headHeaderHash)
|
headHeaderNumber := ReadHeaderNumber(db, headHeaderHash)
|
||||||
if headHeaderNumber == nil {
|
if headHeaderNumber == EmptyNumber {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return ReadHeader(db, headHeaderHash, *headHeaderNumber)
|
return ReadHeader(db, headHeaderHash, headHeaderNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadHeadBlock returns the current canonical head block.
|
// ReadHeadBlock returns the current canonical head block.
|
||||||
|
|
@ -921,8 +923,8 @@ func ReadHeadBlock(db ethdb.Reader) *types.Block {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
headBlockNumber := ReadHeaderNumber(db, headBlockHash)
|
headBlockNumber := ReadHeaderNumber(db, headBlockHash)
|
||||||
if headBlockNumber == nil {
|
if headBlockNumber == EmptyNumber {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return ReadBlock(db, headBlockHash, *headBlockNumber)
|
return ReadBlock(db, headBlockHash, headBlockNumber)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ func DecodeTxLookupEntry(data []byte, db ethdb.Reader) *uint64 {
|
||||||
}
|
}
|
||||||
// Database v4-v5 tx lookup format just stores the hash
|
// Database v4-v5 tx lookup format just stores the hash
|
||||||
if len(data) == common.HashLength {
|
if len(data) == common.HashLength {
|
||||||
return ReadHeaderNumber(db, common.BytesToHash(data))
|
number := ReadHeaderNumber(db, common.BytesToHash(data))
|
||||||
|
return &number
|
||||||
}
|
}
|
||||||
// Finally try database v3 tx lookup format
|
// Finally try database v3 tx lookup format
|
||||||
var entry LegacyTxLookupEntry
|
var entry LegacyTxLookupEntry
|
||||||
|
|
|
||||||
|
|
@ -96,11 +96,11 @@ func (f *chainFreezer) readHeadNumber(db ethdb.KeyValueReader) uint64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
number := ReadHeaderNumber(db, hash)
|
number := ReadHeaderNumber(db, hash)
|
||||||
if number == nil {
|
if number == EmptyNumber {
|
||||||
log.Error("Number of head block is missing")
|
log.Error("Number of head block is missing")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return *number
|
return number
|
||||||
}
|
}
|
||||||
|
|
||||||
// readFinalizedNumber returns the number of finalized block. 0 is returned
|
// readFinalizedNumber returns the number of finalized block. 0 is returned
|
||||||
|
|
@ -111,11 +111,11 @@ func (f *chainFreezer) readFinalizedNumber(db ethdb.KeyValueReader) uint64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
number := ReadHeaderNumber(db, hash)
|
number := ReadHeaderNumber(db, hash)
|
||||||
if number == nil {
|
if number == EmptyNumber {
|
||||||
log.Error("Number of finalized block is missing")
|
log.Error("Number of finalized block is missing")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return *number
|
return number
|
||||||
}
|
}
|
||||||
|
|
||||||
// freezeThreshold returns the threshold for chain freezing. It's determined
|
// freezeThreshold returns the threshold for chain freezing. It's determined
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, ancient string, namespace st
|
||||||
if kvhash, _ := db.Get(headerHashKey(frozen)); len(kvhash) == 0 {
|
if kvhash, _ := db.Get(headerHashKey(frozen)); len(kvhash) == 0 {
|
||||||
// Subsequent header after the freezer limit is missing from the database.
|
// Subsequent header after the freezer limit is missing from the database.
|
||||||
// Reject startup if the database has a more recent head.
|
// Reject startup if the database has a more recent head.
|
||||||
if head := *ReadHeaderNumber(db, ReadHeadHeaderHash(db)); head > frozen-1 {
|
if head := ReadHeaderNumber(db, ReadHeadHeaderHash(db)); head > frozen-1 {
|
||||||
// Find the smallest block stored in the key-value store
|
// Find the smallest block stored in the key-value store
|
||||||
// in range of [frozen, head]
|
// in range of [frozen, head]
|
||||||
var number uint64
|
var number uint64
|
||||||
|
|
|
||||||
|
|
@ -218,10 +218,10 @@ func (indexer *txIndexer) resolveHead() uint64 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
headBlockNumber := rawdb.ReadHeaderNumber(indexer.db, headBlockHash)
|
headBlockNumber := rawdb.ReadHeaderNumber(indexer.db, headBlockHash)
|
||||||
if headBlockNumber == nil {
|
if headBlockNumber == rawdb.EmptyNumber {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return *headBlockNumber
|
return headBlockNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop is the scheduler of the indexer, assigning indexing/unindexing tasks depending
|
// loop is the scheduler of the indexer, assigning indexing/unindexing tasks depending
|
||||||
|
|
|
||||||
|
|
@ -93,17 +93,17 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumbe
|
||||||
case rpc.LatestBlockNumber:
|
case rpc.LatestBlockNumber:
|
||||||
hash = rawdb.ReadHeadBlockHash(b.db)
|
hash = rawdb.ReadHeadBlockHash(b.db)
|
||||||
number := rawdb.ReadHeaderNumber(b.db, hash)
|
number := rawdb.ReadHeaderNumber(b.db, hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
num = *number
|
num = number
|
||||||
case rpc.FinalizedBlockNumber:
|
case rpc.FinalizedBlockNumber:
|
||||||
hash = rawdb.ReadFinalizedBlockHash(b.db)
|
hash = rawdb.ReadFinalizedBlockHash(b.db)
|
||||||
number := rawdb.ReadHeaderNumber(b.db, hash)
|
number := rawdb.ReadHeaderNumber(b.db, hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
num = *number
|
num = number
|
||||||
case rpc.SafeBlockNumber:
|
case rpc.SafeBlockNumber:
|
||||||
return nil, errors.New("safe block not found")
|
return nil, errors.New("safe block not found")
|
||||||
default:
|
default:
|
||||||
|
|
@ -115,10 +115,10 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumbe
|
||||||
|
|
||||||
func (b *testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
|
func (b *testBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
|
||||||
number := rawdb.ReadHeaderNumber(b.db, hash)
|
number := rawdb.ReadHeaderNumber(b.db, hash)
|
||||||
if number == nil {
|
if number == rawdb.EmptyNumber {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return rawdb.ReadHeader(b.db, hash, *number), nil
|
return rawdb.ReadHeader(b.db, hash, number), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
|
func (b *testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) {
|
||||||
|
|
@ -129,9 +129,9 @@ func (b *testBackend) GetBody(ctx context.Context, hash common.Hash, number rpc.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
|
func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
|
||||||
if number := rawdb.ReadHeaderNumber(b.db, hash); number != nil {
|
if number := rawdb.ReadHeaderNumber(b.db, hash); number != rawdb.EmptyNumber {
|
||||||
if header := rawdb.ReadHeader(b.db, hash, *number); header != nil {
|
if header := rawdb.ReadHeader(b.db, hash, number); header != nil {
|
||||||
return rawdb.ReadReceipts(b.db, hash, *number, header.Time, params.TestChainConfig), nil
|
return rawdb.ReadReceipts(b.db, hash, number, header.Time, params.TestChainConfig), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue