use cache, raw getters

This commit is contained in:
Sina Mahmoodi 2025-04-09 16:14:22 +02:00 committed by lightclient
parent a474c1cdd7
commit 3b50e5a62e
No known key found for this signature in database
GPG key ID: 657913021EF45A6A
2 changed files with 96 additions and 18 deletions

View file

@ -31,6 +31,7 @@ import (
type EraDatabase struct { type EraDatabase struct {
datadir string datadir string
network string network string
// TODO: should take into account configured number of fd handles.
cache *lru.Cache[uint64, *era.Era] cache *lru.Cache[uint64, *era.Era]
} }
@ -70,23 +71,10 @@ func (db *EraDatabase) openEra(name string) (*era.Era, error) {
return e, nil return e, nil
} }
func (db *EraDatabase) Close() { func (db *EraDatabase) getEraByEpoch(epoch uint64) (*era.Era, error) {
// 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)
// Check the cache first. // Check the cache first.
if e, ok := db.cache.Get(epoch); ok { if e, ok := db.cache.Get(epoch); ok {
fmt.Printf("Cache hit for epoch %d\n", epoch) return e, nil
return e.GetBlockByNumber(number)
} }
// file name scheme is <network>-<epoch>-<root>. // file name scheme is <network>-<epoch>-<root>.
glob := fmt.Sprintf("%s-%05d-*.era1", db.network, epoch) 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. // Add the era to the cache.
db.cache.Add(epoch, e) 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) 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)
}

View file

@ -22,14 +22,26 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestEraDatabase_Scan(t *testing.T) { func TestEraDatabase(t *testing.T) {
// Create the database // Create the database
db, err := New("testdata", "sepolia") db, err := New("testdata", "sepolia")
require.NoError(t, err) require.NoError(t, err)
defer db.Close()
block, err := db.GetBlockByNumber(15000) block, err := db.GetBlockByNumber(15000)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, block, "block not found") require.NotNil(t, block, "block not found")
defer db.Close()
require.Equal(t, uint64(15000), block.NumberU64()) 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")
} }