From 15ef4faf117bdb672f4b0786598f302aca17f1d8 Mon Sep 17 00:00:00 2001 From: Bui Quang Minh Date: Thu, 11 Jan 2024 16:34:53 +0700 Subject: [PATCH] eth/filters: reduce database read when handling eth_getLogs While profiling, we see that when bloom filter hits, 1/3 CPU time in check log match routine is used to get the corresponding block number from block hash. This is redundant as this information is available already and can be passed via function argument. This commit adds block number parameter to GetLogs interface to pass the available block number information. --- accounts/abi/bind/backends/simulated.go | 8 ++------ eth/api_backend.go | 8 ++------ eth/filters/filter.go | 4 ++-- eth/filters/filter_system.go | 2 +- eth/filters/filter_system_test.go | 8 ++------ internal/ethapi/api_test.go | 2 +- internal/ethapi/backend.go | 2 +- les/api_backend.go | 7 ++----- 8 files changed, 13 insertions(+), 28 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 999365734c..80da901b88 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -847,12 +847,8 @@ func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (typ return rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config()), nil } -func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - number := rawdb.ReadHeaderNumber(fb.db, hash) - if number == nil { - return nil, nil - } - receipts := rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config()) +func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash, blockNumber uint64) ([][]*types.Log, error) { + receipts := rawdb.ReadReceipts(fb.db, hash, blockNumber, fb.bc.Config()) if receipts == nil { return nil, nil } diff --git a/eth/api_backend.go b/eth/api_backend.go index 93637e7c17..5c27561ffd 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -227,13 +227,9 @@ func (b *EthAPIBackend) BlobSidecarsByNumberOrHash(ctx context.Context, blockNrO return nil, errors.New("invalid arguments: neither block number nor block hash hash specified") } -func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { +func (b *EthAPIBackend) GetLogs(ctx context.Context, hash common.Hash, blockNumber uint64) ([][]*types.Log, error) { db := b.eth.ChainDb() - number := rawdb.ReadHeaderNumber(db, hash) - if number == nil { - return nil, errors.New("failed to get block number from hash") - } - logs := rawdb.ReadLogs(db, hash, *number, b.eth.blockchain.Config()) + logs := rawdb.ReadLogs(db, hash, blockNumber, b.eth.blockchain.Config()) if logs == nil { return nil, errors.New("failed to get logs for block") } diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 327622e9f9..f1bf5ebad3 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -39,7 +39,7 @@ type Backend interface { HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) - GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) + GetLogs(ctx context.Context, blockHash common.Hash, blockNumber uint64) ([][]*types.Log, error) SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription @@ -271,7 +271,7 @@ func (f *Filter) blockLogs(ctx context.Context, header *types.Header) (logs []*t // match the filter criteria. This function is called when the bloom filter signals a potential match. func (f *Filter) checkMatches(ctx context.Context, header *types.Header) (logs []*types.Log, err error) { // Get the logs of the block - logsList, err := f.backend.GetLogs(ctx, header.Hash()) + logsList, err := f.backend.GetLogs(ctx, header.Hash(), header.Number.Uint64()) if err != nil { return nil, err } diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 9017cbd856..850abae900 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -445,7 +445,7 @@ func (es *EventSystem) lightFilterLogs(header *types.Header, addresses []common. // Get the logs of the block ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() - logsList, err := es.backend.GetLogs(ctx, header.Hash()) + logsList, err := es.backend.GetLogs(ctx, header.Hash(), header.Number.Uint64()) if err != nil { return nil } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index d30c9f9592..196d6193c7 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -93,12 +93,8 @@ func (b *testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types. return nil, nil } -func (b *testBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - number := rawdb.ReadHeaderNumber(b.db, hash) - if number == nil { - return nil, nil - } - receipts := rawdb.ReadReceipts(b.db, hash, *number, params.TestChainConfig) +func (b *testBackend) GetLogs(ctx context.Context, hash common.Hash, blockNumber uint64) ([][]*types.Log, error) { + receipts := rawdb.ReadReceipts(b.db, hash, blockNumber, params.TestChainConfig) logs := make([][]*types.Log, len(receipts)) for i, receipt := range receipts { diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index e4226fb304..ee295a9dd3 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -595,7 +595,7 @@ func (b testBackend) SubscribeNewTxsEvent(events chan<- core.NewTxsEvent) event. } func (b testBackend) ChainConfig() *params.ChainConfig { return b.chain.Config() } func (b testBackend) Engine() consensus.Engine { return b.chain.Engine() } -func (b testBackend) GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) { +func (b testBackend) GetLogs(ctx context.Context, blockHash common.Hash, blockNumber uint64) ([][]*types.Log, error) { panic("implement me") } func (b testBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index bb9d564be1..6df74a4f34 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -90,7 +90,7 @@ type Backend interface { // Filter API BloomStatus() (uint64, uint64) - GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) + GetLogs(ctx context.Context, blockHash common.Hash, blockNumber uint64) ([][]*types.Log, error) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription diff --git a/les/api_backend.go b/les/api_backend.go index 00091b434a..a2b5e60737 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -182,11 +182,8 @@ func (b *LesApiBackend) BlobSidecarsByNumberOrHash(ctx context.Context, blockNrO return nil, nil } -func (b *LesApiBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) { - if number := rawdb.ReadHeaderNumber(b.eth.chainDb, hash); number != nil { - return light.GetBlockLogs(ctx, b.eth.odr, hash, *number) - } - return nil, nil +func (b *LesApiBackend) GetLogs(ctx context.Context, hash common.Hash, blockNumber uint64) ([][]*types.Log, error) { + return light.GetBlockLogs(ctx, b.eth.odr, hash, blockNumber) } func (b *LesApiBackend) GetTd(ctx context.Context, hash common.Hash) *big.Int {