forked from cerc-io/plugeth
eth/filters: add global block logs cache (#25459)
This adds a cache for block logs which is shared by all filters. The cache size of is configurable using the `--cache.blocklogs` flag. Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
co-authored by
Felix Lange
parent
77308cd6fc
commit
36874b63a1
+32
-7
@@ -450,12 +450,36 @@ func (t *Transaction) CreatedContract(ctx context.Context, args BlockNumberArgs)
|
||||
}
|
||||
|
||||
func (t *Transaction) Logs(ctx context.Context) (*[]*Log, error) {
|
||||
receipt, err := t.getReceipt(ctx)
|
||||
if err != nil || receipt == nil {
|
||||
if _, err := t.resolve(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make([]*Log, 0, len(receipt.Logs))
|
||||
for _, log := range receipt.Logs {
|
||||
if t.block == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if _, ok := t.block.numberOrHash.Hash(); !ok {
|
||||
header, err := t.r.backend.HeaderByNumberOrHash(ctx, *t.block.numberOrHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hash := header.Hash()
|
||||
t.block.numberOrHash.BlockHash = &hash
|
||||
}
|
||||
return t.getLogs(ctx)
|
||||
}
|
||||
|
||||
// getLogs returns log objects for the given tx.
|
||||
// Assumes block hash is resolved.
|
||||
func (t *Transaction) getLogs(ctx context.Context) (*[]*Log, error) {
|
||||
var (
|
||||
hash, _ = t.block.numberOrHash.Hash()
|
||||
filter = t.r.filterSystem.NewBlockFilter(hash, nil, nil)
|
||||
logs, err = filter.Logs(ctx)
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := make([]*Log, 0, len(logs))
|
||||
for _, log := range logs {
|
||||
ret = append(ret, &Log{
|
||||
r: t.r,
|
||||
transaction: t,
|
||||
@@ -978,7 +1002,7 @@ func (b *Block) Logs(ctx context.Context, args struct{ Filter BlockFilterCriteri
|
||||
hash = header.Hash()
|
||||
}
|
||||
// Construct the range filter
|
||||
filter := filters.NewBlockFilter(b.r.backend, hash, addresses, topics)
|
||||
filter := b.r.filterSystem.NewBlockFilter(hash, addresses, topics)
|
||||
|
||||
// Run the filter and return all the logs
|
||||
return runFilter(ctx, b.r, filter)
|
||||
@@ -1137,7 +1161,8 @@ func (p *Pending) EstimateGas(ctx context.Context, args struct {
|
||||
|
||||
// Resolver is the top-level object in the GraphQL hierarchy.
|
||||
type Resolver struct {
|
||||
backend ethapi.Backend
|
||||
backend ethapi.Backend
|
||||
filterSystem *filters.FilterSystem
|
||||
}
|
||||
|
||||
func (r *Resolver) Block(ctx context.Context, args struct {
|
||||
@@ -1284,7 +1309,7 @@ func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria
|
||||
topics = *args.Filter.Topics
|
||||
}
|
||||
// Construct the range filter
|
||||
filter := filters.NewRangeFilter(r.backend, begin, end, addresses, topics)
|
||||
filter := r.filterSystem.NewRangeFilter(begin, end, addresses, topics)
|
||||
return runFilter(ctx, r, filter)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
|
||||
@@ -50,7 +51,7 @@ func TestBuildSchema(t *testing.T) {
|
||||
}
|
||||
defer stack.Close()
|
||||
// Make sure the schema can be parsed and matched up to the object model.
|
||||
if err := newHandler(stack, nil, []string{}, []string{}); err != nil {
|
||||
if err := newHandler(stack, nil, nil, []string{}, []string{}); err != nil {
|
||||
t.Errorf("Could not construct GraphQL handler: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -263,7 +264,8 @@ func createGQLService(t *testing.T, stack *node.Node) {
|
||||
t.Fatalf("could not create import blocks: %v", err)
|
||||
}
|
||||
// create gql service
|
||||
err = New(stack, ethBackend.APIBackend, []string{}, []string{})
|
||||
filterSystem := filters.NewFilterSystem(ethBackend.APIBackend, filters.Config{})
|
||||
err = New(stack, ethBackend.APIBackend, filterSystem, []string{}, []string{})
|
||||
if err != nil {
|
||||
t.Fatalf("could not create graphql service: %v", err)
|
||||
}
|
||||
@@ -348,7 +350,8 @@ func createGQLServiceWithTransactions(t *testing.T, stack *node.Node) {
|
||||
t.Fatalf("could not create import blocks: %v", err)
|
||||
}
|
||||
// create gql service
|
||||
err = New(stack, ethBackend.APIBackend, []string{}, []string{})
|
||||
filterSystem := filters.NewFilterSystem(ethBackend.APIBackend, filters.Config{})
|
||||
err = New(stack, ethBackend.APIBackend, filterSystem, []string{}, []string{})
|
||||
if err != nil {
|
||||
t.Fatalf("could not create graphql service: %v", err)
|
||||
}
|
||||
|
||||
+5
-4
@@ -20,6 +20,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/ethereum/go-ethereum/eth/filters"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/graph-gophers/graphql-go"
|
||||
@@ -55,14 +56,14 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// New constructs a new GraphQL service instance.
|
||||
func New(stack *node.Node, backend ethapi.Backend, cors, vhosts []string) error {
|
||||
return newHandler(stack, backend, cors, vhosts)
|
||||
func New(stack *node.Node, backend ethapi.Backend, filterSystem *filters.FilterSystem, cors, vhosts []string) error {
|
||||
return newHandler(stack, backend, filterSystem, cors, vhosts)
|
||||
}
|
||||
|
||||
// newHandler returns a new `http.Handler` that will answer GraphQL queries.
|
||||
// It additionally exports an interactive query browser on the / endpoint.
|
||||
func newHandler(stack *node.Node, backend ethapi.Backend, cors, vhosts []string) error {
|
||||
q := Resolver{backend}
|
||||
func newHandler(stack *node.Node, backend ethapi.Backend, filterSystem *filters.FilterSystem, cors, vhosts []string) error {
|
||||
q := Resolver{backend, filterSystem}
|
||||
|
||||
s, err := graphql.ParseSchema(schema, &q)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user