mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-25 13:07:17 +00:00
Fix range for eth_getLogs (#2227)
* Fix range for eth_getLogs * Use Or and measure time * more measurement * more measurement * Not compute tx hashes * Not compute tx hashes * Not compute tx hashes * filter logs before derive fields * Fix filtering by block number * fix Co-authored-by: Alex Sharp <alexsharp@Alexs-MacBook-Pro.local>
This commit is contained in:
parent
6292056503
commit
876dde506f
@ -1,7 +1,9 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
@ -18,6 +20,7 @@ import (
|
||||
"github.com/ledgerwatch/erigon/eth/filters"
|
||||
"github.com/ledgerwatch/erigon/ethdb"
|
||||
"github.com/ledgerwatch/erigon/ethdb/bitmapdb"
|
||||
"github.com/ledgerwatch/erigon/ethdb/cbor"
|
||||
"github.com/ledgerwatch/erigon/params"
|
||||
"github.com/ledgerwatch/erigon/rpc"
|
||||
"github.com/ledgerwatch/erigon/turbo/adapter"
|
||||
@ -80,7 +83,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([
|
||||
return nil, err
|
||||
}
|
||||
|
||||
begin = latest
|
||||
begin = 0
|
||||
if crit.FromBlock != nil && crit.FromBlock.Sign() > 0 {
|
||||
begin = crit.FromBlock.Uint64()
|
||||
}
|
||||
@ -130,30 +133,51 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([
|
||||
return returnLogs(logs), nil
|
||||
}
|
||||
|
||||
cc, err := api.chainConfig(tx)
|
||||
if err != nil {
|
||||
iter := blockNumbers.Iterator()
|
||||
for iter.HasNext() {
|
||||
blockNToMatch := uint64(iter.Next())
|
||||
prefix := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(prefix, blockNToMatch)
|
||||
var logIndex uint
|
||||
var blockLogs types.Logs
|
||||
if err := tx.ForPrefix(dbutils.Log, prefix, func(k, v []byte) error {
|
||||
var logs types.Logs
|
||||
if err := cbor.Unmarshal(&logs, bytes.NewReader(v)); err != nil {
|
||||
return fmt.Errorf("receipt unmarshal failed: %w", err)
|
||||
}
|
||||
for _, log := range logs {
|
||||
log.Index = logIndex
|
||||
logIndex++
|
||||
}
|
||||
filtered := filterLogs(logs, crit.Addresses, crit.Topics)
|
||||
if len(filtered) > 0 {
|
||||
txIndex := uint(binary.BigEndian.Uint32(k[8:]))
|
||||
for _, log := range filtered {
|
||||
log.TxIndex = txIndex
|
||||
}
|
||||
blockLogs = append(blockLogs, filtered...)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return returnLogs(logs), err
|
||||
}
|
||||
for _, blockNToMatch := range blockNumbers.ToArray() {
|
||||
b, senders, err := rawdb.ReadBlockByNumberWithSenders(tx, uint64(blockNToMatch))
|
||||
if len(blockLogs) > 0 {
|
||||
b, err := rawdb.ReadBlockByNumber(tx, blockNToMatch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if b == nil {
|
||||
return nil, fmt.Errorf("block not found %d", uint64(blockNToMatch))
|
||||
return nil, fmt.Errorf("block not found %d", blockNToMatch)
|
||||
}
|
||||
receipts, err := getReceipts(ctx, tx, cc, b, senders)
|
||||
if err != nil {
|
||||
return returnLogs(logs), err
|
||||
blockHash := b.Hash()
|
||||
for _, log := range blockLogs {
|
||||
log.BlockNumber = blockNToMatch
|
||||
log.BlockHash = blockHash
|
||||
log.TxHash = b.Transactions()[log.TxIndex].Hash()
|
||||
}
|
||||
unfiltered := make([]*types.Log, 0, len(receipts))
|
||||
for _, receipt := range receipts {
|
||||
unfiltered = append(unfiltered, receipt.Logs...)
|
||||
logs = append(logs, blockLogs...)
|
||||
}
|
||||
unfiltered = filterLogs(unfiltered, nil, nil, crit.Addresses, crit.Topics)
|
||||
logs = append(logs, unfiltered...)
|
||||
}
|
||||
|
||||
return returnLogs(logs), nil
|
||||
}
|
||||
|
||||
@ -180,7 +204,7 @@ func getTopicsBitmap(c ethdb.Tx, topics [][]common.Hash, from, to uint32) (*roar
|
||||
if bitmapForORing == nil {
|
||||
bitmapForORing = m
|
||||
} else {
|
||||
bitmapForORing = roaring.FastOr(bitmapForORing, m)
|
||||
bitmapForORing.Or(m)
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,16 +351,10 @@ func includes(addresses []common.Address, a common.Address) bool {
|
||||
}
|
||||
|
||||
// filterLogs creates a slice of logs matching the given criteria.
|
||||
func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log {
|
||||
func filterLogs(logs []*types.Log, addresses []common.Address, topics [][]common.Hash) []*types.Log {
|
||||
var ret []*types.Log
|
||||
Logs:
|
||||
for _, log := range logs {
|
||||
if fromBlock != nil && fromBlock.Int64() >= 0 && fromBlock.Uint64() > log.BlockNumber {
|
||||
continue
|
||||
}
|
||||
if toBlock != nil && toBlock.Int64() >= 0 && toBlock.Uint64() < log.BlockNumber {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(addresses) > 0 && !includes(addresses, log.Address) {
|
||||
continue
|
||||
|
Loading…
Reference in New Issue
Block a user