forked from cerc-io/plugeth
eth/filters: fix getLogs for pending block (#24949)
* eth/filters: fix pending for getLogs * add pending method to test backend * fix block range validation
This commit is contained in:
+38
-8
@@ -36,6 +36,7 @@ type Backend interface {
|
||||
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)
|
||||
PendingBlockAndReceipts() (*types.Block, types.Receipts)
|
||||
|
||||
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
|
||||
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
|
||||
@@ -128,26 +129,35 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) {
|
||||
}
|
||||
return f.blockLogs(ctx, header)
|
||||
}
|
||||
// Short-cut if all we care about is pending logs
|
||||
if f.begin == rpc.PendingBlockNumber.Int64() {
|
||||
if f.end != rpc.PendingBlockNumber.Int64() {
|
||||
return nil, errors.New("invalid block range")
|
||||
}
|
||||
return f.pendingLogs()
|
||||
}
|
||||
// Figure out the limits of the filter range
|
||||
header, _ := f.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber)
|
||||
if header == nil {
|
||||
return nil, nil
|
||||
}
|
||||
head := header.Number.Uint64()
|
||||
|
||||
if f.begin == -1 {
|
||||
var (
|
||||
head = header.Number.Uint64()
|
||||
end = uint64(f.end)
|
||||
pending = f.end == rpc.PendingBlockNumber.Int64()
|
||||
)
|
||||
if f.begin == rpc.LatestBlockNumber.Int64() {
|
||||
f.begin = int64(head)
|
||||
}
|
||||
end := uint64(f.end)
|
||||
if f.end == -1 {
|
||||
if f.end == rpc.LatestBlockNumber.Int64() || f.end == rpc.PendingBlockNumber.Int64() {
|
||||
end = head
|
||||
}
|
||||
// Gather all indexed logs, and finish with non indexed ones
|
||||
var (
|
||||
logs []*types.Log
|
||||
err error
|
||||
logs []*types.Log
|
||||
err error
|
||||
size, sections = f.backend.BloomStatus()
|
||||
)
|
||||
size, sections := f.backend.BloomStatus()
|
||||
if indexed := sections * size; indexed > uint64(f.begin) {
|
||||
if indexed > end {
|
||||
logs, err = f.indexedLogs(ctx, end)
|
||||
@@ -160,6 +170,13 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) {
|
||||
}
|
||||
rest, err := f.unindexedLogs(ctx, end)
|
||||
logs = append(logs, rest...)
|
||||
if pending {
|
||||
pendingLogs, err := f.pendingLogs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logs = append(logs, pendingLogs...)
|
||||
}
|
||||
return logs, err
|
||||
}
|
||||
|
||||
@@ -272,6 +289,19 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) (logs [
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// pendingLogs returns the logs matching the filter criteria within the pending block.
|
||||
func (f *Filter) pendingLogs() ([]*types.Log, error) {
|
||||
block, receipts := f.backend.PendingBlockAndReceipts()
|
||||
if bloomFilter(block.Bloom(), f.addresses, f.topics) {
|
||||
var unfiltered []*types.Log
|
||||
for _, r := range receipts {
|
||||
unfiltered = append(unfiltered, r.Logs...)
|
||||
}
|
||||
return filterLogs(unfiltered, nil, nil, f.addresses, f.topics), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func includes(addresses []common.Address, a common.Address) bool {
|
||||
for _, addr := range addresses {
|
||||
if addr == a {
|
||||
|
||||
@@ -106,6 +106,10 @@ func (b *testBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types
|
||||
return logs, nil
|
||||
}
|
||||
|
||||
func (b *testBackend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (b *testBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
|
||||
return b.txFeed.Subscribe(ch)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user