rawdb: return boolean

This commit is contained in:
MariusVanDerWijden 2025-05-29 12:04:12 +02:00
parent 33d97e6054
commit c663115ff1
11 changed files with 66 additions and 48 deletions

View file

@ -578,7 +578,7 @@ 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 != rawdb.EmptyNumber { if number, ok := rawdb.ReadHeaderNumber(db, hash); ok {
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)

View file

@ -88,7 +88,7 @@ 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 {
if num := bc.hc.GetBlockNumber(hash); num != rawdb.EmptyNumber { if num, ok := bc.hc.GetBlockNumber(hash); ok {
return &num return &num
} }
return nil return nil
@ -107,8 +107,8 @@ func (bc *BlockChain) GetBody(hash common.Hash) *types.Body {
if cached, ok := bc.bodyCache.Get(hash); ok { if cached, ok := bc.bodyCache.Get(hash); ok {
return cached return cached
} }
number := bc.hc.GetBlockNumber(hash) number, ok := bc.hc.GetBlockNumber(hash)
if number == rawdb.EmptyNumber { if !ok {
return nil return nil
} }
body := rawdb.ReadBody(bc.db, hash, number) body := rawdb.ReadBody(bc.db, hash, number)
@ -127,8 +127,8 @@ func (bc *BlockChain) GetBodyRLP(hash common.Hash) rlp.RawValue {
if cached, ok := bc.bodyRLPCache.Get(hash); ok { if cached, ok := bc.bodyRLPCache.Get(hash); ok {
return cached return cached
} }
number := bc.hc.GetBlockNumber(hash) number, ok := bc.hc.GetBlockNumber(hash)
if number == rawdb.EmptyNumber { if !ok {
return nil return nil
} }
body := rawdb.ReadBodyRLP(bc.db, hash, number) body := rawdb.ReadBodyRLP(bc.db, hash, number)
@ -180,8 +180,8 @@ 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, ok := bc.hc.GetBlockNumber(hash)
if number == rawdb.EmptyNumber { if !ok {
return nil return nil
} }
return bc.GetBlock(hash, number) return bc.GetBlock(hash, number)
@ -200,8 +200,8 @@ func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block {
// GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors. // GetBlocksFromHash returns the block corresponding to hash and up to n-1 ancestors.
// [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, ok := bc.hc.GetBlockNumber(hash)
if number == rawdb.EmptyNumber { if !ok {
return nil return nil
} }
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
@ -221,8 +221,8 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
if receipts, ok := bc.receiptsCache.Get(hash); ok { if receipts, ok := bc.receiptsCache.Get(hash); ok {
return receipts return receipts
} }
number := rawdb.ReadHeaderNumber(bc.db, hash) number, ok := rawdb.ReadHeaderNumber(bc.db, hash)
if number == rawdb.EmptyNumber { if !ok {
return nil return nil
} }
header := bc.GetHeader(hash, number) header := bc.GetHeader(hash, number)
@ -248,8 +248,8 @@ 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, ok := rawdb.ReadHeaderNumber(bc.db, hash)
if number == rawdb.EmptyNumber { if !ok {
return nil return nil
} }
return rawdb.ReadReceiptsRLP(bc.db, hash, number) return rawdb.ReadReceiptsRLP(bc.db, hash, number)

View file

@ -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 == rawdb.EmptyNumber || m != num { if m, ok := rawdb.ReadHeaderNumber(fastDb, hash); !ok || 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 == rawdb.EmptyNumber || m != num { if m, ok := rawdb.ReadHeaderNumber(ancientDb, hash); !ok || 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 == rawdb.EmptyNumber || m != num { if m, ok := rawdb.ReadHeaderNumber(archiveDb, hash); !ok || 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)
} }
} }

View file

@ -97,15 +97,15 @@ 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, bool) {
if cached, ok := hc.numberCache.Get(hash); ok { if cached, ok := hc.numberCache.Get(hash); ok {
return cached return cached, true
} }
number := rawdb.ReadHeaderNumber(hc.chainDb, hash) number, ok := rawdb.ReadHeaderNumber(hc.chainDb, hash)
if number != rawdb.EmptyNumber { if ok {
hc.numberCache.Add(hash, number) hc.numberCache.Add(hash, number)
} }
return number return number, ok
} }
type headerWriteResult struct { type headerWriteResult struct {
@ -402,8 +402,8 @@ func (hc *HeaderChain) GetHeader(hash common.Hash, number uint64) *types.Header
// GetHeaderByHash retrieves a block header from the database by hash, caching it if // GetHeaderByHash retrieves a block header from the database by hash, caching it if
// 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, ok := hc.GetBlockNumber(hash)
if number == rawdb.EmptyNumber { if !ok {
return nil return nil
} }
return hc.GetHeader(hash, number) return hc.GetHeader(hash, number)

View file

@ -142,16 +142,14 @@ 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, bool) {
data, _ := db.Get(headerNumberKey(hash)) data, _ := db.Get(headerNumberKey(hash))
if len(data) != 8 { if len(data) != 8 {
return EmptyNumber return 0, false
} }
number := binary.BigEndian.Uint64(data) number := binary.BigEndian.Uint64(data)
return number return number, true
} }
// WriteHeaderNumber stores the hash->number mapping. // WriteHeaderNumber stores the hash->number mapping.
@ -909,8 +907,8 @@ func ReadHeadHeader(db ethdb.Reader) *types.Header {
if headHeaderHash == (common.Hash{}) { if headHeaderHash == (common.Hash{}) {
return nil return nil
} }
headHeaderNumber := ReadHeaderNumber(db, headHeaderHash) headHeaderNumber, ok := ReadHeaderNumber(db, headHeaderHash)
if headHeaderNumber == EmptyNumber { if !ok {
return nil return nil
} }
return ReadHeader(db, headHeaderHash, headHeaderNumber) return ReadHeader(db, headHeaderHash, headHeaderNumber)
@ -922,8 +920,8 @@ func ReadHeadBlock(db ethdb.Reader) *types.Block {
if headBlockHash == (common.Hash{}) { if headBlockHash == (common.Hash{}) {
return nil return nil
} }
headBlockNumber := ReadHeaderNumber(db, headBlockHash) headBlockNumber, ok := ReadHeaderNumber(db, headBlockHash)
if headBlockNumber == EmptyNumber { if !ok {
return nil return nil
} }
return ReadBlock(db, headBlockHash, headBlockNumber) return ReadBlock(db, headBlockHash, headBlockNumber)

View file

@ -39,7 +39,10 @@ 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 {
number := ReadHeaderNumber(db, common.BytesToHash(data)) number, ok := ReadHeaderNumber(db, common.BytesToHash(data))
if !ok {
return nil
}
return &number return &number
} }
// Finally try database v3 tx lookup format // Finally try database v3 tx lookup format

View file

@ -95,8 +95,8 @@ func (f *chainFreezer) readHeadNumber(db ethdb.KeyValueReader) uint64 {
log.Error("Head block is not reachable") log.Error("Head block is not reachable")
return 0 return 0
} }
number := ReadHeaderNumber(db, hash) number, ok := ReadHeaderNumber(db, hash)
if number == EmptyNumber { if !ok {
log.Error("Number of head block is missing") log.Error("Number of head block is missing")
return 0 return 0
} }
@ -110,8 +110,8 @@ func (f *chainFreezer) readFinalizedNumber(db ethdb.KeyValueReader) uint64 {
if hash == (common.Hash{}) { if hash == (common.Hash{}) {
return 0 return 0
} }
number := ReadHeaderNumber(db, hash) number, ok := ReadHeaderNumber(db, hash)
if number == EmptyNumber { if !ok {
log.Error("Number of finalized block is missing") log.Error("Number of finalized block is missing")
return 0 return 0
} }

View file

@ -243,7 +243,12 @@ 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 { head, ok := ReadHeaderNumber(db, ReadHeadHeaderHash(db))
if !ok {
printChainMetadata(db)
return nil, fmt.Errorf("could not read header number, hash %v", ReadHeadHeaderHash(db))
}
if 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

View file

@ -217,8 +217,8 @@ func (indexer *txIndexer) resolveHead() uint64 {
if headBlockHash == (common.Hash{}) { if headBlockHash == (common.Hash{}) {
return 0 return 0
} }
headBlockNumber := rawdb.ReadHeaderNumber(indexer.db, headBlockHash) headBlockNumber, ok := rawdb.ReadHeaderNumber(indexer.db, headBlockHash)
if headBlockNumber == rawdb.EmptyNumber { if !ok {
return 0 return 0
} }
return headBlockNumber return headBlockNumber

View file

@ -92,15 +92,15 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumbe
switch blockNr { switch blockNr {
case rpc.LatestBlockNumber: case rpc.LatestBlockNumber:
hash = rawdb.ReadHeadBlockHash(b.db) hash = rawdb.ReadHeadBlockHash(b.db)
number := rawdb.ReadHeaderNumber(b.db, hash) number, ok := rawdb.ReadHeaderNumber(b.db, hash)
if number == rawdb.EmptyNumber { if !ok {
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, ok := rawdb.ReadHeaderNumber(b.db, hash)
if number == rawdb.EmptyNumber { if !ok {
return nil, nil return nil, nil
} }
num = number num = number
@ -114,8 +114,8 @@ 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, ok := rawdb.ReadHeaderNumber(b.db, hash)
if number == rawdb.EmptyNumber { if !ok {
return nil, nil return nil, nil
} }
return rawdb.ReadHeader(b.db, hash, number), nil return rawdb.ReadHeader(b.db, hash, number), nil
@ -129,7 +129,7 @@ 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 != rawdb.EmptyNumber { if number, ok := rawdb.ReadHeaderNumber(b.db, hash); ok {
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
} }

View file

@ -76,6 +76,18 @@ func BenchmarkTraceLogging(b *testing.B) {
} }
} }
func BenchmarkVmodule(b *testing.B) {
out := new(bytes.Buffer)
glog := NewGlogHandler(NewTerminalHandlerWithLevel(out, LevelTrace, false))
glog.Verbosity(LevelCrit)
logger := NewLogger(glog)
glog.Vmodule("logger_test.go=5")
for i := 0; i < b.N; i++ {
logger.Warn("This should not be seen", "ignored", "true")
logger.Trace("a message", "foo", "bar")
}
}
func BenchmarkTerminalHandler(b *testing.B) { func BenchmarkTerminalHandler(b *testing.B) {
l := NewLogger(NewTerminalHandler(io.Discard, false)) l := NewLogger(NewTerminalHandler(io.Discard, false))
benchmarkLogger(b, l) benchmarkLogger(b, l)