@@ -380,7 +380,7 @@ func (b *Backend) Forward(ctx context.Context, reqs []*RPCReq, isBatch bool) ([]
380
380
"max_attempts" , b .maxRetries + 1 ,
381
381
"method" , metricLabelMethod ,
382
382
)
383
- res , err := b .doForward (ctx , reqs , isBatch )
383
+ res , err := b .doForward (ctx , reqs , isBatch , false )
384
384
switch err {
385
385
case nil : // do nothing
386
386
case ErrBackendResponseTooLarge :
@@ -454,6 +454,10 @@ func (b *Backend) ProxyWS(clientConn *websocket.Conn, methodWhitelist *StringSet
454
454
455
455
// ForwardRPC makes a call directly to a backend and populate the response into `res`
456
456
func (b * Backend ) ForwardRPC (ctx context.Context , res * RPCRes , id string , method string , params ... any ) error {
457
+ return b .forwardRPC (ctx , false , res , id , method , params ... )
458
+ }
459
+
460
+ func (b * Backend ) forwardRPC (ctx context.Context , isNonConsensusPoll bool , res * RPCRes , id string , method string , params ... any ) error {
457
461
jsonParams , err := json .Marshal (params )
458
462
if err != nil {
459
463
return err
@@ -466,7 +470,7 @@ func (b *Backend) ForwardRPC(ctx context.Context, res *RPCRes, id string, method
466
470
ID : []byte (id ),
467
471
}
468
472
469
- slicedRes , err := b .doForward (ctx , []* RPCReq {& rpcReq }, false )
473
+ slicedRes , err := b .doForward (ctx , []* RPCReq {& rpcReq }, false , isNonConsensusPoll )
470
474
if err != nil {
471
475
return err
472
476
}
@@ -482,9 +486,19 @@ func (b *Backend) ForwardRPC(ctx context.Context, res *RPCRes, id string, method
482
486
return nil
483
487
}
484
488
485
- func (b * Backend ) doForward (ctx context.Context , rpcReqs []* RPCReq , isBatch bool ) ([]* RPCRes , error ) {
489
+ func (b * Backend ) doForward (ctx context.Context , rpcReqs []* RPCReq , isBatch , isNonConsensusPoll bool ) ([]* RPCRes , error ) {
486
490
// we are concerned about network error rates, so we record 1 request independently of how many are in the batch
487
- b .networkRequestsSlidingWindow .Incr ()
491
+ // (we don't count non-consensus polling towards error rates)
492
+ if ! isNonConsensusPoll {
493
+ b .networkRequestsSlidingWindow .Incr ()
494
+ }
495
+
496
+ incrementError := func () {
497
+ if ! isNonConsensusPoll {
498
+ b .intermittentErrorsSlidingWindow .Incr ()
499
+ }
500
+ RecordBackendNetworkErrorRateSlidingWindow (b , b .ErrorRate ())
501
+ }
488
502
489
503
translatedReqs := make (map [string ]* RPCReq , len (rpcReqs ))
490
504
// translate consensus_getReceipts to receipts target
@@ -552,8 +566,7 @@ func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool
552
566
553
567
httpReq , err := http .NewRequestWithContext (ctx , "POST" , b .rpcURL , bytes .NewReader (body ))
554
568
if err != nil {
555
- b .intermittentErrorsSlidingWindow .Incr ()
556
- RecordBackendNetworkErrorRateSlidingWindow (b , b .ErrorRate ())
569
+ incrementError ()
557
570
return nil , wrapErr (err , "error creating backend request" )
558
571
}
559
572
@@ -583,8 +596,7 @@ func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool
583
596
start := time .Now ()
584
597
httpRes , err := b .client .DoLimited (httpReq )
585
598
if err != nil {
586
- b .intermittentErrorsSlidingWindow .Incr ()
587
- RecordBackendNetworkErrorRateSlidingWindow (b , b .ErrorRate ())
599
+ incrementError ()
588
600
return nil , wrapErr (err , "error in backend request" )
589
601
}
590
602
@@ -602,8 +614,7 @@ func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool
602
614
603
615
// Alchemy returns a 400 on bad JSONs, so handle that case
604
616
if httpRes .StatusCode != 200 && httpRes .StatusCode != 400 {
605
- b .intermittentErrorsSlidingWindow .Incr ()
606
- RecordBackendNetworkErrorRateSlidingWindow (b , b .ErrorRate ())
617
+ incrementError ()
607
618
return nil , fmt .Errorf ("response code %d" , httpRes .StatusCode )
608
619
}
609
620
@@ -613,8 +624,7 @@ func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool
613
624
return nil , ErrBackendResponseTooLarge
614
625
}
615
626
if err != nil {
616
- b .intermittentErrorsSlidingWindow .Incr ()
617
- RecordBackendNetworkErrorRateSlidingWindow (b , b .ErrorRate ())
627
+ incrementError ()
618
628
return nil , wrapErr (err , "error reading response body" )
619
629
}
620
630
@@ -629,21 +639,17 @@ func (b *Backend) doForward(ctx context.Context, rpcReqs []*RPCReq, isBatch bool
629
639
}
630
640
} else {
631
641
if err := json .Unmarshal (resB , & rpcRes ); err != nil {
642
+ incrementError ()
632
643
// Infura may return a single JSON-RPC response if, for example, the batch contains a request for an unsupported method
633
644
if responseIsNotBatched (resB ) {
634
- b .intermittentErrorsSlidingWindow .Incr ()
635
- RecordBackendNetworkErrorRateSlidingWindow (b , b .ErrorRate ())
636
645
return nil , ErrBackendUnexpectedJSONRPC
637
646
}
638
- b .intermittentErrorsSlidingWindow .Incr ()
639
- RecordBackendNetworkErrorRateSlidingWindow (b , b .ErrorRate ())
640
647
return nil , ErrBackendBadResponse
641
648
}
642
649
}
643
650
644
651
if len (rpcReqs ) != len (rpcRes ) {
645
- b .intermittentErrorsSlidingWindow .Incr ()
646
- RecordBackendNetworkErrorRateSlidingWindow (b , b .ErrorRate ())
652
+ incrementError ()
647
653
return nil , ErrBackendUnexpectedJSONRPC
648
654
}
649
655
0 commit comments