From 3b50e5a62ea3501168b390eec5e6ef306a2df08e Mon Sep 17 00:00:00 2001 From: Sina Mahmoodi Date: Wed, 9 Apr 2025 16:14:22 +0200 Subject: [PATCH] use cache, raw getters --- core/rawdb/eradb/eradb.go | 98 ++++++++++++++++++++++++++++------ core/rawdb/eradb/eradb_test.go | 16 +++++- 2 files changed, 96 insertions(+), 18 deletions(-) diff --git a/core/rawdb/eradb/eradb.go b/core/rawdb/eradb/eradb.go index 78f12d629d..60c8898585 100644 --- a/core/rawdb/eradb/eradb.go +++ b/core/rawdb/eradb/eradb.go @@ -31,7 +31,8 @@ import ( type EraDatabase struct { datadir string network string - cache *lru.Cache[uint64, *era.Era] + // TODO: should take into account configured number of fd handles. + cache *lru.Cache[uint64, *era.Era] } // New creates a new EraDatabase instance. @@ -70,23 +71,10 @@ func (db *EraDatabase) openEra(name string) (*era.Era, error) { return e, nil } -func (db *EraDatabase) Close() { - // Close all open era1 files in the cache. - keys := db.cache.Keys() - for _, key := range keys { - if e, ok := db.cache.Get(key); ok { - e.Close() - } - } -} - -func (db *EraDatabase) GetBlockByNumber(number uint64) (*types.Block, error) { - // Lookup the table by epoch. - epoch := number / uint64(era.MaxEra1Size) +func (db *EraDatabase) getEraByEpoch(epoch uint64) (*era.Era, error) { // Check the cache first. if e, ok := db.cache.Get(epoch); ok { - fmt.Printf("Cache hit for epoch %d\n", epoch) - return e.GetBlockByNumber(number) + return e, nil } // file name scheme is --. glob := fmt.Sprintf("%s-%05d-*.era1", db.network, epoch) @@ -107,6 +95,84 @@ func (db *EraDatabase) GetBlockByNumber(number uint64) (*types.Block, error) { } // Add the era to the cache. db.cache.Add(epoch, e) + return e, nil +} +func (db *EraDatabase) Close() { + // Close all open era1 files in the cache. + keys := db.cache.Keys() + for _, key := range keys { + if e, ok := db.cache.Get(key); ok { + e.Close() + } + } +} + +// TODO: do we need this method? we do have headers in the freezer. +func (db *EraDatabase) GetHeaderByNumber(number uint64) (*types.Header, error) { + // Lookup the table by epoch. + epoch := number / uint64(era.MaxEra1Size) + e, err := db.getEraByEpoch(epoch) + if err != nil { + return nil, err + } + // The era1 file for given epoch may not exist. + if e == nil { + return nil, nil + } + return e.GetHeaderByNumber(number) +} + +func (db *EraDatabase) GetRawBody(number uint64) ([]byte, error) { + // Lookup the table by epoch. + epoch := number / uint64(era.MaxEra1Size) + e, err := db.getEraByEpoch(epoch) + if err != nil { + return nil, err + } + // The era1 file for given epoch may not exist. + if e == nil { + return nil, nil + } + return e.GetRawBodyByNumber(number) +} + +func (db *EraDatabase) GetRawReceipts(number uint64) ([]byte, error) { + epoch := number / uint64(era.MaxEra1Size) + e, err := db.getEraByEpoch(epoch) + if err != nil { + return nil, err + } + // The era1 file for given epoch may not exist. + if e == nil { + return nil, nil + } + return e.GetRawReceiptsByNumber(number) +} + +func (db *EraDatabase) GetBlockByNumber(number uint64) (*types.Block, error) { + // Lookup the table by epoch. + epoch := number / uint64(era.MaxEra1Size) + e, err := db.getEraByEpoch(epoch) + if err != nil { + return nil, err + } + // The era1 file for given epoch may not exist. + if e == nil { + return nil, nil + } return e.GetBlockByNumber(number) } + +func (db *EraDatabase) GetReceiptsByNumber(number uint64) (types.Receipts, error) { + epoch := number / uint64(era.MaxEra1Size) + e, err := db.getEraByEpoch(epoch) + if err != nil { + return nil, err + } + // The era1 file for given epoch may not exist. + if e == nil { + return nil, nil + } + return e.GetReceiptsByNumber(number) +} diff --git a/core/rawdb/eradb/eradb_test.go b/core/rawdb/eradb/eradb_test.go index c6c8993b86..7163f06cea 100644 --- a/core/rawdb/eradb/eradb_test.go +++ b/core/rawdb/eradb/eradb_test.go @@ -22,14 +22,26 @@ import ( "github.com/stretchr/testify/require" ) -func TestEraDatabase_Scan(t *testing.T) { +func TestEraDatabase(t *testing.T) { // Create the database db, err := New("testdata", "sepolia") require.NoError(t, err) + defer db.Close() block, err := db.GetBlockByNumber(15000) require.NoError(t, err) require.NotNil(t, block, "block not found") - defer db.Close() require.Equal(t, uint64(15000), block.NumberU64()) + + // Get Header + header, err := db.GetHeaderByNumber(15000) + require.NoError(t, err) + require.NotNil(t, header, "header not found") + require.Equal(t, uint64(15000), header.Number.Uint64()) + + // Get Receipts + receipts, err := db.GetReceiptsByNumber(15000) + require.NoError(t, err) + require.NotNil(t, receipts, "receipts not found") + require.Equal(t, 0, len(receipts), "receipts length mismatch") }