@@ -6,20 +6,23 @@ import (
66 "fmt"
77 "strconv"
88
9+ "gfx.cafe/open/jrpc"
10+ "gfx.cafe/open/jrpc/pkg/jsonrpc"
11+ "github.com/ethereum/go-ethereum/common/hexutil"
912 "github.com/gfx-labs/venn/lib/config"
1013 "github.com/gfx-labs/venn/lib/ethtypes"
14+ "github.com/gfx-labs/venn/lib/jrpcutil"
1115 "github.com/gfx-labs/venn/lib/stores/headstore"
1216 "github.com/gfx-labs/venn/lib/subctx"
13- "gfx.cafe/open/jrpc"
14- "gfx.cafe/open/jrpc/pkg/jsonrpc"
15- "github.com/ethereum/go-ethereum/common/hexutil"
1617 "go.uber.org/fx"
18+ "golang.org/x/sync/singleflight"
1719)
1820
1921// HeadReplacer is a middleware that replaces "latest" block tags with actual block numbers
2022type HeadReplacer struct {
2123 headstore headstore.Store
2224 chains map [string ]* config.Chain
25+ sf singleflight.Group
2326}
2427
2528type Params struct {
@@ -137,7 +140,23 @@ func (h *HeadReplacer) Middleware(next jrpc.Handler) jrpc.Handler {
137140 _ = w .Send (strconv .Itoa (chain .Id ), nil )
138141 return
139142 case "eth_blockNumber" :
140- _ = w .Send (h .headstore .Get (r .Context (), chain ))
143+ head , err := h .headstore .Get (r .Context (), chain )
144+ if err != nil {
145+ _ = w .Send (nil , err )
146+ return
147+ }
148+ if head != 0 {
149+ _ = w .Send (head , nil )
150+ return
151+ }
152+ // head is 0 (stalker disabled), passthrough to remotes with singleflight
153+ key := chain .Name + ":eth_blockNumber"
154+ result , err , _ := h .sf .Do (key , func () (any , error ) {
155+ var interceptor jrpcutil.Interceptor
156+ next .ServeRPC (& interceptor , r )
157+ return interceptor .Result , interceptor .Error
158+ })
159+ _ = w .Send (result , err )
141160 return
142161 case "eth_getBlockByNumber" :
143162 newReq , err := h .ReplaceBlockNumberInRequest (r .Context (), r , 0 )
0 commit comments